diff --git a/.github/workflows/create-draft-release.yml b/.github/workflows/create-draft-release.yml index b84d11374..8b9de0023 100644 --- a/.github/workflows/create-draft-release.yml +++ b/.github/workflows/create-draft-release.yml @@ -28,7 +28,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' - name: Install uv run: | diff --git a/.github/workflows/package-install.yml b/.github/workflows/package-install.yml index 3665c1a84..1dbfe8c39 100644 --- a/.github/workflows/package-install.yml +++ b/.github/workflows/package-install.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install uv run: | @@ -40,6 +40,6 @@ jobs: project_dir="$(mktemp -d)" cd "$project_dir" - uv init --name art-install-smoke --python 3.11 --bare + uv init --name art-install-smoke --python 3.12 --bare uv add "openpipe-art[backend] @ file://${wheel_path}" uv sync diff --git a/.github/workflows/prek.yml b/.github/workflows/prek.yml index 018f4545f..b2550f761 100644 --- a/.github/workflows/prek.yml +++ b/.github/workflows/prek.yml @@ -10,7 +10,7 @@ permissions: env: CI_BASE_IMAGE: "pytorch/pytorch:2.9.0-cuda12.8-cudnn9-devel" - CI_PYTHON_MM: "3.11" + CI_PYTHON_MM: "3.12" CI_UV_CACHE_RELEASE_TAG: "prek-uv-cache" CI_UV_CACHE_ASSET_PREFIX: "prek-uv-cache" CI_APEX_PARALLEL_BUILD: "8" @@ -211,8 +211,7 @@ jobs: } trap cleanup EXIT - py_mm="$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')" - cudnn_path="${GITHUB_WORKSPACE}/.venv/lib/python${py_mm}/site-packages/nvidia/cudnn" + cudnn_path="${GITHUB_WORKSPACE}/.venv/lib/python${CI_PYTHON_MM}/site-packages/nvidia/cudnn" export CUDNN_PATH="${cudnn_path}" export CUDNN_HOME="${cudnn_path}" export CUDNN_INCLUDE_PATH="${cudnn_path}/include" @@ -230,7 +229,7 @@ jobs: --apex-nvcc-threads "${CI_APEX_NVCC_THREADS}" echo "CI uv build overrides: APEX_PARALLEL_BUILD=${CI_APEX_PARALLEL_BUILD}, NVCC_APPEND_FLAGS=--threads ${CI_APEX_NVCC_THREADS}, UV_CONCURRENT_BUILDS=${CI_UV_BUILD_SLOTS}" uv --version - uv sync --all-extras --group dev --frozen + uv sync --all-extras --group dev --frozen --python "${CI_PYTHON_MM}" - name: Run prek hooks (lint, format, typecheck, uv.lock, tests) run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 46271cb69..c997b436e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,7 +34,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install uv run: | @@ -63,7 +63,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install uv run: | @@ -89,7 +89,7 @@ jobs: project_dir="$(mktemp -d)" cd "$project_dir" - uv init --name art-runtime-smoke --python 3.11 --bare + uv init --name art-runtime-smoke --python 3.12 --bare uv add "openpipe-art[backend] @ file://${wheel_path}" uv sync uv run python - <<'PY' @@ -163,7 +163,7 @@ jobs: if: inputs.artifact_run_id == '' uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install uv if: inputs.artifact_run_id == '' diff --git a/.python-version b/.python-version index 2c0733315..e4fba2183 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.11 +3.12 diff --git a/pyproject.toml b/pyproject.toml index dad45d838..92b675d76 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "openpipe-art" version = "0.5.18" description = "The OpenPipe Agent Reinforcement Training (ART) library" readme = "README.md" -requires-python = ">=3.11" +requires-python = ">=3.12" dependencies = [ "openai>=2.14.0", "typer>=0.15.2", @@ -49,13 +49,14 @@ megatron = [ "transformer-engine==2.11.0", "transformer-engine-cu12==2.11.0", "transformer-engine-torch==2.11.0", - "megatron-core==0.16.0rc0", + "megatron-core==0.17.0", "pybind11>=2.13.6", "megatron-bridge==0.4.0rc0", "deep-ep==1.2.1 ; sys_platform == 'linux'", "causal-conv1d==1.6.1 ; sys_platform == 'linux' and platform_machine == 'x86_64' and python_full_version < '3.12'", "mamba-ssm==2.3.1 ; sys_platform == 'linux' and platform_machine == 'x86_64' and python_full_version < '3.12'", "nvidia-ml-py==13.580.82", + "nvidia-modelopt>=0.42.0a0 ; sys_platform != 'darwin'", "nvidia-resiliency-ext<0.5 ; sys_platform == 'linux'", "ml-dtypes>=0.5.0 ; python_full_version < '3.13'", ] @@ -147,18 +148,18 @@ markers = [ required-version = ">=0.11.7" override-dependencies = [ "flashinfer-python==0.6.1", + "megatron-core==0.17.0", "numpy<2", "nvidia-resiliency-ext<0.5", "quack-kernels==0.2.5", "transformer-engine==2.11.0", ] exclude-dependencies = ["pynvml", "emerging-optimizers"] -no-build-isolation-package = ["apex", "transformer-engine", "transformer-engine-cu12", "transformer-engine-torch", "megatron-core", "megatron-bridge", "deep-ep", "nv-grouped-gemm"] +no-build-isolation-package = ["apex", "transformer-engine", "transformer-engine-cu12", "transformer-engine-torch", "megatron-bridge", "deep-ep", "nv-grouped-gemm"] [tool.uv.extra-build-dependencies] apex = ["torch>=2.8.0"] deep-ep = ["torch>=2.8.0"] -megatron-core = ["pybind11"] nv-grouped-gemm = ["torch>=2.8.0"] transformer-engine-torch = ["torch>=2.8.0"] @@ -190,7 +191,7 @@ requires-dist = [ ] [tool.ty.environment] -python-version = "3.11" +python-version = "3.12" [tool.ty.rules] # Ignore unused-ignore-comment warnings because they vary depending on whether diff --git a/scripts/ci/build_and_push_uv_cache.sh b/scripts/ci/build_and_push_uv_cache.sh index f4db6bcb4..f98db5f3e 100755 --- a/scripts/ci/build_and_push_uv_cache.sh +++ b/scripts/ci/build_and_push_uv_cache.sh @@ -5,7 +5,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" BASE_IMAGE="${BASE_IMAGE:-pytorch/pytorch:2.9.0-cuda12.8-cudnn9-devel}" -PYTHON_MM="${PYTHON_MM:-3.11}" +PYTHON_MM="${PYTHON_MM:-3.12}" UV_CACHE_RELEASE_TAG="${UV_CACHE_RELEASE_TAG:-prek-uv-cache}" UV_CACHE_ASSET_PREFIX="${UV_CACHE_ASSET_PREFIX:-prek-uv-cache}" BUILD_JOBS="${BUILD_JOBS:-auto}" @@ -36,7 +36,7 @@ Description: Options: --base-image CI base image metadata for fingerprint computation - --python-mm Python major.minor used in CI (default: 3.11) + --python-mm Python major.minor used in CI (default: 3.12) --build-jobs Parallel native-build jobs while prebuilding cache (default: auto) --release-tag GitHub release tag used to store cache assets (default: prek-uv-cache) --asset-prefix Asset prefix for cache archive names (default: prek-uv-cache) diff --git a/scripts/ci/compute_uv_fingerprint.py b/scripts/ci/compute_uv_fingerprint.py index 75e67305a..f9029edf5 100755 --- a/scripts/ci/compute_uv_fingerprint.py +++ b/scripts/ci/compute_uv_fingerprint.py @@ -39,8 +39,8 @@ def _build_parser() -> argparse.ArgumentParser: ) parser.add_argument( "--python-mm", - default="3.11", - help="Python major.minor string used in CI (for example: 3.11)", + default="3.12", + help="Python major.minor string used in CI (for example: 3.12)", ) parser.add_argument( "--torch-cuda-arch-list", diff --git a/src/art/auto_trajectory.py b/src/art/auto_trajectory.py index be8a11752..0b0860808 100644 --- a/src/art/auto_trajectory.py +++ b/src/art/auto_trajectory.py @@ -8,6 +8,7 @@ from openai.types.chat.chat_completion_chunk import ChatCompletionChunk from .openai import init_chat_completion, update_chat_completion +from .preprocessing.moe_routing import attach_moe_routing_metadata_to_choice from .trajectories import History, Trajectory logger = logging.getLogger(__name__) @@ -105,7 +106,13 @@ def handle_httpx_response(self, response: httpx._models.Response) -> None: chat_completion = parse_sse_to_chat_completion(content) choice = chat_completion.choices[0] else: - choice = Choice(**json.loads(content)["choices"][0]) + response_payload = json.loads(content) + choice = Choice(**response_payload["choices"][0]) + attach_moe_routing_metadata_to_choice( + choice=choice, + response_payload=response_payload, + choice_index=0, + ) except (json.JSONDecodeError, KeyError, ValueError) as e: logger.debug(f"Failed to parse response content: {e}") return diff --git a/src/art/dev/engine.py b/src/art/dev/engine.py index 517bc83ab..b6797b381 100644 --- a/src/art/dev/engine.py +++ b/src/art/dev/engine.py @@ -125,6 +125,7 @@ class EngineArgs(TypedDict, total=False): override_generation_config: dict[str, Any] | None enable_sleep_mode: bool enable_expert_parallel: bool + enable_return_routed_experts: bool model_impl: str calculate_kv_scales: bool | None diff --git a/src/art/local/backend.py b/src/art/local/backend.py index 16cce94f7..2e4aa038f 100644 --- a/src/art/local/backend.py +++ b/src/art/local/backend.py @@ -9,7 +9,7 @@ import socket import time from types import TracebackType -from typing import AsyncIterator, Iterable, Literal, cast +from typing import Any, AsyncIterator, Iterable, Literal, cast import warnings logger = logging.getLogger(__name__) @@ -147,6 +147,7 @@ def __init__( in_process: bool = False, path: str | None = None, gpu_cost_per_hour_usd: float | None = None, + enable_expert_replay: bool = True, ) -> None: """ Initializes a local, directory-based Backend interface at the given path. @@ -162,12 +163,15 @@ def __init__( automatic `costs/gpu` accounting on train steps. When unset, ART auto-detects supported GPU types (H200 at $3/hr today) and skips GPU cost logging for unknown devices instead of guessing. + enable_expert_replay: For supported MoE Megatron training, capture + vLLM routed experts and replay them in Megatron. Defaults to True. """ self._in_process = in_process self._path = path or get_default_art_path() self._gpu_cost_per_hour_usd = ( float(gpu_cost_per_hour_usd) if gpu_cost_per_hour_usd is not None else None ) + self._enable_expert_replay = enable_expert_replay os.makedirs(self._path, exist_ok=True) # Other initialization @@ -182,6 +186,27 @@ def __init__( "default" ) + def _model_uses_expert_replay(self, model: AnyTrainableModel) -> bool: + if not self._enable_expert_replay or not self._supports_result_packing: + return False + from ..megatron.model_support.registry import ( + UnsupportedModelArchitectureError, + model_uses_expert_parallel, + ) + + allow_unvalidated_arch = bool( + (model._internal_config or dev.InternalModelConfig()).get( + "allow_unvalidated_arch", False + ) + ) + try: + return model_uses_expert_parallel( + model.base_model, + allow_unvalidated_arch=allow_unvalidated_arch, + ) + except UnsupportedModelArchitectureError: + return False + def supports_automatic_train_step_metrics(self) -> bool: return True @@ -455,6 +480,7 @@ def _get_packed_tensors( plot_tensors: bool, packed_sequence_length: int | None, logprob_calculation_chunk_size: int, + include_moe_routing: bool = False, ) -> PackedTensors | None: internal_config = cast(dev.InternalModelConfig, model._internal_config or {}) tokenizer_key = _tokenizer_cache_key(model.base_model, internal_config) @@ -547,6 +573,7 @@ def _get_packed_tensors( truncate_long_results=False, advantage_balance=advantage_balance, pack_results=self._supports_result_packing, + include_moe_routing=include_moe_routing, ) if ( not allow_training_without_logprobs @@ -603,6 +630,11 @@ async def _prepare_backend_for_training( config_dict: dict = dict(config or {}) internal_config = cast(dev.InternalModelConfig, model._internal_config or {}) _apply_configured_chat_template_server_args(config_dict, internal_config) + if self._model_uses_expert_replay(model): + engine_args = dict(config_dict.get("engine_args", {})) + engine_args["enable_return_routed_experts"] = True + engine_args["async_scheduling"] = False + config_dict["engine_args"] = engine_args server_args = dict(config_dict.get("server_args", {})) # Avoid binding collisions on busy hosts when no explicit port is provided. @@ -850,7 +882,7 @@ async def _train_model( summary, include_trainable_groups=True, ) - + include_moe_routing = self._model_uses_expert_replay(model) packed_tensors = self._get_packed_tensors( model, trajectory_groups, @@ -864,6 +896,7 @@ async def _train_model( logprob_calculation_chunk_size=dev_config.get( "logprob_calculation_chunk_size", 1024 ), + include_moe_routing=include_moe_routing, ) if packed_tensors is None: print( @@ -927,17 +960,34 @@ async def _train_model( disk_packed_tensors = packed_tensors_to_dir( packed_tensors, f"{get_model_dir(model=model, art_path=self._path)}/tensors" ) - # Note: scale_learning_rate_by_reward_std_dev is now handled by the frontend (Model.train()) - grad_accumulation_sequences = max( - 1, int(config.grad_accumulation_sequences or 1) + service_dev_config = cast(dev.TrainConfig, {**dev_config}) + grad_accumulation_sequences = await self._resolve_grad_accumulation_sequences( + service, + config, ) + if include_moe_routing: + from ..megatron.routing_replay import ( + build_moe_routing_replay_bundle_from_packed_tensors, + ) + + routing_replay_dir = ( + f"{get_model_dir(model=model, art_path=self._path)}/tensors/" + "moe_routing_replay" + ) + build_moe_routing_replay_bundle_from_packed_tensors( + packed_tensors=packed_tensors, + global_grad_accumulation_sequences=grad_accumulation_sequences, + ).to_dir(routing_replay_dir) + service_dev_config["moe_routing_replay_path"] = routing_replay_dir + service_dev_config["moe_routing_replay_strict"] = True + # Note: scale_learning_rate_by_reward_std_dev is now handled by the frontend (Model.train()) fallback_gradient_steps = math.ceil( disk_packed_tensors["num_sequences"] / grad_accumulation_sequences ) pbar = tqdm.tqdm(total=fallback_gradient_steps, desc="train") reported_gradient_steps: int | None = None async for result in service.train( - disk_packed_tensors, config, dev_config, verbose + disk_packed_tensors, config, service_dev_config, verbose ): raw_num_gradient_steps = result.pop(TRAIN_GRADIENT_STEPS_KEY, None) if raw_num_gradient_steps is not None: @@ -965,6 +1015,20 @@ async def _train_model( if verbose: print("_train_model complete") + async def _resolve_grad_accumulation_sequences( + self, + service: ModelService, + config: TrainConfig, + ) -> int: + resolver = getattr( + cast(Any, service), + "resolve_global_grad_accumulation_sequences", + None, + ) + if callable(resolver): + return max(1, int(await resolver(config))) + return max(1, int(config.grad_accumulation_sequences or 1)) + # Note: _get_reward_std_dev_learning_rate_multiplier and _log_metrics # have been moved to the Model class (frontend) diff --git a/src/art/megatron/lora.py b/src/art/megatron/lora.py index d32c1a7ea..2d04f0bf6 100644 --- a/src/art/megatron/lora.py +++ b/src/art/megatron/lora.py @@ -962,6 +962,14 @@ def __init__( b_parallel_spec=b_parallel_spec, allreduce=False, ) + component_size = ( + linear_fc1.out_features * _get_shard_world_size("expert_tp") + ) // 2 + _set_lora_shard_strategy_metadata( + self.lora.B_T, + strategy="componentwise", + component_sizes=(component_size, component_size), + ) def forward( self, x: torch.Tensor, tokens_per_expert: list[int] | torch.Tensor diff --git a/src/art/megatron/provider.py b/src/art/megatron/provider.py index 7c54eb75c..20f989a17 100644 --- a/src/art/megatron/provider.py +++ b/src/art/megatron/provider.py @@ -103,13 +103,6 @@ def _apply_default_parallel_topology(provider: GPTModelProvider) -> None: provider.expert_tensor_parallel_size = 1 -def _etp_ep_parallel_domain_size(provider: GPTModelProvider) -> int: - return ( - cast(int, provider.expert_tensor_parallel_size) - * provider.expert_model_parallel_size - ) - - def _apply_art_training_runtime_prepare_defaults(provider: GPTModelProvider) -> None: provider.recompute_granularity = "full" provider.recompute_method = "uniform" @@ -119,7 +112,7 @@ def _apply_art_training_runtime_prepare_defaults(provider: GPTModelProvider) -> def _apply_art_training_runtime_finalize_defaults(provider: GPTModelProvider) -> None: - if _etp_ep_parallel_domain_size(provider) <= 1: + if provider.expert_model_parallel_size <= 1: return # use DeepEP for MoE expert comm. comm can be the same amount of time as actual MLP # compute, so these are very beneficial diff --git a/src/art/megatron/routing_replay.py b/src/art/megatron/routing_replay.py index b30eddd0b..849ce467a 100644 --- a/src/art/megatron/routing_replay.py +++ b/src/art/megatron/routing_replay.py @@ -3,27 +3,25 @@ from collections import defaultdict import json import logging +import math +import os from pathlib import Path +import random import re -import types -from typing import Any, Protocol - -from megatron.core.tensor_parallel import ( - all_to_all, - gather_from_sequence_parallel_region, -) -from megatron.core.transformer.moe.moe_utils import permute, sort_chunks_by_idxs +from typing import TYPE_CHECKING, Any, Protocol + from pydantic import BaseModel, ConfigDict, model_validator from safetensors.torch import load_file, save_file import torch from art.megatron.weights.param_name_canonicalization import canonical_art_param_name +if TYPE_CHECKING: + from art.preprocessing.pack import PackedTensors + ROUTER_NAME_TOKEN = ".mlp.router" -ROUTER_KEY_FORMAT_VERSION = "moe_routing_replay_v1" +ROUTER_KEY_FORMAT_VERSION = "moe_routing_replay_v2" GLOBAL_TOKEN_UIDS_KEY = "global_token_uids" -TRACE_ROW_TOKEN_UIDS_ATTR = "_art_trace_row_token_uids" -TRACE_UID_SPAN_ATTR = "_art_trace_uid_span" _ROUTER_LAYER_PATTERN = re.compile(r"decoder\.layers\.(?P\d+)\.mlp\.router$") _TRACE_CHUNK_PREFIX_PATTERN = re.compile(r"^chunk(?P\d+)\.(?P.+)$") @@ -48,73 +46,6 @@ def _build_tensor_key(router_key: str, call_index: int, field_name: str) -> str: return f"{router_key}/call_{call_index}/{field_name}" -def _flatten_router_tensor(tensor: torch.Tensor) -> torch.Tensor: - if tensor.ndim < 2: - raise RuntimeError( - f"Router tensor must have rank >=2, got shape={tuple(tensor.shape)}" - ) - num_experts = int(tensor.shape[-1]) - return tensor.reshape(-1, num_experts).contiguous() - - -def _extract_router_output_tensors(output: Any) -> tuple[torch.Tensor, torch.Tensor]: - if isinstance(output, (list, tuple)) and len(output) >= 2: - probs, routing_map = output[0], output[1] - elif isinstance(output, dict): - probs = output.get("probs") - routing_map = output.get("routing_map") - else: - raise RuntimeError(f"Unsupported router output type: {type(output)}") - - if not isinstance(probs, torch.Tensor): - raise RuntimeError(f"Expected probs tensor, got {type(probs)}") - if not isinstance(routing_map, torch.Tensor): - raise RuntimeError(f"Expected routing_map tensor, got {type(routing_map)}") - - probs_2d = _flatten_router_tensor(probs.to(torch.float32)) - routing_map_2d = _flatten_router_tensor(routing_map.bool()) - if probs_2d.shape != routing_map_2d.shape: - raise RuntimeError( - "Router output shape mismatch: " - f"probs={tuple(probs_2d.shape)} routing_map={tuple(routing_map_2d.shape)}" - ) - return probs_2d, routing_map_2d - - -def _extract_dp_slot_from_rank_meta(rank_meta: Any) -> tuple[int, int] | None: - if isinstance(rank_meta, dict): - rank_meta = [rank_meta] - if not isinstance(rank_meta, list) or not rank_meta: - return None - dp_ranks = { - int(item["dp_rank"]) - for item in rank_meta - if isinstance(item, dict) and "dp_rank" in item - } - dp_world_sizes = { - int(item["dp_world_size"]) - for item in rank_meta - if isinstance(item, dict) and "dp_world_size" in item - } - if len(dp_ranks) != 1 or len(dp_world_sizes) != 1: - return None - return next(iter(dp_ranks)), next(iter(dp_world_sizes)) - - -def _trace_call_route_metadata( - call_entry: dict[str, Any], -) -> tuple[int | None, int | None]: - sample_index = call_entry.get("micro_sample_index") - if isinstance(sample_index, int): - return int(sample_index), None - dp_slot = _extract_dp_slot_from_rank_meta(call_entry.get("rank_meta")) - micro_order = int(call_entry.get("micro_order", 0)) - if dp_slot is None: - return None, micro_order - dp_rank, dp_world_size = dp_slot - return None, micro_order * dp_world_size + dp_rank - - def build_router_key_from_module_name(*, chunk_index: int, module_name: str) -> str: canonical_name = canonical_art_param_name(module_name) match = _ROUTER_LAYER_PATTERN.search(canonical_name) @@ -135,11 +66,9 @@ def build_router_key_from_trace_name(trace_module_name: str) -> str: "Forward trace router module name must start with 'chunk.'; " f"got '{trace_module_name}'" ) - chunk_index = int(chunk_match.group("chunk")) - module_name = chunk_match.group("name") return build_router_key_from_module_name( - chunk_index=chunk_index, - module_name=module_name, + chunk_index=int(chunk_match.group("chunk")), + module_name=chunk_match.group("name"), ) @@ -158,9 +87,7 @@ class RouterCallRoute(BaseModel): model_config = ConfigDict(arbitrary_types_allowed=True) expert_indices: torch.Tensor - expert_probs: torch.Tensor expert_mask: torch.Tensor - routing_map: torch.Tensor | None = None num_experts: int sample_index: int | None = None micro_slot: int | None = None @@ -170,43 +97,38 @@ def _validate(self) -> "RouterCallRoute": self.expert_indices = _to_tensor_cpu_contiguous( self.expert_indices, dtype=torch.int32 ) - self.expert_probs = _to_tensor_cpu_contiguous( - self.expert_probs, dtype=torch.float32 - ) self.expert_mask = _to_tensor_cpu_contiguous(self.expert_mask, dtype=torch.bool) - if self.routing_map is not None: - self.routing_map = _to_tensor_cpu_contiguous( - self.routing_map, dtype=torch.bool - ) - if self.expert_indices.ndim != 2: raise RuntimeError( - "expert_indices must have shape [num_tokens, max_topk], got " + "expert_indices must have shape [num_tokens, topk], got " f"{tuple(self.expert_indices.shape)}" ) - if self.expert_probs.shape != self.expert_indices.shape: - raise RuntimeError( - "expert_probs shape must match expert_indices shape, got " - f"{tuple(self.expert_probs.shape)} vs {tuple(self.expert_indices.shape)}" - ) if self.expert_mask.shape != self.expert_indices.shape: raise RuntimeError( "expert_mask shape must match expert_indices shape, got " f"{tuple(self.expert_mask.shape)} vs {tuple(self.expert_indices.shape)}" ) + if not bool(self.expert_mask.all().item()): + raise RuntimeError( + "masked slots are unsupported by Megatron native MoE routing replay; " + "route bundles must contain a valid full top-k expert id row for " + "every replayed token" + ) if self.num_experts <= 0: raise RuntimeError(f"num_experts must be >0, got {self.num_experts}") + selected = self.expert_indices[self.expert_mask] + if int(selected.numel()) > 0 and ( + int(selected.min().item()) < 0 + or int(selected.max().item()) >= int(self.num_experts) + ): + raise RuntimeError( + "expert_indices contain ids outside [0, num_experts): " + f"num_experts={self.num_experts}" + ) if self.sample_index is not None: self.sample_index = int(self.sample_index) if self.micro_slot is not None: self.micro_slot = int(self.micro_slot) - if self.routing_map is not None: - expected = (self.expert_indices.shape[0], self.num_experts) - if tuple(self.routing_map.shape) != expected: - raise RuntimeError( - "routing_map shape mismatch: " - f"expected={expected}, got={tuple(self.routing_map.shape)}" - ) return self @property @@ -258,10 +180,10 @@ def _validate(self) -> "StepRoutes": for call_index, route in step_router.calls.items(): if route.num_global_tokens != expected_tokens: raise RuntimeError( - "Route token count mismatch for " - f"router='{router_key}' call={call_index}: " + "Route token count must match step global_token_uids: " + f"router='{router_key}', call={call_index}, " f"route_tokens={route.num_global_tokens}, " - f"expected_tokens={expected_tokens}" + f"global_token_uids={expected_tokens}" ) return self @@ -280,28 +202,38 @@ class MoeRoutingReplayBundle(BaseModel): def _validate(self) -> "MoeRoutingReplayBundle": if self.format_version != ROUTER_KEY_FORMAT_VERSION: raise RuntimeError( - f"Unsupported format_version={self.format_version}; " - f"expected={ROUTER_KEY_FORMAT_VERSION}" + "Unsupported MoE routing replay bundle format: " + f"{self.format_version!r}; expected {ROUTER_KEY_FORMAT_VERSION!r}" ) if self.num_steps <= 0: raise RuntimeError(f"num_steps must be >0, got {self.num_steps}") - if self.max_topk < 0: - raise RuntimeError(f"max_topk must be >=0, got {self.max_topk}") - if set(self.steps.keys()) != set(range(self.num_steps)): - raise RuntimeError( - "steps must be indexed from 0..num_steps-1 without gaps: " - f"num_steps={self.num_steps}, step_keys={sorted(self.steps.keys())}" - ) + if self.max_topk <= 0: + raise RuntimeError(f"max_topk must be >0, got {self.max_topk}") if not self.router_keys: raise RuntimeError("router_keys cannot be empty") + if len(set(self.router_keys)) != len(self.router_keys): + raise RuntimeError("router_keys must be unique") + expected_steps = set(range(self.num_steps)) + if set(self.steps) != expected_steps: + raise RuntimeError( + f"steps must contain exactly {sorted(expected_steps)}, got " + f"{sorted(self.steps)}" + ) router_key_set = set(self.router_keys) for step_index, step_routes in self.steps.items(): - step_router_keys = set(step_routes.routers.keys()) - if step_router_keys != router_key_set: + if set(step_routes.routers) != router_key_set: raise RuntimeError( - f"Step {step_index} router set mismatch. " - f"expected={sorted(router_key_set)}, got={sorted(step_router_keys)}" + f"Step {step_index} router keys differ from bundle router keys: " + f"step_keys={sorted(step_routes.routers)}, " + f"router_keys={self.router_keys}" ) + for router_routes in step_routes.routers.values(): + for route in router_routes.calls.values(): + if route.max_topk > self.max_topk: + raise RuntimeError( + "Route topk exceeds bundle max_topk: " + f"route_topk={route.max_topk}, max_topk={self.max_topk}" + ) return self @classmethod @@ -312,150 +244,96 @@ def from_dir(cls, bundle_dir: str | Path) -> "MoeRoutingReplayBundle": raise FileNotFoundError(f"Missing routing replay manifest: {manifest_path}") with manifest_path.open("r", encoding="utf-8") as handle: manifest = json.load(handle) - if manifest.get("format_version") != ROUTER_KEY_FORMAT_VERSION: raise RuntimeError( - "Unsupported routing replay manifest version: " - f"{manifest.get('format_version')}" + "Unsupported MoE routing replay bundle format: " + f"{manifest.get('format_version')!r}; expected " + f"{ROUTER_KEY_FORMAT_VERSION!r}" ) - topology = ParallelTopology.model_validate(manifest["topology"]) - num_steps = int(manifest["num_steps"]) - max_topk = int(manifest["max_topk"]) - router_keys = [str(key) for key in manifest["router_keys"]] - manifest_steps = manifest["steps"] - steps: dict[int, StepRoutes] = {} - for step_index in range(num_steps): - step_manifest = manifest_steps[str(step_index)] - step_file = base_dir / step_manifest["file"] - if not step_file.exists(): - raise FileNotFoundError( - f"Missing routing replay step file for step={step_index}: {step_file}" - ) - step_tensors = load_file(str(step_file)) + for step_index_str, step_info in manifest["steps"].items(): + step_index = int(step_index_str) + step_tensors = load_file(str(base_dir / step_info["file"])) if GLOBAL_TOKEN_UIDS_KEY not in step_tensors: raise RuntimeError( - f"Step file missing '{GLOBAL_TOKEN_UIDS_KEY}': {step_file}" + f"Missing tensor key '{GLOBAL_TOKEN_UIDS_KEY}' for step={step_index}" ) - global_token_uids = step_tensors[GLOBAL_TOKEN_UIDS_KEY] - routers: dict[str, StepRouterRoutes] = {} - for router_key in router_keys: - router_step_manifest = step_manifest["routers"].get(router_key) - if router_step_manifest is None: - raise RuntimeError( - f"Step manifest missing router_key='{router_key}' for step={step_index}" - ) + for router_key, call_manifest in step_info["routers"].items(): calls: dict[int, RouterCallRoute] = {} - for call_index_raw, call_manifest in router_step_manifest.items(): - call_index = int(call_index_raw) - expert_indices_key = _build_tensor_key( + for call_index_str, call_info in call_manifest.items(): + call_index = int(call_index_str) + indices_key = _build_tensor_key( router_key, call_index, "expert_indices" ) - expert_probs_key = _build_tensor_key( - router_key, call_index, "expert_probs" - ) - expert_mask_key = _build_tensor_key( - router_key, call_index, "expert_mask" - ) - routing_map_key = _build_tensor_key( - router_key, call_index, "routing_map" - ) - if expert_indices_key not in step_tensors: + mask_key = _build_tensor_key(router_key, call_index, "expert_mask") + missing_keys = [ + key + for key in (indices_key, mask_key) + if key not in step_tensors + ] + if missing_keys: raise RuntimeError( - f"Missing tensor key '{expert_indices_key}' in {step_file}" + f"Missing tensor keys {missing_keys} in {step_info['file']}" ) - if expert_probs_key not in step_tensors: - raise RuntimeError( - f"Missing tensor key '{expert_probs_key}' in {step_file}" - ) - if expert_mask_key not in step_tensors: - raise RuntimeError( - f"Missing tensor key '{expert_mask_key}' in {step_file}" - ) - routing_map = ( - step_tensors[routing_map_key] - if routing_map_key in step_tensors - else None - ) calls[call_index] = RouterCallRoute( - expert_indices=step_tensors[expert_indices_key], - expert_probs=step_tensors[expert_probs_key], - expert_mask=step_tensors[expert_mask_key], - routing_map=routing_map, - num_experts=int(call_manifest["num_experts"]), - sample_index=call_manifest.get("sample_index"), - micro_slot=call_manifest.get("micro_slot"), + expert_indices=step_tensors[indices_key], + expert_mask=step_tensors[mask_key], + num_experts=int(call_info["num_experts"]), + sample_index=call_info.get("sample_index"), + micro_slot=call_info.get("micro_slot"), ) routers[router_key] = StepRouterRoutes(calls=calls) steps[step_index] = StepRoutes( routers=routers, - global_token_uids=global_token_uids, + global_token_uids=step_tensors[GLOBAL_TOKEN_UIDS_KEY], ) return cls( - format_version=ROUTER_KEY_FORMAT_VERSION, - topology=topology, - num_steps=num_steps, - max_topk=max_topk, - router_keys=router_keys, + format_version=manifest["format_version"], + topology=ParallelTopology.model_validate(manifest["topology"]), + num_steps=int(manifest["num_steps"]), + max_topk=int(manifest["max_topk"]), + router_keys=list(manifest["router_keys"]), steps=steps, ) def to_dir(self, bundle_dir: str | Path) -> None: base_dir = Path(bundle_dir) base_dir.mkdir(parents=True, exist_ok=True) + manifest_steps: dict[str, Any] = {} - manifest_steps: dict[str, dict[str, Any]] = {} - for step_index in range(self.num_steps): - step_routes = self.steps[step_index] - step_file_name = f"step_{_normalize_step_index(step_index)}.safetensors" - step_file_path = base_dir / step_file_name + for step_index, step_routes in sorted(self.steps.items()): + step_name = f"step_{_normalize_step_index(step_index)}.safetensors" step_tensors: dict[str, torch.Tensor] = { - GLOBAL_TOKEN_UIDS_KEY: _to_tensor_cpu_contiguous( - step_routes.global_token_uids, dtype=torch.int64 - ) + GLOBAL_TOKEN_UIDS_KEY: step_routes.global_token_uids } - step_manifest_routers: dict[str, dict[str, dict[str, int]]] = {} - for router_key in self.router_keys: - router_routes = step_routes.routers[router_key] - call_manifest: dict[str, dict[str, int]] = {} + routers_manifest: dict[str, Any] = {} + for router_key, router_routes in sorted(step_routes.routers.items()): + calls_manifest: dict[str, Any] = {} for call_index, route in sorted(router_routes.calls.items()): step_tensors[ _build_tensor_key(router_key, call_index, "expert_indices") - ] = _to_tensor_cpu_contiguous( - route.expert_indices, dtype=torch.int32 - ) - step_tensors[ - _build_tensor_key(router_key, call_index, "expert_probs") - ] = _to_tensor_cpu_contiguous( - route.expert_probs, dtype=torch.float32 - ) + ] = route.expert_indices step_tensors[ _build_tensor_key(router_key, call_index, "expert_mask") - ] = _to_tensor_cpu_contiguous(route.expert_mask, dtype=torch.bool) - if route.routing_map is not None: - step_tensors[ - _build_tensor_key(router_key, call_index, "routing_map") - ] = _to_tensor_cpu_contiguous( - route.routing_map, dtype=torch.bool - ) - call_entry: dict[str, int] = {"num_experts": route.num_experts} + ] = route.expert_mask + call_info: dict[str, Any] = {"num_experts": int(route.num_experts)} if route.sample_index is not None: - call_entry["sample_index"] = int(route.sample_index) + call_info["sample_index"] = int(route.sample_index) if route.micro_slot is not None: - call_entry["micro_slot"] = int(route.micro_slot) - call_manifest[str(call_index)] = call_entry - step_manifest_routers[router_key] = call_manifest - save_file(step_tensors, str(step_file_path)) + call_info["micro_slot"] = int(route.micro_slot) + calls_manifest[str(call_index)] = call_info + routers_manifest[router_key] = calls_manifest + save_file(step_tensors, str(base_dir / step_name)) manifest_steps[str(step_index)] = { - "file": step_file_name, - "routers": step_manifest_routers, + "file": step_name, + "routers": routers_manifest, } manifest = { - "format_version": ROUTER_KEY_FORMAT_VERSION, + "format_version": self.format_version, "topology": self.topology.model_dump(mode="json"), "num_steps": self.num_steps, "max_topk": self.max_topk, @@ -466,6 +344,148 @@ def to_dir(self, bundle_dir: str | Path) -> None: json.dump(manifest, handle, indent=2, sort_keys=True) +def build_moe_routing_replay_bundle_from_packed_tensors( + *, + packed_tensors: PackedTensors, + global_grad_accumulation_sequences: int, + topology: ParallelTopology | None = None, +) -> MoeRoutingReplayBundle: + routing_replay = packed_tensors.get("moe_routing_replay") + if routing_replay is None: + raise RuntimeError("Packed tensors do not contain MoE routing replay data") + if global_grad_accumulation_sequences <= 0: + raise RuntimeError( + "global_grad_accumulation_sequences must be positive when building " + f"MoE routing replay bundles, got {global_grad_accumulation_sequences}" + ) + expert_indices = routing_replay.expert_indices + token_mask = routing_replay.token_mask + num_sequences = int(expert_indices.shape[0]) + sequence_length = int(expert_indices.shape[1]) + num_layers = int(expert_indices.shape[2]) + topk = int(expert_indices.shape[3]) + num_experts = int(routing_replay.num_experts) + + group_ids = packed_tensors["group_ids"] + parent_ids = packed_tensors["parent_ids"] + non_padding = group_ids != -1 + next_group_ids = torch.nn.functional.pad(group_ids[:, 1:], (0, 1), value=-1) + terminal_completion = ( + non_padding & (group_ids != parent_ids) & (group_ids != next_group_ids) + ) + unexpected_missing = non_padding & ~token_mask & ~terminal_completion + if bool(unexpected_missing.any().item()): + raise RuntimeError( + "Packed tensors are missing MoE routes outside terminal completion " + f"tokens: missing_rows={int(unexpected_missing.sum().item())}" + ) + + router_keys = [ + f"chunk_00.layer_{layer_index:04d}.mlp.router" + for layer_index in range(num_layers) + ] + steps: dict[int, StepRoutes] = {} + num_steps = math.ceil(num_sequences / global_grad_accumulation_sequences) + for step_index in range(num_steps): + start = step_index * global_grad_accumulation_sequences + end = start + global_grad_accumulation_sequences + routers: dict[str, StepRouterRoutes] = {} + for layer_index, router_key in enumerate(router_keys): + calls: dict[int, RouterCallRoute] = {} + for offset, sample_index in enumerate(range(start, end)): + if sample_index < num_sequences: + route_indices = expert_indices[ + sample_index, :, layer_index, : + ].clone() + missing_rows = ~token_mask[sample_index] + if bool(missing_rows.any().item()): + # Megatron Core RouterReplay replays only top-k ids and does + # not consume an expert mask. Rows without vLLM routes are + # allowed only for padding or terminal completion query + # positions, whose next-token logits are not scored. + missing_positions = torch.nonzero( + missing_rows, as_tuple=False + ).flatten() + route_indices[missing_rows] = _synthetic_replay_rows( + row_positions=missing_positions, + num_experts=num_experts, + topk=topk, + dtype=expert_indices.dtype, + seed=(sample_index + 1) * 1_000_003 + + (layer_index + 1) * 97_003, + ) + calls[offset] = RouterCallRoute( + expert_indices=route_indices, + expert_mask=torch.ones_like(route_indices, dtype=torch.bool), + num_experts=num_experts, + sample_index=sample_index, + ) + else: + route_indices = _synthetic_replay_rows( + row_positions=torch.arange(sequence_length), + num_experts=num_experts, + topk=topk, + dtype=expert_indices.dtype, + seed=(step_index + 1) * 1_000_003 + + (layer_index + 1) * 97_003 + + (offset + 1) * 9_176, + ) + calls[offset] = RouterCallRoute( + expert_indices=route_indices, + expert_mask=torch.ones_like(route_indices, dtype=torch.bool), + num_experts=num_experts, + micro_slot=offset, + ) + routers[router_key] = StepRouterRoutes(calls=calls) + steps[step_index] = StepRoutes( + routers=routers, + global_token_uids=torch.arange(sequence_length, dtype=torch.int64), + ) + return MoeRoutingReplayBundle( + topology=topology or parallel_topology_from_env(), + num_steps=num_steps, + max_topk=topk, + router_keys=router_keys, + steps=steps, + ) + + +def parallel_topology_from_env() -> ParallelTopology: + tp = _env_int("ART_MEGATRON_TENSOR_MODEL_PARALLEL_SIZE", 1) + ep = _env_int("ART_MEGATRON_EXPERT_MODEL_PARALLEL_SIZE", 1) + etp = _env_int( + "ART_MEGATRON_EXPERT_TENSOR_PARALLEL_SIZE", + _env_int("ART_MEGATRON_EXPERT_TENSOR_MODEL_PARALLEL_SIZE", 1), + ) + cp = _env_int("ART_MEGATRON_CONTEXT_PARALLEL_SIZE", 1) + pp = _env_int("ART_MEGATRON_PIPELINE_MODEL_PARALLEL_SIZE", 1) + return ParallelTopology(tp=tp, ep=ep, etp=etp, dp=1, sp=tp > 1, cp=cp, pp=pp) + + +def _env_int(name: str, default: int) -> int: + raw = os.environ.get(name) + return default if raw is None or raw == "" else int(raw) + + +def _synthetic_replay_rows( + *, + row_positions: torch.Tensor, + num_experts: int, + topk: int, + dtype: torch.dtype, + seed: int, +) -> torch.Tensor: + return torch.tensor( + [ + random.Random(seed + (int(position) + 1) * 1_299_709).sample( + range(num_experts), topk + ) + for position in row_positions.tolist() + ], + dtype=dtype, + ) + + class LocalTokenIndexer(Protocol): def build_local_token_uids( self, @@ -499,7 +519,6 @@ def build_local_token_uids( context_parallel_size: int, ) -> torch.Tensor: ps = self._ps() - local_uids = global_token_uids.to(dtype=torch.int64, device="cpu").view(1, -1) cp_size = int(ps.get_context_parallel_world_size()) @@ -541,476 +560,13 @@ def build_local_token_uids( return local_uids -_ACTIVE_ROUTING_REPLAY_CONTROLLER: MoeRoutingReplayController | None = None - - -def _active_routing_replay_controller() -> MoeRoutingReplayController | None: - return _ACTIVE_ROUTING_REPLAY_CONTROLLER - - -def _dispatcher_local_token_uids( - controller: MoeRoutingReplayController, - dispatcher: Any, - *, - num_local_tokens: int, -) -> torch.Tensor: - step_routes = controller._active_step_routes - if step_routes is None: - raise RuntimeError("Routing replay dispatcher used without an active step") - local_uids = controller.local_token_indexer.build_local_token_uids( - global_token_uids=step_routes.global_token_uids, - num_local_tokens=num_local_tokens, - sequence_parallel=bool( - getattr(getattr(dispatcher, "config", None), "sequence_parallel", False) - ), - context_parallel_size=int( - getattr(getattr(dispatcher, "config", None), "context_parallel_size", 1) - ), +def _router_replay_classes() -> tuple[type[Any], type[Any]]: + from megatron.core.transformer.moe.router_replay import ( + RouterReplay, + RouterReplayAction, ) - if int(local_uids.numel()) != num_local_tokens: - raise RuntimeError( - "Local routing replay uid count mismatch: " - f"expected={num_local_tokens}, got={int(local_uids.numel())}" - ) - sample_index = getattr(controller, "_active_sample_index", None) - uid_span = int(step_routes.global_token_uids.numel()) - if isinstance(sample_index, int) and sample_index >= 0 and uid_span > 0: - local_uids = local_uids + sample_index * uid_span - return local_uids - - -def _trace_row_uids_from_source(source: Any) -> tuple[torch.Tensor | None, int | None]: - row_token_uids = getattr(source, TRACE_ROW_TOKEN_UIDS_ATTR, None) - if not isinstance(row_token_uids, torch.Tensor): - return None, None - uid_span = getattr(source, TRACE_UID_SPAN_ATTR, None) - uid_span_int = uid_span if isinstance(uid_span, int) and uid_span > 0 else None - return row_token_uids, uid_span_int - - -def _attach_trace_row_uids( - target: Any, - *, - row_token_uids: torch.Tensor, - uid_span: int | None, -) -> None: - setattr( - target, - TRACE_ROW_TOKEN_UIDS_ATTR, - row_token_uids.detach().to(device="cpu", dtype=torch.int64).reshape(-1), - ) - setattr(target, TRACE_UID_SPAN_ATTR, uid_span) - - -@torch._dynamo.disable -def _propagate_grouped_mlp_trace_row_uids(source: Any, linear_fc2: Any) -> None: - row_token_uids, uid_span = _trace_row_uids_from_source(source) - if row_token_uids is None: - return - _attach_trace_row_uids( - linear_fc2, - row_token_uids=row_token_uids, - uid_span=uid_span, - ) - - -@torch._dynamo.disable -def _propagate_fc2_trace_row_uids( - *, - x: Any, - module: Any, - linear_fc2: Any, - lora: Any, -) -> None: - row_token_uids, uid_span = _trace_row_uids_from_source(x) - if row_token_uids is None: - row_token_uids, uid_span = _trace_row_uids_from_source(module) - if row_token_uids is None: - return - _attach_trace_row_uids( - linear_fc2, - row_token_uids=row_token_uids, - uid_span=uid_span, - ) - _attach_trace_row_uids( - lora, - row_token_uids=row_token_uids, - uid_span=uid_span, - ) - - -def _canonicalize_expert_token_order( - expert_inputs: torch.Tensor, - expert_probs: torch.Tensor, - expert_token_uids: torch.Tensor, - *, - tokens_per_expert: torch.Tensor | list[int], -) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]: - if isinstance(tokens_per_expert, torch.Tensor): - counts = [int(count) for count in tokens_per_expert.tolist()] - else: - counts = [int(count) for count in tokens_per_expert] - - if sum(counts) != int(expert_token_uids.numel()): - raise RuntimeError( - "Expert token uid count mismatch after dispatch: " - f"uids={int(expert_token_uids.numel())}, " - f"tokens_per_expert_sum={sum(counts)}" - ) - order_segments: list[torch.Tensor] = [] - cursor = 0 - for count in counts: - if count <= 1: - order_segments.append( - torch.arange(cursor, cursor + count, dtype=torch.long) - ) - cursor += count - continue - segment_uids = expert_token_uids[cursor : cursor + count].to(device="cpu") - segment_order = torch.argsort(segment_uids, stable=True) + cursor - order_segments.append(segment_order) - cursor += count - - if not order_segments: - empty = torch.empty(0, dtype=torch.long) - return expert_inputs, expert_probs, expert_token_uids, empty - - canonical_order_cpu = torch.cat(order_segments, dim=0) - inverse_order_cpu = torch.empty_like(canonical_order_cpu) - inverse_order_cpu[canonical_order_cpu] = torch.arange( - canonical_order_cpu.numel(), dtype=torch.long - ) - - canonical_order = canonical_order_cpu.to( - device=expert_inputs.device, dtype=torch.long - ) - reordered_inputs = expert_inputs.index_select(0, canonical_order) - reordered_probs = expert_probs.index_select(0, canonical_order) - reordered_uids = expert_token_uids.index_select( - 0, - canonical_order_cpu.to(device=expert_token_uids.device, dtype=torch.long), - ) - return ( - reordered_inputs, - reordered_probs, - reordered_uids, - inverse_order_cpu, - ) - - -def _canonical_trace_row_uids( - expert_token_uids: torch.Tensor, - *, - tokens_per_expert: torch.Tensor | list[int], - local_expert_indices: list[int] | tuple[int, ...] | None, - sample_uid_span: int, - num_experts: int, -) -> tuple[torch.Tensor, int]: - if isinstance(tokens_per_expert, torch.Tensor): - counts = [int(count) for count in tokens_per_expert.tolist()] - else: - counts = [int(count) for count in tokens_per_expert] - - expert_indices = ( - [int(expert_index) for expert_index in local_expert_indices] - if local_expert_indices is not None - else list(range(len(counts))) - ) - if len(expert_indices) != len(counts): - raise RuntimeError( - "Local expert index metadata mismatch: " - f"num_expert_indices={len(expert_indices)}, num_counts={len(counts)}" - ) - row_uid_span = sample_uid_span * max(int(num_experts), 1) - row_uid_chunks: list[torch.Tensor] = [] - cursor = 0 - for global_expert_id, count in zip(expert_indices, counts): - count_int = int(count) - segment = expert_token_uids[cursor : cursor + count_int].to(dtype=torch.int64) - sample_ids = torch.div(segment, sample_uid_span, rounding_mode="floor") - local_token_ids = torch.remainder(segment, sample_uid_span) - row_uid_chunks.append( - sample_ids * row_uid_span - + int(global_expert_id) * sample_uid_span - + local_token_ids - ) - cursor += count_int - if cursor != int(expert_token_uids.numel()): - raise RuntimeError( - "Canonical trace row uid construction did not consume all expert rows: " - f"consumed={cursor}, total={int(expert_token_uids.numel())}" - ) - if not row_uid_chunks: - return expert_token_uids.new_empty((0,), dtype=torch.int64), row_uid_span - return torch.cat(row_uid_chunks, dim=0).contiguous(), row_uid_span - - -@torch._dynamo.disable -def _build_dispatch_postprocess_trace( - *, - dispatcher: Any, - controller: Any, - global_input_token_uids: torch.Tensor, - expert_inputs: torch.Tensor, - expert_probs: torch.Tensor, - tokens_per_expert: torch.Tensor | list[int], -) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, int]: - expert_token_uids = global_input_token_uids - if dispatcher.num_local_experts > 1: - sorted_token_uids = sort_chunks_by_idxs( - expert_token_uids.unsqueeze(-1), - dispatcher.num_global_tokens_per_local_expert.ravel(), - dispatcher.sort_input_by_local_experts, - fused=False, - )[0] - expert_token_uids = sorted_token_uids.reshape(-1).contiguous() - - ( - expert_inputs, - expert_probs, - canonical_expert_token_uids, - inverse_order_cpu, - ) = _canonicalize_expert_token_order( - expert_inputs, - expert_probs, - expert_token_uids, - tokens_per_expert=tokens_per_expert, - ) - active_step_routes = controller._active_step_routes - if active_step_routes is None: - raise RuntimeError("MoE replay dispatcher preprocess called before set_step") - trace_row_uids, trace_uid_span = _canonical_trace_row_uids( - canonical_expert_token_uids, - tokens_per_expert=tokens_per_expert, - local_expert_indices=getattr(dispatcher, "local_expert_indices", None), - sample_uid_span=int(active_step_routes.global_token_uids.numel()), - num_experts=int(getattr(dispatcher, "num_experts", 1)), - ) - return ( - expert_inputs, - expert_probs, - inverse_order_cpu, - trace_row_uids, - trace_uid_span, - ) - - -def _patch_alltoall_dispatcher_preprocess() -> None: - try: - from megatron.core.transformer.moe.experts import TEGroupedMLP - from megatron.core.transformer.moe.token_dispatcher import ( - MoEAlltoAllTokenDispatcher, - ) - - from art.megatron.lora import MLPExpertsLinearFC2LoRA - except Exception: - return - - if hasattr(MoEAlltoAllTokenDispatcher, "_art_router_replay_preprocess_patched"): - return - - original_preprocess = MoEAlltoAllTokenDispatcher.preprocess - original_dispatch_preprocess = MoEAlltoAllTokenDispatcher.dispatch_preprocess - original_token_dispatch = MoEAlltoAllTokenDispatcher.token_dispatch - original_dispatch_postprocess = MoEAlltoAllTokenDispatcher.dispatch_postprocess - original_combine_preprocess = MoEAlltoAllTokenDispatcher.combine_preprocess - original_te_grouped_mlp_forward = TEGroupedMLP.forward - original_fc2_forward = MLPExpertsLinearFC2LoRA.forward - - def patched_preprocess( - self: Any, routing_map: torch.Tensor, *args: Any, **kwargs: Any - ): - result = original_preprocess(self, routing_map, *args, **kwargs) - if ( - not getattr(self, "drop_and_pad", False) - and getattr(self.config, "moe_expert_capacity_factor", None) is None - and not ( - getattr(self.config, "moe_router_padding_for_quantization", None) - or getattr(self.config, "moe_router_padding_for_fp8", None) - ) - ): - self.num_out_tokens = int(routing_map.sum().item()) - return result - - def patched_dispatch_preprocess( - self: Any, - hidden_states: torch.Tensor, - routing_map: torch.Tensor, - probs: torch.Tensor, - ): - result = original_dispatch_preprocess(self, hidden_states, routing_map, probs) - self._art_replay_permuted_local_token_uids = None - self._art_replay_global_input_token_uids = None - self._art_replay_expert_input_inverse_permutation = None - - controller = _active_routing_replay_controller() - if controller is None: - return result - - local_token_uids = _dispatcher_local_token_uids( - controller, - self, - num_local_tokens=int(routing_map.shape[0]), - ) - permuted_local_uids = permute( - local_token_uids.to( - device=hidden_states.device, dtype=torch.int64 - ).unsqueeze(-1), - self.routing_map, - num_out_tokens=self.num_out_tokens, - fused=False, - drop_and_pad=self.drop_and_pad, - )[0] - self._art_replay_permuted_local_token_uids = permuted_local_uids.reshape( - -1 - ).contiguous() - return result - - def patched_token_dispatch( - self: Any, - permutated_local_input_tokens: torch.Tensor, - permuted_probs: torch.Tensor, - ): - result = original_token_dispatch( - self, - permutated_local_input_tokens, - permuted_probs, - ) - controller = _active_routing_replay_controller() - permuted_local_token_uids = getattr( - self, "_art_replay_permuted_local_token_uids", None - ) - if controller is None or permuted_local_token_uids is None: - return result - - global_token_uids = permuted_local_token_uids.to( - device=permutated_local_input_tokens.device, dtype=torch.int64 - ).unsqueeze(-1) - if self.ep_size > 1: - global_token_uids = all_to_all( - self.ep_group, - global_token_uids, - self.output_splits, - self.input_splits, - ) - if self.tp_size > 1: - output_split_sizes = ( - None - if self.output_splits_tp is None - else self.output_splits_tp.tolist() - ) - global_token_uids = gather_from_sequence_parallel_region( - global_token_uids, - group=self.tp_group, - output_split_sizes=output_split_sizes, - ) - self._art_replay_global_input_token_uids = global_token_uids.reshape( - -1 - ).contiguous() - return result - - def patched_dispatch_postprocess( - self: Any, - global_input_tokens: torch.Tensor, - global_probs: torch.Tensor, - ): - expert_inputs, tokens_per_expert, expert_probs = original_dispatch_postprocess( - self, - global_input_tokens, - global_probs, - ) - controller = _active_routing_replay_controller() - global_input_token_uids = getattr( - self, "_art_replay_global_input_token_uids", None - ) - if controller is None or global_input_token_uids is None or self.drop_and_pad: - return expert_inputs, tokens_per_expert, expert_probs - - ( - expert_inputs, - expert_probs, - inverse_order_cpu, - trace_row_uids, - trace_uid_span, - ) = _build_dispatch_postprocess_trace( - dispatcher=self, - controller=controller, - global_input_token_uids=global_input_token_uids, - expert_inputs=expert_inputs, - expert_probs=expert_probs, - tokens_per_expert=tokens_per_expert, - ) - self._art_replay_expert_input_inverse_permutation = inverse_order_cpu - _attach_trace_row_uids( - expert_inputs, - row_token_uids=trace_row_uids, - uid_span=trace_uid_span, - ) - return expert_inputs, tokens_per_expert, expert_probs - - def patched_combine_preprocess(self: Any, hidden_states: torch.Tensor): - inverse_order_cpu = getattr( - self, "_art_replay_expert_input_inverse_permutation", None - ) - if inverse_order_cpu is not None and inverse_order_cpu.numel() > 0: - hidden_states = hidden_states.index_select( - 0, - inverse_order_cpu.to(device=hidden_states.device, dtype=torch.long), - ) - self._art_replay_expert_input_inverse_permutation = None - return original_combine_preprocess(self, hidden_states) - - def patched_te_grouped_mlp_forward( - self: Any, - permuted_local_hidden_states: torch.Tensor, - tokens_per_expert: torch.Tensor, - permuted_probs: torch.Tensor, - ): - _propagate_grouped_mlp_trace_row_uids( - permuted_local_hidden_states, - self.linear_fc2, - ) - return original_te_grouped_mlp_forward( - self, - permuted_local_hidden_states, - tokens_per_expert, - permuted_probs, - ) - - def patched_fc2_forward( - self: Any, - x: torch.Tensor, - tokens_per_expert: list[int] | torch.Tensor, - ) -> tuple[torch.Tensor, torch.Tensor | None]: - _propagate_fc2_trace_row_uids( - x=x, - module=self, - linear_fc2=self.linear_fc2, - lora=self.lora, - ) - return original_fc2_forward(self, x, tokens_per_expert) - - setattr(MoEAlltoAllTokenDispatcher, "preprocess", patched_preprocess) - setattr( - MoEAlltoAllTokenDispatcher, - "dispatch_preprocess", - patched_dispatch_preprocess, - ) - setattr(MoEAlltoAllTokenDispatcher, "token_dispatch", patched_token_dispatch) - setattr( - MoEAlltoAllTokenDispatcher, - "dispatch_postprocess", - patched_dispatch_postprocess, - ) - setattr( - MoEAlltoAllTokenDispatcher, - "combine_preprocess", - patched_combine_preprocess, - ) - setattr(TEGroupedMLP, "forward", patched_te_grouped_mlp_forward) - setattr(MLPExpertsLinearFC2LoRA, "forward", patched_fc2_forward) - setattr(MoEAlltoAllTokenDispatcher, "_art_router_replay_preprocess_patched", True) + return RouterReplay, RouterReplayAction class MoeRoutingReplayController: @@ -1021,6 +577,7 @@ def __init__( strict: bool, local_token_indexer: LocalTokenIndexer | None = None, allow_recompute_reuse: bool = True, + device: torch.device | str | None = None, ) -> None: self.bundle = bundle self.strict = strict @@ -1028,31 +585,37 @@ def __init__( self.local_token_indexer = ( local_token_indexer or TopologyAwareLocalTokenIndexer() ) + self._device = torch.device(device) if device is not None else None self._active_step_index: int | None = None self._active_sample_index: int | None = None self._active_step_routes: StepRoutes | None = None + self._active_micro_order: int | None = None self._router_call_cursors: dict[str, int] = {} self._router_call_sequences: dict[str, list[int]] = {} self._router_last_call_indices: dict[str, int] = {} self._router_last_call_keys: dict[str, tuple[str, int] | None] = {} self._router_reuse_counts: dict[str, int] = {} - self._global_uid_to_row_index: dict[int, int] = {} self._local_router_keys: set[str] = set() - self._active_micro_order: int | None = None + self._router_bindings: dict[str, dict[str, Any]] = {} + self._preloaded_targets: dict[tuple[str, int], torch.Tensor] = {} + self._target_buffers: dict[str, torch.Tensor] = {} - self._patched_router_modules: list[dict[str, Any]] = [] + def _target_device(self) -> torch.device: + if self._device is not None: + return self._device + if torch.cuda.is_available(): + return torch.device("cuda", torch.cuda.current_device()) + return torch.device("cpu") def install_router_patches(self, model_chunks: list[Any]) -> None: - if self._patched_router_modules: + if self._router_bindings: return - _patch_alltoall_dispatcher_preprocess() - for chunk_index, chunk in enumerate(model_chunks): for module_name, module in chunk.named_modules(): - if ROUTER_NAME_TOKEN not in module_name: - continue - if not hasattr(module, "routing"): + if ROUTER_NAME_TOKEN not in module_name or not hasattr( + module, "routing" + ): continue router_key = build_router_key_from_module_name( chunk_index=chunk_index, @@ -1063,89 +626,81 @@ def install_router_patches(self, model_chunks: list[Any]) -> None: "Router key from model is missing in replay bundle: " f"router_key='{router_key}'" ) - - original_routing = module.routing - if getattr(module, "_art_router_replay_patched", False): - continue - - sequence_parallel = bool( - getattr(getattr(module, "config", None), "sequence_parallel", False) - ) - context_parallel_size = int( - getattr(getattr(module, "config", None), "context_parallel_size", 1) - ) - - def routing_wrapper( - _module: Any, - logits: torch.Tensor, - *args: Any, - _router_key: str = router_key, - _sequence_parallel: bool = sequence_parallel, - _context_parallel_size: int = context_parallel_size, - **kwargs: Any, - ) -> tuple[torch.Tensor, torch.Tensor]: - live_probs, live_routing_map = original_routing( - logits, *args, **kwargs - ) - replay_probs, replay_routing_map = self.get_route_for_router( - router_key=_router_key, - logits=live_probs, - sequence_parallel=_sequence_parallel, - context_parallel_size=_context_parallel_size, + config = getattr(module, "config", None) + if bool(getattr(config, "moe_router_fusion", False)): + raise RuntimeError( + "MoE routing replay requires moe_router_fusion=False because " + "Megatron Core fused routing bypasses RouterReplay: " + f"router_key='{router_key}'" ) - # same result, but autograd goes through - probs = ( - live_probs - + ( - replay_probs.to( - device=live_probs.device, - dtype=live_probs.dtype, - ) - - live_probs - ).detach() + router_replay = getattr(module, "router_replay", None) + if router_replay is None: + raise RuntimeError( + "MoE routing replay requires provider.moe_enable_routing_replay=True " + "before model construction: " + f"router_key='{router_key}'" ) - routing_map = replay_routing_map.to( - device=live_routing_map.device, - dtype=live_routing_map.dtype, + if getattr(router_replay, "_art_routing_replay_patched", False): + raise RuntimeError( + "RouterReplay instance is already patched: " + f"router_key='{router_key}'" ) - return probs, routing_map - module.routing = types.MethodType(routing_wrapper, module) - module._art_router_replay_patched = True + sequence_parallel = bool(getattr(config, "sequence_parallel", False)) + context_parallel_size = int(getattr(config, "context_parallel_size", 1)) + topk = int(getattr(module, "topk")) + self._router_bindings[router_key] = { + "module": module, + "router_replay": router_replay, + "sequence_parallel": sequence_parallel, + "context_parallel_size": context_parallel_size, + "topk": topk, + } self._local_router_keys.add(router_key) - self._patched_router_modules.append( - { - "module": module, - "router_key": router_key, - "original_routing": original_routing, - } - ) def remove_router_patches(self) -> None: - global _ACTIVE_ROUTING_REPLAY_CONTROLLER - for item in self._patched_router_modules: - module = item["module"] - module.routing = item["original_routing"] - if hasattr(module, "_art_router_replay_patched"): - delattr(module, "_art_router_replay_patched") - self._patched_router_modules.clear() + self._router_bindings.clear() self._local_router_keys.clear() - if _ACTIVE_ROUTING_REPLAY_CONTROLLER is self: - _ACTIVE_ROUTING_REPLAY_CONTROLLER = None + self._target_buffers.clear() + self._clear_native_router_replay_state() + self._reset_step_state() def begin_micro(self, sample_index: int | None, micro_order: int) -> None: self._active_sample_index = sample_index self._active_micro_order = micro_order + for router_key in sorted(self._local_router_keys): + call_indices = self._active_micro_call_indices(router_key) + if len(call_indices) != 1: + raise RuntimeError( + "Routing replay expected exactly one router call per local " + f"microbatch for router='{router_key}', got {call_indices}" + ) + call_index = self._next_route_call_index(router_key) + if call_index != call_indices[0]: + raise RuntimeError( + "Routing replay cursor mismatch while preparing native replay: " + f"router='{router_key}', expected={call_indices[0]}, " + f"actual={call_index}" + ) + target = self._target_for_router_call( + router_key=router_key, + call_index=call_index, + ) + router_replay = self._router_bindings[router_key]["router_replay"] + router_replay.set_target_indices( + self._copy_into_stable_target_buffer(router_key, target) + ) + router_replay.set_router_replay_action( + _router_replay_classes()[1].REPLAY_FORWARD + ) def set_step( self, *, step_index: int, - sample_index: int | list[int | None], + sample_index: int | list[int | None] | None, global_grad_accumulation_sequences: int | None = None, ) -> None: - global _ACTIVE_ROUTING_REPLAY_CONTROLLER - if step_index not in self.bundle.steps: raise RuntimeError( f"Replay bundle missing step_index={step_index}. " @@ -1153,71 +708,140 @@ def set_step( ) step_routes = self.bundle.steps[step_index] self._active_step_index = step_index - if isinstance(sample_index, list): - self._active_sample_index = next( - (index for index in sample_index if index is not None), - None, - ) - else: - self._active_sample_index = sample_index + self._active_sample_index = ( + next((index for index in sample_index if index is not None), None) + if isinstance(sample_index, list) + else sample_index + ) self._active_micro_order = None self._active_step_routes = step_routes - for local_router_key in sorted(self._local_router_keys): - if local_router_key not in step_routes.routers: + self._preloaded_targets = {} + self._router_call_cursors = {} + self._router_call_sequences = {} + self._router_last_call_indices = {} + self._router_last_call_keys = {} + self._router_reuse_counts = {} + + for router_key in sorted(self._local_router_keys): + if router_key not in step_routes.routers: raise RuntimeError( "Replay bundle step is missing local router key: " - f"step={step_index}, router='{local_router_key}'" + f"step={step_index}, router='{router_key}'" ) + router_calls = step_routes.routers[router_key].calls + binding_topk = int(self._router_bindings[router_key]["topk"]) + for call_index, route in router_calls.items(): + if not bool(route.expert_mask.all().item()): + raise RuntimeError( + "masked slots are unsupported by Megatron native MoE routing " + f"replay: step={step_index}, router='{router_key}', " + f"call={call_index}" + ) + if route.max_topk != binding_topk: + raise RuntimeError( + "Replay route topk does not match Megatron router topk: " + f"step={step_index}, router='{router_key}', call={call_index}, " + f"route_topk={route.max_topk}, router_topk={binding_topk}" + ) + self._router_call_cursors[router_key] = 0 + self._router_call_sequences[router_key] = self._build_call_sequence( + router_key=router_key, + sample_index=sample_index, + global_grad_accumulation_sequences=global_grad_accumulation_sequences, + ) + for call_index in self._router_call_sequences[router_key]: + self._preload_target(router_key, call_index) + RouterReplay, RouterReplayAction = _router_replay_classes() + RouterReplay.clear_global_indices() + RouterReplay.set_global_router_replay_action(RouterReplayAction.REPLAY_FORWARD) + + def finalize_step(self) -> None: + if self._active_step_routes is None: + raise RuntimeError("finalize_step called before set_step") + for router_key in sorted(self._local_router_keys): + consumed = self._router_call_cursors.get(router_key, 0) + call_sequence = self._router_call_sequences.get(router_key) + if call_sequence is None: + raise RuntimeError( + "Routing replay call sequence missing for router key: " + f"step={self._active_step_index}, router='{router_key}'" + ) + if consumed != len(call_sequence): + raise RuntimeError( + "Routing replay step consumption mismatch: " + f"step={self._active_step_index}, router='{router_key}', " + f"consumed={consumed}, expected={len(call_sequence)}" + ) + if self._router_reuse_counts: + logger.info( + "Routing replay reused routes for recompute: step=%s counts=%s", + self._active_step_index, + dict(sorted(self._router_reuse_counts.items())), + ) + self._clear_native_router_replay_state() + self._reset_step_state() + + def _reset_step_state(self) -> None: + self._active_step_index = None + self._active_sample_index = None + self._active_step_routes = None + self._active_micro_order = None self._router_call_cursors = {} self._router_call_sequences = {} self._router_last_call_indices = {} self._router_last_call_keys = {} self._router_reuse_counts = {} - local_call_keys = self._build_local_call_keys( + self._preloaded_targets = {} + + @staticmethod + def _clear_native_router_replay_state() -> None: + RouterReplay, _RouterReplayAction = _router_replay_classes() + RouterReplay.clear_global_indices() + RouterReplay.clear_global_router_replay_action() + + def _build_call_sequence( + self, + *, + router_key: str, + sample_index: int | list[int | None] | None, + global_grad_accumulation_sequences: int | None, + ) -> list[int]: + if self._active_step_routes is None or self._active_step_index is None: + raise RuntimeError("Routing replay step is not active") + router_calls = self._active_step_routes.routers[router_key].calls + if all( + self._router_call_key(route) is not None for route in router_calls.values() + ): + calls_by_key: dict[tuple[str, int], list[int]] = defaultdict(list) + for call_index, route in sorted(router_calls.items()): + call_key = self._router_call_key(route) + assert call_key is not None + calls_by_key[call_key].append(call_index) + call_sequence: list[int] = [] + for call_key in self._build_local_call_keys(sample_index=sample_index): + if call_key is None: + continue + matching_call_indices = calls_by_key.get(call_key) + if not matching_call_indices: + raise RuntimeError( + "Replay router call sequence is missing local micro metadata: " + f"step={self._active_step_index}, router='{router_key}', " + f"call_key={call_key}" + ) + call_sequence.extend(matching_call_indices) + return call_sequence + return self._legacy_router_call_sequence( + step_index=self._active_step_index, + router_key=router_key, sample_index=sample_index, + global_grad_accumulation_sequences=global_grad_accumulation_sequences, + total_calls=len(router_calls), ) - for router_key in sorted(self._local_router_keys): - router_calls = step_routes.routers[router_key].calls - if all( - self._router_call_key(route) is not None - for route in router_calls.values() - ): - calls_by_key: dict[tuple[str, int], list[int]] = defaultdict(list) - for call_index, route in sorted(router_calls.items()): - call_key = self._router_call_key(route) - assert call_key is not None - calls_by_key[call_key].append(call_index) - call_sequence = [] - for call_key in local_call_keys: - if call_key is None: - continue - matching_call_indices = calls_by_key.get(call_key) - if not matching_call_indices: - raise RuntimeError( - "Replay router call sequence is missing local micro metadata: " - f"step={step_index}, router='{router_key}', call_key={call_key}" - ) - call_sequence.extend(matching_call_indices) - else: - call_sequence = self._legacy_router_call_sequence( - step_index=step_index, - router_key=router_key, - sample_index=sample_index, - global_grad_accumulation_sequences=global_grad_accumulation_sequences, - total_calls=len(router_calls), - ) - self._router_call_cursors[router_key] = 0 - self._router_call_sequences[router_key] = call_sequence - self._global_uid_to_row_index = { - int(uid.item()): row_index - for row_index, uid in enumerate(step_routes.global_token_uids) - } - _ACTIVE_ROUTING_REPLAY_CONTROLLER = self def _build_local_call_keys( self, *, - sample_index: int | list[int | None], + sample_index: int | list[int | None] | None, ) -> list[tuple[str, int] | None]: if not isinstance(sample_index, list): if sample_index is None: @@ -1241,17 +865,13 @@ def _sample_or_dummy_call_key( return ("sample", int(global_sample_index)) return self._dummy_micro_call_key(local_micro_index=local_micro_index) - def _dummy_micro_call_key( - self, - *, - local_micro_index: int, - ) -> tuple[str, int]: + @staticmethod + def _dummy_micro_call_key(*, local_micro_index: int) -> tuple[str, int]: from megatron.core import parallel_state as ps dp_rank = int(ps.get_data_parallel_rank()) dp_world_size = int(ps.get_data_parallel_world_size()) - micro_slot = local_micro_index * dp_world_size + dp_rank - return ("dummy_micro_slot", micro_slot) + return ("dummy_micro_slot", local_micro_index * dp_world_size + dp_rank) @staticmethod def _router_call_key(route: RouterCallRoute) -> tuple[str, int] | None: @@ -1262,12 +882,11 @@ def _router_call_key(route: RouterCallRoute) -> tuple[str, int] | None: return None def _active_router_call_key(self) -> tuple[str, int] | None: - active_micro_order = self._active_micro_order - if active_micro_order is None: + if self._active_micro_order is None: return None return self._sample_or_dummy_call_key( global_sample_index=self._active_sample_index, - local_micro_index=active_micro_order, + local_micro_index=self._active_micro_order, ) @staticmethod @@ -1275,10 +894,18 @@ def _legacy_router_call_sequence( *, step_index: int, router_key: str, - sample_index: int | list[int | None], + sample_index: int | list[int | None] | None, global_grad_accumulation_sequences: int | None, total_calls: int, ) -> list[int]: + if not isinstance(sample_index, list) and sample_index is None: + if total_calls != 1: + raise RuntimeError( + "Replay router call sequence lacks sample metadata and has " + f"{total_calls} calls for router='{router_key}', step={step_index}" + ) + return [0] + step_sample_count = global_grad_accumulation_sequences if step_sample_count is None: if isinstance(sample_index, list): @@ -1290,8 +917,8 @@ def _legacy_router_call_sequence( if step_sample_count <= 0 or total_calls % step_sample_count != 0: raise RuntimeError( "Replay router call count is not divisible by step sample count: " - f"step={step_index}, router='{router_key}', " - f"total_calls={total_calls}, step_sample_count={step_sample_count}" + f"step={step_index}, router='{router_key}', total_calls={total_calls}, " + f"step_sample_count={step_sample_count}" ) calls_per_sample = total_calls // step_sample_count step_base_sample_index = step_index * step_sample_count @@ -1309,93 +936,71 @@ def _legacy_router_call_sequence( f"step_base_sample_index={step_base_sample_index}, " f"step_sample_count={step_sample_count}" ) - call_start = sample_offset * calls_per_sample - call_sequence.extend(range(call_start, call_start + calls_per_sample)) + start = sample_offset * calls_per_sample + call_sequence.extend(range(start, start + calls_per_sample)) return call_sequence sample_offset = int(sample_index) - step_base_sample_index if sample_offset < 0 or sample_offset >= step_sample_count: raise RuntimeError( "Replay router call index is outside the step-local range: " - f"step={step_index}, router='{router_key}', " - f"sample_index={sample_index}, " + f"step={step_index}, router='{router_key}', sample_index={sample_index}, " f"step_sample_count={step_sample_count}" ) - call_start = sample_offset * calls_per_sample - return list(range(call_start, call_start + calls_per_sample)) + start = sample_offset * calls_per_sample + return list(range(start, start + calls_per_sample)) - def finalize_step(self) -> None: - global _ACTIVE_ROUTING_REPLAY_CONTROLLER + def _active_micro_call_indices(self, router_key: str) -> list[int]: if self._active_step_routes is None: - raise RuntimeError("finalize_step called before set_step") - for router_key in sorted(self._local_router_keys): - consumed = self._router_call_cursors.get(router_key, 0) - call_sequence = self._router_call_sequences.get(router_key) - if call_sequence is None: - raise RuntimeError( - "Routing replay call sequence missing for router key: " - f"step={self._active_step_index}, router='{router_key}'" - ) - if consumed != len(call_sequence): - raise RuntimeError( - "Routing replay step consumption mismatch: " - f"step={self._active_step_index}, router='{router_key}', " - f"consumed={consumed}, expected={len(call_sequence)}" - ) - if self._router_reuse_counts: - logger.info( - "Routing replay reused routes for recompute: step=%s counts=%s", - self._active_step_index, - dict(sorted(self._router_reuse_counts.items())), - ) - self._active_step_index = None - self._active_sample_index = None - self._active_step_routes = None - self._router_call_cursors = {} - self._router_call_sequences = {} - self._router_last_call_indices = {} - self._router_last_call_keys = {} - self._router_reuse_counts = {} - self._global_uid_to_row_index = {} - self._active_micro_order = None - if _ACTIVE_ROUTING_REPLAY_CONTROLLER is self: - _ACTIVE_ROUTING_REPLAY_CONTROLLER = None - - def get_route_for_router( - self, - *, - router_key: str, - logits: torch.Tensor, - sequence_parallel: bool, - context_parallel_size: int, - ) -> tuple[torch.Tensor, torch.Tensor]: - step_routes = self._active_step_routes - if step_routes is None: - raise RuntimeError( - "Routing replay get_route_for_router called before set_step" - ) - call_cursor = self._router_call_cursors.get(router_key, 0) + raise RuntimeError("Routing replay begin_micro called before set_step") + router_calls = self._active_step_routes.routers[router_key].calls + call_sequence = self._router_call_sequences[router_key] + cursor = self._router_call_cursors.get(router_key, 0) + active_call_key = self._active_router_call_key() + if cursor >= len(call_sequence): + last_index = self._router_last_call_indices.get(router_key) + last_key = self._router_last_call_keys.get(router_key) + if ( + active_call_key is not None + and last_index is not None + and last_key == active_call_key + ): + return [last_index] + return [] + first_index = call_sequence[cursor] + if active_call_key is None: + return [first_index] + indices: list[int] = [] + for call_index in call_sequence[cursor:]: + if self._router_call_key(router_calls[call_index]) != active_call_key: + break + indices.append(call_index) + return indices + + def _next_route_call_index(self, router_key: str) -> int: + if self._active_step_routes is None: + raise RuntimeError("Routing replay router call occurred before set_step") + router_calls = self._active_step_routes.routers[router_key].calls call_sequence = self._router_call_sequences.get(router_key) if call_sequence is None: raise RuntimeError( "Routing replay call sequence missing for router key: " f"step={self._active_step_index}, router='{router_key}'" ) - router_calls = step_routes.routers[router_key].calls + cursor = self._router_call_cursors.get(router_key, 0) active_call_key = self._active_router_call_key() - last_call_index = self._router_last_call_indices.get(router_key) - last_call_key = self._router_last_call_keys.get(router_key) - next_call_key = None - if call_cursor < len(call_sequence): - next_call_key = self._router_call_key( - router_calls[call_sequence[call_cursor]] - ) - + last_index = self._router_last_call_indices.get(router_key) + last_key = self._router_last_call_keys.get(router_key) + next_key = ( + self._router_call_key(router_calls[call_sequence[cursor]]) + if cursor < len(call_sequence) + else None + ) if ( active_call_key is not None - and last_call_index is not None - and last_call_key == active_call_key - and next_call_key != active_call_key + and last_index is not None + and last_key == active_call_key + and next_key != active_call_key ): if not self.allow_recompute_reuse: raise RuntimeError( @@ -1403,197 +1008,105 @@ def get_route_for_router( f"step={self._active_step_index}, router='{router_key}', " f"call_key={active_call_key}" ) - route = router_calls[last_call_index] self._router_reuse_counts[router_key] = ( self._router_reuse_counts.get(router_key, 0) + 1 ) - else: - if call_cursor >= len(call_sequence): - raise RuntimeError( - "Routing replay call cursor exceeded local call sequence: " - f"step={self._active_step_index}, router='{router_key}', " - f"call_cursor={call_cursor}, sequence_length={len(call_sequence)}" - ) - route_call_index = call_sequence[call_cursor] - route = router_calls[route_call_index] - self._router_call_cursors[router_key] = call_cursor + 1 - self._router_last_call_indices[router_key] = route_call_index - self._router_last_call_keys[router_key] = self._router_call_key(route) - - num_local_tokens = int(logits.shape[0]) - num_experts = int(logits.shape[1]) - - local_uids = self.local_token_indexer.build_local_token_uids( - global_token_uids=step_routes.global_token_uids, - num_local_tokens=num_local_tokens, - sequence_parallel=sequence_parallel, - context_parallel_size=context_parallel_size, - ) - row_index_tensor = torch.tensor( - [self._global_uid_to_row_index[int(uid)] for uid in local_uids.tolist()], - dtype=torch.int64, - ) - - local_indices = route.expert_indices.index_select(0, row_index_tensor) - local_probs = route.expert_probs.index_select(0, row_index_tensor) - local_mask = route.expert_mask.index_select(0, row_index_tensor) - - probs = torch.zeros( - (num_local_tokens, num_experts), - dtype=logits.dtype, - device=logits.device, - ) - routing_map = torch.zeros( - (num_local_tokens, num_experts), - dtype=torch.bool, - device=logits.device, - ) - - if local_indices.numel() > 0: - indices_device = local_indices.to(device=logits.device, dtype=torch.long) - probs_device = local_probs.to(device=logits.device, dtype=logits.dtype) - mask_device = local_mask.to(device=logits.device, dtype=torch.bool) - row_index_device = ( - torch.arange(num_local_tokens, device=logits.device) - .unsqueeze(1) - .expand_as(indices_device) + return last_index + if cursor >= len(call_sequence): + raise RuntimeError( + "Routing replay call cursor exceeded local call sequence: " + f"step={self._active_step_index}, router='{router_key}', " + f"cursor={cursor}, sequence_length={len(call_sequence)}" ) - - selected_rows = row_index_device[mask_device] - selected_cols = indices_device[mask_device] - selected_probs = probs_device[mask_device] - - if selected_rows.numel() > 0: - probs[selected_rows, selected_cols] = selected_probs - routing_map[selected_rows, selected_cols] = True - - return probs, routing_map - - -def _compact_route_from_dense( - probs_2d: torch.Tensor, - routing_map_2d: torch.Tensor, -) -> RouterCallRoute: - num_tokens, num_experts = probs_2d.shape - if num_tokens == 0: - return RouterCallRoute( - expert_indices=torch.zeros((0, 0), dtype=torch.int32), - expert_probs=torch.zeros((0, 0), dtype=torch.float32), - expert_mask=torch.zeros((0, 0), dtype=torch.bool), - num_experts=num_experts, - ) - - max_topk = int(routing_map_2d.sum(dim=1).max().item()) - expert_indices = torch.zeros((num_tokens, max_topk), dtype=torch.int32) - expert_probs = torch.zeros((num_tokens, max_topk), dtype=torch.float32) - expert_mask = torch.zeros((num_tokens, max_topk), dtype=torch.bool) - for token_index in range(num_tokens): - expert_ids = torch.nonzero( - routing_map_2d[token_index], as_tuple=False - ).flatten() - slot_count = int(expert_ids.numel()) - if slot_count == 0: - continue - expert_indices[token_index, :slot_count] = expert_ids.to(torch.int32) - expert_probs[token_index, :slot_count] = probs_2d[token_index, expert_ids].to( - torch.float32 + call_index = call_sequence[cursor] + self._router_call_cursors[router_key] = cursor + 1 + self._router_last_call_indices[router_key] = call_index + self._router_last_call_keys[router_key] = self._router_call_key( + router_calls[call_index] ) - expert_mask[token_index, :slot_count] = True - - return RouterCallRoute( - expert_indices=expert_indices, - expert_probs=expert_probs, - expert_mask=expert_mask, - num_experts=num_experts, - ) - - -def build_bundle_from_forward_trace_dir( - *, - traces_dir: str | Path, - num_steps: int, - topology: ParallelTopology, -) -> MoeRoutingReplayBundle: - """Build a replay bundle from saved forward traces for the correctness harness. - - This helper is intended for testing/oracle routing replay workflows and is not - part of inference routing capture/export. - """ - trace_dir = Path(traces_dir) - steps: dict[int, StepRoutes] = {} - router_keys_union: set[str] = set() - max_topk = 0 + return call_index - for step_index in range(num_steps): - trace_path = trace_dir / f"forward_trace_step_{step_index:03d}.pt" - if not trace_path.exists(): - raise FileNotFoundError( - f"Missing forward trace for step={step_index}: {trace_path}" - ) - step_trace: dict[str, list[dict[str, Any]]] = torch.load( - trace_path, map_location="cpu", weights_only=False + def _preload_target(self, router_key: str, call_index: int) -> None: + key = (router_key, call_index) + if key in self._preloaded_targets: + return + if self._active_step_routes is None: + raise RuntimeError("Routing replay target preload called before set_step") + route = self._active_step_routes.routers[router_key].calls[call_index] + binding = self._router_bindings[router_key] + target = route.expert_indices.to( + device=self._target_device(), + dtype=torch.long, + non_blocking=True, ) + target = self._slice_target_for_local_rank( + target, + sequence_parallel=bool(binding["sequence_parallel"]), + context_parallel_size=int(binding["context_parallel_size"]), + ).contiguous() + self._preloaded_targets[key] = target - step_routers: dict[str, StepRouterRoutes] = {} - step_global_tokens: int | None = None - for module_name in sorted(step_trace.keys()): - if ROUTER_NAME_TOKEN not in module_name: - continue - router_key = build_router_key_from_trace_name(module_name) - router_calls: dict[int, RouterCallRoute] = {} - for call_index, call_entry in enumerate(step_trace[module_name]): - output = call_entry.get("output") - probs_2d, routing_map_2d = _extract_router_output_tensors(output) - compact_route = _compact_route_from_dense(probs_2d, routing_map_2d) - sample_index, micro_slot = _trace_call_route_metadata(call_entry) - compact_route.sample_index = sample_index - compact_route.micro_slot = micro_slot - router_calls[call_index] = compact_route - max_topk = max(max_topk, compact_route.max_topk) - token_count = compact_route.num_global_tokens - if step_global_tokens is None: - step_global_tokens = token_count - elif step_global_tokens != token_count: - raise RuntimeError( - "Inconsistent token count across routers within step: " - f"step={step_index}, expected={step_global_tokens}, got={token_count}, " - f"router='{router_key}', call={call_index}" - ) - - if not router_calls: - raise RuntimeError( - f"Router trace has no calls for module '{module_name}' at step={step_index}" - ) - step_routers[router_key] = StepRouterRoutes(calls=router_calls) - router_keys_union.add(router_key) - - if not step_routers: + def _target_for_router_call( + self, + *, + router_key: str, + call_index: int, + ) -> torch.Tensor: + key = (router_key, call_index) + if key not in self._preloaded_targets: raise RuntimeError( - f"No router traces found for step={step_index} in {trace_path}" + "Routing replay target was not preloaded before router execution: " + f"step={self._active_step_index}, router='{router_key}', " + f"call={call_index}. begin_micro must be called before forward." ) - if step_global_tokens is None: + target = self._preloaded_targets[key] + topk = int(self._router_bindings[router_key]["topk"]) + if int(target.shape[1]) != topk: raise RuntimeError( - f"Could not infer token count for step={step_index} from router traces" + "Routing replay target topk mismatch at router call: " + f"router='{router_key}', call={call_index}, " + f"target_topk={int(target.shape[1])}, router_topk={topk}" ) - global_token_uids = torch.arange(step_global_tokens, dtype=torch.int64) - steps[step_index] = StepRoutes( - routers=step_routers, - global_token_uids=global_token_uids, - ) + return target - router_keys = sorted(router_keys_union) - for step_index, step_routes in steps.items(): - if set(step_routes.routers.keys()) != set(router_keys): - raise RuntimeError( - f"Step {step_index} router keys differ from global set: " - f"step_keys={sorted(step_routes.routers.keys())}, router_keys={router_keys}" - ) + def _copy_into_stable_target_buffer( + self, router_key: str, target: torch.Tensor + ) -> torch.Tensor: + buffer = self._target_buffers.get(router_key) + if ( + buffer is None + or buffer.shape != target.shape + or buffer.device != target.device + ): + buffer = torch.empty_like(target) + self._target_buffers[router_key] = buffer + buffer.copy_(target, non_blocking=True) + return buffer - return MoeRoutingReplayBundle( - format_version=ROUTER_KEY_FORMAT_VERSION, - topology=topology, - num_steps=num_steps, - max_topk=max_topk, - router_keys=router_keys, - steps=steps, - ) + @staticmethod + def _slice_target_for_local_rank( + target: torch.Tensor, + *, + sequence_parallel: bool, + context_parallel_size: int, + ) -> torch.Tensor: + candidate = target + if context_parallel_size > 1: + from megatron.core import parallel_state as ps + from megatron.core.utils import get_batch_on_this_cp_rank + + if int(ps.get_context_parallel_world_size()) > 1: + candidate = get_batch_on_this_cp_rank( + {"tokens": candidate.view(1, *candidate.shape)} + )["tokens"].reshape(-1, int(candidate.shape[1])) + if sequence_parallel: + from megatron.core import parallel_state as ps + + tp_size = int(ps.get_tensor_model_parallel_world_size()) + tp_rank = int(ps.get_tensor_model_parallel_rank()) if tp_size > 1 else 0 + total_rows = int(candidate.shape[0]) + if tp_size > 1 and total_rows % tp_size == 0: + rows_per_rank = total_rows // tp_size + start = tp_rank * rows_per_rank + candidate = candidate[start : start + rows_per_rank] + return candidate diff --git a/src/art/megatron/runtime/backend.py b/src/art/megatron/runtime/backend.py index 115fb3c1b..2db7a5599 100644 --- a/src/art/megatron/runtime/backend.py +++ b/src/art/megatron/runtime/backend.py @@ -12,8 +12,13 @@ def __init__( *, in_process: bool = False, path: str | None = None, + enable_expert_replay: bool = True, ) -> None: - super().__init__(in_process=in_process, path=path) + super().__init__( + in_process=in_process, + path=path, + enable_expert_replay=enable_expert_replay, + ) self._requires_explicit_packed_sequence_length = True self._packed_sequence_length_requires_chunk_alignment = False self._supports_result_packing = True @@ -34,6 +39,7 @@ async def _get_service(self, model: TrainableModel) -> ModelService: base_model=model.base_model, config=config, output_dir=get_model_dir(model=model, art_path=self._path), + enable_expert_replay=self._enable_expert_replay, ) if not self._in_process: self._services[model.name] = move_to_child_process( diff --git a/src/art/megatron/runtime/bridge_runtime.py b/src/art/megatron/runtime/bridge_runtime.py index 7e801691d..4412278f0 100644 --- a/src/art/megatron/runtime/bridge_runtime.py +++ b/src/art/megatron/runtime/bridge_runtime.py @@ -44,6 +44,13 @@ def _needs_local_hf_prefetch(task: Any) -> bool: if task is None or task.megatron_module is None: return False mapping = task.mapping + # ART Qwen3.5 expert mappings slice the full HF expert tensor before + # delegating to the inner TP mapping, so every ETP rank needs the source. + if type(mapping).__name__ in { + "_ArtExpertMLPGateUpProjMapping", + "_ArtExpertMLPDownProjMapping", + }: + return True tp_size = int(getattr(mapping, "tp_size", 1)) if tp_size <= 1: return True diff --git a/src/art/megatron/service.py b/src/art/megatron/service.py index 478125c82..8c12a96dd 100644 --- a/src/art/megatron/service.py +++ b/src/art/megatron/service.py @@ -38,6 +38,10 @@ ) from .lora import LORA_ALPHA, default_lora_rank_for_handler from .model_support.lora_disk import normalize_lora_checkpoint_to_vllm +from .model_support.registry import ( + UnsupportedModelArchitectureError, + model_uses_expert_parallel, +) from .runtime.client import ( create_megatron_job_paths, stream_megatron_job, @@ -167,6 +171,7 @@ class MegatronService: base_model: str config: dev.InternalModelConfig output_dir: str + enable_expert_replay: bool = True _is_sleeping: bool = False _latest_step: int = 0 _megatron_process: asyncio.subprocess.Process | None = None @@ -227,6 +232,48 @@ def _megatron_random_state(self) -> int | None: def _allow_unvalidated_arch(self) -> bool: return bool(self.config.get("allow_unvalidated_arch", False)) + def _model_uses_expert_replay(self) -> bool: + if not self.enable_expert_replay: + return False + try: + return model_uses_expert_parallel( + self.base_model, + allow_unvalidated_arch=self._allow_unvalidated_arch, + ) + except UnsupportedModelArchitectureError: + return False + + def _trainer_gpu_count(self) -> int: + if self.is_dedicated: + return len(self.config["trainer_gpu_ids"]) + return max(int(torch.cuda.device_count()), 1) + + @staticmethod + def _parallel_env_int(name: str, default: int) -> int: + raw = os.environ.get(name) + return default if raw is None or raw == "" else int(raw) + + def _data_parallel_world_size(self) -> int: + num_gpus = self._trainer_gpu_count() + tp = self._parallel_env_int("ART_MEGATRON_TENSOR_MODEL_PARALLEL_SIZE", num_gpus) + cp = self._parallel_env_int("ART_MEGATRON_CONTEXT_PARALLEL_SIZE", 1) + pp = self._parallel_env_int("ART_MEGATRON_PIPELINE_MODEL_PARALLEL_SIZE", 1) + denominator = max(tp * cp * pp, 1) + if num_gpus % denominator != 0: + raise RuntimeError( + "Cannot resolve Megatron data-parallel world size from trainer " + f"GPUs/topology: num_gpus={num_gpus}, tp={tp}, cp={cp}, pp={pp}" + ) + return max(num_gpus // denominator, 1) + + async def resolve_global_grad_accumulation_sequences( + self, + config: types.TrainConfig, + ) -> int: + if config.grad_accumulation_sequences is not None: + return int(config.grad_accumulation_sequences) + return self._data_parallel_world_size() + def _megatron_runtime_paths(self) -> tuple[str, str, str]: runtime_dir = Path(self.output_dir) / "megatron_runtime" jobs_dir = runtime_dir / "jobs" @@ -672,6 +719,8 @@ async def _ensure_megatron_running(self) -> None: env["MODEL_IDENTIFIER"] = self.base_model if self._allow_unvalidated_arch: env["ART_MEGATRON_ALLOW_UNVALIDATED_ARCH"] = "1" + if self._model_uses_expert_replay(): + env["ART_MEGATRON_ENABLE_MOE_ROUTING_REPLAY"] = "1" env["ART_MEGATRON_JOBS_DIR"] = jobs_dir env["ART_MEGATRON_WAKE_LOCK_PATH"] = wake_lock_path master_addr = env.get("MASTER_ADDR", "127.0.0.1") @@ -885,7 +934,7 @@ async def train( ) if not self._adapter_exists_and_loads(new_checkpoint_dir): raise RuntimeError( - f"Megatron training did not publish LoRA adapter: " + "Megatron training did not publish LoRA adapter: " f"{new_checkpoint_dir}" ) if self.rollout_weights_mode == "merged": diff --git a/src/art/megatron/train.py b/src/art/megatron/train.py index d40a7215a..f0381b04a 100644 --- a/src/art/megatron/train.py +++ b/src/art/megatron/train.py @@ -310,6 +310,33 @@ def configure_moe_routing_replay( runtime.moe_routing_replay_controller = controller +def _moe_routing_replay_requested( + *, + replay_bundle_path: str | None, + replay_bundle: MoeRoutingReplayBundle | None, +) -> bool: + if replay_bundle_path is not None or replay_bundle is not None: + return True + return os.environ.get("ART_MEGATRON_ENABLE_MOE_ROUTING_REPLAY", "").lower() in { + "1", + "true", + "yes", + "on", + } + + +def _enable_native_moe_routing_replay(provider: Any) -> None: + if bool(getattr(provider, "moe_router_fusion", False)): + raise RuntimeError( + "MoE routing replay requires provider.moe_router_fusion=False because " + "Megatron Core fused routing bypasses RouterReplay" + ) + from megatron.core.transformer.moe.router_replay import RouterReplay + + RouterReplay.clear_global_router_replay_instances() + provider.moe_enable_routing_replay = True + + def build_training_runtime( *, model_identifier: str | None = None, @@ -343,6 +370,11 @@ def build_training_runtime( provider = provider_bundle.provider if provider_configure is not None: provider_configure(provider) + if _moe_routing_replay_requested( + replay_bundle_path=moe_routing_replay_path, + replay_bundle=moe_routing_replay_bundle, + ): + _enable_native_moe_routing_replay(provider) finalize_provider_bundle(provider_bundle) _register_trainable_parameter_mode( provider, @@ -531,6 +563,7 @@ def run_megatron_rl_job( optimizer_state_path=job.optimizer_state_path, ) finally: + configure_moe_routing_replay(runtime) if packed_tensors is not None: del packed_tensors if adapter_model is not None: diff --git a/src/art/model.py b/src/art/model.py index f499fe1d3..def7f8603 100644 --- a/src/art/model.py +++ b/src/art/model.py @@ -22,6 +22,7 @@ build_data_metrics_from_summary, summarize_trajectory_groups, ) +from .preprocessing.moe_routing import attach_moe_routing_metadata_to_choice from .trajectories import Trajectory, TrajectoryGroup from .types import TrainSFTConfig from .utils.trajectory_logging import write_trajectory_groups_parquet @@ -56,6 +57,20 @@ def _merge_extra_body_defaults( return merged +def _attach_response_moe_routing_metadata(response: Any) -> None: + choices = getattr(response, "choices", None) + model_dump = getattr(response, "model_dump", None) + if not choices or not callable(model_dump): + return + response_payload = model_dump(mode="python") + for choice_index, choice in enumerate(choices): + attach_moe_routing_metadata_to_choice( + choice=choice, + response_payload=response_payload, + choice_index=choice_index, + ) + + class _OpenAIChatCompletionsProxy: def __init__( self, @@ -74,6 +89,7 @@ async def create(self, *args: Any, **kwargs: Any) -> Any: kwargs.get("extra_body"), ) response = await self._completions.create(*args, **kwargs) + _attach_response_moe_routing_metadata(response) self._record_costs(response) return response diff --git a/src/art/preprocessing/moe_routing.py b/src/art/preprocessing/moe_routing.py new file mode 100644 index 000000000..f62cb9455 --- /dev/null +++ b/src/art/preprocessing/moe_routing.py @@ -0,0 +1,313 @@ +from __future__ import annotations + +from typing import Any + +from openai.types.chat.chat_completion import Choice +from pydantic import BaseModel, ConfigDict, model_validator + +ART_MOE_ROUTING_METADATA_KEY = "art_moe_routing" + +PROMPT_TOKEN_IDS_KEY = "prompt_token_ids" +COMPLETION_TOKEN_IDS_KEY = "completion_token_ids" +PROMPT_ROUTED_EXPERTS_KEY = "prompt_routed_experts" +COMPLETION_ROUTED_EXPERTS_KEY = "completion_routed_experts" +ROUTED_EXPERTS_KEY = "routed_experts" + +_ROUTING_RESPONSE_KEYS = { + PROMPT_TOKEN_IDS_KEY, + COMPLETION_TOKEN_IDS_KEY, + "output_token_ids", + "token_ids", + PROMPT_ROUTED_EXPERTS_KEY, + COMPLETION_ROUTED_EXPERTS_KEY, + ROUTED_EXPERTS_KEY, +} +_ROUTING_EXPERT_KEYS = { + PROMPT_ROUTED_EXPERTS_KEY, + COMPLETION_ROUTED_EXPERTS_KEY, + ROUTED_EXPERTS_KEY, +} + +TokenRoute = list[list[int]] + + +def _has_routing_experts(metadata: dict[str, Any]) -> bool: + return any(metadata.get(key) is not None for key in _ROUTING_EXPERT_KEYS) + + +class MoeRoutingAlignmentStats(BaseModel): + choices_with_routing: int = 0 + routed_tokens: int = 0 + overlap_conflict_rows: int = 0 + overlap_conflict_slots: int = 0 + overlap_compared_slots: int = 0 + + +class MoeRoutingPackStats(BaseModel): + packed_tokens: int = 0 + shared_prefix_rows: int = 0 + shared_prefix_conflict_rows: int = 0 + shared_prefix_conflict_slots: int = 0 + shared_prefix_compared_slots: int = 0 + + def add_alignment(self, stats: MoeRoutingAlignmentStats) -> None: + self.shared_prefix_conflict_rows += stats.overlap_conflict_rows + self.shared_prefix_conflict_slots += stats.overlap_conflict_slots + self.shared_prefix_compared_slots += stats.overlap_compared_slots + + +class PackedMoeRoutingReplay(BaseModel): + model_config = ConfigDict(arbitrary_types_allowed=True) + + expert_indices: Any + token_mask: Any + num_layers: int + topk: int + num_experts: int + pack_stats: MoeRoutingPackStats + + @model_validator(mode="after") + def _validate(self) -> "PackedMoeRoutingReplay": + if self.expert_indices.ndim != 4: + raise RuntimeError( + "expert_indices must have shape " + "[num_sequences, sequence_length, num_layers, topk], got " + f"{tuple(self.expert_indices.shape)}" + ) + if self.token_mask.shape != self.expert_indices.shape[:2]: + raise RuntimeError( + "token_mask shape must match packed route tokens, got " + f"{tuple(self.token_mask.shape)} vs " + f"{tuple(self.expert_indices.shape[:2])}" + ) + if self.num_layers != int(self.expert_indices.shape[2]): + raise RuntimeError( + f"num_layers={self.num_layers} does not match " + f"expert_indices.shape[2]={self.expert_indices.shape[2]}" + ) + if self.topk != int(self.expert_indices.shape[3]): + raise RuntimeError( + f"topk={self.topk} does not match " + f"expert_indices.shape[3]={self.expert_indices.shape[3]}" + ) + if self.num_experts <= 0: + raise RuntimeError(f"num_experts must be >0, got {self.num_experts}") + if self.topk > self.num_experts: + raise RuntimeError( + f"MoE routing topk cannot exceed num_experts: topk={self.topk}, " + f"num_experts={self.num_experts}" + ) + return self + + +def attach_moe_routing_metadata_to_choice( + *, + choice: Choice, + response_payload: dict[str, Any], + choice_index: int = 0, +) -> None: + metadata: dict[str, Any] = { + key: response_payload[key] + for key in _ROUTING_RESPONSE_KEYS + if key in response_payload + } + raw_choices = response_payload.get("choices") + if isinstance(raw_choices, list) and choice_index < len(raw_choices): + raw_choice = raw_choices[choice_index] + if isinstance(raw_choice, dict): + metadata.update( + { + key: raw_choice[key] + for key in _ROUTING_RESPONSE_KEYS + if key in raw_choice + } + ) + if not metadata or not _has_routing_experts(metadata): + return + extra = choice.model_extra + if extra is None: + raise RuntimeError("OpenAI Choice.model_extra is unavailable for route capture") + extra[ART_MOE_ROUTING_METADATA_KEY] = metadata + + +def choice_moe_routing_metadata(choice: Choice) -> dict[str, Any] | None: + extra = choice.model_extra or {} + nested = extra.get(ART_MOE_ROUTING_METADATA_KEY) + if isinstance(nested, dict): + if not _has_routing_experts(nested): + return None + return nested + top_level = {key: extra[key] for key in _ROUTING_RESPONSE_KEYS if key in extra} + if not _has_routing_experts(top_level): + return None + return top_level or None + + +def align_choice_routes_to_tokenized_result( + *, + token_ids: list[int], + choices: list[Choice], + choice_offsets: list[int], + choice_token_lengths: list[int], +) -> tuple[list[TokenRoute | None] | None, MoeRoutingAlignmentStats]: + if not (len(choices) == len(choice_offsets) == len(choice_token_lengths)): + raise RuntimeError( + "Choice routing alignment inputs differ in length: " + f"choices={len(choices)}, offsets={len(choice_offsets)}, " + f"lengths={len(choice_token_lengths)}" + ) + aligned: list[TokenRoute | None] = [None] * len(token_ids) + stats = MoeRoutingAlignmentStats() + saw_routing = False + saw_missing = False + for choice, offset, token_length in zip( + choices, choice_offsets, choice_token_lengths + ): + metadata = choice_moe_routing_metadata(choice) + if metadata is None: + saw_missing = True + continue + saw_routing = True + stats.choices_with_routing += 1 + prompt_token_ids = _normalize_token_ids(metadata.get(PROMPT_TOKEN_IDS_KEY)) + completion_token_ids = _completion_token_ids(metadata) + prompt_routes = _prompt_routes(metadata) + completion_routes = _completion_routes(metadata) + expected_prompt_ids = token_ids[:offset] + expected_completion_ids = token_ids[offset : offset + token_length] + if prompt_token_ids != expected_prompt_ids: + raise RuntimeError( + "vLLM routed prompt token ids do not match ART-tokenized prefix: " + f"offset={offset}, vllm_len={len(prompt_token_ids)}, " + f"art_len={len(expected_prompt_ids)}" + ) + if completion_token_ids != expected_completion_ids: + raise RuntimeError( + "vLLM routed completion token ids do not match ART-tokenized choice: " + f"offset={offset}, vllm_len={len(completion_token_ids)}, " + f"art_len={len(expected_completion_ids)}" + ) + if len(prompt_routes) != len(prompt_token_ids): + raise RuntimeError( + "prompt_routed_experts length does not match prompt_token_ids: " + f"{len(prompt_routes)} != {len(prompt_token_ids)}" + ) + if len(completion_routes) not in { + len(completion_token_ids), + max(len(completion_token_ids) - 1, 0), + }: + raise RuntimeError( + "completion_routed_experts length does not match completion_token_ids: " + f"{len(completion_routes)} != {len(completion_token_ids)}" + ) + for position, route in enumerate(prompt_routes): + _overlay_route(aligned, position, route, stats) + for offset_delta, route in enumerate(completion_routes): + _overlay_route(aligned, offset + offset_delta, route, stats) + stats.routed_tokens = sum(route is not None for route in aligned) + if saw_routing and saw_missing: + raise RuntimeError("Some trainable choices had MoE routes while others did not") + return (aligned if saw_routing else None), stats + + +def _overlay_route( + aligned: list[TokenRoute | None], + position: int, + route: TokenRoute, + stats: MoeRoutingAlignmentStats, +) -> None: + existing = aligned[position] + if existing is None: + aligned[position] = route + return + compared, conflicts = _count_route_slot_conflicts(existing, route) + stats.overlap_compared_slots += compared + stats.overlap_conflict_slots += conflicts + if conflicts: + stats.overlap_conflict_rows += 1 + + +def _count_route_slot_conflicts(left: TokenRoute, right: TokenRoute) -> tuple[int, int]: + _validate_route_shape(left) + _validate_route_shape(right) + if len(left) != len(right) or any( + len(left_layer) != len(right_layer) + for left_layer, right_layer in zip(left, right) + ): + raise RuntimeError("Cannot compare MoE routes with different shapes") + compared = 0 + conflicts = 0 + for left_layer, right_layer in zip(left, right): + for left_expert, right_expert in zip(left_layer, right_layer): + compared += 1 + conflicts += int(int(left_expert) != int(right_expert)) + return compared, conflicts + + +def _normalize_token_ids(raw: Any) -> list[int]: + if raw is None: + raise RuntimeError("Missing routed token ids") + if not isinstance(raw, list): + raise RuntimeError(f"Expected routed token ids list, got {type(raw)}") + return [int(token_id) for token_id in raw] + + +def _normalize_routes(raw: Any, *, field_name: str) -> list[TokenRoute]: + if raw is None: + raise RuntimeError(f"Missing {field_name}") + if not isinstance(raw, list): + raise RuntimeError(f"Expected {field_name} list, got {type(raw)}") + routes: list[TokenRoute] = [] + for token_route in raw: + if not isinstance(token_route, list): + raise RuntimeError(f"Expected token route list in {field_name}") + route: TokenRoute = [] + for layer_route in token_route: + if not isinstance(layer_route, list): + raise RuntimeError(f"Expected layer route list in {field_name}") + route.append([int(expert_id) for expert_id in layer_route]) + _validate_route_shape(route) + routes.append(route) + return routes + + +def _validate_route_shape(route: TokenRoute) -> None: + if not route: + raise RuntimeError("MoE token route cannot have zero layers") + topk = len(route[0]) + if topk <= 0: + raise RuntimeError("MoE token route cannot have zero topk") + if any(len(layer_route) != topk for layer_route in route): + raise RuntimeError("MoE token route topk must be constant across layers") + + +def _completion_token_ids(metadata: dict[str, Any]) -> list[int]: + for key in (COMPLETION_TOKEN_IDS_KEY, "output_token_ids", "token_ids"): + if key in metadata: + return _normalize_token_ids(metadata[key]) + raise RuntimeError("Missing routed completion token ids") + + +def _prompt_routes(metadata: dict[str, Any]) -> list[TokenRoute]: + return _normalize_routes( + metadata.get(PROMPT_ROUTED_EXPERTS_KEY), + field_name=PROMPT_ROUTED_EXPERTS_KEY, + ) + + +def _completion_routes(metadata: dict[str, Any]) -> list[TokenRoute]: + if COMPLETION_ROUTED_EXPERTS_KEY in metadata: + return _normalize_routes( + metadata[COMPLETION_ROUTED_EXPERTS_KEY], + field_name=COMPLETION_ROUTED_EXPERTS_KEY, + ) + if ROUTED_EXPERTS_KEY in metadata: + return _normalize_routes( + metadata[ROUTED_EXPERTS_KEY], + field_name=ROUTED_EXPERTS_KEY, + ) + raise RuntimeError("Missing routed completion experts") + + +def count_route_slot_conflicts(left: TokenRoute, right: TokenRoute) -> tuple[int, int]: + return _count_route_slot_conflicts(left, right) diff --git a/src/art/preprocessing/pack.py b/src/art/preprocessing/pack.py index 5e1ad03f0..753577e1b 100644 --- a/src/art/preprocessing/pack.py +++ b/src/art/preprocessing/pack.py @@ -7,6 +7,12 @@ from typing_extensions import NotRequired, TypedDict, Unpack from ..types import Verbosity +from .moe_routing import ( + MoeRoutingPackStats, + PackedMoeRoutingReplay, + TokenRoute, + count_route_slot_conflicts, +) from .tokenize import TokenizedResult @@ -21,6 +27,7 @@ class PackedTensors(TypedDict): weights: torch.Tensor pixel_values: list[torch.Tensor | None] image_grid_thw: list[torch.Tensor | None] + moe_routing_replay: NotRequired[PackedMoeRoutingReplay] class DiskPackedTensors(TypedDict): @@ -39,6 +46,7 @@ def packed_tensors_from_tokenized_results( advantage_balance: float = 0.0, verbosity: Verbosity = 1, pack_results: bool = True, + include_moe_routing: bool = False, ) -> PackedTensors: # TODO: This function could potentially be optimized with vectorized operations token_ids: list[list[int]] = [[]] @@ -51,12 +59,19 @@ def packed_tensors_from_tokenized_results( weights: list[list[float]] = [[]] pixel_values: list[list[torch.Tensor]] = [[]] image_grid_thw: list[list[torch.Tensor]] = [[]] + moe_routes: list[list[TokenRoute | None]] = [[]] + moe_routing_pack_stats = MoeRoutingPackStats() for result in tokenized_results: if len(result.token_ids) > seq_len and not truncate_long_results: if verbosity > 1: print("Result is too long, skipping") continue + if include_moe_routing and result.moe_routed_experts is None: + raise RuntimeError( + "MoE routing replay from trajectories was requested, but a " + "tokenized result has no aligned routed experts" + ) result_without_prompt = result.without_prompt() if sum(result_without_prompt.assistant_mask) == 0: if verbosity > 1: @@ -82,8 +97,16 @@ def packed_tensors_from_tokenized_results( weights.append([]) pixel_values.append([]) image_grid_thw.append([]) + moe_routes.append([]) group_id = random.randint(-(2**63), 2**63 - 1) if result.prompt_id in group_ids[-1]: + if include_moe_routing: + _record_shared_prefix_route_conflicts( + existing_group_ids=group_ids[-1], + existing_routes=moe_routes[-1], + result=result, + stats=moe_routing_pack_stats, + ) result = result_without_prompt token_ids[-1].extend(result.token_ids) group_ids[-1].extend( @@ -100,6 +123,9 @@ def packed_tensors_from_tokenized_results( pixel_values[-1].append(result.pixel_values) if result.image_grid_thw is not None: image_grid_thw[-1].append(result.image_grid_thw) + if include_moe_routing: + assert result.moe_routed_experts is not None + moe_routes[-1].extend(result.moe_routed_experts) if truncate_long_results: token_ids[-1] = token_ids[-1][:seq_len] group_ids[-1] = group_ids[-1][:seq_len] @@ -109,6 +135,8 @@ def packed_tensors_from_tokenized_results( logprobs[-1] = logprobs[-1][:seq_len] advantages[-1] = advantages[-1][:seq_len] weights[-1] = weights[-1][:seq_len] + if include_moe_routing: + moe_routes[-1] = moe_routes[-1][:seq_len] permutation = list(range(len(token_ids))) random.shuffle(permutation) @@ -122,6 +150,7 @@ def packed_tensors_from_tokenized_results( weights = [weights[i] for i in permutation] pixel_values = [pixel_values[i] for i in permutation] image_grid_thw = [image_grid_thw[i] for i in permutation] + moe_routes = [moe_routes[i] for i in permutation] def pad(values: list[list], pad_value) -> list[list]: max_len = seq_len @@ -158,7 +187,7 @@ def pad(values: list[list], pad_value) -> list[list]: * weights_tensor[assistant_mask_tensor] ).mean() - return { + packed_tensors: PackedTensors = { "tokens": torch.tensor(pad(token_ids, pad_token_id)), "group_ids": torch.tensor(pad(group_ids, -1)), "parent_ids": torch.tensor(pad(parent_ids, -1)), @@ -174,6 +203,108 @@ def pad(values: list[list], pad_value) -> list[list]: torch.concat(tensors) if tensors else None for tensors in image_grid_thw ], } + if include_moe_routing: + ( + route_tensor, + route_mask, + num_layers, + topk, + num_experts, + ) = _tensorize_moe_routes(moe_routes, seq_len) + moe_routing_pack_stats.packed_tokens = int(route_mask.sum().item()) + packed_tensors["moe_routing_replay"] = PackedMoeRoutingReplay( + expert_indices=route_tensor, + token_mask=route_mask, + num_layers=num_layers, + topk=topk, + num_experts=num_experts, + pack_stats=moe_routing_pack_stats, + ) + return packed_tensors + + +def _record_shared_prefix_route_conflicts( + *, + existing_group_ids: list[int], + existing_routes: list[TokenRoute | None], + result: TokenizedResult, + stats: MoeRoutingPackStats, +) -> None: + assert result.moe_routed_experts is not None + prefix_positions = [ + index + for index, group_id in enumerate(existing_group_ids) + if group_id == result.prompt_id + ] + if len(prefix_positions) != result.prompt_length: + raise RuntimeError( + "Shared-prefix route comparison could not find the existing packed " + f"prefix rows: prompt_length={result.prompt_length}, " + f"existing_rows={len(prefix_positions)}" + ) + for prefix_offset, packed_index in enumerate(prefix_positions): + route = result.moe_routed_experts[prefix_offset] + existing = existing_routes[packed_index] + if route is None or existing is None: + raise RuntimeError("Shared-prefix MoE route is missing") + compared, conflicts = count_route_slot_conflicts(existing, route) + stats.shared_prefix_rows += 1 + stats.shared_prefix_compared_slots += compared + stats.shared_prefix_conflict_slots += conflicts + stats.shared_prefix_conflict_rows += int(conflicts > 0) + + +def _tensorize_moe_routes( + routes_by_sequence: list[list[TokenRoute | None]], + seq_len: int, +) -> tuple[torch.Tensor, torch.Tensor, int, int, int]: + first_route = next( + ( + route + for sequence_routes in routes_by_sequence + for route in sequence_routes + if route is not None + ), + None, + ) + if first_route is None: + raise RuntimeError("No MoE routes were packed") + num_layers = len(first_route) + topk = len(first_route[0]) + max_expert_id = 0 + dense_routes: list[list[TokenRoute]] = [] + route_masks: list[list[bool]] = [] + zero_route: TokenRoute = [[0 for _ in range(topk)] for _ in range(num_layers)] + for sequence_routes in routes_by_sequence: + dense_sequence: list[TokenRoute] = [] + mask_sequence: list[bool] = [] + for route in sequence_routes: + if route is None: + dense_sequence.append(zero_route) + mask_sequence.append(False) + continue + if len(route) != num_layers or any( + len(layer_route) != topk for layer_route in route + ): + raise RuntimeError("Packed MoE routes must have one rectangular shape") + max_expert_id = max( + max_expert_id, + max(int(expert_id) for layer in route for expert_id in layer), + ) + dense_sequence.append(route) + mask_sequence.append(True) + while len(dense_sequence) < seq_len: + dense_sequence.append(zero_route) + mask_sequence.append(False) + dense_routes.append(dense_sequence[:seq_len]) + route_masks.append(mask_sequence[:seq_len]) + return ( + torch.tensor(dense_routes, dtype=torch.int32), + torch.tensor(route_masks, dtype=torch.bool), + num_layers, + topk, + max_expert_id + 1, + ) def packed_tensors_from_dir(**kwargs: Unpack[DiskPackedTensors]) -> PackedTensors: diff --git a/src/art/preprocessing/tokenize.py b/src/art/preprocessing/tokenize.py index e3187d935..20783dc2b 100644 --- a/src/art/preprocessing/tokenize.py +++ b/src/art/preprocessing/tokenize.py @@ -19,6 +19,11 @@ default_chat_template_kwargs_for_tokenizer, merge_chat_template_kwargs, ) +from .moe_routing import ( + MoeRoutingAlignmentStats, + TokenRoute, + align_choice_routes_to_tokenized_result, +) from .response_masking import response_only_labels, token_ids_for_template_part ChatTemplateTool = dict[Any, Any] | Callable[..., Any] @@ -151,6 +156,8 @@ class TokenizedResult: choice_offsets: list[int] extra_logprobs: dict[str, list[float]] _tokenizer: "PreTrainedTokenizerBase" = field(repr=False, compare=False) + moe_routed_experts: list[TokenRoute | None] | None = None + moe_routing_alignment_stats: MoeRoutingAlignmentStats | None = None weight: float = 0.0 prompt_id: int = 0 prompt_length: int = 0 @@ -177,6 +184,12 @@ def without_prompt(self) -> "TokenizedResult": key: values[self.prompt_length :] for key, values in self.extra_logprobs.items() }, + moe_routed_experts=( + self.moe_routed_experts[self.prompt_length :] + if self.moe_routed_experts is not None + else None + ), + moe_routing_alignment_stats=self.moe_routing_alignment_stats, _tokenizer=self._tokenizer, weight=self.weight, prompt_id=self.prompt_id, @@ -413,6 +426,7 @@ def tokenize_trajectory( assistant_mask: list[int] = [0] * len(token_ids) logprobs = [float("nan")] * len(token_ids) choice_offsets, choice_token_logprobs = [], [] + trainable_choices: list[Choice] = [] for message in messages_and_choices: if isinstance(message, dict): @@ -446,7 +460,7 @@ def tokenize_trajectory( logprobs[start:end] = [float("nan")] * len(content_token_ids) assistant_mask[start:end] = [1] * len(content_token_ids) else: - choice = message + choice = cast(Choice, message) assert choice.logprobs or allow_training_without_logprobs, ( # ty:ignore[possibly-missing-attribute] "Chat completion choices must have logprobs" ) @@ -461,6 +475,7 @@ def tokenize_trajectory( start -= 4 choice_offsets.append(start) choice_token_logprobs.append(token_logprobs) + trainable_choices.append(choice) try: token_ids[start:end] = ( int(token_logprob.token.split(":")[1]) @@ -542,6 +557,16 @@ def tokenize_trajectory( else: pixel_values = None image_grid_thw = None + moe_routed_experts, moe_routing_alignment_stats = ( + align_choice_routes_to_tokenized_result( + token_ids=token_ids, + choices=trainable_choices, + choice_offsets=choice_offsets, + choice_token_lengths=[ + len(token_logprobs) for token_logprobs in choice_token_logprobs + ], + ) + ) return TokenizedResult( advantage=advantage, chat=chat, @@ -554,6 +579,8 @@ def tokenize_trajectory( trajectory=trajectory, choice_offsets=choice_offsets, extra_logprobs=extra_logprobs, + moe_routed_experts=moe_routed_experts, + moe_routing_alignment_stats=moe_routing_alignment_stats, _tokenizer=tokenizer, ) diff --git a/tests/integration/megatron/model_support/chat_template_rollout.py b/tests/integration/megatron/model_support/chat_template_rollout.py index f337864bf..65e30622c 100644 --- a/tests/integration/megatron/model_support/chat_template_rollout.py +++ b/tests/integration/megatron/model_support/chat_template_rollout.py @@ -6,7 +6,6 @@ import art from art.local import LocalBackend -from art.local.backend import _tokenizer_cache_key from art.preprocessing.pack import PackedTensors from art.preprocessing.tokenize import ( TokenizedResult, @@ -96,16 +95,13 @@ class ChatTemplateRolloutReport(BaseModel): def run_chat_template_rollout(base_model: str) -> ChatTemplateRolloutReport: output_dir = _artifact_dir(base_model) backend = LocalBackend(path=str(output_dir)) - internal_config = art.dev.InternalModelConfig( - {"init_args": {"max_seq_length": 2048}} - ) model = art.TrainableModel( name="model-support-chat-template", project="model-support-validation", base_model=base_model, - _internal_config=internal_config, + _internal_config={"init_args": {"max_seq_length": 2048}}, ) - tokenizer_key = _tokenizer_cache_key(base_model, internal_config) + tokenizer_key = (base_model, None) tokenizer = backend._tokenizers.get(tokenizer_key) if tokenizer is None: from transformers import AutoTokenizer diff --git a/tests/integration/megatron/model_support/hf_parity_worker.py b/tests/integration/megatron/model_support/hf_parity_worker.py index 26e1fa1a4..35107053c 100644 --- a/tests/integration/megatron/model_support/hf_parity_worker.py +++ b/tests/integration/megatron/model_support/hf_parity_worker.py @@ -156,7 +156,6 @@ def _hook(_module: Any, _inputs: Any, output: Any) -> None: ) route = RouterCallRoute( expert_indices=router_indices.detach().cpu().to(torch.int32), - expert_probs=router_scores.detach().cpu().to(torch.float32), expert_mask=torch.ones_like( router_indices.detach().cpu(), dtype=torch.bool ), @@ -497,6 +496,8 @@ def _run_hf_sft_step( def _build_megatron_runtime( request: HfParityRunRequest, + *, + moe_routing_replay_bundle: MoeRoutingReplayBundle | None = None, ) -> megatron_train.TrainingRuntime: return megatron_train.build_training_runtime( model_identifier=request.case_config.base_model, @@ -506,6 +507,8 @@ def _build_megatron_runtime( provider, ORACLE_TOPOLOGY, request.case_config ), optimizer_config=_build_optimizer_config(request.case_config), + moe_routing_replay_bundle=moe_routing_replay_bundle, + moe_routing_replay_strict=True, print_env=False, trainable_parameter_mode="base_model", allow_unvalidated_arch=request.case_config.allow_unvalidated_arch, @@ -629,15 +632,13 @@ def _run_megatron_sft_step( device: torch.device, moe_routing_replay_bundle: MoeRoutingReplayBundle | None = None, ) -> tuple[torch.Tensor, torch.Tensor, dict[str, torch.Tensor]]: - runtime = _build_megatron_runtime(request) + runtime = _build_megatron_runtime( + request, + moe_routing_replay_bundle=moe_routing_replay_bundle, + ) _assert_runtime_configuration(runtime.model, request.case_config) assert runtime.optimizer is not None if moe_routing_replay_bundle is not None: - megatron_train.configure_moe_routing_replay( - runtime, - replay_bundle=moe_routing_replay_bundle, - strict=True, - ) controller = runtime.moe_routing_replay_controller if controller is None: raise RuntimeError( diff --git a/tests/integration/megatron/model_support/lora_coverage.py b/tests/integration/megatron/model_support/lora_coverage.py index 2cfb84ddb..1c30c1918 100644 --- a/tests/integration/megatron/model_support/lora_coverage.py +++ b/tests/integration/megatron/model_support/lora_coverage.py @@ -126,8 +126,11 @@ def _covered_exported_target_modules( if base_name.endswith(".self_attention.out_proj.weight"): covered.add("out_proj") continue - if ".mlp.experts.linear_fc" in base_name: - covered.add("experts") + if ".mlp.experts.linear_fc1" in base_name: + covered.update({"experts", "gate_proj", "up_proj"}) + continue + if ".mlp.experts.linear_fc2" in base_name: + covered.update({"experts", "down_proj"}) continue if ".linear_fc1.weight" in base_name: covered.update({"gate_proj", "up_proj"}) diff --git a/tests/integration/megatron/model_support/oracle_harness.py b/tests/integration/megatron/model_support/oracle_harness.py index 0de3b5a2e..6cf93caaa 100644 --- a/tests/integration/megatron/model_support/oracle_harness.py +++ b/tests/integration/megatron/model_support/oracle_harness.py @@ -16,6 +16,8 @@ from rich.table import Table import torch +from art.megatron.routing_replay import ROUTER_KEY_FORMAT_VERSION + from .forward_trace import ForwardTraceCapture REPO_ROOT = Path(__file__).resolve().parents[4] @@ -176,12 +178,9 @@ def world_size(self) -> int: TOPOLOGIES = [ Topology(tp=1, ep=1, etp=1, dp=1, sp=False), - Topology(tp=2, ep=1, etp=1, dp=1, sp=True), Topology(tp=2, ep=2, etp=1, dp=1, sp=True), Topology(tp=2, ep=1, etp=2, dp=1, sp=True), - Topology(tp=1, ep=1, etp=1, dp=2, sp=False), Topology(tp=1, ep=2, etp=1, dp=2, sp=False), - Topology(tp=1, ep=1, etp=2, dp=2, sp=True), ] DENSE_TOPOLOGIES = [ Topology(tp=1, ep=1, etp=1, dp=1, sp=False), @@ -1152,9 +1151,19 @@ def ensure_oracle(self) -> Path: self.shared_init_path.unlink() bundle_manifest = self.oracle_routing_bundle_dir / "manifest.json" oracle_manifest = self.oracle_dir / "manifest.json" + bundle_format_current = False + if bundle_manifest.exists(): + try: + bundle_format_current = ( + _read_json(bundle_manifest).get("format_version") + == ROUTER_KEY_FORMAT_VERSION + ) + except Exception: + bundle_format_current = False need_capture = ( regenerate or not bundle_manifest.exists() + or not bundle_format_current or not self.shared_init_path.exists() ) run_oracle_topology = partial( diff --git a/tests/integration/megatron/model_support/oracle_worker.py b/tests/integration/megatron/model_support/oracle_worker.py index 712358028..e832c2d71 100644 --- a/tests/integration/megatron/model_support/oracle_worker.py +++ b/tests/integration/megatron/model_support/oracle_worker.py @@ -19,11 +19,10 @@ from art.megatron.routing_replay import ( ParallelTopology as ReplayParallelTopology, ) -from art.megatron.routing_replay import ( - build_bundle_from_forward_trace_dir, -) from art.preprocessing.pack import PackedTensors +from ..routing_replay.bundle import build_bundle_from_forward_trace_dir +from ..routing_replay.trace import install_moe_routing_trace_hooks from .forward_trace import ForwardTraceCapture from .oracle_harness import ( SUPPORTED_SENSITIVITY_MUTATIONS, @@ -906,17 +905,14 @@ def _worker_run(request: WorkerRunRequest) -> None: provider, request.topology, request.case_config ), optimizer_config=_build_optimizer_config(request.case_config), + moe_routing_replay_path=request.moe_routing_replay_path, + moe_routing_replay_strict=request.moe_routing_replay_strict, print_env=False, allow_unvalidated_arch=request.case_config.allow_unvalidated_arch, ) _debug("finished build_training_runtime") model_chunks = runtime.model optimizer = runtime.optimizer - megatron_train.configure_moe_routing_replay( - runtime, - replay_bundle_path=request.moe_routing_replay_path, - strict=request.moe_routing_replay_strict, - ) _assert_runtime_configuration(model_chunks, request.case_config) topology_dir = Path(request.topology_dir) @@ -978,15 +974,10 @@ def _worker_run(request: WorkerRunRequest) -> None: step_traces: list[StepTrace] = [] captured_grads: dict[str, Any] | None = None routing_replay_controller = runtime.moe_routing_replay_controller - micro_start_callback = ( - routing_replay_controller.begin_micro - if routing_replay_controller is not None - else None - ) + install_moe_routing_trace_hooks(lambda: runtime.moe_routing_replay_controller) forward_trace_capture = ForwardTraceCapture( model_chunks, enabled=True, - micro_start_callback=micro_start_callback, strict_output_match=request.mutation is None, ) diff --git a/tests/integration/megatron/model_support/test_oracle_harness_invariants.py b/tests/integration/megatron/model_support/test_oracle_harness_invariants.py index 194b4d24d..7f17de88d 100644 --- a/tests/integration/megatron/model_support/test_oracle_harness_invariants.py +++ b/tests/integration/megatron/model_support/test_oracle_harness_invariants.py @@ -4,8 +4,10 @@ from .oracle_harness import ( DENSE_ORACLE_TOPOLOGY, ORACLE_TOPOLOGY, + TOPOLOGIES, DiffAccumulator, MetricThresholdRule, + Topology, _default_phase_pass_fns, _suite_variants, selected_sensitivity_mutations_for_objective, @@ -71,21 +73,18 @@ def test_dense_suite_variants_include_tp2_dp2_without_oracle_duplicate() -> None ) -def test_moe_suite_variants_include_dp2_ep_and_etp_topologies() -> None: +def test_moe_suite_variants_use_minimal_non_cp_topology_matrix() -> None: + assert TOPOLOGIES == [ + Topology(tp=1, ep=1, etp=1, dp=1, sp=False), + Topology(tp=2, ep=2, etp=1, dp=1, sp=True), + Topology(tp=2, ep=1, etp=2, dp=1, sp=True), + Topology(tp=1, ep=2, etp=1, dp=2, sp=False), + ] + assert [topology.world_size() for topology in TOPOLOGIES] == [1, 2, 2, 2] + variants = _suite_variants("rl", is_moe=True) - assert any( - variant.topology.tp == 1 - and variant.topology.ep == 2 - and variant.topology.dp == 2 - for variant in variants - ) - assert any( - variant.topology.tp == 1 - and variant.topology.etp == 2 - and variant.topology.dp == 2 - for variant in variants - ) + assert [variant.topology for variant in variants] == TOPOLOGIES[1:] def test_max_world_size_arg_filters_dense_variants() -> None: diff --git a/tests/integration/megatron/model_support/test_workflow.py b/tests/integration/megatron/model_support/test_workflow.py index 551578402..50e408e0e 100644 --- a/tests/integration/megatron/model_support/test_workflow.py +++ b/tests/integration/megatron/model_support/test_workflow.py @@ -3,6 +3,7 @@ from art.megatron.model_support.spec import ( ArchitectureReport, LayerFamilyInstance, + ValidationReport, ValidationStageResult, ) @@ -11,6 +12,7 @@ NATIVE_VLLM_LORA_STAGE, SKIP_SENSITIVITY_ENV, assess_minimal_layer_coverage, + build_all_architectures_validation_report, build_validation_report, build_validation_stage_names, run_chat_template_rollout_stage, @@ -21,6 +23,7 @@ run_packed_position_ids_stage, run_train_inf_mismatch_stage, run_yes_no_trainability_stage, + validated_architecture_representative_models, ) @@ -36,6 +39,62 @@ def test_build_validation_stage_names_has_fixed_order() -> None: ] +def test_validated_architecture_representative_models_are_fixed() -> None: + assert validated_architecture_representative_models() == [ + "Qwen/Qwen3-30B-A3B", + "Qwen/Qwen3-32B", + "Qwen/Qwen3.5-35B-A3B", + "Qwen/Qwen3.5-27B", + ] + + +def test_build_all_architectures_validation_report_stops_on_failure( + monkeypatch, + tmp_path, +) -> None: + calls: list[str] = [] + + def _build_validation_report( + *, + base_model, + include_sensitivity=None, + output_json=None, + skip_stages=None, + stop_on_failure=False, + allow_unvalidated_arch=False, + ): + del include_sensitivity + del output_json + del skip_stages + del stop_on_failure + del allow_unvalidated_arch + calls.append(base_model) + return ValidationReport( + base_model=base_model, + model_key="qwen3_dense", + stages=[ + ValidationStageResult( + name="train_inf_mismatch", + passed=base_model != "Qwen/Qwen3-32B", + ) + ], + ) + + monkeypatch.setattr( + "tests.integration.megatron.model_support.workflow.build_validation_report", + _build_validation_report, + ) + + report = build_all_architectures_validation_report( + output_json=tmp_path / "all_architectures.json", + stop_on_failure=True, + ) + + assert calls == ["Qwen/Qwen3-30B-A3B", "Qwen/Qwen3-32B"] + assert report.passed is False + assert [item.base_model for item in report.reports] == calls + + def test_build_validation_report_populates_architecture_stage( monkeypatch, ) -> None: @@ -334,6 +393,69 @@ def test_build_validation_report_captures_lora_coverage_failure(monkeypatch) -> } +def test_build_validation_report_writes_incremental_output_and_stops( + monkeypatch, + tmp_path, +) -> None: + calls: list[str] = [] + monkeypatch.setattr( + "tests.integration.megatron.model_support.workflow.inspect_architecture", + lambda base_model: ArchitectureReport( + base_model=base_model, + model_key="qwen3_5_moe", + handler_key="qwen3_5_moe", + layer_families=[], + recommended_min_layers=1, + ), + ) + monkeypatch.setattr( + "tests.integration.megatron.model_support.workflow.detect_dependency_versions", + lambda: {}, + ) + + def _run_stage_in_subprocess( + *, + stage_name, + base_model, + architecture, + allow_unvalidated_arch=False, + ): + calls.append(stage_name) + return ValidationStageResult( + name=stage_name, + passed=stage_name != "lora_coverage", + metrics={"stage": stage_name}, + ) + + monkeypatch.setattr( + "tests.integration.megatron.model_support.workflow._run_stage_in_subprocess", + _run_stage_in_subprocess, + ) + output_json = tmp_path / "workflow_report.json" + + report = build_validation_report( + base_model="Qwen/Qwen3.5-35B-A3B", + output_json=output_json, + stop_on_failure=True, + ) + + assert calls == ["hf_parity", "lora_coverage"] + assert output_json.exists() + saved = ValidationReport.model_validate_json(output_json.read_text()) + assert saved == report + failed_stage = next( + stage for stage in saved.stages if stage.name == "lora_coverage" + ) + skipped_stage = next( + stage for stage in saved.stages if stage.name == "train_inf_mismatch" + ) + assert failed_stage.passed is False + assert skipped_stage.metrics == { + "skipped": True, + "reason": "stopped after lora_coverage failed", + } + + def test_assess_minimal_layer_coverage_reports_missing_families( monkeypatch, ) -> None: diff --git a/tests/integration/megatron/model_support/workflow.py b/tests/integration/megatron/model_support/workflow.py index b7a22af6a..c239457a8 100644 --- a/tests/integration/megatron/model_support/workflow.py +++ b/tests/integration/megatron/model_support/workflow.py @@ -1,4 +1,5 @@ -from contextlib import contextmanager, redirect_stderr, redirect_stdout +import argparse +from contextlib import contextmanager, nullcontext, redirect_stderr, redirect_stdout import importlib import importlib.metadata import os @@ -8,8 +9,11 @@ import tempfile from typing import Any +from pydantic import BaseModel, Field + from art.megatron.model_support.discovery import inspect_architecture from art.megatron.model_support.registry import ( + VALIDATED_MODEL_SUPPORT_SPECS, get_model_support_handler_for_spec, get_model_support_spec, ) @@ -43,6 +47,12 @@ "yes_no_trainability", ) NATIVE_VLLM_LORA_STAGE = "native_vllm_lora" +ARCHITECTURE_REPRESENTATIVE_MODELS = { + "qwen3_moe": "Qwen/Qwen3-30B-A3B", + "qwen3_dense": "Qwen/Qwen3-32B", + "qwen3_5_moe": "Qwen/Qwen3.5-35B-A3B", + "qwen3_5_dense": "Qwen/Qwen3.5-27B", +} SUBPROCESS_VALIDATION_STAGES = frozenset( { "hf_parity", @@ -58,6 +68,11 @@ ) +class AllArchitecturesValidationReport(BaseModel): + passed: bool = False + reports: list[ValidationReport] = Field(default_factory=list) + + def build_validation_stage_names( *, include_native_vllm_lora: bool = False, @@ -127,6 +142,25 @@ def _subprocess_log_tail(log_path: Path, *, max_lines: int = 40) -> str: return "\n".join(lines[-max_lines:]) +def _inspect_architecture_for_workflow( + base_model: str, + *, + allow_unvalidated_arch: bool, +) -> ArchitectureReport: + # Discovery only inspects layer families, so use a minimal topology instead + # of inheriting visible GPU count and tripping model-specific TP limits. + with _temporary_env( + ART_MEGATRON_TENSOR_MODEL_PARALLEL_SIZE="1", + ART_MEGATRON_EXPERT_MODEL_PARALLEL_SIZE="1", + ART_MEGATRON_EXPERT_TENSOR_PARALLEL_SIZE="1", + ): + return ( + inspect_architecture(base_model, allow_unvalidated_arch=True) + if allow_unvalidated_arch + else inspect_architecture(base_model) + ) + + @contextmanager def _redirect_output(log_path: Path): log_path.parent.mkdir(parents=True, exist_ok=True) @@ -149,6 +183,75 @@ def _temporary_env(**updates: str): os.environ[key] = value +def _write_validation_report( + report: ValidationReport, + output_json: str | Path | None, +) -> None: + if output_json is None: + return + path = Path(output_json) + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(report.model_dump_json(indent=2), encoding="utf-8") + + +def _write_all_architectures_report( + report: AllArchitecturesValidationReport, + output_json: str | Path | None, +) -> None: + if output_json is None: + return + path = Path(output_json) + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(report.model_dump_json(indent=2), encoding="utf-8") + + +def _per_architecture_output_json(output_json: str | Path, model_key: str) -> Path: + path = Path(output_json) + suffix = path.suffix or ".json" + return path.with_name(f"{path.stem}.{model_key}{suffix}") + + +def validated_architecture_representative_models() -> list[str]: + missing_keys = { + spec.key + for spec in VALIDATED_MODEL_SUPPORT_SPECS + if spec.key not in ARCHITECTURE_REPRESENTATIVE_MODELS + } + unknown_keys = set(ARCHITECTURE_REPRESENTATIVE_MODELS) - { + spec.key for spec in VALIDATED_MODEL_SUPPORT_SPECS + } + if missing_keys or unknown_keys: + raise RuntimeError( + "Architecture representative mapping does not match validated specs: " + f"missing={sorted(missing_keys)}, unknown={sorted(unknown_keys)}" + ) + representatives: list[str] = [] + for spec in VALIDATED_MODEL_SUPPORT_SPECS: + base_model = ARCHITECTURE_REPRESENTATIVE_MODELS[spec.key] + if base_model not in spec.model_names: + raise RuntimeError( + f"{base_model!r} is not registered under model support spec {spec.key!r}" + ) + representatives.append(base_model) + return representatives + + +def _mark_remaining_stages_skipped( + report: ValidationReport, + *, + after_stage_name: str, +) -> None: + past_failure = False + for stage in report.stages: + if past_failure: + stage.metrics = { + "skipped": True, + "reason": f"stopped after {after_stage_name} failed", + } + continue + past_failure = stage.name == after_stage_name + + def _run_stage_in_subprocess( *, stage_name: str, @@ -636,6 +739,10 @@ def build_validation_report( *, base_model: str, include_native_vllm_lora: bool = False, + include_sensitivity: bool | None = None, + output_json: str | Path | None = None, + skip_stages: set[str] | None = None, + stop_on_failure: bool = False, allow_unvalidated_arch: bool = False, ) -> ValidationReport: report = initialize_validation_report( @@ -643,11 +750,6 @@ def build_validation_report( include_native_vllm_lora=include_native_vllm_lora, allow_unvalidated_arch=allow_unvalidated_arch, ) - architecture = ( - inspect_architecture(base_model, allow_unvalidated_arch=True) - if allow_unvalidated_arch - else inspect_architecture(base_model) - ) stage_runners = { "hf_parity": run_hf_parity_stage, "lora_coverage": run_lora_coverage_stage, @@ -659,51 +761,179 @@ def build_validation_report( "yes_no_trainability": run_yes_no_trainability_stage, NATIVE_VLLM_LORA_STAGE: run_native_vllm_lora_stage, } - stage_results: dict[str, ValidationStageResult] = {} - for stage_name, stage_runner in stage_runners.items(): - if stage_name in SUBPROCESS_VALIDATION_STAGES: - stage_results[stage_name] = _run_stage_in_subprocess( - stage_name=stage_name, - base_model=base_model, - architecture=architecture, - allow_unvalidated_arch=allow_unvalidated_arch, - ) - continue - try: - stage_results[stage_name] = stage_runner( - base_model=base_model, - architecture=architecture, - allow_unvalidated_arch=allow_unvalidated_arch, - ) - except Exception as exc: - stage_results[stage_name] = ValidationStageResult( - name=stage_name, - passed=False, - metrics=_stage_error_metrics(exc), - ) - for stage in report.stages: - if stage.name == "dependency_resolution": - stage.passed = True - stage.metrics = dict(report.dependency_versions) - continue - if stage.name != "architecture_discovery": - stage_result = stage_results.get(stage.name) - if stage_result is not None: - stage.passed = stage_result.passed - stage.metrics = dict(stage_result.metrics) - stage.artifact_dir = stage_result.artifact_dir - continue - stage.passed = not architecture.unresolved_risks - stage.metrics = { - "recommended_min_layers": architecture.recommended_min_layers, - "layer_families": [ - family.model_dump() for family in architecture.layer_families - ], - "unresolved_risks": list(architecture.unresolved_risks), - } + env = ( + {SKIP_SENSITIVITY_ENV: "0" if include_sensitivity else "1"} + if include_sensitivity is not None + else {} + ) + skip_stages = skip_stages or set() + architecture: ArchitectureReport | None = None + context = _temporary_env(**env) if env else nullcontext() + with context: + for stage in report.stages: + if stage.name in skip_stages: + stage.passed = True + stage.metrics = {"skipped": True, "reason": "--skip-stage"} + _write_validation_report(report, output_json) + continue + if stage.name == "dependency_resolution": + stage.passed = True + stage.metrics = dict(report.dependency_versions) + _write_validation_report(report, output_json) + continue + if stage.name == "architecture_discovery": + try: + architecture = _inspect_architecture_for_workflow( + base_model, + allow_unvalidated_arch=allow_unvalidated_arch, + ) + stage.passed = not architecture.unresolved_risks + stage.metrics = { + "recommended_min_layers": architecture.recommended_min_layers, + "layer_families": [ + family.model_dump() + for family in architecture.layer_families + ], + "unresolved_risks": list(architecture.unresolved_risks), + } + except Exception as exc: + stage.passed = False + stage.metrics = _stage_error_metrics(exc) + _write_validation_report(report, output_json) + if stop_on_failure and not stage.passed: + _mark_remaining_stages_skipped(report, after_stage_name=stage.name) + _write_validation_report(report, output_json) + break + continue + if architecture is None: + raise RuntimeError( + "architecture_discovery must run before subprocess stages" + ) + stage_runner = stage_runners[stage.name] + if stage.name in SUBPROCESS_VALIDATION_STAGES: + stage_result = _run_stage_in_subprocess( + stage_name=stage.name, + base_model=base_model, + architecture=architecture, + allow_unvalidated_arch=allow_unvalidated_arch, + ) + else: + try: + stage_result = stage_runner( + base_model=base_model, + architecture=architecture, + allow_unvalidated_arch=allow_unvalidated_arch, + ) + except Exception as exc: + stage_result = ValidationStageResult( + name=stage.name, + passed=False, + metrics=_stage_error_metrics(exc), + ) + stage.passed = stage_result.passed + stage.metrics = dict(stage_result.metrics) + stage.artifact_dir = stage_result.artifact_dir + _write_validation_report(report, output_json) + if stop_on_failure and not stage.passed: + _mark_remaining_stages_skipped(report, after_stage_name=stage.name) + _write_validation_report(report, output_json) + break return report +def build_all_architectures_validation_report( + *, + include_sensitivity: bool | None = None, + output_json: str | Path | None = None, + skip_stages: set[str] | None = None, + stop_on_failure: bool = False, + allow_unvalidated_arch: bool = False, +) -> AllArchitecturesValidationReport: + aggregate = AllArchitecturesValidationReport() + _write_all_architectures_report(aggregate, output_json) + for base_model in validated_architecture_representative_models(): + model_key = get_model_support_spec( + base_model, + allow_unvalidated_arch=allow_unvalidated_arch, + ).key + report = build_validation_report( + base_model=base_model, + include_sensitivity=include_sensitivity, + output_json=( + _per_architecture_output_json(output_json, model_key) + if output_json is not None + else None + ), + skip_stages=skip_stages, + stop_on_failure=stop_on_failure, + allow_unvalidated_arch=allow_unvalidated_arch, + ) + aggregate.reports.append(report) + aggregate.passed = all( + all(stage.passed for stage in model_report.stages) + for model_report in aggregate.reports + ) + _write_all_architectures_report(aggregate, output_json) + if stop_on_failure and not all(stage.passed for stage in report.stages): + break + return aggregate + + +def _parse_args(argv: list[str] | None = None) -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Run ART Megatron model support workflow" + ) + model_group = parser.add_mutually_exclusive_group(required=True) + model_group.add_argument("--base-model") + model_group.add_argument("--all-architectures", action="store_true") + parser.add_argument("--output-json", required=True) + parser.add_argument("--allow-unsupported-arch", action="store_true") + parser.add_argument("--include-sensitivity", action="store_true") + parser.add_argument("--skip-stage", action="append", default=[]) + parser.add_argument("--stop-on-failure", action="store_true") + return parser.parse_args(argv) + + +def main(argv: list[str] | None = None) -> int: + args = _parse_args(argv) + if args.all_architectures: + all_report = build_all_architectures_validation_report( + include_sensitivity=args.include_sensitivity, + output_json=args.output_json, + skip_stages=set(args.skip_stage), + stop_on_failure=args.stop_on_failure, + allow_unvalidated_arch=args.allow_unsupported_arch, + ) + for report in all_report.reports: + print(f"base_model={report.base_model}", flush=True) + for stage in report.stages: + status = "PASS" if stage.passed else "FAIL" + print(f" {stage.name}: {status}", flush=True) + if stage.artifact_dir: + print(f" artifact_dir={stage.artifact_dir}", flush=True) + if not stage.passed: + print(f" metrics={stage.metrics}", flush=True) + print(f"report_json={args.output_json}", flush=True) + return 0 if all_report.passed else 1 + report = build_validation_report( + base_model=args.base_model, + include_sensitivity=args.include_sensitivity, + output_json=args.output_json, + skip_stages=set(args.skip_stage), + stop_on_failure=args.stop_on_failure, + allow_unvalidated_arch=args.allow_unsupported_arch, + ) + for stage in report.stages: + status = "PASS" if stage.passed else "FAIL" + print(f"{stage.name}: {status}", flush=True) + if stage.artifact_dir: + print(f" artifact_dir={stage.artifact_dir}", flush=True) + if not stage.passed: + print(f" metrics={stage.metrics}", flush=True) + print(f"report_json={args.output_json}", flush=True) + return 0 if all(stage.passed for stage in report.stages) else 1 + + def assess_minimal_layer_coverage( *, base_model: str, @@ -712,9 +942,10 @@ def assess_minimal_layer_coverage( allow_unvalidated_arch: bool = False, ) -> MinimalLayerCoverageReport: architecture_report = architecture or ( - inspect_architecture(base_model, allow_unvalidated_arch=True) - if allow_unvalidated_arch - else inspect_architecture(base_model) + _inspect_architecture_for_workflow( + base_model, + allow_unvalidated_arch=allow_unvalidated_arch, + ) ) missing_layer_families = [ family.key @@ -730,3 +961,7 @@ def assess_minimal_layer_coverage( missing_layer_families=missing_layer_families, unresolved_risks=list(architecture_report.unresolved_risks), ) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/integration/megatron/routing_replay/__init__.py b/tests/integration/megatron/routing_replay/__init__.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/integration/megatron/routing_replay/__init__.py @@ -0,0 +1 @@ + diff --git a/tests/integration/megatron/routing_replay/bundle.py b/tests/integration/megatron/routing_replay/bundle.py new file mode 100644 index 000000000..f9cab1c40 --- /dev/null +++ b/tests/integration/megatron/routing_replay/bundle.py @@ -0,0 +1,234 @@ +from __future__ import annotations + +from pathlib import Path +from typing import Any + +import torch + +from art.megatron.routing_replay import ( + ROUTER_NAME_TOKEN, + MoeRoutingReplayBundle, + ParallelTopology, + RouterCallRoute, + StepRouterRoutes, + StepRoutes, + build_router_key_from_trace_name, +) + + +def _flatten_router_tensor(tensor: torch.Tensor) -> torch.Tensor: + if tensor.ndim < 2: + raise RuntimeError( + f"Router tensor must have rank >=2, got shape={tuple(tensor.shape)}" + ) + num_experts = int(tensor.shape[-1]) + return tensor.reshape(-1, num_experts).contiguous() + + +def _extract_router_output_tensors(output: Any) -> tuple[torch.Tensor, torch.Tensor]: + if isinstance(output, (list, tuple)) and len(output) >= 2: + probs, routing_map = output[0], output[1] + elif isinstance(output, dict): + probs = output.get("probs") + routing_map = output.get("routing_map") + else: + raise RuntimeError(f"Unsupported router output type: {type(output)}") + if not isinstance(probs, torch.Tensor): + raise RuntimeError(f"Expected probs tensor, got {type(probs)}") + if not isinstance(routing_map, torch.Tensor): + raise RuntimeError(f"Expected routing_map tensor, got {type(routing_map)}") + probs_2d = _flatten_router_tensor(probs.to(torch.float32)) + routing_map_2d = _flatten_router_tensor(routing_map.bool()) + if probs_2d.shape != routing_map_2d.shape: + raise RuntimeError( + "Router output shape mismatch: " + f"probs={tuple(probs_2d.shape)} routing_map={tuple(routing_map_2d.shape)}" + ) + return probs_2d, routing_map_2d + + +def _extract_dp_slot_from_rank_meta(rank_meta: Any) -> tuple[int, int] | None: + if isinstance(rank_meta, dict): + rank_meta = [rank_meta] + if not isinstance(rank_meta, list) or not rank_meta: + return None + dp_ranks = { + int(item["dp_rank"]) + for item in rank_meta + if isinstance(item, dict) and "dp_rank" in item + } + dp_world_sizes = { + int(item["dp_world_size"]) + for item in rank_meta + if isinstance(item, dict) and "dp_world_size" in item + } + if len(dp_ranks) != 1 or len(dp_world_sizes) != 1: + return None + return next(iter(dp_ranks)), next(iter(dp_world_sizes)) + + +def _trace_call_route_metadata( + call_entry: dict[str, Any], +) -> tuple[int | None, int | None]: + sample_index = call_entry.get("micro_sample_index") + if isinstance(sample_index, int): + return int(sample_index), None + dp_slot = _extract_dp_slot_from_rank_meta(call_entry.get("rank_meta")) + micro_order = int(call_entry.get("micro_order", 0)) + if dp_slot is None: + return None, micro_order + dp_rank, dp_world_size = dp_slot + return None, micro_order * dp_world_size + dp_rank + + +def _same_route(left: RouterCallRoute, right: RouterCallRoute) -> bool: + return bool( + left.num_experts == right.num_experts + and torch.equal(left.expert_indices, right.expert_indices) + and torch.equal(left.expert_mask, right.expert_mask) + ) + + +def _compact_route_from_dense( + _probs_2d: torch.Tensor, + routing_map_2d: torch.Tensor, +) -> RouterCallRoute: + num_tokens, num_experts = routing_map_2d.shape + if num_tokens == 0: + return RouterCallRoute( + expert_indices=torch.zeros((0, 0), dtype=torch.int32), + expert_mask=torch.zeros((0, 0), dtype=torch.bool), + num_experts=num_experts, + ) + topk_by_row = routing_map_2d.sum(dim=1) + if not bool((topk_by_row == topk_by_row[0]).all().item()): + raise RuntimeError( + "Megatron Core RouterReplay requires a fixed topk for every token row; " + f"observed row counts={torch.unique(topk_by_row).tolist()}" + ) + topk = int(topk_by_row[0].item()) + expert_indices = torch.zeros((num_tokens, topk), dtype=torch.int32) + for token_index in range(num_tokens): + expert_ids = torch.nonzero( + routing_map_2d[token_index], as_tuple=False + ).flatten() + if int(expert_ids.numel()) != topk: + raise RuntimeError( + f"Unexpected route topk for token={token_index}: " + f"expected={topk}, got={int(expert_ids.numel())}" + ) + expert_indices[token_index] = expert_ids.to(torch.int32) + return RouterCallRoute( + expert_indices=expert_indices, + expert_mask=torch.ones_like(expert_indices, dtype=torch.bool), + num_experts=num_experts, + ) + + +def build_bundle_from_forward_trace_dir( + *, + traces_dir: str | Path, + num_steps: int, + topology: ParallelTopology, +) -> MoeRoutingReplayBundle: + trace_dir = Path(traces_dir) + steps: dict[int, StepRoutes] = {} + router_keys_union: set[str] = set() + max_topk = 0 + + for step_index in range(num_steps): + trace_path = trace_dir / f"forward_trace_step_{step_index:03d}.pt" + if not trace_path.exists(): + raise FileNotFoundError( + f"Missing forward trace for step={step_index}: {trace_path}" + ) + step_trace: dict[str, list[dict[str, Any]]] = torch.load( + trace_path, map_location="cpu", weights_only=False + ) + + step_routers: dict[str, StepRouterRoutes] = {} + step_global_tokens: int | None = None + for module_name in sorted(step_trace.keys()): + if ROUTER_NAME_TOKEN not in module_name: + continue + router_key = build_router_key_from_trace_name(module_name) + router_calls: dict[int, RouterCallRoute] = {} + calls_by_micro_key: dict[tuple[str, int], int] = {} + for call_index, call_entry in enumerate(step_trace[module_name]): + probs_2d, routing_map_2d = _extract_router_output_tensors( + call_entry.get("output") + ) + compact_route = _compact_route_from_dense(probs_2d, routing_map_2d) + sample_index, micro_slot = _trace_call_route_metadata(call_entry) + compact_route.sample_index = sample_index + compact_route.micro_slot = micro_slot + micro_key = ( + ("sample", int(sample_index)) + if sample_index is not None + else ( + ("dummy_micro_slot", int(micro_slot)) + if micro_slot is not None + else None + ) + ) + if micro_key is not None and micro_key in calls_by_micro_key: + existing_call_index = calls_by_micro_key[micro_key] + existing_route = router_calls[existing_call_index] + if not _same_route(existing_route, compact_route): + raise RuntimeError( + "Router trace contains conflicting duplicate routes for " + f"router='{router_key}', step={step_index}, " + f"micro_key={micro_key}, existing_call={existing_call_index}, " + f"duplicate_call={call_index}" + ) + continue + stored_call_index = len(router_calls) + if micro_key is not None: + calls_by_micro_key[micro_key] = stored_call_index + router_calls[stored_call_index] = compact_route + max_topk = max(max_topk, compact_route.max_topk) + token_count = compact_route.num_global_tokens + if step_global_tokens is None: + step_global_tokens = token_count + elif step_global_tokens != token_count: + raise RuntimeError( + "Inconsistent token count across routers within step: " + f"step={step_index}, expected={step_global_tokens}, " + f"got={token_count}, router='{router_key}', call={call_index}" + ) + if not router_calls: + raise RuntimeError( + f"Router trace has no calls for module '{module_name}' " + f"at step={step_index}" + ) + step_routers[router_key] = StepRouterRoutes(calls=router_calls) + router_keys_union.add(router_key) + + if not step_routers: + raise RuntimeError( + f"No router traces found for step={step_index} in {trace_path}" + ) + if step_global_tokens is None: + raise RuntimeError( + f"Could not infer token count for step={step_index} from router traces" + ) + steps[step_index] = StepRoutes( + routers=step_routers, + global_token_uids=torch.arange(step_global_tokens, dtype=torch.int64), + ) + + router_keys = sorted(router_keys_union) + for step_index, step_routes in steps.items(): + if set(step_routes.routers) != set(router_keys): + raise RuntimeError( + f"Step {step_index} router keys differ from global set: " + f"step_keys={sorted(step_routes.routers)}, router_keys={router_keys}" + ) + + return MoeRoutingReplayBundle( + topology=topology, + num_steps=num_steps, + max_topk=max_topk, + router_keys=router_keys, + steps=steps, + ) diff --git a/tests/integration/megatron/routing_replay/trace.py b/tests/integration/megatron/routing_replay/trace.py new file mode 100644 index 000000000..6bb2402be --- /dev/null +++ b/tests/integration/megatron/routing_replay/trace.py @@ -0,0 +1,475 @@ +from __future__ import annotations + +from typing import Any, Callable + +from megatron.core.tensor_parallel import ( + all_to_all, + gather_from_sequence_parallel_region, +) +from megatron.core.transformer.moe.moe_utils import permute, sort_chunks_by_idxs +import torch + +TRACE_ROW_TOKEN_UIDS_ATTR = "_art_trace_row_token_uids" +TRACE_UID_SPAN_ATTR = "_art_trace_uid_span" +_CONTROLLER_GETTER: Callable[[], Any | None] | None = None + + +def _active_controller() -> Any | None: + if _CONTROLLER_GETTER is None: + return None + return _CONTROLLER_GETTER() + + +def _dispatcher_local_token_uids( + controller: Any, + dispatcher: Any, + *, + num_local_tokens: int, +) -> torch.Tensor: + step_routes = controller._active_step_routes + if step_routes is None: + raise RuntimeError("Routing replay dispatcher used without an active step") + local_uids = controller.local_token_indexer.build_local_token_uids( + global_token_uids=step_routes.global_token_uids, + num_local_tokens=num_local_tokens, + sequence_parallel=bool( + getattr(getattr(dispatcher, "config", None), "sequence_parallel", False) + ), + context_parallel_size=int( + getattr(getattr(dispatcher, "config", None), "context_parallel_size", 1) + ), + ) + sample_index = getattr(controller, "_active_sample_index", None) + uid_span = int(step_routes.global_token_uids.numel()) + if isinstance(sample_index, int) and sample_index >= 0 and uid_span > 0: + local_uids = local_uids + sample_index * uid_span + return local_uids + + +def _trace_row_uids_from_source(source: Any) -> tuple[torch.Tensor | None, int | None]: + row_token_uids = getattr(source, TRACE_ROW_TOKEN_UIDS_ATTR, None) + if not isinstance(row_token_uids, torch.Tensor): + return None, None + uid_span = getattr(source, TRACE_UID_SPAN_ATTR, None) + uid_span_int = uid_span if isinstance(uid_span, int) and uid_span > 0 else None + return row_token_uids, uid_span_int + + +def _attach_trace_row_uids( + target: Any, + *, + row_token_uids: torch.Tensor, + uid_span: int | None, +) -> None: + setattr( + target, + TRACE_ROW_TOKEN_UIDS_ATTR, + row_token_uids.detach().to(device="cpu", dtype=torch.int64).reshape(-1), + ) + setattr(target, TRACE_UID_SPAN_ATTR, uid_span) + + +@torch._dynamo.disable +def _propagate_grouped_mlp_trace_row_uids(source: Any, linear_fc2: Any) -> None: + row_token_uids, uid_span = _trace_row_uids_from_source(source) + if row_token_uids is None: + return + _attach_trace_row_uids( + linear_fc2, + row_token_uids=row_token_uids, + uid_span=uid_span, + ) + + +@torch._dynamo.disable +def _propagate_fc2_trace_row_uids( + *, + x: Any, + module: Any, + linear_fc2: Any, + lora: Any, +) -> None: + row_token_uids, uid_span = _trace_row_uids_from_source(x) + if row_token_uids is None: + row_token_uids, uid_span = _trace_row_uids_from_source(module) + if row_token_uids is None: + return + _attach_trace_row_uids( + linear_fc2, + row_token_uids=row_token_uids, + uid_span=uid_span, + ) + _attach_trace_row_uids( + lora, + row_token_uids=row_token_uids, + uid_span=uid_span, + ) + + +def _canonicalize_expert_token_order( + expert_inputs: torch.Tensor, + expert_probs: torch.Tensor, + expert_token_uids: torch.Tensor, + *, + tokens_per_expert: torch.Tensor | list[int], +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]: + counts = ( + [int(count) for count in tokens_per_expert.tolist()] + if isinstance(tokens_per_expert, torch.Tensor) + else [int(count) for count in tokens_per_expert] + ) + if sum(counts) != int(expert_token_uids.numel()): + raise RuntimeError( + "Expert token uid count mismatch after dispatch: " + f"uids={int(expert_token_uids.numel())}, " + f"tokens_per_expert_sum={sum(counts)}" + ) + + order_segments: list[torch.Tensor] = [] + cursor = 0 + for count in counts: + if count <= 1: + order_segments.append( + torch.arange(cursor, cursor + count, dtype=torch.long) + ) + cursor += count + continue + segment_uids = expert_token_uids[cursor : cursor + count].to(device="cpu") + order_segments.append(torch.argsort(segment_uids, stable=True) + cursor) + cursor += count + if not order_segments: + empty = torch.empty(0, dtype=torch.long) + return expert_inputs, expert_probs, expert_token_uids, empty + + canonical_order_cpu = torch.cat(order_segments, dim=0) + inverse_order_cpu = torch.empty_like(canonical_order_cpu) + inverse_order_cpu[canonical_order_cpu] = torch.arange( + canonical_order_cpu.numel(), dtype=torch.long + ) + canonical_order = canonical_order_cpu.to( + device=expert_inputs.device, dtype=torch.long + ) + return ( + expert_inputs.index_select(0, canonical_order), + expert_probs.index_select(0, canonical_order), + expert_token_uids.index_select( + 0, + canonical_order_cpu.to(device=expert_token_uids.device, dtype=torch.long), + ), + inverse_order_cpu, + ) + + +def _canonical_trace_row_uids( + expert_token_uids: torch.Tensor, + *, + tokens_per_expert: torch.Tensor | list[int], + local_expert_indices: list[int] | tuple[int, ...] | None, + sample_uid_span: int, + num_experts: int, +) -> tuple[torch.Tensor, int]: + counts = ( + [int(count) for count in tokens_per_expert.tolist()] + if isinstance(tokens_per_expert, torch.Tensor) + else [int(count) for count in tokens_per_expert] + ) + expert_indices = ( + [int(expert_index) for expert_index in local_expert_indices] + if local_expert_indices is not None + else list(range(len(counts))) + ) + if len(expert_indices) != len(counts): + raise RuntimeError( + "Local expert index metadata mismatch: " + f"num_expert_indices={len(expert_indices)}, num_counts={len(counts)}" + ) + row_uid_span = sample_uid_span * max(int(num_experts), 1) + row_uid_chunks: list[torch.Tensor] = [] + cursor = 0 + for global_expert_id, count in zip(expert_indices, counts, strict=True): + segment = expert_token_uids[cursor : cursor + count].to(dtype=torch.int64) + sample_ids = torch.div(segment, sample_uid_span, rounding_mode="floor") + local_token_ids = torch.remainder(segment, sample_uid_span) + row_uid_chunks.append( + sample_ids * row_uid_span + + int(global_expert_id) * sample_uid_span + + local_token_ids + ) + cursor += count + if cursor != int(expert_token_uids.numel()): + raise RuntimeError( + "Canonical trace row uid construction did not consume all expert rows: " + f"consumed={cursor}, total={int(expert_token_uids.numel())}" + ) + if not row_uid_chunks: + return expert_token_uids.new_empty((0,), dtype=torch.int64), row_uid_span + return torch.cat(row_uid_chunks, dim=0).contiguous(), row_uid_span + + +@torch._dynamo.disable +def _build_dispatch_postprocess_trace( + *, + dispatcher: Any, + controller: Any, + global_input_token_uids: torch.Tensor, + expert_inputs: torch.Tensor, + expert_probs: torch.Tensor, + tokens_per_expert: torch.Tensor | list[int], +) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, int]: + expert_token_uids = global_input_token_uids + if dispatcher.num_local_experts > 1: + sorted_token_uids = sort_chunks_by_idxs( + expert_token_uids.unsqueeze(-1), + dispatcher.num_global_tokens_per_local_expert.ravel(), + dispatcher.sort_input_by_local_experts, + fused=False, + )[0] + expert_token_uids = sorted_token_uids.reshape(-1).contiguous() + ( + expert_inputs, + expert_probs, + canonical_expert_token_uids, + inverse_order_cpu, + ) = _canonicalize_expert_token_order( + expert_inputs, + expert_probs, + expert_token_uids, + tokens_per_expert=tokens_per_expert, + ) + active_step_routes = controller._active_step_routes + if active_step_routes is None: + raise RuntimeError("MoE replay dispatcher preprocess called before set_step") + trace_row_uids, trace_uid_span = _canonical_trace_row_uids( + canonical_expert_token_uids, + tokens_per_expert=tokens_per_expert, + local_expert_indices=getattr(dispatcher, "local_expert_indices", None), + sample_uid_span=int(active_step_routes.global_token_uids.numel()), + num_experts=int(getattr(dispatcher, "num_experts", 1)), + ) + return ( + expert_inputs, + expert_probs, + inverse_order_cpu, + trace_row_uids, + trace_uid_span, + ) + + +def install_moe_routing_trace_hooks( + controller_getter: Callable[[], Any | None], +) -> None: + global _CONTROLLER_GETTER + _CONTROLLER_GETTER = controller_getter + try: + from megatron.core.transformer.moe.experts import TEGroupedMLP + from megatron.core.transformer.moe.token_dispatcher import ( + MoEAlltoAllTokenDispatcher, + ) + + from art.megatron.lora import MLPExpertsLinearFC2LoRA + except Exception: + return + + if hasattr(MoEAlltoAllTokenDispatcher, "_art_oracle_trace_patched"): + return + + original_preprocess = MoEAlltoAllTokenDispatcher.preprocess + original_dispatch_preprocess = MoEAlltoAllTokenDispatcher.dispatch_preprocess + original_token_dispatch = MoEAlltoAllTokenDispatcher.token_dispatch + original_dispatch_postprocess = MoEAlltoAllTokenDispatcher.dispatch_postprocess + original_combine_preprocess = MoEAlltoAllTokenDispatcher.combine_preprocess + original_te_grouped_mlp_forward = TEGroupedMLP.forward + original_fc2_forward = MLPExpertsLinearFC2LoRA.forward + + def patched_preprocess( + self: Any, routing_map: torch.Tensor, *args: Any, **kwargs: Any + ): + result = original_preprocess(self, routing_map, *args, **kwargs) + if ( + not getattr(self, "drop_and_pad", False) + and getattr(self.config, "moe_expert_capacity_factor", None) is None + and not ( + getattr(self.config, "moe_router_padding_for_quantization", None) + or getattr(self.config, "moe_router_padding_for_fp8", None) + ) + ): + self.num_out_tokens = int(routing_map.sum().item()) + return result + + def patched_dispatch_preprocess( + self: Any, + hidden_states: torch.Tensor, + routing_map: torch.Tensor, + probs: torch.Tensor, + ): + result = original_dispatch_preprocess(self, hidden_states, routing_map, probs) + self._art_replay_permuted_local_token_uids = None + self._art_replay_global_input_token_uids = None + self._art_replay_expert_input_inverse_permutation = None + + controller = _active_controller() + if controller is None: + return result + local_token_uids = _dispatcher_local_token_uids( + controller, + self, + num_local_tokens=int(routing_map.shape[0]), + ) + permuted_local_uids = permute( + local_token_uids.to( + device=hidden_states.device, dtype=torch.int64 + ).unsqueeze(-1), + self.routing_map, + num_out_tokens=self.num_out_tokens, + fused=False, + drop_and_pad=self.drop_and_pad, + )[0] + self._art_replay_permuted_local_token_uids = permuted_local_uids.reshape( + -1 + ).contiguous() + return result + + def patched_token_dispatch( + self: Any, + permutated_local_input_tokens: torch.Tensor, + permuted_probs: torch.Tensor, + ): + result = original_token_dispatch( + self, + permutated_local_input_tokens, + permuted_probs, + ) + controller = _active_controller() + permuted_local_token_uids = getattr( + self, "_art_replay_permuted_local_token_uids", None + ) + if controller is None or permuted_local_token_uids is None: + return result + + global_token_uids = permuted_local_token_uids.to( + device=permutated_local_input_tokens.device, dtype=torch.int64 + ).unsqueeze(-1) + if self.ep_size > 1: + global_token_uids = all_to_all( + self.ep_group, + global_token_uids, + self.output_splits, + self.input_splits, + ) + if self.tp_size > 1: + output_split_sizes = ( + None + if self.output_splits_tp is None + else self.output_splits_tp.tolist() + ) + global_token_uids = gather_from_sequence_parallel_region( + global_token_uids, + group=self.tp_group, + output_split_sizes=output_split_sizes, + ) + self._art_replay_global_input_token_uids = global_token_uids.reshape( + -1 + ).contiguous() + return result + + def patched_dispatch_postprocess( + self: Any, + global_input_tokens: torch.Tensor, + global_probs: torch.Tensor, + ): + expert_inputs, tokens_per_expert, expert_probs = original_dispatch_postprocess( + self, + global_input_tokens, + global_probs, + ) + controller = _active_controller() + global_input_token_uids = getattr( + self, "_art_replay_global_input_token_uids", None + ) + if controller is None or global_input_token_uids is None or self.drop_and_pad: + return expert_inputs, tokens_per_expert, expert_probs + + ( + expert_inputs, + expert_probs, + inverse_order_cpu, + trace_row_uids, + trace_uid_span, + ) = _build_dispatch_postprocess_trace( + dispatcher=self, + controller=controller, + global_input_token_uids=global_input_token_uids, + expert_inputs=expert_inputs, + expert_probs=expert_probs, + tokens_per_expert=tokens_per_expert, + ) + self._art_replay_expert_input_inverse_permutation = inverse_order_cpu + _attach_trace_row_uids( + expert_inputs, + row_token_uids=trace_row_uids, + uid_span=trace_uid_span, + ) + return expert_inputs, tokens_per_expert, expert_probs + + def patched_combine_preprocess(self: Any, hidden_states: torch.Tensor): + inverse_order_cpu = getattr( + self, "_art_replay_expert_input_inverse_permutation", None + ) + if inverse_order_cpu is not None and inverse_order_cpu.numel() > 0: + hidden_states = hidden_states.index_select( + 0, + inverse_order_cpu.to(device=hidden_states.device, dtype=torch.long), + ) + self._art_replay_expert_input_inverse_permutation = None + return original_combine_preprocess(self, hidden_states) + + def patched_te_grouped_mlp_forward( + self: Any, + permuted_local_hidden_states: torch.Tensor, + tokens_per_expert: torch.Tensor, + permuted_probs: torch.Tensor, + ): + _propagate_grouped_mlp_trace_row_uids( + permuted_local_hidden_states, + self.linear_fc2, + ) + return original_te_grouped_mlp_forward( + self, + permuted_local_hidden_states, + tokens_per_expert, + permuted_probs, + ) + + def patched_fc2_forward( + self: Any, + x: torch.Tensor, + tokens_per_expert: list[int] | torch.Tensor, + ) -> tuple[torch.Tensor, torch.Tensor | None]: + _propagate_fc2_trace_row_uids( + x=x, + module=self, + linear_fc2=self.linear_fc2, + lora=self.lora, + ) + return original_fc2_forward(self, x, tokens_per_expert) + + setattr(MoEAlltoAllTokenDispatcher, "preprocess", patched_preprocess) + setattr( + MoEAlltoAllTokenDispatcher, + "dispatch_preprocess", + patched_dispatch_preprocess, + ) + setattr(MoEAlltoAllTokenDispatcher, "token_dispatch", patched_token_dispatch) + setattr( + MoEAlltoAllTokenDispatcher, + "dispatch_postprocess", + patched_dispatch_postprocess, + ) + setattr( + MoEAlltoAllTokenDispatcher, + "combine_preprocess", + patched_combine_preprocess, + ) + setattr(TEGroupedMLP, "forward", patched_te_grouped_mlp_forward) + setattr(MLPExpertsLinearFC2LoRA, "forward", patched_fc2_forward) + setattr(MoEAlltoAllTokenDispatcher, "_art_oracle_trace_patched", True) diff --git a/tests/integration/megatron/runtime_isolation/test_runtime_launcher.py b/tests/integration/megatron/runtime_isolation/test_runtime_launcher.py index 58b4faf99..0cb4bac95 100644 --- a/tests/integration/megatron/runtime_isolation/test_runtime_launcher.py +++ b/tests/integration/megatron/runtime_isolation/test_runtime_launcher.py @@ -1,7 +1,6 @@ import importlib.util import os from pathlib import Path -from types import SimpleNamespace import pytest @@ -72,38 +71,6 @@ def test_build_runtime_server_cmd_honors_runtime_bin_override(monkeypatch) -> No assert command[:2] == ["/opt/art/bin/runtime", "--wrapped"] -def test_get_vllm_runtime_nccl_so_path_queries_runtime_python( - monkeypatch, - tmp_path: Path, -) -> None: - monkeypatch.delenv("ART_VLLM_RUNTIME_BIN", raising=False) - runtime_root = tmp_path / "custom-runtime" - runtime_bin = runtime_root / ".venv" / "bin" / "art-vllm-runtime-server" - runtime_python = runtime_root / ".venv" / "bin" / "python" - runtime_bin.parent.mkdir(parents=True, exist_ok=True) - runtime_bin.write_text("#!/bin/sh\n", encoding="ascii") - runtime_python.write_text("#!/bin/sh\n", encoding="ascii") - nccl_so_path = tmp_path / "libnccl.so.2" - nccl_so_path.write_text("nccl\n", encoding="ascii") - seen: dict[str, object] = {} - - def fake_run(command, *, capture_output: bool, text: bool): - seen["command"] = command - seen["capture_output"] = capture_output - seen["text"] = text - return SimpleNamespace(returncode=0, stdout=f"{nccl_so_path}\n", stderr="") - - monkeypatch.setenv("ART_VLLM_RUNTIME_PROJECT_ROOT", str(runtime_root)) - monkeypatch.setattr(runtime.subprocess, "run", fake_run) - - assert runtime.get_vllm_runtime_nccl_so_path() == nccl_so_path.resolve() - command = seen["command"] - assert isinstance(command, list) - assert command[0] == str(runtime_python) - assert seen["capture_output"] is True - assert seen["text"] is True - - def test_cleanup_old_managed_runtimes_only_deletes_marked_venvs( monkeypatch, tmp_path: Path, diff --git a/tests/integration/megatron/runtime_isolation/test_runtime_project_isolation.py b/tests/integration/megatron/runtime_isolation/test_runtime_project_isolation.py index a0c9ce492..10d9edc3c 100644 --- a/tests/integration/megatron/runtime_isolation/test_runtime_project_isolation.py +++ b/tests/integration/megatron/runtime_isolation/test_runtime_project_isolation.py @@ -42,6 +42,46 @@ def test_runtime_server_source_contains_only_required_custom_routes() -> None: assert route in source +def test_runtime_patch_always_returns_token_ids( + artifact_dir: Path, +) -> None: + result = subprocess.run( + [ + "uv", + "run", + "--project", + str(ROOT / "vllm_runtime"), + "python", + "-c", + ( + "import json, os; " + "from art_vllm_runtime.patches import apply_vllm_runtime_patches; " + "apply_vllm_runtime_patches(); " + "from vllm.entrypoints.openai.chat_completion import protocol; " + "request = protocol.ChatCompletionRequest(" + "model='m', messages=[{'role': 'user', 'content': 'x'}]" + "); " + "print(json.dumps({" + "'logprobs': request.logprobs, " + "'top_logprobs': request.top_logprobs, " + "'return_token_ids': request.return_token_ids" + "}))" + ), + ], + cwd=ROOT, + check=True, + capture_output=True, + text=True, + ) + (artifact_dir / "route_token_ids_stdout.txt").write_text(result.stdout) + (artifact_dir / "route_token_ids_stderr.txt").write_text(result.stderr) + assert json.loads(result.stdout.strip()) == { + "logprobs": True, + "top_logprobs": 0, + "return_token_ids": True, + } + + def test_runtime_general_plugin_loads_full_patch_set() -> None: pyproject = (ROOT / "vllm_runtime" / "pyproject.toml").read_text() assert 'art = "art_vllm_runtime.patches:apply_vllm_runtime_patches"' in pyproject diff --git a/tests/integration/megatron/train_inf_mismatch/output_parity.py b/tests/integration/megatron/train_inf_mismatch/output_parity.py index e09d28e09..8fd5c0584 100644 --- a/tests/integration/megatron/train_inf_mismatch/output_parity.py +++ b/tests/integration/megatron/train_inf_mismatch/output_parity.py @@ -1,26 +1,32 @@ from __future__ import annotations -import argparse -import asyncio -from contextlib import asynccontextmanager, contextmanager import hashlib import json import math import os from pathlib import Path import random -import shutil -import socket -import subprocess -import sys -import time -from typing import Any, AsyncIterator, Literal, cast +from typing import Any, Literal, cast from pydantic import BaseModel, ConfigDict, Field, model_validator -from .artifacts import REPO_ROOT - -BF16_FWD_MEAN_ABS_PCT_LIMIT = 3.0 +# These gates are intentionally bf16-scale, not fp32 oracle-scale. A 2026-05-18 +# Qwen/Qwen3.5-35B-A3B diagnostic on the exact same real generated tokens found: +# vLLM generation vs Megatron: 2.916% mean_abs_pct, 0.0123 MAE, 0.883 top1, +# 0.976 top20; vLLM prompt_logprobs vs Megatron: 7.896%, 0.0334 MAE, 0.969 +# top1, 0.941 top20; vLLM generation vs vLLM prompt_logprobs: 7.517%, 0.0322 +# MAE, 0.879 top1, 0.941 top20. The real ART path also canonicalizes shared +# prefix routes when vLLM produced different routes for the same prefix. Do not +# tighten these thresholds without rechecking both vLLM self-mismatch and shared +# prefix route-conflict behavior on the measured path. With the workflow's +# 16-token completions, Qwen3.5 MoE reruns on 2026-05-25 measured 4.169% and +# 4.606% mean_abs_pct while staying under the KL gate, so its gate is 5%. +BF16_FWD_MEAN_ABS_PCT_LIMIT = 4.0 +BF16_FWD_MEAN_ABS_PCT_LIMIT_BY_MODEL_KEY = { + "qwen3_moe": 7.0, + "qwen3_5_moe": 5.0, +} +TOP20_KL_CANDIDATE_TO_TARGET_LIMIT = 0.002 MEAN_ABS_PCT_DENOMINATOR_EPS = 1e-18 TOP_K = 20 @@ -40,13 +46,23 @@ class Topology(BaseModel): pp: int = 1 def world_size(self) -> int: - return self.tp * self.dp * self.cp * self.pp + dense_world = self.tp * self.cp * self.pp * self.dp + expert_model_size = self.etp * self.ep * self.pp + if dense_world % expert_model_size != 0: + raise ValueError( + "Invalid Megatron MoE topology: " + f"tp*cp*pp*dp={dense_world} must be divisible by " + f"etp*ep*pp={expert_model_size}" + ) + return dense_world def env(self) -> dict[str, str]: return { "ART_MEGATRON_TENSOR_MODEL_PARALLEL_SIZE": str(self.tp), "ART_MEGATRON_EXPERT_MODEL_PARALLEL_SIZE": str(self.ep), "ART_MEGATRON_EXPERT_TENSOR_PARALLEL_SIZE": str(self.etp), + "ART_MEGATRON_CONTEXT_PARALLEL_SIZE": str(self.cp), + "ART_MEGATRON_PIPELINE_MODEL_PARALLEL_SIZE": str(self.pp), } def slug(self) -> str: @@ -78,6 +94,7 @@ class TrainInfOutputParityConfig(BaseModel): lora_target_modules: list[str] | None = None engine_args: dict[str, Any] = Field(default_factory=dict) server_args: dict[str, Any] = Field(default_factory=dict) + replay_vllm_routing: bool = False @model_validator(mode="after") def _set_default_rollout_modes(self) -> "TrainInfOutputParityConfig": @@ -94,6 +111,11 @@ class LogicalPrompt(BaseModel): sample_id: int family_id: int completion_id: int + # Packed prompt rows are the shared prefix segment exactly: prompt_end-start. + # ART stores the final context token at the start of each completion segment, + # so vLLM's generated-token logprobs start one token after this boundary. + packed_prompt_length: int + scored_token_start_index: int token_ids: list[int] @@ -163,34 +185,6 @@ class RolloutComparison(BaseModel): lora_topk: TopKComparison -class TrainInfOutputParityReport(BaseModel): - base_model: str - artifact_dir: str - topology: str - trainer_gpu_ids: list[int] - inference_gpu_ids: list[int] - logical_prompt_count: int - logical_token_count: int - adapter_path: str - megatron_base_scores: str - megatron_lora_scores: str - rollout_comparisons: list[RolloutComparison] - passed: bool - - -class MegatronWorkerRequest(BaseModel): - config: TrainInfOutputParityConfig - artifact_dir: str - weight_state: WeightState - adapter_path: str | None = None - - -class MegatronWorkerResult(BaseModel): - score_path: str - logical_map_path: str - adapter_path: str | None = None - - def _write_json(path: Path, payload: Any) -> None: path.parent.mkdir(parents=True, exist_ok=True) with path.open("w", encoding="utf-8") as handle: @@ -206,12 +200,6 @@ def _read_json(path: Path) -> dict[str, Any]: return value -def _free_port() -> int: - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: - sock.bind(("127.0.0.1", 0)) - return int(sock.getsockname()[1]) - - def _parse_gpu_ids(value: str | None, default: list[int]) -> list[int]: if value is None or value.strip() == "": return list(default) @@ -253,19 +241,38 @@ def default_rollout_modes_for_model( return modes -@contextmanager -def _provider_topology_env(topology: Topology) -> Any: - names = topology.env() - previous = {name: os.environ.get(name) for name in names} - os.environ.update(names) - try: - yield - finally: - for name, value in previous.items(): - if value is None: - os.environ.pop(name, None) - else: - os.environ[name] = value +def fwd_mean_abs_pct_limit_for_model( + base_model: str, + *, + allow_unvalidated_arch: bool = False, +) -> float: + from art.megatron.model_support.registry import get_model_support_spec + + spec = get_model_support_spec( + base_model, + allow_unvalidated_arch=allow_unvalidated_arch, + ) + return BF16_FWD_MEAN_ABS_PCT_LIMIT_BY_MODEL_KEY.get( + spec.key, + BF16_FWD_MEAN_ABS_PCT_LIMIT, + ) + + +def model_support_is_moe( + base_model: str, + *, + allow_unvalidated_arch: bool = False, +) -> bool: + from art.megatron.model_support.registry import ( + get_model_support_handler_for_spec, + get_model_support_spec, + ) + + spec = get_model_support_spec( + base_model, + allow_unvalidated_arch=allow_unvalidated_arch, + ) + return get_model_support_handler_for_spec(spec).is_moe def config_from_env() -> TrainInfOutputParityConfig: @@ -295,6 +302,20 @@ def config_from_env() -> TrainInfOutputParityConfig: config.packed.prefill_tokens = int(raw_prefill) if raw_decode := os.environ.get("ART_TRAIN_INF_MISMATCH_DECODE_TOKENS"): config.packed.decode_tokens = int(raw_decode) + for env_name, attr in ( + ("ART_TRAIN_INF_MISMATCH_TP", "tp"), + ("ART_TRAIN_INF_MISMATCH_EP", "ep"), + ("ART_TRAIN_INF_MISMATCH_ETP", "etp"), + ("ART_TRAIN_INF_MISMATCH_CP", "cp"), + ("ART_TRAIN_INF_MISMATCH_PP", "pp"), + ): + if raw_value := os.environ.get(env_name): + config.topology = config.topology.model_copy(update={attr: int(raw_value)}) + if not model_support_is_moe( + config.base_model, + allow_unvalidated_arch=config.allow_unvalidated_arch, + ): + config.topology = config.topology.model_copy(update={"ep": 1, "etp": 1}) if raw_targets := os.environ.get("ART_TRAIN_INF_MISMATCH_LORA_TARGET_MODULES"): config.lora_target_modules = _parse_str_list(raw_targets) return config @@ -374,6 +395,8 @@ def build_logical_token_map(packed_tensors: dict[str, Any]) -> LogicalTokenMap: sample_id=sample_id, family_id=family_id, completion_id=completion_id, + packed_prompt_length=prompt_len, + scored_token_start_index=prompt_len + 1, token_ids=flat, ) ) @@ -563,15 +586,15 @@ def compare_rollout( vl = torch.tensor(vllm_lora.target_logprobs, dtype=torch.float32) return RolloutComparison( rollout_mode=rollout_mode, - base=compare_pair(candidate=vb, target=mb, sequence_ids=sequence_ids), - lora=compare_pair(candidate=vl, target=ml, sequence_ids=sequence_ids), + base=compare_pair(candidate=mb, target=vb, sequence_ids=sequence_ids), + lora=compare_pair(candidate=ml, target=vl, sequence_ids=sequence_ids), delta=compare_pair( - candidate=vl - vb, - target=ml - mb, + candidate=ml - mb, + target=vl - vb, sequence_ids=sequence_ids, ), - base_topk=compare_topk(vllm_base, megatron_base), - lora_topk=compare_topk(vllm_lora, megatron_lora), + base_topk=compare_topk(megatron_base, vllm_base), + lora_topk=compare_topk(megatron_lora, vllm_lora), ) @@ -586,38 +609,50 @@ def _set_seed(seed: int) -> None: torch.cuda.manual_seed_all(seed) -def _packed_tensor_config(config: TrainInfOutputParityConfig) -> Any: - from ..model_support.oracle_harness import PackedTensorConfig - - return PackedTensorConfig( - num_sequences=config.packed.num_sequences, - sequence_length=config.packed.sequence_length, - prefill_tokens=config.packed.prefill_tokens, - completion_branches_per_prefix=config.packed.completion_branches_per_prefix, - decode_tokens=config.packed.decode_tokens, - decode_tokens_jitter=config.packed.decode_tokens_jitter, - vocab_high=config.packed.vocab_high, - packing_mode=config.packed.packing_mode, - ) - - -def _build_packed_tensors(config: TrainInfOutputParityConfig) -> dict[str, Any]: - from ..model_support.packed_position_ids import ( - _build_art_realistic_packed_tensors, - ) - - return _build_art_realistic_packed_tensors( - _packed_tensor_config(config), config.seed - ) - - def _configure_provider(provider: Any, config: TrainInfOutputParityConfig) -> None: + provider.tensor_model_parallel_size = config.topology.tp + provider.expert_model_parallel_size = config.topology.ep + provider.expert_tensor_parallel_size = config.topology.etp + provider.context_parallel_size = config.topology.cp + provider.pipeline_model_parallel_size = config.topology.pp if hasattr(provider, "attention_dropout"): provider.attention_dropout = 0.0 if hasattr(provider, "hidden_dropout"): provider.hidden_dropout = 0.0 +def _gather_context_parallel_logits(logits: Any, *, full_sequence_length: int) -> Any: + from megatron.core import parallel_state as ps + import torch + import torch.distributed as dist + + if int(ps.get_context_parallel_world_size()) <= 1: + return logits + if int(logits.shape[1]) == full_sequence_length: + return logits + cp_size = int(ps.get_context_parallel_world_size()) + local_chunks = [torch.empty_like(logits) for _ in range(cp_size)] + dist.all_gather( # ty: ignore[possibly-missing-attribute] + local_chunks, logits.contiguous(), group=ps.get_context_parallel_group() + ) + local_sequence_length = int(logits.shape[1]) + if local_sequence_length % 2 != 0: + raise RuntimeError( + "Cannot reconstruct context-parallel logits with odd local sequence " + f"length {local_sequence_length}" + ) + half = local_sequence_length // 2 + ordered = [chunk[:, :half] for chunk in local_chunks] + ordered.extend(chunk[:, half:] for chunk in reversed(local_chunks)) + gathered = torch.cat(ordered, dim=1) + if int(gathered.shape[1]) != full_sequence_length: + raise RuntimeError( + "Context-parallel logit gather produced unexpected sequence length: " + f"{int(gathered.shape[1])} != {full_sequence_length}" + ) + return gathered + + def _lora_target_modules(config: TrainInfOutputParityConfig) -> list[str]: from art.dev.get_model_config import default_target_modules @@ -706,7 +741,12 @@ def _adapter_config(config: TrainInfOutputParityConfig) -> dict[str, Any]: return LoraConfig( base_model_name_or_path=config.base_model, - r=default_lora_rank_for_handler(get_model_support_handler(config.base_model)), + r=default_lora_rank_for_handler( + get_model_support_handler( + config.base_model, + allow_unvalidated_arch=config.allow_unvalidated_arch, + ) + ), lora_alpha=LORA_ALPHA, target_modules=_lora_target_modules(config), bias="none", @@ -761,7 +801,7 @@ def _run_logits( parent_ids=parent_ids, ) with torch.no_grad(): - return runtime.model[0]( + logits = runtime.model[0]( input_ids=input_ids, position_ids=position_ids, attention_mask=torch.zeros((1, 1, 1, 1), dtype=torch.bool, device=device), @@ -771,6 +811,18 @@ def _run_logits( attention_bias=attention_state, ), ) + from megatron.core import parallel_state, tensor_parallel + + if ( + parallel_state.model_parallel_is_initialized() + and parallel_state.get_tensor_model_parallel_world_size() > 1 + ): + logits = tensor_parallel.gather_from_tensor_model_parallel_region(logits) + logits = _gather_context_parallel_logits( + logits, + full_sequence_length=int(input_ids.shape[1]), + ) + return logits def _extract_scores_from_logits( @@ -803,586 +855,3 @@ def _extract_scores_from_logits( target_logprobs=target_logprobs, topk=topk, ) - - -def _megatron_worker(request: MegatronWorkerRequest) -> None: - import torch - - from art.megatron import train as megatron_train - from art.megatron.weights.merge import load_lora_adapter_state_dict - - local_rank = int(os.environ["LOCAL_RANK"]) - torch.cuda.set_device(local_rank) - torch.distributed.init_process_group(backend="nccl") # type: ignore[possibly-missing-attribute] - _set_seed(request.config.seed) - os.environ.update(request.config.topology.env()) - - runtime = megatron_train.build_training_runtime( - model_identifier=request.config.base_model, - provider_torch_dtype=torch.bfloat16, - provider_bundle_configure=( - lambda bundle: ( - _configure_lora_target_modules( - bundle, - _lora_target_modules(request.config), - ) - if request.config.lora_target_modules is not None - else None - ) - ), - provider_configure=lambda provider: _configure_provider( - provider, request.config - ), - print_env=False, - build_optimizer=False, - # This worker only runs forward passes. Use the LoRA trainable path for - # both base and LoRA scoring so Megatron freezes base weights before DDP - # allocates buffers; base scoring simply does not load a nonzero adapter. - trainable_parameter_mode="lora", - allow_unvalidated_arch=request.config.allow_unvalidated_arch, - ) - for chunk in runtime.model: - chunk.eval() - - artifact_dir = Path(request.artifact_dir) - packed_tensors = _build_packed_tensors(request.config) - logical_map = build_logical_token_map(packed_tensors) - - adapter_path: Path | None = None - if request.weight_state == "lora": - if request.adapter_path is None: - initial_state = _collect_full_lora_state(cast(list[Any], runtime.model)) - if torch.distributed.get_rank() == 0: # type: ignore[possibly-missing-attribute] - adapter_path = artifact_dir / "active_lora" - initialized = _build_deterministic_nonzero_lora( - initial_state or {}, - seed=request.config.seed, - ) - _save_vllm_lora_adapter( - lora_path=adapter_path, - state=initialized, - runtime=runtime, - config=request.config, - ) - torch.distributed.barrier() # type: ignore[possibly-missing-attribute] - adapter_path = artifact_dir / "active_lora" - else: - adapter_path = Path(request.adapter_path) - adapter_model = load_lora_adapter_state_dict( - str(adapter_path), - handler=runtime.model_support_handler, - allow_unvalidated_arch=request.config.allow_unvalidated_arch, - ) - megatron_train.load_adapter_into_model(runtime.model, adapter_model) - - logits = _run_logits(runtime=runtime, packed_tensors=packed_tensors) - score = _extract_scores_from_logits( - logits=logits, - logical_map=logical_map, - side="megatron", - weight_state=request.weight_state, - ) - - if torch.distributed.get_rank() == 0: # type: ignore[possibly-missing-attribute] - score_path = artifact_dir / f"megatron_{request.weight_state}_scores.json" - logical_map_path = artifact_dir / "logical_token_map.json" - _write_json(score_path, score.model_dump(mode="json")) - _write_json(logical_map_path, logical_map.model_dump(mode="json")) - result = MegatronWorkerResult( - score_path=str(score_path), - logical_map_path=str(logical_map_path), - adapter_path=str(adapter_path) if adapter_path is not None else None, - ) - _write_json( - artifact_dir / f"megatron_{request.weight_state}_worker_result.json", - result.model_dump(mode="json"), - ) - torch.distributed.barrier() # type: ignore[possibly-missing-attribute] - torch.distributed.destroy_process_group() # type: ignore[possibly-missing-attribute] - - -def _run_megatron_worker(request: MegatronWorkerRequest) -> MegatronWorkerResult: - artifact_dir = Path(request.artifact_dir) - request_path = artifact_dir / f"megatron_{request.weight_state}_request.json" - _write_json(request_path, request.model_dump(mode="json")) - env = os.environ.copy() - env["CUDA_VISIBLE_DEVICES"] = ",".join( - str(value) for value in request.config.trainer_gpu_ids - ) - env["PYTHONUNBUFFERED"] = "1" - tests_dir = str(REPO_ROOT / "tests") - env["PYTHONPATH"] = ( - tests_dir - if not env.get("PYTHONPATH") - else f"{tests_dir}{os.pathsep}{env['PYTHONPATH']}" - ) - command = [ - sys.executable, - "-m", - "torch.distributed.run", - "--standalone", - "--nproc_per_node", - str(request.config.topology.world_size()), - "-m", - "integration.megatron.train_inf_mismatch.output_parity", - "--worker", - "--request", - str(request_path), - ] - log_path = artifact_dir / f"megatron_{request.weight_state}_worker.log" - with log_path.open("w", encoding="utf-8") as log_file: - run = subprocess.run( - command, - cwd=str(REPO_ROOT / "tests"), - env=env, - stdout=log_file, - stderr=subprocess.STDOUT, - text=True, - check=False, - ) - if run.returncode != 0: - tail = "\n".join(log_path.read_text(encoding="utf-8").splitlines()[-120:]) - raise RuntimeError( - f"Megatron {request.weight_state} worker failed with exit code " - f"{run.returncode}.\n{tail}" - ) - return MegatronWorkerResult.model_validate( - _read_json(artifact_dir / f"megatron_{request.weight_state}_worker_result.json") - ) - - -@asynccontextmanager -async def _direct_vllm_runtime( - *, - config: TrainInfOutputParityConfig, - artifact_dir: Path, - served_model_name: str, - lora_path: str, - rollout_weights_mode: Literal["lora", "merged"], - engine_args: dict[str, Any], -) -> AsyncIterator[tuple[str, int]]: - import art.vllm_runtime as runtime - - port = _free_port() - launch_config = runtime.VllmRuntimeLaunchConfig( - base_model=config.base_model, - port=port, - host="127.0.0.1", - cuda_visible_devices=",".join(str(value) for value in config.inference_gpu_ids), - lora_path=lora_path, - served_model_name=served_model_name, - rollout_weights_mode=rollout_weights_mode, - engine_args=engine_args, - server_args={ - "return_tokens_as_token_ids": True, - **config.server_args, - }, - ) - command = runtime.build_vllm_runtime_server_cmd(launch_config) - log_path = artifact_dir / f"vllm_{served_model_name}.log" - env = os.environ.copy() - env["PYTHONUNBUFFERED"] = "1" - with log_path.open("w", encoding="utf-8") as log_file: - process = subprocess.Popen( - command, - cwd=str(runtime.get_vllm_runtime_working_dir()), - env=env, - stdout=log_file, - stderr=subprocess.STDOUT, - text=True, - ) - try: - await runtime.wait_for_vllm_runtime( - process=process, - host=launch_config.host, - port=launch_config.port, - timeout=float( - os.environ.get("ART_TRAIN_INF_MISMATCH_VLLM_TIMEOUT", "1200") - ), - ) - yield launch_config.host, launch_config.port - finally: - process.terminate() - try: - process.wait(timeout=30) - except subprocess.TimeoutExpired: - process.kill() - process.wait(timeout=30) - - -async def _request_prompt_logprobs( - *, - base_url: str, - model_name: str, - prompt_token_ids: list[int], -) -> dict[str, Any]: - import httpx - - async with httpx.AsyncClient(timeout=300.0) as client: - response = await client.post( - f"{base_url}/v1/completions", - json={ - "model": model_name, - "prompt": prompt_token_ids, - "add_special_tokens": False, - "max_tokens": 0, - "echo": True, - "prompt_logprobs": TOP_K, - "return_token_ids": True, - }, - ) - response.raise_for_status() - return response.json() - - -def _logprob_entry_value(entry: dict[str, Any], token_id: int) -> float: - raw = entry.get(str(token_id)) - if raw is None: - raise RuntimeError(f"Token {token_id} missing from vLLM prompt_logprobs entry") - if isinstance(raw, dict): - return float(raw["logprob"]) - return float(raw.logprob) - - -def _topk_from_entry(entry: dict[str, Any]) -> TokenTopK: - parsed: list[tuple[int, int, float]] = [] - for raw_token_id, raw_value in entry.items(): - token_id = int(raw_token_id) - if isinstance(raw_value, dict): - rank = int(raw_value.get("rank", TOP_K + 1)) - logprob = float(raw_value["logprob"]) - else: - rank = int(raw_value.rank) - logprob = float(raw_value.logprob) - if 1 <= rank <= TOP_K: - parsed.append((rank, token_id, logprob)) - parsed.sort(key=lambda item: item[0]) - return TokenTopK( - token_ids=[token_id for _rank, token_id, _logprob in parsed[:TOP_K]], - logprobs=[logprob for _rank, _token_id, logprob in parsed[:TOP_K]], - ) - - -async def _score_vllm_at_url( - *, - base_url: str, - model_name: str, - logical_map: LogicalTokenMap, - weight_state: WeightState, - rollout_mode: RolloutMode, - artifact_dir: Path, -) -> ScoreBundle: - responses_by_prompt: dict[int, dict[str, Any]] = {} - prompt_by_id = {prompt.prompt_id: prompt for prompt in logical_map.prompts} - for prompt in logical_map.prompts: - response = await _request_prompt_logprobs( - base_url=base_url, - model_name=model_name, - prompt_token_ids=prompt.token_ids, - ) - choice = response["choices"][0] - returned_prompt_ids = [int(value) for value in choice["prompt_token_ids"]] - if returned_prompt_ids != prompt.token_ids: - raise RuntimeError( - "vLLM returned prompt_token_ids do not match request for " - f"prompt_id={prompt.prompt_id}" - ) - responses_by_prompt[prompt.prompt_id] = response - _write_json( - artifact_dir / f"vllm_{rollout_mode}_{weight_state}_responses.json", - responses_by_prompt, - ) - - target_logprobs: list[float] = [] - topk: list[TokenTopK] = [] - for token in logical_map.tokens: - prompt = prompt_by_id[token.prompt_id] - choice = responses_by_prompt[token.prompt_id]["choices"][0] - entries = choice["prompt_logprobs"] - returned_token_id = int(prompt.token_ids[token.vllm_prompt_token_index]) - if returned_token_id != token.token_id: - raise RuntimeError( - "Logical token alignment mismatch: " - f"expected={token.token_id} returned={returned_token_id}" - ) - entry = entries[token.vllm_prompt_token_index] - if entry is None: - raise RuntimeError( - f"Missing prompt logprob entry for prompt_id={token.prompt_id} " - f"index={token.vllm_prompt_token_index}" - ) - target_logprobs.append(_logprob_entry_value(entry, token.token_id)) - topk.append(_topk_from_entry(entry)) - return ScoreBundle( - side="vllm", - weight_state=weight_state, - rollout_mode=rollout_mode, - target_logprobs=target_logprobs, - topk=topk, - ) - - -async def _score_vllm_base( - *, - config: TrainInfOutputParityConfig, - rollout_mode: RolloutMode, - logical_map: LogicalTokenMap, - artifact_dir: Path, -) -> ScoreBundle: - served_name = f"train_inf_base_{rollout_mode}_{int(time.time())}" - placeholder_lora = artifact_dir / "unused_lora_placeholder" - placeholder_lora.mkdir(exist_ok=True) - engine_args = { - "tensor_parallel_size": len(config.inference_gpu_ids), - "enable_expert_parallel": len(config.inference_gpu_ids) > 1, - "max_model_len": config.packed.sequence_length + 8, - **config.engine_args, - } - if rollout_mode == "native_lora": - engine_args["enable_lora"] = True - engine_args["lora_target_modules"] = _lora_target_modules(config) - async with _direct_vllm_runtime( - config=config, - artifact_dir=artifact_dir, - served_model_name=served_name, - lora_path=str(placeholder_lora), - rollout_weights_mode="merged", - engine_args=engine_args, - ) as (host, port): - return await _score_vllm_at_url( - base_url=f"http://{host}:{port}", - model_name=served_name, - logical_map=logical_map, - weight_state="base", - rollout_mode=rollout_mode, - artifact_dir=artifact_dir, - ) - - -async def _score_vllm_native_lora( - *, - config: TrainInfOutputParityConfig, - adapter_path: str, - logical_map: LogicalTokenMap, - artifact_dir: Path, -) -> ScoreBundle: - served_name = f"train_inf_native_lora_{int(time.time())}" - engine_args = { - "tensor_parallel_size": len(config.inference_gpu_ids), - "enable_expert_parallel": len(config.inference_gpu_ids) > 1, - "max_model_len": config.packed.sequence_length + 8, - **config.engine_args, - } - engine_args["lora_target_modules"] = _lora_target_modules(config) - async with _direct_vllm_runtime( - config=config, - artifact_dir=artifact_dir, - served_model_name=served_name, - lora_path=adapter_path, - rollout_weights_mode="lora", - engine_args=engine_args, - ) as (host, port): - return await _score_vllm_at_url( - base_url=f"http://{host}:{port}", - model_name=served_name, - logical_map=logical_map, - weight_state="lora", - rollout_mode="native_lora", - artifact_dir=artifact_dir, - ) - - -async def _score_vllm_merged_lora( - *, - config: TrainInfOutputParityConfig, - adapter_path: str, - logical_map: LogicalTokenMap, - artifact_dir: Path, -) -> ScoreBundle: - from art import dev - from art.megatron.service import MegatronService - - service_name = f"train_inf_merged_lora_{int(time.time())}" - output_dir = artifact_dir / "merged_service" - from art.utils.output_dirs import get_step_checkpoint_dir - - checkpoint_dir = Path(get_step_checkpoint_dir(str(output_dir), 0)) - checkpoint_dir.mkdir(parents=True) - for filename in ("adapter_model.safetensors", "adapter_config.json"): - shutil.copy(Path(adapter_path) / filename, checkpoint_dir / filename) - internal_config = dev.InternalModelConfig( - trainer_gpu_ids=config.trainer_gpu_ids, - inference_gpu_ids=config.inference_gpu_ids, - rollout_weights_mode="merged", - allow_unvalidated_arch=config.allow_unvalidated_arch, - engine_args={ - "tensor_parallel_size": len(config.inference_gpu_ids), - "enable_expert_parallel": len(config.inference_gpu_ids) > 1, - "max_model_len": config.packed.sequence_length + 8, - **config.engine_args, - }, - ) - with _provider_topology_env(config.topology): - service = MegatronService( - model_name=service_name, - base_model=config.base_model, - config=internal_config, - output_dir=str(output_dir), - ) - try: - host, port = await service.start_openai_server( - {"server_args": {"port": _free_port(), **config.server_args}} - ) - return await _score_vllm_at_url( - base_url=f"http://{host}:{port}", - model_name=f"{service_name}@0", - logical_map=logical_map, - weight_state="lora", - rollout_mode="merged", - artifact_dir=artifact_dir, - ) - finally: - await service.aclose() - - -def _assert_lora_active( - base: ScoreBundle, lora: ScoreBundle, *, side: EngineSide -) -> None: - import torch - - base_values = torch.tensor(base.target_logprobs, dtype=torch.float32) - lora_values = torch.tensor(lora.target_logprobs, dtype=torch.float32) - if not bool(torch.isfinite(base_values).all().item()): - raise RuntimeError(f"{side} base target logprobs contain non-finite values") - if not bool(torch.isfinite(lora_values).all().item()): - raise RuntimeError(f"{side} LoRA target logprobs contain non-finite values") - if int(torch.count_nonzero((lora_values - base_values).abs() > 0).item()) == 0: - raise RuntimeError(f"{side} LoRA is not active: all deltas are zero") - - -async def run_train_inf_output_parity( - *, - config: TrainInfOutputParityConfig, - artifact_dir: Path, -) -> TrainInfOutputParityReport: - _write_json(artifact_dir / "probe_config.json", config.model_dump(mode="json")) - lora_result = _run_megatron_worker( - MegatronWorkerRequest( - config=config, - artifact_dir=str(artifact_dir), - weight_state="lora", - adapter_path=None, - ) - ) - if lora_result.adapter_path is None: - raise RuntimeError("LoRA worker did not produce an adapter") - base_result = _run_megatron_worker( - MegatronWorkerRequest( - config=config, - artifact_dir=str(artifact_dir), - weight_state="base", - adapter_path=None, - ) - ) - logical_map = LogicalTokenMap.model_validate( - _read_json(Path(lora_result.logical_map_path)) - ) - base_logical_map = LogicalTokenMap.model_validate( - _read_json(Path(base_result.logical_map_path)) - ) - if base_logical_map != logical_map: - raise RuntimeError("Base and LoRA Megatron workers produced different maps") - - megatron_base = ScoreBundle.model_validate(_read_json(Path(base_result.score_path))) - megatron_lora = ScoreBundle.model_validate(_read_json(Path(lora_result.score_path))) - _assert_lora_active(megatron_base, megatron_lora, side="megatron") - - rollout_comparisons: list[RolloutComparison] = [] - for rollout_mode in config.rollout_modes: - vllm_base = await _score_vllm_base( - config=config, - rollout_mode=rollout_mode, - logical_map=logical_map, - artifact_dir=artifact_dir, - ) - if rollout_mode == "native_lora": - vllm_lora = await _score_vllm_native_lora( - config=config, - adapter_path=lora_result.adapter_path, - logical_map=logical_map, - artifact_dir=artifact_dir, - ) - else: - vllm_lora = await _score_vllm_merged_lora( - config=config, - adapter_path=lora_result.adapter_path, - logical_map=logical_map, - artifact_dir=artifact_dir, - ) - _assert_lora_active(vllm_base, vllm_lora, side="vllm") - _write_json( - artifact_dir / f"vllm_{rollout_mode}_base_scores.json", - vllm_base.model_dump(mode="json"), - ) - _write_json( - artifact_dir / f"vllm_{rollout_mode}_lora_scores.json", - vllm_lora.model_dump(mode="json"), - ) - rollout_comparisons.append( - compare_rollout( - rollout_mode=rollout_mode, - megatron_base=megatron_base, - megatron_lora=megatron_lora, - vllm_base=vllm_base, - vllm_lora=vllm_lora, - logical_map=logical_map, - ) - ) - - passed = all( - comparison.base.mean_abs_pct <= BF16_FWD_MEAN_ABS_PCT_LIMIT - and comparison.lora.mean_abs_pct <= BF16_FWD_MEAN_ABS_PCT_LIMIT - for comparison in rollout_comparisons - ) - report = TrainInfOutputParityReport( - base_model=config.base_model, - artifact_dir=str(artifact_dir), - topology=config.topology.slug(), - trainer_gpu_ids=config.trainer_gpu_ids, - inference_gpu_ids=config.inference_gpu_ids, - logical_prompt_count=len(logical_map.prompts), - logical_token_count=len(logical_map.tokens), - adapter_path=lora_result.adapter_path, - megatron_base_scores=base_result.score_path, - megatron_lora_scores=lora_result.score_path, - rollout_comparisons=rollout_comparisons, - passed=passed, - ) - _write_json(artifact_dir / "comparison_report.json", report.model_dump(mode="json")) - return report - - -def _worker_cli(request_path: Path) -> None: - request = MegatronWorkerRequest.model_validate(_read_json(request_path)) - _megatron_worker(request) - - -def _parse_args(argv: list[str]) -> argparse.Namespace: - parser = argparse.ArgumentParser() - parser.add_argument("--worker", action="store_true") - parser.add_argument("--request", type=Path) - return parser.parse_args(argv) - - -def _main(argv: list[str]) -> int: - args = _parse_args(argv) - if args.worker: - if args.request is None: - raise ValueError("--worker requires --request") - _worker_cli(args.request) - return 0 - raise ValueError("This module is intended to be run through pytest or --worker") - - -if __name__ == "__main__": - raise SystemExit(_main(sys.argv[1:])) diff --git a/tests/integration/megatron/train_inf_mismatch/real_path.py b/tests/integration/megatron/train_inf_mismatch/real_path.py new file mode 100644 index 000000000..41188facd --- /dev/null +++ b/tests/integration/megatron/train_inf_mismatch/real_path.py @@ -0,0 +1,1208 @@ +from __future__ import annotations + +import argparse +import asyncio +from contextlib import asynccontextmanager +import os +from pathlib import Path +import random +import shutil +import socket +import subprocess +import sys +from typing import Any, AsyncIterator, cast +import uuid + +from openai.types.chat.chat_completion import Choice +from pydantic import BaseModel, ConfigDict, Field + +from art.preprocessing.moe_routing import choice_moe_routing_metadata +from art.preprocessing.pack import DiskPackedTensors + +from .artifacts import REPO_ROOT +from .output_parity import ( + TOP20_KL_CANDIDATE_TO_TARGET_LIMIT, + TOP_K, + LogicalTokenMap, + PairComparison, + ScoreBundle, + TokenTopK, + TopKComparison, + TrainInfOutputParityConfig, + WeightState, + _build_deterministic_nonzero_lora, + _collect_full_lora_state, + _configure_lora_target_modules, + _configure_provider, + _extract_scores_from_logits, + _lora_target_modules, + _read_json, + _run_logits, + _save_vllm_lora_adapter, + _set_seed, + _write_json, + build_logical_token_map, + compare_pair, + compare_topk, + fwd_mean_abs_pct_limit_for_model, + model_support_is_moe, +) + + +class RealPathConfig(BaseModel): + model_config = ConfigDict(arbitrary_types_allowed=True) + + output_parity: TrainInfOutputParityConfig = Field( + default_factory=TrainInfOutputParityConfig + ) + prompt_count: int = 2 + rollouts_per_prompt: int = 2 + max_completion_tokens: int = 16 + prompt_sentence_count: int = 28 + diagnose_base: bool = False + trace_layers: bool = False + trace_enforce_eager: bool = False + + +class RealPathMegatronWorkerRequest(BaseModel): + config: TrainInfOutputParityConfig + artifact_dir: str + disk_packed_tensors: DiskPackedTensors + logical_map_path: str + weight_state: WeightState + adapter_path: str | None = None + moe_routing_replay_path: str | None = None + global_grad_accumulation_sequences: int + forward_trace_dir: str | None = None + + +class RealPathMegatronWorkerResult(BaseModel): + score_path: str + adapter_path: str | None = None + + +class RealPathBaseDiagnosticBundle(BaseModel): + vllm_scores: ScoreBundle + megatron_scores: ScoreBundle + megatron_score_path: str + vllm_score_path: str + logical_prompt_count: int + logical_token_count: int + moe_routing_packed_tokens: int + moe_routing_shared_prefix_rows: int + moe_routing_shared_prefix_conflict_rows: int + moe_routing_shared_prefix_conflict_slots: int + moe_routing_shared_prefix_compared_slots: int + vllm_forward_trace_dir: str | None = None + megatron_forward_trace_dir: str | None = None + + +class RealPathTrainInfReport(BaseModel): + base_model: str + artifact_dir: str + logical_prompt_count: int + logical_token_count: int + base_logical_prompt_count: int | None = None + base_logical_token_count: int | None = None + base_moe_routing_packed_tokens: int | None = None + base_moe_routing_shared_prefix_conflict_rows: int | None = None + base_moe_routing_shared_prefix_conflict_slots: int | None = None + adapter_path: str + megatron_base_scores: str | None = None + vllm_base_scores: str | None = None + megatron_lora_scores: str + vllm_lora_scores: str + base: PairComparison | None = None + base_topk: TopKComparison | None = None + lora: PairComparison + lora_topk: TopKComparison + moe_routing_packed_tokens: int + moe_routing_shared_prefix_rows: int + moe_routing_shared_prefix_conflict_rows: int + moe_routing_shared_prefix_conflict_slots: int + moe_routing_shared_prefix_compared_slots: int + mean_abs_pct_limit: float + top20_kl_candidate_to_target_limit: float + passed: bool + + +_PROMPT_SENTENCES = [ + "A careful systems engineer checks assumptions before changing thresholds.", + "The training batch contains shared prefixes and divergent completions.", + "Numerical parity should be measured on the exact tokens used by the policy.", + "Sparse expert routing can create discontinuous output differences.", + "A reproducible test writes enough artifacts to explain every comparison.", + "LoRA adapters must be active and nonzero during both inference and training.", + "The prompt should be realistic enough to exercise ordinary tokenizer paths.", + "Packed Megatron inputs use shared prefixes while vLLM receives flat requests.", + "If tokenization diverges, the mismatch should fail as early as possible.", + "The report includes target logprobs and top token overlap for diagnosis.", + "Routing replay should use vLLM expert ids captured from real rollouts.", + "The model is asked to continue a compact technical note with concrete facts.", + "Every rollout in a group starts from the same prompt and then branches.", + "The comparison avoids hidden fallbacks that mask training inference drift.", + "Strict tests should make incorrect assumptions visible instead of tolerating them.", + "A small live probe can still cover important module and routing behavior.", + "The artifact bundle records the packed tensor layout used by training.", + "Inference responses provide logprobs for generated assistant tokens.", + "Megatron replay receives expert ids before each router executes.", + "The same adapter checkpoint should drive the served and trained policy.", + "Top-k overlap is useful because sampling behavior depends on ranking.", + "Mean absolute percent follows the support branch elementwise convention.", + "The run should not update weights just to measure a forward mismatch.", + "Validation code belongs in tests unless production needs the behavior.", +] + + +def config_from_env() -> RealPathConfig: + from .output_parity import config_from_env as output_config_from_env + + config = RealPathConfig(output_parity=output_config_from_env()) + if raw := os.environ.get("ART_REAL_PATH_PROMPT_COUNT"): + config.prompt_count = int(raw) + if raw := os.environ.get("ART_REAL_PATH_ROLLOUTS_PER_PROMPT"): + config.rollouts_per_prompt = int(raw) + if raw := os.environ.get("ART_REAL_PATH_MAX_COMPLETION_TOKENS"): + config.max_completion_tokens = int(raw) + if raw := os.environ.get("ART_REAL_PATH_PROMPT_SENTENCE_COUNT"): + config.prompt_sentence_count = int(raw) + if raw := os.environ.get("ART_REAL_PATH_DIAGNOSE_BASE"): + config.diagnose_base = raw == "1" + if raw := os.environ.get("ART_REAL_PATH_TRACE_LAYERS"): + config.trace_layers = raw == "1" + if config.trace_layers: + config.diagnose_base = True + if raw := os.environ.get("ART_REAL_PATH_TRACE_ENFORCE_EAGER"): + config.trace_enforce_eager = raw == "1" + return config + + +def _build_prompts(config: RealPathConfig) -> list[str]: + rng = random.Random(config.output_parity.seed) + prompts: list[str] = [] + for index in range(config.prompt_count): + sentences = [ + rng.choice(_PROMPT_SENTENCES) for _ in range(config.prompt_sentence_count) + ] + prompts.append( + "Write a concise continuation for probe " + f"{index}. Preserve the technical tone.\n\n" + " ".join(sentences) + ) + return prompts + + +async def _rollout( + *, + model: Any, + prompt: str, + max_completion_tokens: int, + reward: float, + extra_body: dict[str, Any] | None, +) -> Any: + import art + + messages = [{"role": "user", "content": prompt}] + + async def _request() -> None: + request_kwargs: dict[str, Any] = {} + if extra_body is not None: + request_kwargs["extra_body"] = extra_body + response = await model.openai_client().chat.completions.create( + model=model.get_inference_name(), + messages=messages, + max_tokens=max_completion_tokens, + temperature=0.8, + logprobs=True, + top_logprobs=TOP_K, + **request_kwargs, + ) + if trajectory := art.auto_trajectory(): + logprobs = response.choices[0].logprobs + trajectory.reward = reward + trajectory.metrics["completion_tokens"] = ( + len(logprobs.content or []) if logprobs is not None else 0 + ) + + return await art.capture_auto_trajectory(_request()) + + +async def _collect_real_trajectory_groups( + *, + model: Any, + config: RealPathConfig, +) -> list[Any]: + from transformers import AutoTokenizer + + import art + + if config.rollouts_per_prompt < 2: + raise ValueError("real-path mismatch requires at least two rollouts per prompt") + tokenizer = AutoTokenizer.from_pretrained(config.output_parity.base_model) + chat_template_kwargs: dict[str, Any] = {} + if isinstance(tokenizer.chat_template, str): + if "enable_thinking" in tokenizer.chat_template: + chat_template_kwargs["enable_thinking"] = False + if "preserve_thinking" in tokenizer.chat_template: + chat_template_kwargs["preserve_thinking"] = True + extra_body = ( + {"chat_template_kwargs": chat_template_kwargs} if chat_template_kwargs else None + ) + prompts = _build_prompts(config) + groups = [ + art.TrajectoryGroup( + [ + _rollout( + model=model, + prompt=prompt, + max_completion_tokens=config.max_completion_tokens, + reward=float(rollout_index % 2), + extra_body=extra_body, + ) + for rollout_index in range(config.rollouts_per_prompt) + ] + ) + for prompt in prompts + ] + return await art.gather_trajectory_groups( + cast(Any, groups), + pbar_desc="real-path-rollouts", + ) + + +def _parse_token_id(raw: str | None) -> int: + if raw is None: + raise RuntimeError("vLLM logprob entry is missing token id") + if raw.startswith("token_id:"): + return int(raw.split(":", 1)[1]) + raise RuntimeError( + "Expected vLLM logprob token strings to use token_id:; got " + f"{raw!r}. Ensure return_tokens_as_token_ids is enabled." + ) + + +def _free_port() -> int: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.bind(("127.0.0.1", 0)) + return int(sock.getsockname()[1]) + + +def _choice_score_index( + trajectory_groups: list[Any], + *, + require_routing_metadata: bool, +) -> dict[tuple[int, ...], Choice]: + indexed: dict[tuple[int, ...], Choice] = {} + for group in trajectory_groups: + for trajectory in group: + for item in trajectory.messages_and_choices: + if not isinstance(item, Choice): + continue + metadata = choice_moe_routing_metadata(item) + if metadata is None: + if require_routing_metadata: + raise RuntimeError( + "Real-path trajectory choice is missing routes" + ) + token_logprobs = ( + item.logprobs.content + if item.logprobs is not None + and item.logprobs.content is not None + else [] + ) + indexed.setdefault( + tuple(_parse_token_id(entry.token) for entry in token_logprobs), + item, + ) + continue + prompt_ids = [int(value) for value in metadata["prompt_token_ids"]] + completion_ids = [ + int(value) + for value in ( + metadata.get("completion_token_ids") + or metadata.get("token_ids") + or [] + ) + ] + indexed.setdefault(tuple(prompt_ids + completion_ids), item) + return indexed + + +@asynccontextmanager +async def _direct_vllm_runtime( + *, + config: TrainInfOutputParityConfig, + artifact_dir: Path, + served_model_name: str, + lora_path: str, + rollout_weights_mode: str, + engine_args: dict[str, Any], + forward_trace_dir: Path | None = None, +) -> AsyncIterator[tuple[str, int]]: + import art.vllm_runtime as runtime + + port = _free_port() + launch_config = runtime.VllmRuntimeLaunchConfig( + base_model=config.base_model, + port=port, + host="127.0.0.1", + cuda_visible_devices=",".join(str(value) for value in config.inference_gpu_ids), + lora_path=lora_path, + served_model_name=served_model_name, + rollout_weights_mode=cast(Any, rollout_weights_mode), + engine_args=engine_args, + server_args={"return_tokens_as_token_ids": True, **config.server_args}, + ) + command = runtime.build_vllm_runtime_server_cmd(launch_config) + log_path = artifact_dir / f"real_path_vllm_{served_model_name}.log" + env = os.environ.copy() + env["PYTHONUNBUFFERED"] = "1" + if forward_trace_dir is not None: + trace_site = Path(__file__).resolve().parent / "vllm_forward_trace_site" + env["ART_VLLM_FORWARD_TRACE_DIR"] = str(forward_trace_dir) + env["PYTHONPATH"] = ( + str(trace_site) + if not env.get("PYTHONPATH") + else f"{trace_site}{os.pathsep}{env['PYTHONPATH']}" + ) + with log_path.open("w", encoding="utf-8") as log_file: + process = subprocess.Popen( + command, + cwd=str(runtime.get_vllm_runtime_working_dir()), + env=env, + stdout=log_file, + stderr=subprocess.STDOUT, + text=True, + ) + try: + await runtime.wait_for_vllm_runtime( + process=process, + host=launch_config.host, + port=launch_config.port, + timeout=float( + os.environ.get("ART_TRAIN_INF_MISMATCH_VLLM_TIMEOUT", "1200") + ), + ) + yield launch_config.host, launch_config.port + finally: + process.terminate() + try: + process.wait(timeout=30) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=30) + + +def _topk_from_chat_logprob(entry: Any) -> TokenTopK: + if entry.top_logprobs is None: + raise RuntimeError("vLLM logprob entry is missing top_logprobs") + parsed: list[tuple[int, float]] = [] + for top in entry.top_logprobs: + parsed.append((_parse_token_id(top.token), float(top.logprob))) + return TokenTopK( + token_ids=[token_id for token_id, _logprob in parsed[:TOP_K]], + logprobs=[logprob for _token_id, logprob in parsed[:TOP_K]], + ) + + +def _vllm_scores_from_real_choices( + *, + trajectory_groups: list[Any], + logical_map: LogicalTokenMap, + require_routing_metadata: bool, + weight_state: WeightState, +) -> ScoreBundle: + choices_by_tokens = _choice_score_index( + trajectory_groups, + require_routing_metadata=require_routing_metadata, + ) + prompt_by_id = {prompt.prompt_id: prompt for prompt in logical_map.prompts} + choice_by_prompt_id: dict[int, Choice] = {} + for prompt in logical_map.prompts: + key = ( + tuple(prompt.token_ids) + if require_routing_metadata + else tuple(prompt.token_ids[prompt.scored_token_start_index :]) + ) + choice = choices_by_tokens.get(key) + if choice is None: + raise RuntimeError( + "Could not find captured vLLM choice for logical prompt " + f"{prompt.prompt_id}" + ) + choice_by_prompt_id[prompt.prompt_id] = choice + target_logprobs: list[float] = [] + topk: list[TokenTopK] = [] + for token in logical_map.tokens: + prompt = prompt_by_id[token.prompt_id] + choice = choice_by_prompt_id[token.prompt_id] + metadata = choice_moe_routing_metadata(choice) + vllm_prompt_len = prompt.scored_token_start_index + if ( + metadata is not None + and len(metadata["prompt_token_ids"]) != vllm_prompt_len + ): + raise RuntimeError( + "vLLM routed prompt length does not match ART packed request: " + f"prompt_id={prompt.prompt_id}, art={vllm_prompt_len}, " + f"vllm={len(metadata['prompt_token_ids'])}" + ) + token_logprobs = ( + choice.logprobs.content + if choice.logprobs is not None and choice.logprobs.content is not None + else [] + ) + completion_index = token.vllm_prompt_token_index - vllm_prompt_len + if completion_index < 0 or completion_index >= len(token_logprobs): + raise RuntimeError( + "Logical token is outside captured vLLM completion logprobs: " + f"prompt_id={prompt.prompt_id}, index={token.vllm_prompt_token_index}" + ) + entry = token_logprobs[completion_index] + returned_token_id = _parse_token_id(entry.token) + if returned_token_id != token.token_id: + raise RuntimeError( + "Captured vLLM token id does not match logical token: " + f"expected={token.token_id}, returned={returned_token_id}" + ) + target_logprobs.append(float(entry.logprob)) + topk.append(_topk_from_chat_logprob(entry)) + return ScoreBundle( + side="vllm", + weight_state=weight_state, + rollout_mode="native_lora", + target_logprobs=target_logprobs, + topk=topk, + ) + + +async def _score_base_real_generation_path( + *, + config: RealPathConfig, + artifact_dir: Path, + is_moe: bool, +) -> RealPathBaseDiagnosticBundle: + import art + from art.megatron.routing_replay import ( + build_moe_routing_replay_bundle_from_packed_tensors, + ) + from art.megatron.runtime.backend import MegatronBackend + from art.preprocessing.moe_routing import MoeRoutingPackStats + from art.preprocessing.pack import packed_tensors_to_dir + + parity_config = config.output_parity + served_name = f"train_inf_real_base_{uuid.uuid4().hex[:8]}" + placeholder_lora = artifact_dir / "unused_base_lora_placeholder" + placeholder_lora.mkdir(exist_ok=True) + engine_args = { + "tensor_parallel_size": len(parity_config.inference_gpu_ids), + "enable_expert_parallel": is_moe and len(parity_config.inference_gpu_ids) > 1, + "max_model_len": parity_config.packed.sequence_length + 8, + "max_logprobs": TOP_K, + **parity_config.engine_args, + } + engine_args.pop("enable_lora", None) + engine_args.pop("max_loras", None) + engine_args.pop("lora_target_modules", None) + if is_moe: + engine_args["enable_return_routed_experts"] = True + engine_args["async_scheduling"] = False + vllm_forward_trace_dir = ( + artifact_dir / "real_path_base_vllm_forward_trace" + if config.trace_layers + else None + ) + megatron_forward_trace_dir = ( + artifact_dir / "real_path_base_megatron_forward_trace" + if config.trace_layers + else None + ) + if config.trace_enforce_eager: + engine_args["enforce_eager"] = True + + async with _direct_vllm_runtime( + config=parity_config, + artifact_dir=artifact_dir, + served_model_name=served_name, + lora_path=str(placeholder_lora), + rollout_weights_mode="merged", + engine_args=engine_args, + forward_trace_dir=vllm_forward_trace_dir, + ) as (host, port): + model = art.TrainableModel( + name=f"{served_name}_client", + project="train_inf_mismatch", + base_model=parity_config.base_model, + _internal_config={ + "init_args": { + "max_seq_length": parity_config.packed.sequence_length, + }, + }, + ) + object.__setattr__(model, "inference_base_url", f"http://{host}:{port}/v1") + object.__setattr__(model, "inference_api_key", "EMPTY") + object.__setattr__(model, "inference_model_name", served_name) + trajectory_groups = await _collect_real_trajectory_groups( + model=model, + config=config, + ) + + packing_backend = MegatronBackend( + path=str(artifact_dir / "base_art_path"), + enable_expert_replay=is_moe, + ) + packed_tensors = packing_backend._get_packed_tensors( + model, + trajectory_groups, + advantage_balance=0.0, + allow_training_without_logprobs=False, + scale_rewards=True, + plot_tensors=False, + packed_sequence_length=parity_config.packed.sequence_length, + logprob_calculation_chunk_size=1024, + include_moe_routing=is_moe, + ) + if packed_tensors is None: + raise RuntimeError("Base diagnostic ART path produced no packed tensors") + logical_map = build_logical_token_map(cast(dict[str, Any], packed_tensors)) + logical_map_path = artifact_dir / "real_path_base_logical_token_map.json" + _write_json(logical_map_path, logical_map.model_dump(mode="json")) + + vllm_base = _vllm_scores_from_real_choices( + trajectory_groups=trajectory_groups, + logical_map=logical_map, + require_routing_metadata=is_moe, + weight_state="base", + ) + vllm_score_path = artifact_dir / "real_path_vllm_base_scores.json" + _write_json(vllm_score_path, vllm_base.model_dump(mode="json")) + + routing_replay_path: str | None = None + global_grad_accumulation_sequences = int(packed_tensors["tokens"].shape[0]) + if is_moe: + routing_replay_dir = artifact_dir / "real_path_base_moe_routing_replay" + build_moe_routing_replay_bundle_from_packed_tensors( + packed_tensors=packed_tensors, + global_grad_accumulation_sequences=global_grad_accumulation_sequences, + ).to_dir(routing_replay_dir) + routing_replay_path = str(routing_replay_dir) + stats = packed_tensors["moe_routing_replay"].pack_stats + else: + stats = MoeRoutingPackStats() + + disk_packed_tensors = packed_tensors_to_dir( + packed_tensors, + str(artifact_dir / "real_path_base_packed_tensors"), + ) + _write_json( + artifact_dir / "real_path_base_disk_packed_tensors.json", + cast(dict[str, Any], disk_packed_tensors), + ) + worker_result = _run_real_path_megatron_worker( + RealPathMegatronWorkerRequest( + config=parity_config, + artifact_dir=str(artifact_dir), + disk_packed_tensors=disk_packed_tensors, + logical_map_path=str(logical_map_path), + weight_state="base", + adapter_path=None, + moe_routing_replay_path=routing_replay_path, + global_grad_accumulation_sequences=global_grad_accumulation_sequences, + forward_trace_dir=( + str(megatron_forward_trace_dir) + if megatron_forward_trace_dir is not None + else None + ), + ) + ) + megatron_base = ScoreBundle.model_validate( + _read_json(Path(worker_result.score_path)) + ) + return RealPathBaseDiagnosticBundle( + vllm_scores=vllm_base, + megatron_scores=megatron_base, + megatron_score_path=worker_result.score_path, + vllm_score_path=str(vllm_score_path), + logical_prompt_count=len(logical_map.prompts), + logical_token_count=len(logical_map.tokens), + moe_routing_packed_tokens=int(stats.packed_tokens), + moe_routing_shared_prefix_rows=int(stats.shared_prefix_rows), + moe_routing_shared_prefix_conflict_rows=int(stats.shared_prefix_conflict_rows), + moe_routing_shared_prefix_conflict_slots=int( + stats.shared_prefix_conflict_slots + ), + moe_routing_shared_prefix_compared_slots=int( + stats.shared_prefix_compared_slots + ), + vllm_forward_trace_dir=( + str(vllm_forward_trace_dir) if vllm_forward_trace_dir is not None else None + ), + megatron_forward_trace_dir=( + str(megatron_forward_trace_dir) + if megatron_forward_trace_dir is not None + else None + ), + ) + + +def _move_adapter_to_step_zero(*, adapter_path: str, model: Any, backend: Any) -> str: + from art.utils.output_dirs import get_model_dir, get_step_checkpoint_dir + + model_dir = get_model_dir(model=model, art_path=backend._path) + step_zero = get_step_checkpoint_dir(model_dir, 0) + os.makedirs(step_zero, exist_ok=True) + for filename in ("adapter_model.safetensors", "adapter_config.json"): + shutil.copy(Path(adapter_path) / filename, Path(step_zero) / filename) + return step_zero + + +def _make_nonzero_adapter( + *, + config: TrainInfOutputParityConfig, + artifact_dir: Path, +) -> str: + request = RealPathMegatronWorkerRequest( + config=config, + artifact_dir=str(artifact_dir), + disk_packed_tensors=cast( + DiskPackedTensors, + { + "dir": str(artifact_dir / "unused"), + "num_sequences": 1, + "sequence_length": 1, + }, + ), + logical_map_path=str(artifact_dir / "unused_logical_map.json"), + weight_state="lora", + adapter_path=None, + moe_routing_replay_path=None, + global_grad_accumulation_sequences=1, + forward_trace_dir=None, + ) + return _run_real_path_megatron_worker(request, adapter_only=True).adapter_path or "" + + +def _run_logits_with_replay( + *, + runtime: Any, + packed_tensors: dict[str, Any], + global_grad_accumulation_sequences: int, +) -> Any: + import torch + + if runtime.moe_routing_replay_controller is None: + return _run_logits(runtime=runtime, packed_tensors=packed_tensors) + + logits_by_sample = [] + num_sequences = int(packed_tensors["tokens"].shape[0]) + for sample_index in range(num_sequences): + sample_tensors = { + key: ( + value[sample_index : sample_index + 1] + if isinstance(value, torch.Tensor) + and value.shape[:1] == packed_tensors["tokens"].shape[:1] + else value + ) + for key, value in packed_tensors.items() + } + step_index = sample_index // global_grad_accumulation_sequences + runtime.moe_routing_replay_controller.set_step( + step_index=step_index, + sample_index=sample_index, + global_grad_accumulation_sequences=global_grad_accumulation_sequences, + ) + runtime.moe_routing_replay_controller.begin_micro(sample_index, sample_index) + logits_by_sample.append( + _run_logits(runtime=runtime, packed_tensors=sample_tensors) + ) + runtime.moe_routing_replay_controller.finalize_step() + return torch.cat(logits_by_sample, dim=0) + + +def _real_path_megatron_worker( + request: RealPathMegatronWorkerRequest, + *, + adapter_only: bool = False, +) -> None: + import torch + + from art.megatron import train as megatron_train + from art.megatron.weights.merge import load_lora_adapter_state_dict + from art.preprocessing.pack import packed_tensors_from_dir + + local_rank = int(os.environ["LOCAL_RANK"]) + torch.cuda.set_device(local_rank) + torch.distributed.init_process_group(backend="nccl") # type: ignore[possibly-missing-attribute] + _set_seed(request.config.seed) + os.environ.update(request.config.topology.env()) + + def _configure_worker_bundle(bundle: Any) -> None: + if request.config.lora_target_modules is not None: + _configure_lora_target_modules( + bundle, + _lora_target_modules(request.config), + ) + if not adapter_only and request.weight_state == "base": + bundle.provider.register_pre_wrap_hook(megatron_train.freeze_model) + + runtime = megatron_train.build_training_runtime( + model_identifier=request.config.base_model, + provider_torch_dtype=torch.bfloat16, + provider_bundle_configure=_configure_worker_bundle, + provider_configure=lambda provider: _configure_provider( + provider, request.config + ), + moe_routing_replay_path=request.moe_routing_replay_path, + moe_routing_replay_strict=True, + print_env=False, + build_optimizer=False, + trainable_parameter_mode=( + "lora" if adapter_only or request.weight_state == "lora" else "base_model" + ), + allow_unvalidated_arch=request.config.allow_unvalidated_arch, + ) + for chunk in runtime.model: + chunk.eval() + + artifact_dir = Path(request.artifact_dir) + adapter_path: Path | None = None + if request.weight_state == "lora": + if request.adapter_path is None: + initial_state = _collect_full_lora_state(cast(list[Any], runtime.model)) + if torch.distributed.get_rank() == 0: # type: ignore[possibly-missing-attribute] + adapter_path = artifact_dir / "real_path_active_lora" + initialized = _build_deterministic_nonzero_lora( + initial_state or {}, + seed=request.config.seed, + ) + _save_vllm_lora_adapter( + lora_path=adapter_path, + state=initialized, + runtime=runtime, + config=request.config, + ) + torch.distributed.barrier() # type: ignore[possibly-missing-attribute] + adapter_path = artifact_dir / "real_path_active_lora" + else: + adapter_path = Path(request.adapter_path) + adapter_model = load_lora_adapter_state_dict( + str(adapter_path), + handler=runtime.model_support_handler, + allow_unvalidated_arch=request.config.allow_unvalidated_arch, + ) + megatron_train.load_adapter_into_model(runtime.model, adapter_model) + + if adapter_only: + if torch.distributed.get_rank() == 0: # type: ignore[possibly-missing-attribute] + result = RealPathMegatronWorkerResult( + score_path="", + adapter_path=str(adapter_path) if adapter_path is not None else None, + ) + _write_json( + artifact_dir / "real_path_adapter_worker_result.json", + result.model_dump(mode="json"), + ) + torch.distributed.barrier() # type: ignore[possibly-missing-attribute] + torch.distributed.destroy_process_group() # type: ignore[possibly-missing-attribute] + return + + packed_tensors = packed_tensors_from_dir(**request.disk_packed_tensors) + logical_map = LogicalTokenMap.model_validate( + _read_json(Path(request.logical_map_path)) + ) + forward_trace_capture = None + if request.forward_trace_dir is not None: + from ..model_support.forward_trace import ( + CAPTURE_NAME_TOKENS, + ForwardTraceCapture, + ) + + forward_trace_capture = ForwardTraceCapture( + runtime.model, + enabled=True, + capture_name_tokens=(*CAPTURE_NAME_TOKENS, ".decoder.final_layernorm"), + strict_output_match=True, + ) + forward_trace_capture.set_step( + 0, + list(range(int(packed_tensors["tokens"].shape[0]))), + ) + try: + logits = _run_logits_with_replay( + runtime=runtime, + packed_tensors=cast(dict[str, Any], packed_tensors), + global_grad_accumulation_sequences=request.global_grad_accumulation_sequences, + ) + if forward_trace_capture is not None and request.forward_trace_dir is not None: + trace_dir = Path(request.forward_trace_dir) + forward_trace_capture.save_current_step(trace_dir) + torch.save(logits.detach().cpu(), trace_dir / "logits.pt") + finally: + if forward_trace_capture is not None: + forward_trace_capture.close() + score = _extract_scores_from_logits( + logits=logits, + logical_map=logical_map, + side="megatron", + weight_state=request.weight_state, + rollout_mode="native_lora", + ) + + if torch.distributed.get_rank() == 0: # type: ignore[possibly-missing-attribute] + score_path = artifact_dir / f"real_path_megatron_{request.weight_state}.json" + _write_json(score_path, score.model_dump(mode="json")) + result = RealPathMegatronWorkerResult( + score_path=str(score_path), + adapter_path=str(adapter_path) if adapter_path is not None else None, + ) + _write_json( + artifact_dir + / f"real_path_megatron_{request.weight_state}_worker_result.json", + result.model_dump(mode="json"), + ) + torch.distributed.barrier() # type: ignore[possibly-missing-attribute] + torch.distributed.destroy_process_group() # type: ignore[possibly-missing-attribute] + + +def _run_real_path_megatron_worker( + request: RealPathMegatronWorkerRequest, + *, + adapter_only: bool = False, +) -> RealPathMegatronWorkerResult: + artifact_dir = Path(request.artifact_dir) + request_name = ( + "real_path_adapter_request.json" + if adapter_only + else f"real_path_megatron_{request.weight_state}_request.json" + ) + request_path = artifact_dir / request_name + _write_json(request_path, request.model_dump(mode="json")) + env = os.environ.copy() + env["CUDA_VISIBLE_DEVICES"] = ",".join( + str(value) for value in request.config.trainer_gpu_ids + ) + env["PYTHONUNBUFFERED"] = "1" + tests_dir = str(REPO_ROOT / "tests") + env["PYTHONPATH"] = ( + tests_dir + if not env.get("PYTHONPATH") + else f"{tests_dir}{os.pathsep}{env['PYTHONPATH']}" + ) + command = [ + sys.executable, + "-m", + "torch.distributed.run", + "--standalone", + "--nproc_per_node", + str(request.config.topology.world_size()), + "-m", + "integration.megatron.train_inf_mismatch.real_path", + "--worker", + "--request", + str(request_path), + ] + if adapter_only: + command.append("--adapter-only") + log_path = artifact_dir / ( + "real_path_adapter_worker.log" + if adapter_only + else f"real_path_megatron_{request.weight_state}_worker.log" + ) + with log_path.open("w", encoding="utf-8") as log_file: + run = subprocess.run( + command, + cwd=str(REPO_ROOT / "tests"), + env=env, + stdout=log_file, + stderr=subprocess.STDOUT, + text=True, + check=False, + ) + if run.returncode != 0: + tail = "\n".join(log_path.read_text(encoding="utf-8").splitlines()[-120:]) + raise RuntimeError( + f"Real-path Megatron worker failed with exit code {run.returncode}.\n{tail}" + ) + result_name = ( + "real_path_adapter_worker_result.json" + if adapter_only + else f"real_path_megatron_{request.weight_state}_worker_result.json" + ) + return RealPathMegatronWorkerResult.model_validate( + _read_json(artifact_dir / result_name) + ) + + +def _delete_adapter_safetensors_on_pass(artifact_dir: Path, *, passed: bool) -> None: + if not passed: + return + for path in artifact_dir.rglob("adapter_model.safetensors"): + path.unlink() + + +async def run_real_path_train_inf_mismatch( + *, + config: RealPathConfig, + artifact_dir: Path, +) -> RealPathTrainInfReport: + import art + from art.megatron.routing_replay import ( + build_moe_routing_replay_bundle_from_packed_tensors, + ) + from art.megatron.runtime.backend import MegatronBackend + from art.preprocessing.pack import packed_tensors_to_dir + + parity_config = config.output_parity + is_moe = model_support_is_moe( + parity_config.base_model, + allow_unvalidated_arch=parity_config.allow_unvalidated_arch, + ) + _write_json(artifact_dir / "real_path_config.json", config.model_dump(mode="json")) + adapter_path = _make_nonzero_adapter( + config=parity_config, artifact_dir=artifact_dir + ) + if not adapter_path: + raise RuntimeError("Real-path adapter worker did not create an adapter") + + backend = MegatronBackend( + path=str(artifact_dir / "art_path"), + enable_expert_replay=is_moe, + ) + backend_open = False + model = art.TrainableModel( + name=f"train-inf-real-{uuid.uuid4().hex[:8]}", + project="train_inf_mismatch", + base_model=parity_config.base_model, + _internal_config={ + "trainer_gpu_ids": parity_config.trainer_gpu_ids, + "inference_gpu_ids": parity_config.inference_gpu_ids, + "rollout_weights_mode": "lora", + "allow_unvalidated_arch": parity_config.allow_unvalidated_arch, + "engine_args": { + "tensor_parallel_size": len(parity_config.inference_gpu_ids), + "enable_expert_parallel": is_moe + and len(parity_config.inference_gpu_ids) > 1, + "max_model_len": parity_config.packed.sequence_length + 8, + "max_logprobs": TOP_K, + **parity_config.engine_args, + }, + "init_args": { + "max_seq_length": parity_config.packed.sequence_length, + }, + }, + ) + _move_adapter_to_step_zero(adapter_path=adapter_path, model=model, backend=backend) + + try: + await model.register(backend) + backend_open = True + trajectory_groups = await _collect_real_trajectory_groups( + model=model, + config=config, + ) + packed_tensors = backend._get_packed_tensors( + model, + trajectory_groups, + advantage_balance=0.0, + allow_training_without_logprobs=False, + scale_rewards=True, + plot_tensors=False, + packed_sequence_length=parity_config.packed.sequence_length, + logprob_calculation_chunk_size=1024, + include_moe_routing=is_moe, + ) + if packed_tensors is None: + raise RuntimeError("Real ART path produced no packed tensors") + logical_map = build_logical_token_map(cast(dict[str, Any], packed_tensors)) + logical_map_path = artifact_dir / "real_path_logical_token_map.json" + _write_json(logical_map_path, logical_map.model_dump(mode="json")) + + routing_replay_dir = artifact_dir / "real_path_moe_routing_replay" + global_grad_accumulation_sequences = int(packed_tensors["tokens"].shape[0]) + routing_replay_path: str | None = None + if is_moe: + build_moe_routing_replay_bundle_from_packed_tensors( + packed_tensors=packed_tensors, + global_grad_accumulation_sequences=global_grad_accumulation_sequences, + ).to_dir(routing_replay_dir) + routing_replay_path = str(routing_replay_dir) + disk_packed_tensors = packed_tensors_to_dir( + packed_tensors, + str(artifact_dir / "real_path_packed_tensors"), + ) + _write_json( + artifact_dir / "real_path_disk_packed_tensors.json", + cast(dict[str, Any], disk_packed_tensors), + ) + if is_moe: + routing_replay = packed_tensors["moe_routing_replay"] + stats = routing_replay.pack_stats + else: + from art.preprocessing.moe_routing import MoeRoutingPackStats + + stats = MoeRoutingPackStats() + + vllm_lora = _vllm_scores_from_real_choices( + trajectory_groups=trajectory_groups, + logical_map=logical_map, + require_routing_metadata=is_moe, + weight_state="lora", + ) + _write_json( + artifact_dir / "real_path_vllm_lora_scores.json", + vllm_lora.model_dump(mode="json"), + ) + await backend.close() + backend_open = False + + base_diagnostic: RealPathBaseDiagnosticBundle | None = None + megatron_base: ScoreBundle | None = None + vllm_base: ScoreBundle | None = None + base_comparison: PairComparison | None = None + base_topk_comparison: TopKComparison | None = None + if config.diagnose_base: + base_diagnostic = await _score_base_real_generation_path( + config=config, + artifact_dir=artifact_dir, + is_moe=is_moe, + ) + megatron_base = base_diagnostic.megatron_scores + vllm_base = base_diagnostic.vllm_scores + + worker_result = _run_real_path_megatron_worker( + RealPathMegatronWorkerRequest( + config=parity_config, + artifact_dir=str(artifact_dir), + disk_packed_tensors=disk_packed_tensors, + logical_map_path=str(logical_map_path), + weight_state="lora", + adapter_path=adapter_path, + moe_routing_replay_path=routing_replay_path, + global_grad_accumulation_sequences=global_grad_accumulation_sequences, + ) + ) + megatron_lora = ScoreBundle.model_validate( + _read_json(Path(worker_result.score_path)) + ) + import torch + + sequence_ids = [token.prompt_id for token in logical_map.tokens] + if megatron_base is not None and vllm_base is not None: + base_comparison = compare_pair( + candidate=torch.tensor( + megatron_base.target_logprobs, dtype=torch.float32 + ), + target=torch.tensor(vllm_base.target_logprobs, dtype=torch.float32), + sequence_ids=sequence_ids, + ) + base_topk_comparison = compare_topk(megatron_base, vllm_base) + comparison = compare_pair( + candidate=torch.tensor(megatron_lora.target_logprobs, dtype=torch.float32), + target=torch.tensor(vllm_lora.target_logprobs, dtype=torch.float32), + sequence_ids=sequence_ids, + ) + topk_comparison = compare_topk(megatron_lora, vllm_lora) + mean_abs_pct_limit = fwd_mean_abs_pct_limit_for_model( + parity_config.base_model, + allow_unvalidated_arch=parity_config.allow_unvalidated_arch, + ) + passed = ( + comparison.mean_abs_pct <= mean_abs_pct_limit + and topk_comparison.top20_intersection_kl_candidate_to_target + <= TOP20_KL_CANDIDATE_TO_TARGET_LIMIT + ) + report = RealPathTrainInfReport( + base_model=parity_config.base_model, + artifact_dir=str(artifact_dir), + logical_prompt_count=len(logical_map.prompts), + logical_token_count=len(logical_map.tokens), + base_logical_prompt_count=( + base_diagnostic.logical_prompt_count + if base_diagnostic is not None + else None + ), + base_logical_token_count=( + base_diagnostic.logical_token_count + if base_diagnostic is not None + else None + ), + base_moe_routing_packed_tokens=( + base_diagnostic.moe_routing_packed_tokens + if base_diagnostic is not None + else None + ), + base_moe_routing_shared_prefix_conflict_rows=( + base_diagnostic.moe_routing_shared_prefix_conflict_rows + if base_diagnostic is not None + else None + ), + base_moe_routing_shared_prefix_conflict_slots=( + base_diagnostic.moe_routing_shared_prefix_conflict_slots + if base_diagnostic is not None + else None + ), + adapter_path=adapter_path, + megatron_base_scores=( + base_diagnostic.megatron_score_path + if base_diagnostic is not None + else None + ), + vllm_base_scores=( + base_diagnostic.vllm_score_path if base_diagnostic is not None else None + ), + megatron_lora_scores=worker_result.score_path, + vllm_lora_scores=str(artifact_dir / "real_path_vllm_lora_scores.json"), + base=base_comparison, + base_topk=base_topk_comparison, + lora=comparison, + lora_topk=topk_comparison, + moe_routing_packed_tokens=int(stats.packed_tokens), + moe_routing_shared_prefix_rows=int(stats.shared_prefix_rows), + moe_routing_shared_prefix_conflict_rows=int( + stats.shared_prefix_conflict_rows + ), + moe_routing_shared_prefix_conflict_slots=int( + stats.shared_prefix_conflict_slots + ), + moe_routing_shared_prefix_compared_slots=int( + stats.shared_prefix_compared_slots + ), + mean_abs_pct_limit=mean_abs_pct_limit, + top20_kl_candidate_to_target_limit=TOP20_KL_CANDIDATE_TO_TARGET_LIMIT, + passed=passed, + ) + _write_json( + artifact_dir / "real_path_comparison_report.json", + report.model_dump(mode="json"), + ) + _delete_adapter_safetensors_on_pass(artifact_dir, passed=report.passed) + return report + finally: + if backend_open: + await backend.close() + + +def _worker_cli(request_path: Path, *, adapter_only: bool) -> None: + request = RealPathMegatronWorkerRequest.model_validate(_read_json(request_path)) + _real_path_megatron_worker(request, adapter_only=adapter_only) + + +def _parse_args(argv: list[str]) -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--worker", action="store_true") + parser.add_argument("--adapter-only", action="store_true") + parser.add_argument("--request", type=Path) + return parser.parse_args(argv) + + +def _main(argv: list[str]) -> int: + args = _parse_args(argv) + if args.worker: + if args.request is None: + raise ValueError("--worker requires --request") + _worker_cli(args.request, adapter_only=bool(args.adapter_only)) + return 0 + raise ValueError("This module is intended to be run through pytest or --worker") + + +if __name__ == "__main__": + raise SystemExit(_main(sys.argv[1:])) diff --git a/tests/integration/megatron/train_inf_mismatch/test_live_output_parity.py b/tests/integration/megatron/train_inf_mismatch/test_live_output_parity.py deleted file mode 100644 index 1aef412f7..000000000 --- a/tests/integration/megatron/train_inf_mismatch/test_live_output_parity.py +++ /dev/null @@ -1,52 +0,0 @@ -from __future__ import annotations - -import os -from pathlib import Path - -import pytest - -from .output_parity import ( - BF16_FWD_MEAN_ABS_PCT_LIMIT, - config_from_env, - run_train_inf_output_parity, -) - -torch = pytest.importorskip("torch") - -LIVE_ENV = "ART_RUN_TRAIN_INF_MISMATCH_LIVE" - - -def _require_live_opt_in() -> None: - if os.environ.get(LIVE_ENV) != "1": - pytest.skip(f"set {LIVE_ENV}=1 to run train/inf output parity") - - -def _require_visible_gpus(gpu_ids: list[int]) -> None: - if not torch.cuda.is_available(): - pytest.skip("CUDA is required for train/inf output parity") - visible_count = int(torch.cuda.device_count()) - required = max(gpu_ids) + 1 if gpu_ids else 0 - if visible_count < required: - pytest.skip( - f"Need visible CUDA device ids through {required - 1}, " - f"but torch sees {visible_count} devices" - ) - - -@pytest.mark.asyncio -async def test_train_inf_output_parity_live(artifact_dir: Path) -> None: - _require_live_opt_in() - config = config_from_env() - _require_visible_gpus(config.trainer_gpu_ids + config.inference_gpu_ids) - - report = await run_train_inf_output_parity( - config=config, - artifact_dir=artifact_dir, - ) - - assert report.logical_prompt_count > 0 - assert report.logical_token_count > 0 - assert report.passed, report.model_dump_json(indent=2) - for comparison in report.rollout_comparisons: - assert comparison.base.mean_abs_pct <= BF16_FWD_MEAN_ABS_PCT_LIMIT - assert comparison.lora.mean_abs_pct <= BF16_FWD_MEAN_ABS_PCT_LIMIT diff --git a/tests/integration/megatron/train_inf_mismatch/test_live_real_path_output_parity.py b/tests/integration/megatron/train_inf_mismatch/test_live_real_path_output_parity.py new file mode 100644 index 000000000..ffc7c2455 --- /dev/null +++ b/tests/integration/megatron/train_inf_mismatch/test_live_real_path_output_parity.py @@ -0,0 +1,53 @@ +from __future__ import annotations + +from pathlib import Path + +import pytest + +from .output_parity import model_support_is_moe +from .real_path import ( + config_from_env, + run_real_path_train_inf_mismatch, +) + +torch = pytest.importorskip("torch") + + +def _require_visible_gpus(gpu_ids: list[int]) -> None: + if not torch.cuda.is_available(): + pytest.skip("CUDA is required for real-path train/inf mismatch") + visible_count = int(torch.cuda.device_count()) + required = max(gpu_ids) + 1 if gpu_ids else 0 + if visible_count < required: + pytest.skip( + f"Need visible CUDA device ids through {required - 1}, " + f"but torch sees {visible_count} devices" + ) + + +@pytest.mark.asyncio +async def test_real_path_train_inf_mismatch_live(artifact_dir: Path) -> None: + config = config_from_env() + parity_config = config.output_parity + _require_visible_gpus( + parity_config.trainer_gpu_ids + parity_config.inference_gpu_ids + ) + + report = await run_real_path_train_inf_mismatch( + config=config, + artifact_dir=artifact_dir, + ) + + assert report.logical_prompt_count > 0 + assert report.logical_token_count > 0 + if model_support_is_moe( + parity_config.base_model, + allow_unvalidated_arch=parity_config.allow_unvalidated_arch, + ): + assert report.moe_routing_packed_tokens > 0 + assert report.passed, report.model_dump_json(indent=2) + assert report.lora.mean_abs_pct <= report.mean_abs_pct_limit + assert ( + report.lora_topk.top20_intersection_kl_candidate_to_target + <= report.top20_kl_candidate_to_target_limit + ) diff --git a/tests/integration/megatron/train_inf_mismatch/test_output_parity_invariants.py b/tests/integration/megatron/train_inf_mismatch/test_output_parity_invariants.py index 0a7c0aa15..ee0c71828 100644 --- a/tests/integration/megatron/train_inf_mismatch/test_output_parity_invariants.py +++ b/tests/integration/megatron/train_inf_mismatch/test_output_parity_invariants.py @@ -8,6 +8,7 @@ from . import workflow_stage from .output_parity import ( + TOP20_KL_CANDIDATE_TO_TARGET_LIMIT, TOP_K, EngineSide, ScoreBundle, @@ -19,7 +20,9 @@ compare_rollout, compare_topk, config_from_env, + fwd_mean_abs_pct_limit_for_model, ) +from .real_path import RealPathConfig, _delete_adapter_safetensors_on_pass def test_logical_map_flattens_shared_prefix_branches() -> None: @@ -35,6 +38,11 @@ def test_logical_map_flattens_shared_prefix_branches() -> None: [10, 11, 12, 13, 14], [10, 11, 12, 15, 16], ] + assert [prompt.packed_prompt_length for prompt in logical_map.prompts] == [2, 2] + assert [prompt.scored_token_start_index for prompt in logical_map.prompts] == [ + 3, + 3, + ] assert [token.token_id for token in logical_map.tokens] == [13, 14, 15, 16] assert [token.art_logit_index for token in logical_map.tokens] == [2, 3, 5, 6] assert [token.vllm_prompt_token_index for token in logical_map.tokens] == [ @@ -119,6 +127,39 @@ def test_compare_rollout_reports_base_lora_and_delta_separately() -> None: assert report.delta.mean_abs_pct > 0 +def test_real_path_default_generates_16_tokens_per_rollout() -> None: + assert RealPathConfig().max_completion_tokens == 16 + + +def test_real_path_deletes_only_adapter_safetensors_on_pass(tmp_path) -> None: + run_dir = tmp_path / "run" + active_lora = run_dir / "real_path_active_lora" + checkpoint = run_dir / "art_path" / "models" / "m" / "checkpoints" / "0000" + active_lora.mkdir(parents=True) + checkpoint.mkdir(parents=True) + for directory in (active_lora, checkpoint): + (directory / "adapter_model.safetensors").write_bytes(b"adapter") + (directory / "adapter_config.json").write_text("{}", encoding="utf-8") + score_path = run_dir / "real_path_vllm_lora_scores.json" + score_path.write_text("{}", encoding="utf-8") + + _delete_adapter_safetensors_on_pass(run_dir, passed=False) + + assert len(list(run_dir.rglob("adapter_model.safetensors"))) == 2 + + _delete_adapter_safetensors_on_pass(run_dir, passed=True) + + assert list(run_dir.rglob("adapter_model.safetensors")) == [] + assert len(list(run_dir.rglob("adapter_config.json"))) == 2 + assert score_path.exists() + + +def test_architecture_specific_real_path_limits() -> None: + assert fwd_mean_abs_pct_limit_for_model("Qwen/Qwen3-30B-A3B") == 7.0 + assert fwd_mean_abs_pct_limit_for_model("Qwen/Qwen3.5-35B-A3B") == 5.0 + assert TOP20_KL_CANDIDATE_TO_TARGET_LIMIT == 0.002 + + def test_compare_topk_reports_restricted_intersection_kl() -> None: target = ScoreBundle( side="megatron", @@ -215,3 +256,4 @@ def fake_run(*args, **kwargs): assert report.passed is True assert captured_env["ART_RUN_TRAIN_INF_MISMATCH_LIVE"] == "1" + assert captured_env["ART_REAL_PATH_MAX_COMPLETION_TOKENS"] == "16" diff --git a/tests/integration/megatron/train_inf_mismatch/vllm_forward_trace_site/sitecustomize.py b/tests/integration/megatron/train_inf_mismatch/vllm_forward_trace_site/sitecustomize.py new file mode 100644 index 000000000..54ba8f861 --- /dev/null +++ b/tests/integration/megatron/train_inf_mismatch/vllm_forward_trace_site/sitecustomize.py @@ -0,0 +1,238 @@ +from __future__ import annotations + +import builtins +import functools +import json +import os +from pathlib import Path +import re +import threading +import time +from typing import Any + +_REAL_IMPORT = builtins.__import__ +_LOCK = threading.Lock() +_PATCHED: set[str] = set() +_CALL_INDEX = 0 +_LAYER_RE = re.compile(r"model\.layers\.\d+") + + +def _trace_dir() -> Path | None: + raw = os.environ.get("ART_VLLM_FORWARD_TRACE_DIR") + return Path(raw) if raw else None + + +def _event(kind: str, **payload: Any) -> None: + trace_dir = _trace_dir() + if trace_dir is None: + return + trace_dir.mkdir(parents=True, exist_ok=True) + row = { + "kind": kind, + "pid": os.getpid(), + "time": time.time(), + **payload, + } + with (trace_dir / "manifest.jsonl").open("a", encoding="utf-8") as handle: + handle.write(json.dumps(row, sort_keys=True, default=str) + "\n") + + +def _next_index() -> int: + global _CALL_INDEX + with _LOCK: + value = _CALL_INDEX + _CALL_INDEX += 1 + return value + + +def _primary_tensor(value: Any) -> Any: + import torch + + if isinstance(value, torch.Tensor): + return value + if isinstance(value, dict): + for item in value.values(): + tensor = _primary_tensor(item) + if isinstance(tensor, torch.Tensor): + return tensor + if isinstance(value, (list, tuple)): + for item in value: + tensor = _primary_tensor(item) + if isinstance(tensor, torch.Tensor): + return tensor + return None + + +def _primary_input(name: str, inputs: Any) -> Any: + import torch + + if ( + _LAYER_RE.fullmatch(name) + or name.endswith(".self_attn") + or name.endswith(".attention") + ) and isinstance(inputs, tuple): + for item in inputs[1:]: + if isinstance(item, torch.Tensor) and item.is_floating_point(): + return item + return _primary_tensor(inputs) + + +def _save_tensor( + trace_dir: Path, call_index: int, field: str, tensor: Any +) -> str | None: + import torch + + if not isinstance(tensor, torch.Tensor): + return None + max_rows = int(os.environ.get("ART_VLLM_FORWARD_TRACE_MAX_ROWS", "768")) + if tensor.ndim > 0 and int(tensor.shape[0]) > max_rows: + return None + rel_path = Path("tensors") / f"{call_index:06d}_{field}.pt" + path = trace_dir / rel_path + path.parent.mkdir(parents=True, exist_ok=True) + torch.save(tensor.detach().cpu(), path) + return str(rel_path) + + +def _should_capture(name: str) -> bool: + if name == "model.embed_tokens" or name == "model.norm": + return True + if _LAYER_RE.fullmatch(name): + return True + if os.environ.get("ART_VLLM_FORWARD_TRACE_DETAIL") != "1": + return False + return ( + name.endswith(".input_layernorm") + or name.endswith(".self_attn") + or name.endswith(".qkv_proj") + or name.endswith(".q_norm") + or name.endswith(".k_norm") + or name.endswith(".o_proj") + or name.endswith(".post_attention_layernorm") + or name.endswith(".mlp") + or name.endswith(".gate_up_proj") + or name.endswith(".down_proj") + ) + + +def _shape(value: Any) -> list[int] | None: + return list(value.shape) if hasattr(value, "shape") else None + + +def _make_hook(name: str): + def _hook(module: Any, inputs: Any, output: Any) -> None: + trace_dir = _trace_dir() + if trace_dir is None: + return + call_index = _next_index() + primary_input = _primary_input(name, inputs) + primary_output = _primary_tensor(output) + _event( + "module", + call_index=call_index, + module_name=name, + module_type=module.__class__.__name__, + primary_input_shape=_shape(primary_input), + primary_output_shape=_shape(primary_output), + primary_input_path=_save_tensor( + trace_dir, call_index, "primary_input", primary_input + ), + primary_output_path=_save_tensor( + trace_dir, call_index, "primary_output", primary_output + ), + ) + + return _hook + + +def _register_model_hooks(model: Any) -> None: + if getattr(model, "_art_vllm_forward_trace_registered", False): + return + names: list[str] = [] + for name, module in model.named_modules(): + if _should_capture(name): + module.register_forward_hook(_make_hook(name)) + names.append(name) + setattr(model, "_art_vllm_forward_trace_registered", True) + _event("registered_module_hooks", module_names=names) + + +def _patch_causal_lm_class(module: Any, class_name: str) -> None: + key = f"{module.__name__}.{class_name}" + if key in _PATCHED or not hasattr(module, class_name): + return + cls = getattr(module, class_name) + original_init = cls.__init__ + original_compute_logits = getattr(cls, "compute_logits", None) + + @functools.wraps(original_init) + def __init__(self: Any, *args: Any, **kwargs: Any) -> None: + original_init(self, *args, **kwargs) + if _trace_dir() is not None: + _register_model_hooks(self) + + cls.__init__ = __init__ + + if original_compute_logits is not None: + + @functools.wraps(original_compute_logits) + def compute_logits(self: Any, hidden_states: Any, *args: Any, **kwargs: Any): + output = original_compute_logits(self, hidden_states, *args, **kwargs) + trace_dir = _trace_dir() + if trace_dir is not None: + call_index = _next_index() + _event( + "compute_logits", + call_index=call_index, + module_name="compute_logits", + module_type=self.__class__.__name__, + primary_input_shape=_shape(hidden_states), + primary_output_shape=_shape(output), + primary_input_path=_save_tensor( + trace_dir, call_index, "primary_input", hidden_states + ), + primary_output_path=( + _save_tensor(trace_dir, call_index, "primary_output", output) + if os.environ.get("ART_VLLM_FORWARD_TRACE_SAVE_LOGITS") == "1" + else None + ), + ) + return output + + cls.compute_logits = compute_logits + + _PATCHED.add(key) + _event("patched_class", target=key) + + +def _maybe_patch(name: str, module: Any) -> None: + if _trace_dir() is None: + return + if name == "vllm.model_executor.models.qwen3": + _patch_causal_lm_class(module, "Qwen3ForCausalLM") + elif name == "vllm.model_executor.models.qwen3_moe": + _patch_causal_lm_class(module, "Qwen3MoeForCausalLM") + + +def _import(name, globals=None, locals=None, fromlist=(), level=0): + module = _REAL_IMPORT(name, globals, locals, fromlist, level) + if level == 0: + _maybe_patch(name, module) + return module + + +builtins.__import__ = _import # ty: ignore[invalid-assignment] + + +def _patch_loop() -> None: + import sys + + while True: + if _trace_dir() is not None: + for name, module in list(sys.modules.items()): + _maybe_patch(name, module) + time.sleep(0.1) + + +threading.Thread(target=_patch_loop, daemon=True).start() +_event("sitecustomize_active") diff --git a/tests/integration/megatron/train_inf_mismatch/workflow_stage.py b/tests/integration/megatron/train_inf_mismatch/workflow_stage.py index 296c0184d..b04776c59 100644 --- a/tests/integration/megatron/train_inf_mismatch/workflow_stage.py +++ b/tests/integration/megatron/train_inf_mismatch/workflow_stage.py @@ -45,6 +45,7 @@ def run_train_inf_mismatch(*, base_model: str) -> TrainInfMismatchReport: env["BASE_MODEL"] = base_model env["ART_RUN_TRAIN_INF_MISMATCH_LIVE"] = "1" env["ART_TRAIN_INF_MISMATCH_BASE_MODEL"] = base_model + env["ART_REAL_PATH_MAX_COMPLETION_TOKENS"] = "16" existing_pythonpath = env.get("PYTHONPATH") tests_dir = str(REPO_ROOT / "tests") env["PYTHONPATH"] = ( diff --git a/tests/unit/test_moe_routing_real_path.py b/tests/unit/test_moe_routing_real_path.py new file mode 100644 index 000000000..1f1c57e19 --- /dev/null +++ b/tests/unit/test_moe_routing_real_path.py @@ -0,0 +1,203 @@ +from __future__ import annotations + +import math +from typing import Any, cast + +from openai.types.chat.chat_completion import Choice +import pytest + +from art.megatron.routing_replay import ( + build_moe_routing_replay_bundle_from_packed_tensors, +) +from art.preprocessing.moe_routing import ( + ART_MOE_ROUTING_METADATA_KEY, + align_choice_routes_to_tokenized_result, + attach_moe_routing_metadata_to_choice, +) +from art.preprocessing.pack import packed_tensors_from_tokenized_results +from art.preprocessing.tokenize import TokenizedResult +from art.trajectories import Trajectory + + +class _FakeTokenizer: + def decode(self, token_id: int) -> str: + return str(token_id) + + +def _choice(metadata: dict[str, Any]) -> Choice: + return Choice.model_validate( + { + "index": 0, + "finish_reason": "stop", + "message": {"role": "assistant", "content": "x"}, + ART_MOE_ROUTING_METADATA_KEY: metadata, + } + ) + + +def _route(seed: int) -> list[list[int]]: + return [[seed, seed + 1], [seed + 2, seed + 3]] + + +def test_align_choice_routes_to_tokenized_result_maps_vllm_routes() -> None: + routes, stats = align_choice_routes_to_tokenized_result( + token_ids=[10, 11, 20, 21], + choices=[ + _choice( + { + "prompt_token_ids": [10, 11], + "completion_token_ids": [20, 21], + "prompt_routed_experts": [_route(0), _route(10)], + "completion_routed_experts": [_route(20), _route(30)], + } + ) + ], + choice_offsets=[2], + choice_token_lengths=[2], + ) + + assert routes == [_route(0), _route(10), _route(20), _route(30)] + assert stats.choices_with_routing == 1 + assert stats.routed_tokens == 4 + + +def test_align_choice_routes_to_tokenized_result_uses_current_vllm_contract() -> None: + response_payload = { + "prompt_token_ids": [10, 11], + "prompt_routed_experts": [_route(0), _route(10)], + "choices": [ + { + "index": 0, + "finish_reason": "stop", + "message": {"role": "assistant", "content": "x"}, + "token_ids": [20, 21], + "routed_experts": [_route(20), _route(30)], + } + ], + } + choice = Choice.model_validate(response_payload["choices"][0]) + attach_moe_routing_metadata_to_choice( + choice=choice, + response_payload=response_payload, + choice_index=0, + ) + + routes, stats = align_choice_routes_to_tokenized_result( + token_ids=[10, 11, 20, 21], + choices=[choice], + choice_offsets=[2], + choice_token_lengths=[2], + ) + + assert routes == [_route(0), _route(10), _route(20), _route(30)] + assert stats.choices_with_routing == 1 + assert stats.routed_tokens == 4 + + +def test_align_choice_routes_to_tokenized_result_rejects_token_mismatch() -> None: + with pytest.raises(RuntimeError, match="prompt token ids do not match"): + align_choice_routes_to_tokenized_result( + token_ids=[10, 12, 20], + choices=[ + _choice( + { + "prompt_token_ids": [10, 11], + "completion_token_ids": [20], + "prompt_routed_experts": [_route(0), _route(10)], + "completion_routed_experts": [_route(20)], + } + ) + ], + choice_offsets=[2], + choice_token_lengths=[1], + ) + + +def _tokenized( + token_ids: list[int], + routes: list[list[list[int]]], + *, + prompt_id: int, + prompt_length: int, +) -> TokenizedResult: + return TokenizedResult( + advantage=1.0, + chat="", + token_ids=token_ids, + input_pos=list(range(len(token_ids))), + assistant_mask=[0] * prompt_length + [1] * (len(token_ids) - prompt_length), + logprobs=[math.nan] * prompt_length + [-1.0] * (len(token_ids) - prompt_length), + pixel_values=None, + image_grid_thw=None, + trajectory=Trajectory(), + choice_offsets=[prompt_length], + extra_logprobs={}, + _tokenizer=_FakeTokenizer(), # type: ignore[arg-type] + moe_routed_experts=cast(list[list[list[int]] | None], routes), + prompt_id=prompt_id, + prompt_length=prompt_length, + ) + + +def test_pack_carries_routes_through_shared_prefix_splicing() -> None: + first = _tokenized( + [10, 11, 20, 21], + [_route(0), _route(10), _route(20), _route(30)], + prompt_id=123, + prompt_length=2, + ) + second = _tokenized( + [10, 11, 22, 23], + [_route(0), _route(99), _route(40), _route(50)], + prompt_id=123, + prompt_length=2, + ) + + packed = packed_tensors_from_tokenized_results( + [first, second], + seq_len=8, + pad_token_id=0, + truncate_long_results=False, + include_moe_routing=True, + ) + + assert packed["tokens"].tolist()[0][:6] == [10, 11, 20, 21, 22, 23] + routing_replay = packed["moe_routing_replay"] + assert routing_replay.expert_indices.tolist()[0][:6] == [ + _route(0), + _route(10), + _route(20), + _route(30), + _route(40), + _route(50), + ] + stats = routing_replay.pack_stats + assert stats.shared_prefix_rows == 2 + assert stats.shared_prefix_conflict_rows == 1 + assert stats.shared_prefix_conflict_slots == 4 + + +def test_build_replay_bundle_uses_packed_sequence_sample_calls() -> None: + result = _tokenized( + [10, 11, 20], + [_route(0), _route(10), _route(20)], + prompt_id=456, + prompt_length=2, + ) + packed = packed_tensors_from_tokenized_results( + [result], + seq_len=4, + pad_token_id=0, + truncate_long_results=False, + include_moe_routing=True, + ) + + bundle = build_moe_routing_replay_bundle_from_packed_tensors( + packed_tensors=packed, + global_grad_accumulation_sequences=1, + ) + + route = bundle.steps[0].routers["chunk_00.layer_0000.mlp.router"].calls[0] + assert route.sample_index == 0 + assert route.expert_indices.tolist()[:3] == [[0, 1], [10, 11], [20, 21]] + assert len(set(route.expert_indices.tolist()[3])) == 2 diff --git a/tests/unit/test_moe_routing_replay.py b/tests/unit/test_moe_routing_replay.py index a43a701a1..ca16abc21 100644 --- a/tests/unit/test_moe_routing_replay.py +++ b/tests/unit/test_moe_routing_replay.py @@ -2,7 +2,7 @@ from pathlib import Path import tempfile -from typing import cast +from typing import Any, cast import pytest import torch @@ -20,62 +20,25 @@ ) -def _dense_from_compact( - route: RouterCallRoute, +def _make_route( + rows: list[list[int]], *, - dtype: torch.dtype, -) -> tuple[torch.Tensor, torch.Tensor]: - num_tokens = route.expert_indices.shape[0] - num_experts = route.num_experts - probs = torch.zeros((num_tokens, num_experts), dtype=dtype) - routing_map = torch.zeros((num_tokens, num_experts), dtype=torch.bool) - for token_idx in range(num_tokens): - for slot in range(route.expert_indices.shape[1]): - if not bool(route.expert_mask[token_idx, slot]): - continue - expert_idx = int(route.expert_indices[token_idx, slot].item()) - probs[token_idx, expert_idx] = route.expert_probs[token_idx, slot].to(dtype) - routing_map[token_idx, expert_idx] = True - return probs, routing_map - - -def _assert_probs_close(actual: torch.Tensor, expected: torch.Tensor) -> None: - max_diff = (actual - expected).abs().max().item() - assert max_diff < 1e-6 + sample_index: int | None = None, + micro_slot: int | None = None, +) -> RouterCallRoute: + indices = torch.tensor(rows, dtype=torch.int32) + return RouterCallRoute( + expert_indices=indices, + expert_mask=torch.ones_like(indices, dtype=torch.bool), + num_experts=3, + sample_index=sample_index, + micro_slot=micro_slot, + ) def _make_bundle() -> tuple[MoeRoutingReplayBundle, RouterCallRoute]: router_key = "chunk_00.layer_0000.mlp.router" - route = RouterCallRoute( - expert_indices=torch.tensor( - [ - [0, 2], - [1, 0], - [2, 1], - [1, 0], - ], - dtype=torch.int32, - ), - expert_probs=torch.tensor( - [ - [0.70, 0.30], - [1.00, 0.00], - [0.65, 0.35], - [1.00, 0.00], - ], - dtype=torch.float32, - ), - expert_mask=torch.tensor( - [ - [True, True], - [True, False], - [True, True], - [True, False], - ], - dtype=torch.bool, - ), - num_experts=3, - ) + route = _make_route([[0, 2], [1, 0], [2, 1], [1, 0]], sample_index=0) bundle = MoeRoutingReplayBundle( topology=ParallelTopology(tp=1, ep=1, etp=1, dp=1, sp=False, cp=1, pp=1, vpp=1), num_steps=1, @@ -93,20 +56,6 @@ def _make_bundle() -> tuple[MoeRoutingReplayBundle, RouterCallRoute]: def _make_sampled_bundle() -> MoeRoutingReplayBundle: router_key = "chunk_00.layer_0000.mlp.router" - route0 = RouterCallRoute( - expert_indices=torch.tensor([[0, 2], [1, 0]], dtype=torch.int32), - expert_probs=torch.tensor([[0.70, 0.30], [1.00, 0.00]], dtype=torch.float32), - expert_mask=torch.tensor([[True, True], [True, False]], dtype=torch.bool), - num_experts=3, - sample_index=0, - ) - route1 = RouterCallRoute( - expert_indices=torch.tensor([[2, 1], [0, 1]], dtype=torch.int32), - expert_probs=torch.tensor([[0.60, 0.40], [1.00, 0.00]], dtype=torch.float32), - expert_mask=torch.tensor([[True, True], [True, False]], dtype=torch.bool), - num_experts=3, - sample_index=1, - ) return MoeRoutingReplayBundle( topology=ParallelTopology(tp=1, ep=1, etp=1, dp=1, sp=False, cp=1, pp=1, vpp=1), num_steps=1, @@ -114,7 +63,14 @@ def _make_sampled_bundle() -> MoeRoutingReplayBundle: router_keys=[router_key], steps={ 0: StepRoutes( - routers={router_key: StepRouterRoutes(calls={0: route0, 1: route1})}, + routers={ + router_key: StepRouterRoutes( + calls={ + 0: _make_route([[0, 2], [1, 0]], sample_index=0), + 1: _make_route([[2, 1], [0, 1]], sample_index=1), + } + ) + }, global_token_uids=torch.arange(2, dtype=torch.int64), ) }, @@ -123,27 +79,6 @@ def _make_sampled_bundle() -> MoeRoutingReplayBundle: def _make_multi_call_bundle() -> MoeRoutingReplayBundle: router_key = "chunk_00.layer_0000.mlp.router" - route0 = RouterCallRoute( - expert_indices=torch.tensor([[0, 2]], dtype=torch.int32), - expert_probs=torch.tensor([[0.70, 0.30]], dtype=torch.float32), - expert_mask=torch.tensor([[True, True]], dtype=torch.bool), - num_experts=3, - sample_index=0, - ) - route1 = RouterCallRoute( - expert_indices=torch.tensor([[1, 0]], dtype=torch.int32), - expert_probs=torch.tensor([[1.00, 0.00]], dtype=torch.float32), - expert_mask=torch.tensor([[True, False]], dtype=torch.bool), - num_experts=3, - sample_index=0, - ) - route2 = RouterCallRoute( - expert_indices=torch.tensor([[2, 1]], dtype=torch.int32), - expert_probs=torch.tensor([[0.55, 0.45]], dtype=torch.float32), - expert_mask=torch.tensor([[True, True]], dtype=torch.bool), - num_experts=3, - sample_index=1, - ) return MoeRoutingReplayBundle( topology=ParallelTopology(tp=1, ep=1, etp=1, dp=1, sp=False, cp=1, pp=1, vpp=1), num_steps=1, @@ -153,7 +88,11 @@ def _make_multi_call_bundle() -> MoeRoutingReplayBundle: 0: StepRoutes( routers={ router_key: StepRouterRoutes( - calls={0: route0, 1: route1, 2: route2} + calls={ + 0: _make_route([[0, 2]], sample_index=0), + 1: _make_route([[1, 0]], sample_index=0), + 2: _make_route([[2, 1]], sample_index=1), + } ) }, global_token_uids=torch.arange(1, dtype=torch.int64), @@ -162,21 +101,6 @@ def _make_multi_call_bundle() -> MoeRoutingReplayBundle: ) -class _IdentityIndexer: - def build_local_token_uids( - self, - *, - global_token_uids: torch.Tensor, - num_local_tokens: int, - sequence_parallel: bool, - context_parallel_size: int, - ) -> torch.Tensor: - del sequence_parallel, context_parallel_size - if int(global_token_uids.numel()) < num_local_tokens: - raise RuntimeError("num_local_tokens exceeds global token count") - return global_token_uids[:num_local_tokens].clone() - - class _FakeParallelState: def __init__( self, @@ -199,43 +123,123 @@ def get_tensor_model_parallel_rank(self) -> int: return self._tp_rank -class _FakeRouter(nn.Module): +class _FakeRouterReplay: def __init__(self) -> None: + self.target_topk_idx: torch.Tensor | None = None + self.action: Any = None + self.targets_seen: list[torch.Tensor] = [] + + def set_target_indices(self, topk_indices: torch.Tensor) -> None: + self.target_topk_idx = topk_indices + self.targets_seen.append(topk_indices.detach().cpu().clone()) + + def set_router_replay_action(self, action: Any) -> None: + self.action = action + + def get_replay_topk( + self, + scores: torch.Tensor, + topk: int, + num_groups: int | None = None, + group_topk: int | None = None, + default_compute_topk: Any = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + del num_groups, group_topk + if self.target_topk_idx is None: + return default_compute_topk(scores, topk, None, None) + indices = self.target_topk_idx.to(device=scores.device, dtype=torch.long) + return scores.gather(1, indices), indices + + +class _FakeRouter(nn.Module): + def __init__(self, *, topk: int = 2, router_replay: Any | None = None) -> None: super().__init__() + self.topk = topk + self.router_replay = ( + router_replay if router_replay is not None else _FakeRouterReplay() + ) self.config = type( "Config", (), - {"sequence_parallel": False, "context_parallel_size": 1}, + { + "sequence_parallel": False, + "context_parallel_size": 1, + "moe_router_fusion": False, + }, )() def routing(self, logits: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]: - probs = torch.softmax(logits, dim=-1) - routing_map = torch.zeros_like(logits, dtype=torch.bool) + scores = torch.softmax(logits, dim=-1) + + def _default_topk( + local_scores: torch.Tensor, + topk: int, + num_groups: int | None = None, + group_topk: int | None = None, + ) -> tuple[torch.Tensor, torch.Tensor]: + del num_groups, group_topk + return torch.topk(local_scores, k=topk, dim=1) + + selected_probs, selected_indices = self.router_replay.get_replay_topk( + scores, + self.topk, + None, + None, + _default_topk, + ) + probs = torch.zeros_like(scores) + routing_map = torch.zeros_like(scores, dtype=torch.bool) + rows = torch.arange(scores.shape[0], device=scores.device).unsqueeze(1) + probs[rows, selected_indices] = selected_probs + routing_map[rows, selected_indices] = True return probs, routing_map class _FakeMlp(nn.Module): - def __init__(self) -> None: + def __init__(self, router: _FakeRouter | None = None) -> None: super().__init__() - self.router = _FakeRouter() + self.router = router if router is not None else _FakeRouter() class _FakeLayer(nn.Module): - def __init__(self) -> None: + def __init__(self, router: _FakeRouter | None = None) -> None: super().__init__() - self.mlp = _FakeMlp() + self.mlp = _FakeMlp(router) class _FakeDecoder(nn.Module): - def __init__(self) -> None: + def __init__(self, router: _FakeRouter | None = None) -> None: super().__init__() - self.layers = nn.ModuleList([_FakeLayer()]) + self.layers = nn.ModuleList([_FakeLayer(router)]) class _FakeChunk(nn.Module): - def __init__(self) -> None: + def __init__(self, router: _FakeRouter | None = None) -> None: super().__init__() - self.decoder = _FakeDecoder() + self.decoder = _FakeDecoder(router) + + +def _fake_chunk_router(chunk: _FakeChunk) -> _FakeRouter: + layer = cast(_FakeLayer, chunk.decoder.layers[0]) + return cast(_FakeRouter, layer.mlp.router) + + +def _assert_target( + replay: _FakeRouterReplay, + expected: torch.Tensor, + *, + index: int = -1, +) -> None: + assert torch.equal(replay.targets_seen[index], expected.to(torch.long)) + + +def _expected_routing_map(route: RouterCallRoute) -> torch.Tensor: + routing_map = torch.zeros( + (route.num_global_tokens, route.num_experts), dtype=torch.bool + ) + rows = torch.arange(route.num_global_tokens).unsqueeze(1) + routing_map[rows, route.expert_indices.to(torch.long)] = True + return routing_map def test_build_router_key_from_compiled_module_name() -> None: @@ -304,31 +308,26 @@ def test_bundle_roundtrip_disk() -> None: assert loaded.router_keys == bundle.router_keys loaded_route = loaded.steps[0].routers[bundle.router_keys[0]].calls[0] assert torch.equal(loaded_route.expert_indices, route.expert_indices) - assert torch.equal(loaded_route.expert_probs, route.expert_probs) assert torch.equal(loaded_route.expert_mask, route.expert_mask) -def test_controller_patches_router_and_replays() -> None: +def test_controller_uses_native_router_replay_target_indices() -> None: bundle, route = _make_bundle() - controller = MoeRoutingReplayController( - bundle=bundle, - strict=True, - local_token_indexer=_IdentityIndexer(), - ) + controller = MoeRoutingReplayController(bundle=bundle, strict=True, device="cpu") chunk = _FakeChunk() - controller.install_router_patches([chunk]) - controller.set_step(step_index=0, sample_index=0) + router = _fake_chunk_router(chunk) + replay = cast(_FakeRouterReplay, router.router_replay) - logits = torch.randn((4, 3), dtype=torch.float32) - router = cast( - _FakeRouter, - chunk.decoder.layers[0].mlp.router, # ty: ignore[possibly-missing-attribute] - ) - replay_probs, replay_map = router.routing(logits) - expected_probs, expected_map = _dense_from_compact(route, dtype=logits.dtype) + controller.install_router_patches([chunk]) + controller.set_step(step_index=0, sample_index=[0]) + controller.begin_micro(0, 0) + _probs, routing_map = router.routing(torch.randn((4, 3), dtype=torch.float32)) - assert torch.equal(replay_map.cpu(), expected_map) - _assert_probs_close(replay_probs.cpu(), expected_probs) + expected_map = torch.zeros((4, 3), dtype=torch.bool) + rows = torch.arange(4).unsqueeze(1) + expected_map[rows, route.expert_indices.to(torch.long)] = True + assert torch.equal(routing_map.cpu(), expected_map) + _assert_target(replay, route.expert_indices) controller.finalize_step() controller.remove_router_patches() @@ -336,55 +335,37 @@ def test_controller_patches_router_and_replays() -> None: def test_controller_finalize_fails_when_unconsumed_calls_remain() -> None: bundle, _route = _make_bundle() - controller = MoeRoutingReplayController( - bundle=bundle, - strict=True, - local_token_indexer=_IdentityIndexer(), - ) + controller = MoeRoutingReplayController(bundle=bundle, strict=True, device="cpu") chunk = _FakeChunk() controller.install_router_patches([chunk]) - controller.set_step(step_index=0, sample_index=0) + controller.set_step(step_index=0, sample_index=[0]) with pytest.raises(RuntimeError, match="consumption mismatch"): controller.finalize_step() def test_controller_reuses_route_for_recompute_with_same_active_micro() -> None: bundle = _make_sampled_bundle() - controller = MoeRoutingReplayController( - bundle=bundle, - strict=True, - local_token_indexer=_IdentityIndexer(), - ) + controller = MoeRoutingReplayController(bundle=bundle, strict=True, device="cpu") chunk = _FakeChunk() + router = _fake_chunk_router(chunk) + replay = cast(_FakeRouterReplay, router.router_replay) controller.install_router_patches([chunk]) controller.set_step(step_index=0, sample_index=[0, 1]) - router = cast( - _FakeRouter, - chunk.decoder.layers[0].mlp.router, # ty: ignore[possibly-missing-attribute] - ) - logits = torch.randn((2, 3), dtype=torch.float32) controller.begin_micro(0, 0) - first_probs, first_map = router.routing(logits) - recompute_probs, recompute_map = router.routing(logits) - controller.begin_micro(1, 1) - second_probs, second_map = router.routing(logits) - - expected_first_probs, expected_first_map = _dense_from_compact( - bundle.steps[0].routers[bundle.router_keys[0]].calls[0], - dtype=logits.dtype, - ) - expected_second_probs, expected_second_map = _dense_from_compact( - bundle.steps[0].routers[bundle.router_keys[0]].calls[1], - dtype=logits.dtype, + _probs, routing_map = router.routing(torch.randn((2, 3), dtype=torch.float32)) + _probs, recompute_routing_map = router.routing( + torch.randn((2, 3), dtype=torch.float32) ) + controller.begin_micro(1, 1) + _probs, next_routing_map = router.routing(torch.randn((2, 3), dtype=torch.float32)) - assert torch.equal(first_map.cpu(), expected_first_map) - _assert_probs_close(first_probs.cpu(), expected_first_probs) - assert torch.equal(recompute_map.cpu(), expected_first_map) - _assert_probs_close(recompute_probs.cpu(), expected_first_probs) - assert torch.equal(second_map.cpu(), expected_second_map) - _assert_probs_close(second_probs.cpu(), expected_second_probs) + calls = bundle.steps[0].routers[bundle.router_keys[0]].calls + _assert_target(replay, calls[0].expert_indices, index=0) + _assert_target(replay, calls[1].expert_indices, index=1) + assert torch.equal(routing_map.cpu(), _expected_routing_map(calls[0])) + assert torch.equal(recompute_routing_map.cpu(), _expected_routing_map(calls[0])) + assert torch.equal(next_routing_map.cpu(), _expected_routing_map(calls[1])) controller.finalize_step() controller.remove_router_patches() @@ -392,46 +373,47 @@ def test_controller_reuses_route_for_recompute_with_same_active_micro() -> None: def test_controller_consumes_multiple_captured_calls_before_recompute_reuse() -> None: bundle = _make_multi_call_bundle() - controller = MoeRoutingReplayController( - bundle=bundle, - strict=True, - local_token_indexer=_IdentityIndexer(), - ) + controller = MoeRoutingReplayController(bundle=bundle, strict=True, device="cpu") chunk = _FakeChunk() + router = _fake_chunk_router(chunk) + replay = cast(_FakeRouterReplay, router.router_replay) controller.install_router_patches([chunk]) controller.set_step(step_index=0, sample_index=[0, 1]) - router = cast( - _FakeRouter, - chunk.decoder.layers[0].mlp.router, # ty: ignore[possibly-missing-attribute] - ) - logits = torch.randn((1, 3), dtype=torch.float32) - controller.begin_micro(0, 0) - first_probs, first_map = router.routing(logits) - second_probs, second_map = router.routing(logits) - recompute_probs, recompute_map = router.routing(logits) - controller.begin_micro(1, 1) - next_probs, next_map = router.routing(logits) + with pytest.raises(RuntimeError, match="exactly one router call"): + controller.begin_micro(0, 0) - calls = bundle.steps[0].routers[bundle.router_keys[0]].calls - expected_first_probs, expected_first_map = _dense_from_compact( - calls[0], dtype=logits.dtype - ) - expected_second_probs, expected_second_map = _dense_from_compact( - calls[1], dtype=logits.dtype - ) - expected_next_probs, expected_next_map = _dense_from_compact( - calls[2], dtype=logits.dtype - ) + assert replay.targets_seen == [] - assert torch.equal(first_map.cpu(), expected_first_map) - _assert_probs_close(first_probs.cpu(), expected_first_probs) - assert torch.equal(second_map.cpu(), expected_second_map) - _assert_probs_close(second_probs.cpu(), expected_second_probs) - assert torch.equal(recompute_map.cpu(), expected_second_map) - _assert_probs_close(recompute_probs.cpu(), expected_second_probs) - assert torch.equal(next_map.cpu(), expected_next_map) - _assert_probs_close(next_probs.cpu(), expected_next_probs) - - controller.finalize_step() controller.remove_router_patches() + + +def test_controller_rejects_missing_native_router_replay() -> None: + bundle, _route = _make_bundle() + controller = MoeRoutingReplayController(bundle=bundle, strict=True, device="cpu") + chunk = _FakeChunk(router=_FakeRouter(router_replay=None)) + _fake_chunk_router(chunk).router_replay = None + + with pytest.raises(RuntimeError, match="moe_enable_routing_replay=True"): + controller.install_router_patches([chunk]) + + +def test_controller_rejects_masked_slots() -> None: + bundle, route = _make_bundle() + route.expert_mask[0, 1] = False + controller = MoeRoutingReplayController(bundle=bundle, strict=True, device="cpu") + chunk = _FakeChunk() + controller.install_router_patches([chunk]) + + with pytest.raises(RuntimeError, match="masked slots are unsupported"): + controller.set_step(step_index=0, sample_index=[0]) + + +def test_controller_rejects_topk_mismatch() -> None: + bundle, _route = _make_bundle() + controller = MoeRoutingReplayController(bundle=bundle, strict=True, device="cpu") + chunk = _FakeChunk(router=_FakeRouter(topk=1)) + controller.install_router_patches([chunk]) + + with pytest.raises(RuntimeError, match="topk does not match"): + controller.set_step(step_index=0, sample_index=[0]) diff --git a/uv.lock b/uv.lock index 286c322c0..d0411e156 100644 --- a/uv.lock +++ b/uv.lock @@ -1,28 +1,19 @@ version = 1 revision = 3 -requires-python = ">=3.11" +requires-python = ">=3.12" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'linux'", "python_full_version == '3.13.*' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and sys_platform == 'linux'", - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32'", - "python_full_version < '3.12' and sys_platform == 'linux'", - "python_full_version < '3.12' and sys_platform == 'win32'", - "python_full_version < '3.12' and sys_platform == 'emscripten'", - "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32'", + "python_full_version < '3.13' and sys_platform == 'linux'", + "python_full_version >= '3.14' and sys_platform != 'linux'", + "python_full_version == '3.13.*' and sys_platform != 'linux'", + "python_full_version < '3.13' and sys_platform != 'linux'", ] [manifest] overrides = [ { name = "flashinfer-python", specifier = "==0.6.1" }, + { name = "megatron-core", specifier = "==0.17.0" }, { name = "numpy", specifier = "<2" }, { name = "nvidia-resiliency-ext", specifier = "<0.5" }, { name = "quack-kernels", specifier = "==0.2.5" }, @@ -131,23 +122,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/50/42/32cf8e7704ceb4481406eb87161349abb46a57fee3f008ba9cb610968646/aiohttp-3.13.3.tar.gz", hash = "sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88", size = 7844556, upload-time = "2026-01-03T17:33:05.204Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/4c/a164164834f03924d9a29dc3acd9e7ee58f95857e0b467f6d04298594ebb/aiohttp-3.13.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b", size = 746051, upload-time = "2026-01-03T17:29:43.287Z" }, - { url = "https://files.pythonhosted.org/packages/82/71/d5c31390d18d4f58115037c432b7e0348c60f6f53b727cad33172144a112/aiohttp-3.13.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64", size = 499234, upload-time = "2026-01-03T17:29:44.822Z" }, - { url = "https://files.pythonhosted.org/packages/0e/c9/741f8ac91e14b1d2e7100690425a5b2b919a87a5075406582991fb7de920/aiohttp-3.13.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea", size = 494979, upload-time = "2026-01-03T17:29:46.405Z" }, - { url = "https://files.pythonhosted.org/packages/75/b5/31d4d2e802dfd59f74ed47eba48869c1c21552c586d5e81a9d0d5c2ad640/aiohttp-3.13.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a", size = 1748297, upload-time = "2026-01-03T17:29:48.083Z" }, - { url = "https://files.pythonhosted.org/packages/1a/3e/eefad0ad42959f226bb79664826883f2687d602a9ae2941a18e0484a74d3/aiohttp-3.13.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540", size = 1707172, upload-time = "2026-01-03T17:29:49.648Z" }, - { url = "https://files.pythonhosted.org/packages/c5/3a/54a64299fac2891c346cdcf2aa6803f994a2e4beeaf2e5a09dcc54acc842/aiohttp-3.13.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b", size = 1805405, upload-time = "2026-01-03T17:29:51.244Z" }, - { url = "https://files.pythonhosted.org/packages/6c/70/ddc1b7169cf64075e864f64595a14b147a895a868394a48f6a8031979038/aiohttp-3.13.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3", size = 1899449, upload-time = "2026-01-03T17:29:53.938Z" }, - { url = "https://files.pythonhosted.org/packages/a1/7e/6815aab7d3a56610891c76ef79095677b8b5be6646aaf00f69b221765021/aiohttp-3.13.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1", size = 1748444, upload-time = "2026-01-03T17:29:55.484Z" }, - { url = "https://files.pythonhosted.org/packages/6b/f2/073b145c4100da5511f457dc0f7558e99b2987cf72600d42b559db856fbc/aiohttp-3.13.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3", size = 1606038, upload-time = "2026-01-03T17:29:57.179Z" }, - { url = "https://files.pythonhosted.org/packages/0a/c1/778d011920cae03ae01424ec202c513dc69243cf2db303965615b81deeea/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440", size = 1724156, upload-time = "2026-01-03T17:29:58.914Z" }, - { url = "https://files.pythonhosted.org/packages/0e/cb/3419eabf4ec1e9ec6f242c32b689248365a1cf621891f6f0386632525494/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7", size = 1722340, upload-time = "2026-01-03T17:30:01.962Z" }, - { url = "https://files.pythonhosted.org/packages/7a/e5/76cf77bdbc435bf233c1f114edad39ed4177ccbfab7c329482b179cff4f4/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c", size = 1783041, upload-time = "2026-01-03T17:30:03.609Z" }, - { url = "https://files.pythonhosted.org/packages/9d/d4/dd1ca234c794fd29c057ce8c0566b8ef7fd6a51069de5f06fa84b9a1971c/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51", size = 1596024, upload-time = "2026-01-03T17:30:05.132Z" }, - { url = "https://files.pythonhosted.org/packages/55/58/4345b5f26661a6180afa686c473620c30a66afdf120ed3dd545bbc809e85/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4", size = 1804590, upload-time = "2026-01-03T17:30:07.135Z" }, - { url = "https://files.pythonhosted.org/packages/7b/06/05950619af6c2df7e0a431d889ba2813c9f0129cec76f663e547a5ad56f2/aiohttp-3.13.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29", size = 1740355, upload-time = "2026-01-03T17:30:09.083Z" }, - { url = "https://files.pythonhosted.org/packages/3e/80/958f16de79ba0422d7c1e284b2abd0c84bc03394fbe631d0a39ffa10e1eb/aiohttp-3.13.3-cp311-cp311-win32.whl", hash = "sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239", size = 433701, upload-time = "2026-01-03T17:30:10.869Z" }, - { url = "https://files.pythonhosted.org/packages/dc/f2/27cdf04c9851712d6c1b99df6821a6623c3c9e55956d4b1e318c337b5a48/aiohttp-3.13.3-cp311-cp311-win_amd64.whl", hash = "sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f", size = 457678, upload-time = "2026-01-03T17:30:12.719Z" }, { url = "https://files.pythonhosted.org/packages/a0/be/4fc11f202955a69e0db803a12a062b8379c970c7c84f4882b6da17337cc1/aiohttp-3.13.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c", size = 739732, upload-time = "2026-01-03T17:30:14.23Z" }, { url = "https://files.pythonhosted.org/packages/97/2c/621d5b851f94fa0bb7430d6089b3aa970a9d9b75196bc93bb624b0db237a/aiohttp-3.13.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168", size = 494293, upload-time = "2026-01-03T17:30:15.96Z" }, { url = "https://files.pythonhosted.org/packages/5d/43/4be01406b78e1be8320bb8316dc9c42dbab553d281c40364e0f862d5661c/aiohttp-3.13.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d", size = 493533, upload-time = "2026-01-03T17:30:17.431Z" }, @@ -274,15 +248,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/29/6533c317b74f707ea28f8d633734dbda2119bbadfc61b2f3640ba835d0f7/alembic-1.18.4-py3-none-any.whl", hash = "sha256:a5ed4adcf6d8a4cb575f3d759f071b03cd6e5c7618eb796cb52497be25bfe19a", size = 263893, upload-time = "2026-02-10T16:00:49.997Z" }, ] -[[package]] -name = "aniso8601" -version = "10.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8b/8d/52179c4e3f1978d3d9a285f98c706642522750ef343e9738286130423730/aniso8601-10.0.1.tar.gz", hash = "sha256:25488f8663dd1528ae1f54f94ac1ea51ae25b4d531539b8bc707fed184d16845", size = 47190, upload-time = "2025-04-18T17:29:42.995Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/59/75/e0e10dc7ed1408c28e03a6cb2d7a407f99320eb953f229d008a7a6d05546/aniso8601-10.0.1-py2.py3-none-any.whl", hash = "sha256:eb19717fd4e0db6de1aab06f12450ab92144246b257423fe020af5748c0cb89e", size = 52848, upload-time = "2025-04-18T17:29:41.492Z" }, -] - [[package]] name = "annotated-doc" version = "0.0.4" @@ -329,12 +294,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/6f/60/1e787a0b5ebf318483235be2a689ee367173983067e441b8379564f667c0/apache_tvm_ffi-0.1.9.tar.gz", hash = "sha256:d2d402587e8906de0a07f4746aa78f3d452c7efe3625d4bb39ac2ad693bce530", size = 2513731, upload-time = "2026-02-27T19:28:06.602Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/44/130571cede8704b1412e48b3dd78de41b4d31b68241f954743d1a9925bd9/apache_tvm_ffi-0.1.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:932d94e29595a47109f0ef6e0b4209a934451582954ea8b426e758d6b3e307e3", size = 2070368, upload-time = "2026-02-27T19:27:13.779Z" }, - { url = "https://files.pythonhosted.org/packages/42/b1/9f2cfd6d49b03c5d4ec5c12548d911e2e01265be783f343103b4df716765/apache_tvm_ffi-0.1.9-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c0449fc3802987c3652bea266ffda2934a6f69c80bba791a3f55b91040656a18", size = 2231154, upload-time = "2026-02-27T19:27:15.691Z" }, - { url = "https://files.pythonhosted.org/packages/55/43/63faedea83494e99122466a993bcdccd31cf93c7e8a0d56731120e82e2b9/apache_tvm_ffi-0.1.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6f16d73a82a9e68a439b7d233d48b1b929be17fe92df4bbf1ee2274e573144a3", size = 2323130, upload-time = "2026-02-27T19:27:17.259Z" }, - { url = "https://files.pythonhosted.org/packages/27/96/d735bc4c528efaf0a8a954076963c727aad2dde8577641aa9025ec4f2d52/apache_tvm_ffi-0.1.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:01ebb1308b2666c206aa9a4015eb48f03a5d98ea2e9cfb002bd5e2ca0b9c7ef3", size = 2159854, upload-time = "2026-02-27T19:27:18.789Z" }, - { url = "https://files.pythonhosted.org/packages/e4/3b/6cfc82a3ab5d9e501bbcee5df36eebe09da1c384461d7a55e2a17776d117/apache_tvm_ffi-0.1.9-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21365abd2a2a1a6d3b4e6e4f048309651125becfa795440c3607f3cc27d30ac7", size = 2307140, upload-time = "2026-02-27T19:27:20.222Z" }, - { url = "https://files.pythonhosted.org/packages/5f/61/3ffe1fe3190e12807a12b72ed0d291c7f66569c2e7c3571fde18175f19e1/apache_tvm_ffi-0.1.9-cp311-cp311-win_amd64.whl", hash = "sha256:9ee710a9fba3d9ff9747870bbd7e2175eb8d5b9c791f17fd645f35f6dab3f8aa", size = 1993218, upload-time = "2026-02-27T19:27:22.043Z" }, { url = "https://files.pythonhosted.org/packages/df/f2/b8c4b151169f6d7ba8773c8af68b2e0c1013d7fb3f1bdf87573f47157ce9/apache_tvm_ffi-0.1.9-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:49e52350b0470654847de752e65603b604a4d3323e7e9f5e8a982f44acc4c143", size = 2041756, upload-time = "2026-02-27T19:27:23.931Z" }, { url = "https://files.pythonhosted.org/packages/a7/c0/6d3d54f50012255b41bc3e24944c086f63c4707c8686c7c6780e9283eb96/apache_tvm_ffi-0.1.9-cp312-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d503029e66c43b1a1cb1a42a1e9bb428c8a28dcbdec31c28e705472ca648a3a", size = 2203712, upload-time = "2026-02-27T19:27:25.867Z" }, { url = "https://files.pythonhosted.org/packages/c6/dd/2bab4c6cd86257dbf99e93452a1af833113f8dc3e25a25579f6e4e4c8a94/apache_tvm_ffi-0.1.9-cp312-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28241371934ea8af10d5067087ba1229ebddded7b2c02d33a258ec2a96df8c46", size = 2299704, upload-time = "2026-02-27T19:27:27.477Z" }, @@ -381,14 +340,6 @@ version = "0.31.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/fe/cc/d18065ce2380d80b1bcce927c24a2642efd38918e33fd724bc4bca904877/asyncpg-0.31.0.tar.gz", hash = "sha256:c989386c83940bfbd787180f2b1519415e2d3d6277a70d9d0f0145ac73500735", size = 993667, upload-time = "2025-11-24T23:27:00.812Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/17/cc02bc49bc350623d050fa139e34ea512cd6e020562f2a7312a7bcae4bc9/asyncpg-0.31.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eee690960e8ab85063ba93af2ce128c0f52fd655fdff9fdb1a28df01329f031d", size = 643159, upload-time = "2025-11-24T23:25:36.443Z" }, - { url = "https://files.pythonhosted.org/packages/a4/62/4ded7d400a7b651adf06f49ea8f73100cca07c6df012119594d1e3447aa6/asyncpg-0.31.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2657204552b75f8288de08ca60faf4a99a65deef3a71d1467454123205a88fab", size = 638157, upload-time = "2025-11-24T23:25:37.89Z" }, - { url = "https://files.pythonhosted.org/packages/d6/5b/4179538a9a72166a0bf60ad783b1ef16efb7960e4d7b9afe9f77a5551680/asyncpg-0.31.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a429e842a3a4b4ea240ea52d7fe3f82d5149853249306f7ff166cb9948faa46c", size = 2918051, upload-time = "2025-11-24T23:25:39.461Z" }, - { url = "https://files.pythonhosted.org/packages/e6/35/c27719ae0536c5b6e61e4701391ffe435ef59539e9360959240d6e47c8c8/asyncpg-0.31.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c0807be46c32c963ae40d329b3a686356e417f674c976c07fa49f1b30303f109", size = 2972640, upload-time = "2025-11-24T23:25:41.512Z" }, - { url = "https://files.pythonhosted.org/packages/43/f4/01ebb9207f29e645a64699b9ce0eefeff8e7a33494e1d29bb53736f7766b/asyncpg-0.31.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e5d5098f63beeae93512ee513d4c0c53dc12e9aa2b7a1af5a81cddf93fe4e4da", size = 2851050, upload-time = "2025-11-24T23:25:43.153Z" }, - { url = "https://files.pythonhosted.org/packages/3e/f4/03ff1426acc87be0f4e8d40fa2bff5c3952bef0080062af9efc2212e3be8/asyncpg-0.31.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37fc6c00a814e18eef51833545d1891cac9aa69140598bb076b4cd29b3e010b9", size = 2962574, upload-time = "2025-11-24T23:25:44.942Z" }, - { url = "https://files.pythonhosted.org/packages/c7/39/cc788dfca3d4060f9d93e67be396ceec458dfc429e26139059e58c2c244d/asyncpg-0.31.0-cp311-cp311-win32.whl", hash = "sha256:5a4af56edf82a701aece93190cc4e094d2df7d33f6e915c222fb09efbb5afc24", size = 521076, upload-time = "2025-11-24T23:25:46.486Z" }, - { url = "https://files.pythonhosted.org/packages/28/fc/735af5384c029eb7f1ca60ccb8fa95521dbdaeef788edf4cecfc604c3cab/asyncpg-0.31.0-cp311-cp311-win_amd64.whl", hash = "sha256:480c4befbdf079c14c9ca43c8c5e1fe8b6296c96f1f927158d4f1e750aacc047", size = 584980, upload-time = "2025-11-24T23:25:47.938Z" }, { url = "https://files.pythonhosted.org/packages/2a/a6/59d0a146e61d20e18db7396583242e32e0f120693b67a8de43f1557033e2/asyncpg-0.31.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b44c31e1efc1c15188ef183f287c728e2046abb1d26af4d20858215d50d91fad", size = 662042, upload-time = "2025-11-24T23:25:49.578Z" }, { url = "https://files.pythonhosted.org/packages/36/01/ffaa189dcb63a2471720615e60185c3f6327716fdc0fc04334436fbb7c65/asyncpg-0.31.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0c89ccf741c067614c9b5fc7f1fc6f3b61ab05ae4aaa966e6fd6b93097c7d20d", size = 638504, upload-time = "2025-11-24T23:25:51.501Z" }, { url = "https://files.pythonhosted.org/packages/9f/62/3f699ba45d8bd24c5d65392190d19656d74ff0185f42e19d0bbd973bb371/asyncpg-0.31.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:12b3b2e39dc5470abd5e98c8d3373e4b1d1234d9fbdedf538798b2c13c64460a", size = 3426241, upload-time = "2025-11-24T23:25:53.278Z" }, @@ -438,13 +389,6 @@ version = "15.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e9/c3/83e6e73d1592bc54436eae0bc61704ae0cff0c3cfbde7b58af9ed67ebb49/av-15.1.0.tar.gz", hash = "sha256:39cda2dc810e11c1938f8cb5759c41d6b630550236b3365790e67a313660ec85", size = 3774192, upload-time = "2025-08-30T04:41:56.076Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/47/58/4e44cf6939be7aba96a4abce024e1be11ba7539ecac74d09369b8c03aa05/av-15.1.0-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b785948762a8d45fc58fc24a20251496829ace1817e9a7a508a348d6de2182c3", size = 21767323, upload-time = "2025-08-30T04:39:37.989Z" }, - { url = "https://files.pythonhosted.org/packages/9b/f6/a946544cdb49f6d892d2761b1d61a8bc6ce912fe57ba06769bdc640c0a7f/av-15.1.0-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:9c7131494a3a318612b4ee4db98fe5bc50eb705f6b6536127c7ab776c524fd8b", size = 26946268, upload-time = "2025-08-30T04:39:40.601Z" }, - { url = "https://files.pythonhosted.org/packages/70/7c/b33513c0af73d0033af59a98f035b521c5b93445a6af7e9efbf41a6e8383/av-15.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2b9623ae848625c59213b610c8665817924f913580c7c5c91e0dc18936deb00d", size = 38062118, upload-time = "2025-08-30T04:39:43.928Z" }, - { url = "https://files.pythonhosted.org/packages/5e/95/31b7fb34f9fea7c7389240364194f4f56ad2d460095038cc720f50a90bb3/av-15.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:c8ef597087db560514617143532b1fafc4825ebb2dda9a22418f548b113a0cc7", size = 39571086, upload-time = "2025-08-30T04:39:47.109Z" }, - { url = "https://files.pythonhosted.org/packages/e7/b0/7b0b45474a4e90c35c11d0032947d8b3c7386872957ce29c6f12add69a74/av-15.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:08eac47a90ebae1e2bd5935f400dd515166019bab4ff5b03c4625fa6ac3a0a5e", size = 40112634, upload-time = "2025-08-30T04:39:50.981Z" }, - { url = "https://files.pythonhosted.org/packages/aa/04/038b94bc9a1ee10a451c867d4a2fc91e845f83bfc2dae9df25893abcb57f/av-15.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d3f66ff200ea166e606cb3c5cb1bd2fc714effbec2e262a5d67ce60450c8234a", size = 40878695, upload-time = "2025-08-30T04:39:54.493Z" }, - { url = "https://files.pythonhosted.org/packages/1d/3d/9f8f96c0deeaaf648485a3dbd1699b2f0580f2ce8a36cb616c0138ba7615/av-15.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:57b99544d91121b8bea570e4ddf61700f679a6b677c1f37966bc1a22e1d4cd5c", size = 31335683, upload-time = "2025-08-30T04:39:57.861Z" }, { url = "https://files.pythonhosted.org/packages/d1/58/de78b276d20db6ffcd4371283df771721a833ba525a3d57e753d00a9fe79/av-15.1.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:40c5df37f4c354ab8190c6fd68dab7881d112f527906f64ca73da4c252a58cee", size = 21760991, upload-time = "2025-08-30T04:40:00.801Z" }, { url = "https://files.pythonhosted.org/packages/56/cc/45f85775304ae60b66976360d82ba5b152ad3fd91f9267d5020a51e9a828/av-15.1.0-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:af455ce65ada3d361f80c90c810d9bced4db5655ab9aa513024d6c71c5c476d5", size = 26953097, upload-time = "2025-08-30T04:40:03.998Z" }, { url = "https://files.pythonhosted.org/packages/f3/f8/2d781e5e71d02fc829487e775ccb1185e72f95340d05f2e84eb57a11e093/av-15.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:86226d2474c80c3393fa07a9c366106029ae500716098b72b3ec3f67205524c3", size = 38319710, upload-time = "2025-08-30T04:40:07.701Z" }, @@ -539,38 +483,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8", size = 15148, upload-time = "2022-10-05T19:19:30.546Z" }, ] -[[package]] -name = "backports-tarfile" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/86/72/cd9b395f25e290e633655a100af28cb253e4393396264a98bd5f5951d50f/backports_tarfile-1.2.0.tar.gz", hash = "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991", size = 86406, upload-time = "2024-05-28T17:01:54.731Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl", hash = "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", size = 30181, upload-time = "2024-05-28T17:01:53.112Z" }, -] - [[package]] name = "backports-zstd" version = "1.3.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f4/b1/36a5182ce1d8ef9ef32bff69037bd28b389bbdb66338f8069e61da7028cb/backports_zstd-1.3.0.tar.gz", hash = "sha256:e8b2d68e2812f5c9970cabc5e21da8b409b5ed04e79b4585dbffa33e9b45ebe2", size = 997138, upload-time = "2025-12-29T17:28:06.143Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/28/ed31a0e35feb4538a996348362051b52912d50f00d25c2d388eccef9242c/backports_zstd-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:249f90b39d3741c48620021a968b35f268ca70e35f555abeea9ff95a451f35f9", size = 435660, upload-time = "2025-12-29T17:25:55.207Z" }, - { url = "https://files.pythonhosted.org/packages/00/0d/3db362169d80442adda9dd563c4f0bb10091c8c1c9a158037f4ecd53988e/backports_zstd-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b0e71e83e46154a9d3ced6d4de9a2fea8207ee1e4832aeecf364dc125eda305c", size = 362056, upload-time = "2025-12-29T17:25:56.729Z" }, - { url = "https://files.pythonhosted.org/packages/bd/00/b67ba053a7d6f6dbe2f8a704b7d3a5e01b1d2e2e8edbc9b634f2702ef73c/backports_zstd-1.3.0-cp311-cp311-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:cbc6193acd21f96760c94dd71bf32b161223e8503f5277acb0a5ab54e5598957", size = 505957, upload-time = "2025-12-29T17:25:57.941Z" }, - { url = "https://files.pythonhosted.org/packages/6f/3e/2667c0ddb53ddf28667e330bf9fe92e8e17705a481c9b698e283120565f7/backports_zstd-1.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1df583adc0ae84a8d13d7139f42eade6d90182b1dd3e0d28f7df3c564b9fd55d", size = 475569, upload-time = "2025-12-29T17:25:59.075Z" }, - { url = "https://files.pythonhosted.org/packages/eb/86/4052473217bd954ccdffda5f7264a0e99e7c4ecf70c0f729845c6a45fc5a/backports_zstd-1.3.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d833fc23aa3cc2e05aeffc7cfadd87b796654ad3a7fb214555cda3f1db2d4dc2", size = 581196, upload-time = "2025-12-29T17:26:00.508Z" }, - { url = "https://files.pythonhosted.org/packages/e5/bd/064f6fdb61db3d2c473159ebc844243e650dc032de0f8208443a00127925/backports_zstd-1.3.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:142178fe981061f1d2a57c5348f2cd31a3b6397a35593e7a17dbda817b793a7f", size = 640888, upload-time = "2025-12-29T17:26:02.134Z" }, - { url = "https://files.pythonhosted.org/packages/d8/09/0822403f40932a165a4f1df289d41653683019e4fd7a86b63ed20e9b6177/backports_zstd-1.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5eed0a09a163f3a8125a857cb031be87ed052e4a47bc75085ed7fca786e9bb5b", size = 491100, upload-time = "2025-12-29T17:26:03.418Z" }, - { url = "https://files.pythonhosted.org/packages/a6/a3/f5ac28d74039b7e182a780809dc66b9dbfc893186f5d5444340bba135389/backports_zstd-1.3.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:60aa483fef5843749e993dde01229e5eedebca8c283023d27d6bf6800d1d4ce3", size = 565071, upload-time = "2025-12-29T17:26:05.022Z" }, - { url = "https://files.pythonhosted.org/packages/e1/ac/50209aeb92257a642ee987afa1e61d5b6731ab6bf0bff70905856e5aede6/backports_zstd-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ea0886c1b619773544546e243ed73f6d6c2b1ae3c00c904ccc9903a352d731e1", size = 481519, upload-time = "2025-12-29T17:26:06.255Z" }, - { url = "https://files.pythonhosted.org/packages/08/1f/b06f64199fb4b2e9437cedbf96d0155ca08aeec35fe81d41065acd44762e/backports_zstd-1.3.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5e137657c830a5ce99be40a1d713eb1d246bae488ada28ff0666ac4387aebdd5", size = 509465, upload-time = "2025-12-29T17:26:07.602Z" }, - { url = "https://files.pythonhosted.org/packages/f4/37/2c365196e61c8fffbbc930ffd69f1ada7aa1c7210857b3e565031c787ac6/backports_zstd-1.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:94048c8089755e482e4b34608029cf1142523a625873c272be2b1c9253871a72", size = 585552, upload-time = "2025-12-29T17:26:08.911Z" }, - { url = "https://files.pythonhosted.org/packages/93/8d/c2c4f448bb6b6c9df17410eaedce415e8db0eb25b60d09a3d22a98294d09/backports_zstd-1.3.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:d339c1ec40485e97e600eb9a285fb13169dbf44c5094b945788a62f38b96e533", size = 562893, upload-time = "2025-12-29T17:26:10.566Z" }, - { url = "https://files.pythonhosted.org/packages/74/e8/2110d4d39115130f7514cbbcec673a885f4052bb68d15e41bc96a7558856/backports_zstd-1.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:8aeee9210c54cf8bf83f4d263a6d0d6e7a0298aeb5a14a0a95e90487c5c3157c", size = 631462, upload-time = "2025-12-29T17:26:11.99Z" }, - { url = "https://files.pythonhosted.org/packages/b9/a8/d64b59ae0714fdace14e43873f794eff93613e35e3e85eead33a4f44cd80/backports_zstd-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ba7114a3099e5ea05cbb46568bd0e08bca2ca11e12c6a7b563a24b86b2b4a67f", size = 495125, upload-time = "2025-12-29T17:26:13.218Z" }, - { url = "https://files.pythonhosted.org/packages/ef/d8/bcff0a091fcf27172c57ae463e49d8dec6dc31e01d7e7bf1ae3aad9c3566/backports_zstd-1.3.0-cp311-cp311-win32.whl", hash = "sha256:08dfdfb85da5915383bfae680b6ac10ab5769ab22e690f9a854320720011ae8e", size = 288664, upload-time = "2025-12-29T17:26:14.791Z" }, - { url = "https://files.pythonhosted.org/packages/28/1a/379061e2abf8c3150ad51c1baab9ac723e01cf7538860a6a74c48f8b73ee/backports_zstd-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8aac2e7cdcc8f310c16f98a0062b48d0a081dbb82862794f4f4f5bdafde30a4", size = 313633, upload-time = "2025-12-29T17:26:16.31Z" }, - { url = "https://files.pythonhosted.org/packages/35/e7/eca40858883029fc716660106069b23253e2ec5fd34e86b4101c8cfe864b/backports_zstd-1.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:440ef1be06e82dc0d69dbb57177f2ce98bbd2151013ee7e551e2f2b54caa6120", size = 288814, upload-time = "2025-12-29T17:26:17.571Z" }, { url = "https://files.pythonhosted.org/packages/72/d4/356da49d3053f4bc50e71a8535631b57bc9ca4e8c6d2442e073e0ab41c44/backports_zstd-1.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f4a292e357f3046d18766ce06d990ccbab97411708d3acb934e63529c2ea7786", size = 435972, upload-time = "2025-12-29T17:26:18.752Z" }, { url = "https://files.pythonhosted.org/packages/30/8f/dbe389e60c7e47af488520f31a4aa14028d66da5bf3c60d3044b571eb906/backports_zstd-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fb4c386f38323698991b38edcc9c091d46d4713f5df02a3b5c80a28b40e289ea", size = 362124, upload-time = "2025-12-29T17:26:19.995Z" }, { url = "https://files.pythonhosted.org/packages/55/4b/173beafc99e99e7276ce008ef060b704471e75124c826bc5e2092815da37/backports_zstd-1.3.0-cp312-cp312-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f52523d2bdada29e653261abdc9cfcecd9e5500d305708b7e37caddb24909d4e", size = 506378, upload-time = "2025-12-29T17:26:21.855Z" }, @@ -622,12 +540,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/04/cfab76878f360f124dbb533779e1e4603c801a0f5ada72ae5c742b7c4d7d/backports_zstd-1.3.0-cp313-cp313t-win32.whl", hash = "sha256:7d3f0f2499d2049ec53d2674c605a4b3052c217cc7ee49c05258046411685adc", size = 289389, upload-time = "2025-12-29T17:27:22.287Z" }, { url = "https://files.pythonhosted.org/packages/cb/ff/dbcfb6c9c922ab6d98f3d321e7d0c7b34ecfa26f3ca71d930fe1ef639737/backports_zstd-1.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:eb2f8fab0b1ea05148394cb34a9e543a43477178765f2d6e7c84ed332e34935e", size = 314776, upload-time = "2025-12-29T17:27:23.458Z" }, { url = "https://files.pythonhosted.org/packages/01/4b/82e4baae3117806639fe1c693b1f2f7e6133a7cefd1fa2e38018c8edcd68/backports_zstd-1.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:c66ad9eb5bfbe28c2387b7fc58ddcdecfb336d6e4e60bcba1694a906c1f21a6c", size = 289315, upload-time = "2025-12-29T17:27:24.601Z" }, - { url = "https://files.pythonhosted.org/packages/9a/d9/8c9c246e5ea79a4f45d551088b11b61f2dc7efcdc5dbe6df3be84a506e0c/backports_zstd-1.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:968167d29f012cee7b112ad031a8925e484e97e99288e55e4d62962c3a1013e3", size = 409666, upload-time = "2025-12-29T17:27:57.37Z" }, - { url = "https://files.pythonhosted.org/packages/a4/4f/a55b33c314ca8c9074e99daab54d04c5d212070ae7dbc435329baf1b139e/backports_zstd-1.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d8f6fc7d62b71083b574193dd8fb3a60e6bb34880cc0132aad242943af301f7a", size = 339199, upload-time = "2025-12-29T17:27:58.542Z" }, - { url = "https://files.pythonhosted.org/packages/9d/13/ce31bd048b1c88d0f65d7af60b6cf89cfbed826c7c978f0ebca9a8a71cfc/backports_zstd-1.3.0-pp311-pypy311_pp73-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:e0f2eca6aac280fdb77991ad3362487ee91a7fb064ad40043fb5a0bf5a376943", size = 420332, upload-time = "2025-12-29T17:28:00.332Z" }, - { url = "https://files.pythonhosted.org/packages/cf/80/c0cdbc533d0037b57248588403a3afb050b2a83b8c38aa608e31b3a4d600/backports_zstd-1.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:676eb5e177d4ef528cf3baaeea4fffe05f664e4dd985d3ac06960ef4619c81a9", size = 393879, upload-time = "2025-12-29T17:28:01.57Z" }, - { url = "https://files.pythonhosted.org/packages/0f/38/c97428867cac058ed196ccaeddfdf82ecd43b8a65965f2950a6e7547e77a/backports_zstd-1.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:199eb9bd8aca6a9d489c41a682fad22c587dffe57b613d0fe6d492d0d38ce7c5", size = 413842, upload-time = "2025-12-29T17:28:03.113Z" }, - { url = "https://files.pythonhosted.org/packages/8d/ec/6247be6536668fe1c7dfae3eaa9c94b00b956b716957c0fc986ba78c3cc4/backports_zstd-1.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:2524bd6777a828d5e7ccd7bd1a57f9e7007ae654fc2bd1bc1a207f6428674e4a", size = 299684, upload-time = "2025-12-29T17:28:04.856Z" }, ] [[package]] @@ -649,79 +561,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/46/81/d8c22cd7e5e1c6a7d48e41a1d1d46c92f17dae70a54d9814f746e6027dec/bcrypt-4.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:8a68f4341daf7522fe8d73874de8906f3a339048ba406be6ddc1b3ccb16fc0d9", size = 152930, upload-time = "2022-10-09T15:36:34.635Z" }, ] -[[package]] -name = "bitarray" -version = "3.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/06/92fdc84448d324ab8434b78e65caf4fb4c6c90b4f8ad9bdd4c8021bfaf1e/bitarray-3.8.0.tar.gz", hash = "sha256:3eae38daffd77c9621ae80c16932eea3fb3a4af141fb7cc724d4ad93eff9210d", size = 151991, upload-time = "2025-11-02T21:41:15.117Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/7d/63558f1d0eb09217a3d30c1c847890879973e224a728fcff9391fab999b8/bitarray-3.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:25b9cff6c9856bc396232e2f609ea0c5ec1a8a24c500cee4cca96ba8a3cd50b6", size = 148502, upload-time = "2025-11-02T21:39:09.993Z" }, - { url = "https://files.pythonhosted.org/packages/5e/7b/f957ad211cb0172965b5f0881b67b99e2b6d41512af0a1001f44a44ddf4a/bitarray-3.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d9984017314da772f5f7460add7a0301a4ffc06c72c2998bb16c300a6253607", size = 145484, upload-time = "2025-11-02T21:39:10.904Z" }, - { url = "https://files.pythonhosted.org/packages/9f/dc/897973734f14f91467a3a795a4624752238053ecffaec7c8bbda1e363fda/bitarray-3.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bbbbfbb7d039b20d289ce56b1beb46138d65769d04af50c199c6ac4cb6054d52", size = 330909, upload-time = "2025-11-02T21:39:12.276Z" }, - { url = "https://files.pythonhosted.org/packages/67/be/24b4b792426d92de289e73e09682915d567c2e69d47e8857586cbdc865d0/bitarray-3.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1f723e260c35e1c7c57a09d3a6ebe681bd56c83e1208ae3ce1869b7c0d10d4f", size = 358469, upload-time = "2025-11-02T21:39:13.766Z" }, - { url = "https://files.pythonhosted.org/packages/3e/0e/2eda69a7a59a6998df8fb57cc9d1e0e62888c599fb5237b0a8b479a01afb/bitarray-3.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cbd1660fb48827381ce3a621a4fdc237959e1cd4e98b098952a8f624a0726425", size = 369131, upload-time = "2025-11-02T21:39:15.041Z" }, - { url = "https://files.pythonhosted.org/packages/f7/7b/8a372d6635a6b2622477b2f96a569b2cd0318a62bc95a4a2144c7942c987/bitarray-3.8.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df6d7bf3e15b7e6e202a16ff4948a51759354016026deb04ab9b5acbbe35e096", size = 337089, upload-time = "2025-11-02T21:39:16.124Z" }, - { url = "https://files.pythonhosted.org/packages/93/f0/8eca934dbe5dee47a0e5ef44eeb72e85acacc8097c27cd164337bc4ec5d3/bitarray-3.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d5c931ec1c03111718cabf85f6012bb2815fa0ce578175567fa8d6f2cc15d3b4", size = 328504, upload-time = "2025-11-02T21:39:17.321Z" }, - { url = "https://files.pythonhosted.org/packages/88/dd/928b8e23a9950f8a8bfc42bc1e7de41f4e27f57de01a716308be5f683c2b/bitarray-3.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:41b53711f89008ba2de62e4c2d2260a8b357072fd4f18e1351b28955db2719dc", size = 356461, upload-time = "2025-11-02T21:39:18.396Z" }, - { url = "https://files.pythonhosted.org/packages/a9/93/4fb58417aff47fa2fe1874a39c9346b589a1d78c93a9cb24cccede5dc737/bitarray-3.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4f298daaaea58d45e245a132d6d2bdfb6f856da50dc03d75ebb761439fb626cf", size = 353008, upload-time = "2025-11-02T21:39:19.828Z" }, - { url = "https://files.pythonhosted.org/packages/da/54/aa04e4a7b45aa5913f08ee377d43319b0979925e3c0407882eb29df3be66/bitarray-3.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:30989a2451b693c3f9359d91098a744992b5431a0be4858f1fdf0ec76b457125", size = 334048, upload-time = "2025-11-02T21:39:20.924Z" }, - { url = "https://files.pythonhosted.org/packages/da/52/e851f41076df014c05d6ac1ce34fbf7db5fa31241da3e2f09bb2be9e283d/bitarray-3.8.0-cp311-cp311-win32.whl", hash = "sha256:e5aed4754895942ae15ffa48c52d181e1c1463236fda68d2dba29c03aa61786b", size = 142907, upload-time = "2025-11-02T21:39:22.312Z" }, - { url = "https://files.pythonhosted.org/packages/28/01/db0006148b1dd13b4ac2686df8fa57d12f5887df313a506e939af0cb0997/bitarray-3.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:22c540ed20167d3dbb1e2d868ca935180247d620c40eace90efa774504a40e3b", size = 149670, upload-time = "2025-11-02T21:39:23.341Z" }, - { url = "https://files.pythonhosted.org/packages/7b/ea/b7d55ee269b1426f758a535c9ec2a07c056f20f403fa981685c3c8b4798c/bitarray-3.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:84b52b2cf77bb7f703d16c4007b021078dbbe6cf8ffb57abe81a7bacfc175ef2", size = 146709, upload-time = "2025-11-02T21:39:24.343Z" }, - { url = "https://files.pythonhosted.org/packages/82/a0/0c41d893eda756315491adfdbf9bc928aee3d377a7f97a8834d453aa5de1/bitarray-3.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2fcbe9b3a5996b417e030aa33a562e7e20dfc86271e53d7e841fc5df16268b8", size = 148575, upload-time = "2025-11-02T21:39:25.718Z" }, - { url = "https://files.pythonhosted.org/packages/0e/30/12ab2f4a4429bd844b419c37877caba93d676d18be71354fbbeb21d9f4cc/bitarray-3.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cd761d158f67e288fd0ebe00c3b158095ce80a4bc7c32b60c7121224003ba70d", size = 145454, upload-time = "2025-11-02T21:39:26.695Z" }, - { url = "https://files.pythonhosted.org/packages/26/58/314b3e3f219533464e120f0c51ac5123e7b1c1b91f725a4073fb70c5a858/bitarray-3.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c394a3f055b49f92626f83c1a0b6d6cd2c628f1ccd72481c3e3c6aa4695f3b20", size = 332949, upload-time = "2025-11-02T21:39:27.801Z" }, - { url = "https://files.pythonhosted.org/packages/ea/ce/ca8c706bd8341c7a22dd92d2a528af71f7e5f4726085d93f81fd768cb03b/bitarray-3.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:969fd67de8c42affdb47b38b80f1eaa79ac0ef17d65407cdd931db1675315af1", size = 360599, upload-time = "2025-11-02T21:39:28.964Z" }, - { url = "https://files.pythonhosted.org/packages/ef/dc/aa181df85f933052d962804906b282acb433cb9318b08ec2aceb4ee34faf/bitarray-3.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:99d25aff3745c54e61ab340b98400c52ebec04290a62078155e0d7eb30380220", size = 371972, upload-time = "2025-11-02T21:39:30.228Z" }, - { url = "https://files.pythonhosted.org/packages/ff/d9/b805bfa158c7bcf4df0ac19b1be581b47e1ddb792c11023aed80a7058e78/bitarray-3.8.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e645b4c365d6f1f9e0799380ad6395268f3c3b898244a650aaeb8d9d27b74c35", size = 340303, upload-time = "2025-11-02T21:39:31.342Z" }, - { url = "https://files.pythonhosted.org/packages/1f/42/5308cc97ea929e30727292617a3a88293470166851e13c9e3f16f395da55/bitarray-3.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2fa23fdb3beab313950bbb49674e8a161e61449332d3997089fe3944953f1b77", size = 330494, upload-time = "2025-11-02T21:39:32.769Z" }, - { url = "https://files.pythonhosted.org/packages/4c/89/64f1596cb80433323efdbc8dcd0d6e57c40dfbe6ea3341623f34ec397edd/bitarray-3.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:165052a0e61c880f7093808a0c524ce1b3555bfa114c0dfb5c809cd07918a60d", size = 358123, upload-time = "2025-11-02T21:39:34.331Z" }, - { url = "https://files.pythonhosted.org/packages/27/fd/f3d49c5443b57087f888b5e118c8dd78bb7c8e8cfeeed250f8e92128a05f/bitarray-3.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:337c8cd46a4c6568d367ed676cbf2d7de16f890bb31dbb54c44c1d6bb6d4a1de", size = 356046, upload-time = "2025-11-02T21:39:35.449Z" }, - { url = "https://files.pythonhosted.org/packages/aa/db/1fd0b402bd2b47142e958b6930dbb9445235d03fa703c9a24caa6e576ae2/bitarray-3.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21ca6a47bf20db9e7ad74ca04b3d479e4d76109b68333eb23535553d2705339e", size = 336872, upload-time = "2025-11-02T21:39:36.891Z" }, - { url = "https://files.pythonhosted.org/packages/58/73/680b47718f1313b4538af479c4732eaca0aeda34d93fc5b869f87932d57d/bitarray-3.8.0-cp312-cp312-win32.whl", hash = "sha256:178c5a4c7fdfb5cd79e372ae7f675390e670f3732e5bc68d327e01a5b3ff8d55", size = 143025, upload-time = "2025-11-02T21:39:38.303Z" }, - { url = "https://files.pythonhosted.org/packages/f8/11/7792587c19c79a8283e8838f44709fa4338a8f7d2a3091dfd81c07ae89c7/bitarray-3.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:75a3b6e9c695a6570ea488db75b84bb592ff70a944957efa1c655867c575018b", size = 149969, upload-time = "2025-11-02T21:39:39.715Z" }, - { url = "https://files.pythonhosted.org/packages/9a/00/9df64b5d8a84e8e9ec392f6f9ce93f50626a5b301cb6c6b3fe3406454d66/bitarray-3.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:5591daf81313096909d973fb2612fccd87528fdfdd39f6478bdce54543178954", size = 146907, upload-time = "2025-11-02T21:39:40.815Z" }, - { url = "https://files.pythonhosted.org/packages/3e/35/480364d4baf1e34c79076750914664373f561c58abb5c31c35b3fae613ff/bitarray-3.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18214bac86341f1cc413772e66447d6cca10981e2880b70ecaf4e826c04f95e9", size = 148582, upload-time = "2025-11-02T21:39:42.268Z" }, - { url = "https://files.pythonhosted.org/packages/5e/a8/718b95524c803937f4edbaaf6480f39c80f6ed189d61357b345e8361ffb6/bitarray-3.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:01c5f0dc080b0ebb432f7a68ee1e88a76bd34f6d89c9568fcec65fb16ed71f0e", size = 145433, upload-time = "2025-11-02T21:39:43.552Z" }, - { url = "https://files.pythonhosted.org/packages/03/66/4a10f30dc9e2e01e3b4ecd44a511219f98e63c86b0e0f704c90fac24059b/bitarray-3.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:86685fa04067f7175f9718489ae755f6acde03593a1a9ca89305554af40e14fd", size = 332986, upload-time = "2025-11-02T21:39:44.656Z" }, - { url = "https://files.pythonhosted.org/packages/53/25/4c08774d847f80a1166e4c704b4e0f1c417c0afe6306eae0bc5e70d35faa/bitarray-3.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56896ceeffe25946c4010320629e2d858ca763cd8ded273c81672a5edbcb1e0a", size = 360634, upload-time = "2025-11-02T21:39:45.798Z" }, - { url = "https://files.pythonhosted.org/packages/a5/8f/bf8ad26169ebd0b2746d5c7564db734453ca467f8aab87e9d43b0a794383/bitarray-3.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9858dcbc23ba7eaadcd319786b982278a1a2b2020720b19db43e309579ff76fb", size = 371992, upload-time = "2025-11-02T21:39:46.968Z" }, - { url = "https://files.pythonhosted.org/packages/a9/16/ce166754e7c9d10650e02914552fa637cf3b2591f7ed16632bbf6b783312/bitarray-3.8.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa7dec53c25f1949513457ef8b0ea1fb40e76c672cc4d2daa8ad3c8d6b73491a", size = 340315, upload-time = "2025-11-02T21:39:48.182Z" }, - { url = "https://files.pythonhosted.org/packages/de/2a/fbba3a106ddd260e84b9a624f730257c32ba51a8a029565248dfedfdf6f2/bitarray-3.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15a2eff91f54d2b1f573cca8ca6fb58763ce8fea80e7899ab028f3987ef71cd5", size = 330473, upload-time = "2025-11-02T21:39:49.705Z" }, - { url = "https://files.pythonhosted.org/packages/68/97/56cf3c70196e7307ad32318a9d6ed969dbdc6a4534bbe429112fa7dfe42e/bitarray-3.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b1572ee0eb1967e71787af636bb7d1eb9c6735d5337762c450650e7f51844594", size = 358129, upload-time = "2025-11-02T21:39:51.189Z" }, - { url = "https://files.pythonhosted.org/packages/fd/be/afd391a5c0896d3339613321b2f94af853f29afc8bd3fbc327431244c642/bitarray-3.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5bfac7f236ba1a4d402644bdce47fb9db02a7cf3214a1f637d3a88390f9e5428", size = 356005, upload-time = "2025-11-02T21:39:52.355Z" }, - { url = "https://files.pythonhosted.org/packages/ae/08/a8e1a371babba29bad3378bb3a2cdca2b012170711e7fe1f22031a6b7b95/bitarray-3.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f0a55cf02d2cdd739b40ce10c09bbdd520e141217696add7a48b56e67bdfdfe6", size = 336862, upload-time = "2025-11-02T21:39:54.345Z" }, - { url = "https://files.pythonhosted.org/packages/ee/8a/6dc1d0fdc06991c8dc3b1fcfe1ae49fbaced42064cd1b5f24278e73fe05f/bitarray-3.8.0-cp313-cp313-win32.whl", hash = "sha256:a2ba92f59e30ce915e9e79af37649432e3a212ddddf416d4d686b1b4825bcdb2", size = 143018, upload-time = "2025-11-02T21:39:56.361Z" }, - { url = "https://files.pythonhosted.org/packages/2e/72/76e13f5cd23b8b9071747909663ce3b02da24a5e7e22c35146338625db35/bitarray-3.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:1c8f2a5d8006db5a555e06f9437e76bf52537d3dfd130cb8ae2b30866aca32c9", size = 149977, upload-time = "2025-11-02T21:39:57.718Z" }, - { url = "https://files.pythonhosted.org/packages/01/37/60f336c32336cc3ec03b0c61076f16ea2f05d5371c8a56e802161d218b77/bitarray-3.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:50ddbe3a7b4b6ab96812f5a4d570f401a2cdb95642fd04c062f98939610bbeee", size = 146930, upload-time = "2025-11-02T21:39:59.308Z" }, - { url = "https://files.pythonhosted.org/packages/1b/b0/411327a6c7f6b2bead64bb06fe60b92e0344957ec1ab0645d5ccc25fdafe/bitarray-3.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8cbd4bfc933b33b85c43ef4c1f4d5e3e9d91975ea6368acf5fbac02bac06ea89", size = 148563, upload-time = "2025-11-02T21:40:01.006Z" }, - { url = "https://files.pythonhosted.org/packages/2a/bc/ff80d97c627d774f879da0ea93223adb1267feab7e07d5c17580ffe6d632/bitarray-3.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9d35d8f8a1c9ed4e2b08187b513f8a3c71958600129db3aa26d85ea3abfd1310", size = 145422, upload-time = "2025-11-02T21:40:02.535Z" }, - { url = "https://files.pythonhosted.org/packages/66/e7/b4cb6c5689aacd0a32f3aa8a507155eaa33528c63de2f182b60843fbf700/bitarray-3.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99f55e14e7c56f4fafe1343480c32b110ef03836c21ff7c48bae7add6818f77c", size = 332852, upload-time = "2025-11-02T21:40:03.645Z" }, - { url = "https://files.pythonhosted.org/packages/e7/91/fbd1b047e3e2f4b65590f289c8151df1d203d75b005f5aae4e072fe77d76/bitarray-3.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dfbe2aa45b273f49e715c5345d94874cb65a28482bf231af408891c260601b8d", size = 360801, upload-time = "2025-11-02T21:40:04.827Z" }, - { url = "https://files.pythonhosted.org/packages/ef/4a/63064c593627bac8754fdafcb5343999c93ab2aeb27bcd9d270a010abea5/bitarray-3.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:64af877116edf051375b45f0bda648143176a017b13803ec7b3a3111dc05f4c5", size = 371408, upload-time = "2025-11-02T21:40:05.985Z" }, - { url = "https://files.pythonhosted.org/packages/46/97/ddc07723767bdafd170f2ff6e173c940fa874192783ee464aa3c1dedf07d/bitarray-3.8.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cdfbb27f2c46bb5bbdcee147530cbc5ca8ab858d7693924e88e30ada21b2c5e2", size = 340033, upload-time = "2025-11-02T21:40:07.189Z" }, - { url = "https://files.pythonhosted.org/packages/ad/1e/e1ea9f1146fd4af032817069ff118918d73e5de519854ce3860e2ed560ff/bitarray-3.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4d73d4948dcc5591d880db8933004e01f1dd2296df9de815354d53469beb26fe", size = 330774, upload-time = "2025-11-02T21:40:08.496Z" }, - { url = "https://files.pythonhosted.org/packages/cf/9f/8242296c124a48d1eab471fd0838aeb7ea9c6fd720302d99ab7855d3e6d3/bitarray-3.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:28a85b056c0eb7f5d864c0ceef07034117e8ebfca756f50648c71950a568ba11", size = 358337, upload-time = "2025-11-02T21:40:10.035Z" }, - { url = "https://files.pythonhosted.org/packages/b5/6b/9095d75264c67d479f298c80802422464ce18c3cdd893252eeccf4997611/bitarray-3.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:79ec4498a545733ecace48d780d22407411b07403a2e08b9a4d7596c0b97ebd7", size = 355639, upload-time = "2025-11-02T21:40:11.485Z" }, - { url = "https://files.pythonhosted.org/packages/a0/af/c93c0ae5ef824136e90ac7ddf6cceccb1232f34240b2f55a922f874da9b4/bitarray-3.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:33af25c4ff7723363cb8404dfc2eefeab4110b654f6c98d26aba8a08c745d860", size = 336999, upload-time = "2025-11-02T21:40:12.709Z" }, - { url = "https://files.pythonhosted.org/packages/81/0f/72c951f5997b2876355d5e671f78dd2362493254876675cf22dbd24389ae/bitarray-3.8.0-cp314-cp314-win32.whl", hash = "sha256:2c3bb96b6026643ce24677650889b09073f60b9860a71765f843c99f9ab38b25", size = 142169, upload-time = "2025-11-02T21:40:14.031Z" }, - { url = "https://files.pythonhosted.org/packages/8a/55/ef1b4de8107bf13823da8756c20e1fbc9452228b4e837f46f6d9ddba3eb3/bitarray-3.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:847c7f61964225fc489fe1d49eda7e0e0d253e98862c012cecf845f9ad45cdf4", size = 148737, upload-time = "2025-11-02T21:40:15.436Z" }, - { url = "https://files.pythonhosted.org/packages/5f/26/bc0784136775024ac56cc67c0d6f9aa77a7770de7f82c3a7c9be11c217cd/bitarray-3.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:a2cb35a6efaa0e3623d8272471371a12c7e07b51a33e5efce9b58f655d864b4e", size = 146083, upload-time = "2025-11-02T21:40:17.135Z" }, - { url = "https://files.pythonhosted.org/packages/6e/64/57984e64264bf43d93a1809e645972771566a2d0345f4896b041ce20b000/bitarray-3.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:15e8d0597cc6e8496de6f4dea2a6880c57e1251502a7072f5631108a1aa28521", size = 149455, upload-time = "2025-11-02T21:40:18.558Z" }, - { url = "https://files.pythonhosted.org/packages/81/c0/0d5f2eaef1867f462f764bdb07d1e116c33a1bf052ea21889aefe4282f5b/bitarray-3.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8ffe660e963ae711cb9e2b8d8461c9b1ad6167823837fc17d59d5e539fb898fa", size = 146491, upload-time = "2025-11-02T21:40:19.665Z" }, - { url = "https://files.pythonhosted.org/packages/65/c6/bc1261f7a8862c0c59220a484464739e52235fd1e2afcb24d7f7d3fb5702/bitarray-3.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4779f356083c62e29b4198d290b7b17a39a69702d150678b7efff0fdddf494a8", size = 339721, upload-time = "2025-11-02T21:40:21.277Z" }, - { url = "https://files.pythonhosted.org/packages/81/d8/289ca55dd2939ea17b1108dc53bffc0fdc5160ba44f77502dfaae35d08c6/bitarray-3.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:025d133bf4ca8cf75f904eeb8ea946228d7c043231866143f31946a6f4dd0bf3", size = 367823, upload-time = "2025-11-02T21:40:22.463Z" }, - { url = "https://files.pythonhosted.org/packages/91/a2/61e7461ca9ac0fcb70f327a2e84b006996d2a840898e69037a39c87c6d06/bitarray-3.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:451f9958850ea98440d542278368c8d1e1ea821e2494b204570ba34a340759df", size = 377341, upload-time = "2025-11-02T21:40:23.789Z" }, - { url = "https://files.pythonhosted.org/packages/6c/87/4a0c9c8bdb13916d443e04d8f8542eef9190f31425da3c17c3478c40173f/bitarray-3.8.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6d79f659965290af60d6acc8e2716341865fe74609a7ede2a33c2f86ad893b8f", size = 344985, upload-time = "2025-11-02T21:40:25.261Z" }, - { url = "https://files.pythonhosted.org/packages/17/4c/ff9259b916efe53695b631772e5213699c738efc2471b5ffe273f4000994/bitarray-3.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fbf05678c2ae0064fb1b8de7e9e8f0fc30621b73c8477786dd0fb3868044a8c8", size = 336796, upload-time = "2025-11-02T21:40:26.942Z" }, - { url = "https://files.pythonhosted.org/packages/0f/4b/51b2468bbddbade5e2f3b8d5db08282c5b309e8687b0f02f75a8b5ff559c/bitarray-3.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:c396358023b876cff547ce87f4e8ff8a2280598873a137e8cc69e115262260b8", size = 365085, upload-time = "2025-11-02T21:40:28.224Z" }, - { url = "https://files.pythonhosted.org/packages/bf/79/53473bfc2e052c6dbb628cdc1b156be621c77aaeb715918358b01574be55/bitarray-3.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:ed3493a369fe849cce98542d7405c88030b355e4d2e113887cb7ecc86c205773", size = 361012, upload-time = "2025-11-02T21:40:29.635Z" }, - { url = "https://files.pythonhosted.org/packages/c4/b1/242bf2e44bfc69e73fa2b954b425d761a8e632f78ea31008f1c3cfad0854/bitarray-3.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c764fb167411d5afaef88138542a4bfa28bd5e5ded5e8e42df87cef965efd6e9", size = 340644, upload-time = "2025-11-02T21:40:31.089Z" }, - { url = "https://files.pythonhosted.org/packages/cf/01/12e5ecf30a5de28a32485f226cad4b8a546845f65f755ce0365057ab1e92/bitarray-3.8.0-cp314-cp314t-win32.whl", hash = "sha256:e12769d3adcc419e65860de946df8d2ed274932177ac1cdb05186e498aaa9149", size = 143630, upload-time = "2025-11-02T21:40:32.351Z" }, - { url = "https://files.pythonhosted.org/packages/b6/92/6b6ade587b08024a8a890b07724775d29da9cf7497be5c3cbe226185e463/bitarray-3.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0ca70ccf789446a6dfde40b482ec21d28067172cd1f8efd50d5548159fccad9e", size = 150250, upload-time = "2025-11-02T21:40:33.596Z" }, - { url = "https://files.pythonhosted.org/packages/ed/40/be3858ffed004e47e48a2cefecdbf9b950d41098b780f9dc3aa609a88351/bitarray-3.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2a3d1b05ffdd3e95687942ae7b13c63689f85d3f15c39b33329e3cb9ce6c015f", size = 147015, upload-time = "2025-11-02T21:40:35.064Z" }, -] - [[package]] name = "bitsandbytes" version = "0.49.2" @@ -738,19 +577,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b6/d4/501655842ad6771fb077f576d78cbedb5445d15b1c3c91343ed58ca46f0e/bitsandbytes-0.49.2-py3-none-win_amd64.whl", hash = "sha256:2e0ddd09cd778155388023cbe81f00afbb7c000c214caef3ce83386e7144df7d", size = 55372289, upload-time = "2026-02-16T21:26:16.267Z" }, ] -[[package]] -name = "bitstring" -version = "4.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "bitarray" }, - { name = "tibs" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/36/d3/de6fe4e7065df8c2f1ac1766f5fdccbe75bc18af2cf2dbeecd34d68e1518/bitstring-4.4.0.tar.gz", hash = "sha256:e682ac522bb63e041d16cbc9d0ca86a4f00194db16d0847c7efe066f836b2e37", size = 255209, upload-time = "2026-03-10T20:29:14.824Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/02/1a870bab76f2896d827aa4963be95e56675ffa1453e53525d13c43036edf/bitstring-4.4.0-py3-none-any.whl", hash = "sha256:feac49524fcf3ef27e6081e86f02b10d2adf6c3773bf22fbe0e7eea9534bc737", size = 76846, upload-time = "2026-03-10T20:29:12.832Z" }, -] - [[package]] name = "black" version = "26.3.1" @@ -765,11 +591,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/e1/c5/61175d618685d42b005847464b8fb4743a67b1b8fdb75e50e5a96c31a27a/black-26.3.1.tar.gz", hash = "sha256:2c50f5063a9641c7eed7795014ba37b0f5fa227f3d408b968936e24bc0566b07", size = 666155, upload-time = "2026-03-12T03:36:03.593Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/57/5f11c92861f9c92eb9dddf515530bc2d06db843e44bdcf1c83c1427824bc/black-26.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:28ef38aee69e4b12fda8dba75e21f9b4f979b490c8ac0baa7cb505369ac9e1ff", size = 1851987, upload-time = "2026-03-12T03:40:06.248Z" }, - { url = "https://files.pythonhosted.org/packages/54/aa/340a1463660bf6831f9e39646bf774086dbd8ca7fc3cded9d59bbdf4ad0a/black-26.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf9bf162ed91a26f1adba8efda0b573bc6924ec1408a52cc6f82cb73ec2b142c", size = 1689499, upload-time = "2026-03-12T03:40:07.642Z" }, - { url = "https://files.pythonhosted.org/packages/f3/01/b726c93d717d72733da031d2de10b92c9fa4c8d0c67e8a8a372076579279/black-26.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:474c27574d6d7037c1bc875a81d9be0a9a4f9ee95e62800dab3cfaadbf75acd5", size = 1754369, upload-time = "2026-03-12T03:40:09.279Z" }, - { url = "https://files.pythonhosted.org/packages/e3/09/61e91881ca291f150cfc9eb7ba19473c2e59df28859a11a88248b5cbbc4d/black-26.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:5e9d0d86df21f2e1677cc4bd090cd0e446278bcbbe49bf3659c308c3e402843e", size = 1413613, upload-time = "2026-03-12T03:40:10.943Z" }, - { url = "https://files.pythonhosted.org/packages/16/73/544f23891b22e7efe4d8f812371ab85b57f6a01b2fc45e3ba2e52ba985b8/black-26.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:9a5e9f45e5d5e1c5b5c29b3bd4265dcc90e8b92cf4534520896ed77f791f4da5", size = 1219719, upload-time = "2026-03-12T03:40:12.597Z" }, { url = "https://files.pythonhosted.org/packages/dc/f8/da5eae4fc75e78e6dceb60624e1b9662ab00d6b452996046dfa9b8a6025b/black-26.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e6f89631eb88a7302d416594a32faeee9fb8fb848290da9d0a5f2903519fc1", size = 1895920, upload-time = "2026-03-12T03:40:13.921Z" }, { url = "https://files.pythonhosted.org/packages/2c/9f/04e6f26534da2e1629b2b48255c264cabf5eedc5141d04516d9d68a24111/black-26.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cd2012d35b47d589cb8a16faf8a32ef7a336f56356babd9fcf70939ad1897f", size = 1718499, upload-time = "2026-03-12T03:40:15.239Z" }, { url = "https://files.pythonhosted.org/packages/04/91/a5935b2a63e31b331060c4a9fdb5a6c725840858c599032a6f3aac94055f/black-26.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f76ff19ec5297dd8e66eb64deda23631e642c9393ab592826fd4bdc97a4bce7", size = 1794994, upload-time = "2026-03-12T03:40:17.124Z" }, @@ -840,15 +661,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d3/65/75852e04de5423c9b0c5b88241d0bdea33e6c6f454c88b71377d230216f2/botocore-1.42.74-py3-none-any.whl", hash = "sha256:3a76a8af08b5de82e51a0ae132394e226e15dbf21c8146ac3f7c1f881517a7a7", size = 14688218, upload-time = "2026-03-23T19:33:52.677Z" }, ] -[[package]] -name = "braceexpand" -version = "0.1.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/93/badd4f5ccf25209f3fef2573073da9fe4a45a3da99fca2f800f942130c0f/braceexpand-0.1.7.tar.gz", hash = "sha256:e6e539bd20eaea53547472ff94f4fb5c3d3bf9d0a89388c4b56663aba765f705", size = 7777, upload-time = "2021-05-07T13:49:07.323Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/93/e8c04e80e82391a6e51f218ca49720f64236bc824e92152a2633b74cf7ab/braceexpand-0.1.7-py2.py3-none-any.whl", hash = "sha256:91332d53de7828103dcae5773fb43bc34950b0c8160e35e0f44c4427a3b85014", size = 5923, upload-time = "2021-05-07T13:49:05.146Z" }, -] - [[package]] name = "bracex" version = "2.6" @@ -864,16 +676,6 @@ version = "1.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f7/16/c92ca344d646e71a43b8bb353f0a6490d7f6e06210f8554c8f874e454285/brotli-1.2.0.tar.gz", hash = "sha256:e310f77e41941c13340a95976fe66a8a95b01e783d430eeaf7a2f87e0a57dd0a", size = 7388632, upload-time = "2025-11-05T18:39:42.86Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/ef/f285668811a9e1ddb47a18cb0b437d5fc2760d537a2fe8a57875ad6f8448/brotli-1.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:15b33fe93cedc4caaff8a0bd1eb7e3dab1c61bb22a0bf5bdfdfd97cd7da79744", size = 863110, upload-time = "2025-11-05T18:38:12.978Z" }, - { url = "https://files.pythonhosted.org/packages/50/62/a3b77593587010c789a9d6eaa527c79e0848b7b860402cc64bc0bc28a86c/brotli-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:898be2be399c221d2671d29eed26b6b2713a02c2119168ed914e7d00ceadb56f", size = 445438, upload-time = "2025-11-05T18:38:14.208Z" }, - { url = "https://files.pythonhosted.org/packages/cd/e1/7fadd47f40ce5549dc44493877db40292277db373da5053aff181656e16e/brotli-1.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:350c8348f0e76fff0a0fd6c26755d2653863279d086d3aa2c290a6a7251135dd", size = 1534420, upload-time = "2025-11-05T18:38:15.111Z" }, - { url = "https://files.pythonhosted.org/packages/12/8b/1ed2f64054a5a008a4ccd2f271dbba7a5fb1a3067a99f5ceadedd4c1d5a7/brotli-1.2.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1ad3fda65ae0d93fec742a128d72e145c9c7a99ee2fcd667785d99eb25a7fe", size = 1632619, upload-time = "2025-11-05T18:38:16.094Z" }, - { url = "https://files.pythonhosted.org/packages/89/5a/7071a621eb2d052d64efd5da2ef55ecdac7c3b0c6e4f9d519e9c66d987ef/brotli-1.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:40d918bce2b427a0c4ba189df7a006ac0c7277c180aee4617d99e9ccaaf59e6a", size = 1426014, upload-time = "2025-11-05T18:38:17.177Z" }, - { url = "https://files.pythonhosted.org/packages/26/6d/0971a8ea435af5156acaaccec1a505f981c9c80227633851f2810abd252a/brotli-1.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2a7f1d03727130fc875448b65b127a9ec5d06d19d0148e7554384229706f9d1b", size = 1489661, upload-time = "2025-11-05T18:38:18.41Z" }, - { url = "https://files.pythonhosted.org/packages/f3/75/c1baca8b4ec6c96a03ef8230fab2a785e35297632f402ebb1e78a1e39116/brotli-1.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9c79f57faa25d97900bfb119480806d783fba83cd09ee0b33c17623935b05fa3", size = 1599150, upload-time = "2025-11-05T18:38:19.792Z" }, - { url = "https://files.pythonhosted.org/packages/0d/1a/23fcfee1c324fd48a63d7ebf4bac3a4115bdb1b00e600f80f727d850b1ae/brotli-1.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:844a8ceb8483fefafc412f85c14f2aae2fb69567bf2a0de53cdb88b73e7c43ae", size = 1493505, upload-time = "2025-11-05T18:38:20.913Z" }, - { url = "https://files.pythonhosted.org/packages/36/e5/12904bbd36afeef53d45a84881a4810ae8810ad7e328a971ebbfd760a0b3/brotli-1.2.0-cp311-cp311-win32.whl", hash = "sha256:aa47441fa3026543513139cb8926a92a8e305ee9c71a6209ef7a97d91640ea03", size = 334451, upload-time = "2025-11-05T18:38:21.94Z" }, - { url = "https://files.pythonhosted.org/packages/02/8b/ecb5761b989629a4758c394b9301607a5880de61ee2ee5fe104b87149ebc/brotli-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:022426c9e99fd65d9475dce5c195526f04bb8be8907607e27e747893f6ee3e24", size = 369035, upload-time = "2025-11-05T18:38:22.941Z" }, { url = "https://files.pythonhosted.org/packages/11/ee/b0a11ab2315c69bb9b45a2aaed022499c9c24a205c3a49c3513b541a7967/brotli-1.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:35d382625778834a7f3061b15423919aa03e4f5da34ac8e02c074e4b75ab4f84", size = 861543, upload-time = "2025-11-05T18:38:24.183Z" }, { url = "https://files.pythonhosted.org/packages/e1/2f/29c1459513cd35828e25531ebfcbf3e92a5e49f560b1777a9af7203eb46e/brotli-1.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a61c06b334bd99bc5ae84f1eeb36bfe01400264b3c352f968c6e30a10f9d08b", size = 444288, upload-time = "2025-11-05T18:38:25.139Z" }, { url = "https://files.pythonhosted.org/packages/3d/6f/feba03130d5fceadfa3a1bb102cb14650798c848b1df2a808356f939bb16/brotli-1.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acec55bb7c90f1dfc476126f9711a8e81c9af7fb617409a9ee2953115343f08d", size = 1528071, upload-time = "2025-11-05T18:38:26.081Z" }, @@ -925,10 +727,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/99/39/e7410db7f6f56de57744ea52a115084ceb2735f4d44973f349bb92136586/brotlicffi-1.2.0.1-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3314a3476f59e5443f9f72a6dff16edc0c3463c9b318feaef04ae3e4683f5a", size = 1536838, upload-time = "2026-03-05T19:54:00.705Z" }, { url = "https://files.pythonhosted.org/packages/a6/75/6e7977d1935fc3fbb201cbd619be8f2c7aea25d40a096967132854b34708/brotlicffi-1.2.0.1-cp38-abi3-win32.whl", hash = "sha256:82ea52e2b5d3145b6c406ebd3efb0d55db718b7ad996bd70c62cec0439de1187", size = 343337, upload-time = "2026-03-05T19:54:02.446Z" }, { url = "https://files.pythonhosted.org/packages/d8/ef/e7e485ce5e4ba3843a0a92feb767c7b6098fd6e65ce752918074d175ae71/brotlicffi-1.2.0.1-cp38-abi3-win_amd64.whl", hash = "sha256:da2e82a08e7778b8bc539d27ca03cdd684113e81394bfaaad8d0dfc6a17ddede", size = 379026, upload-time = "2026-03-05T19:54:04.322Z" }, - { url = "https://files.pythonhosted.org/packages/7f/53/6262c2256513e6f530d81642477cb19367270922063eaa2d7b781d8c723d/brotlicffi-1.2.0.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e015af99584c6db1490a69a210c765953e473e63adc2d891ac3062a737c9e851", size = 402265, upload-time = "2026-03-05T19:54:05.858Z" }, - { url = "https://files.pythonhosted.org/packages/1f/d9/d5340b43cf5fbe7fe5a083d237e5338cc1caa73bea523be1c5e452c26290/brotlicffi-1.2.0.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:37cb587d32bf7168e2218c455e22e409ad1f3157c6c71945879a311f3e6b6abf", size = 406710, upload-time = "2026-03-05T19:54:07.272Z" }, - { url = "https://files.pythonhosted.org/packages/a3/82/dbced4c1e0792efdf23fd90ff6d2a320c64ff4dfef7aacc85c04fde9ddd2/brotlicffi-1.2.0.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d6ba65dd528892b4d9960beba2ae011a753620bcfc66cf6fa3cee18d7b0baa4", size = 402787, upload-time = "2026-03-05T19:54:08.73Z" }, - { url = "https://files.pythonhosted.org/packages/ef/6f/534205ba7590c9a8716a614f270c5c2ec419b5b7079b3f9cd31b7b5580de/brotlicffi-1.2.0.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f2a5575653b0672638ba039b82fda56854934d7a6a24d4b8b5033f73ab43cbc1", size = 375108, upload-time = "2026-03-05T19:54:10.079Z" }, ] [[package]] @@ -981,19 +779,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, - { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, - { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, - { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, - { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, - { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, - { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, - { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, - { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, - { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, - { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, - { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, @@ -1048,11 +833,6 @@ version = "7.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/1d/94/7af830a4c63df020644aa99d76147d003a1463f255d0a054958978be5a8a/chardet-7.2.0.tar.gz", hash = "sha256:4ef7292b1342ea805c32cce58a45db204f59d080ed311d6cdaa7ca747fcc0cd5", size = 516522, upload-time = "2026-03-18T00:07:23.76Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/63/3ba1b7828340ac4b4761df5454abd0c48dd620eb4f12a5106c3390539711/chardet-7.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8685b331c4896e9135bd748387f713dd53c019475ae1b8238b8f59be1668acd", size = 545761, upload-time = "2026-03-18T00:06:53.562Z" }, - { url = "https://files.pythonhosted.org/packages/0d/b4/c3d87a7aa5ee1c71fff91a503ae1a0c3bc3b756e646948f6bfdfd2c8c873/chardet-7.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa14cc0e7d2142dd313524b3a339e15cbd8b7a8a7e11a560686e0b6f58038ec9", size = 539103, upload-time = "2026-03-18T00:06:54.837Z" }, - { url = "https://files.pythonhosted.org/packages/71/51/8eb14c4b5308225889eb4bdd9499a3d7cab1a77a82e1bcc1ad0ad22cb3a3/chardet-7.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c51a3d8aa3c162be0495404b39bb1c137b44a634c1f46e2909e2c6a60349c00", size = 560010, upload-time = "2026-03-18T00:06:56.442Z" }, - { url = "https://files.pythonhosted.org/packages/1e/cc/350b4ac6916291624093ea07ac186733e490bd33948d205d07848dbd51ff/chardet-7.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:347ed77bb5eed8929fae7482671690a15c731d66808f1ff0ce7d22224ca7ec79", size = 562610, upload-time = "2026-03-18T00:06:57.95Z" }, - { url = "https://files.pythonhosted.org/packages/36/f9/b757ade39ad981f89e3607abc75827729bf408359ddd31073e7a85cb8aeb/chardet-7.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:d298762002a6b6e81dbcc81ade9e0882e579e968f4801daf4d8ffd6a31b99552", size = 530914, upload-time = "2026-03-18T00:06:59.342Z" }, { url = "https://files.pythonhosted.org/packages/04/f2/5b4bfc3c93458c2d618d71f79e34def05552f178b4d452555a8333696f1a/chardet-7.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c4604344380a6f9b982c28855c1edfd23a45a2c9142b9a34bc0c08986049f398", size = 547261, upload-time = "2026-03-18T00:07:00.869Z" }, { url = "https://files.pythonhosted.org/packages/38/fd/3effc8151d19b6ced8d1de427df5a039b1cce4cef79a3ac6f3c1d1135502/chardet-7.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:195c54d8f04a7a9c321cb7cebececa35b1c818c7aa7c195086bae10fcbb3391f", size = 539283, upload-time = "2026-03-18T00:07:02.419Z" }, { url = "https://files.pythonhosted.org/packages/9e/b1/c1990fcafa601fcebe9308ae23026906f1e04b53b53ed38e6a81499acd30/chardet-7.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ddd03a67fca8c91287f8718dfbe3f94c2c1aa1fd3a82433b693f5b868dedf319", size = 561023, upload-time = "2026-03-18T00:07:04.078Z" }, @@ -1077,22 +857,6 @@ version = "3.4.6" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7b/60/e3bec1881450851b087e301bedc3daa9377a4d45f1c26aa90b0b235e38aa/charset_normalizer-3.4.6.tar.gz", hash = "sha256:1ae6b62897110aa7c79ea2f5dd38d1abca6db663687c0b1ad9aed6f6bae3d9d6", size = 143363, upload-time = "2026-03-15T18:53:25.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/28/ff6f234e628a2de61c458be2779cb182bc03f6eec12200d4a525bbfc9741/charset_normalizer-3.4.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:82060f995ab5003a2d6e0f4ad29065b7672b6593c8c63559beefe5b443242c3e", size = 293582, upload-time = "2026-03-15T18:50:25.454Z" }, - { url = "https://files.pythonhosted.org/packages/1c/b7/b1a117e5385cbdb3205f6055403c2a2a220c5ea80b8716c324eaf75c5c95/charset_normalizer-3.4.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60c74963d8350241a79cb8feea80e54d518f72c26db618862a8f53e5023deaf9", size = 197240, upload-time = "2026-03-15T18:50:27.196Z" }, - { url = "https://files.pythonhosted.org/packages/a1/5f/2574f0f09f3c3bc1b2f992e20bce6546cb1f17e111c5be07308dc5427956/charset_normalizer-3.4.6-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6e4333fb15c83f7d1482a76d45a0818897b3d33f00efd215528ff7c51b8e35d", size = 217363, upload-time = "2026-03-15T18:50:28.601Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d1/0ae20ad77bc949ddd39b51bf383b6ca932f2916074c95cad34ae465ab71f/charset_normalizer-3.4.6-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bc72863f4d9aba2e8fd9085e63548a324ba706d2ea2c83b260da08a59b9482de", size = 212994, upload-time = "2026-03-15T18:50:30.102Z" }, - { url = "https://files.pythonhosted.org/packages/60/ac/3233d262a310c1b12633536a07cde5ddd16985e6e7e238e9f3f9423d8eb9/charset_normalizer-3.4.6-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9cc4fc6c196d6a8b76629a70ddfcd4635a6898756e2d9cac5565cf0654605d73", size = 204697, upload-time = "2026-03-15T18:50:31.654Z" }, - { url = "https://files.pythonhosted.org/packages/25/3c/8a18fc411f085b82303cfb7154eed5bd49c77035eb7608d049468b53f87c/charset_normalizer-3.4.6-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:0c173ce3a681f309f31b87125fecec7a5d1347261ea11ebbb856fa6006b23c8c", size = 191673, upload-time = "2026-03-15T18:50:33.433Z" }, - { url = "https://files.pythonhosted.org/packages/ff/a7/11cfe61d6c5c5c7438d6ba40919d0306ed83c9ab957f3d4da2277ff67836/charset_normalizer-3.4.6-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c907cdc8109f6c619e6254212e794d6548373cc40e1ec75e6e3823d9135d29cc", size = 201120, upload-time = "2026-03-15T18:50:35.105Z" }, - { url = "https://files.pythonhosted.org/packages/b5/10/cf491fa1abd47c02f69687046b896c950b92b6cd7337a27e6548adbec8e4/charset_normalizer-3.4.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:404a1e552cf5b675a87f0651f8b79f5f1e6fd100ee88dc612f89aa16abd4486f", size = 200911, upload-time = "2026-03-15T18:50:36.819Z" }, - { url = "https://files.pythonhosted.org/packages/28/70/039796160b48b18ed466fde0af84c1b090c4e288fae26cd674ad04a2d703/charset_normalizer-3.4.6-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e3c701e954abf6fc03a49f7c579cc80c2c6cc52525340ca3186c41d3f33482ef", size = 192516, upload-time = "2026-03-15T18:50:38.228Z" }, - { url = "https://files.pythonhosted.org/packages/ff/34/c56f3223393d6ff3124b9e78f7de738047c2d6bc40a4f16ac0c9d7a1cb3c/charset_normalizer-3.4.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7a6967aaf043bceabab5412ed6bd6bd26603dae84d5cb75bf8d9a74a4959d398", size = 218795, upload-time = "2026-03-15T18:50:39.664Z" }, - { url = "https://files.pythonhosted.org/packages/e8/3b/ce2d4f86c5282191a041fdc5a4ce18f1c6bd40a5bd1f74cf8625f08d51c1/charset_normalizer-3.4.6-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:5feb91325bbceade6afab43eb3b508c63ee53579fe896c77137ded51c6b6958e", size = 201833, upload-time = "2026-03-15T18:50:41.552Z" }, - { url = "https://files.pythonhosted.org/packages/3b/9b/b6a9f76b0fd7c5b5ec58b228ff7e85095370282150f0bd50b3126f5506d6/charset_normalizer-3.4.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f820f24b09e3e779fe84c3c456cb4108a7aa639b0d1f02c28046e11bfcd088ed", size = 213920, upload-time = "2026-03-15T18:50:43.33Z" }, - { url = "https://files.pythonhosted.org/packages/ae/98/7bc23513a33d8172365ed30ee3a3b3fe1ece14a395e5fc94129541fc6003/charset_normalizer-3.4.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b35b200d6a71b9839a46b9b7fff66b6638bb52fc9658aa58796b0326595d3021", size = 206951, upload-time = "2026-03-15T18:50:44.789Z" }, - { url = "https://files.pythonhosted.org/packages/32/73/c0b86f3d1458468e11aec870e6b3feac931facbe105a894b552b0e518e79/charset_normalizer-3.4.6-cp311-cp311-win32.whl", hash = "sha256:9ca4c0b502ab399ef89248a2c84c54954f77a070f28e546a85e91da627d1301e", size = 143703, upload-time = "2026-03-15T18:50:46.103Z" }, - { url = "https://files.pythonhosted.org/packages/c6/e3/76f2facfe8eddee0bbd38d2594e709033338eae44ebf1738bcefe0a06185/charset_normalizer-3.4.6-cp311-cp311-win_amd64.whl", hash = "sha256:a9e68c9d88823b274cf1e72f28cb5dc89c990edf430b0bfd3e2fb0785bfeabf4", size = 153857, upload-time = "2026-03-15T18:50:47.563Z" }, - { url = "https://files.pythonhosted.org/packages/e2/dc/9abe19c9b27e6cd3636036b9d1b387b78c40dedbf0b47f9366737684b4b0/charset_normalizer-3.4.6-cp311-cp311-win_arm64.whl", hash = "sha256:97d0235baafca5f2b09cf332cc275f021e694e8362c6bb9c96fc9a0eb74fc316", size = 142751, upload-time = "2026-03-15T18:50:49.234Z" }, { url = "https://files.pythonhosted.org/packages/e5/62/c0815c992c9545347aeea7859b50dc9044d147e2e7278329c6e02ac9a616/charset_normalizer-3.4.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ef7fedc7a6ecbe99969cd09632516738a97eeb8bd7258bf8a0f23114c057dab", size = 295154, upload-time = "2026-03-15T18:50:50.88Z" }, { url = "https://files.pythonhosted.org/packages/a8/37/bdca6613c2e3c58c7421891d80cc3efa1d32e882f7c4a7ee6039c3fc951a/charset_normalizer-3.4.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a4ea868bc28109052790eb2b52a9ab33f3aa7adc02f96673526ff47419490e21", size = 199191, upload-time = "2026-03-15T18:50:52.658Z" }, { url = "https://files.pythonhosted.org/packages/6c/92/9934d1bbd69f7f398b38c5dae1cbf9cc672e7c34a4adf7b17c0a9c17d15d/charset_normalizer-3.4.6-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:836ab36280f21fc1a03c99cd05c6b7af70d2697e374c7af0b61ed271401a72a2", size = 218674, upload-time = "2026-03-15T18:50:54.102Z" }, @@ -1226,7 +990,7 @@ dependencies = [ { name = "rich" }, { name = "semantic-version" }, { name = "sentry-sdk" }, - { name = "setuptools", marker = "python_full_version >= '3.12'" }, + { name = "setuptools" }, { name = "simplejson" }, { name = "urllib3" }, { name = "wrapt" }, @@ -1264,17 +1028,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload-time = "2025-07-26T12:01:02.277Z" }, - { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload-time = "2025-07-26T12:01:04.072Z" }, - { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload-time = "2025-07-26T12:01:05.688Z" }, - { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload-time = "2025-07-26T12:01:07.054Z" }, - { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload-time = "2025-07-26T12:01:08.801Z" }, - { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload-time = "2025-07-26T12:01:10.319Z" }, - { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload-time = "2025-07-26T12:01:12.659Z" }, - { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload-time = "2025-07-26T12:01:15.533Z" }, - { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, - { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, - { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, @@ -1330,11 +1083,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, - { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" }, - { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" }, - { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" }, - { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload-time = "2025-07-26T12:02:57.468Z" }, - { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" }, ] [[package]] @@ -1343,21 +1091,6 @@ version = "7.13.5" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9d/e0/70553e3000e345daff267cec284ce4cbf3fc141b6da229ac52775b5428f1/coverage-7.13.5.tar.gz", hash = "sha256:c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179", size = 915967, upload-time = "2026-03-17T10:33:18.341Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/37/d24c8f8220ff07b839b2c043ea4903a33b0f455abe673ae3c03bbdb7f212/coverage-7.13.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66a80c616f80181f4d643b0f9e709d97bcea413ecd9631e1dedc7401c8e6695d", size = 219381, upload-time = "2026-03-17T10:30:14.68Z" }, - { url = "https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587", size = 219880, upload-time = "2026-03-17T10:30:16.231Z" }, - { url = "https://files.pythonhosted.org/packages/55/2f/e0e5b237bffdb5d6c530ce87cc1d413a5b7d7dfd60fb067ad6d254c35c76/coverage-7.13.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0672854dc733c342fa3e957e0605256d2bf5934feeac328da9e0b5449634a642", size = 250303, upload-time = "2026-03-17T10:30:17.748Z" }, - { url = "https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b", size = 252218, upload-time = "2026-03-17T10:30:19.804Z" }, - { url = "https://files.pythonhosted.org/packages/da/69/2f47bb6fa1b8d1e3e5d0c4be8ccb4313c63d742476a619418f85740d597b/coverage-7.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be3d4bbad9d4b037791794ddeedd7d64a56f5933a2c1373e18e9e568b9141686", size = 254326, upload-time = "2026-03-17T10:30:21.321Z" }, - { url = "https://files.pythonhosted.org/packages/d5/d0/79db81da58965bd29dabc8f4ad2a2af70611a57cba9d1ec006f072f30a54/coverage-7.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d2afbc5cc54d286bfb54541aa50b64cdb07a718227168c87b9e2fb8f25e1743", size = 256267, upload-time = "2026-03-17T10:30:23.094Z" }, - { url = "https://files.pythonhosted.org/packages/e5/32/d0d7cc8168f91ddab44c0ce4806b969df5f5fdfdbb568eaca2dbc2a04936/coverage-7.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3ad050321264c49c2fa67bb599100456fc51d004b82534f379d16445da40fb75", size = 250430, upload-time = "2026-03-17T10:30:25.311Z" }, - { url = "https://files.pythonhosted.org/packages/4d/06/a055311d891ddbe231cd69fdd20ea4be6e3603ffebddf8704b8ca8e10a3c/coverage-7.13.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7300c8a6d13335b29bb76d7651c66af6bd8658517c43499f110ddc6717bfc209", size = 252017, upload-time = "2026-03-17T10:30:27.284Z" }, - { url = "https://files.pythonhosted.org/packages/d6/f6/d0fd2d21e29a657b5f77a2fe7082e1568158340dceb941954f776dce1b7b/coverage-7.13.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:eb07647a5738b89baab047f14edd18ded523de60f3b30e75c2acc826f79c839a", size = 250080, upload-time = "2026-03-17T10:30:29.481Z" }, - { url = "https://files.pythonhosted.org/packages/4e/ab/0d7fb2efc2e9a5eb7ddcc6e722f834a69b454b7e6e5888c3a8567ecffb31/coverage-7.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9adb6688e3b53adffefd4a52d72cbd8b02602bfb8f74dcd862337182fd4d1a4e", size = 253843, upload-time = "2026-03-17T10:30:31.301Z" }, - { url = "https://files.pythonhosted.org/packages/ba/6f/7467b917bbf5408610178f62a49c0ed4377bb16c1657f689cc61470da8ce/coverage-7.13.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7c8d4bc913dd70b93488d6c496c77f3aff5ea99a07e36a18f865bca55adef8bd", size = 249802, upload-time = "2026-03-17T10:30:33.358Z" }, - { url = "https://files.pythonhosted.org/packages/75/2c/1172fb689df92135f5bfbbd69fc83017a76d24ea2e2f3a1154007e2fb9f8/coverage-7.13.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0e3c426ffc4cd952f54ee9ffbdd10345709ecc78a3ecfd796a57236bfad0b9b8", size = 250707, upload-time = "2026-03-17T10:30:35.2Z" }, - { url = "https://files.pythonhosted.org/packages/67/21/9ac389377380a07884e3b48ba7a620fcd9dbfaf1d40565facdc6b36ec9ef/coverage-7.13.5-cp311-cp311-win32.whl", hash = "sha256:259b69bb83ad9894c4b25be2528139eecba9a82646ebdda2d9db1ba28424a6bf", size = 221880, upload-time = "2026-03-17T10:30:36.775Z" }, - { url = "https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl", hash = "sha256:258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9", size = 222816, upload-time = "2026-03-17T10:30:38.891Z" }, - { url = "https://files.pythonhosted.org/packages/12/a6/1d3f6155fb0010ca68eba7fe48ca6c9da7385058b77a95848710ecf189b1/coverage-7.13.5-cp311-cp311-win_arm64.whl", hash = "sha256:bff95879c33ec8da99fc9b6fe345ddb5be6414b41d6d1ad1c8f188d26f36e028", size = 221483, upload-time = "2026-03-17T10:30:40.463Z" }, { url = "https://files.pythonhosted.org/packages/a0/c3/a396306ba7db865bf96fc1fb3b7fd29bcbf3d829df642e77b13555163cd6/coverage-7.13.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:460cf0114c5016fa841214ff5564aa4864f11948da9440bc97e21ad1f4ba1e01", size = 219554, upload-time = "2026-03-17T10:30:42.208Z" }, { url = "https://files.pythonhosted.org/packages/a6/16/a68a19e5384e93f811dccc51034b1fd0b865841c390e3c931dcc4699e035/coverage-7.13.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e223ce4b4ed47f065bfb123687686512e37629be25cc63728557ae7db261422", size = 219908, upload-time = "2026-03-17T10:30:43.906Z" }, { url = "https://files.pythonhosted.org/packages/29/72/20b917c6793af3a5ceb7fb9c50033f3ec7865f2911a1416b34a7cfa0813b/coverage-7.13.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6e3370441f4513c6252bf042b9c36d22491142385049243253c7e48398a15a9f", size = 251419, upload-time = "2026-03-17T10:30:45.545Z" }, @@ -1473,9 +1206,6 @@ dependencies = [ { name = "cuda-pathfinder" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/2b/ebcbb60aa6dba830474cd360c42e10282f7a343c0a1f58d24fbd3b7c2d77/cuda_bindings-12.9.4-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a6a429dc6c13148ff1e27c44f40a3dd23203823e637b87fd0854205195988306", size = 11840604, upload-time = "2025-10-21T14:51:34.565Z" }, - { url = "https://files.pythonhosted.org/packages/45/e7/b47792cc2d01c7e1d37c32402182524774dadd2d26339bd224e0e913832e/cuda_bindings-12.9.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c912a3d9e6b6651853eed8eed96d6800d69c08e94052c292fec3f282c5a817c9", size = 12210593, upload-time = "2025-10-21T14:51:36.574Z" }, - { url = "https://files.pythonhosted.org/packages/dd/be/90d32049e06abcfba4b2e7df1dbcb5e16215c8852eef0cd8b25f38a66bd4/cuda_bindings-12.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:443b0875916879c2e4c3722941e25e42d5ab9bcbf34c9e83404fb100fa1f6913", size = 11490933, upload-time = "2025-10-21T14:51:38.792Z" }, { url = "https://files.pythonhosted.org/packages/0c/c2/65bfd79292b8ff18be4dd7f7442cea37bcbc1a228c1886f1dea515c45b67/cuda_bindings-12.9.4-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:694ba35023846625ef471257e6b5a4bc8af690f961d197d77d34b1d1db393f56", size = 11760260, upload-time = "2025-10-21T14:51:40.79Z" }, { url = "https://files.pythonhosted.org/packages/a9/c1/dabe88f52c3e3760d861401bb994df08f672ec893b8f7592dc91626adcf3/cuda_bindings-12.9.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fda147a344e8eaeca0c6ff113d2851ffca8f7dfc0a6c932374ee5c47caa649c8", size = 12151019, upload-time = "2025-10-21T14:51:43.167Z" }, { url = "https://files.pythonhosted.org/packages/df/6b/9c1b1a6c01392bfdd758e9486f52a1a72bc8f49e98f9355774ef98b5fb4e/cuda_bindings-12.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:696ca75d249ddf287d01b9a698b8e2d8a05046495a9c051ca15659dc52d17615", size = 11586961, upload-time = "2025-10-21T14:51:45.394Z" }, @@ -1601,10 +1331,6 @@ version = "1.8.20" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33", size = 1645207, upload-time = "2026-01-29T23:03:28.199Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/56/c3baf5cbe4dd77427fd9aef99fcdade259ad128feeb8a786c246adb838e5/debugpy-1.8.20-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:eada6042ad88fa1571b74bd5402ee8b86eded7a8f7b827849761700aff171f1b", size = 2208318, upload-time = "2026-01-29T23:03:36.481Z" }, - { url = "https://files.pythonhosted.org/packages/9a/7d/4fa79a57a8e69fe0d9763e98d1110320f9ecd7f1f362572e3aafd7417c9d/debugpy-1.8.20-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:7de0b7dfeedc504421032afba845ae2a7bcc32ddfb07dae2c3ca5442f821c344", size = 3171493, upload-time = "2026-01-29T23:03:37.775Z" }, - { url = "https://files.pythonhosted.org/packages/7d/f2/1e8f8affe51e12a26f3a8a8a4277d6e60aa89d0a66512f63b1e799d424a4/debugpy-1.8.20-cp311-cp311-win32.whl", hash = "sha256:773e839380cf459caf73cc533ea45ec2737a5cc184cf1b3b796cd4fd98504fec", size = 5209240, upload-time = "2026-01-29T23:03:39.109Z" }, - { url = "https://files.pythonhosted.org/packages/d5/92/1cb532e88560cbee973396254b21bece8c5d7c2ece958a67afa08c9f10dc/debugpy-1.8.20-cp311-cp311-win_amd64.whl", hash = "sha256:1f7650546e0eded1902d0f6af28f787fa1f1dbdbc97ddabaf1cd963a405930cb", size = 5233481, upload-time = "2026-01-29T23:03:40.659Z" }, { url = "https://files.pythonhosted.org/packages/14/57/7f34f4736bfb6e00f2e4c96351b07805d83c9a7b33d28580ae01374430f7/debugpy-1.8.20-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d", size = 2550686, upload-time = "2026-01-29T23:03:42.023Z" }, { url = "https://files.pythonhosted.org/packages/ab/78/b193a3975ca34458f6f0e24aaf5c3e3da72f5401f6054c0dfd004b41726f/debugpy-1.8.20-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b", size = 4310588, upload-time = "2026-01-29T23:03:43.314Z" }, { url = "https://files.pythonhosted.org/packages/c1/55/f14deb95eaf4f30f07ef4b90a8590fc05d9e04df85ee379712f6fb6736d7/debugpy-1.8.20-cp312-cp312-win32.whl", hash = "sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390", size = 5331372, upload-time = "2026-01-29T23:03:45.526Z" }, @@ -1758,13 +1484,6 @@ version = "1.5.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ae/62/590caabec6c41003f46a244b6fd707d35ca2e552e0c70cbf454e08bf6685/duckdb-1.5.1.tar.gz", hash = "sha256:b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d", size = 17995082, upload-time = "2026-03-23T12:12:15.894Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/3e/827ffcf58f0abc6ad6dcf826c5d24ebfc65e03ad1a20d74cad9806f91c99/duckdb-1.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad", size = 30067835, upload-time = "2026-03-23T12:10:34.026Z" }, - { url = "https://files.pythonhosted.org/packages/04/b5/e921ecf8a7e0cc7da2100c98bef64b3da386df9444f467d6389364851302/duckdb-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3", size = 15970464, upload-time = "2026-03-23T12:10:42.063Z" }, - { url = "https://files.pythonhosted.org/packages/dd/da/ed804006cd09ba303389d573c8b15d74220667cbd1fd990c26e98d0e0a5b/duckdb-1.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101", size = 14222994, upload-time = "2026-03-23T12:10:45.162Z" }, - { url = "https://files.pythonhosted.org/packages/b3/43/c904d81a61306edab81a9d74bb37bbe65679639abb7030d4c4fec9ed84f7/duckdb-1.5.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141", size = 19244880, upload-time = "2026-03-23T12:10:48.529Z" }, - { url = "https://files.pythonhosted.org/packages/50/db/358715d677bfe5e117d9e1f2d6cc2fc2b0bd621144d1f15335b8b59f95d7/duckdb-1.5.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71", size = 21350874, upload-time = "2026-03-23T12:10:52.095Z" }, - { url = "https://files.pythonhosted.org/packages/3f/db/fd647ce46315347976f5576a279bacb8134d23b1f004bd0bcda7ce9cf429/duckdb-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130", size = 13068140, upload-time = "2026-03-23T12:10:55.622Z" }, - { url = "https://files.pythonhosted.org/packages/27/95/e29d42792707619da5867ffab338d7e7b086242c7296aa9cfc6dcf52d568/duckdb-1.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723", size = 13908823, upload-time = "2026-03-23T12:10:58.572Z" }, { url = "https://files.pythonhosted.org/packages/3f/06/be4c62f812c6e23898733073ace0482eeb18dffabe0585d63a3bf38bca1e/duckdb-1.5.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6", size = 30113703, upload-time = "2026-03-23T12:11:02.536Z" }, { url = "https://files.pythonhosted.org/packages/44/03/1794dcdda75ff203ab0982ff7eb5232549b58b9af66f243f1b7212d6d6be/duckdb-1.5.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225", size = 15991802, upload-time = "2026-03-23T12:11:06.321Z" }, { url = "https://files.pythonhosted.org/packages/87/03/293bccd838a293d42ea26dec7f4eb4f58b57b6c9ffcfabc6518a5f20a24a/duckdb-1.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59", size = 14246803, upload-time = "2026-03-23T12:11:09.624Z" }, @@ -1793,16 +1512,10 @@ name = "dulwich" version = "0.25.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.12'" }, { name = "urllib3" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/9c9bc6ac66007f8090b1da9079c0e4bbea5aa9583c3c12098e0f11462dd5/dulwich-0.25.2.tar.gz", hash = "sha256:bca22c8aa4cbecbe8493b76e3fd6101513f09cf405cd9b92e116a48d9469e55a", size = 1126499, upload-time = "2026-01-11T22:04:47.667Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/22/b6cbdf804b401318df1be69d79dfb307d7547c7e97bf1c0617e4bcd8aee1/dulwich-0.25.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a662d0ad211290b39e75859cff656efa93acb06d79ccee978684a5a9ea74935", size = 1339095, upload-time = "2026-01-11T22:04:12.369Z" }, - { url = "https://files.pythonhosted.org/packages/ed/8a/772b97a8bd023bfab9c6eb690ea60ff321948a308e3ced7af5358a30d061/dulwich-0.25.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:fe5e5e06e52bc03fe809c50bb65554a363eee63259b6d9fc46eadaf49129c400", size = 1402305, upload-time = "2026-01-11T22:04:14.633Z" }, - { url = "https://files.pythonhosted.org/packages/53/06/4a3491b0ee7f12d083389ca330523b3de3f759c565e1832824c5e5a500f9/dulwich-0.25.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d331a20ba827da1d5d95de5a5151c6b7a945ddcdd381a61aeea543dc5e821be1", size = 1430967, upload-time = "2026-01-11T22:04:16.604Z" }, - { url = "https://files.pythonhosted.org/packages/5d/dd/b90dc96dc7374e20305444276413e9adda246ed6da67897f5cf19e7a6d24/dulwich-0.25.2-cp311-cp311-win32.whl", hash = "sha256:093b14820fe208f83688538e9232c91cb4b2af69c8ece524129e7bdd03a50864", size = 987632, upload-time = "2026-01-11T22:04:18.268Z" }, - { url = "https://files.pythonhosted.org/packages/98/0b/3bcd27ff638634e9c4ae09f53212a0ccbf5b7c71762e42a9969e58cce865/dulwich-0.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:428e5c513401fb089793f22dc585fdde0e87ef9c9753e20551e5e0f5265e3f16", size = 1004139, upload-time = "2026-01-11T22:04:19.691Z" }, { url = "https://files.pythonhosted.org/packages/da/8a/4ec87df697cf1af9172b015e1256ca93856d9454d7e24a4f9168d3667892/dulwich-0.25.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce00c68c4fcd7ea53641153a69aab9a010ae140387a39f13e9ecf05f60fefd77", size = 1318435, upload-time = "2026-01-11T22:04:21.97Z" }, { url = "https://files.pythonhosted.org/packages/e1/fe/1260a7217eb439bae33bae3af98b84ed53e0601e19bd87e580df09650021/dulwich-0.25.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:6ece907b40f503c68e27bd77c71d3de25ac5c6256c43b82f7843232e7769cebd", size = 1395034, upload-time = "2026-01-11T22:04:23.384Z" }, { url = "https://files.pythonhosted.org/packages/3f/24/e8cec93df1bfba4087919842a0754b50f0c6e605d620976d5d8625229caa/dulwich-0.25.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e2d5cc06cc25d88f87fd966bee74c62903473f81a1646323bf1e4fe8fec4b797", size = 1423110, upload-time = "2026-01-11T22:04:24.937Z" }, @@ -1829,15 +1542,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b0/0d/9feae160378a3553fa9a339b0e9c1a048e147a4127210e286ef18b730f03/durationpy-0.10-py3-none-any.whl", hash = "sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286", size = 3922, upload-time = "2025-05-17T13:52:36.463Z" }, ] -[[package]] -name = "ebmlite" -version = "3.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ea/ae/70f7b3e255c330ac64bc404d8305f2bf1b439bc14c1b18da72ff566a4f4a/ebmlite-3.4.1.tar.gz", hash = "sha256:428cc88014e7f3544dfd64f1e7a35b7636d11eaef944d27c5da9d203f1498316", size = 90832, upload-time = "2025-07-24T15:06:14.172Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/57/06/41a15af1f9b4d3144fa4ee39d8e7b9b87a97ad3a04a6fa85c64788ca0af8/ebmlite-3.4.1-py3-none-any.whl", hash = "sha256:995765284e69d139fab34bbfb40e9e16a04116a95c7c9af368d90db7ca6b395c", size = 93430, upload-time = "2025-07-24T15:06:13.118Z" }, -] - [[package]] name = "einops" version = "0.8.2" @@ -1967,22 +1671,6 @@ version = "0.9.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/dd/00/dab9ca274cf1fde19223fea7104631bea254751026e75bf99f2b6d0d1568/fastar-0.9.0.tar.gz", hash = "sha256:d49114d5f0b76c5cc242875d90fa4706de45e0456ddedf416608ecd0787fb410", size = 70124, upload-time = "2026-03-20T14:26:34.503Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/01/4ecbe0b4938608f9c6c5c4d4f6b872975fe30152bfaa8e44fe0e3b6cbcc4/fastar-0.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:facc7522bd1c1e7569bedb602932fc7292408a320f415d72180634d58f661bf0", size = 708809, upload-time = "2026-03-20T14:25:31.299Z" }, - { url = "https://files.pythonhosted.org/packages/11/6a/085b3cae0e04da4d42306dc07e2cc4f95d9c8f27df4dfd1a25d0f80516cb/fastar-0.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c8ac3e8aaee57dfc822b04f570f0a963c2381a9dc8990fe0c6e965efd23fd451", size = 629764, upload-time = "2026-03-20T14:25:19.017Z" }, - { url = "https://files.pythonhosted.org/packages/3c/c2/cdd996a37837e6cc5edc4d09775d2a2bc63e9e931129db69947cf4c77148/fastar-0.9.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d90493b4bb56db728b38eb18a551df386113d72ad4e7f1a97572f3662a9b8a85", size = 869631, upload-time = "2026-03-20T14:24:53.779Z" }, - { url = "https://files.pythonhosted.org/packages/30/d4/4a5a3c341d26197ea3ae6bed79fc9bb4ead8ddc74a93bdb74e4ee0bac18e/fastar-0.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17e2c3b46408193ea13c1e1177275ca7951e88bd3dce16baccb8de4f5e0dc2e8", size = 762096, upload-time = "2026-03-20T14:23:49.175Z" }, - { url = "https://files.pythonhosted.org/packages/bc/dd/1d346cdfcd3064f6c435eff90a8d7cf0021487e3681453bdd681b9488d81/fastar-0.9.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:52f96a3d4cfbe4f06b376706fa0562f3a1d2329bc37168119af0e47e1ac21cab", size = 759627, upload-time = "2026-03-20T14:24:01.984Z" }, - { url = "https://files.pythonhosted.org/packages/02/a1/e91eb7ae1e41c0d3ead86dc199beb13a0b80101e2948d66adeb578b09e60/fastar-0.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57e9b94e485713c79bb259f7ecff1213527d05e9aa43a157c3fbc88812cf163e", size = 926211, upload-time = "2026-03-20T14:24:15.218Z" }, - { url = "https://files.pythonhosted.org/packages/9b/63/9fea9604e7aecc2f062f0df5729f74712d81615a1b18fa6a1a13106184fa/fastar-0.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fb06d0a0cc3cf52a9c07559bb16ab99eb75afe0b3d5ce68f5c299569460851ac", size = 818748, upload-time = "2026-03-20T14:24:40.765Z" }, - { url = "https://files.pythonhosted.org/packages/b0/f8/521438041d69873bb68b144b09080ae4f1621cebb8238b1e54821057206b/fastar-0.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c75e779f72d845037d4bf6692d01ac66f014eaef965c9231d41d5cc1276b89fc", size = 822380, upload-time = "2026-03-20T14:25:06.825Z" }, - { url = "https://files.pythonhosted.org/packages/92/05/f33cc3f5f96ffb7d81a7f06c9239d4eea584527292a030a73d3218148f41/fastar-0.9.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:24b13fc4ef3f1e3c9cc2dcf07ad9445900db9d3ce09b73021547a55994d0407f", size = 886569, upload-time = "2026-03-20T14:24:27.567Z" }, - { url = "https://files.pythonhosted.org/packages/60/32/6e7cb45dce544f97b0199325084a0a5a895cb903e0539690619e78d8d7cf/fastar-0.9.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec7852de506d022ad36ad56f4aefb10c259dd59e485bf87af827954d404ba9d5", size = 969993, upload-time = "2026-03-20T14:25:44.222Z" }, - { url = "https://files.pythonhosted.org/packages/6a/ee/04cf9374e5e6a82ddc87073d684c1fa7a9ca368bf85c2786535b1bfc38a9/fastar-0.9.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:a79c53c3003958dca88a7ec3dd805bf9c2fb2a659110039f44571d57e329e3d4", size = 1036738, upload-time = "2026-03-20T14:25:57.551Z" }, - { url = "https://files.pythonhosted.org/packages/b6/94/e6f6ad29c25c5f531a406e3a35ef5c034ea177748f9fb621073519adb3d5/fastar-0.9.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:00328ce7ae76be7f9e2faa6a221a0b41212e4115c27e2ac5e585bcf226bfc2eb", size = 1078557, upload-time = "2026-03-20T14:26:10.358Z" }, - { url = "https://files.pythonhosted.org/packages/1f/44/a1c9f6afe93d1cc1abb68a7cda2bada509d756d24e22d5d949ca86b4f45e/fastar-0.9.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5c03fad1ad9ac57cf03a4db9e18c7109c37416ff4eb9ebfca98fcd2b233a26c4", size = 1029251, upload-time = "2026-03-20T14:26:23.215Z" }, - { url = "https://files.pythonhosted.org/packages/75/31/9e77bc2af3c8b8a433b7175d14b9c75d0ab901542c7452fdf942ece5a155/fastar-0.9.0-cp311-cp311-win32.whl", hash = "sha256:163ba4c543d2112c8186be2f134d11456b593071ba9ea3faba4f155bde7c5dac", size = 454633, upload-time = "2026-03-20T14:26:55.344Z" }, - { url = "https://files.pythonhosted.org/packages/0c/d4/a78d51d1290cdce2d6d3162a18d12c736b71d3feef5a446b3fe021443eb3/fastar-0.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:2137d5d26044b44bb19197a8fc959256c772615ee959cddd0f74320b548fc966", size = 486772, upload-time = "2026-03-20T14:26:43.569Z" }, - { url = "https://files.pythonhosted.org/packages/fa/39/471aefca4c8180689cc0dc6f2f23bc283a3ca07114f713307fb947d320af/fastar-0.9.0-cp311-cp311-win_arm64.whl", hash = "sha256:ecb94de3bc96d9fae95641a7907385541517a4c17416153d3b952d37dce0a2a3", size = 463586, upload-time = "2026-03-20T14:26:35.483Z" }, { url = "https://files.pythonhosted.org/packages/4d/9b/300bc0dafa8495718976076db216f42d57b251a582589566a63b4ed2cb82/fastar-0.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7a8b5daa50d9b4c07367dffc40880467170bf1c31ca63a2286506edbe6d3d65b", size = 706914, upload-time = "2026-03-20T14:25:32.501Z" }, { url = "https://files.pythonhosted.org/packages/95/97/f1e34c8224dc373c6fab5b33e33be0d184751fdc27013af3278b1e4e6e6c/fastar-0.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9ec841a69fea73361c6df6d9183915c09e9ce3bd96493763fa46019e79918400", size = 627422, upload-time = "2026-03-20T14:25:20.318Z" }, { url = "https://files.pythonhosted.org/packages/a9/ad/e2499d136e24c2d896f2ec58183c91c6f8185d758177537724ed2f3e1b54/fastar-0.9.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ad46bc23040142e9be4b4005ea366834dbf0f1b6a90b8ecdc3ec96c42dec4adf", size = 865265, upload-time = "2026-03-20T14:24:55.418Z" }, @@ -2047,19 +1735,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4b/c7/080bbb2b3c4e739fe6486fd765a09905f6c16c1068b2fcf2bb51a5e83937/fastar-0.9.0-cp314-cp314t-win32.whl", hash = "sha256:32787880600a988d11547628034993ef948499ae4514a30509817242c4eb98b1", size = 452317, upload-time = "2026-03-20T14:27:03.243Z" }, { url = "https://files.pythonhosted.org/packages/42/39/00553739a7e9e35f78a0c5911d181acf6b6e132337adc9bbc3575f5f6f04/fastar-0.9.0-cp314-cp314t-win_amd64.whl", hash = "sha256:92fa18ec4958f33473259980685d29248ac44c96eed34026ad7550f93dd9ee23", size = 483994, upload-time = "2026-03-20T14:26:52.76Z" }, { url = "https://files.pythonhosted.org/packages/4f/36/a7af08d233624515d9a0f5d41b7a01a51fd825b8c795e41800215a3200e7/fastar-0.9.0-cp314-cp314t-win_arm64.whl", hash = "sha256:34f646ac4f5bed3661a106ca56c1744e7146a02aacf517d47b24fd3f25dc1ff6", size = 460604, upload-time = "2026-03-20T14:26:40.771Z" }, - { url = "https://files.pythonhosted.org/packages/69/9f/4aeaa0a1ac2aca142a276ea136e651e94ba1341bd840ba455ed250d1970b/fastar-0.9.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b74ce299066288f3b90221dca8507f59c7d9e8df91387948006b9a0fea4f9bdc", size = 710738, upload-time = "2026-03-20T14:25:41.17Z" }, - { url = "https://files.pythonhosted.org/packages/d0/19/9f8fb5c0e803254c5d535c362102dd604d9bdb206d5a36150f4637cadf09/fastar-0.9.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:76be31936cabce31cbb6381128f851cf0a6da2d5c25357615cd1504b26dc31cf", size = 633000, upload-time = "2026-03-20T14:25:28.496Z" }, - { url = "https://files.pythonhosted.org/packages/ef/8d/0d1d9a87a78f1e686bb6c7c69688a4c9ad1efb65e49cc66310b97fdf900b/fastar-0.9.0-pp311-pypy311_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c4c9ea0e0d69445b0ca3b0bd80bd8237fec8a914275b0472ecca2b555c12f3a3", size = 871226, upload-time = "2026-03-20T14:25:04.351Z" }, - { url = "https://files.pythonhosted.org/packages/ef/04/366937320b1cca522570c527a45b1254bd68d057e68956baefc49eacae27/fastar-0.9.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b665c33afcd1d581b82235b690d999c5446ccc2c4d80c4a95f30df3b43d22494", size = 763872, upload-time = "2026-03-20T14:23:59.122Z" }, - { url = "https://files.pythonhosted.org/packages/c8/f2/121c5432bb152da68fc466a0d0206d66383a40a2f9beff5583d9277aceee/fastar-0.9.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d2a9a49f9217f4f60f9ba23fdd1f7f3f04fed97391145eb9460ec83ca0b4bd33", size = 762897, upload-time = "2026-03-20T14:24:11.932Z" }, - { url = "https://files.pythonhosted.org/packages/80/9e/88d3a603b997063e032f94cc0fff74031d76903f38cc30416a400395df03/fastar-0.9.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59d860e82a531e9cc67e7f500a299bffbe6e93d80bbf48401fd8f452a0c58f28", size = 927024, upload-time = "2026-03-20T14:24:24.689Z" }, - { url = "https://files.pythonhosted.org/packages/a6/17/d6dc778c45b0c7d9a279706d7a5d62122dab0a7a0cb39aac6f5ef42f13f6/fastar-0.9.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3feede2d72ec0782b5ccc18568f36cbe33816be396551aa47b3e1b73c322cdd2", size = 821265, upload-time = "2026-03-20T14:24:50.407Z" }, - { url = "https://files.pythonhosted.org/packages/e0/e0/cec25d43df7ea4b4e3e875352c6d51c848c855792ba276c546732a7170af/fastar-0.9.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9ac410d32cbb514e966c45f0fedd0f9447b0dea9e734af714648da503603df6", size = 824024, upload-time = "2026-03-20T14:25:16.142Z" }, - { url = "https://files.pythonhosted.org/packages/52/90/c354969770d21d1b07c9281b5e23052392c288d22984a1917d30940e86cb/fastar-0.9.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:40b8c08df809e5e58d1839ccb37bafe4485deb6ee56bb7c5f0cbb72d701eb965", size = 888886, upload-time = "2026-03-20T14:24:38.229Z" }, - { url = "https://files.pythonhosted.org/packages/8c/ac/eb2a01ed94e79b72003840448d2b69644a54a47f615c7d693432a1337caa/fastar-0.9.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:d62a4fd86eda3bea7cc32efd64d43b6d0fcdbbec009558b750fc362f20142789", size = 972503, upload-time = "2026-03-20T14:25:54.207Z" }, - { url = "https://files.pythonhosted.org/packages/8d/88/f7e28100fa7ff4a26a3493ad7a5d45d70f6de858c05f5c34aca3570c5839/fastar-0.9.0-pp311-pypy311_pp73-musllinux_1_2_armv7l.whl", hash = "sha256:7bf6958bb6f94e5ec522e4a255b8e940d3561ad973f0be5dde6115b5a0854af5", size = 1039106, upload-time = "2026-03-20T14:26:07.686Z" }, - { url = "https://files.pythonhosted.org/packages/c0/de/52c578180fdaaf0f3289de8a878f1ac070f7e3e18a0689d3fd44dd7dae2c/fastar-0.9.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:c210b839c0a33cf8d08270963ad237bcb63029dddf6d6025333f7e5ca63930bd", size = 1080754, upload-time = "2026-03-20T14:26:20.299Z" }, - { url = "https://files.pythonhosted.org/packages/a4/45/1ea024be428ad9d89e9f738c9379507e97df9f9ed97e50e4a1d10ff90fef/fastar-0.9.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:fad70e257daefb42bab68dcd68beaf2e2a99da056d65f2c9f988449a4e869306", size = 1031304, upload-time = "2026-03-20T14:26:33.294Z" }, ] [[package]] @@ -2077,17 +1752,6 @@ version = "0.14.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/c3/7d/d9daedf0f2ebcacd20d599928f8913e9d2aea1d56d2d355a93bfa2b611d7/fastuuid-0.14.0.tar.gz", hash = "sha256:178947fc2f995b38497a74172adee64fdeb8b7ec18f2a5934d037641ba265d26", size = 18232, upload-time = "2025-10-19T22:19:22.402Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/98/f3/12481bda4e5b6d3e698fbf525df4443cc7dce746f246b86b6fcb2fba1844/fastuuid-0.14.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:73946cb950c8caf65127d4e9a325e2b6be0442a224fd51ba3b6ac44e1912ce34", size = 516386, upload-time = "2025-10-19T22:42:40.176Z" }, - { url = "https://files.pythonhosted.org/packages/59/19/2fc58a1446e4d72b655648eb0879b04e88ed6fa70d474efcf550f640f6ec/fastuuid-0.14.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:12ac85024637586a5b69645e7ed986f7535106ed3013640a393a03e461740cb7", size = 264569, upload-time = "2025-10-19T22:25:50.977Z" }, - { url = "https://files.pythonhosted.org/packages/78/29/3c74756e5b02c40cfcc8b1d8b5bac4edbd532b55917a6bcc9113550e99d1/fastuuid-0.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:05a8dde1f395e0c9b4be515b7a521403d1e8349443e7641761af07c7ad1624b1", size = 254366, upload-time = "2025-10-19T22:29:49.166Z" }, - { url = "https://files.pythonhosted.org/packages/52/96/d761da3fccfa84f0f353ce6e3eb8b7f76b3aa21fd25e1b00a19f9c80a063/fastuuid-0.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09378a05020e3e4883dfdab438926f31fea15fd17604908f3d39cbeb22a0b4dc", size = 278978, upload-time = "2025-10-19T22:35:41.306Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c2/f84c90167cc7765cb82b3ff7808057608b21c14a38531845d933a4637307/fastuuid-0.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbb0c4b15d66b435d2538f3827f05e44e2baafcc003dd7d8472dc67807ab8fd8", size = 279692, upload-time = "2025-10-19T22:25:36.997Z" }, - { url = "https://files.pythonhosted.org/packages/af/7b/4bacd03897b88c12348e7bd77943bac32ccf80ff98100598fcff74f75f2e/fastuuid-0.14.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cd5a7f648d4365b41dbf0e38fe8da4884e57bed4e77c83598e076ac0c93995e7", size = 303384, upload-time = "2025-10-19T22:29:46.578Z" }, - { url = "https://files.pythonhosted.org/packages/c0/a2/584f2c29641df8bd810d00c1f21d408c12e9ad0c0dafdb8b7b29e5ddf787/fastuuid-0.14.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c0a94245afae4d7af8c43b3159d5e3934c53f47140be0be624b96acd672ceb73", size = 460921, upload-time = "2025-10-19T22:36:42.006Z" }, - { url = "https://files.pythonhosted.org/packages/24/68/c6b77443bb7764c760e211002c8638c0c7cce11cb584927e723215ba1398/fastuuid-0.14.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2b29e23c97e77c3a9514d70ce343571e469098ac7f5a269320a0f0b3e193ab36", size = 480575, upload-time = "2025-10-19T22:28:18.975Z" }, - { url = "https://files.pythonhosted.org/packages/5a/87/93f553111b33f9bb83145be12868c3c475bf8ea87c107063d01377cc0e8e/fastuuid-0.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1e690d48f923c253f28151b3a6b4e335f2b06bf669c68a02665bc150b7839e94", size = 452317, upload-time = "2025-10-19T22:25:32.75Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8c/a04d486ca55b5abb7eaa65b39df8d891b7b1635b22db2163734dc273579a/fastuuid-0.14.0-cp311-cp311-win32.whl", hash = "sha256:a6f46790d59ab38c6aa0e35c681c0484b50dc0acf9e2679c005d61e019313c24", size = 154804, upload-time = "2025-10-19T22:24:15.615Z" }, - { url = "https://files.pythonhosted.org/packages/9c/b2/2d40bf00820de94b9280366a122cbaa60090c8cf59e89ac3938cf5d75895/fastuuid-0.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:e150eab56c95dc9e3fefc234a0eedb342fac433dacc273cd4d150a5b0871e1fa", size = 156099, upload-time = "2025-10-19T22:24:31.646Z" }, { url = "https://files.pythonhosted.org/packages/02/a2/e78fcc5df65467f0d207661b7ef86c5b7ac62eea337c0c0fcedbeee6fb13/fastuuid-0.14.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:77e94728324b63660ebf8adb27055e92d2e4611645bf12ed9d88d30486471d0a", size = 510164, upload-time = "2025-10-19T22:31:45.635Z" }, { url = "https://files.pythonhosted.org/packages/2b/b3/c846f933f22f581f558ee63f81f29fa924acd971ce903dab1a9b6701816e/fastuuid-0.14.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:caa1f14d2102cb8d353096bc6ef6c13b2c81f347e6ab9d6fbd48b9dea41c153d", size = 261837, upload-time = "2025-10-19T22:38:38.53Z" }, { url = "https://files.pythonhosted.org/packages/54/ea/682551030f8c4fa9a769d9825570ad28c0c71e30cf34020b85c1f7ee7382/fastuuid-0.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d23ef06f9e67163be38cece704170486715b177f6baae338110983f99a72c070", size = 251370, upload-time = "2025-10-19T22:40:26.07Z" }, @@ -2141,15 +1805,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a4/a5/842ae8f0c08b61d6484b52f99a03510a3a72d23141942d216ebe81fefbce/filelock-3.25.2-py3-none-any.whl", hash = "sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70", size = 26759, upload-time = "2026-03-11T20:45:37.437Z" }, ] -[[package]] -name = "filetype" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/29/745f7d30d47fe0f251d3ad3dc2978a23141917661998763bebb6da007eb1/filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb", size = 998020, upload-time = "2022-11-02T17:34:04.141Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/79/1b8fa1bb3568781e84c9200f951c735f3f157429f44be0495da55894d620/filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25", size = 19970, upload-time = "2022-11-02T17:34:01.425Z" }, -] - [[package]] name = "fla-core" version = "0.4.2" @@ -2176,30 +1831,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/60/ee/a3cba17965482b35c4990af90bad108e82c32edcb59911c37f318b5f4198/flash_linear_attention-0.4.2-py3-none-any.whl", hash = "sha256:c08be006ce4dbe1be81f54938ee8e6fc7968cfba397c8d06c7669e97b8c44c0d", size = 284661, upload-time = "2026-03-12T14:45:44.905Z" }, ] -[[package]] -name = "flashinfer-python" -version = "0.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "apache-tvm-ffi" }, - { name = "click" }, - { name = "einops" }, - { name = "ninja" }, - { name = "numpy" }, - { name = "nvidia-cudnn-frontend" }, - { name = "nvidia-cutlass-dsl" }, - { name = "nvidia-ml-py" }, - { name = "packaging" }, - { name = "requests" }, - { name = "tabulate" }, - { name = "torch" }, - { name = "tqdm" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/68/81/5a84e14df7358d2c2903b18c6f2779bd4b4a6739076d01a847d4c18fb102/flashinfer_python-0.6.1.tar.gz", hash = "sha256:8dc2fc5dc187fc70151d5f39ef560fde8a38117a4f6cf40dce0ddb09cbd4f0bf", size = 5141191, upload-time = "2026-01-14T05:40:27.825Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/d5/bca632bb5781689415186421bbee2ad39ae8a39b0996d579c76901e5c66f/flashinfer_python-0.6.1-py3-none-any.whl", hash = "sha256:610dd4ac15e7a0874b79e7577d027cb35133e8dc31dc3137c2f2d6497fe46f18", size = 7580432, upload-time = "2026-01-14T05:40:25.636Z" }, -] - [[package]] name = "flask" version = "3.1.3" @@ -2230,35 +1861,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4f/af/72ad54402e599152de6d067324c46fe6a4f531c7c65baf7e96c63db55eaf/flask_cors-6.0.2-py3-none-any.whl", hash = "sha256:e57544d415dfd7da89a9564e1e3a9e515042df76e12130641ca6f3f2f03b699a", size = 13257, upload-time = "2025-12-12T20:31:41.3Z" }, ] -[[package]] -name = "flask-restful" -version = "0.3.10" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aniso8601" }, - { name = "flask" }, - { name = "pytz" }, - { name = "six" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c0/ce/a0a133db616ea47f78a41e15c4c68b9f08cab3df31eb960f61899200a119/Flask-RESTful-0.3.10.tar.gz", hash = "sha256:fe4af2ef0027df8f9b4f797aba20c5566801b6ade995ac63b588abf1a59cec37", size = 110453, upload-time = "2023-05-21T03:58:55.781Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/7b/f0b45f0df7d2978e5ae51804bb5939b7897b2ace24306009da0cc34d8d1f/Flask_RESTful-0.3.10-py2.py3-none-any.whl", hash = "sha256:1cf93c535172f112e080b0d4503a8d15f93a48c88bdd36dd87269bdaf405051b", size = 26217, upload-time = "2023-05-21T03:58:54.004Z" }, -] - [[package]] name = "fonttools" version = "4.62.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9a/08/7012b00a9a5874311b639c3920270c36ee0c445b69d9989a85e5c92ebcb0/fonttools-4.62.1.tar.gz", hash = "sha256:e54c75fd6041f1122476776880f7c3c3295ffa31962dc6ebe2543c00dca58b5d", size = 3580737, upload-time = "2026-03-13T13:54:25.52Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:40975849bac44fb0b9253d77420c6d8b523ac4dcdcefeff6e4d706838a5b80f7", size = 2871039, upload-time = "2026-03-13T13:52:33.127Z" }, - { url = "https://files.pythonhosted.org/packages/24/7f/66d3f8a9338a9b67fe6e1739f47e1cd5cee78bd3bc1206ef9b0b982289a5/fonttools-4.62.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9dde91633f77fa576879a0c76b1d89de373cae751a98ddf0109d54e173b40f14", size = 2416346, upload-time = "2026-03-13T13:52:35.676Z" }, - { url = "https://files.pythonhosted.org/packages/aa/53/5276ceba7bff95da7793a07c5284e1da901cf00341ce5e2f3273056c0cca/fonttools-4.62.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6acb4109f8bee00fec985c8c7afb02299e35e9c94b57287f3ea542f28bd0b0a7", size = 5100897, upload-time = "2026-03-13T13:52:38.102Z" }, - { url = "https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1c5c25671ce8805e0d080e2ffdeca7f1e86778c5cbfbeae86d7f866d8830517b", size = 5071078, upload-time = "2026-03-13T13:52:41.305Z" }, - { url = "https://files.pythonhosted.org/packages/e3/be/d378fca4c65ea1956fee6d90ace6e861776809cbbc5af22388a090c3c092/fonttools-4.62.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a5d8825e1140f04e6c99bb7d37a9e31c172f3bc208afbe02175339e699c710e1", size = 5076908, upload-time = "2026-03-13T13:52:44.122Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d9/ae6a1d0693a4185a84605679c8a1f719a55df87b9c6e8e817bfdd9ef5936/fonttools-4.62.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:268abb1cb221e66c014acc234e872b7870d8b5d4657a83a8f4205094c32d2416", size = 5202275, upload-time = "2026-03-13T13:52:46.591Z" }, - { url = "https://files.pythonhosted.org/packages/54/6c/af95d9c4efb15cabff22642b608342f2bd67137eea6107202d91b5b03184/fonttools-4.62.1-cp311-cp311-win32.whl", hash = "sha256:942b03094d7edbb99bdf1ae7e9090898cad7bf9030b3d21f33d7072dbcb51a53", size = 2293075, upload-time = "2026-03-13T13:52:48.711Z" }, - { url = "https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:e8514f4924375f77084e81467e63238b095abda5107620f49421c368a6017ed2", size = 2344593, upload-time = "2026-03-13T13:52:50.725Z" }, { url = "https://files.pythonhosted.org/packages/47/d4/dbacced3953544b9a93088cc10ef2b596d348c983d5c67a404fa41ec51ba/fonttools-4.62.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:90365821debbd7db678809c7491ca4acd1e0779b9624cdc6ddaf1f31992bf974", size = 2870219, upload-time = "2026-03-13T13:52:53.664Z" }, { url = "https://files.pythonhosted.org/packages/66/9e/a769c8e99b81e5a87ab7e5e7236684de4e96246aae17274e5347d11ebd78/fonttools-4.62.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12859ff0b47dd20f110804c3e0d0970f7b832f561630cd879969011541a464a9", size = 2414891, upload-time = "2026-03-13T13:52:56.493Z" }, { url = "https://files.pythonhosted.org/packages/69/64/f19a9e3911968c37e1e620e14dfc5778299e1474f72f4e57c5ec771d9489/fonttools-4.62.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c125ffa00c3d9003cdaaf7f2c79e6e535628093e14b5de1dccb08859b680936", size = 5033197, upload-time = "2026-03-13T13:52:59.179Z" }, @@ -2300,22 +1908,6 @@ version = "1.8.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/03/077f869d540370db12165c0aa51640a873fb661d8b315d1d4d67b284d7ac/frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84", size = 86912, upload-time = "2025-10-06T05:35:45.98Z" }, - { url = "https://files.pythonhosted.org/packages/df/b5/7610b6bd13e4ae77b96ba85abea1c8cb249683217ef09ac9e0ae93f25a91/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9", size = 50046, upload-time = "2025-10-06T05:35:47.009Z" }, - { url = "https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93", size = 50119, upload-time = "2025-10-06T05:35:48.38Z" }, - { url = "https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f", size = 231067, upload-time = "2025-10-06T05:35:49.97Z" }, - { url = "https://files.pythonhosted.org/packages/45/7e/afe40eca3a2dc19b9904c0f5d7edfe82b5304cb831391edec0ac04af94c2/frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695", size = 233160, upload-time = "2025-10-06T05:35:51.729Z" }, - { url = "https://files.pythonhosted.org/packages/a6/aa/7416eac95603ce428679d273255ffc7c998d4132cfae200103f164b108aa/frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52", size = 228544, upload-time = "2025-10-06T05:35:53.246Z" }, - { url = "https://files.pythonhosted.org/packages/8b/3d/2a2d1f683d55ac7e3875e4263d28410063e738384d3adc294f5ff3d7105e/frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581", size = 243797, upload-time = "2025-10-06T05:35:54.497Z" }, - { url = "https://files.pythonhosted.org/packages/78/1e/2d5565b589e580c296d3bb54da08d206e797d941a83a6fdea42af23be79c/frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567", size = 247923, upload-time = "2025-10-06T05:35:55.861Z" }, - { url = "https://files.pythonhosted.org/packages/aa/c3/65872fcf1d326a7f101ad4d86285c403c87be7d832b7470b77f6d2ed5ddc/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b", size = 230886, upload-time = "2025-10-06T05:35:57.399Z" }, - { url = "https://files.pythonhosted.org/packages/a0/76/ac9ced601d62f6956f03cc794f9e04c81719509f85255abf96e2510f4265/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92", size = 245731, upload-time = "2025-10-06T05:35:58.563Z" }, - { url = "https://files.pythonhosted.org/packages/b9/49/ecccb5f2598daf0b4a1415497eba4c33c1e8ce07495eb07d2860c731b8d5/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d", size = 241544, upload-time = "2025-10-06T05:35:59.719Z" }, - { url = "https://files.pythonhosted.org/packages/53/4b/ddf24113323c0bbcc54cb38c8b8916f1da7165e07b8e24a717b4a12cbf10/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd", size = 241806, upload-time = "2025-10-06T05:36:00.959Z" }, - { url = "https://files.pythonhosted.org/packages/a7/fb/9b9a084d73c67175484ba2789a59f8eebebd0827d186a8102005ce41e1ba/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967", size = 229382, upload-time = "2025-10-06T05:36:02.22Z" }, - { url = "https://files.pythonhosted.org/packages/95/a3/c8fb25aac55bf5e12dae5c5aa6a98f85d436c1dc658f21c3ac73f9fa95e5/frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25", size = 39647, upload-time = "2025-10-06T05:36:03.409Z" }, - { url = "https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b", size = 44064, upload-time = "2025-10-06T05:36:04.368Z" }, - { url = "https://files.pythonhosted.org/packages/5d/16/c2c9ab44e181f043a86f9a8f84d5124b62dbcb3a02c0977ec72b9ac1d3e0/frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a", size = 39937, upload-time = "2025-10-06T05:36:05.669Z" }, { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, @@ -2543,11 +2135,6 @@ version = "1.8.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/03/41/4b9c02f99e4c5fb477122cd5437403b552873f014616ac1d19ac8221a58d/google_crc32c-1.8.0.tar.gz", hash = "sha256:a428e25fb7691024de47fecfbff7ff957214da51eddded0da0ae0e0f03a2cf79", size = 14192, upload-time = "2025-12-16T00:35:25.142Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/ef/21ccfaab3d5078d41efe8612e0ed0bfc9ce22475de074162a91a25f7980d/google_crc32c-1.8.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:014a7e68d623e9a4222d663931febc3033c5c7c9730785727de2a81f87d5bab8", size = 31298, upload-time = "2025-12-16T00:20:32.241Z" }, - { url = "https://files.pythonhosted.org/packages/c5/b8/f8413d3f4b676136e965e764ceedec904fe38ae8de0cdc52a12d8eb1096e/google_crc32c-1.8.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:86cfc00fe45a0ac7359e5214a1704e51a99e757d0272554874f419f79838c5f7", size = 30872, upload-time = "2025-12-16T00:33:58.785Z" }, - { url = "https://files.pythonhosted.org/packages/f6/fd/33aa4ec62b290477181c55bb1c9302c9698c58c0ce9a6ab4874abc8b0d60/google_crc32c-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:19b40d637a54cb71e0829179f6cb41835f0fbd9e8eb60552152a8b52c36cbe15", size = 33243, upload-time = "2025-12-16T00:40:21.46Z" }, - { url = "https://files.pythonhosted.org/packages/71/03/4820b3bd99c9653d1a5210cb32f9ba4da9681619b4d35b6a052432df4773/google_crc32c-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:17446feb05abddc187e5441a45971b8394ea4c1b6efd88ab0af393fd9e0a156a", size = 33608, upload-time = "2025-12-16T00:40:22.204Z" }, - { url = "https://files.pythonhosted.org/packages/7c/43/acf61476a11437bf9733fb2f70599b1ced11ec7ed9ea760fdd9a77d0c619/google_crc32c-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:71734788a88f551fbd6a97be9668a0020698e07b2bf5b3aa26a36c10cdfb27b2", size = 34439, upload-time = "2025-12-16T00:35:20.458Z" }, { url = "https://files.pythonhosted.org/packages/e9/5f/7307325b1198b59324c0fa9807cafb551afb65e831699f2ce211ad5c8240/google_crc32c-1.8.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:4b8286b659c1335172e39563ab0a768b8015e88e08329fa5321f774275fc3113", size = 31300, upload-time = "2025-12-16T00:21:56.723Z" }, { url = "https://files.pythonhosted.org/packages/21/8e/58c0d5d86e2220e6a37befe7e6a94dd2f6006044b1a33edf1ff6d9f7e319/google_crc32c-1.8.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:2a3dc3318507de089c5384cc74d54318401410f82aa65b2d9cdde9d297aca7cb", size = 30867, upload-time = "2025-12-16T00:38:31.302Z" }, { url = "https://files.pythonhosted.org/packages/ce/a9/a780cc66f86335a6019f557a8aaca8fbb970728f0efd2430d15ff1beae0e/google_crc32c-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14f87e04d613dfa218d6135e81b78272c3b904e2a7053b841481b38a7d901411", size = 33364, upload-time = "2025-12-16T00:40:22.96Z" }, @@ -2563,8 +2150,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/56/15/c25671c7aad70f8179d858c55a6ae8404902abe0cdcf32a29d581792b491/google_crc32c-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b0d1a7afc6e8e4635564ba8aa5c0548e3173e41b6384d7711a9123165f582de2", size = 33381, upload-time = "2025-12-16T00:40:26.268Z" }, { url = "https://files.pythonhosted.org/packages/42/fa/f50f51260d7b0ef5d4898af122d8a7ec5a84e2984f676f746445f783705f/google_crc32c-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8b3f68782f3cbd1bce027e48768293072813469af6a61a86f6bb4977a4380f21", size = 33734, upload-time = "2025-12-16T00:40:27.028Z" }, { url = "https://files.pythonhosted.org/packages/08/a5/7b059810934a09fb3ccb657e0843813c1fee1183d3bc2c8041800374aa2c/google_crc32c-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:d511b3153e7011a27ab6ee6bb3a5404a55b994dc1a7322c0b87b29606d9790e2", size = 34878, upload-time = "2025-12-16T00:35:23.142Z" }, - { url = "https://files.pythonhosted.org/packages/52/c5/c171e4d8c44fec1422d801a6d2e5d7ddabd733eeda505c79730ee9607f07/google_crc32c-1.8.0-pp311-pypy311_pp73-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:87fa445064e7db928226b2e6f0d5304ab4cd0339e664a4e9a25029f384d9bb93", size = 28615, upload-time = "2025-12-16T00:40:29.298Z" }, - { url = "https://files.pythonhosted.org/packages/9c/97/7d75fe37a7a6ed171a2cf17117177e7aab7e6e0d115858741b41e9dd4254/google_crc32c-1.8.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f639065ea2042d5c034bf258a9f085eaa7af0cd250667c0635a3118e8f92c69c", size = 28800, upload-time = "2025-12-16T00:40:30.322Z" }, ] [[package]] @@ -2662,15 +2247,6 @@ version = "3.3.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a3/51/1664f6b78fc6ebbd98019a1fd730e83fa78f2db7058f72b1463d3612b8db/greenlet-3.3.2.tar.gz", hash = "sha256:2eaf067fc6d886931c7962e8c6bede15d2f01965560f3359b27c80bde2d151f2", size = 188267, upload-time = "2026-02-20T20:54:15.531Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/47/16400cb42d18d7a6bb46f0626852c1718612e35dcb0dffa16bbaffdf5dd2/greenlet-3.3.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:c56692189a7d1c7606cb794be0a8381470d95c57ce5be03fb3d0ef57c7853b86", size = 278890, upload-time = "2026-02-20T20:19:39.263Z" }, - { url = "https://files.pythonhosted.org/packages/a3/90/42762b77a5b6aa96cd8c0e80612663d39211e8ae8a6cd47c7f1249a66262/greenlet-3.3.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ebd458fa8285960f382841da585e02201b53a5ec2bac6b156fc623b5ce4499f", size = 581120, upload-time = "2026-02-20T20:47:30.161Z" }, - { url = "https://files.pythonhosted.org/packages/bf/6f/f3d64f4fa0a9c7b5c5b3c810ff1df614540d5aa7d519261b53fba55d4df9/greenlet-3.3.2-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a443358b33c4ec7b05b79a7c8b466f5d275025e750298be7340f8fc63dff2a55", size = 594363, upload-time = "2026-02-20T20:55:56.965Z" }, - { url = "https://files.pythonhosted.org/packages/9c/8b/1430a04657735a3f23116c2e0d5eb10220928846e4537a938a41b350bed6/greenlet-3.3.2-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4375a58e49522698d3e70cc0b801c19433021b5c37686f7ce9c65b0d5c8677d2", size = 605046, upload-time = "2026-02-20T21:02:45.234Z" }, - { url = "https://files.pythonhosted.org/packages/72/83/3e06a52aca8128bdd4dcd67e932b809e76a96ab8c232a8b025b2850264c5/greenlet-3.3.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e2cd90d413acbf5e77ae41e5d3c9b3ac1d011a756d7284d7f3f2b806bbd6358", size = 594156, upload-time = "2026-02-20T20:20:59.955Z" }, - { url = "https://files.pythonhosted.org/packages/70/79/0de5e62b873e08fe3cef7dbe84e5c4bc0e8ed0c7ff131bccb8405cd107c8/greenlet-3.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:442b6057453c8cb29b4fb36a2ac689382fc71112273726e2423f7f17dc73bf99", size = 1554649, upload-time = "2026-02-20T20:49:32.293Z" }, - { url = "https://files.pythonhosted.org/packages/5a/00/32d30dee8389dc36d42170a9c66217757289e2afb0de59a3565260f38373/greenlet-3.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:45abe8eb6339518180d5a7fa47fa01945414d7cca5ecb745346fc6a87d2750be", size = 1619472, upload-time = "2026-02-20T20:21:07.966Z" }, - { url = "https://files.pythonhosted.org/packages/f1/3a/efb2cf697fbccdf75b24e2c18025e7dfa54c4f31fab75c51d0fe79942cef/greenlet-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e692b2dae4cc7077cbb11b47d258533b48c8fde69a33d0d8a82e2fe8d8531d5", size = 230389, upload-time = "2026-02-20T20:17:18.772Z" }, - { url = "https://files.pythonhosted.org/packages/e1/a1/65bbc059a43a7e2143ec4fc1f9e3f673e04f9c7b371a494a101422ac4fd5/greenlet-3.3.2-cp311-cp311-win_arm64.whl", hash = "sha256:02b0a8682aecd4d3c6c18edf52bc8e51eacdd75c8eac52a790a210b06aa295fd", size = 229645, upload-time = "2026-02-20T20:18:18.695Z" }, { url = "https://files.pythonhosted.org/packages/ea/ab/1608e5a7578e62113506740b88066bf09888322a311cff602105e619bd87/greenlet-3.3.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:ac8d61d4343b799d1e526db579833d72f23759c71e07181c2d2944e429eb09cd", size = 280358, upload-time = "2026-02-20T20:17:43.971Z" }, { url = "https://files.pythonhosted.org/packages/a5/23/0eae412a4ade4e6623ff7626e38998cb9b11e9ff1ebacaa021e4e108ec15/greenlet-3.3.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ceec72030dae6ac0c8ed7591b96b70410a8be370b6a477b1dbc072856ad02bd", size = 601217, upload-time = "2026-02-20T20:47:31.462Z" }, { url = "https://files.pythonhosted.org/packages/f8/16/5b1678a9c07098ecb9ab2dd159fafaf12e963293e61ee8d10ecb55273e5e/greenlet-3.3.2-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2a5be83a45ce6188c045bcc44b0ee037d6a518978de9a5d97438548b953a1ac", size = 611792, upload-time = "2026-02-20T20:55:58.423Z" }, @@ -2717,16 +2293,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/06/8a/3d098f35c143a89520e568e6539cc098fcd294495910e359889ce8741c84/grpcio-1.78.0.tar.gz", hash = "sha256:7382b95189546f375c174f53a5fa873cef91c4b8005faa05cc5b3beea9c4f1c5", size = 12852416, upload-time = "2026-02-06T09:57:18.093Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/86/c7/d0b780a29b0837bf4ca9580904dfb275c1fc321ded7897d620af7047ec57/grpcio-1.78.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:2777b783f6c13b92bd7b716667452c329eefd646bfb3f2e9dabea2e05dbd34f6", size = 5951525, upload-time = "2026-02-06T09:55:01.989Z" }, - { url = "https://files.pythonhosted.org/packages/c5/b1/96920bf2ee61df85a9503cb6f733fe711c0ff321a5a697d791b075673281/grpcio-1.78.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:9dca934f24c732750389ce49d638069c3892ad065df86cb465b3fa3012b70c9e", size = 11830418, upload-time = "2026-02-06T09:55:04.462Z" }, - { url = "https://files.pythonhosted.org/packages/83/0c/7c1528f098aeb75a97de2bae18c530f56959fb7ad6c882db45d9884d6edc/grpcio-1.78.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:459ab414b35f4496138d0ecd735fed26f1318af5e52cb1efbc82a09f0d5aa911", size = 6524477, upload-time = "2026-02-06T09:55:07.111Z" }, - { url = "https://files.pythonhosted.org/packages/8d/52/e7c1f3688f949058e19a011c4e0dec973da3d0ae5e033909677f967ae1f4/grpcio-1.78.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:082653eecbdf290e6e3e2c276ab2c54b9e7c299e07f4221872380312d8cf395e", size = 7198266, upload-time = "2026-02-06T09:55:10.016Z" }, - { url = "https://files.pythonhosted.org/packages/e5/61/8ac32517c1e856677282c34f2e7812d6c328fa02b8f4067ab80e77fdc9c9/grpcio-1.78.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85f93781028ec63f383f6bc90db785a016319c561cc11151fbb7b34e0d012303", size = 6730552, upload-time = "2026-02-06T09:55:12.207Z" }, - { url = "https://files.pythonhosted.org/packages/bd/98/b8ee0158199250220734f620b12e4a345955ac7329cfd908d0bf0fda77f0/grpcio-1.78.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f12857d24d98441af6a1d5c87442d624411db486f7ba12550b07788f74b67b04", size = 7304296, upload-time = "2026-02-06T09:55:15.044Z" }, - { url = "https://files.pythonhosted.org/packages/bd/0f/7b72762e0d8840b58032a56fdbd02b78fc645b9fa993d71abf04edbc54f4/grpcio-1.78.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5397fff416b79e4b284959642a4e95ac4b0f1ece82c9993658e0e477d40551ec", size = 8288298, upload-time = "2026-02-06T09:55:17.276Z" }, - { url = "https://files.pythonhosted.org/packages/24/ae/ae4ce56bc5bb5caa3a486d60f5f6083ac3469228faa734362487176c15c5/grpcio-1.78.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fbe6e89c7ffb48518384068321621b2a69cab509f58e40e4399fdd378fa6d074", size = 7730953, upload-time = "2026-02-06T09:55:19.545Z" }, - { url = "https://files.pythonhosted.org/packages/b5/6e/8052e3a28eb6a820c372b2eb4b5e32d195c661e137d3eca94d534a4cfd8a/grpcio-1.78.0-cp311-cp311-win32.whl", hash = "sha256:6092beabe1966a3229f599d7088b38dfc8ffa1608b5b5cdda31e591e6500f856", size = 4076503, upload-time = "2026-02-06T09:55:21.521Z" }, - { url = "https://files.pythonhosted.org/packages/08/62/f22c98c5265dfad327251fa2f840b591b1df5f5e15d88b19c18c86965b27/grpcio-1.78.0-cp311-cp311-win_amd64.whl", hash = "sha256:1afa62af6e23f88629f2b29ec9e52ec7c65a7176c1e0a83292b93c76ca882558", size = 4799767, upload-time = "2026-02-06T09:55:24.107Z" }, { url = "https://files.pythonhosted.org/packages/4e/f4/7384ed0178203d6074446b3c4f46c90a22ddf7ae0b3aee521627f54cfc2a/grpcio-1.78.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:f9ab915a267fc47c7e88c387a3a28325b58c898e23d4995f765728f4e3dedb97", size = 5913985, upload-time = "2026-02-06T09:55:26.832Z" }, { url = "https://files.pythonhosted.org/packages/81/ed/be1caa25f06594463f685b3790b320f18aea49b33166f4141bfdc2bfb236/grpcio-1.78.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3f8904a8165ab21e07e58bf3e30a73f4dffc7a1e0dbc32d51c61b5360d26f43e", size = 11811853, upload-time = "2026-02-06T09:55:29.224Z" }, { url = "https://files.pythonhosted.org/packages/24/a7/f06d151afc4e64b7e3cc3e872d331d011c279aaab02831e40a81c691fb65/grpcio-1.78.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:859b13906ce098c0b493af92142ad051bf64c7870fa58a123911c88606714996", size = 6475766, upload-time = "2026-02-06T09:55:31.825Z" }, @@ -2764,7 +2330,7 @@ name = "gunicorn" version = "25.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "packaging", marker = "sys_platform != 'win32'" }, + { name = "packaging" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/13/ef67f59f6a7896fdc2c1d62b5665c5219d6b0a9a1784938eb9a28e55e128/gunicorn-25.1.0.tar.gz", hash = "sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616", size = 594377, upload-time = "2026-02-13T11:09:58.989Z" } wheels = [ @@ -2941,13 +2507,6 @@ version = "0.7.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961, upload-time = "2025-10-10T03:55:08.559Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/08/17e07e8d89ab8f343c134616d72eebfe03798835058e2ab579dcc8353c06/httptools-0.7.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657", size = 206521, upload-time = "2025-10-10T03:54:31.002Z" }, - { url = "https://files.pythonhosted.org/packages/aa/06/c9c1b41ff52f16aee526fd10fbda99fa4787938aa776858ddc4a1ea825ec/httptools-0.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70", size = 110375, upload-time = "2025-10-10T03:54:31.941Z" }, - { url = "https://files.pythonhosted.org/packages/cc/cc/10935db22fda0ee34c76f047590ca0a8bd9de531406a3ccb10a90e12ea21/httptools-0.7.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df", size = 456621, upload-time = "2025-10-10T03:54:33.176Z" }, - { url = "https://files.pythonhosted.org/packages/0e/84/875382b10d271b0c11aa5d414b44f92f8dd53e9b658aec338a79164fa548/httptools-0.7.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e", size = 454954, upload-time = "2025-10-10T03:54:34.226Z" }, - { url = "https://files.pythonhosted.org/packages/30/e1/44f89b280f7e46c0b1b2ccee5737d46b3bb13136383958f20b580a821ca0/httptools-0.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274", size = 440175, upload-time = "2025-10-10T03:54:35.942Z" }, - { url = "https://files.pythonhosted.org/packages/6f/7e/b9287763159e700e335028bc1824359dc736fa9b829dacedace91a39b37e/httptools-0.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec", size = 440310, upload-time = "2025-10-10T03:54:37.1Z" }, - { url = "https://files.pythonhosted.org/packages/b3/07/5b614f592868e07f5c94b1f301b5e14a21df4e8076215a3bccb830a687d8/httptools-0.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb", size = 86875, upload-time = "2025-10-10T03:54:38.421Z" }, { url = "https://files.pythonhosted.org/packages/53/7f/403e5d787dc4942316e515e949b0c8a013d84078a915910e9f391ba9b3ed/httptools-0.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5", size = 206280, upload-time = "2025-10-10T03:54:39.274Z" }, { url = "https://files.pythonhosted.org/packages/2a/0d/7f3fd28e2ce311ccc998c388dd1c53b18120fda3b70ebb022b135dc9839b/httptools-0.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5", size = 110004, upload-time = "2025-10-10T03:54:40.403Z" }, { url = "https://files.pythonhosted.org/packages/84/a6/b3965e1e146ef5762870bbe76117876ceba51a201e18cc31f5703e454596/httptools-0.7.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03", size = 517655, upload-time = "2025-10-10T03:54:41.347Z" }, @@ -2991,19 +2550,6 @@ http2 = [ { name = "h2" }, ] -[[package]] -name = "httpx-aiohttp" -version = "0.1.12" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "httpx" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/63/2c/b894861cecf030fb45675ea24aa55b5722e97c602a163d872fca66c5a6d8/httpx_aiohttp-0.1.12.tar.gz", hash = "sha256:81feec51fd82c0ecfa0e9aaf1b1a6c2591260d5e2bcbeb7eb0277a78e610df2c", size = 275945, upload-time = "2025-12-12T10:12:15.283Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/16/8d/85c9701e9af72ca132a1783e2a54364a90c6da832304416a30fc11196ab2/httpx_aiohttp-0.1.12-py3-none-any.whl", hash = "sha256:5b0eac39a7f360fa7867a60bcb46bb1024eada9c01cbfecdb54dc1edb3fb7141", size = 6367, upload-time = "2025-12-12T10:12:14.018Z" }, -] - [[package]] name = "huey" version = "2.6.0" @@ -3047,21 +2593,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c6/50/e0edd38dcd63fb26a8547f13d28f7a008bc4a3fd4eb4ff030673f22ad41a/hydra_core-1.3.2-py3-none-any.whl", hash = "sha256:fa0238a9e31df3373b35b0bfb672c34cc92718d21f81311d8996a16de1141d8b", size = 154547, upload-time = "2023-02-23T18:33:40.801Z" }, ] -[[package]] -name = "hypercorn" -version = "0.18.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "h11" }, - { name = "h2" }, - { name = "priority" }, - { name = "wsproto" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/44/01/39f41a014b83dd5c795217362f2ca9071cf243e6a75bdcd6cd5b944658cc/hypercorn-0.18.0.tar.gz", hash = "sha256:d63267548939c46b0247dc8e5b45a9947590e35e64ee73a23c074aa3cf88e9da", size = 68420, upload-time = "2025-11-08T13:54:04.78Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/93/35/850277d1b17b206bd10874c8a9a3f52e059452fb49bb0d22cbb908f6038b/hypercorn-0.18.0-py3-none-any.whl", hash = "sha256:225e268f2c1c2f28f6d8f6db8f40cb8c992963610c5725e13ccfcddccb24b1cd", size = 61640, upload-time = "2025-11-08T13:54:03.202Z" }, -] - [[package]] name = "hyperframe" version = "6.1.0" @@ -3098,17 +2629,6 @@ version = "3.5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f4/57/60d1a6a512f2f0508d0bc8b4f1cc5616fd3196619b66bd6a01f9155a1292/ijson-3.5.0.tar.gz", hash = "sha256:94688760720e3f5212731b3cb8d30267f9a045fb38fb3870254e7b9504246f31", size = 68658, upload-time = "2026-02-24T03:58:30.974Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/65/da/644343198abca5e0f6e2486063f8d8f3c443ca0ef5e5c890e51ef6032e33/ijson-3.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5616311404b858d32740b7ad8b9a799c62165f5ecb85d0a8ed16c21665a90533", size = 88964, upload-time = "2026-02-24T03:56:53.099Z" }, - { url = "https://files.pythonhosted.org/packages/5b/63/8621190aa2baf96156dfd4c632b6aa9f1464411e50b98750c09acc0505ea/ijson-3.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e9733f94029dd41702d573ef64752e2556e72aea14623d6dbb7a44ca1ccf30fd", size = 60582, upload-time = "2026-02-24T03:56:54.261Z" }, - { url = "https://files.pythonhosted.org/packages/20/31/6a3f041fdd17dacff33b7d7d3ba3df6dca48740108340c6042f974b2ad20/ijson-3.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db8398c6721b98412a4f618da8022550c8b9c5d9214040646071b5deb4d4a393", size = 60632, upload-time = "2026-02-24T03:56:55.159Z" }, - { url = "https://files.pythonhosted.org/packages/e4/68/474541998abbdecfd46a744536878335de89aceb9f085bff1aaf35575ceb/ijson-3.5.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c061314845c08163b1784b6076ea5f075372461a32e6916f4e5f211fd4130b64", size = 131988, upload-time = "2026-02-24T03:56:56.35Z" }, - { url = "https://files.pythonhosted.org/packages/cd/32/e05ff8b72a44fe9d192f41c5dcbc35cfa87efc280cdbfe539ffaf4a7535e/ijson-3.5.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1111a1c5ac79119c5d6e836f900c1a53844b50a18af38311baa6bb61e2645aca", size = 138669, upload-time = "2026-02-24T03:56:57.555Z" }, - { url = "https://files.pythonhosted.org/packages/49/b5/955a83b031102c7a602e2c06d03aff0a0e584212f09edb94ccc754d203ac/ijson-3.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1e74aff8c681c24002b61b1822f9511d4c384f324f7dbc08c78538e01fdc9fcb", size = 135093, upload-time = "2026-02-24T03:56:59.267Z" }, - { url = "https://files.pythonhosted.org/packages/e8/f2/30250cfcb4d2766669b31f6732689aab2bb91de426a15a3ebe482df7ee48/ijson-3.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:739a7229b1b0cc5f7e2785a6e7a5fc915e850d3fed9588d0e89a09f88a417253", size = 138715, upload-time = "2026-02-24T03:57:00.491Z" }, - { url = "https://files.pythonhosted.org/packages/a2/05/785a145d7e75e04e04480d59b6323cd4b1d9013a6cd8643fa635fbc93490/ijson-3.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ef88712160360cab3ca6471a4e5418243f8b267cf1fe1620879d1b5558babc71", size = 133194, upload-time = "2026-02-24T03:57:01.759Z" }, - { url = "https://files.pythonhosted.org/packages/14/eb/80d6f8a748dead4034cea0939494a67d10ccf88d6413bf6e860393139676/ijson-3.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6ca0d1b6b5f8166a6248f4309497585fb8553b04bc8179a0260fad636cfdb798", size = 135588, upload-time = "2026-02-24T03:57:03.131Z" }, - { url = "https://files.pythonhosted.org/packages/ee/a8/bbc21f9400ebdbca48fab272593e0d1f875691be1e927d264d90d48b8c47/ijson-3.5.0-cp311-cp311-win32.whl", hash = "sha256:966039cf9047c7967febf7b9a52ec6f38f5464a4c7fbb5565e0224b7376fefff", size = 52721, upload-time = "2026-02-24T03:57:04.365Z" }, - { url = "https://files.pythonhosted.org/packages/0d/2e/4e8c0208b8f920ee80c88c956f93e78318f2cfb646455353b182738b490c/ijson-3.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:6bad6a1634cb7c9f3f4c7e52325283b35b565f5b6cc27d42660c6912ce883422", size = 55121, upload-time = "2026-02-24T03:57:05.498Z" }, { url = "https://files.pythonhosted.org/packages/aa/17/9c63c7688025f3a8c47ea717b8306649c8c7244e49e20a2be4e3515dc75c/ijson-3.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ebefbe149a6106cc848a3eaf536af51a9b5ccc9082de801389f152dba6ab755", size = 88536, upload-time = "2026-02-24T03:57:06.809Z" }, { url = "https://files.pythonhosted.org/packages/6f/dd/e15c2400244c117b06585452ebc63ae254f5a6964f712306afd1422daae0/ijson-3.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:19e30d9f00f82e64de689c0b8651b9cfed879c184b139d7e1ea5030cec401c21", size = 60499, upload-time = "2026-02-24T03:57:09.155Z" }, { url = "https://files.pythonhosted.org/packages/77/a9/bf4fe3538a0c965f16b406f180a06105b875da83f0743e36246be64ef550/ijson-3.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a04a33ee78a6f27b9b8528c1ca3c207b1df3b8b867a4cf2fcc4109986f35c227", size = 60330, upload-time = "2026-02-24T03:57:10.574Z" }, @@ -3164,12 +2684,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6d/5e/e06c2de3c3d4a9cfb655c1ad08a68fb72838d271072cdd3196576ac4431a/ijson-3.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c21bfb61f71f191565885bf1bc29e0a186292d866b4880637b833848360bdc1b", size = 205495, upload-time = "2026-02-24T03:58:09.163Z" }, { url = "https://files.pythonhosted.org/packages/7c/11/778201eb2e202ddd76b36b0fb29bf3d8e3c167389d8aa883c62524e49f47/ijson-3.5.0-cp314-cp314t-win32.whl", hash = "sha256:a2619460d6795b70d0155e5bf016200ac8a63ab5397aa33588bb02b6c21759e6", size = 56280, upload-time = "2026-02-24T03:58:10.116Z" }, { url = "https://files.pythonhosted.org/packages/23/28/96711503245339084c8086b892c47415895eba49782d6cc52d9f4ee50301/ijson-3.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4f24b78d4ef028d17eb57ad1b16c0aed4a17bdd9badbf232dc5d9305b7e13854", size = 58965, upload-time = "2026-02-24T03:58:11.278Z" }, - { url = "https://files.pythonhosted.org/packages/d9/3b/d31ecfa63a218978617446159f3d77aab2417a5bd2885c425b176353ff78/ijson-3.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d64c624da0e9d692d6eb0ff63a79656b59d76bf80773a17c5b0f835e4e8ef627", size = 57715, upload-time = "2026-02-24T03:58:24.545Z" }, - { url = "https://files.pythonhosted.org/packages/30/51/b170e646d378e8cccf9637c05edb5419b00c2c4df64b0258c3af5355608e/ijson-3.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:876f7df73b7e0d6474f9caa729b9cdbfc8e76de9075a4887dfd689e29e85c4ca", size = 57205, upload-time = "2026-02-24T03:58:25.681Z" }, - { url = "https://files.pythonhosted.org/packages/ef/83/44dbd0231b0a8c6c14d27473d10c4e27dfbce7d5d9a833c79e3e6c33eb40/ijson-3.5.0-pp311-pypy311_pp73-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e7dbff2c8d9027809b0cde663df44f3210da10ea377121d42896fb6ee405dd31", size = 71229, upload-time = "2026-02-24T03:58:27.103Z" }, - { url = "https://files.pythonhosted.org/packages/c8/98/cf84048b7c6cec888826e696a31f45bee7ebcac15e532b6be1fc4c2c9608/ijson-3.5.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4217a1edc278660679e1197c83a1a2a2d367792bfbb2a3279577f4b59b93730d", size = 71217, upload-time = "2026-02-24T03:58:28.021Z" }, - { url = "https://files.pythonhosted.org/packages/3c/0a/e34c729a87ff67dc6540f6bcc896626158e691d433ab57db0086d73decd2/ijson-3.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:04f0fc740311388ee745ba55a12292b722d6f52000b11acbb913982ba5fbdf87", size = 68618, upload-time = "2026-02-24T03:58:28.918Z" }, - { url = "https://files.pythonhosted.org/packages/c1/0f/e849d072f2e0afe49627de3995fc9dae54b4c804c70c0840f928d95c10e1/ijson-3.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fdeee6957f92e0c114f65c55cf8fe7eabb80cfacab64eea6864060913173f66d", size = 55369, upload-time = "2026-02-24T03:58:29.839Z" }, ] [[package]] @@ -3262,8 +2776,7 @@ dependencies = [ { name = "appnope", marker = "sys_platform == 'darwin'" }, { name = "comm" }, { name = "debugpy" }, - { name = "ipython", version = "9.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "ipython", version = "9.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "ipython" }, { name = "jupyter-client" }, { name = "jupyter-core" }, { name = "matplotlib-inline" }, @@ -3279,63 +2792,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl", hash = "sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661", size = 118788, upload-time = "2026-02-06T16:43:25.149Z" }, ] -[[package]] -name = "ipython" -version = "9.10.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.12' and sys_platform == 'linux'", - "python_full_version < '3.12' and sys_platform == 'win32'", - "python_full_version < '3.12' and sys_platform == 'emscripten'", - "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32'", -] -dependencies = [ - { name = "colorama", marker = "python_full_version < '3.12' and sys_platform == 'win32'" }, - { name = "decorator", marker = "python_full_version < '3.12'" }, - { name = "ipython-pygments-lexers", marker = "python_full_version < '3.12'" }, - { name = "jedi", marker = "python_full_version < '3.12'" }, - { name = "matplotlib-inline", marker = "python_full_version < '3.12'" }, - { name = "pexpect", marker = "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit", marker = "python_full_version < '3.12'" }, - { name = "pygments", marker = "python_full_version < '3.12'" }, - { name = "stack-data", marker = "python_full_version < '3.12'" }, - { name = "traitlets", marker = "python_full_version < '3.12'" }, - { name = "typing-extensions", marker = "python_full_version < '3.12'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a6/60/2111715ea11f39b1535bed6024b7dec7918b71e5e5d30855a5b503056b50/ipython-9.10.0.tar.gz", hash = "sha256:cd9e656be97618a0676d058134cd44e6dc7012c0e5cb36a9ce96a8c904adaf77", size = 4426526, upload-time = "2026-02-02T10:00:33.594Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl", hash = "sha256:c6ab68cc23bba8c7e18e9b932797014cc61ea7fd6f19de180ab9ba73e65ee58d", size = 622774, upload-time = "2026-02-02T10:00:31.503Z" }, -] - [[package]] name = "ipython" version = "9.11.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'linux'", - "python_full_version == '3.13.*' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and sys_platform == 'linux'", - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32'", -] -dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" }, - { name = "decorator", marker = "python_full_version >= '3.12'" }, - { name = "ipython-pygments-lexers", marker = "python_full_version >= '3.12'" }, - { name = "jedi", marker = "python_full_version >= '3.12'" }, - { name = "matplotlib-inline", marker = "python_full_version >= '3.12'" }, - { name = "pexpect", marker = "python_full_version >= '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit", marker = "python_full_version >= '3.12'" }, - { name = "pygments", marker = "python_full_version >= '3.12'" }, - { name = "stack-data", marker = "python_full_version >= '3.12'" }, - { name = "traitlets", marker = "python_full_version >= '3.12'" }, +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, ] sdist = { url = "https://files.pythonhosted.org/packages/86/28/a4698eda5a8928a45d6b693578b135b753e14fa1c2b36ee9441e69a45576/ipython-9.11.0.tar.gz", hash = "sha256:2a94bc4406b22ecc7e4cb95b98450f3ea493a76bec8896cda11b78d7752a6667", size = 4427354, upload-time = "2026-03-05T08:57:30.549Z" } wheels = [ @@ -3360,8 +2831,7 @@ version = "8.1.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "comm" }, - { name = "ipython", version = "9.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "ipython", version = "9.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "ipython" }, { name = "jupyterlab-widgets" }, { name = "traitlets" }, { name = "widgetsnbextension" }, @@ -3405,9 +2875,6 @@ wheels = [ name = "jaraco-context" version = "6.1.2" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "backports-tarfile", marker = "python_full_version < '3.12'" }, -] sdist = { url = "https://files.pythonhosted.org/packages/af/50/4763cd07e722bb6285316d390a164bc7e479db9d90daa769f22578f698b4/jaraco_context-6.1.2.tar.gz", hash = "sha256:f1a6c9d391e661cc5b8d39861ff077a7dc24dc23833ccee564b234b81c82dfe3", size = 16801, upload-time = "2026-03-20T22:13:33.922Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl", hash = "sha256:bf8150b79a2d5d91ae48629d8b427a8f7ba0e1097dd6202a9059f29a36379535", size = 7871, upload-time = "2026-03-20T22:13:32.808Z" }, @@ -3464,19 +2931,6 @@ version = "0.13.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/0d/5e/4ec91646aee381d01cdb9974e30882c9cd3b8c5d1079d6b5ff4af522439a/jiter-0.13.0.tar.gz", hash = "sha256:f2839f9c2c7e2dffc1bc5929a510e14ce0a946be9365fd1219e7ef342dae14f4", size = 164847, upload-time = "2026-02-02T12:37:56.441Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/29/499f8c9eaa8a16751b1c0e45e6f5f1761d180da873d417996cc7bddc8eef/jiter-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ea026e70a9a28ebbdddcbcf0f1323128a8db66898a06eaad3a4e62d2f554d096", size = 311157, upload-time = "2026-02-02T12:35:37.758Z" }, - { url = "https://files.pythonhosted.org/packages/50/f6/566364c777d2ab450b92100bea11333c64c38d32caf8dc378b48e5b20c46/jiter-0.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66aa3e663840152d18cc8ff1e4faad3dd181373491b9cfdc6004b92198d67911", size = 319729, upload-time = "2026-02-02T12:35:39.246Z" }, - { url = "https://files.pythonhosted.org/packages/73/dd/560f13ec5e4f116d8ad2658781646cca91b617ae3b8758d4a5076b278f70/jiter-0.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3524798e70655ff19aec58c7d05adb1f074fecff62da857ea9be2b908b6d701", size = 354766, upload-time = "2026-02-02T12:35:40.662Z" }, - { url = "https://files.pythonhosted.org/packages/7c/0d/061faffcfe94608cbc28a0d42a77a74222bdf5055ccdbe5fd2292b94f510/jiter-0.13.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ec7e287d7fbd02cb6e22f9a00dd9c9cd504c40a61f2c61e7e1f9690a82726b4c", size = 362587, upload-time = "2026-02-02T12:35:42.025Z" }, - { url = "https://files.pythonhosted.org/packages/92/c9/c66a7864982fd38a9773ec6e932e0398d1262677b8c60faecd02ffb67bf3/jiter-0.13.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47455245307e4debf2ce6c6e65a717550a0244231240dcf3b8f7d64e4c2f22f4", size = 487537, upload-time = "2026-02-02T12:35:43.459Z" }, - { url = "https://files.pythonhosted.org/packages/6c/86/84eb4352cd3668f16d1a88929b5888a3fe0418ea8c1dfc2ad4e7bf6e069a/jiter-0.13.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ee9da221dca6e0429c2704c1b3655fe7b025204a71d4d9b73390c759d776d165", size = 373717, upload-time = "2026-02-02T12:35:44.928Z" }, - { url = "https://files.pythonhosted.org/packages/6e/09/9fe4c159358176f82d4390407a03f506a8659ed13ca3ac93a843402acecf/jiter-0.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24ab43126d5e05f3d53a36a8e11eb2f23304c6c1117844aaaf9a0aa5e40b5018", size = 362683, upload-time = "2026-02-02T12:35:46.636Z" }, - { url = "https://files.pythonhosted.org/packages/c9/5e/85f3ab9caca0c1d0897937d378b4a515cae9e119730563572361ea0c48ae/jiter-0.13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9da38b4fedde4fb528c740c2564628fbab737166a0e73d6d46cb4bb5463ff411", size = 392345, upload-time = "2026-02-02T12:35:48.088Z" }, - { url = "https://files.pythonhosted.org/packages/12/4c/05b8629ad546191939e6f0c2f17e29f542a398f4a52fb987bc70b6d1eb8b/jiter-0.13.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0b34c519e17658ed88d5047999a93547f8889f3c1824120c26ad6be5f27b6cf5", size = 517775, upload-time = "2026-02-02T12:35:49.482Z" }, - { url = "https://files.pythonhosted.org/packages/4d/88/367ea2eb6bc582c7052e4baf5ddf57ebe5ab924a88e0e09830dfb585c02d/jiter-0.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2a6394e6af690d462310a86b53c47ad75ac8c21dc79f120714ea449979cb1d3", size = 551325, upload-time = "2026-02-02T12:35:51.104Z" }, - { url = "https://files.pythonhosted.org/packages/f3/12/fa377ffb94a2f28c41afaed093e0d70cfe512035d5ecb0cad0ae4792d35e/jiter-0.13.0-cp311-cp311-win32.whl", hash = "sha256:0f0c065695f616a27c920a56ad0d4fc46415ef8b806bf8fc1cacf25002bd24e1", size = 204709, upload-time = "2026-02-02T12:35:52.467Z" }, - { url = "https://files.pythonhosted.org/packages/cb/16/8e8203ce92f844dfcd3d9d6a5a7322c77077248dbb12da52d23193a839cd/jiter-0.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:0733312953b909688ae3c2d58d043aa040f9f1a6a75693defed7bc2cc4bf2654", size = 204560, upload-time = "2026-02-02T12:35:53.925Z" }, - { url = "https://files.pythonhosted.org/packages/44/26/97cc40663deb17b9e13c3a5cf29251788c271b18ee4d262c8f94798b8336/jiter-0.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:5d9b34ad56761b3bf0fbe8f7e55468704107608512350962d3317ffd7a4382d5", size = 189608, upload-time = "2026-02-02T12:35:55.304Z" }, { url = "https://files.pythonhosted.org/packages/2e/30/7687e4f87086829955013ca12a9233523349767f69653ebc27036313def9/jiter-0.13.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0a2bd69fc1d902e89925fc34d1da51b2128019423d7b339a45d9e99c894e0663", size = 307958, upload-time = "2026-02-02T12:35:57.165Z" }, { url = "https://files.pythonhosted.org/packages/c3/27/e57f9a783246ed95481e6749cc5002a8a767a73177a83c63ea71f0528b90/jiter-0.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f917a04240ef31898182f76a332f508f2cc4b57d2b4d7ad2dbfebbfe167eb505", size = 318597, upload-time = "2026-02-02T12:35:58.591Z" }, { url = "https://files.pythonhosted.org/packages/cf/52/e5719a60ac5d4d7c5995461a94ad5ef962a37c8bf5b088390e6fad59b2ff/jiter-0.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1e2b199f446d3e82246b4fd9236d7cb502dc2222b18698ba0d986d2fecc6152", size = 348821, upload-time = "2026-02-02T12:36:00.093Z" }, @@ -3533,10 +2987,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/47/66/eea81dfff765ed66c68fd2ed8c96245109e13c896c2a5015c7839c92367e/jiter-0.13.0-cp314-cp314t-win32.whl", hash = "sha256:24dc96eca9f84da4131cdf87a95e6ce36765c3b156fc9ae33280873b1c32d5f6", size = 201196, upload-time = "2026-02-02T12:37:19.101Z" }, { url = "https://files.pythonhosted.org/packages/ff/32/4ac9c7a76402f8f00d00842a7f6b83b284d0cf7c1e9d4227bc95aa6d17fa/jiter-0.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0a8d76c7524087272c8ae913f5d9d608bd839154b62c4322ef65723d2e5bb0b8", size = 204215, upload-time = "2026-02-02T12:37:20.495Z" }, { url = "https://files.pythonhosted.org/packages/f9/8e/7def204fea9f9be8b3c21a6f2dd6c020cf56c7d5ff753e0e23ed7f9ea57e/jiter-0.13.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2c26cf47e2cad140fa23b6d58d435a7c0161f5c514284802f25e87fddfe11024", size = 187152, upload-time = "2026-02-02T12:37:22.124Z" }, - { url = "https://files.pythonhosted.org/packages/79/b3/3c29819a27178d0e461a8571fb63c6ae38be6dc36b78b3ec2876bbd6a910/jiter-0.13.0-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b1cbfa133241d0e6bdab48dcdc2604e8ba81512f6bbd68ec3e8e1357dd3c316c", size = 307016, upload-time = "2026-02-02T12:37:42.755Z" }, - { url = "https://files.pythonhosted.org/packages/eb/ae/60993e4b07b1ac5ebe46da7aa99fdbb802eb986c38d26e3883ac0125c4e0/jiter-0.13.0-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:db367d8be9fad6e8ebbac4a7578b7af562e506211036cba2c06c3b998603c3d2", size = 305024, upload-time = "2026-02-02T12:37:44.774Z" }, - { url = "https://files.pythonhosted.org/packages/77/fa/2227e590e9cf98803db2811f172b2d6460a21539ab73006f251c66f44b14/jiter-0.13.0-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45f6f8efb2f3b0603092401dc2df79fa89ccbc027aaba4174d2d4133ed661434", size = 339337, upload-time = "2026-02-02T12:37:46.668Z" }, - { url = "https://files.pythonhosted.org/packages/2d/92/015173281f7eb96c0ef580c997da8ef50870d4f7f4c9e03c845a1d62ae04/jiter-0.13.0-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:597245258e6ad085d064780abfb23a284d418d3e61c57362d9449c6c7317ee2d", size = 346395, upload-time = "2026-02-02T12:37:48.09Z" }, { url = "https://files.pythonhosted.org/packages/80/60/e50fa45dd7e2eae049f0ce964663849e897300433921198aef94b6ffa23a/jiter-0.13.0-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:3d744a6061afba08dd7ae375dcde870cffb14429b7477e10f67e9e6d68772a0a", size = 305169, upload-time = "2026-02-02T12:37:50.376Z" }, { url = "https://files.pythonhosted.org/packages/d2/73/a009f41c5eed71c49bec53036c4b33555afcdee70682a18c6f66e396c039/jiter-0.13.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:ff732bd0a0e778f43d5009840f20b935e79087b4dc65bd36f1cd0f9b04b8ff7f", size = 303808, upload-time = "2026-02-02T12:37:52.092Z" }, { url = "https://files.pythonhosted.org/packages/c4/10/528b439290763bff3d939268085d03382471b442f212dca4ff5f12802d43/jiter-0.13.0-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab44b178f7981fcaea7e0a5df20e773c663d06ffda0198f1a524e91b2fde7e59", size = 337384, upload-time = "2026-02-02T12:37:53.582Z" }, @@ -3661,7 +3111,6 @@ name = "keyring" version = "25.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "importlib-metadata", marker = "python_full_version < '3.12'" }, { name = "jaraco-classes" }, { name = "jaraco-context" }, { name = "jaraco-functools" }, @@ -3680,21 +3129,6 @@ version = "1.5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482, upload-time = "2026-03-09T13:15:53.382Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/dd/a495a9c104be1c476f0386e714252caf2b7eca883915422a64c50b88c6f5/kiwisolver-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c", size = 122798, upload-time = "2026-03-09T13:12:58.963Z" }, - { url = "https://files.pythonhosted.org/packages/11/60/37b4047a2af0cf5ef6d8b4b26e91829ae6fc6a2d1f74524bcb0e7cd28a32/kiwisolver-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb", size = 66216, upload-time = "2026-03-09T13:13:00.155Z" }, - { url = "https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac", size = 63911, upload-time = "2026-03-09T13:13:01.671Z" }, - { url = "https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27", size = 1438209, upload-time = "2026-03-09T13:13:03.385Z" }, - { url = "https://files.pythonhosted.org/packages/fd/d6/76621246f5165e5372f02f5e6f3f48ea336a8f9e96e43997d45b240ed8cd/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398", size = 1248888, upload-time = "2026-03-09T13:13:05.231Z" }, - { url = "https://files.pythonhosted.org/packages/b2/c1/31559ec6fb39a5b48035ce29bb63ade628f321785f38c384dee3e2c08bc1/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db", size = 1266304, upload-time = "2026-03-09T13:13:06.743Z" }, - { url = "https://files.pythonhosted.org/packages/5e/ef/1cb8276f2d29cc6a41e0a042f27946ca347d3a4a75acf85d0a16aa6dcc82/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc", size = 1319650, upload-time = "2026-03-09T13:13:08.607Z" }, - { url = "https://files.pythonhosted.org/packages/4c/e4/5ba3cecd7ce6236ae4a80f67e5d5531287337d0e1f076ca87a5abe4cd5d0/kiwisolver-1.5.0-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679", size = 970949, upload-time = "2026-03-09T13:13:10.299Z" }, - { url = "https://files.pythonhosted.org/packages/5a/69/dc61f7ae9a2f071f26004ced87f078235b5507ab6e5acd78f40365655034/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309", size = 2199125, upload-time = "2026-03-09T13:13:11.841Z" }, - { url = "https://files.pythonhosted.org/packages/e5/7b/abbe0f1b5afa85f8d084b73e90e5f801c0939eba16ac2e49af7c61a6c28d/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2", size = 2293783, upload-time = "2026-03-09T13:13:14.399Z" }, - { url = "https://files.pythonhosted.org/packages/8a/80/5908ae149d96d81580d604c7f8aefd0e98f4fd728cf172f477e9f2a81744/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c", size = 1960726, upload-time = "2026-03-09T13:13:16.047Z" }, - { url = "https://files.pythonhosted.org/packages/84/08/a78cb776f8c085b7143142ce479859cfec086bd09ee638a317040b6ef420/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08", size = 2464738, upload-time = "2026-03-09T13:13:17.897Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e1/65584da5356ed6cb12c63791a10b208860ac40a83de165cb6a6751a686e3/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4", size = 2270718, upload-time = "2026-03-09T13:13:19.421Z" }, - { url = "https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b", size = 73480, upload-time = "2026-03-09T13:13:20.818Z" }, - { url = "https://files.pythonhosted.org/packages/d8/0e/2ee5debc4f77a625778fec5501ff3e8036fe361b7ee28ae402a485bb9694/kiwisolver-1.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac", size = 64930, upload-time = "2026-03-09T13:13:21.997Z" }, { url = "https://files.pythonhosted.org/packages/4d/b2/818b74ebea34dabe6d0c51cb1c572e046730e64844da6ed646d5298c40ce/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9", size = 123158, upload-time = "2026-03-09T13:13:23.127Z" }, { url = "https://files.pythonhosted.org/packages/bf/d9/405320f8077e8e1c5c4bd6adc45e1e6edf6d727b6da7f2e2533cf58bff71/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588", size = 66388, upload-time = "2026-03-09T13:13:24.765Z" }, { url = "https://files.pythonhosted.org/packages/99/9f/795fedf35634f746151ca8839d05681ceb6287fbed6cc1c9bf235f7887c2/kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819", size = 64068, upload-time = "2026-03-09T13:13:25.878Z" }, @@ -3773,11 +3207,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0f/41/c5f71f9f00aabcc71fee8b7475e3f64747282580c2fe748961ba29b18385/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203", size = 138036, upload-time = "2026-03-09T13:15:36.894Z" }, { url = "https://files.pythonhosted.org/packages/fa/06/7399a607f434119c6e1fdc8ec89a8d51ccccadf3341dee4ead6bd14caaf5/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7", size = 194295, upload-time = "2026-03-09T13:15:38.22Z" }, { url = "https://files.pythonhosted.org/packages/b5/91/53255615acd2a1eaca307ede3c90eb550bae9c94581f8c00081b6b1c8f44/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57", size = 75987, upload-time = "2026-03-09T13:15:39.65Z" }, - { url = "https://files.pythonhosted.org/packages/e9/eb/5fcbbbf9a0e2c3a35effb88831a483345326bbc3a030a3b5b69aee647f84/kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232", size = 59532, upload-time = "2026-03-09T13:15:47.047Z" }, - { url = "https://files.pythonhosted.org/packages/c3/9b/e17104555bb4db148fd52327feea1e96be4b88e8e008b029002c281a21ab/kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a", size = 57420, upload-time = "2026-03-09T13:15:48.199Z" }, - { url = "https://files.pythonhosted.org/packages/48/44/2b5b95b7aa39fb2d8d9d956e0f3d5d45aef2ae1d942d4c3ffac2f9cfed1a/kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737", size = 79892, upload-time = "2026-03-09T13:15:49.694Z" }, - { url = "https://files.pythonhosted.org/packages/52/7d/7157f9bba6b455cfb4632ed411e199fc8b8977642c2b12082e1bd9e6d173/kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16", size = 77603, upload-time = "2026-03-09T13:15:50.945Z" }, - { url = "https://files.pythonhosted.org/packages/0a/dd/8050c947d435c8d4bc94e3252f4d8bb8a76cfb424f043a8680be637a57f1/kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1", size = 73558, upload-time = "2026-03-09T13:15:52.112Z" }, ] [[package]] @@ -3909,15 +3338,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1a/94/1f5d72655ab6534129540843776c40eff757387b88e798d8b3bf7e313fd4/langsmith-0.7.22-py3-none-any.whl", hash = "sha256:6e9d5148314d74e86748cb9d3898632cad0320c9323d95f70f969e5bc078eee4", size = 359927, upload-time = "2026-03-19T22:45:21.603Z" }, ] -[[package]] -name = "lark" -version = "1.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/60/bc7622aefb2aee1c0b4ba23c1446d3e30225c8770b38d7aedbfb65ca9d5a/lark-1.2.2.tar.gz", hash = "sha256:ca807d0162cd16cef15a8feecb862d7319e7a09bdb13aef927968e45040fed80", size = 252132, upload-time = "2024-08-13T19:49:00.652Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/00/d90b10b962b4277f5e64a78b6609968859ff86889f5b898c1a778c06ec00/lark-1.2.2-py3-none-any.whl", hash = "sha256:c2276486b02f0f1b90be155f2c8ba4a8e194d42775786db622faccd652d8e80c", size = 111036, upload-time = "2024-08-13T19:48:58.603Z" }, -] - [[package]] name = "litellm" version = "1.82.0" @@ -3947,22 +3367,6 @@ version = "6.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/28/30/9abc9e34c657c33834eaf6cd02124c61bdf5944d802aa48e69be8da3585d/lxml-6.1.0.tar.gz", hash = "sha256:bfd57d8008c4965709a919c3e9a98f76c2c7cb319086b3d26858250620023b13", size = 4197006, upload-time = "2026-04-18T04:32:51.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/5d/3bccad330292946f97962df9d5f2d3ae129cce6e212732a781e856b91e07/lxml-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cec05be8c876f92a5aa07b01d60bbb4d11cfbdd654cad0561c0d7b5c043a61b9", size = 8526232, upload-time = "2026-04-18T04:27:40.389Z" }, - { url = "https://files.pythonhosted.org/packages/a7/51/adc8826570a112f83bb4ddb3a2ab510bbc2ccd62c1b9fe1f34fae2d90b57/lxml-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9c03e048b6ce8e77b09c734e931584894ecd58d08296804ca2d0b184c933ce50", size = 4595448, upload-time = "2026-04-18T04:27:44.208Z" }, - { url = "https://files.pythonhosted.org/packages/54/84/5a9ec07cbe1d2334a6465f863b949a520d2699a755738986dcd3b6b89e3f/lxml-6.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:942454ff253da14218f972b23dc72fa4edf6c943f37edd19cd697618b626fac5", size = 4923771, upload-time = "2026-04-18T04:32:17.402Z" }, - { url = "https://files.pythonhosted.org/packages/a7/23/851cfa33b6b38adb628e45ad51fb27105fa34b2b3ba9d1d4aa7a9428dfe0/lxml-6.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d036ee7b99d5148072ac7c9b847193decdfeac633db350363f7bce4fff108f0e", size = 5068101, upload-time = "2026-04-18T04:32:21.437Z" }, - { url = "https://files.pythonhosted.org/packages/b0/38/41bf99c2023c6b79916ba057d83e9db21d642f473cac210201222882d38b/lxml-6.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ae5d8d5427f3cc317e7950f2da7ad276df0cfa37b8de2f5658959e618ea8512", size = 5002573, upload-time = "2026-04-18T04:32:25.373Z" }, - { url = "https://files.pythonhosted.org/packages/c2/20/053aa10bdc39747e1e923ce2d45413075e84f70a136045bb09e5eaca41d3/lxml-6.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:363e47283bde87051b821826e71dde47f107e08614e1aa312ba0c5711e77738c", size = 5202816, upload-time = "2026-04-18T04:32:29.393Z" }, - { url = "https://files.pythonhosted.org/packages/9a/da/bc710fad8bf04b93baee752c192eaa2210cd3a84f969d0be7830fea55802/lxml-6.1.0-cp311-cp311-manylinux_2_28_i686.whl", hash = "sha256:f504d861d9f2a8f94020130adac88d66de93841707a23a86244263d1e54682f5", size = 5329999, upload-time = "2026-04-18T04:32:34.019Z" }, - { url = "https://files.pythonhosted.org/packages/b3/cb/bf035dedbdf7fab49411aa52e4236f3445e98d38647d85419e6c0d2806b9/lxml-6.1.0-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:23a5dc68e08ed13331d61815c08f260f46b4a60fdd1640bbeb82cf89a9d90289", size = 4659643, upload-time = "2026-04-18T04:32:37.932Z" }, - { url = "https://files.pythonhosted.org/packages/5c/4f/22be31f33727a5e4c7b01b0a874503026e50329b259d3587e0b923cf964b/lxml-6.1.0-cp311-cp311-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f15401d8d3dbf239e23c818afc10c7207f7b95f9a307e092122b6f86dd43209a", size = 5265963, upload-time = "2026-04-18T04:32:41.881Z" }, - { url = "https://files.pythonhosted.org/packages/c8/2b/d44d0e5c79226017f4ab8c87a802ebe4f89f97e6585a8e4166dffcdd7b6e/lxml-6.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fcf3da95e93349e0647d48d4b36a12783105bcc74cb0c416952f9988410846a3", size = 5045444, upload-time = "2026-04-18T04:32:44.512Z" }, - { url = "https://files.pythonhosted.org/packages/d3/c3/3f034fec1594c331a6dbf9491238fdcc9d66f68cc529e109ec75b97197e1/lxml-6.1.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:0d082495c5fcf426e425a6e28daaba1fcb6d8f854a4ff01effb1f1f381203eb9", size = 4712703, upload-time = "2026-04-18T04:32:47.16Z" }, - { url = "https://files.pythonhosted.org/packages/12/16/0b83fccc158218aca75a7aa33e97441df737950734246b9fffa39301603d/lxml-6.1.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:e3c4f84b24a1fcba435157d111c4b755099c6ff00a3daee1ad281817de75ed11", size = 5252745, upload-time = "2026-04-18T04:32:50.427Z" }, - { url = "https://files.pythonhosted.org/packages/dd/ee/12e6c1b39a77666c02eaa77f94a870aaf63c4ac3a497b2d52319448b01c6/lxml-6.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:976a6b39b1b13e8c354ad8d3f261f3a4ac6609518af91bdb5094760a08f132c4", size = 5226822, upload-time = "2026-04-18T04:32:53.437Z" }, - { url = "https://files.pythonhosted.org/packages/34/20/c7852904858b4723af01d2fc14b5d38ff57cb92f01934a127ebd9a9e51aa/lxml-6.1.0-cp311-cp311-win32.whl", hash = "sha256:857efde87d365706590847b916baff69c0bc9252dc5af030e378c9800c0b10e3", size = 3594026, upload-time = "2026-04-18T04:27:31.903Z" }, - { url = "https://files.pythonhosted.org/packages/02/05/d60c732b56da5085175c07c74b2df4e6d181b0c9a61e1691474f06ef4b39/lxml-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:183bfb45a493081943be7ea2b5adfc2b611e1cf377cefa8b8a8be404f45ef9a7", size = 4025114, upload-time = "2026-04-18T04:27:34.077Z" }, - { url = "https://files.pythonhosted.org/packages/c2/df/c84dcc175fd690823436d15b41cb920cd5ba5e14cd8bfb00949d5903b320/lxml-6.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:19f4164243fc206d12ed3d866e80e74f5bc3627966520da1a5f97e42c32a3f39", size = 3667742, upload-time = "2026-04-18T04:27:38.45Z" }, { url = "https://files.pythonhosted.org/packages/d2/d4/9326838b59dc36dfae42eec9656b97520f9997eee1de47b8316aaeed169c/lxml-6.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d2f17a16cd8751e8eb233a7e41aecdf8e511712e00088bf9be455f604cd0d28d", size = 8570663, upload-time = "2026-04-18T04:27:48.253Z" }, { url = "https://files.pythonhosted.org/packages/d8/a4/053745ce1f8303ccbb788b86c0db3a91b973675cefc42566a188637b7c40/lxml-6.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f0cea5b1d3e6e77d71bd2b9972eb2446221a69dc52bb0b9c3c6f6e5700592d93", size = 4624024, upload-time = "2026-04-18T04:27:52.594Z" }, { url = "https://files.pythonhosted.org/packages/90/97/a517944b20f8fd0932ad2109482bee4e29fe721416387a363306667941f6/lxml-6.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fc46da94826188ed45cb53bd8e3fc076ae22675aea2087843d4735627f867c6d", size = 4930895, upload-time = "2026-04-18T04:32:56.29Z" }, @@ -4035,12 +3439,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c2/ca/77123e4d77df3cb1e968ade7b1f808f5d3a5c1c96b18a33895397de292c1/lxml-6.1.0-cp314-cp314t-win32.whl", hash = "sha256:00750d63ef0031a05331b9223463b1c7c02b9004cef2346a5b2877f0f9494dd2", size = 3897377, upload-time = "2026-04-18T04:32:07.656Z" }, { url = "https://files.pythonhosted.org/packages/64/ce/3554833989d074267c063209bae8b09815e5656456a2d332b947806b05ff/lxml-6.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:80410c3a7e3c617af04de17caa9f9f20adaa817093293d69eae7d7d0522836f5", size = 4392701, upload-time = "2026-04-18T04:32:12.113Z" }, { url = "https://files.pythonhosted.org/packages/2b/a0/9b916c68c0e57752c07f8f64b30138d9d4059dbeb27b90274dedbea128ff/lxml-6.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:26dd9f57ee3bd41e7d35b4c98a2ffd89ed11591649f421f0ec19f67d50ec67ac", size = 3817120, upload-time = "2026-04-18T04:32:15.803Z" }, - { url = "https://files.pythonhosted.org/packages/f2/88/55143966481409b1740a3ac669e611055f49efd68087a5ce41582325db3e/lxml-6.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:546b66c0dd1bb8d9fa89d7123e5fa19a8aff3a1f2141eb22df96112afb17b842", size = 3930134, upload-time = "2026-04-18T04:32:35.008Z" }, - { url = "https://files.pythonhosted.org/packages/b5/97/28b985c2983938d3cb696dd5501423afb90a8c3e869ef5d3c62569282c0f/lxml-6.1.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5cfa1a34df366d9dc0d5eaf420f4cf2bb1e1bebe1066d1c2fc28c179f8a4004c", size = 4210749, upload-time = "2026-04-18T04:36:03.626Z" }, - { url = "https://files.pythonhosted.org/packages/29/67/dfab2b7d58214921935ccea7ce9b3df9b7d46f305d12f0f532ac7cf6b804/lxml-6.1.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:db88156fcf544cdbf0d95588051515cfdfd4c876fc66444eb98bceb5d6db76de", size = 4318463, upload-time = "2026-04-18T04:36:06.309Z" }, - { url = "https://files.pythonhosted.org/packages/32/a2/4ac7eb32a4d997dd352c32c32399aae27b3f268d440e6f9cfa405b575d2f/lxml-6.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:07f98f5496f96bf724b1e3c933c107f0cbf2745db18c03d2e13a291c3afd2635", size = 4251124, upload-time = "2026-04-18T04:36:09.056Z" }, - { url = "https://files.pythonhosted.org/packages/33/ef/d6abd850bb4822f9b720cfe36b547a558e694881010ff7d012191e8769c6/lxml-6.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4642e04449a1e164b5ff71ffd901ddb772dfabf5c9adf1b7be5dffe1212bc037", size = 4401758, upload-time = "2026-04-18T04:36:11.803Z" }, - { url = "https://files.pythonhosted.org/packages/40/44/3ee09a5b60cb44c4f2fbc1c9015cfd6ff5afc08f991cab295d3024dcbf2d/lxml-6.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:7da13bb6fbadfafb474e0226a30570a3445cfd47c86296f2446dafbd77079ace", size = 3508860, upload-time = "2026-04-18T04:32:48.619Z" }, ] [[package]] @@ -4097,17 +3495,6 @@ version = "3.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, - { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, - { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, - { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, - { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, - { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, - { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, - { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, - { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, - { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, - { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, @@ -4182,13 +3569,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/8a/76/d3c6e3a13fe484ebe7718d14e269c9569c4eb0020a968a327acb3b9a8fe6/matplotlib-3.10.8.tar.gz", hash = "sha256:2299372c19d56bcd35cf05a2738308758d32b9eaed2371898d8f5bd33f084aa3", size = 34806269, upload-time = "2025-12-10T22:56:51.155Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/86/de7e3a1cdcfc941483af70609edc06b83e7c8a0e0dc9ac325200a3f4d220/matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6be43b667360fef5c754dda5d25a32e6307a03c204f3c0fc5468b78fa87b4160", size = 8251215, upload-time = "2025-12-10T22:55:16.175Z" }, - { url = "https://files.pythonhosted.org/packages/fd/14/baad3222f424b19ce6ad243c71de1ad9ec6b2e4eb1e458a48fdc6d120401/matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2b336e2d91a3d7006864e0990c83b216fcdca64b5a6484912902cef87313d78", size = 8139625, upload-time = "2025-12-10T22:55:17.712Z" }, - { url = "https://files.pythonhosted.org/packages/8f/a0/7024215e95d456de5883e6732e708d8187d9753a21d32f8ddb3befc0c445/matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:efb30e3baaea72ce5928e32bab719ab4770099079d66726a62b11b1ef7273be4", size = 8712614, upload-time = "2025-12-10T22:55:20.8Z" }, - { url = "https://files.pythonhosted.org/packages/5a/f4/b8347351da9a5b3f41e26cf547252d861f685c6867d179a7c9d60ad50189/matplotlib-3.10.8-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d56a1efd5bfd61486c8bc968fa18734464556f0fb8e51690f4ac25d85cbbbbc2", size = 9540997, upload-time = "2025-12-10T22:55:23.258Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c0/c7b914e297efe0bc36917bf216b2acb91044b91e930e878ae12981e461e5/matplotlib-3.10.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238b7ce5717600615c895050239ec955d91f321c209dd110db988500558e70d6", size = 9596825, upload-time = "2025-12-10T22:55:25.217Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d3/a4bbc01c237ab710a1f22b4da72f4ff6d77eb4c7735ea9811a94ae239067/matplotlib-3.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:18821ace09c763ec93aef5eeff087ee493a24051936d7b9ebcad9662f66501f9", size = 8135090, upload-time = "2025-12-10T22:55:27.162Z" }, - { url = "https://files.pythonhosted.org/packages/89/dd/a0b6588f102beab33ca6f5218b31725216577b2a24172f327eaf6417d5c9/matplotlib-3.10.8-cp311-cp311-win_arm64.whl", hash = "sha256:bab485bcf8b1c7d2060b4fcb6fc368a9e6f4cd754c9c2fea281f4be21df394a2", size = 8012377, upload-time = "2025-12-10T22:55:29.185Z" }, { url = "https://files.pythonhosted.org/packages/9e/67/f997cdcbb514012eb0d10cd2b4b332667997fb5ebe26b8d41d04962fa0e6/matplotlib-3.10.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:64fcc24778ca0404ce0cb7b6b77ae1f4c7231cdd60e6778f999ee05cbd581b9a", size = 8260453, upload-time = "2025-12-10T22:55:30.709Z" }, { url = "https://files.pythonhosted.org/packages/7e/65/07d5f5c7f7c994f12c768708bd2e17a4f01a2b0f44a1c9eccad872433e2e/matplotlib-3.10.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9a5ca4ac220a0cdd1ba6bcba3608547117d30468fefce49bb26f55c1a3d5c58", size = 8148321, upload-time = "2025-12-10T22:55:33.265Z" }, { url = "https://files.pythonhosted.org/packages/3e/f3/c5195b1ae57ef85339fd7285dfb603b22c8b4e79114bae5f4f0fcf688677/matplotlib-3.10.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ab4aabc72de4ff77b3ec33a6d78a68227bf1123465887f9905ba79184a1cc04", size = 8716944, upload-time = "2025-12-10T22:55:34.922Z" }, @@ -4224,9 +3604,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4d/4b/e7beb6bbd49f6bae727a12b270a2654d13c397576d25bd6786e47033300f/matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:595ba4d8fe983b88f0eec8c26a241e16d6376fe1979086232f481f8f3f67494c", size = 9614011, upload-time = "2025-12-10T22:56:33.85Z" }, { url = "https://files.pythonhosted.org/packages/7c/e6/76f2813d31f032e65f6f797e3f2f6e4aab95b65015924b1c51370395c28a/matplotlib-3.10.8-cp314-cp314t-win_amd64.whl", hash = "sha256:25d380fe8b1dc32cf8f0b1b448470a77afb195438bafdf1d858bfb876f3edf7b", size = 8362801, upload-time = "2025-12-10T22:56:36.107Z" }, { url = "https://files.pythonhosted.org/packages/5d/49/d651878698a0b67f23aa28e17f45a6d6dd3d3f933fa29087fa4ce5947b5a/matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f", size = 8192560, upload-time = "2025-12-10T22:56:38.008Z" }, - { url = "https://files.pythonhosted.org/packages/04/30/3afaa31c757f34b7725ab9d2ba8b48b5e89c2019c003e7d0ead143aabc5a/matplotlib-3.10.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6da7c2ce169267d0d066adcf63758f0604aa6c3eebf67458930f9d9b79ad1db1", size = 8249198, upload-time = "2025-12-10T22:56:45.584Z" }, - { url = "https://files.pythonhosted.org/packages/48/2f/6334aec331f57485a642a7c8be03cb286f29111ae71c46c38b363230063c/matplotlib-3.10.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9153c3292705be9f9c64498a8872118540c3f4123d1a1c840172edf262c8be4a", size = 8136817, upload-time = "2025-12-10T22:56:47.339Z" }, - { url = "https://files.pythonhosted.org/packages/73/e4/6d6f14b2a759c622f191b2d67e9075a3f56aaccb3be4bb9bb6890030d0a0/matplotlib-3.10.8-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ae029229a57cd1e8fe542485f27e7ca7b23aa9e8944ddb4985d0bc444f1eca2", size = 8713867, upload-time = "2025-12-10T22:56:48.954Z" }, ] [[package]] @@ -4266,7 +3643,7 @@ dependencies = [ { name = "imageio" }, { name = "imageio-ffmpeg" }, { name = "mamba-ssm" }, - { name = "megatron-core", extra = ["dev", "mlm"] }, + { name = "megatron-core" }, { name = "mlflow" }, { name = "nvidia-resiliency-ext" }, { name = "omegaconf" }, @@ -4289,79 +3666,19 @@ dependencies = [ [[package]] name = "megatron-core" -version = "0.16.0rc0" -source = { git = "https://github.com/NVIDIA-NeMo/Megatron-Bridge.git?subdirectory=3rdparty%2FMegatron-LM&rev=e049cc00c24d03e2ae45d2608c7a44e2d2364e3d#e049cc00c24d03e2ae45d2608c7a44e2d2364e3d" } -dependencies = [ - { name = "numpy" }, - { name = "packaging" }, - { name = "torch" }, -] - -[package.optional-dependencies] -dev = [ - { name = "av" }, - { name = "causal-conv1d" }, - { name = "datasets" }, - { name = "einops" }, - { name = "fastapi" }, - { name = "flash-linear-attention" }, - { name = "flashinfer-python" }, - { name = "hypercorn" }, - { name = "mamba-ssm" }, - { name = "megatron-energon", extra = ["av-decode"] }, - { name = "multi-storage-client" }, - { name = "nv-grouped-gemm" }, - { name = "nvidia-modelopt", marker = "sys_platform != 'darwin'" }, - { name = "nvidia-resiliency-ext" }, - { name = "nvtx" }, - { name = "onnxscript" }, - { name = "openai", extra = ["aiohttp"] }, - { name = "opentelemetry-api" }, - { name = "orjson" }, - { name = "quart" }, - { name = "tensorstore" }, - { name = "tqdm" }, - { name = "transformer-engine" }, - { name = "wget" }, -] -mlm = [ - { name = "accelerate" }, - { name = "flask-restful" }, - { name = "sentencepiece" }, - { name = "tiktoken" }, - { name = "transformers" }, - { name = "wandb" }, -] - -[[package]] -name = "megatron-energon" -version = "6.0.1" +version = "0.17.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "braceexpand" }, - { name = "click" }, - { name = "multi-storage-client" }, { name = "numpy" }, - { name = "pillow" }, - { name = "pyyaml" }, - { name = "s3fs" }, + { name = "packaging" }, { name = "torch" }, - { name = "tqdm" }, - { name = "webdataset" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/19/7cbb748913db83662c9e4a82164e2a008482048809d3aa163440aa3824bd/megatron_energon-6.0.1.tar.gz", hash = "sha256:39dddd2c91ddf2938ad5440a061363930b09a0c09ee1b459764df149cac34f21", size = 141410, upload-time = "2025-03-17T12:11:22.452Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/89/f690c7d282200d6e36078f4bfbb9e6862102105c062fbf9b518c5b72df38/megatron_core-0.17.0.tar.gz", hash = "sha256:ff66c206ed164bc602ff00310388605fac41f284262176e17246a9e94163b205", size = 1385595, upload-time = "2026-04-16T20:22:32.079Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/d8/d67bac7beaba18d595b3a7d038661b6f27d69fa2099b2fabe85a63343054/megatron_energon-6.0.1-py3-none-any.whl", hash = "sha256:2214250bdc7956791556f3a48b221601fd63d36844644cff9110c312b1cd47a5", size = 202240, upload-time = "2025-03-17T12:11:20.657Z" }, -] - -[package.optional-dependencies] -av-decode = [ - { name = "av" }, - { name = "bitstring" }, - { name = "ebmlite" }, - { name = "filetype" }, - { name = "sortedcontainers" }, - { name = "soundfile" }, + { url = "https://files.pythonhosted.org/packages/79/f8/175724fe6ff44c350b59c169c94dd3748f082bdb1a42684c1a6e698d8223/megatron_core-0.17.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:326dab6f084e65995d87e7f93721c80639b78de1f8690a5f90566c53aef57a5b", size = 1717190, upload-time = "2026-04-16T20:22:24.36Z" }, + { url = "https://files.pythonhosted.org/packages/4e/ad/1c15b4078ad9fc99ba347e112bdf5082d182473f729d906e0c99b8a1f5fb/megatron_core-0.17.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0cbacf043603f9dc2735310e1b1dcd5c076c02caab13849c2d2fe6a99cbea4f6", size = 1725087, upload-time = "2026-04-16T20:22:27.517Z" }, + { url = "https://files.pythonhosted.org/packages/42/37/922434ed189ceaef037e4d40ff1f0e2af3026ceeff9516da766a179446f7/megatron_core-0.17.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d60377cb8bc54037027176a65c65105239474f51ff5b26d034bfe112956e03c", size = 1717170, upload-time = "2026-04-16T20:22:26.079Z" }, + { url = "https://files.pythonhosted.org/packages/dc/44/0ee6bca0e8056d6daf0c21f15f74e36b2628318e19dd78dfaac185c6b547/megatron_core-0.17.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a54ad8a8e221ba989a721da73496cc86ecd84ec79a711449060a15d690005b5", size = 1725175, upload-time = "2026-04-16T20:22:30.032Z" }, ] [[package]] @@ -4373,11 +3690,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/0e/4a/c27b42ed9b1c7d13d9ba8b6905dece787d6259152f2309338aed29b2447b/ml_dtypes-0.5.4.tar.gz", hash = "sha256:8ab06a50fb9bf9666dd0fe5dfb4676fa2b0ac0f31ecff72a6c3af8e22c063453", size = 692314, upload-time = "2025-11-17T22:32:31.031Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/5e/712092cfe7e5eb667b8ad9ca7c54442f21ed7ca8979745f1000e24cf8737/ml_dtypes-0.5.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6c7ecb74c4bd71db68a6bea1edf8da8c34f3d9fe218f038814fd1d310ac76c90", size = 679734, upload-time = "2025-11-17T22:31:39.223Z" }, - { url = "https://files.pythonhosted.org/packages/4f/cf/912146dfd4b5c0eea956836c01dcd2fce6c9c844b2691f5152aca196ce4f/ml_dtypes-0.5.4-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bc11d7e8c44a65115d05e2ab9989d1e045125d7be8e05a071a48bc76eb6d6040", size = 5056165, upload-time = "2025-11-17T22:31:41.071Z" }, - { url = "https://files.pythonhosted.org/packages/a9/80/19189ea605017473660e43762dc853d2797984b3c7bf30ce656099add30c/ml_dtypes-0.5.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:19b9a53598f21e453ea2fbda8aa783c20faff8e1eeb0d7ab899309a0053f1483", size = 5034975, upload-time = "2025-11-17T22:31:42.758Z" }, - { url = "https://files.pythonhosted.org/packages/b4/24/70bd59276883fdd91600ca20040b41efd4902a923283c4d6edcb1de128d2/ml_dtypes-0.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:7c23c54a00ae43edf48d44066a7ec31e05fdc2eee0be2b8b50dd1903a1db94bb", size = 210742, upload-time = "2025-11-17T22:31:44.068Z" }, - { url = "https://files.pythonhosted.org/packages/a0/c9/64230ef14e40aa3f1cb254ef623bf812735e6bec7772848d19131111ac0d/ml_dtypes-0.5.4-cp311-cp311-win_arm64.whl", hash = "sha256:557a31a390b7e9439056644cb80ed0735a6e3e3bb09d67fd5687e4b04238d1de", size = 160709, upload-time = "2025-11-17T22:31:46.557Z" }, { url = "https://files.pythonhosted.org/packages/a8/b8/3c70881695e056f8a32f8b941126cf78775d9a4d7feba8abcb52cb7b04f2/ml_dtypes-0.5.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a174837a64f5b16cab6f368171a1a03a27936b31699d167684073ff1c4237dac", size = 676927, upload-time = "2025-11-17T22:31:48.182Z" }, { url = "https://files.pythonhosted.org/packages/54/0f/428ef6881782e5ebb7eca459689448c0394fa0a80bea3aa9262cba5445ea/ml_dtypes-0.5.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a7f7c643e8b1320fd958bf098aa7ecf70623a42ec5154e3be3be673f4c34d900", size = 5028464, upload-time = "2025-11-17T22:31:50.135Z" }, { url = "https://files.pythonhosted.org/packages/3a/cb/28ce52eb94390dda42599c98ea0204d74799e4d8047a0eb559b6fd648056/ml_dtypes-0.5.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ad459e99793fa6e13bd5b7e6792c8f9190b4e5a1b45c63aba14a4d0a7f1d5ff", size = 5009002, upload-time = "2025-11-17T22:31:52.001Z" }, @@ -4534,14 +3846,6 @@ version = "0.20.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ea/9c/bfbd12955a49180cbd234c5d29ec6f74fe641698f0cd9df154a854fc8a15/msgspec-0.20.0.tar.gz", hash = "sha256:692349e588fde322875f8d3025ac01689fead5901e7fb18d6870a44519d62a29", size = 317862, upload-time = "2025-11-24T03:56:28.934Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/59/fdcb3af72f750a8de2bcf39d62ada70b5eb17b06d7f63860e0a679cb656b/msgspec-0.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:09e0efbf1ac641fedb1d5496c59507c2f0dc62a052189ee62c763e0aae217520", size = 193345, upload-time = "2025-11-24T03:55:20.613Z" }, - { url = "https://files.pythonhosted.org/packages/5a/15/3c225610da9f02505d37d69a77f4a2e7daae2a125f99d638df211ba84e59/msgspec-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23ee3787142e48f5ee746b2909ce1b76e2949fbe0f97f9f6e70879f06c218b54", size = 186867, upload-time = "2025-11-24T03:55:22.4Z" }, - { url = "https://files.pythonhosted.org/packages/81/36/13ab0c547e283bf172f45491edfdea0e2cecb26ae61e3a7b1ae6058b326d/msgspec-0.20.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:81f4ac6f0363407ac0465eff5c7d4d18f26870e00674f8fcb336d898a1e36854", size = 215351, upload-time = "2025-11-24T03:55:23.958Z" }, - { url = "https://files.pythonhosted.org/packages/6b/96/5c095b940de3aa6b43a71ec76275ac3537b21bd45c7499b5a17a429110fa/msgspec-0.20.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bb4d873f24ae18cd1334f4e37a178ed46c9d186437733351267e0a269bdf7e53", size = 219896, upload-time = "2025-11-24T03:55:25.356Z" }, - { url = "https://files.pythonhosted.org/packages/98/7a/81a7b5f01af300761087b114dafa20fb97aed7184d33aab64d48874eb187/msgspec-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b92b8334427b8393b520c24ff53b70f326f79acf5f74adb94fd361bcff8a1d4e", size = 220389, upload-time = "2025-11-24T03:55:26.99Z" }, - { url = "https://files.pythonhosted.org/packages/70/c0/3d0cce27db9a9912421273d49eab79ce01ecd2fed1a2f1b74af9b445f33c/msgspec-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:562c44b047c05cc0384e006fae7a5e715740215c799429e0d7e3e5adf324285a", size = 223348, upload-time = "2025-11-24T03:55:28.311Z" }, - { url = "https://files.pythonhosted.org/packages/89/5e/406b7d578926b68790e390d83a1165a9bfc2d95612a1a9c1c4d5c72ea815/msgspec-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:d1dcc93a3ce3d3195985bfff18a48274d0b5ffbc96fa1c5b89da6f0d9af81b29", size = 188713, upload-time = "2025-11-24T03:55:29.553Z" }, - { url = "https://files.pythonhosted.org/packages/47/87/14fe2316624ceedf76a9e94d714d194cbcb699720b210ff189f89ca4efd7/msgspec-0.20.0-cp311-cp311-win_arm64.whl", hash = "sha256:aa387aa330d2e4bd69995f66ea8fdc87099ddeedf6fdb232993c6a67711e7520", size = 174229, upload-time = "2025-11-24T03:55:31.107Z" }, { url = "https://files.pythonhosted.org/packages/d9/6f/1e25eee957e58e3afb2a44b94fa95e06cebc4c236193ed0de3012fff1e19/msgspec-0.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2aba22e2e302e9231e85edc24f27ba1f524d43c223ef5765bd8624c7df9ec0a5", size = 196391, upload-time = "2025-11-24T03:55:32.677Z" }, { url = "https://files.pythonhosted.org/packages/7f/ee/af51d090ada641d4b264992a486435ba3ef5b5634bc27e6eb002f71cef7d/msgspec-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:716284f898ab2547fedd72a93bb940375de9fbfe77538f05779632dc34afdfde", size = 188644, upload-time = "2025-11-24T03:55:33.934Z" }, { url = "https://files.pythonhosted.org/packages/49/d6/9709ee093b7742362c2934bfb1bbe791a1e09bed3ea5d8a18ce552fbfd73/msgspec-0.20.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:558ed73315efa51b1538fa8f1d3b22c8c5ff6d9a2a62eff87d25829b94fc5054", size = 218852, upload-time = "2025-11-24T03:55:35.575Z" }, @@ -4592,61 +3896,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/15/cf/f2966a2638144491f8696c27320d5219f48a072715075d168b31d3237720/msrest-0.7.1-py3-none-any.whl", hash = "sha256:21120a810e1233e5e6cc7fe40b474eeb4ec6f757a15d7cf86702c369f9567c32", size = 85384, upload-time = "2022-06-13T22:41:22.42Z" }, ] -[[package]] -name = "multi-storage-client" -version = "0.45.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "filelock" }, - { name = "jmespath" }, - { name = "jsonschema" }, - { name = "lark" }, - { name = "opentelemetry-api" }, - { name = "prettytable" }, - { name = "psutil" }, - { name = "python-dateutil" }, - { name = "pyyaml" }, - { name = "tqdm" }, - { name = "tzdata" }, - { name = "wcmatch" }, - { name = "xattr" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/b3/232cac829b63ebd3fd6bb0f3da1cb3daeb56220777b02e4dfde56ad157f5/multi_storage_client-0.45.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:4df24806b3a35877acd303dd6c85abc1aede6367f600ddd9e69f780e72aeecec", size = 9010262, upload-time = "2026-03-20T19:20:01.864Z" }, - { url = "https://files.pythonhosted.org/packages/e2/05/f058b9ba6dfd0c44eaadd9842dab00c9e17bcb80a1662dd6308737f07dd2/multi_storage_client-0.45.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10f52c40b6bae1b3f581cbdb5218ede3e91bf6d52701c3141532377e75e459d1", size = 5396447, upload-time = "2026-03-20T19:15:27.869Z" }, - { url = "https://files.pythonhosted.org/packages/9c/fa/cce8fb4cd52ea96ae8611d739bb85206753c4c9513309b214a23b5e83ba2/multi_storage_client-0.45.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2993fbc79251ad56376a6a43e86ba01f48f47a010e673b5d1b1eaa11b10cbb9", size = 5587666, upload-time = "2026-03-20T19:19:15.197Z" }, - { url = "https://files.pythonhosted.org/packages/7d/8b/e285118932e83ec313637e1d60ea32311088650fa105b07b849b65552090/multi_storage_client-0.45.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2ce402eb5fbcb0a45de82d26a8ebabcf41bd73de528868511dba9efd806e2ac5", size = 9010280, upload-time = "2026-03-20T19:17:39.914Z" }, - { url = "https://files.pythonhosted.org/packages/04/95/c63f7ed36f14dff197724344c536407664a117d33d5c0da02b77192367f7/multi_storage_client-0.45.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f555987548994ee248ba6be9b798afe45bab4295932e0172f04563fa9044bcdb", size = 5394381, upload-time = "2026-03-20T19:18:51.466Z" }, - { url = "https://files.pythonhosted.org/packages/6c/3d/65d89e7efcecd6b7d0db6646b8e2ee4fc1d6929b7c6a53b3ef640c2c6fe7/multi_storage_client-0.45.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55e53afee3ff45b9d8bfb542829281d8bf8ec6927690f316f4bb121264b36715", size = 5584291, upload-time = "2026-03-20T19:15:51.877Z" }, - { url = "https://files.pythonhosted.org/packages/c4/fc/27df22313d3d59f51ed5021d711b79cc61b096faeb855cc8545ff2461586/multi_storage_client-0.45.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:bed3ae0c0cb8645dd69fdabd2d03aa0bd11434406c5f8630db7ce7260c091a1c", size = 9006995, upload-time = "2026-03-20T19:18:04.838Z" }, - { url = "https://files.pythonhosted.org/packages/ed/bd/fd139b17e210f1116b89b8309f25af2edc43fc8ef26015a026941f581975/multi_storage_client-0.45.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e9c92c5593217afb2e6d6b29fee9eef81cb5c3d9ee6c07e0d3a4f2bd276de0f", size = 5394018, upload-time = "2026-03-20T19:19:38.654Z" }, - { url = "https://files.pythonhosted.org/packages/3a/a4/2e3258b95df21c1d7408762758aa939d0b130c7a196ba7e720be8c9dcb46/multi_storage_client-0.45.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d620ca0cbe832ab39651f03774565f912624a2d5c9da34141c7d873d13c17b1", size = 5584308, upload-time = "2026-03-20T19:18:28.977Z" }, -] - [[package]] name = "multidict" version = "6.7.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/1a/c2/c2d94cbe6ac1753f3fc980da97b3d930efe1da3af3c9f5125354436c073d/multidict-6.7.1.tar.gz", hash = "sha256:ec6652a1bee61c53a3e5776b6049172c53b6aaba34f18c9ad04f82712bac623d", size = 102010, upload-time = "2026-01-26T02:46:45.979Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/f1/a90635c4f88fb913fbf4ce660b83b7445b7a02615bda034b2f8eb38fd597/multidict-6.7.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7ff981b266af91d7b4b3793ca3382e53229088d193a85dfad6f5f4c27fc73e5d", size = 76626, upload-time = "2026-01-26T02:43:26.485Z" }, - { url = "https://files.pythonhosted.org/packages/a6/9b/267e64eaf6fc637a15b35f5de31a566634a2740f97d8d094a69d34f524a4/multidict-6.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:844c5bca0b5444adb44a623fb0a1310c2f4cd41f402126bb269cd44c9b3f3e1e", size = 44706, upload-time = "2026-01-26T02:43:27.607Z" }, - { url = "https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f2a0a924d4c2e9afcd7ec64f9de35fcd96915149b2216e1cb2c10a56df483855", size = 44356, upload-time = "2026-01-26T02:43:28.661Z" }, - { url = "https://files.pythonhosted.org/packages/fd/d2/0a36c8473f0cbaeadd5db6c8b72d15bbceeec275807772bfcd059bef487d/multidict-6.7.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8be1802715a8e892c784c0197c2ace276ea52702a0ede98b6310c8f255a5afb3", size = 244355, upload-time = "2026-01-26T02:43:31.165Z" }, - { url = "https://files.pythonhosted.org/packages/5d/16/8c65be997fd7dd311b7d39c7b6e71a0cb449bad093761481eccbbe4b42a2/multidict-6.7.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e2d2ed645ea29f31c4c7ea1552fcfd7cb7ba656e1eafd4134a6620c9f5fdd9e", size = 246433, upload-time = "2026-01-26T02:43:32.581Z" }, - { url = "https://files.pythonhosted.org/packages/01/fb/4dbd7e848d2799c6a026ec88ad39cf2b8416aa167fcc903baa55ecaa045c/multidict-6.7.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:95922cee9a778659e91db6497596435777bd25ed116701a4c034f8e46544955a", size = 225376, upload-time = "2026-01-26T02:43:34.417Z" }, - { url = "https://files.pythonhosted.org/packages/b6/8a/4a3a6341eac3830f6053062f8fbc9a9e54407c80755b3f05bc427295c2d0/multidict-6.7.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6b83cabdc375ffaaa15edd97eb7c0c672ad788e2687004990074d7d6c9b140c8", size = 257365, upload-time = "2026-01-26T02:43:35.741Z" }, - { url = "https://files.pythonhosted.org/packages/f7/a2/dd575a69c1aa206e12d27d0770cdf9b92434b48a9ef0cd0d1afdecaa93c4/multidict-6.7.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:38fb49540705369bab8484db0689d86c0a33a0a9f2c1b197f506b71b4b6c19b0", size = 254747, upload-time = "2026-01-26T02:43:36.976Z" }, - { url = "https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:439cbebd499f92e9aa6793016a8acaa161dfa749ae86d20960189f5398a19144", size = 246293, upload-time = "2026-01-26T02:43:38.258Z" }, - { url = "https://files.pythonhosted.org/packages/5a/a4/23466059dc3854763423d0ad6c0f3683a379d97673b1b89ec33826e46728/multidict-6.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6d3bc717b6fe763b8be3f2bee2701d3c8eb1b2a8ae9f60910f1b2860c82b6c49", size = 242962, upload-time = "2026-01-26T02:43:40.034Z" }, - { url = "https://files.pythonhosted.org/packages/1f/67/51dd754a3524d685958001e8fa20a0f5f90a6a856e0a9dcabff69be3dbb7/multidict-6.7.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:619e5a1ac57986dbfec9f0b301d865dddf763696435e2962f6d9cf2fdff2bb71", size = 237360, upload-time = "2026-01-26T02:43:41.752Z" }, - { url = "https://files.pythonhosted.org/packages/64/3f/036dfc8c174934d4b55d86ff4f978e558b0e585cef70cfc1ad01adc6bf18/multidict-6.7.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0b38ebffd9be37c1170d33bc0f36f4f262e0a09bc1aac1c34c7aa51a7293f0b3", size = 245940, upload-time = "2026-01-26T02:43:43.042Z" }, - { url = "https://files.pythonhosted.org/packages/3d/20/6214d3c105928ebc353a1c644a6ef1408bc5794fcb4f170bb524a3c16311/multidict-6.7.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:10ae39c9cfe6adedcdb764f5e8411d4a92b055e35573a2eaa88d3323289ef93c", size = 253502, upload-time = "2026-01-26T02:43:44.371Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e2/c653bc4ae1be70a0f836b82172d643fcf1dade042ba2676ab08ec08bff0f/multidict-6.7.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:25167cc263257660290fba06b9318d2026e3c910be240a146e1f66dd114af2b0", size = 247065, upload-time = "2026-01-26T02:43:45.745Z" }, - { url = "https://files.pythonhosted.org/packages/c8/11/a854b4154cd3bd8b1fd375e8a8ca9d73be37610c361543d56f764109509b/multidict-6.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:128441d052254f42989ef98b7b6a6ecb1e6f708aa962c7984235316db59f50fa", size = 241870, upload-time = "2026-01-26T02:43:47.054Z" }, - { url = "https://files.pythonhosted.org/packages/13/bf/9676c0392309b5fdae322333d22a829715b570edb9baa8016a517b55b558/multidict-6.7.1-cp311-cp311-win32.whl", hash = "sha256:d62b7f64ffde3b99d06b707a280db04fb3855b55f5a06df387236051d0668f4a", size = 41302, upload-time = "2026-01-26T02:43:48.753Z" }, - { url = "https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:bdbf9f3b332abd0cdb306e7c2113818ab1e922dc84b8f8fd06ec89ed2a19ab8b", size = 45981, upload-time = "2026-01-26T02:43:49.921Z" }, - { url = "https://files.pythonhosted.org/packages/ac/ad/9dd5305253fa00cd3c7555dbef69d5bf4133debc53b87ab8d6a44d411665/multidict-6.7.1-cp311-cp311-win_arm64.whl", hash = "sha256:b8c990b037d2fff2f4e33d3f21b9b531c5745b33a49a7d6dbe7a177266af44f6", size = 43159, upload-time = "2026-01-26T02:43:51.635Z" }, { url = "https://files.pythonhosted.org/packages/8d/9c/f20e0e2cf80e4b2e4b1c365bf5fe104ee633c751a724246262db8f1a0b13/multidict-6.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a90f75c956e32891a4eda3639ce6dd86e87105271f43d43442a3aedf3cddf172", size = 76893, upload-time = "2026-01-26T02:43:52.754Z" }, { url = "https://files.pythonhosted.org/packages/fe/cf/18ef143a81610136d3da8193da9d80bfe1cb548a1e2d1c775f26b23d024a/multidict-6.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fccb473e87eaa1382689053e4a4618e7ba7b9b9b8d6adf2027ee474597128cd", size = 45456, upload-time = "2026-01-26T02:43:53.893Z" }, { url = "https://files.pythonhosted.org/packages/a9/65/1caac9d4cd32e8433908683446eebc953e82d22b03d10d41a5f0fefe991b/multidict-6.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0fa96985700739c4c7853a43c0b3e169360d6855780021bfc6d0f1ce7c123e7", size = 43872, upload-time = "2026-01-26T02:43:55.041Z" }, @@ -4877,14 +4132,6 @@ version = "1.26.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129, upload-time = "2024-02-06T00:26:44.495Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", size = 20630554, upload-time = "2024-02-05T23:51:50.149Z" }, - { url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", size = 13997127, upload-time = "2024-02-05T23:52:15.314Z" }, - { url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", size = 14222994, upload-time = "2024-02-05T23:52:47.569Z" }, - { url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", size = 18252005, upload-time = "2024-02-05T23:53:15.637Z" }, - { url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", size = 13885297, upload-time = "2024-02-05T23:53:42.16Z" }, - { url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567, upload-time = "2024-02-05T23:54:11.696Z" }, - { url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812, upload-time = "2024-02-05T23:54:26.453Z" }, - { url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913, upload-time = "2024-02-05T23:54:53.933Z" }, { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901, upload-time = "2024-02-05T23:55:32.801Z" }, { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868, upload-time = "2024-02-05T23:55:56.28Z" }, { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109, upload-time = "2024-02-05T23:56:20.368Z" }, @@ -4895,17 +4142,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754, upload-time = "2024-02-05T23:58:36.364Z" }, ] -[[package]] -name = "nv-grouped-gemm" -version = "1.1.4.post8" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "absl-py" }, - { name = "numpy" }, - { name = "torch" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/02/ad/046a097b63a96c1ba1d85f0031dbe7fcbdb33e6c445dfbaba2ffaefdd497/nv_grouped_gemm-1.1.4.post8.tar.gz", hash = "sha256:ab321693f0292cfd8a26dc7b6f14decd9eb00e209494de7218e4fad36191275d", size = 20821209, upload-time = "2025-12-17T02:22:38.432Z" } - [[package]] name = "nvidia-cublas-cu12" version = "12.8.4.1" @@ -4954,18 +4190,12 @@ name = "nvidia-cudnn-frontend" version = "1.20.0" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/8b/f660f8e4e771738688668057f84353e55450eb9b85e52f01cfb905783a94/nvidia_cudnn_frontend-1.20.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c6a1b246a0bc70553424c7656c637823c73f7d98cca5a58db26f39e1207d2085", size = 2368995, upload-time = "2026-03-16T18:28:41.675Z" }, - { url = "https://files.pythonhosted.org/packages/69/3e/2cae8081e1e926689eeffb91cd44e18424d8405121a05d66a489ddb9b760/nvidia_cudnn_frontend-1.20.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e1101a7fb810c62fd52a2a3beeeda85ea611e49ae18844044e63b1ea31a7b23", size = 2520413, upload-time = "2026-03-16T18:25:14.789Z" }, - { url = "https://files.pythonhosted.org/packages/ee/65/ee9a687fcf68996216ab1d36b63ac7d3ce0b3821abd9a45c31833389975e/nvidia_cudnn_frontend-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:9415c1f41ff84d2712a6ab55a87e06e5d934d05af6b45adaa709fc07e85eb32f", size = 1944242, upload-time = "2026-03-16T18:32:39.073Z" }, { url = "https://files.pythonhosted.org/packages/0e/eb/22b4cad479206a3824edf494582e19fc4a291b9c14febdb859e56b82c03f/nvidia_cudnn_frontend-1.20.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bb891643598ac7b3734b82e5a459cbf778e467ebf7a5b586840003fb66df0ef3", size = 2371995, upload-time = "2026-03-16T18:29:29.024Z" }, { url = "https://files.pythonhosted.org/packages/aa/83/ee43fc097f475367f1ff5d5e3e1d8191d253f486cdd502d13600759fb845/nvidia_cudnn_frontend-1.20.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce50afe3d1efda07f52e8df5e992f33e92dbb443d0e61e2de703ad5762edc53c", size = 2521021, upload-time = "2026-03-16T18:25:37.316Z" }, - { url = "https://files.pythonhosted.org/packages/cc/03/d2d725c9c6eb04cd4a3216a7d1a37ab825d2ae8822b79a78b458ab703607/nvidia_cudnn_frontend-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:f2449b0cfc547688e27f975c6ad5101257ae86df0315a80f28af78995adf55b6", size = 1944734, upload-time = "2026-03-16T18:33:02.866Z" }, { url = "https://files.pythonhosted.org/packages/d7/26/e5a309fe92ad67f2dc1ea85b2615f40db6c19f6a7b36b40036d57ae23a66/nvidia_cudnn_frontend-1.20.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:651fdc9a61b0a4456b557d5f82fab72739b0a6ee61384a4cb23767191e2640cd", size = 2371699, upload-time = "2026-03-16T18:30:19.865Z" }, { url = "https://files.pythonhosted.org/packages/2d/6f/a9f5df2e003ce6f57b6e609e323fc13379a0f7966d2e044de4ceb87ec4b4/nvidia_cudnn_frontend-1.20.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f317548e700f74c167fa4988de5f0ac06931820e4d0c35b5c7dfe629dd191be4", size = 2521383, upload-time = "2026-03-16T18:26:12.09Z" }, - { url = "https://files.pythonhosted.org/packages/90/8f/cba72a4deb5168bba97d0094dbfe05591a12bc9cc9432bbfd0c107ddca33/nvidia_cudnn_frontend-1.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:64e5c21853732a2f6ecf031d95d100656514d43fd2260f64266b5f8536f46434", size = 1944767, upload-time = "2026-03-16T18:33:25.204Z" }, { url = "https://files.pythonhosted.org/packages/f9/a0/d2634d910257e6827d178dcebdf109f7f2bd8003659675dffc82fa101077/nvidia_cudnn_frontend-1.20.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a1cf3e86664fb64e4752d3936d9cebd0afa6c4b5f6ccde19b6ee4d65fcd9d17", size = 2373944, upload-time = "2026-03-16T18:31:06.31Z" }, { url = "https://files.pythonhosted.org/packages/79/a2/dd2a75942b0311a50bfef3173b240695a5ebdbcbd3c5154d8f333ef6dac6/nvidia_cudnn_frontend-1.20.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4da0e9ed299843abdcccdde73392577809403d4ef2ad26b4335a3eaee42423f", size = 2522596, upload-time = "2026-03-16T18:26:34.249Z" }, - { url = "https://files.pythonhosted.org/packages/ce/af/7110cea67a8cc8f3cd129cead952f5d50078c8bb99cf35e9f78c74a27097/nvidia_cudnn_frontend-1.20.0-cp314-cp314-win_amd64.whl", hash = "sha256:3f596e54398efab24727fc47291c61f969051f37e57e186ffe0fb6df06db19fd", size = 1946060, upload-time = "2026-03-16T18:33:47.963Z" }, ] [[package]] @@ -5048,8 +4278,6 @@ dependencies = [ { name = "typing-extensions" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/60/bf/b9d0fd1ba281b111c941d9616dd9f98a509d84bf35076e60fef27ec7abd6/nvidia_cutlass_dsl_libs_base-4.4.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:261832dafe7579dc83cd3816ab9ea845e3de3737d876c215f01fb4edff1f4473", size = 75476977, upload-time = "2026-03-16T02:26:40.932Z" }, - { url = "https://files.pythonhosted.org/packages/a5/23/86dda6d69a3fc29d0cde2a8b54c056ad69b73a6e5e230e18d906d2ec3b7c/nvidia_cutlass_dsl_libs_base-4.4.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:40c2352b2fcc80789a216cbeb9b2ee10c85c15de839cda8f5c1d18166b8249df", size = 74356100, upload-time = "2026-03-16T02:26:12.778Z" }, { url = "https://files.pythonhosted.org/packages/8e/7d/0df5e38d11e52cc72095a14d6448bc1c5d0d4b00b069a1189ca417fb225b/nvidia_cutlass_dsl_libs_base-4.4.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:2ec8812eeadcbb6fe20bda2e295ed9c00653f8253b78e33cf0ab65a47b829e73", size = 75473821, upload-time = "2026-03-16T02:27:08.371Z" }, { url = "https://files.pythonhosted.org/packages/56/98/e264964741d9cc9816625d9600d17a5249fd5cbd8c2d166fb0d0c34dfe5a/nvidia_cutlass_dsl_libs_base-4.4.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:22e37b58f7a6f2f43bba533c4df8a088012122e0b4e9a632eca23937adeafb39", size = 74355593, upload-time = "2026-03-16T02:25:11.762Z" }, { url = "https://files.pythonhosted.org/packages/1b/c9/2f17950ee2deb4b5f6b82f8155515a21792fe296e81bb638f164d8e2ca9b/nvidia_cutlass_dsl_libs_base-4.4.2-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:b59a052cbfb9a25747d1b6d413615456bea38d1f377da085af07c0d86a4c8b39", size = 75477304, upload-time = "2026-03-16T02:27:35.645Z" }, @@ -5134,38 +4362,10 @@ dependencies = [ { name = "torch" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/46/77/8cda264b262e2868a4e6ebcddaea112200b1e34b8d5a35a2fe3b4978d137/nvidia_resiliency_ext-0.4.1-cp311-cp311-manylinux_2_31_aarch64.whl", hash = "sha256:d8ca454a8b8abef72e0ff0e33914686c263414e8891471c02a9f6af9d2d6b925", size = 443649, upload-time = "2025-07-17T03:49:16.183Z" }, - { url = "https://files.pythonhosted.org/packages/3a/53/029cc7493b5833cb8dfa201f15a1e422e2e1cc6308d34c5b0a90028a73fd/nvidia_resiliency_ext-0.4.1-cp311-cp311-manylinux_2_31_x86_64.whl", hash = "sha256:dde6034f29350ac6326cdd861ceec641bdd93be0eddbf034739f4cd9452a4dd9", size = 449189, upload-time = "2025-07-17T03:52:15.24Z" }, { url = "https://files.pythonhosted.org/packages/70/05/38d491962273c7905708762279f440520eb79f3c00b67a023497215ad023/nvidia_resiliency_ext-0.4.1-cp312-cp312-manylinux_2_31_aarch64.whl", hash = "sha256:b3bd5f01535574b16d0f38bca6e39afe3806c4a2896eee1b321cd944e00025a7", size = 444570, upload-time = "2025-07-17T03:50:58.877Z" }, { url = "https://files.pythonhosted.org/packages/18/8b/4cb8aa2bbdf3705d3034c3f3dacdadb03b3b7dd3dc7f5200e64663fb477f/nvidia_resiliency_ext-0.4.1-cp312-cp312-manylinux_2_31_x86_64.whl", hash = "sha256:ca9f8de465af345952bedbea53c90c0e2323d88cfd830ded0e806fad91845c0e", size = 450280, upload-time = "2025-07-17T03:49:55.327Z" }, ] -[[package]] -name = "nvtx" -version = "0.2.15" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/92/dd/692765e87de30bae1522cdffaa0f2b52949658a92a0fa6d96b1a01eae9d2/nvtx-0.2.15.tar.gz", hash = "sha256:2287d3be05b85661deb386f878d1f536c2e532774aa9ec7a50c434942ed81ae5", size = 121230, upload-time = "2026-03-18T10:01:25.547Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/80/65/435d10b2041ee082c07d5aed129afd504012c8908796d695f10e66bcc716/nvtx-0.2.15-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:157b80ea9b4db6c8f47f8dbe2fa2e81e7a7f1445bb87f8268f43dec9210b78a1", size = 806443, upload-time = "2026-03-18T10:05:49.308Z" }, - { url = "https://files.pythonhosted.org/packages/47/bc/be94576ba33af75bcc68a857daade64cb86481764d4fb0f36308b1f6fc85/nvtx-0.2.15-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02bca69ee55e0be41eabf908de9dbcdd18e702c7f49f9aa63fd396ce684ff5d5", size = 808183, upload-time = "2026-03-18T10:11:16.262Z" }, - { url = "https://files.pythonhosted.org/packages/f6/7a/42109f1cfb1ff9913201cb2b804956a4f003db4c018c2522a3c8066b3a1c/nvtx-0.2.15-cp311-cp311-win_amd64.whl", hash = "sha256:dbe41f78f5a811bd4cdad0a237e5b41a4937d8c2c6c9abdd161091671a598bc0", size = 134631, upload-time = "2026-03-18T10:02:11.247Z" }, - { url = "https://files.pythonhosted.org/packages/c2/07/698355285a03a366ef63ea9762fc1feef3f9f25483e1655408f72d827090/nvtx-0.2.15-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2cc530cd0f1a2c14a3a7e683833db509888ac5ed4ead94e5c9e2c7317c6937a7", size = 807159, upload-time = "2026-03-18T10:09:49.232Z" }, - { url = "https://files.pythonhosted.org/packages/c0/d1/08f22448d83481408d663065764ba583df091a7de629ed38fc97e522f1af/nvtx-0.2.15-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3ca8030a6d197952318013dd1c12c22da1d4b9feb76ba72e0fcd449961183c2c", size = 806187, upload-time = "2026-03-18T10:13:32.972Z" }, - { url = "https://files.pythonhosted.org/packages/54/23/c97c39e3b7ba256aa343cb828ca0d1c8421f705ca84795658ecd14ca95ed/nvtx-0.2.15-cp312-cp312-win_amd64.whl", hash = "sha256:70a1e768964e0520b68ccabc4df391cc227537c45936a7eba6507bc65e617e00", size = 129178, upload-time = "2026-03-18T10:02:55.299Z" }, - { url = "https://files.pythonhosted.org/packages/05/c9/8341224b8284f7deb6a634119939de5885adc421e64b6743693b30da2186/nvtx-0.2.15-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d28660d9c46f8ba750d781572b6aa5a1e6221abba224ab32d7fb32c2d0fd67df", size = 780787, upload-time = "2026-03-18T10:10:40.634Z" }, - { url = "https://files.pythonhosted.org/packages/b1/c0/4a5bb7897918de7c7e0191d9342df8ae4cb797ff07276e0f20d13e497ce7/nvtx-0.2.15-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10749686633f880ad53dcdbb2179fad41b45dcf5b7631d4a1070a577577bd386", size = 782575, upload-time = "2026-03-18T10:13:57.3Z" }, - { url = "https://files.pythonhosted.org/packages/38/b9/6b381ac7c5a3ded331aebbf25f8959d19b51d320fb2514c76c6b6edddaaa/nvtx-0.2.15-cp313-cp313-win_amd64.whl", hash = "sha256:a6650b029263d12f8427a4dee8bd59cb9c91bccb60543bfcb20bc2b00fdcd672", size = 128764, upload-time = "2026-03-18T10:02:33.343Z" }, - { url = "https://files.pythonhosted.org/packages/75/69/a9acb6d95d2e0e381b2956544768528dd8d7a9e827af8c2014169d838284/nvtx-0.2.15-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25813ead4fff4d3a6e04f69a72507b096a6bdbecefa369f1100b0e584767bca8", size = 833375, upload-time = "2026-03-18T10:06:31.955Z" }, - { url = "https://files.pythonhosted.org/packages/38/56/c7e8645061cc2fc23f3a54f33e1e340df59216f07dcfb97d46b8ae7dd26c/nvtx-0.2.15-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3741edac4678b92f03d22a3f0a2dfd469f422f85e63db71b038e02525b2404ad", size = 788639, upload-time = "2026-03-18T10:12:01.69Z" }, - { url = "https://files.pythonhosted.org/packages/96/03/fadd82acdbca6d1c49ac517081a0c3714346f52f4c7e1d4449d77605b4aa/nvtx-0.2.15-cp313-cp313t-win_amd64.whl", hash = "sha256:8be06c3c8c267eba56a0396366b9593092e0b75ea8d3702b303d48c0a1662f0e", size = 142609, upload-time = "2026-03-18T10:01:48.832Z" }, - { url = "https://files.pythonhosted.org/packages/e0/5b/ca0ba6fa769d08174b7a5b4775c279e2e26611cdd5e7833aa699187871c7/nvtx-0.2.15-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5171b8283dd3ea9ae688a86d16901b4c2c142c4eb0a4bdbf6c222f5f67f9524", size = 781769, upload-time = "2026-03-18T10:08:59.357Z" }, - { url = "https://files.pythonhosted.org/packages/f7/e1/e02fafc01c18f1868a2d2c030953f49e38d65f2d95884789a6c46ff308f1/nvtx-0.2.15-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6d0f27d4f8a2f479eb64a6b842c13aee32120348a1715d995b9bb9f75b35cf", size = 774614, upload-time = "2026-03-18T10:12:46.979Z" }, - { url = "https://files.pythonhosted.org/packages/20/77/a2b64335bab7c75fe1c054cc4ebe2d3b3234cbdb04d2e1d6ca73551c54f5/nvtx-0.2.15-cp314-cp314-win_amd64.whl", hash = "sha256:9934fad0b441cfa6e896a848b092498ba23e2ff205c2b9a7b60520ff8367ffef", size = 130932, upload-time = "2026-03-18T10:03:43.507Z" }, - { url = "https://files.pythonhosted.org/packages/db/24/528619230976c18364eda2340906ea67b3bf7588b7ce59e054723614abae/nvtx-0.2.15-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aca61135c76b8107ae3c994325613afa661e1336a991c59cc9c6176829b3b32c", size = 834439, upload-time = "2026-03-18T10:05:01.181Z" }, - { url = "https://files.pythonhosted.org/packages/ef/7b/c1b96f13ef89bdf2a8c2f326a97bed89699271990d7c8624fda3fedc6e61/nvtx-0.2.15-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:58653bf6fd8453947b9e5153da2ad7aeb0ceafa030de7f133efb3eada5da7ca7", size = 790247, upload-time = "2026-03-18T10:11:39.124Z" }, - { url = "https://files.pythonhosted.org/packages/14/5d/e000de781d92b732d52c572517db0e9e3a0085795f8bdc18201713c52d1f/nvtx-0.2.15-cp314-cp314t-win_amd64.whl", hash = "sha256:9d1d10db4fb4a3b0ffd6ed37bf25f0a966a3b4d34b3c9abb1f6572732959a6e5", size = 149109, upload-time = "2026-03-18T10:03:21.615Z" }, -] - [[package]] name = "oauthlib" version = "3.3.1" @@ -5200,12 +4400,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/3b/8a/335c03a8683a88a32f9a6bb98899ea6df241a41df64b37b9696772414794/onnx-1.20.1.tar.gz", hash = "sha256:ded16de1df563d51fbc1ad885f2a426f814039d8b5f4feb77febe09c0295ad67", size = 12048980, upload-time = "2026-01-10T01:40:03.043Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/38/1a0e74d586c08833404100f5c052f92732fb5be417c0b2d7cb0838443bfe/onnx-1.20.1-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:53426e1b458641e7a537e9f176330012ff59d90206cac1c1a9d03cdd73ed3095", size = 17904965, upload-time = "2026-01-10T01:39:13.532Z" }, - { url = "https://files.pythonhosted.org/packages/96/25/64b076e9684d17335f80b15b3bf502f7a8e1a89f08a6b208d4f2861b3011/onnx-1.20.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ca7281f8c576adf396c338cf43fff26faee8d4d2e2577b8e73738f37ceccf945", size = 17415179, upload-time = "2026-01-10T01:39:16.516Z" }, - { url = "https://files.pythonhosted.org/packages/ac/d5/6743b409421ced20ad5af1b3a7b4c4e568689ffaca86db431692fca409a6/onnx-1.20.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2297f428c51c7fc6d8fad0cf34384284dfeff3f86799f8e83ef905451348ade0", size = 17513672, upload-time = "2026-01-10T01:39:19.35Z" }, - { url = "https://files.pythonhosted.org/packages/9a/6b/dae82e6fdb2043302f29adca37522312ea2be55b75907b59be06fbdffe87/onnx-1.20.1-cp311-cp311-win32.whl", hash = "sha256:63d9cbcab8c96841eadeb7c930e07bfab4dde8081eb76fb68e0dfb222706b81e", size = 16239336, upload-time = "2026-01-10T01:39:22.506Z" }, - { url = "https://files.pythonhosted.org/packages/8e/17/a0d7863390c1f2067d7c02dcc1477034965c32aaa1407bfcf775305ffee4/onnx-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:d78cde72d7ca8356a2d99c5dc0dbf67264254828cae2c5780184486c0cd7b3bf", size = 16392120, upload-time = "2026-01-10T01:39:25.106Z" }, - { url = "https://files.pythonhosted.org/packages/aa/72/9b879a46eb7a3322223791f36bf9c25d95da9ed93779eabb75a560f22e5b/onnx-1.20.1-cp311-cp311-win_arm64.whl", hash = "sha256:0104bb2d4394c179bcea3df7599a45a2932b80f4633840896fcf0d7d8daecea2", size = 16346923, upload-time = "2026-01-10T01:39:27.782Z" }, { url = "https://files.pythonhosted.org/packages/7c/4c/4b17e82f91ab9aa07ff595771e935ca73547b035030dc5f5a76e63fbfea9/onnx-1.20.1-cp312-abi3-macosx_12_0_universal2.whl", hash = "sha256:1d923bb4f0ce1b24c6859222a7e6b2f123e7bfe7623683662805f2e7b9e95af2", size = 17903547, upload-time = "2026-01-10T01:39:31.015Z" }, { url = "https://files.pythonhosted.org/packages/64/5e/1bfa100a9cb3f2d3d5f2f05f52f7e60323b0e20bb0abace1ae64dbc88f25/onnx-1.20.1-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ddc0b7d8b5a94627dc86c533d5e415af94cbfd103019a582669dad1f56d30281", size = 17412021, upload-time = "2026-01-10T01:39:33.885Z" }, { url = "https://files.pythonhosted.org/packages/fb/71/d3fec0dcf9a7a99e7368112d9c765154e81da70fcba1e3121131a45c245b/onnx-1.20.1-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9336b6b8e6efcf5c490a845f6afd7e041c89a56199aeda384ed7d58fb953b080", size = 17510450, upload-time = "2026-01-10T01:39:36.589Z" }, @@ -5290,12 +4484,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c9/30/844dc675ee6902579b8eef01ed23917cc9319a1c9c0c14ec6e39340c96d0/openai-2.24.0-py3-none-any.whl", hash = "sha256:fed30480d7d6c884303287bde864980a4b137b60553ffbcf9ab4a233b7a73d94", size = 1120122, upload-time = "2026-02-24T20:02:05.669Z" }, ] -[package.optional-dependencies] -aiohttp = [ - { name = "aiohttp" }, - { name = "httpx-aiohttp" }, -] - [[package]] name = "openpipe-art" version = "0.5.18" @@ -5342,14 +4530,13 @@ langgraph = [ ] megatron = [ { name = "apex" }, - { name = "causal-conv1d", marker = "python_full_version < '3.12' and platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "deep-ep", marker = "sys_platform == 'linux'" }, - { name = "mamba-ssm", marker = "python_full_version < '3.12' and platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "megatron-bridge" }, { name = "megatron-core" }, { name = "ml-dtypes", marker = "python_full_version < '3.13'" }, { name = "numpy" }, { name = "nvidia-ml-py" }, + { name = "nvidia-modelopt", marker = "sys_platform != 'darwin'" }, { name = "nvidia-resiliency-ext" }, { name = "pybind11" }, { name = "quack-kernels" }, @@ -5417,7 +4604,7 @@ requires-dist = [ { name = "mamba-ssm", marker = "python_full_version < '3.12' and platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'megatron'", specifier = "==2.3.1" }, { name = "matplotlib", marker = "extra == 'plotting'", specifier = ">=3.10.1" }, { name = "megatron-bridge", marker = "extra == 'megatron'", git = "https://github.com/NVIDIA-NeMo/Megatron-Bridge.git?rev=e049cc00c24d03e2ae45d2608c7a44e2d2364e3d" }, - { name = "megatron-core", marker = "extra == 'megatron'", specifier = "==0.16.0rc0" }, + { name = "megatron-core", marker = "extra == 'megatron'", specifier = "==0.17.0" }, { name = "ml-dtypes", marker = "python_full_version < '3.13' and extra == 'megatron'", specifier = ">=0.5.0" }, { name = "nbclient", marker = "extra == 'backend'", specifier = ">=0.10.1" }, { name = "nbmake", marker = "extra == 'backend'", specifier = ">=1.5.5" }, @@ -5426,6 +4613,7 @@ requires-dist = [ { name = "numpy", marker = "extra == 'tinker'", specifier = "<2" }, { name = "nvidia-cudnn-frontend", marker = "sys_platform == 'linux' and extra == 'backend'", specifier = "<1.21" }, { name = "nvidia-ml-py", marker = "extra == 'megatron'", specifier = "==13.580.82" }, + { name = "nvidia-modelopt", marker = "sys_platform != 'darwin' and extra == 'megatron'", specifier = ">=0.42.0a0" }, { name = "nvidia-resiliency-ext", marker = "sys_platform == 'linux' and extra == 'backend'", specifier = "<0.5" }, { name = "nvidia-resiliency-ext", marker = "sys_platform == 'linux' and extra == 'megatron'", specifier = "<0.5" }, { name = "openai", specifier = ">=2.14.0" }, @@ -5540,21 +4728,6 @@ version = "3.11.7" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/53/45/b268004f745ede84e5798b48ee12b05129d19235d0e15267aa57dcdb400b/orjson-3.11.7.tar.gz", hash = "sha256:9b1a67243945819ce55d24a30b59d6a168e86220452d2c96f4d1f093e71c0c49", size = 6144992, upload-time = "2026-02-02T15:38:49.29Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/37/02/da6cb01fc6087048d7f61522c327edf4250f1683a58a839fdcc435746dd5/orjson-3.11.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9487abc2c2086e7c8eb9a211d2ce8855bae0e92586279d0d27b341d5ad76c85c", size = 228664, upload-time = "2026-02-02T15:37:25.542Z" }, - { url = "https://files.pythonhosted.org/packages/c1/c2/5885e7a5881dba9a9af51bc564e8967225a642b3e03d089289a35054e749/orjson-3.11.7-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:79cacb0b52f6004caf92405a7e1f11e6e2de8bdf9019e4f76b44ba045125cd6b", size = 125344, upload-time = "2026-02-02T15:37:26.92Z" }, - { url = "https://files.pythonhosted.org/packages/a4/1d/4e7688de0a92d1caf600dfd5fb70b4c5bfff51dfa61ac555072ef2d0d32a/orjson-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2e85fe4698b6a56d5e2ebf7ae87544d668eb6bde1ad1226c13f44663f20ec9e", size = 128404, upload-time = "2026-02-02T15:37:28.108Z" }, - { url = "https://files.pythonhosted.org/packages/2f/b2/ec04b74ae03a125db7bd69cffd014b227b7f341e3261bf75b5eb88a1aa92/orjson-3.11.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8d14b71c0b12963fe8a62aac87119f1afdf4cb88a400f61ca5ae581449efcb5", size = 123677, upload-time = "2026-02-02T15:37:30.287Z" }, - { url = "https://files.pythonhosted.org/packages/4c/69/f95bdf960605f08f827f6e3291fe243d8aa9c5c9ff017a8d7232209184c3/orjson-3.11.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91c81ef070c8f3220054115e1ef468b1c9ce8497b4e526cb9f68ab4dc0a7ac62", size = 128950, upload-time = "2026-02-02T15:37:31.595Z" }, - { url = "https://files.pythonhosted.org/packages/a4/1b/de59c57bae1d148ef298852abd31909ac3089cff370dfd4cd84cc99cbc42/orjson-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:411ebaf34d735e25e358a6d9e7978954a9c9d58cfb47bc6683cdc3964cd2f910", size = 141756, upload-time = "2026-02-02T15:37:32.985Z" }, - { url = "https://files.pythonhosted.org/packages/ee/9e/9decc59f4499f695f65c650f6cfa6cd4c37a3fbe8fa235a0a3614cb54386/orjson-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a16bcd08ab0bcdfc7e8801d9c4a9cc17e58418e4d48ddc6ded4e9e4b1a94062b", size = 130812, upload-time = "2026-02-02T15:37:34.204Z" }, - { url = "https://files.pythonhosted.org/packages/28/e6/59f932bcabd1eac44e334fe8e3281a92eacfcb450586e1f4bde0423728d8/orjson-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c0b51672e466fd7e56230ffbae7f1639e18d0ce023351fb75da21b71bc2c960", size = 133444, upload-time = "2026-02-02T15:37:35.446Z" }, - { url = "https://files.pythonhosted.org/packages/f1/36/b0f05c0eaa7ca30bc965e37e6a2956b0d67adb87a9872942d3568da846ae/orjson-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:136dcd6a2e796dfd9ffca9fc027d778567b0b7c9968d092842d3c323cef88aa8", size = 138609, upload-time = "2026-02-02T15:37:36.657Z" }, - { url = "https://files.pythonhosted.org/packages/b8/03/58ec7d302b8d86944c60c7b4b82975d5161fcce4c9bc8c6cb1d6741b6115/orjson-3.11.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:7ba61079379b0ae29e117db13bda5f28d939766e410d321ec1624afc6a0b0504", size = 408918, upload-time = "2026-02-02T15:37:38.076Z" }, - { url = "https://files.pythonhosted.org/packages/06/3a/868d65ef9a8b99be723bd510de491349618abd9f62c826cf206d962db295/orjson-3.11.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0527a4510c300e3b406591b0ba69b5dc50031895b0a93743526a3fc45f59d26e", size = 143998, upload-time = "2026-02-02T15:37:39.706Z" }, - { url = "https://files.pythonhosted.org/packages/5b/c7/1e18e1c83afe3349f4f6dc9e14910f0ae5f82eac756d1412ea4018938535/orjson-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a709e881723c9b18acddcfb8ba357322491ad553e277cf467e1e7e20e2d90561", size = 134802, upload-time = "2026-02-02T15:37:41.002Z" }, - { url = "https://files.pythonhosted.org/packages/d4/0b/ccb7ee1a65b37e8eeb8b267dc953561d72370e85185e459616d4345bab34/orjson-3.11.7-cp311-cp311-win32.whl", hash = "sha256:c43b8b5bab288b6b90dac410cca7e986a4fa747a2e8f94615aea407da706980d", size = 127828, upload-time = "2026-02-02T15:37:42.241Z" }, - { url = "https://files.pythonhosted.org/packages/af/9e/55c776dffda3f381e0f07d010a4f5f3902bf48eaba1bb7684d301acd4924/orjson-3.11.7-cp311-cp311-win_amd64.whl", hash = "sha256:6543001328aa857187f905308a028935864aefe9968af3848401b6fe80dbb471", size = 124941, upload-time = "2026-02-02T15:37:43.444Z" }, - { url = "https://files.pythonhosted.org/packages/aa/8e/424a620fa7d263b880162505fb107ef5e0afaa765b5b06a88312ac291560/orjson-3.11.7-cp311-cp311-win_arm64.whl", hash = "sha256:1ee5cc7160a821dfe14f130bc8e63e7611051f964b463d9e2a3a573204446a4d", size = 126245, upload-time = "2026-02-02T15:37:45.18Z" }, { url = "https://files.pythonhosted.org/packages/80/bf/76f4f1665f6983385938f0e2a5d7efa12a58171b8456c252f3bae8a4cf75/orjson-3.11.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:bd03ea7606833655048dab1a00734a2875e3e86c276e1d772b2a02556f0d895f", size = 228545, upload-time = "2026-02-02T15:37:46.376Z" }, { url = "https://files.pythonhosted.org/packages/79/53/6c72c002cb13b5a978a068add59b25a8bdf2800ac1c9c8ecdb26d6d97064/orjson-3.11.7-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:89e440ebc74ce8ab5c7bc4ce6757b4a6b1041becb127df818f6997b5c71aa60b", size = 125224, upload-time = "2026-02-02T15:37:47.697Z" }, { url = "https://files.pythonhosted.org/packages/2c/83/10e48852865e5dd151bdfe652c06f7da484578ed02c5fca938e3632cb0b8/orjson-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ede977b5fe5ac91b1dffc0a517ca4542d2ec8a6a4ff7b2652d94f640796342a", size = 128154, upload-time = "2026-02-02T15:37:48.954Z" }, @@ -5608,15 +4781,6 @@ version = "1.12.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/12/0c/f1761e21486942ab9bb6feaebc610fa074f7c5e496e6962dea5873348077/ormsgpack-1.12.2.tar.gz", hash = "sha256:944a2233640273bee67521795a73cf1e959538e0dfb7ac635505010455e53b33", size = 39031, upload-time = "2026-01-18T20:55:28.023Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/08/8b68f24b18e69d92238aa8f258218e6dfeacf4381d9d07ab8df303f524a9/ormsgpack-1.12.2-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:bd5f4bf04c37888e864f08e740c5a573c4017f6fd6e99fa944c5c935fabf2dd9", size = 378266, upload-time = "2026-01-18T20:55:59.876Z" }, - { url = "https://files.pythonhosted.org/packages/0d/24/29fc13044ecb7c153523ae0a1972269fcd613650d1fa1a9cec1044c6b666/ormsgpack-1.12.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34d5b28b3570e9fed9a5a76528fc7230c3c76333bc214798958e58e9b79cc18a", size = 203035, upload-time = "2026-01-18T20:55:30.59Z" }, - { url = "https://files.pythonhosted.org/packages/ad/c2/00169fb25dd8f9213f5e8a549dfb73e4d592009ebc85fbbcd3e1dcac575b/ormsgpack-1.12.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3708693412c28f3538fb5a65da93787b6bbab3484f6bc6e935bfb77a62400ae5", size = 210539, upload-time = "2026-01-18T20:55:48.569Z" }, - { url = "https://files.pythonhosted.org/packages/1b/33/543627f323ff3c73091f51d6a20db28a1a33531af30873ea90c5ac95a9b5/ormsgpack-1.12.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43013a3f3e2e902e1d05e72c0f1aeb5bedbb8e09240b51e26792a3c89267e181", size = 212401, upload-time = "2026-01-18T20:56:10.101Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5d/f70e2c3da414f46186659d24745483757bcc9adccb481a6eb93e2b729301/ormsgpack-1.12.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7c8b1667a72cbba74f0ae7ecf3105a5e01304620ed14528b2cb4320679d2869b", size = 387082, upload-time = "2026-01-18T20:56:12.047Z" }, - { url = "https://files.pythonhosted.org/packages/c0/d6/06e8dc920c7903e051f30934d874d4afccc9bb1c09dcaf0bc03a7de4b343/ormsgpack-1.12.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:df6961442140193e517303d0b5d7bc2e20e69a879c2d774316125350c4a76b92", size = 482346, upload-time = "2026-01-18T20:56:05.152Z" }, - { url = "https://files.pythonhosted.org/packages/66/c4/f337ac0905eed9c393ef990c54565cd33644918e0a8031fe48c098c71dbf/ormsgpack-1.12.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c6a4c34ddef109647c769d69be65fa1de7a6022b02ad45546a69b3216573eb4a", size = 425181, upload-time = "2026-01-18T20:55:37.83Z" }, - { url = "https://files.pythonhosted.org/packages/78/29/6d5758fabef3babdf4bbbc453738cc7de9cd3334e4c38dd5737e27b85653/ormsgpack-1.12.2-cp311-cp311-win_amd64.whl", hash = "sha256:73670ed0375ecc303858e3613f407628dd1fca18fe6ac57b7b7ce66cc7bb006c", size = 117182, upload-time = "2026-01-18T20:55:31.472Z" }, - { url = "https://files.pythonhosted.org/packages/c4/57/17a15549233c37e7fd054c48fe9207492e06b026dbd872b826a0b5f833b6/ormsgpack-1.12.2-cp311-cp311-win_arm64.whl", hash = "sha256:c2be829954434e33601ae5da328cccce3266b098927ca7a30246a0baec2ce7bd", size = 111464, upload-time = "2026-01-18T20:55:38.811Z" }, { url = "https://files.pythonhosted.org/packages/4c/36/16c4b1921c308a92cef3bf6663226ae283395aa0ff6e154f925c32e91ff5/ormsgpack-1.12.2-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:7a29d09b64b9694b588ff2f80e9826bdceb3a2b91523c5beae1fab27d5c940e7", size = 378618, upload-time = "2026-01-18T20:55:50.835Z" }, { url = "https://files.pythonhosted.org/packages/c0/68/468de634079615abf66ed13bb5c34ff71da237213f29294363beeeca5306/ormsgpack-1.12.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b39e629fd2e1c5b2f46f99778450b59454d1f901bc507963168985e79f09c5d", size = 203186, upload-time = "2026-01-18T20:56:11.163Z" }, { url = "https://files.pythonhosted.org/packages/73/a9/d756e01961442688b7939bacd87ce13bfad7d26ce24f910f6028178b2cc8/ormsgpack-1.12.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:958dcb270d30a7cb633a45ee62b9444433fa571a752d2ca484efdac07480876e", size = 210738, upload-time = "2026-01-18T20:56:09.181Z" }, @@ -5671,13 +4835,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790, upload-time = "2025-09-29T23:18:30.065Z" }, - { url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831, upload-time = "2025-09-29T23:38:56.071Z" }, - { url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267, upload-time = "2025-09-29T23:18:41.627Z" }, - { url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281, upload-time = "2025-09-29T23:18:56.834Z" }, - { url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453, upload-time = "2025-09-29T23:19:09.247Z" }, - { url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361, upload-time = "2025-09-29T23:19:25.342Z" }, - { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702, upload-time = "2025-09-29T23:19:38.296Z" }, { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, @@ -5799,16 +4956,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/cb/72/9a51afa0a822b09e286c4cb827ed7b00bc818dac7bd11a5f161e493a217d/pendulum-3.2.0.tar.gz", hash = "sha256:e80feda2d10fa3ff8b1526715f7d33dcb7e08494b3088f2c8a3ac92d4a4331ce", size = 86912, upload-time = "2026-01-30T11:22:24.093Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/27/a4be6ec12161b503dd036f8d7cc57f8626170ae31bb298038be9af0001ce/pendulum-3.2.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5d775cc608c909ad415c8e789c84a9f120bb6a794c4215b2d8d910893cf0ec6a", size = 337923, upload-time = "2026-01-30T11:20:51.61Z" }, - { url = "https://files.pythonhosted.org/packages/59/e1/2a214e18355ec2a6ce3f683a97eecdb6050866ff3a6cf165d411450aeb1b/pendulum-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8de794a7f665aebc8c1ba4dd4b05ab8fe1a36ce9c0498366adf1d1edd79b2686", size = 327379, upload-time = "2026-01-30T11:20:53.085Z" }, - { url = "https://files.pythonhosted.org/packages/9d/01/7392e58ebc1d9e70b987dc8bb0c89710b47ac8125067efe7aa4c420b616f/pendulum-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bac7df7696e1c942e17c0556b3a7bcdd1d7aa5b24faee7620cb071e754a0622", size = 340115, upload-time = "2026-01-30T11:20:54.635Z" }, - { url = "https://files.pythonhosted.org/packages/ef/33/80de84c5ca1a3e4f7f3b75090c9b61b6dbb6d095e302ee592cebbaf0bbfb/pendulum-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db0f6a8a04475d9cba26ce701e7d66d266fd97227f2f5f499270eba04be1c7e9", size = 373969, upload-time = "2026-01-30T11:20:56.209Z" }, - { url = "https://files.pythonhosted.org/packages/75/e4/f7b4c1818927ab394a2a0a9b7011f360a0a75839a22678833c5bc0a84183/pendulum-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c352c63c1ff05f2198409b28498d7158547a8be23e1fbd4aa2cf5402fb239b55", size = 379058, upload-time = "2026-01-30T11:20:57.618Z" }, - { url = "https://files.pythonhosted.org/packages/36/94/9947cf710620afcc68751683f2f8de88d902505e7c13c0349d7e9d362f97/pendulum-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de8c1ad1d1aa7d4ceae341528bab35a0f8c88a5aa63f2f5d84e16b517d1b32c2", size = 348403, upload-time = "2026-01-30T11:20:59.56Z" }, - { url = "https://files.pythonhosted.org/packages/6f/12/0e6ba0bb00fa57907af2a3fca8643bded5dba1e87072d50673776a0d6ed2/pendulum-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1ba955511c12fec2252038b0c866c25c0c30b720bf74d3023710f121e42b1498", size = 517457, upload-time = "2026-01-30T11:21:01.602Z" }, - { url = "https://files.pythonhosted.org/packages/c6/fe/dae5fbfe67bd41d943def0ad8f1e7f6988aa8e527255e433cd7c494f9ad5/pendulum-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4115bf364a2ec6d5ddc476751ceaa4164a04f2c15589f0d29aa210ddb784b15d", size = 561103, upload-time = "2026-01-30T11:21:03.924Z" }, - { url = "https://files.pythonhosted.org/packages/ce/a0/8f646160b98abfc19152505af19bd643a4279ec2bdbe0959f16b7025fc6b/pendulum-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:4151a903356413fdd9549de0997b708fb95a214ed97803ffb479ffd834088378", size = 260595, upload-time = "2026-01-30T11:21:05.495Z" }, - { url = "https://files.pythonhosted.org/packages/79/01/feead7af9ded7a13f2d798fb6573e70f469113eafcd8cc8f59671584ca3e/pendulum-3.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:acfdee9ddc56053cb7c8c075afbfde0857322d09e56a56195b9cd127fae87e4c", size = 255382, upload-time = "2026-01-30T11:21:06.847Z" }, { url = "https://files.pythonhosted.org/packages/41/56/dd0ea9f97d25a0763cda09e2217563b45714786118d8c68b0b745395d6eb/pendulum-3.2.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:bf0b489def51202a39a2a665dcc4162d5e46934a740fe4c4fe3068979610156c", size = 337830, upload-time = "2026-01-30T11:21:08.298Z" }, { url = "https://files.pythonhosted.org/packages/cf/98/83d62899bf7226fc12396de4bc1fb2b5da27e451c7c60790043aaf8b4731/pendulum-3.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:937a529aa302efa18dcf25e53834964a87ffb2df8f80e3669ab7757a6126beaf", size = 327574, upload-time = "2026-01-30T11:21:09.715Z" }, { url = "https://files.pythonhosted.org/packages/76/fa/ff2aa992b23f0543c709b1a3f3f9ed760ec71fd02c8bb01f93bf008b52e4/pendulum-3.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85c7689defc65c4dc29bf257f7cca55d210fabb455de9476e1748d2ab2ae80d7", size = 339891, upload-time = "2026-01-30T11:21:11.089Z" }, @@ -5839,13 +4986,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c9/37/b4f2b5f1200351c4869b8b46ad5c21019e3dbe0417f5867ae969fad7b5fe/pendulum-3.2.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:a50d8cf42f06d3d8c3f8bb2a7ac47fa93b5145e69de6a7209be6a47afdd9cf76", size = 561926, upload-time = "2026-01-30T11:21:51.698Z" }, { url = "https://files.pythonhosted.org/packages/a0/9e/567376582da58f5fe8e4f579db2bcfbf243cf619a5825bdf1023ad1436b3/pendulum-3.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:e5bbb92b155cd5018b3cf70ee49ed3b9c94398caaaa7ed97fe41e5bb5a968418", size = 258817, upload-time = "2026-01-30T11:21:53.074Z" }, { url = "https://files.pythonhosted.org/packages/95/67/dfffd7eb50d67fa821cd4d92cf71575ead6162930202bc40dfcedf78c38c/pendulum-3.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:d53134418e04335c3029a32e9341cccc9b085a28744fb5ee4e6a8f5039363b1a", size = 253292, upload-time = "2026-01-30T11:21:54.484Z" }, - { url = "https://files.pythonhosted.org/packages/c9/0d/d5ac8468a1b40f09a62d6e91654088de432367907579dd161c0fb1bdf222/pendulum-3.2.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9585594d32faa71efa5a78f576f1ee4f79e9c5340d7c6f0cd6c5dfe725effaaa", size = 338760, upload-time = "2026-01-30T11:22:12.225Z" }, - { url = "https://files.pythonhosted.org/packages/a0/e5/7fa8c8be6caac8e0be78fbe7668df571f44820ed779cb3736fab645fcba8/pendulum-3.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:26401e2de77c437e8f3b6160c08c6c5d45518d906f8f9b48fd7cb5aa0f4e2aff", size = 328333, upload-time = "2026-01-30T11:22:13.811Z" }, - { url = "https://files.pythonhosted.org/packages/ad/78/73a1031b7d1bf7986e8e655cea3f018164b3470aecfea25a4074e77dda73/pendulum-3.2.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:637e65af042f383a2764a886aa28ccc6f853bf7a142df18e41c720542934c13b", size = 340841, upload-time = "2026-01-30T11:22:15.278Z" }, - { url = "https://files.pythonhosted.org/packages/49/40/4e36e9074e92b0164c088b9ada3c02bfea386d83e24fa98b30fe9b6e61a8/pendulum-3.2.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6e46c28f4d067233c4a4c42748f4ffa641d9289c09e0e81488beb6d4b3fab51", size = 348959, upload-time = "2026-01-30T11:22:16.718Z" }, - { url = "https://files.pythonhosted.org/packages/24/99/8bf7fcb91b526e1efe17d047faa845709b88800fff915ff848ff26054293/pendulum-3.2.0-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:71d46bcc86269f97bfd8c5f1475d55e717696a0a010b1871023605ca94624031", size = 518102, upload-time = "2026-01-30T11:22:18.2Z" }, - { url = "https://files.pythonhosted.org/packages/b8/b0/a36c468d2d0dec62ddea7c5e4177e93abb12f48ac90f09f24d0581c5189f/pendulum-3.2.0-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:5cd956d4176afc7bfe8a91bf3f771b46ff8d326f6c5bf778eb5010eb742ebba6", size = 561884, upload-time = "2026-01-30T11:22:19.671Z" }, - { url = "https://files.pythonhosted.org/packages/c5/4d/dad105261898907bf806cabca53d3878529a9fa2c0d5d7f95f2035246fc2/pendulum-3.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:39ef129d7b90aab49708645867abdd207b714ba7bff12dae549975b0aca09716", size = 261236, upload-time = "2026-01-30T11:22:21.059Z" }, { url = "https://files.pythonhosted.org/packages/02/fb/d65db067a67df7252f18b0cb7420dda84078b9e8bfb375215469c14a50be/pendulum-3.2.0-py3-none-any.whl", hash = "sha256:f3a9c18a89b4d9ef39c5fa6a78722aaff8d5be2597c129a3b16b9f40a561acf3", size = 114111, upload-time = "2026-01-30T11:22:22.361Z" }, ] @@ -5876,17 +5016,6 @@ version = "12.1.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/1f/42/5c74462b4fd957fcd7b13b04fb3205ff8349236ea74c7c375766d6c82288/pillow-12.1.1.tar.gz", hash = "sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4", size = 46980264, upload-time = "2026-02-11T04:23:07.146Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/46/5da1ec4a5171ee7bf1a0efa064aba70ba3d6e0788ce3f5acd1375d23c8c0/pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32", size = 5304084, upload-time = "2026-02-11T04:20:27.501Z" }, - { url = "https://files.pythonhosted.org/packages/78/93/a29e9bc02d1cf557a834da780ceccd54e02421627200696fcf805ebdc3fb/pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38", size = 4657866, upload-time = "2026-02-11T04:20:29.827Z" }, - { url = "https://files.pythonhosted.org/packages/13/84/583a4558d492a179d31e4aae32eadce94b9acf49c0337c4ce0b70e0a01f2/pillow-12.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5", size = 6232148, upload-time = "2026-02-11T04:20:31.329Z" }, - { url = "https://files.pythonhosted.org/packages/d5/e2/53c43334bbbb2d3b938978532fbda8e62bb6e0b23a26ce8592f36bcc4987/pillow-12.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090", size = 8038007, upload-time = "2026-02-11T04:20:34.225Z" }, - { url = "https://files.pythonhosted.org/packages/b8/a6/3d0e79c8a9d58150dd98e199d7c1c56861027f3829a3a60b3c2784190180/pillow-12.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af", size = 6345418, upload-time = "2026-02-11T04:20:35.858Z" }, - { url = "https://files.pythonhosted.org/packages/a2/c8/46dfeac5825e600579157eea177be43e2f7ff4a99da9d0d0a49533509ac5/pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b", size = 7034590, upload-time = "2026-02-11T04:20:37.91Z" }, - { url = "https://files.pythonhosted.org/packages/af/bf/e6f65d3db8a8bbfeaf9e13cc0417813f6319863a73de934f14b2229ada18/pillow-12.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5", size = 6458655, upload-time = "2026-02-11T04:20:39.496Z" }, - { url = "https://files.pythonhosted.org/packages/f9/c2/66091f3f34a25894ca129362e510b956ef26f8fb67a0e6417bc5744e56f1/pillow-12.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d", size = 7159286, upload-time = "2026-02-11T04:20:41.139Z" }, - { url = "https://files.pythonhosted.org/packages/7b/5a/24bc8eb526a22f957d0cec6243146744966d40857e3d8deb68f7902ca6c1/pillow-12.1.1-cp311-cp311-win32.whl", hash = "sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c", size = 6328663, upload-time = "2026-02-11T04:20:43.184Z" }, - { url = "https://files.pythonhosted.org/packages/31/03/bef822e4f2d8f9d7448c133d0a18185d3cce3e70472774fffefe8b0ed562/pillow-12.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563", size = 7031448, upload-time = "2026-02-11T04:20:44.696Z" }, - { url = "https://files.pythonhosted.org/packages/49/70/f76296f53610bd17b2e7d31728b8b7825e3ac3b5b3688b51f52eab7c0818/pillow-12.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80", size = 2453651, upload-time = "2026-02-11T04:20:46.243Z" }, { url = "https://files.pythonhosted.org/packages/07/d3/8df65da0d4df36b094351dce696f2989bec731d4f10e743b1c5f4da4d3bf/pillow-12.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052", size = 5262803, upload-time = "2026-02-11T04:20:47.653Z" }, { url = "https://files.pythonhosted.org/packages/d6/71/5026395b290ff404b836e636f51d7297e6c83beceaa87c592718747e670f/pillow-12.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984", size = 4657601, upload-time = "2026-02-11T04:20:49.328Z" }, { url = "https://files.pythonhosted.org/packages/b1/2e/1001613d941c67442f745aff0f7cc66dd8df9a9c084eb497e6a543ee6f7e/pillow-12.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79", size = 6234995, upload-time = "2026-02-11T04:20:51.032Z" }, @@ -5948,13 +5077,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/01/4a/9202e8d11714c1fc5951f2e1ef362f2d7fbc595e1f6717971d5dd750e969/pillow-12.1.1-cp314-cp314t-win32.whl", hash = "sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36", size = 6438736, upload-time = "2026-02-11T04:22:46.347Z" }, { url = "https://files.pythonhosted.org/packages/f3/ca/cbce2327eb9885476b3957b2e82eb12c866a8b16ad77392864ad601022ce/pillow-12.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b", size = 7182894, upload-time = "2026-02-11T04:22:48.114Z" }, { url = "https://files.pythonhosted.org/packages/ec/d2/de599c95ba0a973b94410477f8bf0b6f0b5e67360eb89bcb1ad365258beb/pillow-12.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334", size = 2546446, upload-time = "2026-02-11T04:22:50.342Z" }, - { url = "https://files.pythonhosted.org/packages/56/11/5d43209aa4cb58e0cc80127956ff1796a68b928e6324bbf06ef4db34367b/pillow-12.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f", size = 5228606, upload-time = "2026-02-11T04:22:52.106Z" }, - { url = "https://files.pythonhosted.org/packages/5f/d5/3b005b4e4fda6698b371fa6c21b097d4707585d7db99e98d9b0b87ac612a/pillow-12.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9", size = 4622321, upload-time = "2026-02-11T04:22:53.827Z" }, - { url = "https://files.pythonhosted.org/packages/df/36/ed3ea2d594356fd8037e5a01f6156c74bc8d92dbb0fa60746cc96cabb6e8/pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e", size = 5247579, upload-time = "2026-02-11T04:22:56.094Z" }, - { url = "https://files.pythonhosted.org/packages/54/9a/9cc3e029683cf6d20ae5085da0dafc63148e3252c2f13328e553aaa13cfb/pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9", size = 6989094, upload-time = "2026-02-11T04:22:58.288Z" }, - { url = "https://files.pythonhosted.org/packages/00/98/fc53ab36da80b88df0967896b6c4b4cd948a0dc5aa40a754266aa3ae48b3/pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3", size = 5313850, upload-time = "2026-02-11T04:23:00.554Z" }, - { url = "https://files.pythonhosted.org/packages/30/02/00fa585abfd9fe9d73e5f6e554dc36cc2b842898cbfc46d70353dae227f8/pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735", size = 5963343, upload-time = "2026-02-11T04:23:02.934Z" }, - { url = "https://files.pythonhosted.org/packages/f2/26/c56ce33ca856e358d27fda9676c055395abddb82c35ac0f593877ed4562e/pillow-12.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e", size = 7029880, upload-time = "2026-02-11T04:23:04.783Z" }, ] [[package]] @@ -6073,15 +5195,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ee/8c/83087ebc47ab0396ce092363001fa37c17153119ee282700c0713a195853/prettytable-3.17.0-py3-none-any.whl", hash = "sha256:aad69b294ddbe3e1f95ef8886a060ed1666a0b83018bbf56295f6f226c43d287", size = 34433, upload-time = "2025-11-14T17:33:19.093Z" }, ] -[[package]] -name = "priority" -version = "2.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/3c/eb7c35f4dcede96fca1842dac5f4f5d15511aa4b52f3a961219e68ae9204/priority-2.0.0.tar.gz", hash = "sha256:c965d54f1b8d0d0b19479db3924c7c36cf672dbf2aec92d43fbdaf4492ba18c0", size = 24792, upload-time = "2021-06-27T10:15:05.487Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/5f/82c8074f7e84978129347c2c6ec8b6c59f3584ff1a20bc3c940a3e061790/priority-2.0.0-py3-none-any.whl", hash = "sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa", size = 8946, upload-time = "2021-06-27T10:15:03.856Z" }, -] - [[package]] name = "prometheus-client" version = "0.24.1" @@ -6109,21 +5222,6 @@ version = "0.4.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/d4/4e2c9aaf7ac2242b9358f98dccd8f90f2605402f5afeff6c578682c2c491/propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf", size = 80208, upload-time = "2025-10-08T19:46:24.597Z" }, - { url = "https://files.pythonhosted.org/packages/c2/21/d7b68e911f9c8e18e4ae43bdbc1e1e9bbd971f8866eb81608947b6f585ff/propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5", size = 45777, upload-time = "2025-10-08T19:46:25.733Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e", size = 47647, upload-time = "2025-10-08T19:46:27.304Z" }, - { url = "https://files.pythonhosted.org/packages/58/1a/3c62c127a8466c9c843bccb503d40a273e5cc69838805f322e2826509e0d/propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566", size = 214929, upload-time = "2025-10-08T19:46:28.62Z" }, - { url = "https://files.pythonhosted.org/packages/56/b9/8fa98f850960b367c4b8fe0592e7fc341daa7a9462e925228f10a60cf74f/propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165", size = 221778, upload-time = "2025-10-08T19:46:30.358Z" }, - { url = "https://files.pythonhosted.org/packages/46/a6/0ab4f660eb59649d14b3d3d65c439421cf2f87fe5dd68591cbe3c1e78a89/propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc", size = 228144, upload-time = "2025-10-08T19:46:32.607Z" }, - { url = "https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48", size = 210030, upload-time = "2025-10-08T19:46:33.969Z" }, - { url = "https://files.pythonhosted.org/packages/40/e2/27e6feebb5f6b8408fa29f5efbb765cd54c153ac77314d27e457a3e993b7/propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570", size = 208252, upload-time = "2025-10-08T19:46:35.309Z" }, - { url = "https://files.pythonhosted.org/packages/9e/f8/91c27b22ccda1dbc7967f921c42825564fa5336a01ecd72eb78a9f4f53c2/propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85", size = 202064, upload-time = "2025-10-08T19:46:36.993Z" }, - { url = "https://files.pythonhosted.org/packages/f2/26/7f00bd6bd1adba5aafe5f4a66390f243acab58eab24ff1a08bebb2ef9d40/propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e", size = 212429, upload-time = "2025-10-08T19:46:38.398Z" }, - { url = "https://files.pythonhosted.org/packages/84/89/fd108ba7815c1117ddca79c228f3f8a15fc82a73bca8b142eb5de13b2785/propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757", size = 216727, upload-time = "2025-10-08T19:46:39.732Z" }, - { url = "https://files.pythonhosted.org/packages/79/37/3ec3f7e3173e73f1d600495d8b545b53802cbf35506e5732dd8578db3724/propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f", size = 205097, upload-time = "2025-10-08T19:46:41.025Z" }, - { url = "https://files.pythonhosted.org/packages/61/b0/b2631c19793f869d35f47d5a3a56fb19e9160d3c119f15ac7344fc3ccae7/propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1", size = 38084, upload-time = "2025-10-08T19:46:42.693Z" }, - { url = "https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6", size = 41637, upload-time = "2025-10-08T19:46:43.778Z" }, - { url = "https://files.pythonhosted.org/packages/9c/e9/754f180cccd7f51a39913782c74717c581b9cc8177ad0e949f4d51812383/propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239", size = 38064, upload-time = "2025-10-08T19:46:44.872Z" }, { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, @@ -6262,17 +5360,6 @@ version = "2.9.11" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ac/6c/8767aaa597ba424643dc87348c6f1754dd9f48e80fdc1b9f7ca5c3a7c213/psycopg2-binary-2.9.11.tar.gz", hash = "sha256:b6aed9e096bf63f9e75edf2581aa9a7e7186d97ab5c177aa6c87797cd591236c", size = 379620, upload-time = "2025-10-10T11:14:48.041Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/ae/8d8266f6dd183ab4d48b95b9674034e1b482a3f8619b33a0d86438694577/psycopg2_binary-2.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0e8480afd62362d0a6a27dd09e4ca2def6fa50ed3a4e7c09165266106b2ffa10", size = 3756452, upload-time = "2025-10-10T11:11:11.583Z" }, - { url = "https://files.pythonhosted.org/packages/4b/34/aa03d327739c1be70e09d01182619aca8ebab5970cd0cfa50dd8b9cec2ac/psycopg2_binary-2.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:763c93ef1df3da6d1a90f86ea7f3f806dc06b21c198fa87c3c25504abec9404a", size = 3863957, upload-time = "2025-10-10T11:11:16.932Z" }, - { url = "https://files.pythonhosted.org/packages/48/89/3fdb5902bdab8868bbedc1c6e6023a4e08112ceac5db97fc2012060e0c9a/psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e164359396576a3cc701ba8af4751ae68a07235d7a380c631184a611220d9a4", size = 4410955, upload-time = "2025-10-10T11:11:21.21Z" }, - { url = "https://files.pythonhosted.org/packages/ce/24/e18339c407a13c72b336e0d9013fbbbde77b6fd13e853979019a1269519c/psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:d57c9c387660b8893093459738b6abddbb30a7eab058b77b0d0d1c7d521ddfd7", size = 4468007, upload-time = "2025-10-10T11:11:24.831Z" }, - { url = "https://files.pythonhosted.org/packages/91/7e/b8441e831a0f16c159b5381698f9f7f7ed54b77d57bc9c5f99144cc78232/psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2c226ef95eb2250974bf6fa7a842082b31f68385c4f3268370e3f3870e7859ee", size = 4165012, upload-time = "2025-10-10T11:11:29.51Z" }, - { url = "https://files.pythonhosted.org/packages/0d/61/4aa89eeb6d751f05178a13da95516c036e27468c5d4d2509bb1e15341c81/psycopg2_binary-2.9.11-cp311-cp311-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a311f1edc9967723d3511ea7d2708e2c3592e3405677bf53d5c7246753591fbb", size = 3981881, upload-time = "2025-10-30T02:55:07.332Z" }, - { url = "https://files.pythonhosted.org/packages/76/a1/2f5841cae4c635a9459fe7aca8ed771336e9383b6429e05c01267b0774cf/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ebb415404821b6d1c47353ebe9c8645967a5235e6d88f914147e7fd411419e6f", size = 3650985, upload-time = "2025-10-10T11:11:34.975Z" }, - { url = "https://files.pythonhosted.org/packages/84/74/4defcac9d002bca5709951b975173c8c2fa968e1a95dc713f61b3a8d3b6a/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f07c9c4a5093258a03b28fab9b4f151aa376989e7f35f855088234e656ee6a94", size = 3296039, upload-time = "2025-10-10T11:11:40.432Z" }, - { url = "https://files.pythonhosted.org/packages/6d/c2/782a3c64403d8ce35b5c50e1b684412cf94f171dc18111be8c976abd2de1/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:00ce1830d971f43b667abe4a56e42c1e2d594b32da4802e44a73bacacb25535f", size = 3043477, upload-time = "2025-10-30T02:55:11.182Z" }, - { url = "https://files.pythonhosted.org/packages/c8/31/36a1d8e702aa35c38fc117c2b8be3f182613faa25d794b8aeaab948d4c03/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cffe9d7697ae7456649617e8bb8d7a45afb71cd13f7ab22af3e5c61f04840908", size = 3345842, upload-time = "2025-10-10T11:11:45.366Z" }, - { url = "https://files.pythonhosted.org/packages/6e/b4/a5375cda5b54cb95ee9b836930fea30ae5a8f14aa97da7821722323d979b/psycopg2_binary-2.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:304fd7b7f97eef30e91b8f7e720b3db75fee010b520e434ea35ed1ff22501d03", size = 2713894, upload-time = "2025-10-10T11:11:48.775Z" }, { url = "https://files.pythonhosted.org/packages/d8/91/f870a02f51be4a65987b45a7de4c2e1897dd0d01051e2b559a38fa634e3e/psycopg2_binary-2.9.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:be9b840ac0525a283a96b556616f5b4820e0526addb8dcf6525a0fa162730be4", size = 3756603, upload-time = "2025-10-10T11:11:52.213Z" }, { url = "https://files.pythonhosted.org/packages/27/fa/cae40e06849b6c9a95eb5c04d419942f00d9eaac8d81626107461e268821/psycopg2_binary-2.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f090b7ddd13ca842ebfe301cd587a76a4cf0913b1e429eb92c1be5dbeb1a19bc", size = 3864509, upload-time = "2025-10-10T11:11:56.452Z" }, { url = "https://files.pythonhosted.org/packages/2d/75/364847b879eb630b3ac8293798e380e441a957c53657995053c5ec39a316/psycopg2_binary-2.9.11-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ab8905b5dcb05bf3fb22e0cf90e10f469563486ffb6a96569e51f897c750a76a", size = 4411159, upload-time = "2025-10-10T11:12:00.49Z" }, @@ -6350,13 +5437,6 @@ version = "23.0.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/88/22/134986a4cc224d593c1afde5494d18ff629393d74cc2eddb176669f234a4/pyarrow-23.0.1.tar.gz", hash = "sha256:b8c5873e33440b2bc2f4a79d2b47017a89c5a24116c055625e6f2ee50523f019", size = 1167336, upload-time = "2026-02-16T10:14:12.39Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/41/8e6b6ef7e225d4ceead8459427a52afdc23379768f54dd3566014d7618c1/pyarrow-23.0.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6f0147ee9e0386f519c952cc670eb4a8b05caa594eeffe01af0e25f699e4e9bb", size = 34302230, upload-time = "2026-02-16T10:09:03.859Z" }, - { url = "https://files.pythonhosted.org/packages/bf/4a/1472c00392f521fea03ae93408bf445cc7bfa1ab81683faf9bc188e36629/pyarrow-23.0.1-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:0ae6e17c828455b6265d590100c295193f93cc5675eb0af59e49dbd00d2de350", size = 35850050, upload-time = "2026-02-16T10:09:11.877Z" }, - { url = "https://files.pythonhosted.org/packages/0c/b2/bd1f2f05ded56af7f54d702c8364c9c43cd6abb91b0e9933f3d77b4f4132/pyarrow-23.0.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:fed7020203e9ef273360b9e45be52a2a47d3103caf156a30ace5247ffb51bdbd", size = 44491918, upload-time = "2026-02-16T10:09:18.144Z" }, - { url = "https://files.pythonhosted.org/packages/0b/62/96459ef5b67957eac38a90f541d1c28833d1b367f014a482cb63f3b7cd2d/pyarrow-23.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:26d50dee49d741ac0e82185033488d28d35be4d763ae6f321f97d1140eb7a0e9", size = 47562811, upload-time = "2026-02-16T10:09:25.792Z" }, - { url = "https://files.pythonhosted.org/packages/7d/94/1170e235add1f5f45a954e26cd0e906e7e74e23392dcb560de471f7366ec/pyarrow-23.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3c30143b17161310f151f4a2bcfe41b5ff744238c1039338779424e38579d701", size = 48183766, upload-time = "2026-02-16T10:09:34.645Z" }, - { url = "https://files.pythonhosted.org/packages/0e/2d/39a42af4570377b99774cdb47f63ee6c7da7616bd55b3d5001aa18edfe4f/pyarrow-23.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db2190fa79c80a23fdd29fef4b8992893f024ae7c17d2f5f4db7171fa30c2c78", size = 50607669, upload-time = "2026-02-16T10:09:44.153Z" }, - { url = "https://files.pythonhosted.org/packages/00/ca/db94101c187f3df742133ac837e93b1f269ebdac49427f8310ee40b6a58f/pyarrow-23.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:f00f993a8179e0e1c9713bcc0baf6d6c01326a406a9c23495ec1ba9c9ebf2919", size = 27527698, upload-time = "2026-02-16T10:09:50.263Z" }, { url = "https://files.pythonhosted.org/packages/9a/4b/4166bb5abbfe6f750fc60ad337c43ecf61340fa52ab386da6e8dbf9e63c4/pyarrow-23.0.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:f4b0dbfa124c0bb161f8b5ebb40f1a680b70279aa0c9901d44a2b5a20806039f", size = 34214575, upload-time = "2026-02-16T10:09:56.225Z" }, { url = "https://files.pythonhosted.org/packages/e1/da/3f941e3734ac8088ea588b53e860baeddac8323ea40ce22e3d0baa865cc9/pyarrow-23.0.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:7707d2b6673f7de054e2e83d59f9e805939038eebe1763fe811ee8fa5c0cd1a7", size = 35832540, upload-time = "2026-02-16T10:10:03.428Z" }, { url = "https://files.pythonhosted.org/packages/88/7c/3d841c366620e906d54430817531b877ba646310296df42ef697308c2705/pyarrow-23.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:86ff03fb9f1a320266e0de855dee4b17da6794c595d207f89bba40d16b5c78b9", size = 44470940, upload-time = "2026-02-16T10:10:10.704Z" }, @@ -6433,18 +5513,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/df/a0/9c823651872e6a0face3f0311de2a40c8bbcb9c8dcb15680bd019ac56ac7/pycares-5.0.1.tar.gz", hash = "sha256:5a3c249c830432631439815f9a818463416f2a8cbdb1e988e78757de9ae75081", size = 652222, upload-time = "2026-01-01T12:37:00.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/78/43b09f4b8e5fb8a6024661b458b48987abdb39304c78117b106b10a029f1/pycares-5.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c29ca77ff9712e20787201ca8e76ad89384771c0e058a0a4f3dc05afbc4b32de", size = 136177, upload-time = "2026-01-01T12:35:11.567Z" }, - { url = "https://files.pythonhosted.org/packages/19/05/194c0e039ff52b166b50e79ff166c61f931fbca2bf94fc0dbaaf39041518/pycares-5.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f11424bf5cf6226d0b136ed47daa58434e377c61b62d0100d1de7793f8e34a72", size = 130960, upload-time = "2026-01-01T12:35:12.828Z" }, - { url = "https://files.pythonhosted.org/packages/0d/84/5fce65cc058c5ab619c0dd1370d539667235a5565da72ca77f3f741cdc70/pycares-5.0.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d765afb52d579879f5c4f005763827d3b1eb86b23139e9614e6089c9f98db017", size = 220584, upload-time = "2026-01-01T12:35:14.005Z" }, - { url = "https://files.pythonhosted.org/packages/f6/74/d82304297308f6c24a17961bf589b53eefa5f7f2724158c842c67fa0b302/pycares-5.0.1-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ea0d57ba5add4bfbcc40cbdfa92bbb8a5ef0c4c21881e26c7229d9bdc92a4533", size = 252166, upload-time = "2026-01-01T12:35:15.293Z" }, - { url = "https://files.pythonhosted.org/packages/39/a2/0ead3ba4228a490b52eb44d43514dae172c90421bb30a3659516e5b251a2/pycares-5.0.1-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ae9ec2aa3553d33e6220aeb1a05f4853fb83fce4cec3e0dea2dc970338ea47dc", size = 239085, upload-time = "2026-01-01T12:35:16.594Z" }, - { url = "https://files.pythonhosted.org/packages/26/ad/e59f173933f0e696a6afbbd63935114d1400524a72da4f2cbafc6002a398/pycares-5.0.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5c63fb2498b05e9f5670a1bf3b900c5d09343b3b6d5001a9714d593f9eb54de1", size = 222936, upload-time = "2026-01-01T12:35:17.521Z" }, - { url = "https://files.pythonhosted.org/packages/98/fa/d85bfe663a9c292efd8e699779027612c0c65ff50dc4cc9eb7a143613460/pycares-5.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:71316f7a87c15a8d32127ff01374dc2c969c37410693cc0cf6532590b7f18e7a", size = 223506, upload-time = "2026-01-01T12:35:18.535Z" }, - { url = "https://files.pythonhosted.org/packages/2a/6b/4c225a5b10a4c9f88891a20bfe363eca1b1ce7d5244b396e5683c6070998/pycares-5.0.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a2117dffbb78615bfdb41ad77b17038689e4e01c66f153649e80d268c6228b4f", size = 251633, upload-time = "2026-01-01T12:35:19.819Z" }, - { url = "https://files.pythonhosted.org/packages/26/ce/ba2349413b5197b72ec19c46e07f6be3a324f80a7b1579c7cbb1b82d6dc2/pycares-5.0.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7d7c4f5d8b88b586ef2288142b806250020e6490b9f2bd8fd5f634a78fd20fcf", size = 237703, upload-time = "2026-01-01T12:35:20.827Z" }, - { url = "https://files.pythonhosted.org/packages/84/2f/1fd794e6fca10d9e20569113d10a4f92cc2b4242d3eb45524419a37cca6b/pycares-5.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:433b9a4b5a7e10ef8aef0b957e6cd0bfc1bb5bc730d2729f04e93c91c25979c0", size = 222622, upload-time = "2026-01-01T12:35:22.518Z" }, - { url = "https://files.pythonhosted.org/packages/c9/07/7db7977649b210092a7e02d550fcebdfa69bc995c684a3b960c88a5dc4ce/pycares-5.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:cf2699883b88713670d3f9c0a1e44ac24c70aeace9f8c6aa7f0b9f222d5b08a5", size = 117438, upload-time = "2026-01-01T12:35:23.402Z" }, - { url = "https://files.pythonhosted.org/packages/fc/ca/f322ddaa8b3414667de8faeea944ce9d3ddfaf1455839f499a21fcea4cec/pycares-5.0.1-cp311-cp311-win_arm64.whl", hash = "sha256:9528dc11749e5e098c996475b60f879e1db5a6cb3dd0cdc747530620bb1a8941", size = 108920, upload-time = "2026-01-01T12:35:24.599Z" }, { url = "https://files.pythonhosted.org/packages/75/67/e84ba11d3fec3bf1322c3b302c4df13c85e0a1bc48f16d65cd0f59ad9853/pycares-5.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2ee551be4f3f3ac814ac8547586c464c9035e914f5122a534d25de147fa745e1", size = 136241, upload-time = "2026-01-01T12:35:25.439Z" }, { url = "https://files.pythonhosted.org/packages/ce/ae/50fbb3b4e52b9f1d16a36ffabd051ef8b2106b3f0a0d1c1113904d187a9d/pycares-5.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:252d4e5a52a68f825eaa90e16b595f9baee22c760f51e286ab612c6829b96de3", size = 131069, upload-time = "2026-01-01T12:35:26.293Z" }, { url = "https://files.pythonhosted.org/packages/0e/ea/f431599f1ac42149ea4768e516db7cdae3a503a6646319ae63ab66da1486/pycares-5.0.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c1aa549b8c2f2e224215c793d660270778dcba9abc3b85abbc7c41eabe4f1e5", size = 221120, upload-time = "2026-01-01T12:35:27.143Z" }, @@ -6576,20 +5644,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", size = 2105873, upload-time = "2025-11-04T13:39:31.373Z" }, - { url = "https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", size = 1899826, upload-time = "2025-11-04T13:39:32.897Z" }, - { url = "https://files.pythonhosted.org/packages/33/7f/1d5cab3ccf44c1935a359d51a8a2a9e1a654b744b5e7f80d41b88d501eec/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", size = 1917869, upload-time = "2025-11-04T13:39:34.469Z" }, - { url = "https://files.pythonhosted.org/packages/6e/6a/30d94a9674a7fe4f4744052ed6c5e083424510be1e93da5bc47569d11810/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8", size = 2063890, upload-time = "2025-11-04T13:39:36.053Z" }, - { url = "https://files.pythonhosted.org/packages/50/be/76e5d46203fcb2750e542f32e6c371ffa9b8ad17364cf94bb0818dbfb50c/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e", size = 2229740, upload-time = "2025-11-04T13:39:37.753Z" }, - { url = "https://files.pythonhosted.org/packages/d3/ee/fed784df0144793489f87db310a6bbf8118d7b630ed07aa180d6067e653a/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1", size = 2350021, upload-time = "2025-11-04T13:39:40.94Z" }, - { url = "https://files.pythonhosted.org/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b", size = 2066378, upload-time = "2025-11-04T13:39:42.523Z" }, - { url = "https://files.pythonhosted.org/packages/b0/3b/698cf8ae1d536a010e05121b4958b1257f0b5522085e335360e53a6b1c8b/pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b", size = 2175761, upload-time = "2025-11-04T13:39:44.553Z" }, - { url = "https://files.pythonhosted.org/packages/b8/ba/15d537423939553116dea94ce02f9c31be0fa9d0b806d427e0308ec17145/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284", size = 2146303, upload-time = "2025-11-04T13:39:46.238Z" }, - { url = "https://files.pythonhosted.org/packages/58/7f/0de669bf37d206723795f9c90c82966726a2ab06c336deba4735b55af431/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594", size = 2340355, upload-time = "2025-11-04T13:39:48.002Z" }, - { url = "https://files.pythonhosted.org/packages/e5/de/e7482c435b83d7e3c3ee5ee4451f6e8973cff0eb6007d2872ce6383f6398/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e", size = 2319875, upload-time = "2025-11-04T13:39:49.705Z" }, - { url = "https://files.pythonhosted.org/packages/fe/e6/8c9e81bb6dd7560e33b9053351c29f30c8194b72f2d6932888581f503482/pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b", size = 1987549, upload-time = "2025-11-04T13:39:51.842Z" }, - { url = "https://files.pythonhosted.org/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe", size = 2011305, upload-time = "2025-11-04T13:39:53.485Z" }, - { url = "https://files.pythonhosted.org/packages/56/d8/0e271434e8efd03186c5386671328154ee349ff0354d83c74f5caaf096ed/pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f", size = 1972902, upload-time = "2025-11-04T13:39:56.488Z" }, { url = "https://files.pythonhosted.org/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload-time = "2025-11-04T13:39:58.079Z" }, { url = "https://files.pythonhosted.org/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload-time = "2025-11-04T13:39:59.956Z" }, { url = "https://files.pythonhosted.org/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload-time = "2025-11-04T13:40:02.241Z" }, @@ -6646,22 +5700,10 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, - { url = "https://files.pythonhosted.org/packages/11/72/90fda5ee3b97e51c494938a4a44c3a35a9c96c19bba12372fb9c634d6f57/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", size = 2115441, upload-time = "2025-11-04T13:42:39.557Z" }, - { url = "https://files.pythonhosted.org/packages/1f/53/8942f884fa33f50794f119012dc6a1a02ac43a56407adaac20463df8e98f/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", size = 1930291, upload-time = "2025-11-04T13:42:42.169Z" }, - { url = "https://files.pythonhosted.org/packages/79/c8/ecb9ed9cd942bce09fc888ee960b52654fbdbede4ba6c2d6e0d3b1d8b49c/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", size = 1948632, upload-time = "2025-11-04T13:42:44.564Z" }, - { url = "https://files.pythonhosted.org/packages/2e/1b/687711069de7efa6af934e74f601e2a4307365e8fdc404703afc453eab26/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad", size = 2138905, upload-time = "2025-11-04T13:42:47.156Z" }, { url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload-time = "2025-11-04T13:42:49.689Z" }, { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, - { url = "https://files.pythonhosted.org/packages/5f/9b/1b3f0e9f9305839d7e84912f9e8bfbd191ed1b1ef48083609f0dabde978c/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26", size = 2101980, upload-time = "2025-11-04T13:43:25.97Z" }, - { url = "https://files.pythonhosted.org/packages/a4/ed/d71fefcb4263df0da6a85b5d8a7508360f2f2e9b3bf5814be9c8bccdccc1/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808", size = 1923865, upload-time = "2025-11-04T13:43:28.763Z" }, - { url = "https://files.pythonhosted.org/packages/ce/3a/626b38db460d675f873e4444b4bb030453bbe7b4ba55df821d026a0493c4/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc", size = 2134256, upload-time = "2025-11-04T13:43:31.71Z" }, - { url = "https://files.pythonhosted.org/packages/83/d9/8412d7f06f616bbc053d30cb4e5f76786af3221462ad5eee1f202021eb4e/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1", size = 2174762, upload-time = "2025-11-04T13:43:34.744Z" }, - { url = "https://files.pythonhosted.org/packages/55/4c/162d906b8e3ba3a99354e20faa1b49a85206c47de97a639510a0e673f5da/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84", size = 2143141, upload-time = "2025-11-04T13:43:37.701Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f2/f11dd73284122713f5f89fc940f370d035fa8e1e078d446b3313955157fe/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770", size = 2330317, upload-time = "2025-11-04T13:43:40.406Z" }, - { url = "https://files.pythonhosted.org/packages/88/9d/b06ca6acfe4abb296110fb1273a4d848a0bfb2ff65f3ee92127b3244e16b/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f", size = 2316992, upload-time = "2025-11-04T13:43:43.602Z" }, - { url = "https://files.pythonhosted.org/packages/36/c7/cfc8e811f061c841d7990b0201912c3556bfeb99cdcb7ed24adc8d6f8704/pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51", size = 2145302, upload-time = "2025-11-04T13:43:46.64Z" }, ] [[package]] @@ -6852,9 +5894,6 @@ version = "6.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9a/85/b02b80d74bdb95bfe491d49ad1627e9833c73d331edbe6eed0bdfe170361/python-box-6.1.0.tar.gz", hash = "sha256:6e7c243b356cb36e2c0f0e5ed7850969fede6aa812a7f501de7768996c7744d7", size = 41443, upload-time = "2022-10-29T22:30:45.515Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/16/48bcaacf750fa2cc78882a53eef953c28a42e4a84f5e0b27e05d7188a92a/python_box-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ac44b3b85714a4575cc273b5dbd39ef739f938ef6c522d6757704a29e7797d16", size = 1571634, upload-time = "2022-10-29T22:32:40.118Z" }, - { url = "https://files.pythonhosted.org/packages/8b/b4/ae3736cfc3970fe6ee348620780811c016fe4c01d2d0ff4a3a19f4eff5f7/python_box-6.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f0036f91e13958d2b37d2bc74c1197aa36ffd66755342eb64910f63d8a2990f", size = 3546030, upload-time = "2022-10-29T22:35:05.688Z" }, - { url = "https://files.pythonhosted.org/packages/f3/7d/5cc1f3145792b803ee6debc82d1faf791659baa15c2de7b1d9318adbcd68/python_box-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:af6bcee7e1abe9251e9a41ca9ab677e1f679f6059321cfbae7e78a3831e0b736", size = 957417, upload-time = "2022-10-29T22:33:41.542Z" }, { url = "https://files.pythonhosted.org/packages/88/c6/6d1e368710cb6c458ed692d179d7e101ebce80a3e640b2e74cc7ae886d6f/python_box-6.1.0-py3-none-any.whl", hash = "sha256:bdec0a5f5a17b01fc538d292602a077aa8c641fb121e1900dff0591791af80e8", size = 27277, upload-time = "2022-10-29T22:30:43.645Z" }, ] @@ -6907,11 +5946,6 @@ version = "0.4.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b6/34/b4e015b99031667a7b960f888889c5bd34ef585c85e1cb56a594b92836ac/pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a", size = 23015, upload-time = "2026-01-30T01:03:45.924Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/92/790ebe03f07b57e53b10884c329b9a1a308648fc083a6d4a39a10a28c8fc/pytokens-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d70e77c55ae8380c91c0c18dea05951482e263982911fc7410b1ffd1dadd3440", size = 160864, upload-time = "2026-01-30T01:02:57.882Z" }, - { url = "https://files.pythonhosted.org/packages/13/25/a4f555281d975bfdd1eba731450e2fe3a95870274da73fb12c40aeae7625/pytokens-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a58d057208cb9075c144950d789511220b07636dd2e4708d5645d24de666bdc", size = 248565, upload-time = "2026-01-30T01:02:59.912Z" }, - { url = "https://files.pythonhosted.org/packages/17/50/bc0394b4ad5b1601be22fa43652173d47e4c9efbf0044c62e9a59b747c56/pytokens-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b49750419d300e2b5a3813cf229d4e5a4c728dae470bcc89867a9ad6f25a722d", size = 260824, upload-time = "2026-01-30T01:03:01.471Z" }, - { url = "https://files.pythonhosted.org/packages/4e/54/3e04f9d92a4be4fc6c80016bc396b923d2a6933ae94b5f557c939c460ee0/pytokens-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9907d61f15bf7261d7e775bd5d7ee4d2930e04424bab1972591918497623a16", size = 264075, upload-time = "2026-01-30T01:03:04.143Z" }, - { url = "https://files.pythonhosted.org/packages/d1/1b/44b0326cb5470a4375f37988aea5d61b5cc52407143303015ebee94abfd6/pytokens-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee44d0f85b803321710f9239f335aafe16553b39106384cef8e6de40cb4ef2f6", size = 103323, upload-time = "2026-01-30T01:03:05.412Z" }, { url = "https://files.pythonhosted.org/packages/41/5d/e44573011401fb82e9d51e97f1290ceb377800fb4eed650b96f4753b499c/pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083", size = 160663, upload-time = "2026-01-30T01:03:06.473Z" }, { url = "https://files.pythonhosted.org/packages/f0/e6/5bbc3019f8e6f21d09c41f8b8654536117e5e211a85d89212d59cbdab381/pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1", size = 255626, upload-time = "2026-01-30T01:03:08.177Z" }, { url = "https://files.pythonhosted.org/packages/bf/3c/2d5297d82286f6f3d92770289fd439956b201c0a4fc7e72efb9b2293758e/pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1", size = 269779, upload-time = "2026-01-30T01:03:09.756Z" }, @@ -6949,9 +5983,6 @@ name = "pywin32" version = "311" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/af/449a6a91e5d6db51420875c54f6aff7c97a86a3b13a0b4f1a5c13b988de3/pywin32-311-cp311-cp311-win32.whl", hash = "sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151", size = 8697031, upload-time = "2025-07-14T20:13:13.266Z" }, - { url = "https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl", hash = "sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503", size = 9508308, upload-time = "2025-07-14T20:13:15.147Z" }, - { url = "https://files.pythonhosted.org/packages/44/7b/9c2ab54f74a138c491aba1b1cd0795ba61f144c711daea84a88b63dc0f6c/pywin32-311-cp311-cp311-win_arm64.whl", hash = "sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2", size = 8703930, upload-time = "2025-07-14T20:13:16.945Z" }, { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload-time = "2025-07-14T20:13:20.765Z" }, { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload-time = "2025-07-14T20:13:22.543Z" }, { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload-time = "2025-07-14T20:13:24.682Z" }, @@ -6978,15 +6009,6 @@ version = "6.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, - { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, - { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, - { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, - { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, - { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, - { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, - { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, @@ -7036,16 +6058,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86", size = 1333328, upload-time = "2025-09-08T23:07:45.946Z" }, - { url = "https://files.pythonhosted.org/packages/bd/a0/fc7e78a23748ad5443ac3275943457e8452da67fda347e05260261108cbc/pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581", size = 908803, upload-time = "2025-09-08T23:07:47.551Z" }, - { url = "https://files.pythonhosted.org/packages/7e/22/37d15eb05f3bdfa4abea6f6d96eb3bb58585fbd3e4e0ded4e743bc650c97/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f", size = 668836, upload-time = "2025-09-08T23:07:49.436Z" }, - { url = "https://files.pythonhosted.org/packages/b1/c4/2a6fe5111a01005fc7af3878259ce17684fabb8852815eda6225620f3c59/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e", size = 857038, upload-time = "2025-09-08T23:07:51.234Z" }, - { url = "https://files.pythonhosted.org/packages/cb/eb/bfdcb41d0db9cd233d6fb22dc131583774135505ada800ebf14dfb0a7c40/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e", size = 1657531, upload-time = "2025-09-08T23:07:52.795Z" }, - { url = "https://files.pythonhosted.org/packages/ab/21/e3180ca269ed4a0de5c34417dfe71a8ae80421198be83ee619a8a485b0c7/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2", size = 2034786, upload-time = "2025-09-08T23:07:55.047Z" }, - { url = "https://files.pythonhosted.org/packages/3b/b1/5e21d0b517434b7f33588ff76c177c5a167858cc38ef740608898cd329f2/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394", size = 1894220, upload-time = "2025-09-08T23:07:57.172Z" }, - { url = "https://files.pythonhosted.org/packages/03/f2/44913a6ff6941905efc24a1acf3d3cb6146b636c546c7406c38c49c403d4/pyzmq-27.1.0-cp311-cp311-win32.whl", hash = "sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f", size = 567155, upload-time = "2025-09-08T23:07:59.05Z" }, - { url = "https://files.pythonhosted.org/packages/23/6d/d8d92a0eb270a925c9b4dd039c0b4dc10abc2fcbc48331788824ef113935/pyzmq-27.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97", size = 633428, upload-time = "2025-09-08T23:08:00.663Z" }, - { url = "https://files.pythonhosted.org/packages/ae/14/01afebc96c5abbbd713ecfc7469cfb1bc801c819a74ed5c9fad9a48801cb/pyzmq-27.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07", size = 559497, upload-time = "2025-09-08T23:08:02.15Z" }, { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, @@ -7078,11 +6090,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" }, { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" }, { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" }, - { url = "https://files.pythonhosted.org/packages/4c/c6/c4dcdecdbaa70969ee1fdced6d7b8f60cfabe64d25361f27ac4665a70620/pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066", size = 836265, upload-time = "2025-09-08T23:09:49.376Z" }, - { url = "https://files.pythonhosted.org/packages/3e/79/f38c92eeaeb03a2ccc2ba9866f0439593bb08c5e3b714ac1d553e5c96e25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604", size = 800208, upload-time = "2025-09-08T23:09:51.073Z" }, - { url = "https://files.pythonhosted.org/packages/49/0e/3f0d0d335c6b3abb9b7b723776d0b21fa7f3a6c819a0db6097059aada160/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c", size = 567747, upload-time = "2025-09-08T23:09:52.698Z" }, - { url = "https://files.pythonhosted.org/packages/a1/cf/f2b3784d536250ffd4be70e049f3b60981235d70c6e8ce7e3ef21e1adb25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271", size = 747371, upload-time = "2025-09-08T23:09:54.563Z" }, - { url = "https://files.pythonhosted.org/packages/01/1b/5dbe84eefc86f48473947e2f41711aded97eecef1231f4558f1f02713c12/pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355", size = 544862, upload-time = "2025-09-08T23:09:56.509Z" }, ] [[package]] @@ -7100,26 +6107,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e4/7a/1a6d9997f979ce6985210a1783766b6c9b85bf6c21dcb990728526ca4d41/quack_kernels-0.2.5-py3-none-any.whl", hash = "sha256:5f7c246c8cb55c560f7601c952d60bddb4ba3e5c741220703a0c781a0aac3aa2", size = 156759, upload-time = "2026-01-31T09:07:08.989Z" }, ] -[[package]] -name = "quart" -version = "0.20.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiofiles" }, - { name = "blinker" }, - { name = "click" }, - { name = "flask" }, - { name = "hypercorn" }, - { name = "itsdangerous" }, - { name = "jinja2" }, - { name = "markupsafe" }, - { name = "werkzeug" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1d/9d/12e1143a5bd2ccc05c293a6f5ae1df8fd94a8fc1440ecc6c344b2b30ce13/quart-0.20.0.tar.gz", hash = "sha256:08793c206ff832483586f5ae47018c7e40bdd75d886fee3fabbdaa70c2cf505d", size = 63874, upload-time = "2024-12-23T13:53:05.664Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/e9/cc28f21f52913adf333f653b9e0a3bf9cb223f5083a26422968ba73edd8d/quart-0.20.0-py3-none-any.whl", hash = "sha256:003c08f551746710acb757de49d9b768986fd431517d0eb127380b656b98b8f1", size = 77960, upload-time = "2024-12-23T13:53:02.842Z" }, -] - [[package]] name = "qwen-vl-utils" version = "0.0.14" @@ -7155,22 +6142,6 @@ version = "2026.2.28" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/8b/71/41455aa99a5a5ac1eaf311f5d8efd9ce6433c03ac1e0962de163350d0d97/regex-2026.2.28.tar.gz", hash = "sha256:a729e47d418ea11d03469f321aaf67cdee8954cde3ff2cf8403ab87951ad10f2", size = 415184, upload-time = "2026-02-28T02:19:42.792Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/db/8cbfd0ba3f302f2d09dd0019a9fcab74b63fee77a76c937d0e33161fb8c1/regex-2026.2.28-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e621fb7c8dc147419b28e1702f58a0177ff8308a76fa295c71f3e7827849f5d9", size = 488462, upload-time = "2026-02-28T02:16:22.616Z" }, - { url = "https://files.pythonhosted.org/packages/5d/10/ccc22c52802223f2368731964ddd117799e1390ffc39dbb31634a83022ee/regex-2026.2.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0d5bef2031cbf38757a0b0bc4298bb4824b6332d28edc16b39247228fbdbad97", size = 290774, upload-time = "2026-02-28T02:16:23.993Z" }, - { url = "https://files.pythonhosted.org/packages/62/b9/6796b3bf3101e64117201aaa3a5a030ec677ecf34b3cd6141b5d5c6c67d5/regex-2026.2.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bcb399ed84eabf4282587ba151f2732ad8168e66f1d3f85b1d038868fe547703", size = 288724, upload-time = "2026-02-28T02:16:25.403Z" }, - { url = "https://files.pythonhosted.org/packages/9c/02/291c0ae3f3a10cea941d0f5366da1843d8d1fa8a25b0671e20a0e454bb38/regex-2026.2.28-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c1b34dfa72f826f535b20712afa9bb3ba580020e834f3c69866c5bddbf10098", size = 791924, upload-time = "2026-02-28T02:16:26.863Z" }, - { url = "https://files.pythonhosted.org/packages/0f/57/f0235cc520d9672742196c5c15098f8f703f2758d48d5a7465a56333e496/regex-2026.2.28-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:851fa70df44325e1e4cdb79c5e676e91a78147b1b543db2aec8734d2add30ec2", size = 860095, upload-time = "2026-02-28T02:16:28.772Z" }, - { url = "https://files.pythonhosted.org/packages/b3/7c/393c94cbedda79a0f5f2435ebd01644aba0b338d327eb24b4aa5b8d6c07f/regex-2026.2.28-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:516604edd17b1c2c3e579cf4e9b25a53bf8fa6e7cedddf1127804d3e0140ca64", size = 906583, upload-time = "2026-02-28T02:16:30.977Z" }, - { url = "https://files.pythonhosted.org/packages/2c/73/a72820f47ca5abf2b5d911d0407ba5178fc52cf9780191ed3a54f5f419a2/regex-2026.2.28-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7ce83654d1ab701cb619285a18a8e5a889c1216d746ddc710c914ca5fd71022", size = 800234, upload-time = "2026-02-28T02:16:32.55Z" }, - { url = "https://files.pythonhosted.org/packages/34/b3/6e6a4b7b31fa998c4cf159a12cbeaf356386fbd1a8be743b1e80a3da51e4/regex-2026.2.28-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2791948f7c70bb9335a9102df45e93d428f4b8128020d85920223925d73b9e1", size = 772803, upload-time = "2026-02-28T02:16:34.029Z" }, - { url = "https://files.pythonhosted.org/packages/10/e7/5da0280c765d5a92af5e1cd324b3fe8464303189cbaa449de9a71910e273/regex-2026.2.28-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:03a83cc26aa2acda6b8b9dfe748cf9e84cbd390c424a1de34fdcef58961a297a", size = 781117, upload-time = "2026-02-28T02:16:36.253Z" }, - { url = "https://files.pythonhosted.org/packages/76/39/0b8d7efb256ae34e1b8157acc1afd8758048a1cf0196e1aec2e71fd99f4b/regex-2026.2.28-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ec6f5674c5dc836994f50f1186dd1fafde4be0666aae201ae2fcc3d29d8adf27", size = 854224, upload-time = "2026-02-28T02:16:38.119Z" }, - { url = "https://files.pythonhosted.org/packages/21/ff/a96d483ebe8fe6d1c67907729202313895d8de8495569ec319c6f29d0438/regex-2026.2.28-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:50c2fc924749543e0eacc93ada6aeeb3ea5f6715825624baa0dccaec771668ae", size = 761898, upload-time = "2026-02-28T02:16:40.333Z" }, - { url = "https://files.pythonhosted.org/packages/89/bd/d4f2e75cb4a54b484e796017e37c0d09d8a0a837de43d17e238adf163f4e/regex-2026.2.28-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ba55c50f408fb5c346a3a02d2ce0ebc839784e24f7c9684fde328ff063c3cdea", size = 844832, upload-time = "2026-02-28T02:16:41.875Z" }, - { url = "https://files.pythonhosted.org/packages/8a/a7/428a135cf5e15e4e11d1e696eb2bf968362f8ea8a5f237122e96bc2ae950/regex-2026.2.28-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:edb1b1b3a5576c56f08ac46f108c40333f222ebfd5cf63afdfa3aab0791ebe5b", size = 788347, upload-time = "2026-02-28T02:16:43.472Z" }, - { url = "https://files.pythonhosted.org/packages/a9/59/68691428851cf9c9c3707217ab1d9b47cfeec9d153a49919e6c368b9e926/regex-2026.2.28-cp311-cp311-win32.whl", hash = "sha256:948c12ef30ecedb128903c2c2678b339746eb7c689c5c21957c4a23950c96d15", size = 266033, upload-time = "2026-02-28T02:16:45.094Z" }, - { url = "https://files.pythonhosted.org/packages/42/8b/1483de1c57024e89296cbcceb9cccb3f625d416ddb46e570be185c9b05a9/regex-2026.2.28-cp311-cp311-win_amd64.whl", hash = "sha256:fd63453f10d29097cc3dc62d070746523973fb5aa1c66d25f8558bebd47fed61", size = 277978, upload-time = "2026-02-28T02:16:46.75Z" }, - { url = "https://files.pythonhosted.org/packages/a4/36/abec45dc6e7252e3dbc797120496e43bb5730a7abf0d9cb69340696a2f2d/regex-2026.2.28-cp311-cp311-win_arm64.whl", hash = "sha256:00f2b8d9615aa165fdff0a13f1a92049bfad555ee91e20d246a51aa0b556c60a", size = 270340, upload-time = "2026-02-28T02:16:48.626Z" }, { url = "https://files.pythonhosted.org/packages/07/42/9061b03cf0fc4b5fa2c3984cbbaed54324377e440a5c5a29d29a72518d62/regex-2026.2.28-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:fcf26c3c6d0da98fada8ae4ef0aa1c3405a431c0a77eb17306d38a89b02adcd7", size = 489574, upload-time = "2026-02-28T02:16:50.455Z" }, { url = "https://files.pythonhosted.org/packages/77/83/0c8a5623a233015595e3da499c5a1c13720ac63c107897a6037bb97af248/regex-2026.2.28-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02473c954af35dd2defeb07e44182f5705b30ea3f351a7cbffa9177beb14da5d", size = 291426, upload-time = "2026-02-28T02:16:52.52Z" }, { url = "https://files.pythonhosted.org/packages/9e/06/3ef1ac6910dc3295ebd71b1f9bfa737e82cfead211a18b319d45f85ddd09/regex-2026.2.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9b65d33a17101569f86d9c5966a8b1d7fbf8afdda5a8aa219301b0a80f58cf7d", size = 289200, upload-time = "2026-02-28T02:16:54.08Z" }, @@ -7326,21 +6297,6 @@ version = "0.7.6" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e5/f5/8bed2310abe4ae04b67a38374a4d311dd85220f5d8da56f47ae9361be0b0/rignore-0.7.6.tar.gz", hash = "sha256:00d3546cd793c30cb17921ce674d2c8f3a4b00501cb0e3dd0e82217dbeba2671", size = 57140, upload-time = "2025-11-05T21:41:21.968Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/41/b6e2be3069ef3b7f24e35d2911bd6deb83d20ed5642ad81d5a6d1c015473/rignore-0.7.6-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:40be8226e12d6653abbebaffaea2885f80374c1c8f76fe5ca9e0cadd120a272c", size = 885285, upload-time = "2025-11-05T20:42:39.763Z" }, - { url = "https://files.pythonhosted.org/packages/52/66/ba7f561b6062402022887706a7f2b2c2e2e2a28f1e3839202b0a2f77e36d/rignore-0.7.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:182f4e5e4064d947c756819446a7d4cdede8e756b8c81cf9e509683fe38778d7", size = 823882, upload-time = "2025-11-05T20:42:23.488Z" }, - { url = "https://files.pythonhosted.org/packages/f5/81/4087453df35a90b07370647b19017029324950c1b9137d54bf1f33843f17/rignore-0.7.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16b63047648a916a87be1e51bb5c009063f1b8b6f5afe4f04f875525507e63dc", size = 899362, upload-time = "2025-11-05T20:40:51.111Z" }, - { url = "https://files.pythonhosted.org/packages/fb/c9/390a8fdfabb76d71416be773bd9f162977bd483084f68daf19da1dec88a6/rignore-0.7.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ba5524f5178deca4d7695e936604ebc742acb8958f9395776e1fcb8133f8257a", size = 873633, upload-time = "2025-11-05T20:41:06.193Z" }, - { url = "https://files.pythonhosted.org/packages/df/c9/79404fcb0faa76edfbc9df0901f8ef18568d1104919ebbbad6d608c888d1/rignore-0.7.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62020dbb89a1dd4b84ab3d60547b3b2eb2723641d5fb198463643f71eaaed57d", size = 1167633, upload-time = "2025-11-05T20:41:22.491Z" }, - { url = "https://files.pythonhosted.org/packages/6e/8d/b3466d32d445d158a0aceb80919085baaae495b1f540fb942f91d93b5e5b/rignore-0.7.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b34acd532769d5a6f153a52a98dcb81615c949ab11697ce26b2eb776af2e174d", size = 941434, upload-time = "2025-11-05T20:41:38.151Z" }, - { url = "https://files.pythonhosted.org/packages/e8/40/9cd949761a7af5bc27022a939c91ff622d29c7a0b66d0c13a863097dde2d/rignore-0.7.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c5e53b752f9de44dff7b3be3c98455ce3bf88e69d6dc0cf4f213346c5e3416c", size = 959461, upload-time = "2025-11-05T20:42:08.476Z" }, - { url = "https://files.pythonhosted.org/packages/b5/87/1e1a145731f73bdb7835e11f80da06f79a00d68b370d9a847de979575e6d/rignore-0.7.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25b3536d13a5d6409ce85f23936f044576eeebf7b6db1d078051b288410fc049", size = 985323, upload-time = "2025-11-05T20:41:52.735Z" }, - { url = "https://files.pythonhosted.org/packages/6c/31/1ecff992fc3f59c4fcdcb6c07d5f6c1e6dfb55ccda19c083aca9d86fa1c6/rignore-0.7.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e01cad2b0b92f6b1993f29fc01f23f2d78caf4bf93b11096d28e9d578eb08ce", size = 1079173, upload-time = "2025-11-05T21:40:12.007Z" }, - { url = "https://files.pythonhosted.org/packages/17/18/162eedadb4c2282fa4c521700dbf93c9b14b8842e8354f7d72b445b8d593/rignore-0.7.6-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5991e46ab9b4868334c9e372ab0892b0150f3f586ff2b1e314272caeb38aaedb", size = 1139012, upload-time = "2025-11-05T21:40:29.399Z" }, - { url = "https://files.pythonhosted.org/packages/78/96/a9ca398a8af74bb143ad66c2a31303c894111977e28b0d0eab03867f1b43/rignore-0.7.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6c8ae562e5d1246cba5eaeb92a47b2a279e7637102828dde41dcbe291f529a3e", size = 1118827, upload-time = "2025-11-05T21:40:46.6Z" }, - { url = "https://files.pythonhosted.org/packages/9f/22/1c1a65047df864def9a047dbb40bc0b580b8289a4280e62779cd61ae21f2/rignore-0.7.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:aaf938530dcc0b47c4cfa52807aa2e5bfd5ca6d57a621125fe293098692f6345", size = 1128182, upload-time = "2025-11-05T21:41:04.239Z" }, - { url = "https://files.pythonhosted.org/packages/bd/f4/1526eb01fdc2235aca1fd9d0189bee4021d009a8dcb0161540238c24166e/rignore-0.7.6-cp311-cp311-win32.whl", hash = "sha256:166ebce373105dd485ec213a6a2695986346e60c94ff3d84eb532a237b24a4d5", size = 646547, upload-time = "2025-11-05T21:41:49.439Z" }, - { url = "https://files.pythonhosted.org/packages/7c/c8/dda0983e1845706beb5826459781549a840fe5a7eb934abc523e8cd17814/rignore-0.7.6-cp311-cp311-win_amd64.whl", hash = "sha256:44f35ee844b1a8cea50d056e6a595190ce9d42d3cccf9f19d280ae5f3058973a", size = 727139, upload-time = "2025-11-05T21:41:34.367Z" }, - { url = "https://files.pythonhosted.org/packages/e3/47/eb1206b7bf65970d41190b879e1723fc6bbdb2d45e53565f28991a8d9d96/rignore-0.7.6-cp311-cp311-win_arm64.whl", hash = "sha256:14b58f3da4fa3d5c3fa865cab49821675371f5e979281c683e131ae29159a581", size = 657598, upload-time = "2025-11-05T21:41:23.758Z" }, { url = "https://files.pythonhosted.org/packages/0b/0e/012556ef3047a2628842b44e753bb15f4dc46806780ff090f1e8fe4bf1eb/rignore-0.7.6-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:03e82348cb7234f8d9b2834f854400ddbbd04c0f8f35495119e66adbd37827a8", size = 883488, upload-time = "2025-11-05T20:42:41.359Z" }, { url = "https://files.pythonhosted.org/packages/93/b0/d4f1f3fe9eb3f8e382d45ce5b0547ea01c4b7e0b4b4eb87bcd66a1d2b888/rignore-0.7.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9e624f6be6116ea682e76c5feb71ea91255c67c86cb75befe774365b2931961", size = 820411, upload-time = "2025-11-05T20:42:24.782Z" }, { url = "https://files.pythonhosted.org/packages/4a/c8/dea564b36dedac8de21c18e1851789545bc52a0c22ece9843444d5608a6a/rignore-0.7.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bda49950d405aa8d0ebe26af807c4e662dd281d926530f03f29690a2e07d649a", size = 897821, upload-time = "2025-11-05T20:40:52.613Z" }, @@ -7401,18 +6357,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fc/d3/18210222b37e87e36357f7b300b7d98c6dd62b133771e71ae27acba83a4f/rignore-0.7.6-cp314-cp314t-win32.whl", hash = "sha256:c1d8f117f7da0a4a96a8daef3da75bc090e3792d30b8b12cfadc240c631353f9", size = 647033, upload-time = "2025-11-05T21:42:00.095Z" }, { url = "https://files.pythonhosted.org/packages/3e/87/033eebfbee3ec7d92b3bb1717d8f68c88e6fc7de54537040f3b3a405726f/rignore-0.7.6-cp314-cp314t-win_amd64.whl", hash = "sha256:ca36e59408bec81de75d307c568c2d0d410fb880b1769be43611472c61e85c96", size = 725647, upload-time = "2025-11-05T21:41:44.449Z" }, { url = "https://files.pythonhosted.org/packages/79/62/b88e5879512c55b8ee979c666ee6902adc4ed05007226de266410ae27965/rignore-0.7.6-cp314-cp314t-win_arm64.whl", hash = "sha256:b83adabeb3e8cf662cabe1931b83e165b88c526fa6af6b3aa90429686e474896", size = 656035, upload-time = "2025-11-05T21:41:31.13Z" }, - { url = "https://files.pythonhosted.org/packages/82/78/a6250ff0c49a3cdb943910ada4116e708118e9b901c878cfae616c80a904/rignore-0.7.6-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a20b6fb61bcced9a83dfcca6599ad45182b06ba720cff7c8d891e5b78db5b65f", size = 886470, upload-time = "2025-11-05T20:42:52.314Z" }, - { url = "https://files.pythonhosted.org/packages/35/af/c69c0c51b8f9f7914d95c4ea91c29a2ac067572048cae95dd6d2efdbe05d/rignore-0.7.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:392dcabfecbe176c9ebbcb40d85a5e86a5989559c4f988c2741da7daf1b5be25", size = 825976, upload-time = "2025-11-05T20:42:35.118Z" }, - { url = "https://files.pythonhosted.org/packages/f1/d2/1b264f56132264ea609d3213ab603d6a27016b19559a1a1ede1a66a03dcd/rignore-0.7.6-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22baa462abdc36fdd5a5e2dae423107723351b85ff093762f9261148b9d0a04a", size = 899739, upload-time = "2025-11-05T20:41:01.518Z" }, - { url = "https://files.pythonhosted.org/packages/55/e4/b3c5dfdd8d8a10741dfe7199ef45d19a0e42d0c13aa377c83bd6caf65d90/rignore-0.7.6-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53fb28882d2538cb2d231972146c4927a9d9455e62b209f85d634408c4103538", size = 874843, upload-time = "2025-11-05T20:41:17.687Z" }, - { url = "https://files.pythonhosted.org/packages/cc/10/d6f3750233881a2a154cefc9a6a0a9b19da526b19f7f08221b552c6f827d/rignore-0.7.6-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87409f7eeb1103d6b77f3472a3a0d9a5953e3ae804a55080bdcb0120ee43995b", size = 1170348, upload-time = "2025-11-05T20:41:34.21Z" }, - { url = "https://files.pythonhosted.org/packages/6e/10/ad98ca05c9771c15af734cee18114a3c280914b6e34fde9ffea2e61e88aa/rignore-0.7.6-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:684014e42e4341ab3ea23a203551857fcc03a7f8ae96ca3aefb824663f55db32", size = 942315, upload-time = "2025-11-05T20:41:48.508Z" }, - { url = "https://files.pythonhosted.org/packages/de/00/ab5c0f872acb60d534e687e629c17e0896c62da9b389c66d3aa16b817aa8/rignore-0.7.6-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77356ebb01ba13f8a425c3d30fcad40e57719c0e37670d022d560884a30e4767", size = 961047, upload-time = "2025-11-05T20:42:19.403Z" }, - { url = "https://files.pythonhosted.org/packages/b8/86/3030fdc363a8f0d1cd155b4c453d6db9bab47a24fcc64d03f61d9d78fe6a/rignore-0.7.6-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6cbd8a48abbd3747a6c830393cd578782fab5d43f4deea48c5f5e344b8fed2b0", size = 986090, upload-time = "2025-11-05T20:42:03.581Z" }, - { url = "https://files.pythonhosted.org/packages/33/b8/133aa4002cee0ebbb39362f94e4898eec7fbd09cec9fcbce1cd65b355b7f/rignore-0.7.6-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2673225dcec7f90497e79438c35e34638d0d0391ccea3cbb79bfb9adc0dc5bd7", size = 1079656, upload-time = "2025-11-05T21:40:24.89Z" }, - { url = "https://files.pythonhosted.org/packages/67/56/36d5d34210e5e7dfcd134eed8335b19e80ae940ee758f493e4f2b344dd70/rignore-0.7.6-pp311-pypy311_pp73-musllinux_1_2_armv7l.whl", hash = "sha256:c081f17290d8a2b96052b79207622aa635686ea39d502b976836384ede3d303c", size = 1139789, upload-time = "2025-11-05T21:40:42.119Z" }, - { url = "https://files.pythonhosted.org/packages/6b/5b/bb4f9420802bf73678033a4a55ab1bede36ce2e9b41fec5f966d83d932b3/rignore-0.7.6-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:57e8327aacc27f921968cb2a174f9e47b084ce9a7dd0122c8132d22358f6bd79", size = 1120308, upload-time = "2025-11-05T21:40:59.402Z" }, - { url = "https://files.pythonhosted.org/packages/ce/8b/a1299085b28a2f6135e30370b126e3c5055b61908622f2488ade67641479/rignore-0.7.6-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:d8955b57e42f2a5434670d5aa7b75eaf6e74602ccd8955dddf7045379cd762fb", size = 1129444, upload-time = "2025-11-05T21:41:17.906Z" }, ] [[package]] @@ -7421,21 +6365,6 @@ version = "0.30.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425", size = 370157, upload-time = "2025-11-30T20:21:53.789Z" }, - { url = "https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d", size = 359676, upload-time = "2025-11-30T20:21:55.475Z" }, - { url = "https://files.pythonhosted.org/packages/84/86/04dbba1b087227747d64d80c3b74df946b986c57af0a9f0c98726d4d7a3b/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4", size = 389938, upload-time = "2025-11-30T20:21:57.079Z" }, - { url = "https://files.pythonhosted.org/packages/42/bb/1463f0b1722b7f45431bdd468301991d1328b16cffe0b1c2918eba2c4eee/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f", size = 402932, upload-time = "2025-11-30T20:21:58.47Z" }, - { url = "https://files.pythonhosted.org/packages/99/ee/2520700a5c1f2d76631f948b0736cdf9b0acb25abd0ca8e889b5c62ac2e3/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4", size = 525830, upload-time = "2025-11-30T20:21:59.699Z" }, - { url = "https://files.pythonhosted.org/packages/e0/ad/bd0331f740f5705cc555a5e17fdf334671262160270962e69a2bdef3bf76/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97", size = 412033, upload-time = "2025-11-30T20:22:00.991Z" }, - { url = "https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89", size = 390828, upload-time = "2025-11-30T20:22:02.723Z" }, - { url = "https://files.pythonhosted.org/packages/ab/2b/d88bb33294e3e0c76bc8f351a3721212713629ffca1700fa94979cb3eae8/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d", size = 404683, upload-time = "2025-11-30T20:22:04.367Z" }, - { url = "https://files.pythonhosted.org/packages/50/32/c759a8d42bcb5289c1fac697cd92f6fe01a018dd937e62ae77e0e7f15702/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038", size = 421583, upload-time = "2025-11-30T20:22:05.814Z" }, - { url = "https://files.pythonhosted.org/packages/2b/81/e729761dbd55ddf5d84ec4ff1f47857f4374b0f19bdabfcf929164da3e24/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7", size = 572496, upload-time = "2025-11-30T20:22:07.713Z" }, - { url = "https://files.pythonhosted.org/packages/14/f6/69066a924c3557c9c30baa6ec3a0aa07526305684c6f86c696b08860726c/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed", size = 598669, upload-time = "2025-11-30T20:22:09.312Z" }, - { url = "https://files.pythonhosted.org/packages/5f/48/905896b1eb8a05630d20333d1d8ffd162394127b74ce0b0784ae04498d32/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85", size = 561011, upload-time = "2025-11-30T20:22:11.309Z" }, - { url = "https://files.pythonhosted.org/packages/22/16/cd3027c7e279d22e5eb431dd3c0fbc677bed58797fe7581e148f3f68818b/rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c", size = 221406, upload-time = "2025-11-30T20:22:13.101Z" }, - { url = "https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825", size = 236024, upload-time = "2025-11-30T20:22:14.853Z" }, - { url = "https://files.pythonhosted.org/packages/14/a6/364bba985e4c13658edb156640608f2c9e1d3ea3c81b27aa9d889fff0e31/rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229", size = 229069, upload-time = "2025-11-30T20:22:16.577Z" }, { url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad", size = 375086, upload-time = "2025-11-30T20:22:17.93Z" }, { url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05", size = 359053, upload-time = "2025-11-30T20:22:19.297Z" }, { url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28", size = 390763, upload-time = "2025-11-30T20:22:21.661Z" }, @@ -7509,18 +6438,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030, upload-time = "2025-11-30T20:24:10.956Z" }, { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570, upload-time = "2025-11-30T20:24:12.735Z" }, { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532, upload-time = "2025-11-30T20:24:14.634Z" }, - { url = "https://files.pythonhosted.org/packages/69/71/3f34339ee70521864411f8b6992e7ab13ac30d8e4e3309e07c7361767d91/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58", size = 372292, upload-time = "2025-11-30T20:24:16.537Z" }, - { url = "https://files.pythonhosted.org/packages/57/09/f183df9b8f2d66720d2ef71075c59f7e1b336bec7ee4c48f0a2b06857653/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a", size = 362128, upload-time = "2025-11-30T20:24:18.086Z" }, - { url = "https://files.pythonhosted.org/packages/7a/68/5c2594e937253457342e078f0cc1ded3dd7b2ad59afdbf2d354869110a02/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb", size = 391542, upload-time = "2025-11-30T20:24:20.092Z" }, - { url = "https://files.pythonhosted.org/packages/49/5c/31ef1afd70b4b4fbdb2800249f34c57c64beb687495b10aec0365f53dfc4/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c", size = 404004, upload-time = "2025-11-30T20:24:22.231Z" }, - { url = "https://files.pythonhosted.org/packages/e3/63/0cfbea38d05756f3440ce6534d51a491d26176ac045e2707adc99bb6e60a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3", size = 527063, upload-time = "2025-11-30T20:24:24.302Z" }, - { url = "https://files.pythonhosted.org/packages/42/e6/01e1f72a2456678b0f618fc9a1a13f882061690893c192fcad9f2926553a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5", size = 413099, upload-time = "2025-11-30T20:24:25.916Z" }, - { url = "https://files.pythonhosted.org/packages/b8/25/8df56677f209003dcbb180765520c544525e3ef21ea72279c98b9aa7c7fb/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738", size = 392177, upload-time = "2025-11-30T20:24:27.834Z" }, - { url = "https://files.pythonhosted.org/packages/4a/b4/0a771378c5f16f8115f796d1f437950158679bcd2a7c68cf251cfb00ed5b/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f", size = 406015, upload-time = "2025-11-30T20:24:29.457Z" }, - { url = "https://files.pythonhosted.org/packages/36/d8/456dbba0af75049dc6f63ff295a2f92766b9d521fa00de67a2bd6427d57a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877", size = 423736, upload-time = "2025-11-30T20:24:31.22Z" }, - { url = "https://files.pythonhosted.org/packages/13/64/b4d76f227d5c45a7e0b796c674fd81b0a6c4fbd48dc29271857d8219571c/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a", size = 573981, upload-time = "2025-11-30T20:24:32.934Z" }, - { url = "https://files.pythonhosted.org/packages/20/91/092bacadeda3edf92bf743cc96a7be133e13a39cdbfd7b5082e7ab638406/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4", size = 599782, upload-time = "2025-11-30T20:24:35.169Z" }, - { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" }, ] [[package]] @@ -7599,19 +6516,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/5c/ce583cfbba69f4f989658c7e984b1175d4e1f5f19132d9554a5ff7031647/runpod-1.8.1-py3-none-any.whl", hash = "sha256:2cc36ce80c02b7b6f54216154345e5064bfa510718acfc684cd9f56ac506d518", size = 157526, upload-time = "2025-11-19T22:54:06.968Z" }, ] -[[package]] -name = "s3fs" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "botocore" }, - { name = "fsspec" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d9/9a/504cb277632c4d325beabbd03bb43778f0decb9be22d9e0e6c62f44540c7/s3fs-0.4.2.tar.gz", hash = "sha256:2ca5de8dc18ad7ad350c0bd01aef0406aa5d0fff78a561f0f710f9d9858abdd0", size = 57527, upload-time = "2020-03-31T15:24:26.388Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/e4/b8fc59248399d2482b39340ec9be4bb2493846ac23641b43115a7e5cd675/s3fs-0.4.2-py3-none-any.whl", hash = "sha256:91c1dfb45e5217bd441a7a560946fe865ced6225ff7eb0fb459fe6e601a95ed3", size = 19791, upload-time = "2020-03-31T15:24:24.952Z" }, -] - [[package]] name = "s3transfer" version = "0.16.0" @@ -7658,12 +6562,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/0e/d4/40988bf3b8e34feec1d0e6a051446b1f66225f8529b9309becaeef62b6c4/scikit_learn-1.8.0.tar.gz", hash = "sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd", size = 7335585, upload-time = "2025-12-10T07:08:53.618Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/92/53ea2181da8ac6bf27170191028aee7251f8f841f8d3edbfdcaf2008fde9/scikit_learn-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:146b4d36f800c013d267b29168813f7a03a43ecd2895d04861f1240b564421da", size = 8595835, upload-time = "2025-12-10T07:07:39.385Z" }, - { url = "https://files.pythonhosted.org/packages/01/18/d154dc1638803adf987910cdd07097d9c526663a55666a97c124d09fb96a/scikit_learn-1.8.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f984ca4b14914e6b4094c5d52a32ea16b49832c03bd17a110f004db3c223e8e1", size = 8080381, upload-time = "2025-12-10T07:07:41.93Z" }, - { url = "https://files.pythonhosted.org/packages/8a/44/226142fcb7b7101e64fdee5f49dbe6288d4c7af8abf593237b70fca080a4/scikit_learn-1.8.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e30adb87f0cc81c7690a84f7932dd66be5bac57cfe16b91cb9151683a4a2d3b", size = 8799632, upload-time = "2025-12-10T07:07:43.899Z" }, - { url = "https://files.pythonhosted.org/packages/36/4d/4a67f30778a45d542bbea5db2dbfa1e9e100bf9ba64aefe34215ba9f11f6/scikit_learn-1.8.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ada8121bcb4dac28d930febc791a69f7cb1673c8495e5eee274190b73a4559c1", size = 9103788, upload-time = "2025-12-10T07:07:45.982Z" }, - { url = "https://files.pythonhosted.org/packages/89/3c/45c352094cfa60050bcbb967b1faf246b22e93cb459f2f907b600f2ceda5/scikit_learn-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:c57b1b610bd1f40ba43970e11ce62821c2e6569e4d74023db19c6b26f246cb3b", size = 8081706, upload-time = "2025-12-10T07:07:48.111Z" }, - { url = "https://files.pythonhosted.org/packages/3d/46/5416595bb395757f754feb20c3d776553a386b661658fb21b7c814e89efe/scikit_learn-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:2838551e011a64e3053ad7618dda9310175f7515f1742fa2d756f7c874c05961", size = 7688451, upload-time = "2025-12-10T07:07:49.873Z" }, { url = "https://files.pythonhosted.org/packages/90/74/e6a7cc4b820e95cc38cf36cd74d5aa2b42e8ffc2d21fe5a9a9c45c1c7630/scikit_learn-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5fb63362b5a7ddab88e52b6dbb47dac3fd7dafeee740dc6c8d8a446ddedade8e", size = 8548242, upload-time = "2025-12-10T07:07:51.568Z" }, { url = "https://files.pythonhosted.org/packages/49/d8/9be608c6024d021041c7f0b3928d4749a706f4e2c3832bbede4fb4f58c95/scikit_learn-1.8.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:5025ce924beccb28298246e589c691fe1b8c1c96507e6d27d12c5fadd85bfd76", size = 8079075, upload-time = "2025-12-10T07:07:53.697Z" }, { url = "https://files.pythonhosted.org/packages/dd/47/f187b4636ff80cc63f21cd40b7b2d177134acaa10f6bb73746130ee8c2e5/scikit_learn-1.8.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4496bb2cf7a43ce1a2d7524a79e40bc5da45cf598dbf9545b7e8316ccba47bb4", size = 8660492, upload-time = "2025-12-10T07:07:55.574Z" }, @@ -7705,16 +6603,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/75/b4ce781849931fef6fd529afa6b63711d5a733065722d0c3e2724af9e40a/scipy-1.17.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:1f95b894f13729334fb990162e911c9e5dc1ab390c58aa6cbecb389c5b5e28ec", size = 31613675, upload-time = "2026-02-23T00:16:00.13Z" }, - { url = "https://files.pythonhosted.org/packages/f7/58/bccc2861b305abdd1b8663d6130c0b3d7cc22e8d86663edbc8401bfd40d4/scipy-1.17.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:e18f12c6b0bc5a592ed23d3f7b891f68fd7f8241d69b7883769eb5d5dfb52696", size = 28162057, upload-time = "2026-02-23T00:16:09.456Z" }, - { url = "https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a3472cfbca0a54177d0faa68f697d8ba4c80bbdc19908c3465556d9f7efce9ee", size = 20334032, upload-time = "2026-02-23T00:16:17.358Z" }, - { url = "https://files.pythonhosted.org/packages/ec/e6/cef1cf3557f0c54954198554a10016b6a03b2ec9e22a4e1df734936bd99c/scipy-1.17.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:766e0dc5a616d026a3a1cffa379af959671729083882f50307e18175797b3dfd", size = 22709533, upload-time = "2026-02-23T00:16:25.791Z" }, - { url = "https://files.pythonhosted.org/packages/4d/60/8804678875fc59362b0fb759ab3ecce1f09c10a735680318ac30da8cd76b/scipy-1.17.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:744b2bf3640d907b79f3fd7874efe432d1cf171ee721243e350f55234b4cec4c", size = 33062057, upload-time = "2026-02-23T00:16:36.931Z" }, - { url = "https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4", size = 35349300, upload-time = "2026-02-23T00:16:49.108Z" }, - { url = "https://files.pythonhosted.org/packages/b4/3d/7ccbbdcbb54c8fdc20d3b6930137c782a163fa626f0aef920349873421ba/scipy-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd96a1898c0a47be4520327e01f874acfd61fb48a9420f8aa9f6483412ffa444", size = 35127333, upload-time = "2026-02-23T00:17:01.293Z" }, - { url = "https://files.pythonhosted.org/packages/e8/19/f926cb11c42b15ba08e3a71e376d816ac08614f769b4f47e06c3580c836a/scipy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4eb6c25dd62ee8d5edf68a8e1c171dd71c292fdae95d8aeb3dd7d7de4c364082", size = 37741314, upload-time = "2026-02-23T00:17:12.576Z" }, - { url = "https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff", size = 36607512, upload-time = "2026-02-23T00:17:23.424Z" }, - { url = "https://files.pythonhosted.org/packages/68/7f/bdd79ceaad24b671543ffe0ef61ed8e659440eb683b66f033454dcee90eb/scipy-1.17.1-cp311-cp311-win_arm64.whl", hash = "sha256:9ecb4efb1cd6e8c4afea0daa91a87fbddbce1b99d2895d151596716c0b2e859d", size = 24599248, upload-time = "2026-02-23T00:17:34.561Z" }, { url = "https://files.pythonhosted.org/packages/35/48/b992b488d6f299dbe3f11a20b24d3dda3d46f1a635ede1c46b5b17a7b163/scipy-1.17.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:35c3a56d2ef83efc372eaec584314bd0ef2e2f0d2adb21c55e6ad5b344c0dcb8", size = 31610954, upload-time = "2026-02-23T00:17:49.855Z" }, { url = "https://files.pythonhosted.org/packages/b2/02/cf107b01494c19dc100f1d0b7ac3cc08666e96ba2d64db7626066cee895e/scipy-1.17.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:fcb310ddb270a06114bb64bbe53c94926b943f5b7f0842194d585c65eb4edd76", size = 28172662, upload-time = "2026-02-23T00:18:01.64Z" }, { url = "https://files.pythonhosted.org/packages/cf/a9/599c28631bad314d219cf9ffd40e985b24d603fc8a2f4ccc5ae8419a535b/scipy-1.17.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:cc90d2e9c7e5c7f1a482c9875007c095c3194b1cfedca3c2f3291cdc2bc7c086", size = 20344366, upload-time = "2026-02-23T00:18:12.015Z" }, @@ -7809,14 +6697,6 @@ version = "0.2.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/15/15/2e7a025fc62d764b151ae6d0f2a92f8081755ebe8d4a64099accc6f77ba6/sentencepiece-0.2.1.tar.gz", hash = "sha256:8138cec27c2f2282f4a34d9a016e3374cd40e5c6e9cb335063db66a0a3b71fad", size = 3228515, upload-time = "2025-08-12T07:00:51.718Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d8/15/46afbab00733d81788b64be430ca1b93011bb9388527958e26cc31832de5/sentencepiece-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6356d0986b8b8dc351b943150fcd81a1c6e6e4d439772e8584c64230e58ca987", size = 1942560, upload-time = "2025-08-12T06:59:25.82Z" }, - { url = "https://files.pythonhosted.org/packages/fa/79/7c01b8ef98a0567e9d84a4e7a910f8e7074fcbf398a5cd76f93f4b9316f9/sentencepiece-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8f8ba89a3acb3dc1ae90f65ec1894b0b9596fdb98ab003ff38e058f898b39bc7", size = 1325385, upload-time = "2025-08-12T06:59:27.722Z" }, - { url = "https://files.pythonhosted.org/packages/bb/88/2b41e07bd24f33dcf2f18ec3b74247aa4af3526bad8907b8727ea3caba03/sentencepiece-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:02593eca45440ef39247cee8c47322a34bdcc1d8ae83ad28ba5a899a2cf8d79a", size = 1253319, upload-time = "2025-08-12T06:59:29.306Z" }, - { url = "https://files.pythonhosted.org/packages/a0/54/38a1af0c6210a3c6f95aa46d23d6640636d020fba7135cd0d9a84ada05a7/sentencepiece-0.2.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a0d15781a171d188b661ae4bde1d998c303f6bd8621498c50c671bd45a4798e", size = 1316162, upload-time = "2025-08-12T06:59:30.914Z" }, - { url = "https://files.pythonhosted.org/packages/ef/66/fb191403ade791ad2c3c1e72fe8413e63781b08cfa3aa4c9dfc536d6e795/sentencepiece-0.2.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f5a3e0d9f445ed9d66c0fec47d4b23d12cfc858b407a03c194c1b26c2ac2a63", size = 1387785, upload-time = "2025-08-12T06:59:32.491Z" }, - { url = "https://files.pythonhosted.org/packages/a9/2d/3bd9b08e70067b2124518b308db6a84a4f8901cc8a4317e2e4288cdd9b4d/sentencepiece-0.2.1-cp311-cp311-win32.whl", hash = "sha256:6d297a1748d429ba8534eebe5535448d78b8acc32d00a29b49acf28102eeb094", size = 999555, upload-time = "2025-08-12T06:59:34.475Z" }, - { url = "https://files.pythonhosted.org/packages/32/b8/f709977f5fda195ae1ea24f24e7c581163b6f142b1005bc3d0bbfe4d7082/sentencepiece-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:82d9ead6591015f009cb1be1cb1c015d5e6f04046dbb8c9588b931e869a29728", size = 1054617, upload-time = "2025-08-12T06:59:36.461Z" }, - { url = "https://files.pythonhosted.org/packages/7a/40/a1fc23be23067da0f703709797b464e8a30a1c78cc8a687120cd58d4d509/sentencepiece-0.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:39f8651bd10974eafb9834ce30d9bcf5b73e1fc798a7f7d2528f9820ca86e119", size = 1033877, upload-time = "2025-08-12T06:59:38.391Z" }, { url = "https://files.pythonhosted.org/packages/4a/be/32ce495aa1d0e0c323dcb1ba87096037358edee539cac5baf8755a6bd396/sentencepiece-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:57cae326c8727de58c85977b175af132a7138d84c764635d7e71bbee7e774133", size = 1943152, upload-time = "2025-08-12T06:59:40.048Z" }, { url = "https://files.pythonhosted.org/packages/88/7e/ff23008899a58678e98c6ff592bf4d368eee5a71af96d0df6b38a039dd4f/sentencepiece-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:56dd39a3c4d6493db3cdca7e8cc68c6b633f0d4195495cbadfcf5af8a22d05a6", size = 1325651, upload-time = "2025-08-12T06:59:41.536Z" }, { url = "https://files.pythonhosted.org/packages/19/84/42eb3ce4796777a1b5d3699dfd4dca85113e68b637f194a6c8d786f16a04/sentencepiece-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d9381351182ff9888cc80e41c632e7e274b106f450de33d67a9e8f6043da6f76", size = 1253645, upload-time = "2025-08-12T06:59:42.903Z" }, @@ -7878,16 +6758,6 @@ version = "1.3.7" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/8d/48/49393a96a2eef1ab418b17475fb92b8fcfad83d099e678751b05472e69de/setproctitle-1.3.7.tar.gz", hash = "sha256:bc2bc917691c1537d5b9bca1468437176809c7e11e5694ca79a9ca12345dcb9e", size = 27002, upload-time = "2025-09-05T12:51:25.278Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/cd/1b7ba5cad635510720ce19d7122154df96a2387d2a74217be552887c93e5/setproctitle-1.3.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a600eeb4145fb0ee6c287cb82a2884bd4ec5bbb076921e287039dcc7b7cc6dd0", size = 18085, upload-time = "2025-09-05T12:49:22.183Z" }, - { url = "https://files.pythonhosted.org/packages/8f/1a/b2da0a620490aae355f9d72072ac13e901a9fec809a6a24fc6493a8f3c35/setproctitle-1.3.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:97a090fed480471bb175689859532709e28c085087e344bca45cf318034f70c4", size = 13097, upload-time = "2025-09-05T12:49:23.322Z" }, - { url = "https://files.pythonhosted.org/packages/18/2e/bd03ff02432a181c1787f6fc2a678f53b7dacdd5ded69c318fe1619556e8/setproctitle-1.3.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1607b963e7b53e24ec8a2cb4e0ab3ae591d7c6bf0a160feef0551da63452b37f", size = 32191, upload-time = "2025-09-05T12:49:24.567Z" }, - { url = "https://files.pythonhosted.org/packages/28/78/1e62fc0937a8549f2220445ed2175daacee9b6764c7963b16148119b016d/setproctitle-1.3.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a20fb1a3974e2dab857870cf874b325b8705605cb7e7e8bcbb915bca896f52a9", size = 33203, upload-time = "2025-09-05T12:49:25.871Z" }, - { url = "https://files.pythonhosted.org/packages/a0/3c/65edc65db3fa3df400cf13b05e9d41a3c77517b4839ce873aa6b4043184f/setproctitle-1.3.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f8d961bba676e07d77665204f36cffaa260f526e7b32d07ab3df6a2c1dfb44ba", size = 34963, upload-time = "2025-09-05T12:49:27.044Z" }, - { url = "https://files.pythonhosted.org/packages/a1/32/89157e3de997973e306e44152522385f428e16f92f3cf113461489e1e2ee/setproctitle-1.3.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:db0fd964fbd3a9f8999b502f65bd2e20883fdb5b1fae3a424e66db9a793ed307", size = 32398, upload-time = "2025-09-05T12:49:28.909Z" }, - { url = "https://files.pythonhosted.org/packages/4a/18/77a765a339ddf046844cb4513353d8e9dcd8183da9cdba6e078713e6b0b2/setproctitle-1.3.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:db116850fcf7cca19492030f8d3b4b6e231278e8fe097a043957d22ce1bdf3ee", size = 33657, upload-time = "2025-09-05T12:49:30.323Z" }, - { url = "https://files.pythonhosted.org/packages/6b/63/f0b6205c64d74d2a24a58644a38ec77bdbaa6afc13747e75973bf8904932/setproctitle-1.3.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:316664d8b24a5c91ee244460bdaf7a74a707adaa9e14fbe0dc0a53168bb9aba1", size = 31836, upload-time = "2025-09-05T12:49:32.309Z" }, - { url = "https://files.pythonhosted.org/packages/ba/51/e1277f9ba302f1a250bbd3eedbbee747a244b3cc682eb58fb9733968f6d8/setproctitle-1.3.7-cp311-cp311-win32.whl", hash = "sha256:b74774ca471c86c09b9d5037c8451fff06bb82cd320d26ae5a01c758088c0d5d", size = 12556, upload-time = "2025-09-05T12:49:33.529Z" }, - { url = "https://files.pythonhosted.org/packages/b6/7b/822a23f17e9003dfdee92cd72758441ca2a3680388da813a371b716fb07f/setproctitle-1.3.7-cp311-cp311-win_amd64.whl", hash = "sha256:acb9097213a8dd3410ed9f0dc147840e45ca9797785272928d4be3f0e69e3be4", size = 13243, upload-time = "2025-09-05T12:49:34.553Z" }, { url = "https://files.pythonhosted.org/packages/fb/f0/2dc88e842077719d7384d86cc47403e5102810492b33680e7dadcee64cd8/setproctitle-1.3.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2dc99aec591ab6126e636b11035a70991bc1ab7a261da428491a40b84376654e", size = 18049, upload-time = "2025-09-05T12:49:36.241Z" }, { url = "https://files.pythonhosted.org/packages/f0/b4/50940504466689cda65680c9e9a1e518e5750c10490639fa687489ac7013/setproctitle-1.3.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cdd8aa571b7aa39840fdbea620e308a19691ff595c3a10231e9ee830339dd798", size = 13079, upload-time = "2025-09-05T12:49:38.088Z" }, { url = "https://files.pythonhosted.org/packages/d0/99/71630546b9395b095f4082be41165d1078204d1696c2d9baade3de3202d0/setproctitle-1.3.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2906b6c7959cdb75f46159bf0acd8cc9906cf1361c9e1ded0d065fe8f9039629", size = 32932, upload-time = "2025-09-05T12:49:39.271Z" }, @@ -7938,9 +6808,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e7/e3/54b496ac724e60e61cc3447f02690105901ca6d90da0377dffe49ff99fc7/setproctitle-1.3.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1fae595d032b30dab4d659bece20debd202229fce12b55abab978b7f30783d73", size = 33958, upload-time = "2025-09-05T12:50:39.841Z" }, { url = "https://files.pythonhosted.org/packages/ea/a8/c84bb045ebf8c6fdc7f7532319e86f8380d14bbd3084e6348df56bdfe6fd/setproctitle-1.3.7-cp314-cp314t-win32.whl", hash = "sha256:02432f26f5d1329ab22279ff863c83589894977063f59e6c4b4845804a08f8c2", size = 12745, upload-time = "2025-09-05T12:50:41.377Z" }, { url = "https://files.pythonhosted.org/packages/08/b6/3a5a4f9952972791a9114ac01dfc123f0df79903577a3e0a7a404a695586/setproctitle-1.3.7-cp314-cp314t-win_amd64.whl", hash = "sha256:cbc388e3d86da1f766d8fc2e12682e446064c01cea9f88a88647cfe7c011de6a", size = 13469, upload-time = "2025-09-05T12:50:42.67Z" }, - { url = "https://files.pythonhosted.org/packages/c3/5b/5e1c117ac84e3cefcf8d7a7f6b2461795a87e20869da065a5c087149060b/setproctitle-1.3.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b1cac6a4b0252b8811d60b6d8d0f157c0fdfed379ac89c25a914e6346cf355a1", size = 12587, upload-time = "2025-09-05T12:51:21.195Z" }, - { url = "https://files.pythonhosted.org/packages/73/02/b9eadc226195dcfa90eed37afe56b5dd6fa2f0e5220ab8b7867b8862b926/setproctitle-1.3.7-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f1704c9e041f2b1dc38f5be4552e141e1432fba3dd52c72eeffd5bc2db04dc65", size = 14286, upload-time = "2025-09-05T12:51:22.61Z" }, - { url = "https://files.pythonhosted.org/packages/28/26/1be1d2a53c2a91ec48fa2ff4a409b395f836798adf194d99de9c059419ea/setproctitle-1.3.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b08b61976ffa548bd5349ce54404bf6b2d51bd74d4f1b241ed1b0f25bce09c3a", size = 13282, upload-time = "2025-09-05T12:51:24.094Z" }, ] [[package]] @@ -7976,17 +6843,6 @@ version = "4.1.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/0e/2a/54837395a3487c725669428d513293612a48d82b95a0642c936932e5d898/simplejson-4.1.1.tar.gz", hash = "sha256:c08eb9f7a90f77ae470e19a07472e9a79ebc0d1c2315d86a72767665bd5ba79f", size = 118860, upload-time = "2026-04-24T19:24:59.819Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/25/39013ffe279d90093ec1c848565b3683c586906c10fa55d9000ec29d046b/simplejson-4.1.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2867c64d92abd1992c15666fae198203093f593e43d6b81adf176bae530d493a", size = 111538, upload-time = "2026-04-24T19:22:49.051Z" }, - { url = "https://files.pythonhosted.org/packages/f2/ae/2c272971c8a87e2539c54a98eb6ff037bee1e2e93943c3986cf7500a4f3a/simplejson-4.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c47c46e16c8ea9e4850061e6ed5aa2b9cd2074cb2274bfd9c138cba15ce7453", size = 90594, upload-time = "2026-04-24T19:22:50.408Z" }, - { url = "https://files.pythonhosted.org/packages/4e/a2/6eebfb99dedc139f549200f61ade6d1890ac5707c5d427bdfa6fe39c9313/simplejson-4.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e294e33dbf316a9bbdd4030d46503c9b0f19470ae7ad6af5bae6c426bc2e869f", size = 90718, upload-time = "2026-04-24T19:22:51.694Z" }, - { url = "https://files.pythonhosted.org/packages/80/7e/c9e6c0c4ad8415e64dad0c47f619b556b02680a41631b4dbc281d55dc54d/simplejson-4.1.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7ce252b28fddbdd83db5bd7d93dad2a8a591d7ada098afec9c1b23d6b722a7a4", size = 180901, upload-time = "2026-04-24T19:22:53.025Z" }, - { url = "https://files.pythonhosted.org/packages/34/09/69e331e3994b1ed9be6ce9ace4ade704e7ed503edf869929ca7bb404eda8/simplejson-4.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c44ef6b02a4eb67ed17a72342341792149b3ff46f15426c26e970e49addf327", size = 178133, upload-time = "2026-04-24T19:22:54.574Z" }, - { url = "https://files.pythonhosted.org/packages/5d/40/ed806f24afef295c1032448f5ff6f6f2979392d5645ddb9f4fed7f38194d/simplejson-4.1.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:82bfca2b85a34178c25829c703f0a9e9f113a5af7539285bd3efb583a0bf1ba3", size = 188155, upload-time = "2026-04-24T19:22:56.044Z" }, - { url = "https://files.pythonhosted.org/packages/38/94/8d6f515b827b0f7881a49c8c1ac6920b7ae9428939ef04238c973278b42a/simplejson-4.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0e4b23f71dd781f8830f1663dc01a4944d3dbf87a1f93d78fba1cf64722d0ccf", size = 176225, upload-time = "2026-04-24T19:22:57.981Z" }, - { url = "https://files.pythonhosted.org/packages/c9/fd/6dffb4956563d48bbe46b91ff341adae34920e94008fd6b8d728072abfc7/simplejson-4.1.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:82fee635d7b73ad801030b05a75fbd34a098da0c2ecf600667a03636d09e1e42", size = 185535, upload-time = "2026-04-24T19:22:59.618Z" }, - { url = "https://files.pythonhosted.org/packages/de/d2/a509ee37763e79aec75d68f8521db1440306edeba3b8b4064ab4ee8bf1d9/simplejson-4.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68e62eda21192c5ea9bb92d571ca46a4477fef48762f50d433de2b4253051551", size = 179302, upload-time = "2026-04-24T19:23:01.324Z" }, - { url = "https://files.pythonhosted.org/packages/d8/23/5b343bfd2a79d3b6818e4db3586c405a001a090d4c89d336e31273ce7177/simplejson-4.1.1-cp311-cp311-win32.whl", hash = "sha256:ffd3d82294b47f5ec64050021ace95fd62628a0c1cc8bbf4d06d2d1fb697e055", size = 88408, upload-time = "2026-04-24T19:23:02.808Z" }, - { url = "https://files.pythonhosted.org/packages/38/04/df9b37aedbd524dca20840d25ebe01d6ae486b89792aeff5d15b9c4114f7/simplejson-4.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:78a3fe0995be42bed62a26aa78e0e0b4d87c6545785346b9cc898f3389569a35", size = 90526, upload-time = "2026-04-24T19:23:04.408Z" }, { url = "https://files.pythonhosted.org/packages/60/25/e90998fe8e480eb43b966c09e835379887d427567ebd496563d3b1e16b19/simplejson-4.1.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:19040a17154dc03d289bab68d73ce0a6a0be01de30c584bbdd93490bead14b22", size = 112414, upload-time = "2026-04-24T19:23:06.084Z" }, { url = "https://files.pythonhosted.org/packages/9c/a0/abd4785f36c3400f1fbb21f517be39295a750a714f04b7ee175adf6ef580/simplejson-4.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a94ebaecdbaa80d9551a3ec6bf0c9302fc8b53ab6c1b2bfd498a1df4cb28158d", size = 91120, upload-time = "2026-04-24T19:23:07.877Z" }, { url = "https://files.pythonhosted.org/packages/b8/78/fc060d2e3b13c6ec59288574b8efac64075e316b2afba4396a56b2422f78/simplejson-4.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:67341c95c0a168ab4a6d1e807e50463f1c8da932c3286d81e201266c427061fa", size = 91055, upload-time = "2026-04-24T19:23:09.264Z" }, @@ -8254,25 +7110,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, ] -[[package]] -name = "soundfile" -version = "0.13.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cffi" }, - { name = "numpy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e1/41/9b873a8c055582859b239be17902a85339bec6a30ad162f98c9b0288a2cc/soundfile-0.13.1.tar.gz", hash = "sha256:b2c68dab1e30297317080a5b43df57e302584c49e2942defdde0acccc53f0e5b", size = 46156, upload-time = "2025-01-25T09:17:04.831Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/28/e2a36573ccbcf3d57c00626a21fe51989380636e821b341d36ccca0c1c3a/soundfile-0.13.1-py2.py3-none-any.whl", hash = "sha256:a23c717560da2cf4c7b5ae1142514e0fd82d6bbd9dfc93a50423447142f2c445", size = 25751, upload-time = "2025-01-25T09:16:44.235Z" }, - { url = "https://files.pythonhosted.org/packages/ea/ab/73e97a5b3cc46bba7ff8650a1504348fa1863a6f9d57d7001c6b67c5f20e/soundfile-0.13.1-py2.py3-none-macosx_10_9_x86_64.whl", hash = "sha256:82dc664d19831933fe59adad199bf3945ad06d84bc111a5b4c0d3089a5b9ec33", size = 1142250, upload-time = "2025-01-25T09:16:47.583Z" }, - { url = "https://files.pythonhosted.org/packages/a0/e5/58fd1a8d7b26fc113af244f966ee3aecf03cb9293cb935daaddc1e455e18/soundfile-0.13.1-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:743f12c12c4054921e15736c6be09ac26b3b3d603aef6fd69f9dde68748f2593", size = 1101406, upload-time = "2025-01-25T09:16:49.662Z" }, - { url = "https://files.pythonhosted.org/packages/58/ae/c0e4a53d77cf6e9a04179535766b3321b0b9ced5f70522e4caf9329f0046/soundfile-0.13.1-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:9c9e855f5a4d06ce4213f31918653ab7de0c5a8d8107cd2427e44b42df547deb", size = 1235729, upload-time = "2025-01-25T09:16:53.018Z" }, - { url = "https://files.pythonhosted.org/packages/57/5e/70bdd9579b35003a489fc850b5047beeda26328053ebadc1fb60f320f7db/soundfile-0.13.1-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:03267c4e493315294834a0870f31dbb3b28a95561b80b134f0bd3cf2d5f0e618", size = 1313646, upload-time = "2025-01-25T09:16:54.872Z" }, - { url = "https://files.pythonhosted.org/packages/fe/df/8c11dc4dfceda14e3003bb81a0d0edcaaf0796dd7b4f826ea3e532146bba/soundfile-0.13.1-py2.py3-none-win32.whl", hash = "sha256:c734564fab7c5ddf8e9be5bf70bab68042cd17e9c214c06e365e20d64f9a69d5", size = 899881, upload-time = "2025-01-25T09:16:56.663Z" }, - { url = "https://files.pythonhosted.org/packages/14/e9/6b761de83277f2f02ded7e7ea6f07828ec78e4b229b80e4ca55dd205b9dc/soundfile-0.13.1-py2.py3-none-win_amd64.whl", hash = "sha256:1e70a05a0626524a69e9f0f4dd2ec174b4e9567f4d8b6c11d38b5c289be36ee9", size = 1019162, upload-time = "2025-01-25T09:16:59.573Z" }, -] - [[package]] name = "sqlalchemy" version = "2.0.48" @@ -8283,13 +7120,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/1f/73/b4a9737255583b5fa858e0bb8e116eb94b88c910164ed2ed719147bde3de/sqlalchemy-2.0.48.tar.gz", hash = "sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7", size = 9886075, upload-time = "2026-03-02T15:28:51.474Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/6d/b8b78b5b80f3c3ab3f7fa90faa195ec3401f6d884b60221260fd4d51864c/sqlalchemy-2.0.48-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc", size = 2157184, upload-time = "2026-03-02T15:38:28.161Z" }, - { url = "https://files.pythonhosted.org/packages/21/4b/4f3d4a43743ab58b95b9ddf5580a265b593d017693df9e08bd55780af5bb/sqlalchemy-2.0.48-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c", size = 3313555, upload-time = "2026-03-02T15:58:57.21Z" }, - { url = "https://files.pythonhosted.org/packages/21/dd/3b7c53f1dbbf736fd27041aee68f8ac52226b610f914085b1652c2323442/sqlalchemy-2.0.48-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7", size = 3313057, upload-time = "2026-03-02T15:52:29.366Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cc/3e600a90ae64047f33313d7d32e5ad025417f09d2ded487e8284b5e21a15/sqlalchemy-2.0.48-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d", size = 3265431, upload-time = "2026-03-02T15:58:59.096Z" }, - { url = "https://files.pythonhosted.org/packages/8b/19/780138dacfe3f5024f4cf96e4005e91edf6653d53d3673be4844578faf1d/sqlalchemy-2.0.48-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571", size = 3287646, upload-time = "2026-03-02T15:52:31.569Z" }, - { url = "https://files.pythonhosted.org/packages/40/fd/f32ced124f01a23151f4777e4c705f3a470adc7bd241d9f36a7c941a33bf/sqlalchemy-2.0.48-cp311-cp311-win32.whl", hash = "sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617", size = 2116956, upload-time = "2026-03-02T15:46:54.535Z" }, - { url = "https://files.pythonhosted.org/packages/58/d5/dd767277f6feef12d05651538f280277e661698f617fa4d086cce6055416/sqlalchemy-2.0.48-cp311-cp311-win_amd64.whl", hash = "sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c", size = 2141627, upload-time = "2026-03-02T15:46:55.849Z" }, { url = "https://files.pythonhosted.org/packages/ef/91/a42ae716f8925e9659df2da21ba941f158686856107a61cc97a95e7647a3/sqlalchemy-2.0.48-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b", size = 2155737, upload-time = "2026-03-02T15:49:13.207Z" }, { url = "https://files.pythonhosted.org/packages/b9/52/f75f516a1f3888f027c1cfb5d22d4376f4b46236f2e8669dcb0cddc60275/sqlalchemy-2.0.48-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb", size = 3337020, upload-time = "2026-03-02T15:50:34.547Z" }, { url = "https://files.pythonhosted.org/packages/37/9a/0c28b6371e0cdcb14f8f1930778cb3123acfcbd2c95bb9cf6b4a2ba0cce3/sqlalchemy-2.0.48-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894", size = 3349983, upload-time = "2026-03-02T15:53:25.542Z" }, @@ -8444,42 +7274,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/73/c6/825dab04195756cf8ff2e12698f22513b3db2f64925bdd41671bfb33aaa5/tensorboard_data_server-0.7.2-py3-none-manylinux_2_31_x86_64.whl", hash = "sha256:ef687163c24185ae9754ed5650eb5bc4d84ff257aabdc33f0cc6f74d8ba54530", size = 6590363, upload-time = "2023-10-23T21:23:35.583Z" }, ] -[[package]] -name = "tensorstore" -version = "0.1.82" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ml-dtypes" }, - { name = "numpy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cd/9b/43aedb544937f214dd7c665a7edf1b8b74f2f55d53ebd351c0ce69acf81a/tensorstore-0.1.82.tar.gz", hash = "sha256:ccfceffb7611fc61330f6da24b8b0abd9251d480ac8a5bac5a1729f9ed0c3a9f", size = 7160364, upload-time = "2026-03-13T00:22:16.888Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/d2/66513f1782dc52425bda0d5f7baae94ea639bbd226650ecb000223cc9359/tensorstore-0.1.82-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:6ae87ae9baf7593b5c8d09dbdf3ee6969068833a6fd85317b781a4cf7cb7e533", size = 16555813, upload-time = "2026-03-13T00:21:24.802Z" }, - { url = "https://files.pythonhosted.org/packages/04/4f/66a8af7dd6f5d8dabebe6edcdf0b87a06ac1f92318d972e9e6f5d3754b5d/tensorstore-0.1.82-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2471638a184473e384a6c3ffd98453b670a78372f2d3ed9707f27aebe5482c47", size = 14899141, upload-time = "2026-03-13T00:21:27.591Z" }, - { url = "https://files.pythonhosted.org/packages/36/50/7a9840eb6c9ec52348dcadf8ef2dca7b2cb7d3ae25bafb672a236fd885f4/tensorstore-0.1.82-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:38eed3828101622552e63564d7a3a10b0cecb05f61d40e0f236b95f622a60897", size = 19339518, upload-time = "2026-03-13T00:21:29.885Z" }, - { url = "https://files.pythonhosted.org/packages/1f/5f/85b42d1173b0ebbd1c11879f8ff60a72d7f5bbc111255d2c685a33813f2a/tensorstore-0.1.82-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aed5a6fc605e711c8a8dbd8ae73b919b8c6ca04ae94b0e0f6489fc54cdcab245", size = 20947623, upload-time = "2026-03-13T00:21:32.084Z" }, - { url = "https://files.pythonhosted.org/packages/11/23/dcbd9ab116d58d3a1ed9686102592c032b7ffd558aa8626fff1c18701ccd/tensorstore-0.1.82-cp311-cp311-win_amd64.whl", hash = "sha256:afb825258329241341aa3e64293b64562df7812a02d5f6c6e4c9f731d0e34b0e", size = 13387579, upload-time = "2026-03-13T00:21:34.393Z" }, - { url = "https://files.pythonhosted.org/packages/0d/c3/5ab0b99487b2596bdc0ebd3a569e50415949a63bad90b18e6476de91a7bb/tensorstore-0.1.82-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:f0ac091bd47ea6f051fe11230ad2642c254b46a8fabdd5184b0600556b5529ed", size = 16570668, upload-time = "2026-03-13T00:21:36.386Z" }, - { url = "https://files.pythonhosted.org/packages/aa/95/92b00a4b2e6192528a9c5bac9f53007acf4aa5d54943b9e114bedb72b2da/tensorstore-0.1.82-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8cae7d0c9b2fa0653f90b147daaf9ed04664cab7d297b9772efcfa088da26cab", size = 14904517, upload-time = "2026-03-13T00:21:38.464Z" }, - { url = "https://files.pythonhosted.org/packages/46/7e/c9c8ad65ee4015787e32d31bcf8278fcb27109e809f8334a64285bd73028/tensorstore-0.1.82-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34c491ea3c6c1904d4618bfe40020bd83aaeb19d52a266ea0f6919eb3fdc64c4", size = 19344428, upload-time = "2026-03-13T00:21:40.575Z" }, - { url = "https://files.pythonhosted.org/packages/f9/8a/590bb60a190d414abd2f83dd5b5148722d0c5d310a73e21b7a60ab98cf00/tensorstore-0.1.82-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4182300d8ffa172e961e79c6bd89e38ce6bc5cd3abf1a7dacb22c2396ce40b7", size = 20964954, upload-time = "2026-03-13T00:21:42.515Z" }, - { url = "https://files.pythonhosted.org/packages/43/1c/34e6e97426e1718106e9cb74d3045992bdea3ee368f9ea4ea25b809bdba8/tensorstore-0.1.82-cp312-cp312-win_amd64.whl", hash = "sha256:6369809d01edf66cd487cde5c94f57138167c09561f3d906020fd53c72687f92", size = 13393361, upload-time = "2026-03-13T00:21:44.443Z" }, - { url = "https://files.pythonhosted.org/packages/58/d1/0b39f577f047340f7c466e7f929aba0b83d33a852952ae2dc4242c141ee6/tensorstore-0.1.82-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:9874349ff23a9e94df361e7a0378efd3f22a1b14c1bb4d00905e6477eb56b732", size = 16570239, upload-time = "2026-03-13T00:21:46.655Z" }, - { url = "https://files.pythonhosted.org/packages/be/41/d33bea17f9afaee862f268fc10c364997267ab29b9be2aeebe01105cb38b/tensorstore-0.1.82-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cb2b87e8df78dc629e09a001d19b64813f249f9c78e4ade76de26e18f68bc591", size = 14904654, upload-time = "2026-03-13T00:21:48.708Z" }, - { url = "https://files.pythonhosted.org/packages/16/b9/f9f3d00e84724968d1111bbcf5b9ec2797496f4849e86a4fdea7278f7b0d/tensorstore-0.1.82-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3e0d4f5240247986c66154c3e6c71deed5ef337ae5a52509b3125c8045717bb3", size = 19343727, upload-time = "2026-03-13T00:21:50.664Z" }, - { url = "https://files.pythonhosted.org/packages/3b/8f/570fb1069b9789b47376bdc8129371bd3dc62bbaf57054816527e79ff88a/tensorstore-0.1.82-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f2c51d0c40a3a4e49590a1ec07494c518c46905c8f3ec1f5583120cfba3b2cf", size = 20964994, upload-time = "2026-03-13T00:21:52.918Z" }, - { url = "https://files.pythonhosted.org/packages/b2/d7/e1f168c6d82fd4af1acfade95f0ba4fe3593bac9e9a81ec074a80fe6258c/tensorstore-0.1.82-cp313-cp313-win_amd64.whl", hash = "sha256:82bbac5e11eeaa80ad1aedad1c7a8f1f4f39362c5f56906820b21fc34a497100", size = 13393826, upload-time = "2026-03-13T00:21:55.459Z" }, - { url = "https://files.pythonhosted.org/packages/95/c2/c75d42a223b5367ae0b7e10c847f6180139582cdaf51e30e28ad29721fd6/tensorstore-0.1.82-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:aa9d7b3f092a65b5573e6c9919bea1e16c909844f346c82407dc454a67a3fa11", size = 16574644, upload-time = "2026-03-13T00:21:57.382Z" }, - { url = "https://files.pythonhosted.org/packages/37/86/b2c19cc443c9fb69d682d0e5d67ac4c165edde4e4a92adbcaa6a1ec084ed/tensorstore-0.1.82-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32f70923d3a5dd687ebfd4eb9d0892766bff9acef92a468852c1872e96bbb440", size = 14906299, upload-time = "2026-03-13T00:21:59.563Z" }, - { url = "https://files.pythonhosted.org/packages/3e/71/e88cd2e6859adbd414669827800b98db646ce5156b264a34f4f0fbeb488b/tensorstore-0.1.82-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35607c5c0135d31c1b7bd821ad0446840161708a289df52cffc796d0321f3d60", size = 19345817, upload-time = "2026-03-13T00:22:01.682Z" }, - { url = "https://files.pythonhosted.org/packages/65/e8/48dfcf42c344980564e01052900fb2a3a28d90d515133fe69bdded70df6c/tensorstore-0.1.82-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:54d40a696115a8d13184920842a20c570bdb1cb3ba2352b05394814608290f6a", size = 20966508, upload-time = "2026-03-13T00:22:04.61Z" }, - { url = "https://files.pythonhosted.org/packages/16/65/2e465b576f61618a8a1a0e068811298a7338e9163713bcc24f5fe4abbf6c/tensorstore-0.1.82-cp314-cp314-win_amd64.whl", hash = "sha256:c7f63af7aabdf3a3e224d5b36c924bcb59ebc4fb8e485edc8fe13b8bf8b1ba32", size = 13785613, upload-time = "2026-03-13T00:22:06.643Z" }, - { url = "https://files.pythonhosted.org/packages/ee/e3/49a49e0b1605a58f31aed5ee3833b3a088984b16b5c3e7efaf34bd990ccb/tensorstore-0.1.82-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:69950d352327473014299a57f4c9fc7e0caa9c9e9100b3bc0a0c37f79c47fe6d", size = 16651920, upload-time = "2026-03-13T00:22:08.539Z" }, - { url = "https://files.pythonhosted.org/packages/77/69/bb0b929a2b1a1b72f15f6d9c5337b3ce0117de625f46345f56c815c106ee/tensorstore-0.1.82-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0224e20fad9ca9538c3e8ac4a32ef354acaa7ab2c130e4944c2eda58c3200742", size = 14988973, upload-time = "2026-03-13T00:22:10.493Z" }, - { url = "https://files.pythonhosted.org/packages/7e/e6/847146a4d802fd258eb032226ce3153167c4d0f44f4176633a77beb3af14/tensorstore-0.1.82-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c45dae1b34cad5bd56796e961c35ceb5a70617e4eb182faf73dd9cc4b21f3f87", size = 19365580, upload-time = "2026-03-13T00:22:12.679Z" }, - { url = "https://files.pythonhosted.org/packages/b3/06/46261b7ec4f6707edf9da8d4a2d68b4819b599e0f9b4906d5bfcec7fd5b2/tensorstore-0.1.82-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d8678ce55c4ca9daac815995d47aae6d3648c75dcdbb9f01326067ccc4de10a", size = 20981853, upload-time = "2026-03-13T00:22:14.817Z" }, -] - [[package]] name = "termcolor" version = "3.3.0" @@ -8498,44 +7292,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, ] -[[package]] -name = "tibs" -version = "0.5.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/cd/6cf028decf1c2df4d26077dd5d0532587d93d4917233d5e004133166a940/tibs-0.5.7.tar.gz", hash = "sha256:173dfbecb2309edd9771f453580c88cf251e775613461566b23dbd756b3d54cb", size = 78255, upload-time = "2026-03-12T13:06:29.79Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/4f/1149a5cf2c1be6862e1dcba0c22134c43c44f05ddeef4697ecf20067e508/tibs-0.5.7-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:01ea5258bdf942d21560dc07d532082cd04f07cfef65fedd58ae84f7d0d2562a", size = 401281, upload-time = "2026-03-12T13:06:25.78Z" }, - { url = "https://files.pythonhosted.org/packages/eb/af/59041580d51eb06077029cc64f0b2f9165b1c87075b7fe85f400e01ec6f9/tibs-0.5.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f5eea45851c960628a2bd29847765d55e19a687c5374456ad2c8cf6410eb1efa", size = 377945, upload-time = "2026-03-12T13:06:42.493Z" }, - { url = "https://files.pythonhosted.org/packages/ee/73/3b614d39221f02fca2f37dcdc1c65e25c963bf1da4b90ad9db393f9c130d/tibs-0.5.7-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a9feed5931b881809a950eca0e01e757113e2383a2af06a3e6982f110c869e2", size = 409620, upload-time = "2026-03-12T13:06:28.611Z" }, - { url = "https://files.pythonhosted.org/packages/16/a6/917ca6ca266135f0f52041700c4eb766097258dd987b81a630c061969db5/tibs-0.5.7-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:501728d096e10d9a165aa526743d47418a6bbfd7b084fa47ecb22be7641d3edb", size = 426017, upload-time = "2026-03-12T13:06:40.139Z" }, - { url = "https://files.pythonhosted.org/packages/ce/f6/3c795420f81bac44390d897712aebe186186d88ea5653e20f4ac5097b0b1/tibs-0.5.7-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77103a9f1af72ac4cf5006828d0fb21578d19ce55fd990e9a1c8e46fd549561f", size = 449717, upload-time = "2026-03-12T13:06:45.416Z" }, - { url = "https://files.pythonhosted.org/packages/98/00/700b97377b55973ac233a280d6ff81c0187710c73a5ac3356ef79bf15eb2/tibs-0.5.7-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f95d5db62960205a1e9eba73ce67dc14e7366ae080cd4e5b6f005ebd90faf02", size = 453131, upload-time = "2026-03-12T13:06:46.623Z" }, - { url = "https://files.pythonhosted.org/packages/6d/41/38ccfe6fe48432ea20f6e6a49a42aeb9662042e5f4e8f9a4029047a6c44a/tibs-0.5.7-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace018a057459e3dccd06a4aae1c5c8cd57e352b263dcef534ae39bf3e03b5cf", size = 419054, upload-time = "2026-03-12T13:06:27.25Z" }, - { url = "https://files.pythonhosted.org/packages/73/08/d9a66639564b92d5be07eb30bbd7a5b9052f338da09fd4ec3732346ff129/tibs-0.5.7-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2a618de62004d9217d2d2ab0f7f9bbdd098c12642dc01f07b3fb00f0b5f3131a", size = 448585, upload-time = "2026-03-12T13:06:33.306Z" }, - { url = "https://files.pythonhosted.org/packages/70/c1/24131985486d5bf878468226d9d0bdff5a0b04838b773a7339d22965f74e/tibs-0.5.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42725200f1b02687ed6e6a1c01e0ec150dc829d21d901ffc74cc0ac4d821f57f", size = 586259, upload-time = "2026-03-12T13:06:14.095Z" }, - { url = "https://files.pythonhosted.org/packages/02/0c/f74c6672d28054c55b6c593588792858be420dbf4b56d0adbf79fc1b7f8f/tibs-0.5.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:63255749f937c5e6fedcc7d54e7bd359aef711017e6855f373b0510a14ee2215", size = 701427, upload-time = "2026-03-12T13:06:37.234Z" }, - { url = "https://files.pythonhosted.org/packages/f4/bf/2c39836a5a1664cda596ba069d065322976245a5f86dab9f2b9a3eaff024/tibs-0.5.7-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:4b7510235379368b7523f624d46e0680f3706e3a3965877a6583cdcb598b8bac", size = 660754, upload-time = "2026-03-12T13:06:38.67Z" }, - { url = "https://files.pythonhosted.org/packages/1d/77/5a7a10001c38f4d1266d4f7a84fae27357c88834a0266bc401e37e1a7884/tibs-0.5.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29480bf03e3372a5f9cc59ea0541f76f8efd696d4f0d214715e94247c342a037", size = 631034, upload-time = "2026-03-12T13:06:18.1Z" }, - { url = "https://files.pythonhosted.org/packages/0d/be/bb20938ab5d1e63ee4c5cf78be815ab2a8674e7aa0b2500db210f7db3e6d/tibs-0.5.7-cp314-cp314t-win32.whl", hash = "sha256:b9535dc7b7484904a58b51bd8e64da7efbf1d8466ff7e84ed1d78f4ddc561c99", size = 278952, upload-time = "2026-03-12T13:06:20.285Z" }, - { url = "https://files.pythonhosted.org/packages/d5/9a/e76888e8567dbe02a67a27d46e5acf06e3504df1268ebc6d8313942ec560/tibs-0.5.7-cp314-cp314t-win_amd64.whl", hash = "sha256:1906729038b85c3b4c040aa28a456d85bc976d0c5007177350eb73374ffa0fd0", size = 294069, upload-time = "2026-03-12T13:06:15.756Z" }, - { url = "https://files.pythonhosted.org/packages/10/37/f74a5f4288984cb909dbccd4cc254154f3ed97b16db1913406f1bd2914c9/tibs-0.5.7-cp314-cp314t-win_arm64.whl", hash = "sha256:7d6592ed93c6748acd39df484c1ee24d40ee247c2a20ca38ba03363506fd24f3", size = 278929, upload-time = "2026-03-12T13:06:43.962Z" }, - { url = "https://files.pythonhosted.org/packages/12/2d/de2c579d3eea0f18212b5b16decb04568b7a0ef912d00581a77492609d4e/tibs-0.5.7-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:859f05315ffb307d3474c505d694f3a547f00730a024c982f5f60316a5505b3c", size = 411352, upload-time = "2026-03-12T13:06:52.016Z" }, - { url = "https://files.pythonhosted.org/packages/74/71/4c21ccc5c2e1672f9cd91ed2c46604c250cffd9d386113772dded128b5cf/tibs-0.5.7-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:a883ca13a922a66b2c1326a9c188123a574741a72510a4bf52fd6f97db191e44", size = 383971, upload-time = "2026-03-12T13:06:50.143Z" }, - { url = "https://files.pythonhosted.org/packages/38/85/399940ac5393772792a209911a5efa42cf55cf621771e48b863211ac5a2a/tibs-0.5.7-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f70bd250769381c73110d6f24feaf8b6fcd44f680b3cb28a20ea06db3d04fb6f", size = 416256, upload-time = "2026-03-12T13:06:24.222Z" }, - { url = "https://files.pythonhosted.org/packages/02/94/481a73e74d398949f57d297b1809a10a951d252e7ec94b6715ed952ce500/tibs-0.5.7-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:76746f01b3db9dbd802f5e615f11f68df7a29ecef521b082dca53f3fa7d0084f", size = 428003, upload-time = "2026-03-12T13:06:23.064Z" }, - { url = "https://files.pythonhosted.org/packages/9b/e0/72db1760a7f7fec1d5f3690e0855fbbccbcf0a4a2fd318c9d71f3b33f3a7/tibs-0.5.7-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:847709c108800ad6a45efaf9a040628278956938a4897f7427a2587013dc3b98", size = 455589, upload-time = "2026-03-12T13:06:53.144Z" }, - { url = "https://files.pythonhosted.org/packages/3e/26/9cd3395914bf705d6ae1e9a6c323f727e9dc88fef716327ce7f486e0b55a/tibs-0.5.7-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad61df93b50f875b277ab736c5d37b6bce56f9abce489a22f4e02d9daa2966e3", size = 459266, upload-time = "2026-03-12T13:06:21.678Z" }, - { url = "https://files.pythonhosted.org/packages/e9/3b/267f19a008d13c704dc0b044138a56239272a43531ccb05464129d0fbd01/tibs-0.5.7-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e13b9c7ff2604b0146772025e1ac6f85c8c625bf6ac73736ff671eaf357dda41", size = 423466, upload-time = "2026-03-12T13:06:41.212Z" }, - { url = "https://files.pythonhosted.org/packages/e5/d4/424ae3515e0e013ad83186074bf3beb53399b9052c00da703415ccc316ca/tibs-0.5.7-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0a7ce857ef05c59dc61abadc31c4b9b1e3c62f9e5fb29217988c308936aea71e", size = 452080, upload-time = "2026-03-12T13:06:32.112Z" }, - { url = "https://files.pythonhosted.org/packages/b0/15/ab80beba83a134745439d33763e1d3b017f994abeb9c309a3ac9fd94e90e/tibs-0.5.7-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1d5521cc6768bfa6282a0c591ba06b079ab91b5c7d5696925ad2abac59779a54", size = 592311, upload-time = "2026-03-12T13:06:47.807Z" }, - { url = "https://files.pythonhosted.org/packages/4c/21/f5cf41c15431e63aeaefb494e714d48d9e9061b4e01fcc01d1987e2e5faa/tibs-0.5.7-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:477608f9b87e24a22ab6d50b81da04a5cb59bfa49598ff7ec5165035a18fb392", size = 703400, upload-time = "2026-03-12T13:06:16.968Z" }, - { url = "https://files.pythonhosted.org/packages/4e/ec/b3bdb7dcc3de8513c5678a685f4e25bb85ef48526d7d535ddc592f9e8602/tibs-0.5.7-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:ac0aa2aae38f7325c91c261ce1d18f769c4c7033c98d6ea3ea5534585cf16452", size = 664623, upload-time = "2026-03-12T13:06:48.894Z" }, - { url = "https://files.pythonhosted.org/packages/a4/71/7b85af3ad1b2cd9871c8f50ba0eb17e54e12481b467678535e58aced0d98/tibs-0.5.7-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1b56583db148e5094d781c3d746815dbcbb6378c6f813c8ce291efd4ab21da8b", size = 635199, upload-time = "2026-03-12T13:06:34.798Z" }, - { url = "https://files.pythonhosted.org/packages/b9/63/60220fb502beb857306afd4a5bac4a8617ae496f3b1f4968d127380fdefe/tibs-0.5.7-cp38-abi3-win32.whl", hash = "sha256:d4f3ff613d486650816bc5516760c0382a2cc0ca8aeddd8914d011bc3b81d9a2", size = 288454, upload-time = "2026-03-12T13:06:30.978Z" }, - { url = "https://files.pythonhosted.org/packages/46/ab/aab78827ba7e0d65fe346b86d1d61e0792c38d5f9b7547e0f71b7027c835/tibs-0.5.7-cp38-abi3-win_amd64.whl", hash = "sha256:a61d36155f8ab8642e1b6744e13822f72050fc7ec4f86ec6965295afa04949e2", size = 304135, upload-time = "2026-03-12T13:06:35.884Z" }, - { url = "https://files.pythonhosted.org/packages/48/59/e9e6a610928a4bcbf04f0ac1436ee320aa8cbe95181f1aa32687c50e858b/tibs-0.5.7-cp38-abi3-win_arm64.whl", hash = "sha256:130bc68ff500fc8185677df7a97350b5d5339e6ba7e325bc3031337f6424ede7", size = 289272, upload-time = "2026-03-12T13:06:19.247Z" }, -] - [[package]] name = "tiktoken" version = "0.12.0" @@ -8546,13 +7302,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/4d017d0f76ec3171d469d80fc03dfbb4e48a4bcaddaa831b31d526f05edc/tiktoken-0.12.0.tar.gz", hash = "sha256:b18ba7ee2b093863978fcb14f74b3707cdc8d4d4d3836853ce7ec60772139931", size = 37806, upload-time = "2025-10-06T20:22:45.419Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/de/46/21ea696b21f1d6d1efec8639c204bdf20fde8bafb351e1355c72c5d7de52/tiktoken-0.12.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6e227c7f96925003487c33b1b32265fad2fbcec2b7cf4817afb76d416f40f6bb", size = 1051565, upload-time = "2025-10-06T20:21:44.566Z" }, - { url = "https://files.pythonhosted.org/packages/c9/d9/35c5d2d9e22bb2a5f74ba48266fb56c63d76ae6f66e02feb628671c0283e/tiktoken-0.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c06cf0fcc24c2cb2adb5e185c7082a82cba29c17575e828518c2f11a01f445aa", size = 995284, upload-time = "2025-10-06T20:21:45.622Z" }, - { url = "https://files.pythonhosted.org/packages/01/84/961106c37b8e49b9fdcf33fe007bb3a8fdcc380c528b20cc7fbba80578b8/tiktoken-0.12.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:f18f249b041851954217e9fd8e5c00b024ab2315ffda5ed77665a05fa91f42dc", size = 1129201, upload-time = "2025-10-06T20:21:47.074Z" }, - { url = "https://files.pythonhosted.org/packages/6a/d0/3d9275198e067f8b65076a68894bb52fd253875f3644f0a321a720277b8a/tiktoken-0.12.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:47a5bc270b8c3db00bb46ece01ef34ad050e364b51d406b6f9730b64ac28eded", size = 1152444, upload-time = "2025-10-06T20:21:48.139Z" }, - { url = "https://files.pythonhosted.org/packages/78/db/a58e09687c1698a7c592e1038e01c206569b86a0377828d51635561f8ebf/tiktoken-0.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:508fa71810c0efdcd1b898fda574889ee62852989f7c1667414736bcb2b9a4bd", size = 1195080, upload-time = "2025-10-06T20:21:49.246Z" }, - { url = "https://files.pythonhosted.org/packages/9e/1b/a9e4d2bf91d515c0f74afc526fd773a812232dd6cda33ebea7f531202325/tiktoken-0.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1af81a6c44f008cba48494089dd98cccb8b313f55e961a52f5b222d1e507967", size = 1255240, upload-time = "2025-10-06T20:21:50.274Z" }, - { url = "https://files.pythonhosted.org/packages/9d/15/963819345f1b1fb0809070a79e9dd96938d4ca41297367d471733e79c76c/tiktoken-0.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:3e68e3e593637b53e56f7237be560f7a394451cb8c11079755e80ae64b9e6def", size = 879422, upload-time = "2025-10-06T20:21:51.734Z" }, { url = "https://files.pythonhosted.org/packages/a4/85/be65d39d6b647c79800fd9d29241d081d4eeb06271f383bb87200d74cf76/tiktoken-0.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b97f74aca0d78a1ff21b8cd9e9925714c15a9236d6ceacf5c7327c117e6e21e8", size = 1050728, upload-time = "2025-10-06T20:21:52.756Z" }, { url = "https://files.pythonhosted.org/packages/4a/42/6573e9129bc55c9bf7300b3a35bef2c6b9117018acca0dc760ac2d93dffe/tiktoken-0.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b90f5ad190a4bb7c3eb30c5fa32e1e182ca1ca79f05e49b448438c3e225a49b", size = 994049, upload-time = "2025-10-06T20:21:53.782Z" }, { url = "https://files.pythonhosted.org/packages/66/c5/ed88504d2f4a5fd6856990b230b56d85a777feab84e6129af0822f5d0f70/tiktoken-0.12.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:65b26c7a780e2139e73acc193e5c63ac754021f160df919add909c1492c0fb37", size = 1129008, upload-time = "2025-10-06T20:21:54.832Z" }, @@ -8690,15 +7439,6 @@ version = "2.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" }, - { url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" }, - { url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" }, - { url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" }, - { url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" }, - { url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" }, - { url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" }, - { url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" }, { url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size = 154894, upload-time = "2026-01-11T11:21:56.07Z" }, { url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size = 149053, upload-time = "2026-01-11T11:21:57.467Z" }, { url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size = 243481, upload-time = "2026-01-11T11:21:58.661Z" }, @@ -8781,25 +7521,19 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvshmem-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "setuptools", marker = "python_full_version >= '3.12'" }, + { name = "setuptools" }, { name = "sympy" }, { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "typing-extensions" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/8b/4b61d6e13f7108f36910df9ab4b58fd389cc2520d54d81b88660804aad99/torch-2.10.0-2-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:418997cb02d0a0f1497cf6a09f63166f9f5df9f3e16c8a716ab76a72127c714f", size = 79423467, upload-time = "2026-02-10T21:44:48.711Z" }, { url = "https://files.pythonhosted.org/packages/d3/54/a2ba279afcca44bbd320d4e73675b282fcee3d81400ea1b53934efca6462/torch-2.10.0-2-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:13ec4add8c3faaed8d13e0574f5cd4a323c11655546f91fbe6afa77b57423574", size = 79498202, upload-time = "2026-02-10T21:44:52.603Z" }, { url = "https://files.pythonhosted.org/packages/ec/23/2c9fe0c9c27f7f6cb865abcea8a4568f29f00acaeadfc6a37f6801f84cb4/torch-2.10.0-2-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:e521c9f030a3774ed770a9c011751fb47c4d12029a3d6522116e48431f2ff89e", size = 79498254, upload-time = "2026-02-10T21:44:44.095Z" }, - { url = "https://files.pythonhosted.org/packages/36/ab/7b562f1808d3f65414cd80a4f7d4bb00979d9355616c034c171249e1a303/torch-2.10.0-3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:ac5bdcbb074384c66fa160c15b1ead77839e3fe7ed117d667249afce0acabfac", size = 915518691, upload-time = "2026-03-11T14:15:43.147Z" }, { url = "https://files.pythonhosted.org/packages/b3/7a/abada41517ce0011775f0f4eacc79659bc9bc6c361e6bfe6f7052a6b9363/torch-2.10.0-3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:98c01b8bb5e3240426dcde1446eed6f40c778091c8544767ef1168fc663a05a6", size = 915622781, upload-time = "2026-03-11T14:17:11.354Z" }, { url = "https://files.pythonhosted.org/packages/ab/c6/4dfe238342ffdcec5aef1c96c457548762d33c40b45a1ab7033bb26d2ff2/torch-2.10.0-3-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:80b1b5bfe38eb0e9f5ff09f206dcac0a87aadd084230d4a36eea5ec5232c115b", size = 915627275, upload-time = "2026-03-11T14:16:11.325Z" }, { url = "https://files.pythonhosted.org/packages/d8/f0/72bf18847f58f877a6a8acf60614b14935e2f156d942483af1ffc081aea0/torch-2.10.0-3-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:46b3574d93a2a8134b3f5475cfb98e2eb46771794c57015f6ad1fb795ec25e49", size = 915523474, upload-time = "2026-03-11T14:17:44.422Z" }, { url = "https://files.pythonhosted.org/packages/f4/39/590742415c3030551944edc2ddc273ea1fdfe8ffb2780992e824f1ebee98/torch-2.10.0-3-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:b1d5e2aba4eb7f8e87fbe04f86442887f9167a35f092afe4c237dfcaaef6e328", size = 915632474, upload-time = "2026-03-11T14:15:13.666Z" }, { url = "https://files.pythonhosted.org/packages/b6/8e/34949484f764dde5b222b7fe3fede43e4a6f0da9d7f8c370bb617d629ee2/torch-2.10.0-3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:0228d20b06701c05a8f978357f657817a4a63984b0c90745def81c18aedfa591", size = 915523882, upload-time = "2026-03-11T14:14:46.311Z" }, - { url = "https://files.pythonhosted.org/packages/78/89/f5554b13ebd71e05c0b002f95148033e730d3f7067f67423026cc9c69410/torch-2.10.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:3282d9febd1e4e476630a099692b44fdc214ee9bf8ee5377732d9d9dfe5712e4", size = 145992610, upload-time = "2026-01-21T16:25:26.327Z" }, - { url = "https://files.pythonhosted.org/packages/ae/30/a3a2120621bf9c17779b169fc17e3dc29b230c29d0f8222f499f5e159aa8/torch-2.10.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a2f9edd8dbc99f62bc4dfb78af7bf89499bca3d753423ac1b4e06592e467b763", size = 915607863, upload-time = "2026-01-21T16:25:06.696Z" }, - { url = "https://files.pythonhosted.org/packages/6f/3d/c87b33c5f260a2a8ad68da7147e105f05868c281c63d65ed85aa4da98c66/torch-2.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:29b7009dba4b7a1c960260fc8ac85022c784250af43af9fb0ebafc9883782ebd", size = 113723116, upload-time = "2026-01-21T16:25:21.916Z" }, - { url = "https://files.pythonhosted.org/packages/61/d8/15b9d9d3a6b0c01b883787bd056acbe5cc321090d4b216d3ea89a8fcfdf3/torch-2.10.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:b7bd80f3477b830dd166c707c5b0b82a898e7b16f59a7d9d42778dd058272e8b", size = 79423461, upload-time = "2026-01-21T16:24:50.266Z" }, { url = "https://files.pythonhosted.org/packages/cc/af/758e242e9102e9988969b5e621d41f36b8f258bb4a099109b7a4b4b50ea4/torch-2.10.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:5fd4117d89ffd47e3dcc71e71a22efac24828ad781c7e46aaaf56bf7f2796acf", size = 145996088, upload-time = "2026-01-21T16:24:44.171Z" }, { url = "https://files.pythonhosted.org/packages/23/8e/3c74db5e53bff7ed9e34c8123e6a8bfef718b2450c35eefab85bb4a7e270/torch-2.10.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:787124e7db3b379d4f1ed54dd12ae7c741c16a4d29b49c0226a89bea50923ffb", size = 915711952, upload-time = "2026-01-21T16:23:53.503Z" }, { url = "https://files.pythonhosted.org/packages/6e/01/624c4324ca01f66ae4c7cd1b74eb16fb52596dce66dbe51eff95ef9e7a4c/torch-2.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:2c66c61f44c5f903046cc696d088e21062644cbe541c7f1c4eaae88b2ad23547", size = 113757972, upload-time = "2026-01-21T16:24:39.516Z" }, @@ -8831,10 +7565,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/37/de/921b6491efce5c389a5ef9bbed3d2d6660005840dae488124173180859ab/torch_c_dlpack_ext-0.1.5.tar.gz", hash = "sha256:d06f0357d575d22a168cc77acb9020fc4bae30968ceb6718a055dcbe92bacabe", size = 12913, upload-time = "2026-01-12T11:25:08.484Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/65/66/c12a9bb3a5ddc0962c00467891bf1ffdda39a4d4780bf0fbbf54523ff34e/torch_c_dlpack_ext-0.1.5-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:56bd25a2af19280bf8a06aa62cff5510106f43235b9327d8561b3e9a659c4d84", size = 5076782, upload-time = "2026-01-12T11:24:37.868Z" }, - { url = "https://files.pythonhosted.org/packages/20/e1/64e1e579d107064785549e70758e38a42376ab7e73d86897ed4beab10e74/torch_c_dlpack_ext-0.1.5-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fba674110e1fab0b176bb5a28223e157db65c90767d4ba74abdbee9f537b0e9d", size = 440949, upload-time = "2026-01-12T11:24:39.716Z" }, - { url = "https://files.pythonhosted.org/packages/64/5c/3e1382a620824f92920ab3fae132d8fb4e85898284c99e0c6a7764e452ce/torch_c_dlpack_ext-0.1.5-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3448c4f0d64104d0b2e58080a7efa72304a04960c18f338024b80b13cd3eca26", size = 897768, upload-time = "2026-01-12T11:24:41.209Z" }, - { url = "https://files.pythonhosted.org/packages/54/4f/76ea1006b9038b496d01e916c91efd17cb782abde2491a261cf203f57e30/torch_c_dlpack_ext-0.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:74676474e0afa9a4216c4755ea7cf05e8158be1d168f6bda669ba91097c263f2", size = 1479088, upload-time = "2026-01-12T11:24:42.436Z" }, { url = "https://files.pythonhosted.org/packages/b1/67/10d236698525d7b7db4d74ec0a4b01f5b2db33968995fdd9ac6b4635e327/torch_c_dlpack_ext-0.1.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:c0f2bd51fcd99c0e5b50314e1985f2728c4941bfa821f065e6c30951d1f995ca", size = 5291237, upload-time = "2026-01-12T11:24:44.011Z" }, { url = "https://files.pythonhosted.org/packages/87/06/8d760997307a5c3be4384424667bf31aae0a42060838c532c7d846516175/torch_c_dlpack_ext-0.1.5-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3562ee411258676f9c38b8ad39306d1c8d027b6a86f6a87c920d2d009a9d1510", size = 443069, upload-time = "2026-01-12T11:24:45.451Z" }, { url = "https://files.pythonhosted.org/packages/e2/79/a914539b4785f3e44f891aa012a886edb8bc10fe081c440981c57543ce21/torch_c_dlpack_ext-0.1.5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e6f9da4bb9af70e27facc777458be62e10dbbbddda7672d16138db0553c5a524", size = 897846, upload-time = "2026-01-12T11:24:48.168Z" }, @@ -8868,10 +7598,6 @@ dependencies = [ { name = "torch" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/be/c704bceaf11c4f6b19d64337a34a877fcdfe3bd68160a8c9ae9bea4a35a3/torchvision-0.25.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db74a551946b75d19f9996c419a799ffdf6a223ecf17c656f90da011f1d75b20", size = 1874923, upload-time = "2026-01-21T16:27:46.574Z" }, - { url = "https://files.pythonhosted.org/packages/ae/e9/f143cd71232430de1f547ceab840f68c55e127d72558b1061a71d0b193cd/torchvision-0.25.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:f49964f96644dbac2506dffe1a0a7ec0f2bf8cf7a588c3319fed26e6329ffdf3", size = 2344808, upload-time = "2026-01-21T16:27:43.191Z" }, - { url = "https://files.pythonhosted.org/packages/43/ae/ad5d6165797de234c9658752acb4fce65b78a6a18d82efdf8367c940d8da/torchvision-0.25.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:153c0d2cbc34b7cf2da19d73450f24ba36d2b75ec9211b9962b5022fb9e4ecee", size = 8070752, upload-time = "2026-01-21T16:27:33.748Z" }, - { url = "https://files.pythonhosted.org/packages/23/19/55b28aecdc7f38df57b8eb55eb0b14a62b470ed8efeb22cdc74224df1d6a/torchvision-0.25.0-cp311-cp311-win_amd64.whl", hash = "sha256:ea580ffd6094cc01914ad32f8c8118174f18974629af905cea08cb6d5d48c7b7", size = 4038722, upload-time = "2026-01-21T16:27:41.355Z" }, { url = "https://files.pythonhosted.org/packages/56/3a/6ea0d73f49a9bef38a1b3a92e8dd455cea58470985d25635beab93841748/torchvision-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2abe430c90b1d5e552680037d68da4eb80a5852ebb1c811b2b89d299b10573b", size = 1874920, upload-time = "2026-01-21T16:27:45.348Z" }, { url = "https://files.pythonhosted.org/packages/51/f8/c0e1ef27c66e15406fece94930e7d6feee4cb6374bbc02d945a630d6426e/torchvision-0.25.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:b75deafa2dfea3e2c2a525559b04783515e3463f6e830cb71de0fb7ea36fe233", size = 2344556, upload-time = "2026-01-21T16:27:40.125Z" }, { url = "https://files.pythonhosted.org/packages/68/2f/f24b039169db474e8688f649377de082a965fbf85daf4e46c44412f1d15a/torchvision-0.25.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f25aa9e380865b11ea6e9d99d84df86b9cc959f1a007cd966fc6f1ab2ed0e248", size = 8072351, upload-time = "2026-01-21T16:27:21.074Z" }, @@ -9005,8 +7731,6 @@ name = "triton" version = "3.6.0" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/2c/96f92f3c60387e14cc45aed49487f3486f89ea27106c1b1376913c62abe4/triton-3.6.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49df5ef37379c0c2b5c0012286f80174fcf0e073e5ade1ca9a86c36814553651", size = 176081190, upload-time = "2026-01-20T16:16:00.523Z" }, - { url = "https://files.pythonhosted.org/packages/e0/12/b05ba554d2c623bffa59922b94b0775673de251f468a9609bc9e45de95e9/triton-3.6.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8e323d608e3a9bfcc2d9efcc90ceefb764a82b99dea12a86d643c72539ad5d3", size = 188214640, upload-time = "2026-01-20T16:00:35.869Z" }, { url = "https://files.pythonhosted.org/packages/17/5d/08201db32823bdf77a0e2b9039540080b2e5c23a20706ddba942924ebcd6/triton-3.6.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:374f52c11a711fd062b4bfbb201fd9ac0a5febd28a96fb41b4a0f51dde3157f4", size = 176128243, upload-time = "2026-01-20T16:16:07.857Z" }, { url = "https://files.pythonhosted.org/packages/ab/a8/cdf8b3e4c98132f965f88c2313a4b493266832ad47fb52f23d14d4f86bb5/triton-3.6.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74caf5e34b66d9f3a429af689c1c7128daba1d8208df60e81106b115c00d6fca", size = 188266850, upload-time = "2026-01-20T16:00:43.041Z" }, { url = "https://files.pythonhosted.org/packages/3c/12/34d71b350e89a204c2c7777a9bba0dcf2f19a5bfdd70b57c4dbc5ffd7154/triton-3.6.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:448e02fe6dc898e9e5aa89cf0ee5c371e99df5aa5e8ad976a80b93334f3494fd", size = 176133521, upload-time = "2026-01-20T16:16:13.321Z" }, @@ -9024,7 +7748,6 @@ name = "triton-windows" version = "3.6.0.post26" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/20/acab7b4f50abe68d93f632b2e29cfb9e76284eaf9b4041a6eabbbd4afdc7/triton_windows-3.6.0.post26-cp311-cp311-win_amd64.whl", hash = "sha256:369a47ed3ca25f6d405387a058b8fbc62e6ff4592bbf87b0c5f6de372ab68931", size = 47401354, upload-time = "2026-03-10T02:51:33.9Z" }, { url = "https://files.pythonhosted.org/packages/62/1e/8d9814e67ba3f20094cf3c69e7815a491f20beb86469a647550ba86728b0/triton_windows-3.6.0.post26-cp312-cp312-win_amd64.whl", hash = "sha256:189d8c57911aa9d2ff983a715e5c967b325f576307db60924cab22b501a36515", size = 47402104, upload-time = "2026-03-10T02:51:40.997Z" }, { url = "https://files.pythonhosted.org/packages/2e/69/7579a5da5d8c5372711bb4b99a185ad35eae6c7549d85b9f75171e06832b/triton_windows-3.6.0.post26-cp313-cp313-win_amd64.whl", hash = "sha256:033f3d50c6a0e4539a3ccfa042304dbf76bf79155f382f9c09d010323d5a9a32", size = 47402101, upload-time = "2026-03-10T02:51:47.669Z" }, { url = "https://files.pythonhosted.org/packages/7e/27/3d272c154c00c044e0f113d053650d6faf56258789dcdc1e5e3e4a91d86d/triton_windows-3.6.0.post26-cp314-cp314-win_amd64.whl", hash = "sha256:c8029386813d6df4ec700bbff050c1e308fd24d66be3d8848274fc5d97bad396", size = 48580269, upload-time = "2026-03-10T02:51:54.665Z" }, @@ -9291,13 +8014,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/65/36/2d24b2cbe78547c6532da33fb8613debd3126eccc33a6374ab788f5e46e9/uuid_utils-0.14.1-cp39-abi3-win32.whl", hash = "sha256:b54d6aa6252d96bac1fdbc80d26ba71bad9f220b2724d692ad2f2310c22ef523", size = 183476, upload-time = "2026-02-20T22:50:32.745Z" }, { url = "https://files.pythonhosted.org/packages/83/92/2d7e90df8b1a69ec4cff33243ce02b7a62f926ef9e2f0eca5a026889cd73/uuid_utils-0.14.1-cp39-abi3-win_amd64.whl", hash = "sha256:fc27638c2ce267a0ce3e06828aff786f91367f093c80625ee21dad0208e0f5ba", size = 187147, upload-time = "2026-02-20T22:50:45.807Z" }, { url = "https://files.pythonhosted.org/packages/d9/26/529f4beee17e5248e37e0bc17a2761d34c0fa3b1e5729c88adb2065bae6e/uuid_utils-0.14.1-cp39-abi3-win_arm64.whl", hash = "sha256:b04cb49b42afbc4ff8dbc60cf054930afc479d6f4dd7f1ec3bbe5dbfdde06b7a", size = 188132, upload-time = "2026-02-20T22:50:41.718Z" }, - { url = "https://files.pythonhosted.org/packages/91/f9/6c64bdbf71f58ccde7919e00491812556f446a5291573af92c49a5e9aaef/uuid_utils-0.14.1-pp311-pypy311_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:b197cd5424cf89fb019ca7f53641d05bfe34b1879614bed111c9c313b5574cd8", size = 591617, upload-time = "2026-02-20T22:50:24.532Z" }, - { url = "https://files.pythonhosted.org/packages/d0/f0/758c3b0fb0c4871c7704fef26a5bc861de4f8a68e4831669883bebe07b0f/uuid_utils-0.14.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:12c65020ba6cb6abe1d57fcbfc2d0ea0506c67049ee031714057f5caf0f9bc9c", size = 303702, upload-time = "2026-02-20T22:50:40.687Z" }, - { url = "https://files.pythonhosted.org/packages/85/89/d91862b544c695cd58855efe3201f83894ed82fffe34500774238ab8eba7/uuid_utils-0.14.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b5d2ad28063d422ccc2c28d46471d47b61a58de885d35113a8f18cb547e25bf", size = 337678, upload-time = "2026-02-20T22:50:39.768Z" }, - { url = "https://files.pythonhosted.org/packages/ee/6b/cf342ba8a898f1de024be0243fac67c025cad530c79ea7f89c4ce718891a/uuid_utils-0.14.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da2234387b45fde40b0fedfee64a0ba591caeea9c48c7698ab6e2d85c7991533", size = 343711, upload-time = "2026-02-20T22:50:43.965Z" }, - { url = "https://files.pythonhosted.org/packages/b3/20/049418d094d396dfa6606b30af925cc68a6670c3b9103b23e6990f84b589/uuid_utils-0.14.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50fffc2827348c1e48972eed3d1c698959e63f9d030aa5dd82ba451113158a62", size = 476731, upload-time = "2026-02-20T22:50:30.589Z" }, - { url = "https://files.pythonhosted.org/packages/77/a1/0857f64d53a90321e6a46a3d4cc394f50e1366132dcd2ae147f9326ca98b/uuid_utils-0.14.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1dbe718765f70f5b7f9b7f66b6a937802941b1cc56bcf642ce0274169741e01", size = 338902, upload-time = "2026-02-20T22:50:33.927Z" }, - { url = "https://files.pythonhosted.org/packages/ed/d0/5bf7cbf1ac138c92b9ac21066d18faf4d7e7f651047b700eb192ca4b9fdb/uuid_utils-0.14.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:258186964039a8e36db10810c1ece879d229b01331e09e9030bc5dcabe231bd2", size = 364700, upload-time = "2026-02-20T22:50:21.732Z" }, ] [[package]] @@ -9356,12 +8072,6 @@ version = "0.22.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/d5/69900f7883235562f1f50d8184bb7dd84a2fb61e9ec63f3782546fdbd057/uvloop-0.22.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c60ebcd36f7b240b30788554b6f0782454826a0ed765d8430652621b5de674b9", size = 1352420, upload-time = "2025-10-16T22:16:21.187Z" }, - { url = "https://files.pythonhosted.org/packages/a8/73/c4e271b3bce59724e291465cc936c37758886a4868787da0278b3b56b905/uvloop-0.22.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b7f102bf3cb1995cfeaee9321105e8f5da76fdb104cdad8986f85461a1b7b77", size = 748677, upload-time = "2025-10-16T22:16:22.558Z" }, - { url = "https://files.pythonhosted.org/packages/86/94/9fb7fad2f824d25f8ecac0d70b94d0d48107ad5ece03769a9c543444f78a/uvloop-0.22.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53c85520781d84a4b8b230e24a5af5b0778efdb39142b424990ff1ef7c48ba21", size = 3753819, upload-time = "2025-10-16T22:16:23.903Z" }, - { url = "https://files.pythonhosted.org/packages/74/4f/256aca690709e9b008b7108bc85fba619a2bc37c6d80743d18abad16ee09/uvloop-0.22.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:56a2d1fae65fd82197cb8c53c367310b3eabe1bbb9fb5a04d28e3e3520e4f702", size = 3804529, upload-time = "2025-10-16T22:16:25.246Z" }, - { url = "https://files.pythonhosted.org/packages/7f/74/03c05ae4737e871923d21a76fe28b6aad57f5c03b6e6bfcfa5ad616013e4/uvloop-0.22.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40631b049d5972c6755b06d0bfe8233b1bd9a8a6392d9d1c45c10b6f9e9b2733", size = 3621267, upload-time = "2025-10-16T22:16:26.819Z" }, - { url = "https://files.pythonhosted.org/packages/75/be/f8e590fe61d18b4a92070905497aec4c0e64ae1761498cad09023f3f4b3e/uvloop-0.22.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:535cc37b3a04f6cd2c1ef65fa1d370c9a35b6695df735fcff5427323f2cd5473", size = 3723105, upload-time = "2025-10-16T22:16:28.252Z" }, { url = "https://files.pythonhosted.org/packages/3d/ff/7f72e8170be527b4977b033239a83a68d5c881cc4775fca255c677f7ac5d/uvloop-0.22.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42", size = 1359936, upload-time = "2025-10-16T22:16:29.436Z" }, { url = "https://files.pythonhosted.org/packages/c3/c6/e5d433f88fd54d81ef4be58b2b7b0cea13c442454a1db703a1eea0db1a59/uvloop-0.22.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:51eb9bd88391483410daad430813d982010f9c9c89512321f5b60e2cddbdddd6", size = 752769, upload-time = "2025-10-16T22:16:30.493Z" }, { url = "https://files.pythonhosted.org/packages/24/68/a6ac446820273e71aa762fa21cdcc09861edd3536ff47c5cd3b7afb10eeb/uvloop-0.22.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:700e674a166ca5778255e0e1dc4e9d79ab2acc57b9171b79e65feba7184b3370", size = 4317413, upload-time = "2025-10-16T22:16:31.644Z" }, @@ -9447,9 +8157,6 @@ version = "6.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, - { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, - { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, @@ -9477,19 +8184,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440, upload-time = "2025-10-14T15:06:21.08Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/f8/2c5f479fb531ce2f0564eda479faecf253d886b1ab3630a39b7bf7362d46/watchfiles-1.1.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5", size = 406529, upload-time = "2025-10-14T15:04:32.899Z" }, - { url = "https://files.pythonhosted.org/packages/fe/cd/f515660b1f32f65df671ddf6f85bfaca621aee177712874dc30a97397977/watchfiles-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741", size = 394384, upload-time = "2025-10-14T15:04:33.761Z" }, - { url = "https://files.pythonhosted.org/packages/7b/c3/28b7dc99733eab43fca2d10f55c86e03bd6ab11ca31b802abac26b23d161/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6", size = 448789, upload-time = "2025-10-14T15:04:34.679Z" }, - { url = "https://files.pythonhosted.org/packages/4a/24/33e71113b320030011c8e4316ccca04194bf0cbbaeee207f00cbc7d6b9f5/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b", size = 460521, upload-time = "2025-10-14T15:04:35.963Z" }, - { url = "https://files.pythonhosted.org/packages/f4/c3/3c9a55f255aa57b91579ae9e98c88704955fa9dac3e5614fb378291155df/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14", size = 488722, upload-time = "2025-10-14T15:04:37.091Z" }, - { url = "https://files.pythonhosted.org/packages/49/36/506447b73eb46c120169dc1717fe2eff07c234bb3232a7200b5f5bd816e9/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d", size = 596088, upload-time = "2025-10-14T15:04:38.39Z" }, - { url = "https://files.pythonhosted.org/packages/82/ab/5f39e752a9838ec4d52e9b87c1e80f1ee3ccdbe92e183c15b6577ab9de16/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff", size = 472923, upload-time = "2025-10-14T15:04:39.666Z" }, - { url = "https://files.pythonhosted.org/packages/af/b9/a419292f05e302dea372fa7e6fda5178a92998411f8581b9830d28fb9edb/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606", size = 456080, upload-time = "2025-10-14T15:04:40.643Z" }, - { url = "https://files.pythonhosted.org/packages/b0/c3/d5932fd62bde1a30c36e10c409dc5d54506726f08cb3e1d8d0ba5e2bc8db/watchfiles-1.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701", size = 629432, upload-time = "2025-10-14T15:04:41.789Z" }, - { url = "https://files.pythonhosted.org/packages/f7/77/16bddd9779fafb795f1a94319dc965209c5641db5bf1edbbccace6d1b3c0/watchfiles-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10", size = 623046, upload-time = "2025-10-14T15:04:42.718Z" }, - { url = "https://files.pythonhosted.org/packages/46/ef/f2ecb9a0f342b4bfad13a2787155c6ee7ce792140eac63a34676a2feeef2/watchfiles-1.1.1-cp311-cp311-win32.whl", hash = "sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849", size = 271473, upload-time = "2025-10-14T15:04:43.624Z" }, - { url = "https://files.pythonhosted.org/packages/94/bc/f42d71125f19731ea435c3948cad148d31a64fccde3867e5ba4edee901f9/watchfiles-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4", size = 287598, upload-time = "2025-10-14T15:04:44.516Z" }, - { url = "https://files.pythonhosted.org/packages/57/c9/a30f897351f95bbbfb6abcadafbaca711ce1162f4db95fc908c98a9165f3/watchfiles-1.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e", size = 277210, upload-time = "2025-10-14T15:04:45.883Z" }, { url = "https://files.pythonhosted.org/packages/74/d5/f039e7e3c639d9b1d09b07ea412a6806d38123f0508e5f9b48a87b0a76cc/watchfiles-1.1.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d", size = 404745, upload-time = "2025-10-14T15:04:46.731Z" }, { url = "https://files.pythonhosted.org/packages/a5/96/a881a13aa1349827490dab2d363c8039527060cfcc2c92cc6d13d1b1049e/watchfiles-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610", size = 391769, upload-time = "2025-10-14T15:04:48.003Z" }, { url = "https://files.pythonhosted.org/packages/4b/5b/d3b460364aeb8da471c1989238ea0e56bec24b6042a68046adf3d9ddb01c/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af", size = 449374, upload-time = "2025-10-14T15:04:49.179Z" }, @@ -9549,10 +8243,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072, upload-time = "2025-10-14T15:05:48.928Z" }, { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104, upload-time = "2025-10-14T15:05:49.908Z" }, { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112, upload-time = "2025-10-14T15:05:50.941Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8e/e500f8b0b77be4ff753ac94dc06b33d8f0d839377fee1b78e8c8d8f031bf/watchfiles-1.1.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88", size = 408250, upload-time = "2025-10-14T15:06:10.264Z" }, - { url = "https://files.pythonhosted.org/packages/bd/95/615e72cd27b85b61eec764a5ca51bd94d40b5adea5ff47567d9ebc4d275a/watchfiles-1.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336", size = 396117, upload-time = "2025-10-14T15:06:11.28Z" }, - { url = "https://files.pythonhosted.org/packages/c9/81/e7fe958ce8a7fb5c73cc9fb07f5aeaf755e6aa72498c57d760af760c91f8/watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24", size = 450493, upload-time = "2025-10-14T15:06:12.321Z" }, - { url = "https://files.pythonhosted.org/packages/6e/d4/ed38dd3b1767193de971e694aa544356e63353c33a85d948166b5ff58b9e/watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49", size = 457546, upload-time = "2025-10-14T15:06:13.372Z" }, ] [[package]] @@ -9599,20 +8289,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5c/51/1011621f5c1efe326613231c317f54cf31ff07a220e8425c7a749809cdf1/weave-0.52.35-py3-none-any.whl", hash = "sha256:b3ed2209da6017cd580a71c24a8c0d967f32bd16f736ed32b04823a7330d4709", size = 954994, upload-time = "2026-03-19T20:04:18.961Z" }, ] -[[package]] -name = "webdataset" -version = "1.0.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "braceexpand" }, - { name = "numpy" }, - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5a/3a/68800d92e065cf4750ebecf973b13979c0c929b439e1293012938862038d/webdataset-1.0.2.tar.gz", hash = "sha256:7f0498be827cfa46cc5430a58768a24e2c6a410676a61be1838f53d61afdaab4", size = 80090, upload-time = "2025-06-19T23:26:21.945Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/00/aca6beb3658dab4ed3dbb41a78e6e7f31342e0b41d28088f205525751601/webdataset-1.0.2-py3-none-any.whl", hash = "sha256:3dbfced32b25c0d199c6b9787937b6f85742bc3c84f652c846893075c1c082d9", size = 74956, upload-time = "2025-06-19T23:26:20.354Z" }, -] - [[package]] name = "websocket-client" version = "1.9.0" @@ -9628,15 +8304,6 @@ version = "16.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hash = "sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5", size = 179346, upload-time = "2026-01-10T09:23:47.181Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/db/de907251b4ff46ae804ad0409809504153b3f30984daf82a1d84a9875830/websockets-16.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:31a52addea25187bde0797a97d6fc3d2f92b6f72a9370792d65a6e84615ac8a8", size = 177340, upload-time = "2026-01-10T09:22:34.539Z" }, - { url = "https://files.pythonhosted.org/packages/f3/fa/abe89019d8d8815c8781e90d697dec52523fb8ebe308bf11664e8de1877e/websockets-16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:417b28978cdccab24f46400586d128366313e8a96312e4b9362a4af504f3bbad", size = 175022, upload-time = "2026-01-10T09:22:36.332Z" }, - { url = "https://files.pythonhosted.org/packages/58/5d/88ea17ed1ded2079358b40d31d48abe90a73c9e5819dbcde1606e991e2ad/websockets-16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:af80d74d4edfa3cb9ed973a0a5ba2b2a549371f8a741e0800cb07becdd20f23d", size = 175319, upload-time = "2026-01-10T09:22:37.602Z" }, - { url = "https://files.pythonhosted.org/packages/d2/ae/0ee92b33087a33632f37a635e11e1d99d429d3d323329675a6022312aac2/websockets-16.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:08d7af67b64d29823fed316505a89b86705f2b7981c07848fb5e3ea3020c1abe", size = 184631, upload-time = "2026-01-10T09:22:38.789Z" }, - { url = "https://files.pythonhosted.org/packages/c8/c5/27178df583b6c5b31b29f526ba2da5e2f864ecc79c99dae630a85d68c304/websockets-16.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7be95cfb0a4dae143eaed2bcba8ac23f4892d8971311f1b06f3c6b78952ee70b", size = 185870, upload-time = "2026-01-10T09:22:39.893Z" }, - { url = "https://files.pythonhosted.org/packages/87/05/536652aa84ddc1c018dbb7e2c4cbcd0db884580bf8e95aece7593fde526f/websockets-16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d6297ce39ce5c2e6feb13c1a996a2ded3b6832155fcfc920265c76f24c7cceb5", size = 185361, upload-time = "2026-01-10T09:22:41.016Z" }, - { url = "https://files.pythonhosted.org/packages/6d/e2/d5332c90da12b1e01f06fb1b85c50cfc489783076547415bf9f0a659ec19/websockets-16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1c1b30e4f497b0b354057f3467f56244c603a79c0d1dafce1d16c283c25f6e64", size = 184615, upload-time = "2026-01-10T09:22:42.442Z" }, - { url = "https://files.pythonhosted.org/packages/77/fb/d3f9576691cae9253b51555f841bc6600bf0a983a461c79500ace5a5b364/websockets-16.0-cp311-cp311-win32.whl", hash = "sha256:5f451484aeb5cafee1ccf789b1b66f535409d038c56966d6101740c1614b86c6", size = 178246, upload-time = "2026-01-10T09:22:43.654Z" }, - { url = "https://files.pythonhosted.org/packages/54/67/eaff76b3dbaf18dcddabc3b8c1dba50b483761cccff67793897945b37408/websockets-16.0-cp311-cp311-win_amd64.whl", hash = "sha256:8d7f0659570eefb578dacde98e24fb60af35350193e4f56e11190787bee77dac", size = 178684, upload-time = "2026-01-10T09:22:44.941Z" }, { url = "https://files.pythonhosted.org/packages/84/7b/bac442e6b96c9d25092695578dda82403c77936104b5682307bd4deb1ad4/websockets-16.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:71c989cbf3254fbd5e84d3bff31e4da39c43f884e64f2551d14bb3c186230f00", size = 177365, upload-time = "2026-01-10T09:22:46.787Z" }, { url = "https://files.pythonhosted.org/packages/b0/fe/136ccece61bd690d9c1f715baaeefd953bb2360134de73519d5df19d29ca/websockets-16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8b6e209ffee39ff1b6d0fa7bfef6de950c60dfb91b8fcead17da4ee539121a79", size = 175038, upload-time = "2026-01-10T09:22:47.999Z" }, { url = "https://files.pythonhosted.org/packages/40/1e/9771421ac2286eaab95b8575b0cb701ae3663abf8b5e1f64f1fd90d0a673/websockets-16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86890e837d61574c92a97496d590968b23c2ef0aeb8a9bc9421d174cd378ae39", size = 175328, upload-time = "2026-01-10T09:22:49.809Z" }, @@ -9673,11 +8340,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206", size = 185356, upload-time = "2026-01-10T09:23:32.627Z" }, { url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl", hash = "sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6", size = 178085, upload-time = "2026-01-10T09:23:33.816Z" }, { url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd", size = 178531, upload-time = "2026-01-10T09:23:35.016Z" }, - { url = "https://files.pythonhosted.org/packages/72/07/c98a68571dcf256e74f1f816b8cc5eae6eb2d3d5cfa44d37f801619d9166/websockets-16.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:349f83cd6c9a415428ee1005cadb5c2c56f4389bc06a9af16103c3bc3dcc8b7d", size = 174947, upload-time = "2026-01-10T09:23:36.166Z" }, - { url = "https://files.pythonhosted.org/packages/7e/52/93e166a81e0305b33fe416338be92ae863563fe7bce446b0f687b9df5aea/websockets-16.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:4a1aba3340a8dca8db6eb5a7986157f52eb9e436b74813764241981ca4888f03", size = 175260, upload-time = "2026-01-10T09:23:37.409Z" }, - { url = "https://files.pythonhosted.org/packages/56/0c/2dbf513bafd24889d33de2ff0368190a0e69f37bcfa19009ef819fe4d507/websockets-16.0-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da", size = 176071, upload-time = "2026-01-10T09:23:39.158Z" }, - { url = "https://files.pythonhosted.org/packages/a5/8f/aea9c71cc92bf9b6cc0f7f70df8f0b420636b6c96ef4feee1e16f80f75dd/websockets-16.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0298d07ee155e2e9fda5be8a9042200dd2e3bb0b8a38482156576f863a9d457c", size = 176968, upload-time = "2026-01-10T09:23:41.031Z" }, - { url = "https://files.pythonhosted.org/packages/9a/3f/f70e03f40ffc9a30d817eef7da1be72ee4956ba8d7255c399a01b135902a/websockets-16.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:a653aea902e0324b52f1613332ddf50b00c06fdaf7e92624fbf8c77c78fa5767", size = 178735, upload-time = "2026-01-10T09:23:42.259Z" }, { url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598, upload-time = "2026-01-10T09:23:45.395Z" }, ] @@ -9693,12 +8355,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/b2/0bba9bbb4596d2d2f285a16c2ab04118f6b957d8441566e1abb892e6a6b2/werkzeug-3.1.7-py3-none-any.whl", hash = "sha256:4b314d81163a3e1a169b6a0be2a000a0e204e8873c5de6586f453c55688d422f", size = 226295, upload-time = "2026-03-24T01:08:06.133Z" }, ] -[[package]] -name = "wget" -version = "3.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/47/6a/62e288da7bcda82b935ff0c6cfe542970f04e29c756b0e147251b2fb251f/wget-3.2.zip", hash = "sha256:35e630eca2aa50ce998b9b1a127bb26b30dfee573702782aa982f875e3f16061", size = 10857, upload-time = "2015-10-22T15:26:37.51Z" } - [[package]] name = "wheel" version = "0.45.1" @@ -9723,17 +8379,6 @@ version = "2.1.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/2e/64/925f213fdcbb9baeb1530449ac71a4d57fc361c053d06bf78d0c5c7cd80c/wrapt-2.1.2.tar.gz", hash = "sha256:3996a67eecc2c68fd47b4e3c564405a5777367adfd9b8abb58387b63ee83b21e", size = 81678, upload-time = "2026-03-06T02:53:25.134Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/81/60c4471fce95afa5922ca09b88a25f03c93343f759aae0f31fb4412a85c7/wrapt-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:96159a0ee2b0277d44201c3b5be479a9979cf154e8c82fa5df49586a8e7679bb", size = 60666, upload-time = "2026-03-06T02:52:58.934Z" }, - { url = "https://files.pythonhosted.org/packages/6b/be/80e80e39e7cb90b006a0eaf11c73ac3a62bbfb3068469aec15cc0bc795de/wrapt-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98ba61833a77b747901e9012072f038795de7fc77849f1faa965464f3f87ff2d", size = 61601, upload-time = "2026-03-06T02:53:00.487Z" }, - { url = "https://files.pythonhosted.org/packages/b0/be/d7c88cd9293c859fc74b232abdc65a229bb953997995d6912fc85af18323/wrapt-2.1.2-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:767c0dbbe76cae2a60dd2b235ac0c87c9cccf4898aef8062e57bead46b5f6894", size = 114057, upload-time = "2026-03-06T02:52:44.08Z" }, - { url = "https://files.pythonhosted.org/packages/ea/25/36c04602831a4d685d45a93b3abea61eca7fe35dab6c842d6f5d570ef94a/wrapt-2.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c691a6bc752c0cc4711cc0c00896fcd0f116abc253609ef64ef930032821842", size = 116099, upload-time = "2026-03-06T02:54:56.74Z" }, - { url = "https://files.pythonhosted.org/packages/5c/4e/98a6eb417ef551dc277bec1253d5246b25003cf36fdf3913b65cb7657a56/wrapt-2.1.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f3b7d73012ea75aee5844de58c88f44cf62d0d62711e39da5a82824a7c4626a8", size = 112457, upload-time = "2026-03-06T02:53:52.842Z" }, - { url = "https://files.pythonhosted.org/packages/cb/a6/a6f7186a5297cad8ec53fd7578533b28f795fdf5372368c74bd7e6e9841c/wrapt-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:577dff354e7acd9d411eaf4bfe76b724c89c89c8fc9b7e127ee28c5f7bcb25b6", size = 115351, upload-time = "2026-03-06T02:53:32.684Z" }, - { url = "https://files.pythonhosted.org/packages/97/6f/06e66189e721dbebd5cf20e138acc4d1150288ce118462f2fcbff92d38db/wrapt-2.1.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:3d7b6fd105f8b24e5bd23ccf41cb1d1099796524bcc6f7fbb8fe576c44befbc9", size = 111748, upload-time = "2026-03-06T02:53:08.455Z" }, - { url = "https://files.pythonhosted.org/packages/ef/43/4808b86f499a51370fbdbdfa6cb91e9b9169e762716456471b619fca7a70/wrapt-2.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:866abdbf4612e0b34764922ef8b1c5668867610a718d3053d59e24a5e5fcfc15", size = 113783, upload-time = "2026-03-06T02:53:02.02Z" }, - { url = "https://files.pythonhosted.org/packages/91/2c/a3f28b8fa7ac2cefa01cfcaca3471f9b0460608d012b693998cd61ef43df/wrapt-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5a0a0a3a882393095573344075189eb2d566e0fd205a2b6414e9997b1b800a8b", size = 57977, upload-time = "2026-03-06T02:53:27.844Z" }, - { url = "https://files.pythonhosted.org/packages/3f/c3/2b1c7bd07a27b1db885a2fab469b707bdd35bddf30a113b4917a7e2139d2/wrapt-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:64a07a71d2730ba56f11d1a4b91f7817dc79bc134c11516b75d1921a7c6fcda1", size = 60336, upload-time = "2026-03-06T02:54:28.104Z" }, - { url = "https://files.pythonhosted.org/packages/ec/5c/76ece7b401b088daa6503d6264dd80f9a727df3e6042802de9a223084ea2/wrapt-2.1.2-cp311-cp311-win_arm64.whl", hash = "sha256:b89f095fe98bc12107f82a9f7d570dc83a0870291aeb6b1d7a7d35575f55d98a", size = 58756, upload-time = "2026-03-06T02:53:16.319Z" }, { url = "https://files.pythonhosted.org/packages/4c/b6/1db817582c49c7fcbb7df6809d0f515af29d7c2fbf57eb44c36e98fb1492/wrapt-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ff2aad9c4cda28a8f0653fc2d487596458c2a3f475e56ba02909e950a9efa6a9", size = 61255, upload-time = "2026-03-06T02:52:45.663Z" }, { url = "https://files.pythonhosted.org/packages/a2/16/9b02a6b99c09227c93cd4b73acc3678114154ec38da53043c0ddc1fba0dc/wrapt-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6433ea84e1cfacf32021d2a4ee909554ade7fd392caa6f7c13f1f4bf7b8e8748", size = 61848, upload-time = "2026-03-06T02:53:48.728Z" }, { url = "https://files.pythonhosted.org/packages/af/aa/ead46a88f9ec3a432a4832dfedb84092fc35af2d0ba40cd04aea3889f247/wrapt-2.1.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c20b757c268d30d6215916a5fa8461048d023865d888e437fab451139cad6c8e", size = 121433, upload-time = "2026-03-06T02:54:40.328Z" }, @@ -9792,18 +8437,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1a/c7/8528ac2dfa2c1e6708f647df7ae144ead13f0a31146f43c7264b4942bf12/wrapt-2.1.2-py3-none-any.whl", hash = "sha256:b8fd6fa2b2c4e7621808f8c62e8317f4aae56e59721ad933bac5239d913cf0e8", size = 43993, upload-time = "2026-03-06T02:53:12.905Z" }, ] -[[package]] -name = "wsproto" -version = "1.3.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c7/79/12135bdf8b9c9367b8701c2c19a14c913c120b882d50b014ca0d38083c2c/wsproto-1.3.2.tar.gz", hash = "sha256:b86885dcf294e15204919950f666e06ffc6c7c114ca900b060d6e16293528294", size = 50116, upload-time = "2025-11-20T18:18:01.871Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl", hash = "sha256:61eea322cdf56e8cc904bd3ad7573359a242ba65688716b0710a5eb12beab584", size = 24405, upload-time = "2025-11-20T18:18:00.454Z" }, -] - [[package]] name = "wurlitzer" version = "3.1.1" @@ -9813,52 +8446,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9a/24/93ce54550a9dd3fd996ed477f00221f215bf6da3580397fbc138d6036e2e/wurlitzer-3.1.1-py3-none-any.whl", hash = "sha256:0b2749c2cde3ef640bf314a9f94b24d929fe1ca476974719a6909dfc568c3aac", size = 8590, upload-time = "2024-06-12T10:27:28.787Z" }, ] -[[package]] -name = "xattr" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cffi" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/08/d5/25f7b19af3a2cb4000cac4f9e5525a40bec79f4f5d0ac9b517c0544586a0/xattr-1.3.0.tar.gz", hash = "sha256:30439fabd7de0787b27e9a6e1d569c5959854cb322f64ce7380fedbfa5035036", size = 17148, upload-time = "2025-10-13T22:16:47.353Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/64/292426ad5653e72c6e1325bbff22868a20077290d967cebb9c0624ad08b6/xattr-1.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:331a51bf8f20c27822f44054b0d760588462d3ed472d5e52ba135cf0bea510e8", size = 23448, upload-time = "2025-10-13T22:15:59.229Z" }, - { url = "https://files.pythonhosted.org/packages/63/84/6539fbe620da8e5927406e76b9c8abad8953025d5f578d792747c38a8c0e/xattr-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:196360f068b74fa0132a8c6001ce1333f095364b8f43b6fd8cdaf2f18741ef89", size = 18553, upload-time = "2025-10-13T22:16:00.151Z" }, - { url = "https://files.pythonhosted.org/packages/cc/bb/c1c2e24a49f8d13ff878fb85aabc42ea1b2f98ce08d8205b9661d517a9cc/xattr-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:405d2e4911d37f2b9400fa501acd920fe0c97fe2b2ec252cb23df4b59c000811", size = 18848, upload-time = "2025-10-13T22:16:01.046Z" }, - { url = "https://files.pythonhosted.org/packages/02/c2/a60aad150322b217dfe33695d8d9f32bc01e8f300641b6ba4b73f4b3c03f/xattr-1.3.0-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4ae3a66ae1effd40994f64defeeaa97da369406485e60bfb421f2d781be3b75d", size = 38547, upload-time = "2025-10-13T22:16:01.973Z" }, - { url = "https://files.pythonhosted.org/packages/c6/58/2eca142bad4ea0a2be6b58d3122d0acce310c4e53fa7defd168202772178/xattr-1.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:69cd3bfe779f7ba87abe6473fdfa428460cf9e78aeb7e390cfd737b784edf1b5", size = 38753, upload-time = "2025-10-13T22:16:03.244Z" }, - { url = "https://files.pythonhosted.org/packages/2b/50/d032e5254c2c27d36bdb02abdf2735db6768a441f0e3d0f139e0f9f56638/xattr-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c5742ca61761a99ae0c522f90a39d5fb8139280f27b254e3128482296d1df2db", size = 38054, upload-time = "2025-10-13T22:16:04.656Z" }, - { url = "https://files.pythonhosted.org/packages/04/24/458a306439aabe0083ca0a7b14c3e6a800ab9782b5ec0bdcec4ec9f3dc6c/xattr-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a04ada131e9bdfd32db3ab1efa9f852646f4f7c9d6fde0596c3825c67161be3", size = 37562, upload-time = "2025-10-13T22:16:05.97Z" }, - { url = "https://files.pythonhosted.org/packages/bf/78/00bdc9290066173e53e1e734d8d8e1a84a6faa9c66aee9df81e4d9aeec1c/xattr-1.3.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dd4e63614722d183e81842cb237fd1cc978d43384166f9fe22368bfcb187ebe5", size = 23476, upload-time = "2025-10-13T22:16:06.942Z" }, - { url = "https://files.pythonhosted.org/packages/53/16/5243722294eb982514fa7b6b87a29dfb7b29b8e5e1486500c5babaf6e4b3/xattr-1.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:995843ef374af73e3370b0c107319611f3cdcdb6d151d629449efecad36be4c4", size = 18556, upload-time = "2025-10-13T22:16:08.209Z" }, - { url = "https://files.pythonhosted.org/packages/d6/5c/d7ab0e547bea885b55f097206459bd612cefb652c5fc1f747130cbc0d42c/xattr-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fa23a25220e29d956cedf75746e3df6cc824cc1553326d6516479967c540e386", size = 18869, upload-time = "2025-10-13T22:16:10.319Z" }, - { url = "https://files.pythonhosted.org/packages/98/25/25cc7d64f07de644b7e9057842227adf61017e5bcfe59a79df79f768874c/xattr-1.3.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b4345387087fffcd28f709eb45aae113d911e1a1f4f0f70d46b43ba81e69ccdd", size = 38797, upload-time = "2025-10-13T22:16:11.624Z" }, - { url = "https://files.pythonhosted.org/packages/a9/24/cc350bcdbed006dfcc6ade0ac817693b8b3d4b2787f20e427fd0697042e4/xattr-1.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe92bb05eb849ab468fe13e942be0f8d7123f15d074f3aba5223fad0c4b484de", size = 38956, upload-time = "2025-10-13T22:16:13.121Z" }, - { url = "https://files.pythonhosted.org/packages/9b/b2/9416317ac89e2ed759a861857cda0d5e284c3691e6f460d36cc2bd5ce4d1/xattr-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6c42ef5bdac3febbe28d3db14d3a8a159d84ba5daca2b13deae6f9f1fc0d4092", size = 38214, upload-time = "2025-10-13T22:16:14.389Z" }, - { url = "https://files.pythonhosted.org/packages/38/63/188f7cb41ab35d795558325d5cc8ab552171d5498cfb178fd14409651e18/xattr-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2aaa5d66af6523332189108f34e966ca120ff816dfa077ca34b31e6263f8a236", size = 37754, upload-time = "2025-10-13T22:16:15.306Z" }, - { url = "https://files.pythonhosted.org/packages/27/d3/6a1731a339842afcbb2643bc93628d4ab9c52d1bf26a7b085ca8f35bba6e/xattr-1.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:937d8c91f6f372788aff8cc0984c4be3f0928584839aaa15ff1c95d64562071c", size = 23474, upload-time = "2025-10-13T22:16:16.33Z" }, - { url = "https://files.pythonhosted.org/packages/1b/25/6741ed3d4371eaa2fae70b259d17a580d858ebff8af0042a59e11bb6385f/xattr-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e470b3f15e9c3e263662506ff26e73b3027e1c9beac2cbe9ab89cad9c70c0495", size = 18558, upload-time = "2025-10-13T22:16:17.251Z" }, - { url = "https://files.pythonhosted.org/packages/ba/84/cc450688abeb8647aa93a62c1435bb532db11313abfeb9d43b28b4751503/xattr-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f2238b2a973fcbf5fefa1137db97c296d27f4721f7b7243a1fac51514565e9ec", size = 18869, upload-time = "2025-10-13T22:16:18.607Z" }, - { url = "https://files.pythonhosted.org/packages/b9/49/0e2315225ba7557e9801f9f0168a0195a7e13a3223088081eb32d2760533/xattr-1.3.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f32bb00395371f4a3bed87080ae315b19171ba114e8a5aa403a2c8508998ce78", size = 38702, upload-time = "2025-10-13T22:16:19.539Z" }, - { url = "https://files.pythonhosted.org/packages/7e/8c/de4f4441c318ac38a5d3d7d4b8b940305a667e9320c34a45e57f6eb6b0e8/xattr-1.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:78df56bfe3dd4912548561ed880225437d6d49ef082fe6ccd45670810fa53cfe", size = 38869, upload-time = "2025-10-13T22:16:20.554Z" }, - { url = "https://files.pythonhosted.org/packages/ef/2a/38e0498c22aa733a9b5265f4929af4613e5b967659cf3e5f2f933b3ba118/xattr-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:864c34c14728f21c3ef89a9f276d75ae5e31dd34f48064e0d37e4bf0f671fc6e", size = 38210, upload-time = "2025-10-13T22:16:22.212Z" }, - { url = "https://files.pythonhosted.org/packages/62/21/49b386eb8dcf42ac8e3ff55b6e8ea0a1e8b6b799571599c795265d2dc1b5/xattr-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1fd185b3f01121bd172c98b943f9341ca3b9ea6c6d3eb7fe7074723614d959ff", size = 37753, upload-time = "2025-10-13T22:16:23.959Z" }, - { url = "https://files.pythonhosted.org/packages/24/49/b8bc589427696d67bc2b0992c188e576f70242c586a379f97698772c0c3d/xattr-1.3.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:630c85020282bd0bcb72c3d031491c4e91d7f29bb4c094ebdfb9db51375c5b07", size = 23543, upload-time = "2025-10-13T22:16:25.242Z" }, - { url = "https://files.pythonhosted.org/packages/9d/0a/03192e78071cfb86e6d8ceae0e5dcec4bacf0fd734755263aabd01532e50/xattr-1.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:95f1e14a4d9ca160b4b78c527bf2bac6addbeb0fd9882c405fc0b5e3073a8752", size = 18673, upload-time = "2025-10-13T22:16:26.224Z" }, - { url = "https://files.pythonhosted.org/packages/3d/36/9ab4f0b5c3d10df3aceaecf7e395cabe7fb7c7c004b2dc3f3cff0ef70fc3/xattr-1.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:88557c0769f64b1d014aada916c9630cfefa38b0be6c247eae20740d2d8f7b47", size = 18877, upload-time = "2025-10-13T22:16:27.164Z" }, - { url = "https://files.pythonhosted.org/packages/1c/1c/ab905d19a1349e847e37e02933316d17adfd1dd70b64d366885ab0bd959d/xattr-1.3.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c6992eb5da32c0a1375a9eeacfab15c66eebc8bd34be63ebd1eae80cc2f8bf03", size = 38782, upload-time = "2025-10-13T22:16:28.157Z" }, - { url = "https://files.pythonhosted.org/packages/83/a7/f615a6e5d48d47e9febbe5a62b94ffa0d8bfc6d325b899873281abac10c4/xattr-1.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:da5954424099ca9d402933eaf6112c29ddde26e6da59b32f0bf5a4e35eec0b28", size = 38936, upload-time = "2025-10-13T22:16:29.291Z" }, - { url = "https://files.pythonhosted.org/packages/9f/6c/a8221567a7cbc00ac305a4842318562f90bb1fdd16636e1379361133f1f4/xattr-1.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:726b4d0b66724759132cacdcd84a5b19e00b0cdf704f4c2cf96d0c08dc5eaeb5", size = 38268, upload-time = "2025-10-13T22:16:30.238Z" }, - { url = "https://files.pythonhosted.org/packages/3e/4d/38a98df630e19360d98df8d98ec4a2560612840823f0bf55f81e0e84c866/xattr-1.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:928c49ceb0c70fc04732e46fa236d7c8281bfc3db1b40875e5f548bb14d2668c", size = 37825, upload-time = "2025-10-13T22:16:31.557Z" }, - { url = "https://files.pythonhosted.org/packages/97/3f/6d50237645edd83e9dc6bf6521e4e28335845b674cabefd69f12bc4db59a/xattr-1.3.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:f3bef26fd2d5d7b17488f4cc4424a69894c5a8ed71dd5f657fbbf69f77f68a51", size = 23788, upload-time = "2025-10-13T22:16:32.465Z" }, - { url = "https://files.pythonhosted.org/packages/f4/8b/3efd48c85e08d1bfcbd46f87368b155d3d3de78bb660b408fbaff7623572/xattr-1.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:64f1fb511f8463851e0d97294eb0e0fde54b059150da90582327fb43baa1bb92", size = 18825, upload-time = "2025-10-13T22:16:33.442Z" }, - { url = "https://files.pythonhosted.org/packages/fd/19/4b4e3e2ea5fa213ff4220e84450628fecde042b0961e7b4e6d845e555ade/xattr-1.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1e6c216927b16fd4b72df655d5124b69b2a406cb3132b5231179021182f0f0d1", size = 19023, upload-time = "2025-10-13T22:16:34.395Z" }, - { url = "https://files.pythonhosted.org/packages/6f/4a/6460befb22ce8d43abdb22d2bf5aa63b8311507c75dc50ad402681b4b095/xattr-1.3.0-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c0d9ab346cdd20539afddf2f9e123efee0fe8d54254d9fc580b4e2b4e6d77351", size = 43732, upload-time = "2025-10-13T22:16:35.41Z" }, - { url = "https://files.pythonhosted.org/packages/15/a8/3fa83e9f91dc868d764b2ca3758bf449945c4b1511e137e33a6210609b58/xattr-1.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2c5e7ba0e893042deef4e8638db7a497680f587ac7bd6d68925f29af633dfa6b", size = 43851, upload-time = "2025-10-13T22:16:36.416Z" }, - { url = "https://files.pythonhosted.org/packages/28/b3/06bf7f691c3f35e94a37e097ae1868fbaa916cc174b1b916fb7aeca441e4/xattr-1.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1e0dabb39596d8d7b83d6f9f7fa30be68cf15bfb135cb633e2aad9887d308a32", size = 43274, upload-time = "2025-10-13T22:16:37.805Z" }, - { url = "https://files.pythonhosted.org/packages/df/41/d6298c95513eabe091a6851bff5e7928fab49ffd9143808feaaf7721cf33/xattr-1.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5eeaa944516b7507ec51456751334b4880e421de169bbd067c4f32242670d606", size = 42864, upload-time = "2025-10-13T22:16:38.811Z" }, -] - [[package]] name = "xformers" version = "0.0.35" @@ -9879,21 +8466,6 @@ version = "3.6.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/02/84/30869e01909fb37a6cc7e18688ee8bf1e42d57e7e0777636bd47524c43c7/xxhash-3.6.0.tar.gz", hash = "sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6", size = 85160, upload-time = "2025-10-02T14:37:08.097Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/d4/cc2f0400e9154df4b9964249da78ebd72f318e35ccc425e9f403c392f22a/xxhash-3.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b47bbd8cf2d72797f3c2772eaaac0ded3d3af26481a26d7d7d41dc2d3c46b04a", size = 32844, upload-time = "2025-10-02T14:34:14.037Z" }, - { url = "https://files.pythonhosted.org/packages/5e/ec/1cc11cd13e26ea8bc3cb4af4eaadd8d46d5014aebb67be3f71fb0b68802a/xxhash-3.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2b6821e94346f96db75abaa6e255706fb06ebd530899ed76d32cd99f20dc52fa", size = 30809, upload-time = "2025-10-02T14:34:15.484Z" }, - { url = "https://files.pythonhosted.org/packages/04/5f/19fe357ea348d98ca22f456f75a30ac0916b51c753e1f8b2e0e6fb884cce/xxhash-3.6.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d0a9751f71a1a65ce3584e9cae4467651c7e70c9d31017fa57574583a4540248", size = 194665, upload-time = "2025-10-02T14:34:16.541Z" }, - { url = "https://files.pythonhosted.org/packages/90/3b/d1f1a8f5442a5fd8beedae110c5af7604dc37349a8e16519c13c19a9a2de/xxhash-3.6.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b29ee68625ab37b04c0b40c3fafdf24d2f75ccd778333cfb698f65f6c463f62", size = 213550, upload-time = "2025-10-02T14:34:17.878Z" }, - { url = "https://files.pythonhosted.org/packages/c4/ef/3a9b05eb527457d5db13a135a2ae1a26c80fecd624d20f3e8dcc4cb170f3/xxhash-3.6.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6812c25fe0d6c36a46ccb002f40f27ac903bf18af9f6dd8f9669cb4d176ab18f", size = 212384, upload-time = "2025-10-02T14:34:19.182Z" }, - { url = "https://files.pythonhosted.org/packages/0f/18/ccc194ee698c6c623acbf0f8c2969811a8a4b6185af5e824cd27b9e4fd3e/xxhash-3.6.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4ccbff013972390b51a18ef1255ef5ac125c92dc9143b2d1909f59abc765540e", size = 445749, upload-time = "2025-10-02T14:34:20.659Z" }, - { url = "https://files.pythonhosted.org/packages/a5/86/cf2c0321dc3940a7aa73076f4fd677a0fb3e405cb297ead7d864fd90847e/xxhash-3.6.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:297b7fbf86c82c550e12e8fb71968b3f033d27b874276ba3624ea868c11165a8", size = 193880, upload-time = "2025-10-02T14:34:22.431Z" }, - { url = "https://files.pythonhosted.org/packages/82/fb/96213c8560e6f948a1ecc9a7613f8032b19ee45f747f4fca4eb31bb6d6ed/xxhash-3.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dea26ae1eb293db089798d3973a5fc928a18fdd97cc8801226fae705b02b14b0", size = 210912, upload-time = "2025-10-02T14:34:23.937Z" }, - { url = "https://files.pythonhosted.org/packages/40/aa/4395e669b0606a096d6788f40dbdf2b819d6773aa290c19e6e83cbfc312f/xxhash-3.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7a0b169aafb98f4284f73635a8e93f0735f9cbde17bd5ec332480484241aaa77", size = 198654, upload-time = "2025-10-02T14:34:25.644Z" }, - { url = "https://files.pythonhosted.org/packages/67/74/b044fcd6b3d89e9b1b665924d85d3f400636c23590226feb1eb09e1176ce/xxhash-3.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:08d45aef063a4531b785cd72de4887766d01dc8f362a515693df349fdb825e0c", size = 210867, upload-time = "2025-10-02T14:34:27.203Z" }, - { url = "https://files.pythonhosted.org/packages/bc/fd/3ce73bf753b08cb19daee1eb14aa0d7fe331f8da9c02dd95316ddfe5275e/xxhash-3.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:929142361a48ee07f09121fe9e96a84950e8d4df3bb298ca5d88061969f34d7b", size = 414012, upload-time = "2025-10-02T14:34:28.409Z" }, - { url = "https://files.pythonhosted.org/packages/ba/b3/5a4241309217c5c876f156b10778f3ab3af7ba7e3259e6d5f5c7d0129eb2/xxhash-3.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51312c768403d8540487dbbfb557454cfc55589bbde6424456951f7fcd4facb3", size = 191409, upload-time = "2025-10-02T14:34:29.696Z" }, - { url = "https://files.pythonhosted.org/packages/c0/01/99bfbc15fb9abb9a72b088c1d95219fc4782b7d01fc835bd5744d66dd0b8/xxhash-3.6.0-cp311-cp311-win32.whl", hash = "sha256:d1927a69feddc24c987b337ce81ac15c4720955b667fe9b588e02254b80446fd", size = 30574, upload-time = "2025-10-02T14:34:31.028Z" }, - { url = "https://files.pythonhosted.org/packages/65/79/9d24d7f53819fe301b231044ea362ce64e86c74f6e8c8e51320de248b3e5/xxhash-3.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:26734cdc2d4ffe449b41d186bbeac416f704a482ed835d375a5c0cb02bc63fef", size = 31481, upload-time = "2025-10-02T14:34:32.062Z" }, - { url = "https://files.pythonhosted.org/packages/30/4e/15cd0e3e8772071344eab2961ce83f6e485111fed8beb491a3f1ce100270/xxhash-3.6.0-cp311-cp311-win_arm64.whl", hash = "sha256:d72f67ef8bf36e05f5b6c65e8524f265bd61071471cd4cf1d36743ebeeeb06b7", size = 27861, upload-time = "2025-10-02T14:34:33.555Z" }, { url = "https://files.pythonhosted.org/packages/9a/07/d9412f3d7d462347e4511181dea65e47e0d0e16e26fbee2ea86a2aefb657/xxhash-3.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c", size = 32744, upload-time = "2025-10-02T14:34:34.622Z" }, { url = "https://files.pythonhosted.org/packages/79/35/0429ee11d035fc33abe32dca1b2b69e8c18d236547b9a9b72c1929189b9a/xxhash-3.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204", size = 30816, upload-time = "2025-10-02T14:34:36.043Z" }, { url = "https://files.pythonhosted.org/packages/b7/f2/57eb99aa0f7d98624c0932c5b9a170e1806406cdbcdb510546634a1359e0/xxhash-3.6.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490", size = 194035, upload-time = "2025-10-02T14:34:37.354Z" }, @@ -9969,11 +8541,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9a/9a/c19c42c5b3f5a4aad748a6d5b4f23df3bed7ee5445accc65a0fb3ff03953/xxhash-3.6.0-cp314-cp314t-win32.whl", hash = "sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119", size = 31586, upload-time = "2025-10-02T14:36:15.603Z" }, { url = "https://files.pythonhosted.org/packages/03/d6/4cc450345be9924fd5dc8c590ceda1db5b43a0a889587b0ae81a95511360/xxhash-3.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f", size = 32526, upload-time = "2025-10-02T14:36:16.708Z" }, { url = "https://files.pythonhosted.org/packages/0f/c9/7243eb3f9eaabd1a88a5a5acadf06df2d83b100c62684b7425c6a11bcaa8/xxhash-3.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95", size = 28898, upload-time = "2025-10-02T14:36:17.843Z" }, - { url = "https://files.pythonhosted.org/packages/93/1e/8aec23647a34a249f62e2398c42955acd9b4c6ed5cf08cbea94dc46f78d2/xxhash-3.6.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0f7b7e2ec26c1666ad5fc9dbfa426a6a3367ceaf79db5dd76264659d509d73b0", size = 30662, upload-time = "2025-10-02T14:37:01.743Z" }, - { url = "https://files.pythonhosted.org/packages/b8/0b/b14510b38ba91caf43006209db846a696ceea6a847a0c9ba0a5b1adc53d6/xxhash-3.6.0-pp311-pypy311_pp73-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5dc1e14d14fa0f5789ec29a7062004b5933964bb9b02aae6622b8f530dc40296", size = 41056, upload-time = "2025-10-02T14:37:02.879Z" }, - { url = "https://files.pythonhosted.org/packages/50/55/15a7b8a56590e66ccd374bbfa3f9ffc45b810886c8c3b614e3f90bd2367c/xxhash-3.6.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:881b47fc47e051b37d94d13e7455131054b56749b91b508b0907eb07900d1c13", size = 36251, upload-time = "2025-10-02T14:37:04.44Z" }, - { url = "https://files.pythonhosted.org/packages/62/b2/5ac99a041a29e58e95f907876b04f7067a0242cb85b5f39e726153981503/xxhash-3.6.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6dc31591899f5e5666f04cc2e529e69b4072827085c1ef15294d91a004bc1bd", size = 32481, upload-time = "2025-10-02T14:37:05.869Z" }, - { url = "https://files.pythonhosted.org/packages/7b/d9/8d95e906764a386a3d3b596f3c68bb63687dfca806373509f51ce8eea81f/xxhash-3.6.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:15e0dac10eb9309508bfc41f7f9deaa7755c69e35af835db9cb10751adebc35d", size = 31565, upload-time = "2025-10-02T14:37:06.966Z" }, ] [[package]] @@ -9987,24 +8554,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", size = 123641, upload-time = "2026-03-01T22:04:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", size = 86248, upload-time = "2026-03-01T22:04:44.757Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", size = 85988, upload-time = "2026-03-01T22:04:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", size = 100566, upload-time = "2026-03-01T22:04:47.639Z" }, - { url = "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", size = 92079, upload-time = "2026-03-01T22:04:48.925Z" }, - { url = "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", size = 108741, upload-time = "2026-03-01T22:04:50.838Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", size = 108099, upload-time = "2026-03-01T22:04:52.499Z" }, - { url = "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", size = 102678, upload-time = "2026-03-01T22:04:55.176Z" }, - { url = "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", size = 100803, upload-time = "2026-03-01T22:04:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", size = 100163, upload-time = "2026-03-01T22:04:58.492Z" }, - { url = "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", size = 93859, upload-time = "2026-03-01T22:05:00.268Z" }, - { url = "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", size = 108202, upload-time = "2026-03-01T22:05:02.273Z" }, - { url = "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", size = 99866, upload-time = "2026-03-01T22:05:03.597Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", size = 107852, upload-time = "2026-03-01T22:05:04.986Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", size = 102919, upload-time = "2026-03-01T22:05:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl", hash = "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", size = 82602, upload-time = "2026-03-01T22:05:08.444Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", size = 87461, upload-time = "2026-03-01T22:05:10.145Z" }, - { url = "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", size = 82336, upload-time = "2026-03-01T22:05:11.554Z" }, { url = "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", size = 124737, upload-time = "2026-03-01T22:05:12.897Z" }, { url = "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", size = 87029, upload-time = "2026-03-01T22:05:14.376Z" }, { url = "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", size = 86310, upload-time = "2026-03-01T22:05:15.71Z" }, @@ -10113,23 +8662,6 @@ version = "0.25.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz", hash = "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", size = 711513, upload-time = "2025-09-14T22:15:54.002Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/83/c3ca27c363d104980f1c9cee1101cc8ba724ac8c28a033ede6aab89585b1/zstandard-0.25.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:933b65d7680ea337180733cf9e87293cc5500cc0eb3fc8769f4d3c88d724ec5c", size = 795254, upload-time = "2025-09-14T22:16:26.137Z" }, - { url = "https://files.pythonhosted.org/packages/ac/4d/e66465c5411a7cf4866aeadc7d108081d8ceba9bc7abe6b14aa21c671ec3/zstandard-0.25.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3f79487c687b1fc69f19e487cd949bf3aae653d181dfb5fde3bf6d18894706f", size = 640559, upload-time = "2025-09-14T22:16:27.973Z" }, - { url = "https://files.pythonhosted.org/packages/12/56/354fe655905f290d3b147b33fe946b0f27e791e4b50a5f004c802cb3eb7b/zstandard-0.25.0-cp311-cp311-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:0bbc9a0c65ce0eea3c34a691e3c4b6889f5f3909ba4822ab385fab9057099431", size = 5348020, upload-time = "2025-09-14T22:16:29.523Z" }, - { url = "https://files.pythonhosted.org/packages/3b/13/2b7ed68bd85e69a2069bcc72141d378f22cae5a0f3b353a2c8f50ef30c1b/zstandard-0.25.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:01582723b3ccd6939ab7b3a78622c573799d5d8737b534b86d0e06ac18dbde4a", size = 5058126, upload-time = "2025-09-14T22:16:31.811Z" }, - { url = "https://files.pythonhosted.org/packages/c9/dd/fdaf0674f4b10d92cb120ccff58bbb6626bf8368f00ebfd2a41ba4a0dc99/zstandard-0.25.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5f1ad7bf88535edcf30038f6919abe087f606f62c00a87d7e33e7fc57cb69fcc", size = 5405390, upload-time = "2025-09-14T22:16:33.486Z" }, - { url = "https://files.pythonhosted.org/packages/0f/67/354d1555575bc2490435f90d67ca4dd65238ff2f119f30f72d5cde09c2ad/zstandard-0.25.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:06acb75eebeedb77b69048031282737717a63e71e4ae3f77cc0c3b9508320df6", size = 5452914, upload-time = "2025-09-14T22:16:35.277Z" }, - { url = "https://files.pythonhosted.org/packages/bb/1f/e9cfd801a3f9190bf3e759c422bbfd2247db9d7f3d54a56ecde70137791a/zstandard-0.25.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9300d02ea7c6506f00e627e287e0492a5eb0371ec1670ae852fefffa6164b072", size = 5559635, upload-time = "2025-09-14T22:16:37.141Z" }, - { url = "https://files.pythonhosted.org/packages/21/88/5ba550f797ca953a52d708c8e4f380959e7e3280af029e38fbf47b55916e/zstandard-0.25.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfd06b1c5584b657a2892a6014c2f4c20e0db0208c159148fa78c65f7e0b0277", size = 5048277, upload-time = "2025-09-14T22:16:38.807Z" }, - { url = "https://files.pythonhosted.org/packages/46/c0/ca3e533b4fa03112facbe7fbe7779cb1ebec215688e5df576fe5429172e0/zstandard-0.25.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f373da2c1757bb7f1acaf09369cdc1d51d84131e50d5fa9863982fd626466313", size = 5574377, upload-time = "2025-09-14T22:16:40.523Z" }, - { url = "https://files.pythonhosted.org/packages/12/9b/3fb626390113f272abd0799fd677ea33d5fc3ec185e62e6be534493c4b60/zstandard-0.25.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c0e5a65158a7946e7a7affa6418878ef97ab66636f13353b8502d7ea03c8097", size = 4961493, upload-time = "2025-09-14T22:16:43.3Z" }, - { url = "https://files.pythonhosted.org/packages/cb/d3/23094a6b6a4b1343b27ae68249daa17ae0651fcfec9ed4de09d14b940285/zstandard-0.25.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c8e167d5adf59476fa3e37bee730890e389410c354771a62e3c076c86f9f7778", size = 5269018, upload-time = "2025-09-14T22:16:45.292Z" }, - { url = "https://files.pythonhosted.org/packages/8c/a7/bb5a0c1c0f3f4b5e9d5b55198e39de91e04ba7c205cc46fcb0f95f0383c1/zstandard-0.25.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:98750a309eb2f020da61e727de7d7ba3c57c97cf6213f6f6277bb7fb42a8e065", size = 5443672, upload-time = "2025-09-14T22:16:47.076Z" }, - { url = "https://files.pythonhosted.org/packages/27/22/503347aa08d073993f25109c36c8d9f029c7d5949198050962cb568dfa5e/zstandard-0.25.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:22a086cff1b6ceca18a8dd6096ec631e430e93a8e70a9ca5efa7561a00f826fa", size = 5822753, upload-time = "2025-09-14T22:16:49.316Z" }, - { url = "https://files.pythonhosted.org/packages/e2/be/94267dc6ee64f0f8ba2b2ae7c7a2df934a816baaa7291db9e1aa77394c3c/zstandard-0.25.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:72d35d7aa0bba323965da807a462b0966c91608ef3a48ba761678cb20ce5d8b7", size = 5366047, upload-time = "2025-09-14T22:16:51.328Z" }, - { url = "https://files.pythonhosted.org/packages/7b/a3/732893eab0a3a7aecff8b99052fecf9f605cf0fb5fb6d0290e36beee47a4/zstandard-0.25.0-cp311-cp311-win32.whl", hash = "sha256:f5aeea11ded7320a84dcdd62a3d95b5186834224a9e55b92ccae35d21a8b63d4", size = 436484, upload-time = "2025-09-14T22:16:55.005Z" }, - { url = "https://files.pythonhosted.org/packages/43/a3/c6155f5c1cce691cb80dfd38627046e50af3ee9ddc5d0b45b9b063bfb8c9/zstandard-0.25.0-cp311-cp311-win_amd64.whl", hash = "sha256:daab68faadb847063d0c56f361a289c4f268706b598afbf9ad113cbe5c38b6b2", size = 506183, upload-time = "2025-09-14T22:16:52.753Z" }, - { url = "https://files.pythonhosted.org/packages/8c/3e/8945ab86a0820cc0e0cdbf38086a92868a9172020fdab8a03ac19662b0e5/zstandard-0.25.0-cp311-cp311-win_arm64.whl", hash = "sha256:22a06c5df3751bb7dc67406f5374734ccee8ed37fc5981bf1ad7041831fa1137", size = 462533, upload-time = "2025-09-14T22:16:53.878Z" }, { url = "https://files.pythonhosted.org/packages/82/fc/f26eb6ef91ae723a03e16eddb198abcfce2bc5a42e224d44cc8b6765e57e/zstandard-0.25.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", size = 795738, upload-time = "2025-09-14T22:16:56.237Z" }, { url = "https://files.pythonhosted.org/packages/aa/1c/d920d64b22f8dd028a8b90e2d756e431a5d86194caa78e3819c7bf53b4b3/zstandard-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", size = 640436, upload-time = "2025-09-14T22:16:57.774Z" }, { url = "https://files.pythonhosted.org/packages/53/6c/288c3f0bd9fcfe9ca41e2c2fbfd17b2097f6af57b62a81161941f09afa76/zstandard-0.25.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", size = 5343019, upload-time = "2025-09-14T22:16:59.302Z" }, diff --git a/vllm_runtime/src/art_vllm_runtime/dedicated_server.py b/vllm_runtime/src/art_vllm_runtime/dedicated_server.py index 73590f03b..856c055b9 100644 --- a/vllm_runtime/src/art_vllm_runtime/dedicated_server.py +++ b/vllm_runtime/src/art_vllm_runtime/dedicated_server.py @@ -101,7 +101,9 @@ def _append_cli_arg(vllm_args: list[str], key: str, value: object) -> None: match value: case True: vllm_args.append(cli_key) - case False | None: + case False: + vllm_args.append(f"--no-{key.replace('_', '-')}") + case None: return case str() | int() | float(): vllm_args.append(f"{cli_key}={value}") @@ -137,12 +139,13 @@ def _append_cli_arg(vllm_args: list[str], key: str, value: object) -> None: def main(argv: list[str] | None = None) -> None: args = parse_args(argv) + engine_args = json.loads(args.engine_args_json) + server_args = json.loads(args.server_args_json) os.environ["CUDA_VISIBLE_DEVICES"] = args.cuda_visible_devices os.environ["VLLM_ALLOW_RUNTIME_LORA_UPDATING"] = "1" if args.rollout_weights_mode == "merged": os.environ["VLLM_SERVER_DEV_MODE"] = "1" - apply_vllm_runtime_patches() from vllm.entrypoints.openai import api_server @@ -152,9 +155,6 @@ def main(argv: list[str] | None = None) -> None: ) from vllm.utils.argparse_utils import FlexibleArgumentParser - engine_args = json.loads(args.engine_args_json) - server_args = json.loads(args.server_args_json) - _patch_art_runtime_routes() vllm_args = [ diff --git a/vllm_runtime/src/art_vllm_runtime/patches.py b/vllm_runtime/src/art_vllm_runtime/patches.py index aed69b601..f4f58eac9 100644 --- a/vllm_runtime/src/art_vllm_runtime/patches.py +++ b/vllm_runtime/src/art_vllm_runtime/patches.py @@ -1,8 +1,14 @@ """Monkey patches and bootstrap contract for the ART-owned vLLM runtime.""" import ctypes +import inspect +import logging from typing import Any +import numpy as np + +logger = logging.getLogger(__name__) + def apply_vllm_runtime_patches() -> None: patch_transformers_v5_compat() @@ -10,6 +16,7 @@ def apply_vllm_runtime_patches() -> None: patch_listen_for_disconnect() patch_tool_parser_manager() patch_nccl_unique_id_bootstrap() + patch_routed_experts_prefix_cache_sidecar() def patch_transformers_v5_compat() -> None: @@ -55,6 +62,7 @@ def __init__(self, *args: object, **kwargs: object) -> None: self.logprobs = True if self.top_logprobs is None: self.top_logprobs = 0 + self.return_token_ids = True protocol.ChatCompletionRequest = ChatCompletionRequest # ty:ignore[invalid-assignment] setattr(protocol, "_art_chat_completion_request_patched", True) @@ -160,3 +168,357 @@ def patched_comm_init_rank( patched_comm_init_rank.__art_patched__ = True # type: ignore[attr-defined] NCCLLibrary.ncclCommInitRank = patched_comm_init_rank # type: ignore[method-assign] + + +def _lora_cache_key(lora_request: Any) -> tuple[Any, ...]: + if lora_request is None: + return () + return ( + getattr(lora_request, "adapter_id", None), + getattr(lora_request, "name", None), + getattr(lora_request, "path", None), + ) + + +def _request_token_ids(req_state: Any) -> list[int] | None: + prompt_token_ids = getattr(req_state, "prompt_token_ids", None) + if prompt_token_ids is None: + return None + return list(prompt_token_ids) + list(getattr(req_state, "output_token_ids", ())) + + +def _route_block_key( + token_ids: list[int], + end: int, + lora_key: tuple[Any, ...], +) -> tuple[Any, ...]: + return (lora_key, tuple(token_ids[:end])) + + +def _runner_block_size(runner: Any) -> int: + kv_cache_config = getattr(runner, "kv_cache_config", None) + groups = getattr(kv_cache_config, "kv_cache_groups", None) + if groups and len(groups) == 1: + return int(groups[0].kv_cache_spec.block_size) + return int(getattr(runner.cache_config, "block_size", 16)) + + +def _request_snapshots( + runner: Any, ordered: dict[str, int] +) -> dict[str, dict[str, Any]]: + snapshots: dict[str, dict[str, Any]] = {} + for req_id in ordered: + req_state = runner.requests.get(req_id) + if req_state is None: + continue + token_ids = _request_token_ids(req_state) + if token_ids is None: + continue + snapshots[req_id] = { + "token_ids": token_ids, + "lora_key": _lora_cache_key(getattr(req_state, "lora_request", None)), + "num_computed_tokens": int(getattr(req_state, "num_computed_tokens", 0)), + } + return snapshots + + +def patch_routed_experts_prefix_cache_sidecar() -> None: + from vllm.model_executor.layers.fused_moe import routed_experts_capturer + + if getattr(routed_experts_capturer, "_art_prefix_route_sidecar_patched", False): + return + + host_cls = routed_experts_capturer._RoutedExpertsHostCache + capturer_cls = routed_experts_capturer._RoutedExpertsCapturerReal + + original_host_init = host_cls.__init__ + original_get_or_grow_buffer = host_cls.get_or_grow_buffer + original_free_request = host_cls.free_request + original_scatter_to_host = capturer_cls._scatter_to_host + original_get_routed_experts = capturer_cls.get_routed_experts + original_issue_routing_d2h_copy = routed_experts_capturer.issue_routing_d2h_copy + + def host_init(self: Any, *args: Any, **kwargs: Any) -> None: + original_host_init(self, *args, **kwargs) + self._art_req_filled_masks: dict[str, np.ndarray] = {} + self._art_prefix_route_blocks: dict[tuple[Any, ...], np.ndarray] = {} + self._art_prefix_route_waiters: dict[ + tuple[Any, ...], list[tuple[str, int, int]] + ] = {} + self._art_prefix_route_needs_by_req: dict[str, set[tuple[Any, ...]]] = {} + self._art_prefix_route_hydrated_tokens = 0 + self._art_prefix_route_cache_misses = 0 + self._art_prefix_route_cache_conflicts = 0 + + def get_or_grow_buffer(self: Any, req_id: str, max_pos: int) -> np.ndarray: + buf = original_get_or_grow_buffer(self, req_id, max_pos) + mask = self._art_req_filled_masks.get(req_id) + if mask is None: + self._art_req_filled_masks[req_id] = np.zeros(buf.shape[0], dtype=np.bool_) + elif mask.shape[0] < buf.shape[0]: + new_mask = np.zeros(buf.shape[0], dtype=np.bool_) + new_mask[: mask.shape[0]] = mask + self._art_req_filled_masks[req_id] = new_mask + return buf + + def free_request(self: Any, req_id: str) -> None: + original_free_request(self, req_id) + self._art_req_filled_masks.pop(req_id, None) + for key in self._art_prefix_route_needs_by_req.pop(req_id, set()): + waiters = self._art_prefix_route_waiters.get(key) + if waiters is None: + continue + waiters = [waiter for waiter in waiters if waiter[0] != req_id] + if waiters: + self._art_prefix_route_waiters[key] = waiters + else: + self._art_prefix_route_waiters.pop(key, None) + + def mark_filled(self: Any, req_id: str, positions: np.ndarray) -> None: + if positions.size == 0: + return + self.get_or_grow_buffer(req_id, int(positions.max())) + self._art_req_filled_masks[req_id][positions] = True + + def require_filled(self: Any, req_id: str, seqlen: int) -> None: + mask = self._art_req_filled_masks.get(req_id) + if mask is None or mask.shape[0] < seqlen or not bool(mask[:seqlen].all()): + available = ( + mask[:seqlen] if mask is not None else np.zeros(0, dtype=np.bool_) + ) + missing = np.flatnonzero(~available)[:16].tolist() + raise RuntimeError( + "Routed expert capture is incomplete for request " + f"{req_id}: seqlen={seqlen}, first_missing_positions={missing}" + ) + + def fill_prefix_block( + self: Any, + req_id: str, + start: int, + end: int, + value: np.ndarray, + key: tuple[Any, ...] | None = None, + ) -> bool: + buf = self.get_or_grow_buffer(req_id, end - 1) + mask = self._art_req_filled_masks[req_id] + if bool(mask[start:end].all()): + if key is not None: + needs = self._art_prefix_route_needs_by_req.get(req_id) + if needs is not None: + needs.discard(key) + if not needs: + self._art_prefix_route_needs_by_req.pop(req_id, None) + return False + buf[start:end] = value + mask[start:end] = True + self.update_filled_len(req_id, end - 1) + if key is not None: + needs = self._art_prefix_route_needs_by_req.get(req_id) + if needs is not None: + needs.discard(key) + if not needs: + self._art_prefix_route_needs_by_req.pop(req_id, None) + return True + + def store_prefix_block( + self: Any, + key: tuple[Any, ...], + value: np.ndarray, + ) -> None: + existing = self._art_prefix_route_blocks.get(key) + if existing is None: + existing = value.copy() + self._art_prefix_route_blocks[key] = existing + elif not np.array_equal(existing, value): + self._art_prefix_route_cache_conflicts += 1 + hydrated = 0 + for req_id, start, end in self._art_prefix_route_waiters.pop(key, []): + if self._art_fill_prefix_block(req_id, start, end, existing, key): + hydrated += end - start + if hydrated: + self._art_prefix_route_hydrated_tokens += hydrated + logger.info( + "Hydrated %s routed-expert prefix-cache tokens from materialized " + "route block", + hydrated, + ) + + def store_prefix_blocks( + self: Any, + req_id: str, + token_ids: list[int], + lora_key: tuple[Any, ...], + block_size: int, + max_pos_exclusive: int, + ) -> None: + if block_size <= 0: + return + upper = min(max_pos_exclusive, len(token_ids)) + upper -= upper % block_size + if upper <= 0: + return + buf = self.get_buffer(req_id) + mask = self._art_req_filled_masks.get(req_id) + if buf is None or mask is None: + return + for end in range(block_size, upper + 1, block_size): + start = end - block_size + if end > mask.shape[0] or not bool(mask[start:end].all()): + continue + key = _route_block_key(token_ids, end, lora_key) + value = buf[start:end].copy() + self._art_store_prefix_block(key, value) + + def need_cached_prefix( + self: Any, + req_id: str, + token_ids: list[int], + lora_key: tuple[Any, ...], + cached_len: int, + block_size: int, + ) -> None: + if block_size <= 0 or cached_len <= 0: + return + upper = min(cached_len, len(token_ids)) + upper -= upper % block_size + if upper <= 0: + return + hydrated = 0 + for end in range(block_size, upper + 1, block_size): + start = end - block_size + mask = self._art_req_filled_masks.get(req_id) + if ( + mask is not None + and end <= mask.shape[0] + and bool(mask[start:end].all()) + ): + continue + key = _route_block_key(token_ids, end, lora_key) + value = self._art_prefix_route_blocks.get(key) + if value is None: + needs = self._art_prefix_route_needs_by_req.setdefault(req_id, set()) + if key not in needs: + self._art_prefix_route_waiters.setdefault(key, []).append( + (req_id, start, end) + ) + needs.add(key) + self._art_prefix_route_cache_misses += block_size + continue + if self._art_fill_prefix_block(req_id, start, end, value, key): + hydrated += block_size + if hydrated: + self._art_prefix_route_hydrated_tokens += hydrated + logger.info( + "Hydrated %s routed-expert prefix-cache tokens for request %s", + hydrated, + req_id, + ) + + def require_no_unmet_prefix_route_needs(self: Any, req_id: str) -> None: + needs = self._art_prefix_route_needs_by_req.get(req_id) + if needs: + raise RuntimeError( + "Routed expert capture is missing materialized prefix-cache " + f"route blocks for request {req_id}: unmet_blocks={len(needs)}" + ) + + def scatter_to_host(self: Any) -> None: + positions = self._pending_positions.copy() + scheduled = dict(self._pending_num_scheduled or {}) + metadata = getattr(self, "_art_pending_route_metadata", None) + original_scatter_to_host(self) + host_cache = self.host_cache + if host_cache is None: + return + block_size = int((metadata or {}).get("block_size", 0)) + snapshots = (metadata or {}).get("snapshots", {}) + offset = 0 + for req_id, n_tokens in scheduled.items(): + pos = positions[offset : offset + n_tokens] + host_cache._art_mark_filled(req_id, pos) + snapshot = snapshots.get(req_id) + if snapshot is not None and pos.size: + host_cache._art_store_prefix_blocks( + req_id, + snapshot["token_ids"], + snapshot["lora_key"], + block_size, + int(pos.max()) + 1, + ) + offset += n_tokens + self._art_pending_route_metadata = None + + def get_routed_experts( + self: Any, + req_id: str, + seqlen: int | None = None, + free_slot: bool = True, + ) -> np.ndarray | None: + if self.host_cache is not None: + filled = self.host_cache.get_filled_len(req_id) + effective_len = min(filled, seqlen) if seqlen is not None else filled + if effective_len > 0: + self.host_cache._art_require_no_unmet_prefix_route_needs(req_id) + self.host_cache._art_require_filled(req_id, effective_len) + return original_get_routed_experts(self, req_id, seqlen, free_slot) + + def issue_routing_d2h_copy( + input_batch_req_ids: list[str], + num_scheduled_tokens: dict[str, int], + positions: Any, + positions_cpu: Any, + ) -> None: + capturer = routed_experts_capturer.get_global_experts_capturer() + host_cache = capturer.get_host_cache() if capturer is not None else None + frame = inspect.currentframe() + runner = frame.f_back.f_locals.get("self") if frame and frame.f_back else None + ordered = { + req_id: num_scheduled_tokens[req_id] + for req_id in input_batch_req_ids + if req_id in num_scheduled_tokens + } + metadata: dict[str, Any] | None = None + if host_cache is not None and runner is not None: + block_size = _runner_block_size(runner) + snapshots = _request_snapshots(runner, ordered) + for req_id, snapshot in snapshots.items(): + host_cache._art_need_cached_prefix( + req_id, + snapshot["token_ids"], + snapshot["lora_key"], + snapshot["num_computed_tokens"], + block_size, + ) + metadata = {"block_size": block_size, "snapshots": snapshots} + original_issue_routing_d2h_copy( + input_batch_req_ids, + num_scheduled_tokens, + positions, + positions_cpu, + ) + if capturer is not None and metadata is not None and sum(ordered.values()) > 0: + capturer._art_pending_route_metadata = metadata + + host_cls.__init__ = host_init # type: ignore[method-assign] + host_cls.get_or_grow_buffer = get_or_grow_buffer # type: ignore[method-assign] + host_cls.free_request = free_request # type: ignore[method-assign] + host_cls._art_mark_filled = mark_filled # type: ignore[attr-defined] + host_cls._art_require_filled = require_filled # type: ignore[attr-defined] + host_cls._art_fill_prefix_block = fill_prefix_block # type: ignore[attr-defined] + host_cls._art_store_prefix_block = store_prefix_block # type: ignore[attr-defined] + host_cls._art_store_prefix_blocks = store_prefix_blocks # type: ignore[attr-defined] + host_cls._art_need_cached_prefix = need_cached_prefix # type: ignore[attr-defined] + host_cls._art_require_no_unmet_prefix_route_needs = ( # type: ignore[attr-defined] + require_no_unmet_prefix_route_needs + ) + capturer_cls._scatter_to_host = scatter_to_host # type: ignore[method-assign] + capturer_cls.get_routed_experts = get_routed_experts # type: ignore[method-assign] + routed_experts_capturer.issue_routing_d2h_copy = issue_routing_d2h_copy + try: + from vllm.v1.worker import gpu_model_runner + + gpu_model_runner.issue_routing_d2h_copy = issue_routing_d2h_copy + except Exception: + pass + setattr(routed_experts_capturer, "_art_prefix_route_sidecar_patched", True)