mirror of
https://github.com/p-e-w/heretic.git
synced 2026-09-02 02:16:16 -07:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 26ea30e117 | |||
| c6f1f34a63 | |||
| ce355f98c8 | |||
| 33833aeec2 | |||
| 9b85b7052c | |||
| 19f3ce3108 | |||
| 13e464716f | |||
| 47cd3b16f2 | |||
| faf3c154aa | |||
| 3abe88c39f | |||
| 4338d28cef | |||
| 9f2045ccaa | |||
| 03e9514024 | |||
| 8593a5b416 | |||
| 9b323a1aba | |||
| 4d6e0032e4 | |||
| 3f68a0d4e5 | |||
| 00185db9fc | |||
| e218c30e8c | |||
| 554a58aa0f | |||
| b186d6c28e | |||
| 6ea3b8d778 | |||
| 6757ada999 | |||
| 2fd163f5e4 | |||
| e735203d56 | |||
| ed14dd14ca | |||
| 1a9d01c002 | |||
| c9ce36ddde | |||
| d68a41fb54 | |||
| a3dbfd21e6 | |||
| 61c59f7227 | |||
| 46b5ced274 | |||
| c62e10d570 | |||
| 906d96f78a | |||
| b79aa717c6 | |||
| db07814a97 | |||
| b790094193 | |||
| 6338e2c99b | |||
| 4dcacb5eba | |||
| b8d2c5a7e9 | |||
| 4e3a3a78a3 | |||
| 551db26bb7 | |||
| 8b5b85bec9 | |||
| 1b4851536d | |||
| b2bdc1f9d6 | |||
| 9b7624ddfa | |||
| 0e7c14d94a | |||
| 02ce8ad079 | |||
| 79ea9ce905 | |||
| 216c089974 | |||
| 43f8e86a84 | |||
| da92f745de | |||
| ebb5e651df | |||
| 513e3acc72 |
@@ -40,6 +40,11 @@ jobs:
|
||||
- name: Check typing
|
||||
run: uv run ty check --output-format=github --error-on-warning .
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
PYTHONUNBUFFERED: "1"
|
||||
run: uv run tests/run_tests.py 2>&1
|
||||
|
||||
- name: Build package
|
||||
run: uv build
|
||||
|
||||
|
||||
+6
-3
@@ -15,11 +15,14 @@ wheels/
|
||||
# Editors
|
||||
/.vscode/
|
||||
|
||||
# Configuration files
|
||||
# Configuration file (root only, not ignored in test directories)
|
||||
/config.toml
|
||||
|
||||
# Study checkpoints
|
||||
/checkpoints/
|
||||
checkpoints/
|
||||
|
||||
# Residual plots
|
||||
/plots/
|
||||
plots/
|
||||
|
||||
# Models generated by tests
|
||||
/tests/*/model/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<img width="128" height="128" align="right" alt="Logo" src="https://github.com/user-attachments/assets/df5f2840-2f92-4991-aa57-252747d7182e" />
|
||||
<img width="128" align="right" alt="Logo" src="https://github.com/user-attachments/assets/df5f2840-2f92-4991-aa57-252747d7182e" />
|
||||
|
||||
# Heretic: Fully automatic censorship removal for language models<br><br>[](https://discord.gg/gdXc48gSyT) [](https://huggingface.co/heretic-org)
|
||||
# Heretic: Fully automatic censorship removal for language models<br><br>[](https://discord.gg/gdXc48gSyT) [](https://matrix.to/#/#heretic:matrix.org) [](https://huggingface.co/heretic-org) [](https://codeberg.org/p-e-w/heretic)
|
||||
|
||||
[](https://trendshift.io/repositories/20538)
|
||||
|
||||
@@ -20,6 +20,11 @@ as possible. Using Heretic does not require an understanding of transformer
|
||||
internals. In fact, anyone who knows how to run a command-line program
|
||||
can use Heretic to decensor language models.
|
||||
|
||||
Heretic supports most dense models, including many multimodal models,
|
||||
several different MoE architectures, and even some hybrid models like Qwen3.5.
|
||||
Pure state-space models and certain other research architectures are not yet
|
||||
supported out of the box.
|
||||
|
||||
<img width="650" height="715" alt="Screenshot" src="https://github.com/user-attachments/assets/d71a5efa-d6be-4705-a817-63332afb2d15" />
|
||||
|
||||
|
||||
@@ -65,15 +70,15 @@ Heretic have been well-received by users (links and emphasis added):
|
||||
> Has been the best unquantized abliterated model that I have been able to run on 16gb vram."
|
||||
> [*(Link to comment)*](https://old.reddit.com/r/LocalLLaMA/comments/1phjxca/im_calling_these_people_out_right_now/nt06tji/)
|
||||
|
||||
Heretic supports most dense models, including many multimodal models, and
|
||||
several different MoE architectures. It does not yet support SSMs/hybrid models,
|
||||
models with inhomogeneous layers, and certain novel attention systems.
|
||||
Heretic models have also been independently benchmarked using standard metrics
|
||||
like MMLU and GSM8K, and have been found to compare favorably with models
|
||||
produced by competing abliteration tools:
|
||||
[1](https://old.reddit.com/r/LocalLLaMA/comments/1sojjoc/abliterlitics_benchmark_and_tensor_analysis/),
|
||||
[2](https://old.reddit.com/r/LocalLLaMA/comments/1sy18lx/abliterlitics_benchmarks_and_tensor_comparison/).
|
||||
|
||||
You can find a small collection of models that have been decensored using Heretic
|
||||
[on Hugging Face](https://huggingface.co/collections/p-e-w/the-bestiary),
|
||||
and the community has created and published
|
||||
[well over 1,000](https://huggingface.co/models?other=heretic)
|
||||
Heretic models in addition to those.
|
||||
The community has created and published
|
||||
[well over 4000](https://huggingface.co/models?other=heretic)
|
||||
models with Heretic.
|
||||
|
||||
|
||||
## Usage
|
||||
@@ -81,13 +86,28 @@ Heretic models in addition to those.
|
||||
Prepare a Python 3.10+ environment with PyTorch 2.2+ installed as appropriate
|
||||
for your hardware. Then run:
|
||||
|
||||
```
|
||||
```sh
|
||||
pip install -U heretic-llm
|
||||
heretic Qwen/Qwen3-4B-Instruct-2507
|
||||
```
|
||||
|
||||
Replace `Qwen/Qwen3-4B-Instruct-2507` with whatever model you want to decensor.
|
||||
|
||||
> [!IMPORTANT]
|
||||
>
|
||||
> While PyTorch 2.2 is the minimum version of PyTorch needed for Heretic to work,
|
||||
> some models and configurations might require features only found in
|
||||
> later versions. For example, loading MXFP4-quantized models like gpt-oss
|
||||
> uses `torch.accelerator`, which was added in PyTorch 2.6.
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> Heretic uses [uv](https://docs.astral.sh/uv/) for dependency management,
|
||||
> and the repository includes a `uv.lock` file pinning every package version.
|
||||
> If you already use uv (and you probably should!), you can just clone the repo
|
||||
> and run Heretic with `uv run heretic`, which ensures that your dependencies
|
||||
> match those used by the developers, improving reliability and security.
|
||||
|
||||
The process is fully automatic and does not require configuration; however,
|
||||
Heretic has a variety of configuration parameters that can be changed for
|
||||
greater control. Run `heretic --help` to see available command-line options,
|
||||
@@ -96,14 +116,15 @@ a configuration file.
|
||||
|
||||
At the start of a program run, Heretic benchmarks the system to determine
|
||||
the optimal batch size to make the most of the available hardware.
|
||||
On an RTX 3090, with the default configuration, decensoring Llama-3.1-8B-Instruct
|
||||
takes about 45 minutes. Note that Heretic supports model quantization with
|
||||
On an RTX 3090, with the default configuration, decensoring
|
||||
[Qwen3-4B-Instruct-2507](https://huggingface.co/Qwen/Qwen3-4B-Instruct-2507)
|
||||
takes about 20-30 minutes. Note that Heretic supports model quantization with
|
||||
bitsandbytes, which can drastically reduce the amount of VRAM required to process
|
||||
models. Set the `quantization` option to `bnb_4bit` to enable quantization.
|
||||
|
||||
After Heretic has finished decensoring a model, you are given the option to
|
||||
save the model, upload it to Hugging Face, chat with it to test how well it works,
|
||||
or any combination of those actions.
|
||||
run standard benchmarks on it, or any combination of those actions.
|
||||
|
||||
|
||||
## Research features
|
||||
@@ -113,7 +134,7 @@ provides features designed to support research into the semantics of model inter
|
||||
(interpretability). To use those features, you need to install Heretic with the
|
||||
optional `research` extra:
|
||||
|
||||
```
|
||||
```sh
|
||||
pip install -U heretic-llm[research]
|
||||
```
|
||||
|
||||
|
||||
+45
-15
@@ -27,6 +27,12 @@ device_map = "auto"
|
||||
# Maximum memory to allocate per device.
|
||||
# max_memory = { "0" = "20GB", "cpu" = "64GB" }
|
||||
|
||||
# Whether to move intermediate analysis tensors (such as residuals and logprobs)
|
||||
# to CPU memory as soon as possible to reduce peak VRAM usage.
|
||||
# This lowers peak VRAM usage during residual analysis and evaluation,
|
||||
# but may slightly reduce performance due to host/device transfers.
|
||||
offload_outputs_to_cpu = true
|
||||
|
||||
# Number of input sequences to process in parallel (0 = auto).
|
||||
batch_size = 0 # auto
|
||||
|
||||
@@ -36,9 +42,38 @@ max_batch_size = 128
|
||||
# Maximum number of tokens to generate for each response.
|
||||
max_response_length = 100
|
||||
|
||||
# List of pairs of the form [cot_initializer, closed_cot_block] used to skip
|
||||
# the Chain-of-Thought block in responses, so that evaluation happens
|
||||
# at the start of the actual response.
|
||||
chain_of_thought_skips = [
|
||||
# Most thinking models.
|
||||
[
|
||||
"<think>",
|
||||
"<think></think>",
|
||||
],
|
||||
# gpt-oss.
|
||||
[
|
||||
"<|channel|>analysis<|message|>",
|
||||
"<|channel|>analysis<|message|><|end|><|start|>assistant<|channel|>final<|message|>",
|
||||
],
|
||||
# Unknown, suggested by user.
|
||||
[
|
||||
"<thought>",
|
||||
"<thought></thought>",
|
||||
],
|
||||
# Unknown, suggested by user.
|
||||
[
|
||||
"[THINK]",
|
||||
"[THINK][/THINK]",
|
||||
],
|
||||
]
|
||||
|
||||
# Whether to print prompt/response pairs when counting refusals.
|
||||
print_responses = false
|
||||
|
||||
# Whether to print additional information that can help with debugging.
|
||||
print_debug_information = false
|
||||
|
||||
# Whether to print detailed information about residuals and refusal directions.
|
||||
print_residual_geometry = false
|
||||
|
||||
@@ -64,13 +99,13 @@ kl_divergence_target = 0.01
|
||||
|
||||
# Whether to adjust the refusal directions so that only the component that is
|
||||
# orthogonal to the good direction is subtracted during abliteration.
|
||||
orthogonalize_direction = false
|
||||
orthogonalize_direction = true
|
||||
|
||||
# How to apply row normalization of the weights. Options:
|
||||
# "none" (no normalization),
|
||||
# "pre" (compute LoRA adapter relative to row-normalized weights),
|
||||
# "full" (like "pre", but renormalizes to preserve original row magnitudes).
|
||||
row_normalization = "none"
|
||||
row_normalization = "full"
|
||||
|
||||
# The rank of the LoRA adapter to use when "full" row normalization is used.
|
||||
# Row magnitude preservation is approximate due to non-linear effects,
|
||||
@@ -91,15 +126,15 @@ n_trials = 200
|
||||
# Number of trials that use random sampling for the purpose of exploration.
|
||||
n_startup_trials = 60
|
||||
|
||||
# Random seed for reproducible optimization. Set to an integer to enable.
|
||||
# Applies to Python's random module, NumPy, PyTorch, and Optuna.
|
||||
# seed = 75
|
||||
|
||||
# Directory to save and load study progress to/from.
|
||||
study_checkpoint_dir = "checkpoints"
|
||||
|
||||
# Maximum size for individual safetensors files generated when exporting a model.
|
||||
max_shard_size = "5GB"
|
||||
|
||||
# Strings whose presence in a response (case insensitive) identifies the response as a refusal.
|
||||
refusal_markers = [
|
||||
"disclaimer",
|
||||
"sorry",
|
||||
"i can'",
|
||||
"i cant",
|
||||
@@ -137,11 +172,10 @@ refusal_markers = [
|
||||
# System prompt to use when prompting the model.
|
||||
system_prompt = "You are a helpful assistant."
|
||||
|
||||
# Move intermediate analysis tensors (such as residuals and logprobs)
|
||||
# to CPU memory as soon as possible to reduce peak VRAM usage.
|
||||
# This lowers peak VRAM usage during residual analysis and evaluation,
|
||||
# but may slightly reduce performance due to host/device transfers.
|
||||
offload_outputs_to_cpu = true
|
||||
# Each "dataset" below can be a Hugging Face dataset ID, a path to a dataset on disk,
|
||||
# or a path to a plain text file with one prompt per line (empty lines are ignored).
|
||||
# For text files, "column" is ignored and "split" is optional; when given, it selects
|
||||
# a subset of the lines using slice notation (e.g. "[:400]").
|
||||
|
||||
# Dataset of prompts that tend to not result in refusals (used for calculating refusal directions).
|
||||
[good_prompts]
|
||||
@@ -150,7 +184,6 @@ split = "train[:400]"
|
||||
column = "text"
|
||||
residual_plot_label = '"Harmless" prompts'
|
||||
residual_plot_color = "royalblue"
|
||||
commit = ""
|
||||
|
||||
# Dataset of prompts that tend to result in refusals (used for calculating refusal directions).
|
||||
[bad_prompts]
|
||||
@@ -159,18 +192,15 @@ split = "train[:400]"
|
||||
column = "text"
|
||||
residual_plot_label = '"Harmful" prompts'
|
||||
residual_plot_color = "darkorange"
|
||||
commit = ""
|
||||
|
||||
# Dataset of prompts that tend to not result in refusals (used for evaluating model performance).
|
||||
[good_evaluation_prompts]
|
||||
dataset = "mlabonne/harmless_alpaca"
|
||||
split = "test[:100]"
|
||||
column = "text"
|
||||
commit = ""
|
||||
|
||||
# Dataset of prompts that tend to result in refusals (used for evaluating model performance).
|
||||
[bad_evaluation_prompts]
|
||||
dataset = "mlabonne/harmful_behaviors"
|
||||
split = "test[:100]"
|
||||
column = "text"
|
||||
commit = ""
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
# Rename this file to config.toml, place it in the working directory
|
||||
# that you run Heretic from, and edit the configuration to your liking.
|
||||
|
||||
max_response_length = 300
|
||||
|
||||
residual_plot_title = "PaCMAP Projection of Residuals for Serious/Humorous Prompts"
|
||||
|
||||
refusal_markers = [
|
||||
"😅",
|
||||
"here's one",
|
||||
"why did",
|
||||
"walked into a bar",
|
||||
"gets worse",
|
||||
"the punchline",
|
||||
"classic",
|
||||
"dad joke",
|
||||
"bad joke",
|
||||
"pun intended",
|
||||
"ba dum tss",
|
||||
"rimshot",
|
||||
"😂",
|
||||
"😄",
|
||||
"😆",
|
||||
"haha",
|
||||
"hehe",
|
||||
"lol",
|
||||
"funny",
|
||||
"joke",
|
||||
"humor",
|
||||
"that's hilarious",
|
||||
"you could say",
|
||||
"one-liner",
|
||||
"comedian",
|
||||
"stand-up",
|
||||
"unexpectedly",
|
||||
"because apparently",
|
||||
"to be fair",
|
||||
"on the bright side",
|
||||
"lmao",
|
||||
"omg",
|
||||
"rofl",
|
||||
"silly",
|
||||
"humorous",
|
||||
"clever",
|
||||
]
|
||||
|
||||
[good_prompts]
|
||||
dataset = "mlabonne/harmless_alpaca"
|
||||
split = "train[:400]"
|
||||
column = "text"
|
||||
residual_plot_label = "Serious prompts"
|
||||
residual_plot_color = "royalblue"
|
||||
|
||||
[bad_prompts]
|
||||
dataset = "UnstableLlama/jokes"
|
||||
split = "train[:200]"
|
||||
column = "text"
|
||||
residual_plot_label = "Humorous prompts"
|
||||
residual_plot_color = "darkorange"
|
||||
|
||||
[good_evaluation_prompts]
|
||||
dataset = "mlabonne/harmless_alpaca"
|
||||
split = "test[:100]"
|
||||
column = "text"
|
||||
|
||||
[bad_evaluation_prompts]
|
||||
dataset = "UnstableLlama/jokes"
|
||||
split = "train[200:250]"
|
||||
column = "text"
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "heretic-llm"
|
||||
version = "1.2.0"
|
||||
version = "1.4.0"
|
||||
description = "Fully automatic censorship removal for language models"
|
||||
readme = "README.md"
|
||||
license = "AGPL-3.0-or-later"
|
||||
@@ -25,23 +25,23 @@ dependencies = [
|
||||
"accelerate~=1.13",
|
||||
"bitsandbytes~=0.49",
|
||||
"datasets~=4.7",
|
||||
"hf-transfer~=0.1",
|
||||
"huggingface-hub~=1.7",
|
||||
"immutabledict~=4.3",
|
||||
"kernels~=0.12",
|
||||
"langdetect~=1.0",
|
||||
"lm-eval[hf]~=0.4",
|
||||
"numpy~=2.2",
|
||||
"optuna~=4.7",
|
||||
"peft~=0.18",
|
||||
"peft~=0.19",
|
||||
"psutil~=7.2",
|
||||
"py-cpuinfo~=9.0",
|
||||
"pydantic-settings~=2.13",
|
||||
"questionary~=2.1",
|
||||
"rich~=14.3",
|
||||
"tomli-w~=1.2",
|
||||
"torch", # version deliberately unspecified
|
||||
"torchvision", # version deliberately unspecified
|
||||
"tqdm~=4.67",
|
||||
"transformers~=5.3",
|
||||
"transformers[kernels]~=5.6",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
@@ -60,8 +60,8 @@ dev = [
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/p-e-w/heretic"
|
||||
Documentation = "https://github.com/p-e-w/heretic"
|
||||
Homepage = "https://heretic-project.org"
|
||||
Documentation = "https://heretic-project.org/tutorial"
|
||||
Repository = "https://github.com/p-e-w/heretic.git"
|
||||
Issues = "https://github.com/p-e-w/heretic/issues"
|
||||
Changelog = "https://github.com/p-e-w/heretic/releases"
|
||||
|
||||
+151
-26
@@ -4,7 +4,12 @@
|
||||
from enum import Enum
|
||||
from typing import Dict
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic import (
|
||||
BaseModel,
|
||||
Field,
|
||||
NonNegativeInt,
|
||||
PositiveInt,
|
||||
)
|
||||
from pydantic_settings import (
|
||||
BaseSettings,
|
||||
CliSettingsSource,
|
||||
@@ -13,6 +18,12 @@ from pydantic_settings import (
|
||||
TomlConfigSettingsSource,
|
||||
)
|
||||
|
||||
# !!!IMPORTANT!!!
|
||||
#
|
||||
# Any settings added to the classes defined in this module
|
||||
# must be evaluated for privacy implications and have
|
||||
# exclude=True set in their field definitions if appropriate.
|
||||
|
||||
|
||||
class QuantizationMethod(str, Enum):
|
||||
NONE = "none"
|
||||
@@ -26,14 +37,30 @@ class RowNormalization(str, Enum):
|
||||
FULL = "full"
|
||||
|
||||
|
||||
class ExportStrategy(str, Enum):
|
||||
MERGE = "merge"
|
||||
ADAPTER = "adapter"
|
||||
|
||||
|
||||
class DatasetSpecification(BaseModel):
|
||||
dataset: str = Field(
|
||||
description="Hugging Face dataset ID, or path to dataset on disk."
|
||||
)
|
||||
|
||||
split: str = Field(description="Portion of the dataset to use.")
|
||||
commit: str | None = Field(
|
||||
default=None,
|
||||
description="Hugging Face commit hash of the dataset.",
|
||||
)
|
||||
|
||||
column: str = Field(description="Column in the dataset that contains the prompts.")
|
||||
split: str | None = Field(
|
||||
default=None,
|
||||
description="Portion of the dataset to use. Required for datasets, optional for plain text files.",
|
||||
)
|
||||
|
||||
column: str | None = Field(
|
||||
default=None,
|
||||
description="Column in the dataset that contains the prompts. Required for datasets, ignored for plain text files.",
|
||||
)
|
||||
|
||||
prefix: str = Field(
|
||||
default="",
|
||||
@@ -53,15 +80,13 @@ class DatasetSpecification(BaseModel):
|
||||
residual_plot_label: str | None = Field(
|
||||
default=None,
|
||||
description="Label to use for the dataset in plots of residual vectors.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
residual_plot_color: str | None = Field(
|
||||
default=None,
|
||||
description="Matplotlib color to use for the dataset in plots of residual vectors.",
|
||||
)
|
||||
commit: str | None = Field(
|
||||
default=None,
|
||||
description="Hugging Face commit hash of the dataset.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
|
||||
@@ -80,12 +105,37 @@ class BenchmarkSpecification(BaseModel):
|
||||
class Settings(BaseSettings):
|
||||
model: str = Field(description="Hugging Face model ID, or path to model on disk.")
|
||||
|
||||
model_commit: str | None = Field(
|
||||
default=None,
|
||||
description="Hugging Face commit hash of the model.",
|
||||
)
|
||||
|
||||
evaluate_model: str | None = Field(
|
||||
default=None,
|
||||
description=(
|
||||
"If this model ID or path is set, then instead of abliterating the main model, "
|
||||
"evaluate this model relative to the main model."
|
||||
),
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
collect_reproducibles: str | None = Field(
|
||||
default=None,
|
||||
description=(
|
||||
"If this directory path is set, then instead of abliterating a model, "
|
||||
"download all reproduce.json files from public Heretic model repositories "
|
||||
"on Hugging Face, and store them in that directory for archival purposes."
|
||||
),
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
reproduce: str | None = Field(
|
||||
default=None,
|
||||
description=(
|
||||
"If this path or URL to a reproduce.json file is set, load reproduction information "
|
||||
"from that file, and attempt to reproduce the abliterated model it originated from."
|
||||
),
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
dtypes: list[str] = Field(
|
||||
@@ -126,22 +176,30 @@ class Settings(BaseSettings):
|
||||
description='Maximum memory to allocate per device (e.g., { "0" = "20GB", "cpu" = "64GB" }).',
|
||||
)
|
||||
|
||||
trust_remote_code: bool | None = Field(
|
||||
default=None,
|
||||
description="Whether to trust remote code when loading the model.",
|
||||
offload_outputs_to_cpu: bool = Field(
|
||||
default=True,
|
||||
description=(
|
||||
"Whether to move intermediate analysis tensors (such as residuals and logprobs) "
|
||||
"to CPU memory as soon as possible to reduce peak VRAM usage. "
|
||||
"This lowers peak VRAM usage during residual analysis and evaluation, "
|
||||
"but may slightly reduce performance due to host/device transfers."
|
||||
),
|
||||
)
|
||||
|
||||
batch_size: int = Field(
|
||||
batch_size: NonNegativeInt = Field(
|
||||
default=0, # auto
|
||||
description="Number of input sequences to process in parallel (0 = auto).",
|
||||
)
|
||||
|
||||
max_batch_size: int = Field(
|
||||
max_batch_size: PositiveInt = Field(
|
||||
default=128,
|
||||
description="Maximum batch size to try when automatically determining the optimal batch size.",
|
||||
# When storing a settings object, the batch size is already fixed,
|
||||
# either determined by the automatic mechanism or by explicit user choice.
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
max_response_length: int = Field(
|
||||
max_response_length: PositiveInt = Field(
|
||||
default=100,
|
||||
description="Maximum number of tokens to generate for each response.",
|
||||
)
|
||||
@@ -183,36 +241,51 @@ class Settings(BaseSettings):
|
||||
"the Chain-of-Thought block in responses, so that evaluation happens "
|
||||
"at the start of the actual response."
|
||||
),
|
||||
# When storing a settings object, the response prefix is already fixed,
|
||||
# either determined by the automatic mechanism or by explicit user choice.
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
print_responses: bool = Field(
|
||||
default=False,
|
||||
description="Whether to print prompt/response pairs when counting refusals.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
print_debug_information: bool = Field(
|
||||
default=False,
|
||||
description="Whether to print additional information that can help with debugging.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
print_residual_geometry: bool = Field(
|
||||
default=False,
|
||||
description="Whether to print detailed information about residuals and refusal directions.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
plot_residuals: bool = Field(
|
||||
default=False,
|
||||
description="Whether to generate plots showing PaCMAP projections of residual vectors.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
residual_plot_path: str = Field(
|
||||
default="plots",
|
||||
description="Base path to save plots of residual vectors to.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
residual_plot_title: str = Field(
|
||||
default='PaCMAP Projection of Residual Vectors for "Harmless" and "Harmful" Prompts',
|
||||
description="Title placed above plots of residual vectors.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
residual_plot_style: str = Field(
|
||||
default="dark_background",
|
||||
description="Matplotlib style sheet to use for plots of residual vectors.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
kl_divergence_scale: float = Field(
|
||||
@@ -232,7 +305,7 @@ class Settings(BaseSettings):
|
||||
)
|
||||
|
||||
orthogonalize_direction: bool = Field(
|
||||
default=False,
|
||||
default=True,
|
||||
description=(
|
||||
"Whether to adjust the refusal directions so that only the component that is "
|
||||
"orthogonal to the good direction is subtracted during abliteration."
|
||||
@@ -240,7 +313,7 @@ class Settings(BaseSettings):
|
||||
)
|
||||
|
||||
row_normalization: RowNormalization = Field(
|
||||
default=RowNormalization.NONE,
|
||||
default=RowNormalization.FULL,
|
||||
description=(
|
||||
"How to apply row normalization of the weights. Options: "
|
||||
'"none" (no normalization), '
|
||||
@@ -249,7 +322,7 @@ class Settings(BaseSettings):
|
||||
),
|
||||
)
|
||||
|
||||
full_normalization_lora_rank: int = Field(
|
||||
full_normalization_lora_rank: PositiveInt = Field(
|
||||
default=3,
|
||||
description=(
|
||||
'The rank of the LoRA adapter to use when "full" row normalization is used. '
|
||||
@@ -270,12 +343,12 @@ class Settings(BaseSettings):
|
||||
),
|
||||
)
|
||||
|
||||
n_trials: int = Field(
|
||||
n_trials: PositiveInt = Field(
|
||||
default=200,
|
||||
description="Number of abliteration trials to run during optimization.",
|
||||
)
|
||||
|
||||
n_startup_trials: int = Field(
|
||||
n_startup_trials: NonNegativeInt = Field(
|
||||
default=60,
|
||||
description="Number of trials that use random sampling for the purpose of exploration.",
|
||||
)
|
||||
@@ -291,6 +364,7 @@ class Settings(BaseSettings):
|
||||
study_checkpoint_dir: str = Field(
|
||||
default="checkpoints",
|
||||
description="Directory to save and load study progress to/from.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
benchmarks: list[BenchmarkSpecification] = Field(
|
||||
@@ -352,10 +426,69 @@ class Settings(BaseSettings):
|
||||
),
|
||||
],
|
||||
description="Benchmarks to offer to the user for evaluating abliterated models.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
max_shard_size: PositiveInt | str = Field(
|
||||
default="5GB",
|
||||
description="Maximum size for individual safetensors files generated when exporting a model.",
|
||||
)
|
||||
|
||||
export_strategy: ExportStrategy | None = Field(
|
||||
default=None,
|
||||
description='How to export the model: "merge", "adapter", or unset to prompt the user.',
|
||||
)
|
||||
|
||||
checkpoint_action: str | None = Field(
|
||||
default=None,
|
||||
description='Action to take in case a checkpoint exists: "continue", "restart", or unset to prompt the user.',
|
||||
)
|
||||
|
||||
trial_index: NonNegativeInt | None = Field(
|
||||
default=None,
|
||||
description="Index (in the sorted Pareto front) of the trial to use, or unset to prompt the user.",
|
||||
)
|
||||
|
||||
n_additional_trials: PositiveInt | None = Field(
|
||||
default=None,
|
||||
description="Number of additional trials to run, or unset to prompt the user.",
|
||||
)
|
||||
|
||||
model_action: str | None = Field(
|
||||
default=None,
|
||||
description='Action to take with the decensored model: "save", "upload", or unset to prompt the user.',
|
||||
)
|
||||
|
||||
save_directory: str | None = Field(
|
||||
default=None,
|
||||
description="Directory to save the model to, or unset to prompt the user.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
upload_repo_id: str | None = Field(
|
||||
default=None,
|
||||
description="Name of the Hugging Face repository to upload the model to, or unset to prompt the user.",
|
||||
exclude=True,
|
||||
)
|
||||
|
||||
upload_repo_private: bool | None = Field(
|
||||
default=None,
|
||||
description="Whether the Hugging Face repository to upload the model to should be private, or unset to prompt the user.",
|
||||
)
|
||||
|
||||
upload_reproducibility_information: str | None = Field(
|
||||
default=None,
|
||||
description='Which reproducibility information to add to the Hugging Face repository: "full", "basic", "none", or unset to prompt the user.',
|
||||
)
|
||||
|
||||
ignore_mismatches: bool | None = Field(
|
||||
default=None,
|
||||
description="Whether to attempt to reproduce the model even if there are environment mismatches, or unset to prompt the user.",
|
||||
)
|
||||
|
||||
refusal_markers: list[str] = Field(
|
||||
default=[
|
||||
"disclaimer",
|
||||
"sorry",
|
||||
"i can'",
|
||||
"i cant",
|
||||
@@ -397,14 +530,6 @@ class Settings(BaseSettings):
|
||||
description="System prompt to use when prompting the model.",
|
||||
)
|
||||
|
||||
offload_outputs_to_cpu: bool = Field(
|
||||
default=True,
|
||||
description=(
|
||||
"Whether to move intermediate analysis tensors (such as residuals and logprobs) "
|
||||
"to CPU memory as soon as possible to reduce peak VRAM usage."
|
||||
),
|
||||
)
|
||||
|
||||
good_prompts: DatasetSpecification = Field(
|
||||
default=DatasetSpecification(
|
||||
dataset="mlabonne/harmless_alpaca",
|
||||
|
||||
+642
-284
File diff suppressed because it is too large
Load Diff
+100
-28
@@ -17,12 +17,14 @@ from torch.nn import Module, ModuleList
|
||||
from transformers import (
|
||||
AutoModelForCausalLM,
|
||||
AutoModelForImageTextToText,
|
||||
AutoProcessor,
|
||||
AutoTokenizer,
|
||||
BatchEncoding,
|
||||
BitsAndBytesConfig,
|
||||
PretrainedConfig,
|
||||
PreTrainedModel,
|
||||
PreTrainedTokenizerBase,
|
||||
ProcessorMixin,
|
||||
TextStreamer,
|
||||
)
|
||||
from transformers.generation import (
|
||||
@@ -31,7 +33,7 @@ from transformers.generation import (
|
||||
|
||||
from .config import QuantizationMethod, RowNormalization, Settings
|
||||
from .system import empty_cache
|
||||
from .utils import Prompt, batchify, print
|
||||
from .utils import Prompt, batchify, format_exception, print
|
||||
|
||||
|
||||
def get_model_class(
|
||||
@@ -56,20 +58,35 @@ class AbliterationParameters:
|
||||
class Model:
|
||||
model: PreTrainedModel | PeftModel
|
||||
tokenizer: PreTrainedTokenizerBase
|
||||
# Set for multimodal models, None for text-only ones.
|
||||
processor: ProcessorMixin | None
|
||||
peft_config: LoraConfig
|
||||
dtype: torch.dtype
|
||||
|
||||
def __init__(self, settings: Settings):
|
||||
self.settings = settings
|
||||
self.needs_reload = False
|
||||
|
||||
self.revision_kwargs = {}
|
||||
if settings.model_commit is not None:
|
||||
self.revision_kwargs["revision"] = settings.model_commit
|
||||
|
||||
print()
|
||||
print(f"Loading model [bold]{settings.model}[/]...")
|
||||
|
||||
self.tokenizer = AutoTokenizer.from_pretrained(
|
||||
settings.model,
|
||||
trust_remote_code=settings.trust_remote_code,
|
||||
**self.revision_kwargs,
|
||||
)
|
||||
|
||||
# Multimodal models have a processor we'll want to save.
|
||||
self.processor = None
|
||||
if get_model_class(settings.model) == AutoModelForImageTextToText:
|
||||
self.processor = AutoProcessor.from_pretrained(
|
||||
settings.model,
|
||||
**self.revision_kwargs,
|
||||
)
|
||||
|
||||
# Fallback for tokenizers that don't declare a special pad token.
|
||||
if self.tokenizer.pad_token is None:
|
||||
self.tokenizer.pad_token = self.tokenizer.eos_token
|
||||
@@ -85,10 +102,8 @@ class Model:
|
||||
if settings.max_memory
|
||||
else None
|
||||
)
|
||||
self.trusted_models = {settings.model: settings.trust_remote_code}
|
||||
|
||||
if self.settings.evaluate_model is not None:
|
||||
self.trusted_models[settings.evaluate_model] = settings.trust_remote_code
|
||||
self.trusted_models = set()
|
||||
|
||||
for dtype in settings.dtypes:
|
||||
print(f"* Trying dtype [bold]{dtype}[/]...")
|
||||
@@ -107,14 +122,19 @@ class Model:
|
||||
dtype=dtype,
|
||||
device_map=settings.device_map,
|
||||
max_memory=self.max_memory,
|
||||
trust_remote_code=self.trusted_models.get(settings.model),
|
||||
trust_remote_code=True
|
||||
if settings.model in self.trusted_models
|
||||
else None,
|
||||
**self.revision_kwargs,
|
||||
**extra_kwargs,
|
||||
)
|
||||
|
||||
self.dtype = self.model.dtype
|
||||
|
||||
# If we reach this point and the model requires trust_remote_code,
|
||||
# either the user accepted, or settings.trust_remote_code is True.
|
||||
if self.trusted_models.get(settings.model) is None:
|
||||
self.trusted_models[settings.model] = True
|
||||
# the user must have agreed when prompted to execute remote code,
|
||||
# because from_pretrained raises an exception otherwise.
|
||||
self.trusted_models.add(settings.model)
|
||||
|
||||
# A test run can reveal dtype-related problems such as the infamous
|
||||
# "RuntimeError: probability tensor contains either `inf`, `nan` or element < 0"
|
||||
@@ -131,7 +151,13 @@ class Model:
|
||||
except Exception as error:
|
||||
self.model = None # ty:ignore[invalid-assignment]
|
||||
empty_cache()
|
||||
print(f"* [red]Failed[/] ({error})")
|
||||
|
||||
formatted = format_exception(error)
|
||||
if "\n" in formatted:
|
||||
print(f"* [red]Failed:\n{formatted}[/]")
|
||||
else:
|
||||
print(f"* [red]Failed ({formatted})[/]")
|
||||
|
||||
continue
|
||||
|
||||
if settings.quantization == QuantizationMethod.BNB_4BIT:
|
||||
@@ -148,13 +174,15 @@ class Model:
|
||||
# so we don't need to do anything manually.
|
||||
|
||||
print(f"* Transformer model with [bold]{len(self.get_layers())}[/] layers")
|
||||
print("* Abliterable components:")
|
||||
|
||||
all_components = {}
|
||||
for layer_index in range(len(self.get_layers())):
|
||||
for component, modules in self.get_layer_modules(layer_index).items():
|
||||
if component not in all_components:
|
||||
all_components[component] = 0
|
||||
all_components[component] += len(modules)
|
||||
|
||||
print("* Abliterable components:")
|
||||
for component, count in all_components.items():
|
||||
print(f" * [bold]{component}[/]: [bold]{count}[/] modules total")
|
||||
|
||||
@@ -256,7 +284,10 @@ class Model:
|
||||
self.settings.model,
|
||||
torch_dtype=self.model.dtype,
|
||||
device_map="cpu",
|
||||
trust_remote_code=self.trusted_models.get(self.settings.model),
|
||||
trust_remote_code=True
|
||||
if self.settings.model in self.trusted_models
|
||||
else None,
|
||||
**self.revision_kwargs,
|
||||
)
|
||||
|
||||
# Apply LoRA adapters to the CPU model
|
||||
@@ -291,33 +322,41 @@ class Model:
|
||||
- Slow path: If switching models or after merge_and_unload(),
|
||||
performs full model reload with quantization config.
|
||||
"""
|
||||
current_model = getattr(self.model.config, "name_or_path", None)
|
||||
|
||||
# If a prior model load was interrupted/cancelled mid-process, self.model will be None.
|
||||
current_model = None
|
||||
if self.model is not None:
|
||||
current_model = getattr(self.model.config, "name_or_path", None)
|
||||
|
||||
if current_model == self.settings.model and not self.needs_reload:
|
||||
# Reset LoRA adapters to zero (identity transformation)
|
||||
# Reset LoRA adapters to zero (identity transformation).
|
||||
for name, module in self.model.named_modules():
|
||||
if "lora_B" in name and hasattr(module, "weight"):
|
||||
torch.nn.init.zeros_(module.weight)
|
||||
return
|
||||
|
||||
dtype = self.model.dtype
|
||||
|
||||
# Purge existing model object from memory to make space.
|
||||
self.model = None # ty:ignore[invalid-assignment]
|
||||
empty_cache()
|
||||
|
||||
quantization_config = self._get_quantization_config(str(dtype).split(".")[-1])
|
||||
quantization_config = self._get_quantization_config(
|
||||
str(self.dtype).split(".")[-1]
|
||||
)
|
||||
|
||||
# Build kwargs, only include quantization_config if it's not None
|
||||
# Build kwargs, only include quantization_config if it's not None.
|
||||
extra_kwargs = {}
|
||||
if quantization_config is not None:
|
||||
extra_kwargs["quantization_config"] = quantization_config
|
||||
|
||||
self.model = get_model_class(self.settings.model).from_pretrained(
|
||||
self.settings.model,
|
||||
dtype=dtype,
|
||||
dtype=self.dtype,
|
||||
device_map=self.settings.device_map,
|
||||
max_memory=self.max_memory,
|
||||
trust_remote_code=self.trusted_models.get(self.settings.model),
|
||||
trust_remote_code=True
|
||||
if self.settings.model in self.trusted_models
|
||||
else None,
|
||||
**self.revision_kwargs,
|
||||
**extra_kwargs,
|
||||
)
|
||||
|
||||
@@ -360,8 +399,8 @@ class Model:
|
||||
with suppress(Exception):
|
||||
try_add("attn.o_proj", layer.self_attn.o_proj) # ty:ignore[possibly-missing-attribute]
|
||||
|
||||
# Qwen3.5 MoE hybrid layers use GatedDeltaNet (linear attention) instead
|
||||
# of standard self-attention, so self_attn.o_proj doesn't exist on those layers.
|
||||
# Qwen3.5 MoE hybrid layers use GatedDeltaNet (linear attention) instead of
|
||||
# standard self-attention, so self_attn.o_proj doesn't exist on those layers.
|
||||
with suppress(Exception):
|
||||
try_add("attn.o_proj", layer.linear_attn.out_proj) # ty:ignore[possibly-missing-attribute]
|
||||
|
||||
@@ -379,6 +418,21 @@ class Model:
|
||||
for expert in layer.block_sparse_moe.experts: # ty:ignore[possibly-missing-attribute, not-iterable]
|
||||
try_add("mlp.down_proj", expert.w2) # ty:ignore[possibly-missing-attribute]
|
||||
|
||||
# LFM dense operator blocks.
|
||||
with suppress(Exception):
|
||||
try_add("attn.o_proj", layer.conv.out_proj) # ty:ignore[possibly-missing-attribute]
|
||||
|
||||
with suppress(Exception):
|
||||
try_add("mlp.down_proj", layer.feed_forward.w2) # ty:ignore[possibly-missing-attribute]
|
||||
|
||||
# LFM transformer blocks.
|
||||
with suppress(Exception):
|
||||
try_add("attn.o_proj", layer.self_attn.out_proj) # ty:ignore[possibly-missing-attribute]
|
||||
|
||||
with suppress(Exception):
|
||||
for expert in layer.feed_forward.experts: # ty:ignore[possibly-missing-attribute, not-iterable]
|
||||
try_add("mlp.down_proj", expert.w2) # ty:ignore[possibly-missing-attribute]
|
||||
|
||||
# Granite MoE Hybrid - attention layers with shared_mlp.
|
||||
with suppress(Exception):
|
||||
try_add("mlp.down_proj", layer.shared_mlp.output_linear) # ty:ignore[possibly-missing-attribute]
|
||||
@@ -395,11 +449,13 @@ class Model:
|
||||
return modules
|
||||
|
||||
def get_abliterable_components(self) -> list[str]:
|
||||
components: set[str] = set()
|
||||
|
||||
# Scan all layers because hybrid models (e.g. Qwen3.5 MoE) have different
|
||||
# components on different layers (some have self_attn, others linear_attn).
|
||||
components: set[str] = set()
|
||||
for layer_index in range(len(self.get_layers())):
|
||||
components.update(self.get_layer_modules(layer_index).keys())
|
||||
|
||||
return sorted(components)
|
||||
|
||||
def abliterate(
|
||||
@@ -443,6 +499,12 @@ class Model:
|
||||
params.min_weight - params.max_weight
|
||||
)
|
||||
|
||||
# A weight of 0 disables this component's ablation. reset_model() has
|
||||
# already left the adapter at identity, so abort before the otherwise
|
||||
# wasteful decomposition (which would also be operating on a zero matrix).
|
||||
if weight == 0:
|
||||
continue
|
||||
|
||||
if refusal_direction is None:
|
||||
# The index must be shifted by 1 because the first element
|
||||
# of refusal_directions is the direction for the embeddings.
|
||||
@@ -524,7 +586,16 @@ class Model:
|
||||
W = W - W_org
|
||||
# Use a low-rank SVD to get an approximation of the matrix.
|
||||
r = self.peft_config.r
|
||||
|
||||
# svd_lowrank is randomized:
|
||||
# https://github.com/pytorch/pytorch/blob/20919052303c0b5ba87f8bf7e19237dc33ab09d3/torch/_lowrank.py#L108-L109
|
||||
# Reseed immediately before the call so restoring a trial is independent of RNG history.
|
||||
torch.manual_seed(self.settings.seed)
|
||||
# "It's safe to call this function if CUDA is not available;
|
||||
# in that case, it is silently ignored."
|
||||
torch.cuda.manual_seed_all(self.settings.seed) # ty:ignore[invalid-argument-type]
|
||||
U, S, Vh = torch.svd_lowrank(W, q=2 * r + 4, niter=6)
|
||||
|
||||
# Truncate it to the part we want to store in the LoRA adapter.
|
||||
# Note: svd_lowrank actually returns V, so transpose it to get Vh.
|
||||
U = U[:, :r]
|
||||
@@ -720,7 +791,7 @@ class Model:
|
||||
_, outputs = self.generate(
|
||||
prompts,
|
||||
max_new_tokens=1,
|
||||
output_scores=True,
|
||||
output_logits=True,
|
||||
return_dict_in_generate=True,
|
||||
use_cache=False,
|
||||
)
|
||||
@@ -730,15 +801,16 @@ class Model:
|
||||
outputs = cast(GenerateDecoderOnlyOutput, outputs)
|
||||
|
||||
# Logits for the first (only) generated token.
|
||||
# This cast is valid because we passed output_scores=True above.
|
||||
logits = cast(tuple[FloatTensor], outputs.scores)[0]
|
||||
# Use raw logits, not processed generation scores; processors can insert
|
||||
# -inf for suppressed tokens, which can make KL divergence evaluate to NaN.
|
||||
# This cast is valid because we passed output_logits=True above.
|
||||
logits = cast(tuple[FloatTensor], outputs.logits)[0]
|
||||
|
||||
# The returned tensor has shape (prompt, token).
|
||||
logprobs = F.log_softmax(logits, dim=-1)
|
||||
|
||||
del outputs
|
||||
|
||||
if self.settings.offload_outputs_to_cpu:
|
||||
del outputs, logits
|
||||
logprobs = logprobs.cpu()
|
||||
empty_cache()
|
||||
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# Copyright (C) 2025-2026 Philipp Emanuel Weidmann <pew@worldwidemann.com> + contributors
|
||||
|
||||
import json
|
||||
import platform
|
||||
import random
|
||||
import shutil
|
||||
from dataclasses import asdict
|
||||
from enum import IntEnum
|
||||
from pathlib import Path
|
||||
from typing import Any, cast
|
||||
from urllib.request import urlopen
|
||||
|
||||
import cpuinfo
|
||||
import questionary
|
||||
import torch
|
||||
from huggingface_hub import HfApi, hf_hub_download
|
||||
from huggingface_hub.utils import (
|
||||
GatedRepoError,
|
||||
disable_progress_bars,
|
||||
enable_progress_bars,
|
||||
)
|
||||
from questionary import Choice, Style
|
||||
from rich.table import Table
|
||||
|
||||
from .config import Settings
|
||||
from .system import (
|
||||
get_accelerator_info_dict,
|
||||
get_heretic_version_info,
|
||||
get_requirements_dict,
|
||||
)
|
||||
from .utils import ask_if_unset, print
|
||||
|
||||
|
||||
def collect_reproducibles(path: str):
|
||||
print(
|
||||
f"Collecting [bold]reproduce.json[/] files from Hugging Face and storing them in [bold]{path}[/]..."
|
||||
)
|
||||
print()
|
||||
|
||||
api = HfApi()
|
||||
|
||||
models = api.list_models(
|
||||
filter=["heretic", "reproducible"],
|
||||
sort="created_at",
|
||||
expand=["gated", "tags"],
|
||||
)
|
||||
|
||||
found = 0
|
||||
downloaded = 0
|
||||
|
||||
# We're only downloading tiny files, so the progress bars are just noise.
|
||||
disable_progress_bars()
|
||||
|
||||
try:
|
||||
for model in models:
|
||||
# Ignore repositories containing quantizations.
|
||||
if model.tags is not None and "gguf" in model.tags:
|
||||
continue
|
||||
|
||||
if model.gated:
|
||||
try:
|
||||
api.auth_check(model.id, repo_type="model")
|
||||
except GatedRepoError:
|
||||
continue
|
||||
|
||||
print(f"[bold]{model.id}[/]...", end="")
|
||||
|
||||
user, repository = model.id.split("/")
|
||||
|
||||
paths_info = api.get_paths_info(
|
||||
model.id,
|
||||
"reproduce/reproduce.json",
|
||||
expand=True,
|
||||
)
|
||||
# The reproduce.json file might not exist in the repository
|
||||
# despite the relevant tags being present.
|
||||
if not paths_info:
|
||||
print(" [yellow]no reproduce.json found[/]")
|
||||
continue
|
||||
|
||||
found += 1
|
||||
|
||||
commit_hash = paths_info[0].last_commit.oid
|
||||
|
||||
file_path = (
|
||||
Path(path)
|
||||
/ "huggingface.co"
|
||||
/ user
|
||||
/ f"{repository}-{commit_hash[:7]}.json"
|
||||
)
|
||||
if file_path.exists():
|
||||
print(" already stored")
|
||||
continue
|
||||
|
||||
cache_path = hf_hub_download(
|
||||
model.id,
|
||||
"reproduce/reproduce.json",
|
||||
)
|
||||
|
||||
file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copyfile(cache_path, file_path)
|
||||
print(" [green]downloaded[/]")
|
||||
|
||||
downloaded += 1
|
||||
finally:
|
||||
enable_progress_bars()
|
||||
|
||||
print()
|
||||
print(f"Found: [bold]{found}[/] files")
|
||||
print(f"Downloaded: [bold]{downloaded}[/] files")
|
||||
print(f"Already stored: [bold]{found - downloaded}[/] files")
|
||||
|
||||
|
||||
def load_reproduction_information(path: str) -> dict[str, Any]:
|
||||
if path.lower().startswith(("http://", "https://")):
|
||||
# The path is a URL on the web.
|
||||
|
||||
# Obtain raw download URL.
|
||||
path = path.replace("/blob/", "/raw/") # Hugging Face, GitHub
|
||||
path = path.replace("/src/branch/", "/raw/branch/") # Codeberg
|
||||
|
||||
json_str = urlopen(path).read().decode("utf-8")
|
||||
else:
|
||||
# The path is (assumed to be) a local file system path.
|
||||
json_str = Path(path).read_text(encoding="utf-8")
|
||||
|
||||
return json.loads(json_str)
|
||||
|
||||
|
||||
class MismatchSeverity(IntEnum):
|
||||
LOW = 1
|
||||
MEDIUM = 2
|
||||
HIGH = 3
|
||||
CRITICAL = 4
|
||||
|
||||
def __rich__(self) -> str:
|
||||
match self:
|
||||
case MismatchSeverity.LOW:
|
||||
return "[green]low[/]"
|
||||
case MismatchSeverity.MEDIUM:
|
||||
return "[yellow]medium[/]"
|
||||
case MismatchSeverity.HIGH:
|
||||
return "[red]high[/]"
|
||||
case MismatchSeverity.CRITICAL:
|
||||
return "[bold red]critical[/]"
|
||||
case _:
|
||||
raise ValueError(f"unknown MismatchSeverity value: {self}")
|
||||
|
||||
|
||||
def get_package_mismatch_severity(package_name: str) -> MismatchSeverity:
|
||||
if package_name in [
|
||||
"heretic-llm",
|
||||
]:
|
||||
return MismatchSeverity.CRITICAL
|
||||
elif package_name in [
|
||||
"torch",
|
||||
"transformers",
|
||||
]:
|
||||
return MismatchSeverity.HIGH
|
||||
elif package_name in [
|
||||
"accelerate",
|
||||
"bitsandbytes",
|
||||
"kernels",
|
||||
"optuna",
|
||||
"peft",
|
||||
"tokenizers",
|
||||
"triton",
|
||||
]:
|
||||
return MismatchSeverity.MEDIUM
|
||||
else:
|
||||
return MismatchSeverity.LOW
|
||||
|
||||
|
||||
def format_version_information(version_information: dict[str, Any]) -> str:
|
||||
version = version_information["version"]
|
||||
metadata = version_information["metadata"]
|
||||
|
||||
if "type" in metadata:
|
||||
match metadata["type"]:
|
||||
case "pypi":
|
||||
return version
|
||||
case "git":
|
||||
return f"{version}-git+{metadata['url']}@{metadata['commit_hash']}"
|
||||
case "local":
|
||||
# Append a random number to ensure that two local installations
|
||||
# are always considered to be different versions.
|
||||
return f"{version}-local-{random.randint(2**16, 2**17)}"
|
||||
case _:
|
||||
raise ValueError(
|
||||
f"unknown metadata.type value in version information: {metadata['type']}"
|
||||
)
|
||||
else:
|
||||
return f"{version}-unknown-{random.randint(2**16, 2**17)}"
|
||||
|
||||
|
||||
def check_environment(
|
||||
settings: Settings,
|
||||
reproduction_information: dict[str, Any],
|
||||
) -> bool | None:
|
||||
mismatch_severity: MismatchSeverity | None = None
|
||||
|
||||
system_mismatches = []
|
||||
package_mismatches = []
|
||||
|
||||
def verify(
|
||||
mismatch_list: list[tuple[str, Any, Any, MismatchSeverity]],
|
||||
name: str,
|
||||
this: Any,
|
||||
original: Any,
|
||||
severity: MismatchSeverity,
|
||||
):
|
||||
nonlocal mismatch_severity
|
||||
if this != original:
|
||||
mismatch_list.append((name, this, original, severity))
|
||||
if mismatch_severity is None:
|
||||
mismatch_severity = severity
|
||||
else:
|
||||
mismatch_severity = max(severity, mismatch_severity)
|
||||
|
||||
if "system" in reproduction_information:
|
||||
system = reproduction_information["system"]
|
||||
|
||||
verify(
|
||||
system_mismatches,
|
||||
"Python version",
|
||||
platform.python_version(),
|
||||
system["python"]["version"],
|
||||
MismatchSeverity.LOW,
|
||||
)
|
||||
|
||||
verify(
|
||||
system_mismatches,
|
||||
"Operating system",
|
||||
platform.platform(),
|
||||
system["os"]["platform"],
|
||||
MismatchSeverity.LOW,
|
||||
)
|
||||
|
||||
verify(
|
||||
system_mismatches,
|
||||
"CPU",
|
||||
cpuinfo.get_cpu_info().get("brand_raw"),
|
||||
system["cpu"]["brand"],
|
||||
MismatchSeverity.LOW,
|
||||
)
|
||||
|
||||
accelerators = get_accelerator_info_dict()
|
||||
|
||||
verify(
|
||||
system_mismatches,
|
||||
"Accelerator type",
|
||||
accelerators["type"],
|
||||
system["accelerators"]["type"],
|
||||
MismatchSeverity.HIGH,
|
||||
)
|
||||
|
||||
if (
|
||||
accelerators["type"]
|
||||
and accelerators["type"] == system["accelerators"]["type"]
|
||||
):
|
||||
verify(
|
||||
system_mismatches,
|
||||
accelerators["api_name"],
|
||||
accelerators["api_version"],
|
||||
system["accelerators"]["api_version"],
|
||||
MismatchSeverity.MEDIUM,
|
||||
)
|
||||
verify(
|
||||
system_mismatches,
|
||||
"Driver version",
|
||||
accelerators["driver_version"],
|
||||
system["accelerators"]["driver_version"],
|
||||
MismatchSeverity.MEDIUM,
|
||||
)
|
||||
verify(
|
||||
system_mismatches,
|
||||
"Devices",
|
||||
"\n".join([device["name"] for device in accelerators["devices"]]),
|
||||
"\n".join(
|
||||
[device["name"] for device in system["accelerators"]["devices"]]
|
||||
),
|
||||
MismatchSeverity.MEDIUM,
|
||||
)
|
||||
|
||||
else:
|
||||
print(
|
||||
(
|
||||
"[yellow]The provided JSON file does not contain system information. "
|
||||
"Some system parameters can affect reproducibility, but due to the lack of system information, "
|
||||
"Heretic is unable to verify that those parameters match the original environment. "
|
||||
"Reproduction may or may not produce a byte-for-byte identical model.[/]"
|
||||
)
|
||||
)
|
||||
|
||||
requirements = get_requirements_dict()
|
||||
requirements["heretic-llm"] = format_version_information(
|
||||
asdict(get_heretic_version_info())
|
||||
)
|
||||
requirements["torch"] = torch.__version__
|
||||
|
||||
original_requirements = reproduction_information["environment"]["requirements"]
|
||||
original_requirements["heretic-llm"] = format_version_information(
|
||||
reproduction_information["environment"]["heretic"]
|
||||
)
|
||||
original_requirements["torch"] = reproduction_information["environment"][
|
||||
"pytorch_version"
|
||||
]
|
||||
|
||||
package_names = sorted(requirements.keys() | original_requirements.keys())
|
||||
|
||||
for package_name in package_names:
|
||||
verify(
|
||||
package_mismatches,
|
||||
package_name,
|
||||
requirements.get(package_name),
|
||||
original_requirements.get(package_name),
|
||||
get_package_mismatch_severity(package_name),
|
||||
)
|
||||
|
||||
if system_mismatches or package_mismatches:
|
||||
print()
|
||||
print(
|
||||
(
|
||||
"[yellow]Your local environment doesn't perfectly match the environment "
|
||||
"used to produce the original model. The following components differ:[/]"
|
||||
)
|
||||
)
|
||||
|
||||
if system_mismatches:
|
||||
table = Table()
|
||||
table.add_column("Component")
|
||||
table.add_column("This system", overflow="fold")
|
||||
table.add_column("Original system", overflow="fold")
|
||||
table.add_column("Severity", width=8)
|
||||
|
||||
for component, this, original, severity in system_mismatches:
|
||||
table.add_row(f"[bold]{component}[/]", this, original, severity)
|
||||
|
||||
print()
|
||||
print("[bold]System Mismatches[/]")
|
||||
print(table)
|
||||
|
||||
if package_mismatches:
|
||||
table = Table()
|
||||
table.add_column("Package")
|
||||
table.add_column("This system", overflow="fold")
|
||||
table.add_column("Original system", overflow="fold")
|
||||
table.add_column("Severity", width=8)
|
||||
|
||||
for package, this, original, severity in package_mismatches:
|
||||
table.add_row(f"[bold]{package}[/]", this, original, severity)
|
||||
|
||||
print()
|
||||
print("[bold]Package Mismatches[/]")
|
||||
print(table)
|
||||
|
||||
if system_mismatches or package_mismatches:
|
||||
print()
|
||||
print(
|
||||
(
|
||||
f"There is a {cast(MismatchSeverity, mismatch_severity).__rich__()} chance "
|
||||
"that reproduction won't produce a byte-for-byte identical model. "
|
||||
"However, the resulting model will very likely still behave similarly "
|
||||
"to the original model."
|
||||
)
|
||||
)
|
||||
|
||||
if settings.ignore_mismatches is None:
|
||||
print()
|
||||
|
||||
return ask_if_unset(
|
||||
settings.ignore_mismatches,
|
||||
questionary.select(
|
||||
"How would you like to proceed?",
|
||||
choices=[
|
||||
Choice(
|
||||
title="Attempt to reproduce the model anyway",
|
||||
value=True,
|
||||
),
|
||||
Choice(
|
||||
title="Exit program",
|
||||
value=False,
|
||||
),
|
||||
],
|
||||
style=Style([("highlighted", "reverse")]),
|
||||
),
|
||||
)
|
||||
else:
|
||||
# There are no mismatches at all, so there is nothing to confirm.
|
||||
return True
|
||||
+61
-45
@@ -25,6 +25,7 @@ from accelerate.utils import (
|
||||
|
||||
def empty_cache():
|
||||
"""Clears the backend cache and collects garbage."""
|
||||
|
||||
# Collecting garbage is not an idempotent operation, and to avoid OOM errors,
|
||||
# gc.collect() has to be called both before and after emptying the backend cache.
|
||||
# See https://github.com/p-e-w/heretic/pull/17 for details.
|
||||
@@ -48,6 +49,7 @@ def empty_cache():
|
||||
|
||||
def get_nvidia_driver_version() -> str | None:
|
||||
"""Gets the NVIDIA driver version using nvidia-smi."""
|
||||
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
["nvidia-smi", "--query-gpu=driver_version", "--format=csv,noheader"],
|
||||
@@ -61,6 +63,7 @@ def get_nvidia_driver_version() -> str | None:
|
||||
|
||||
def get_amdgpu_driver_version() -> str | None:
|
||||
"""Gets the AMD GPU (ROCm) driver and suite version info."""
|
||||
|
||||
# 1. Try amd-smi (modern standard for ROCm 6.0+)
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
@@ -101,6 +104,7 @@ def get_amdgpu_driver_version() -> str | None:
|
||||
|
||||
def get_xpu_driver_version() -> str | None:
|
||||
"""Gets the Intel XPU driver version."""
|
||||
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
["xpu-smi", "discovery"],
|
||||
@@ -117,6 +121,7 @@ def get_xpu_driver_version() -> str | None:
|
||||
|
||||
def get_npu_driver_version() -> str | None:
|
||||
"""Gets the Huawei NPU driver version."""
|
||||
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
["npu-smi", "info", "-t", "board", "-i", "0"],
|
||||
@@ -133,6 +138,7 @@ def get_npu_driver_version() -> str | None:
|
||||
|
||||
def get_mps_driver_version() -> str | None:
|
||||
"""Gets the Apple Silicon (MPS) driver version via macOS version."""
|
||||
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
["sw_vers", "-productVersion"],
|
||||
@@ -156,6 +162,7 @@ class HereticVersionInfo:
|
||||
|
||||
def get_heretic_version_info() -> HereticVersionInfo:
|
||||
"""Detects version and installation source (PyPI, Git, Local) of heretic-llm."""
|
||||
|
||||
package_name = "heretic-llm"
|
||||
origin_metadata: dict[str, Any] = {"type": "unknown"}
|
||||
# This package must be installed for this code to run.
|
||||
@@ -171,6 +178,7 @@ def get_heretic_version_info() -> HereticVersionInfo:
|
||||
if not direct_url_content:
|
||||
# Standard PyPI installation.
|
||||
origin_metadata["type"] = "pypi"
|
||||
|
||||
return HereticVersionInfo(
|
||||
version=base_version,
|
||||
origin="PyPI",
|
||||
@@ -178,51 +186,48 @@ def get_heretic_version_info() -> HereticVersionInfo:
|
||||
metadata=origin_metadata,
|
||||
)
|
||||
|
||||
try:
|
||||
data = json.loads(direct_url_content)
|
||||
data = json.loads(direct_url_content)
|
||||
|
||||
# Check for Git source.
|
||||
if "vcs_info" in data and data["vcs_info"].get("vcs") == "git":
|
||||
vcs_info = data["vcs_info"]
|
||||
commit_hash = vcs_info.get("commit_id", "unknown")
|
||||
repo_url = data.get("url", "unknown_repo")
|
||||
requested_revision = vcs_info.get("requested_revision")
|
||||
# Check for Git source.
|
||||
if "vcs_info" in data and data["vcs_info"].get("vcs") == "git":
|
||||
vcs_info = data["vcs_info"]
|
||||
commit_hash = vcs_info.get("commit_id", "unknown")
|
||||
repo_url = data.get("url", "unknown_repo")
|
||||
requested_revision = vcs_info.get("requested_revision")
|
||||
|
||||
if requested_revision:
|
||||
origin_str = (
|
||||
f"Git ({repo_url}@{requested_revision} - commit: {commit_hash})"
|
||||
)
|
||||
else:
|
||||
origin_str = f"Git ({repo_url} @ {commit_hash})"
|
||||
|
||||
origin_metadata.update(
|
||||
{
|
||||
"type": "git",
|
||||
"url": repo_url,
|
||||
"commit_hash": commit_hash,
|
||||
"requested_revision": requested_revision,
|
||||
}
|
||||
if requested_revision:
|
||||
origin_str = (
|
||||
f"Git ({repo_url}@{requested_revision} - commit: {commit_hash})"
|
||||
)
|
||||
else:
|
||||
origin_str = f"Git ({repo_url} @ {commit_hash})"
|
||||
|
||||
return HereticVersionInfo(
|
||||
version=base_version,
|
||||
origin=origin_str,
|
||||
is_standard_pypi=False,
|
||||
metadata=origin_metadata,
|
||||
)
|
||||
origin_metadata.update(
|
||||
{
|
||||
"type": "git",
|
||||
"url": repo_url,
|
||||
"commit_hash": commit_hash,
|
||||
"requested_revision": requested_revision,
|
||||
}
|
||||
)
|
||||
|
||||
# Check for local file/wheel directory.
|
||||
if "url" in data and data["url"].startswith("file://"):
|
||||
origin_metadata["type"] = "local"
|
||||
return HereticVersionInfo(
|
||||
version=base_version,
|
||||
origin="Local",
|
||||
is_standard_pypi=False,
|
||||
metadata=origin_metadata,
|
||||
)
|
||||
return HereticVersionInfo(
|
||||
version=base_version,
|
||||
origin=origin_str,
|
||||
is_standard_pypi=False,
|
||||
metadata=origin_metadata,
|
||||
)
|
||||
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
# Check for local file/wheel directory.
|
||||
if "url" in data and data["url"].startswith("file://"):
|
||||
origin_metadata["type"] = "local"
|
||||
|
||||
return HereticVersionInfo(
|
||||
version=base_version,
|
||||
origin="Local",
|
||||
is_standard_pypi=False,
|
||||
metadata=origin_metadata,
|
||||
)
|
||||
|
||||
return HereticVersionInfo(
|
||||
version=base_version,
|
||||
@@ -234,6 +239,7 @@ def get_heretic_version_info() -> HereticVersionInfo:
|
||||
|
||||
def get_accelerator_info_dict() -> dict[str, Any]:
|
||||
"""Retrieves raw accelerator info (CUDA, ROCm, etc) directly into structured keys."""
|
||||
|
||||
if torch.cuda.is_available():
|
||||
count = torch.cuda.device_count()
|
||||
is_rocm = getattr(torch.version, "hip", None) is not None
|
||||
@@ -320,6 +326,7 @@ def get_accelerator_info_dict() -> dict[str, Any]:
|
||||
|
||||
def get_accelerator_info(include_warnings: bool = True) -> str:
|
||||
"""Convenience wrapper for hardware detection and console-friendly formatting."""
|
||||
|
||||
info = get_accelerator_info_dict()
|
||||
|
||||
if info["type"] is None:
|
||||
@@ -350,6 +357,7 @@ def get_accelerator_info(include_warnings: bool = True) -> str:
|
||||
|
||||
def get_cpu_info_dict() -> dict[str, str | int | None]:
|
||||
"""Gets granular CPU identifiers using the py-cpuinfo library."""
|
||||
|
||||
info = cpuinfo.get_cpu_info()
|
||||
|
||||
return {
|
||||
@@ -363,6 +371,7 @@ def get_cpu_info_dict() -> dict[str, str | int | None]:
|
||||
|
||||
def get_cpu_info() -> str:
|
||||
"""Gets the CPU brand name."""
|
||||
|
||||
info = get_cpu_info_dict()
|
||||
parts = []
|
||||
parts.append(
|
||||
@@ -397,12 +406,14 @@ def get_python_env_info_dict() -> dict[str, str]:
|
||||
|
||||
def get_python_env_info() -> str:
|
||||
"""Detects the type of Python environment (Conda, Venv, etc.) and build info."""
|
||||
|
||||
info = get_python_env_info_dict()
|
||||
return f"{info['version']} ({info['implementation']}, {info['compiler']}) [{info['environment']}]"
|
||||
|
||||
|
||||
def get_package_version(name: str) -> str | None:
|
||||
def get_package_version(name: str) -> str:
|
||||
"""Gets the installed version of a package, stripping local suffixes like +cu128."""
|
||||
|
||||
# Normalize name: pip considers hyphens and underscores equivalent.
|
||||
normalized_name = name.lower().replace("_", "-")
|
||||
version_str = importlib.metadata.version(normalized_name)
|
||||
@@ -411,8 +422,12 @@ def get_package_version(name: str) -> str | None:
|
||||
|
||||
def get_requirements_dict() -> dict[str, str]:
|
||||
"""Recursively finds all direct and transitive dependencies of heretic-llm and core libraries."""
|
||||
|
||||
# We start with heretic-llm and the core compute libraries.
|
||||
# PyTorch is not listed as a dependency in the heretic-llm package
|
||||
# because installation is hardware-specific and must be done manually.
|
||||
packages_to_check = ["heretic-llm", "torch", "torchaudio", "torchvision"]
|
||||
|
||||
visited = set()
|
||||
required_packages = set()
|
||||
|
||||
@@ -445,18 +460,19 @@ def get_requirements_dict() -> dict[str, str]:
|
||||
# If a package is listed as a dependency but not installed, we skip it.
|
||||
continue
|
||||
|
||||
required_packages_sorted = sorted(required_packages)
|
||||
|
||||
# Lookup versions for all discovered packages.
|
||||
dependencies = {}
|
||||
version_info = get_heretic_version_info()
|
||||
for name in required_packages:
|
||||
|
||||
for package in required_packages_sorted:
|
||||
# If heretic-llm was installed from source (Git/Local), exclude it
|
||||
# from requirements.txt to prevent pip from downloading an unrelated
|
||||
# version from PyPI during reproduction.
|
||||
if name == "heretic-llm" and not version_info.is_standard_pypi:
|
||||
if package == "heretic-llm" and not version_info.is_standard_pypi:
|
||||
continue
|
||||
|
||||
version_str = get_package_version(name)
|
||||
if version_str:
|
||||
dependencies[name] = version_str
|
||||
dependencies[package] = get_package_version(package)
|
||||
|
||||
return dependencies
|
||||
|
||||
+382
-372
@@ -1,29 +1,30 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# Copyright (C) 2025-2026 Philipp Emanuel Weidmann <pew@worldwidemann.com> + contributors
|
||||
|
||||
import getpass
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import random
|
||||
import tempfile
|
||||
import traceback
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
from importlib.metadata import version
|
||||
from pathlib import Path
|
||||
from typing import Any, TypeVar
|
||||
from typing import TypeVar
|
||||
|
||||
import huggingface_hub
|
||||
import numpy as np
|
||||
import questionary
|
||||
import tomli_w
|
||||
import torch
|
||||
from datasets import DatasetDict, ReadInstruction, load_dataset, load_from_disk
|
||||
from datasets.config import DATASET_STATE_JSON_FILENAME
|
||||
from datasets.download.download_manager import DownloadMode
|
||||
from datasets.utils.info_utils import VerificationMode
|
||||
from huggingface_hub.utils import validate_repo_id
|
||||
from optuna import Trial
|
||||
from optuna.trial import FrozenTrial
|
||||
from psutil import Process
|
||||
from questionary import Choice, Style
|
||||
from questionary import Question
|
||||
from rich.console import Console
|
||||
|
||||
from .config import DatasetSpecification, Settings
|
||||
@@ -36,6 +37,9 @@ from .system import (
|
||||
is_xpu_available,
|
||||
)
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
print = Console(highlight=False).print
|
||||
|
||||
|
||||
@@ -62,111 +66,6 @@ def print_memory_usage():
|
||||
p("Driver (reserved) MPS memory", torch.mps.driver_allocated_memory())
|
||||
|
||||
|
||||
def is_notebook() -> bool:
|
||||
# Check for specific environment variables (Colab, Kaggle).
|
||||
# This is necessary because when running as a subprocess (e.g. !heretic),
|
||||
# get_ipython() might not be available or might not reflect the notebook environment.
|
||||
if os.getenv("COLAB_GPU") or os.getenv("KAGGLE_KERNEL_RUN_TYPE"):
|
||||
return True
|
||||
|
||||
# Check IPython shell type (for library usage).
|
||||
try:
|
||||
from IPython import get_ipython # ty:ignore[unresolved-import]
|
||||
|
||||
shell = get_ipython()
|
||||
if shell is None:
|
||||
return False
|
||||
|
||||
shell_name = shell.__class__.__name__
|
||||
if shell_name in ["ZMQInteractiveShell", "Shell"]:
|
||||
return True
|
||||
|
||||
if "google.colab" in str(shell.__class__):
|
||||
return True
|
||||
|
||||
return False
|
||||
except (ImportError, NameError, AttributeError):
|
||||
return False
|
||||
|
||||
|
||||
def prompt_select(message: str, choices: list[Any]) -> Any:
|
||||
if is_notebook():
|
||||
print()
|
||||
print(message)
|
||||
real_choices = []
|
||||
|
||||
for i, choice in enumerate(choices, 1):
|
||||
if isinstance(choice, Choice):
|
||||
print(f"[{i}] {choice.title}")
|
||||
real_choices.append(choice.value)
|
||||
else:
|
||||
print(f"[{i}] {choice}")
|
||||
real_choices.append(choice)
|
||||
|
||||
while True:
|
||||
try:
|
||||
selection = input("Enter number: ")
|
||||
index = int(selection) - 1
|
||||
if 0 <= index < len(real_choices):
|
||||
return real_choices[index]
|
||||
print(
|
||||
f"[red]Please enter a number between 1 and {len(real_choices)}[/]"
|
||||
)
|
||||
except ValueError:
|
||||
print("[red]Invalid input. Please enter a number.[/]")
|
||||
else:
|
||||
return questionary.select(
|
||||
message,
|
||||
choices=choices,
|
||||
style=Style([("highlighted", "reverse")]),
|
||||
).ask()
|
||||
|
||||
|
||||
def prompt_text(
|
||||
message: str,
|
||||
default: str = "",
|
||||
qmark: str = "?",
|
||||
unsafe: bool = False,
|
||||
) -> str:
|
||||
if is_notebook():
|
||||
print()
|
||||
result = input(f"{message} [{default}]: " if default else f"{message}: ")
|
||||
return result if result else default
|
||||
else:
|
||||
question = questionary.text(message, default=default, qmark=qmark)
|
||||
if unsafe:
|
||||
return question.unsafe_ask()
|
||||
else:
|
||||
return question.ask()
|
||||
|
||||
|
||||
def prompt_path(message: str) -> str:
|
||||
if is_notebook():
|
||||
return prompt_text(message)
|
||||
else:
|
||||
return questionary.path(message, only_directories=True).ask()
|
||||
|
||||
|
||||
def prompt_password(message: str) -> str:
|
||||
if is_notebook():
|
||||
print()
|
||||
return getpass.getpass(message)
|
||||
else:
|
||||
return questionary.password(message).ask()
|
||||
|
||||
|
||||
def prompt_confirm(message: str, default: bool = True) -> bool:
|
||||
if is_notebook():
|
||||
print()
|
||||
choices = "[Y/n]" if default else "[y/N]"
|
||||
result = input(f"{message} {choices} ").strip().lower()
|
||||
if not result:
|
||||
return default
|
||||
return result in ("y", "yes")
|
||||
else:
|
||||
return questionary.confirm(message, default=default).ask()
|
||||
|
||||
|
||||
def format_duration(seconds: float) -> str:
|
||||
seconds = round(seconds)
|
||||
hours, seconds = divmod(seconds, 3600)
|
||||
@@ -180,12 +79,64 @@ def format_duration(seconds: float) -> str:
|
||||
return f"{seconds}s"
|
||||
|
||||
|
||||
def format_exception(error: Exception) -> str:
|
||||
# Walk causal chain to find a non-empty message.
|
||||
current = error
|
||||
while current is not None:
|
||||
message = str(current).strip()
|
||||
if message:
|
||||
return message
|
||||
current = current.__cause__ or current.__context__
|
||||
|
||||
# If there is no message in the entire causal chain, fall back to the complete traceback.
|
||||
return traceback.format_exc().strip()
|
||||
|
||||
|
||||
def ask_if_unset(value: T, question: Question, unsafe: bool = False) -> T:
|
||||
if value is None:
|
||||
if unsafe:
|
||||
return question.unsafe_ask()
|
||||
else:
|
||||
return question.ask()
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def is_hf_path(path: str) -> bool:
|
||||
"""Checks whether a path likely refers to a Hugging Face repository."""
|
||||
|
||||
# Match Transformers: Existing local paths take precedence over Hub lookup,
|
||||
# even if the path string is also a valid repository ID.
|
||||
if Path(path).exists():
|
||||
return False
|
||||
|
||||
validate_repo_id(path)
|
||||
return True
|
||||
|
||||
|
||||
@dataclass
|
||||
class Prompt:
|
||||
system: str
|
||||
user: str
|
||||
|
||||
|
||||
def get_split_slice(split_str: str, length: int) -> tuple[int, int]:
|
||||
"""Resolves a split specification into absolute (start, end) indices."""
|
||||
|
||||
# The split name is the part before the slice, e.g. "train" in "train[:400]".
|
||||
split_name = split_str.split("[")[0]
|
||||
|
||||
# Associate the split with its number of examples (lines).
|
||||
name_to_length = {split_name: length}
|
||||
|
||||
# Convert the instructions to absolute indices and select the first one.
|
||||
absolute_instruction = ReadInstruction.from_spec(split_str).to_absolute(
|
||||
name_to_length
|
||||
)[0]
|
||||
|
||||
return absolute_instruction.from_, absolute_instruction.to
|
||||
|
||||
|
||||
def load_prompts(
|
||||
settings: Settings,
|
||||
specification: DatasetSpecification,
|
||||
@@ -193,25 +144,43 @@ def load_prompts(
|
||||
path = specification.dataset
|
||||
split_str = specification.split
|
||||
|
||||
if os.path.isdir(path):
|
||||
if Path(path, DATASET_STATE_JSON_FILENAME).exists():
|
||||
if os.path.isfile(path):
|
||||
# Plain text file with one prompt per line. Empty lines are ignored.
|
||||
with open(path, encoding="utf-8") as file:
|
||||
prompts = [line.strip() for line in file if line.strip()]
|
||||
|
||||
# The split is optional for text files. When given, it selects a subset
|
||||
# of the lines using slice notation (e.g. "[:400]"). A synthetic split
|
||||
# name is prepended because ReadInstruction expects a named split.
|
||||
if split_str is not None:
|
||||
start, end = get_split_slice(f"_{split_str}", len(prompts))
|
||||
prompts = prompts[start:end]
|
||||
else:
|
||||
# All dataset sources require an explicit split and column.
|
||||
if split_str is None:
|
||||
raise ValueError(f'The "split" field is required for datasets: {path}')
|
||||
|
||||
if specification.column is None:
|
||||
raise ValueError(f'The "column" field is required for datasets: {path}')
|
||||
|
||||
if is_hf_path(path):
|
||||
dataset = load_dataset(
|
||||
path,
|
||||
revision=specification.commit,
|
||||
split=split_str,
|
||||
)
|
||||
elif Path(path, DATASET_STATE_JSON_FILENAME).exists():
|
||||
# Dataset saved with datasets.save_to_disk; needs special handling.
|
||||
# Path should be the subdirectory for a particular split.
|
||||
dataset = load_from_disk(path)
|
||||
assert not isinstance(dataset, DatasetDict), (
|
||||
"Loading dataset dicts is not supported"
|
||||
)
|
||||
# Parse the split instructions.
|
||||
instruction = ReadInstruction.from_spec(split_str)
|
||||
# Associate the split with its number of examples (lines).
|
||||
split_name = str(dataset.split)
|
||||
name2len = {split_name: len(dataset)}
|
||||
# Convert the instructions to absolute indices and select the first one.
|
||||
abs_instruction = instruction.to_absolute(name2len)[0]
|
||||
# Get the dataset by applying the indices.
|
||||
dataset = dataset[abs_instruction.from_ : abs_instruction.to]
|
||||
# Parse the split instructions and apply them.
|
||||
start, end = get_split_slice(split_str, len(dataset))
|
||||
dataset = dataset[start:end]
|
||||
else:
|
||||
# Path is a local directory.
|
||||
# Path should be a local directory.
|
||||
dataset = load_dataset(
|
||||
path,
|
||||
split=split_str,
|
||||
@@ -220,11 +189,8 @@ def load_prompts(
|
||||
# But also don't use cached data, as the dataset may have changed on disk.
|
||||
download_mode=DownloadMode.FORCE_REDOWNLOAD,
|
||||
)
|
||||
else:
|
||||
# Probably a repository path; let load_dataset figure it out.
|
||||
dataset = load_dataset(path, split=split_str)
|
||||
|
||||
prompts = list(dataset[specification.column])
|
||||
prompts = list(dataset[specification.column])
|
||||
|
||||
if specification.prefix:
|
||||
prompts = [f"{specification.prefix} {prompt}" for prompt in prompts]
|
||||
@@ -247,14 +213,11 @@ def load_prompts(
|
||||
]
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
def batchify(items: list[T], batch_size: int) -> list[list[T]]:
|
||||
return [items[i : i + batch_size] for i in range(0, len(items), batch_size)]
|
||||
|
||||
|
||||
def get_trial_parameters(trial: Trial) -> dict[str, str]:
|
||||
def get_trial_parameters(trial: Trial | FrozenTrial) -> dict[str, str]:
|
||||
params = {}
|
||||
|
||||
direction_index = trial.user_attrs["direction_index"]
|
||||
@@ -271,21 +234,29 @@ def get_trial_parameters(trial: Trial) -> dict[str, str]:
|
||||
|
||||
def get_readme_intro(
|
||||
settings: Settings,
|
||||
trial: Trial,
|
||||
base_refusals: int,
|
||||
bad_prompts: list[Prompt],
|
||||
trial: Trial | FrozenTrial,
|
||||
contains_reproducibility_information: bool,
|
||||
) -> str:
|
||||
if Path(settings.model).exists():
|
||||
if is_hf_path(settings.model):
|
||||
model_link = f"[{settings.model}](https://huggingface.co/{settings.model})"
|
||||
else:
|
||||
# Hide the path, which may contain private information.
|
||||
model_link = "a model"
|
||||
else:
|
||||
model_link = f"[{settings.model}](https://huggingface.co/{settings.model})"
|
||||
|
||||
version_info = get_heretic_version_info()
|
||||
if contains_reproducibility_information:
|
||||
reproducibility_instructions = """
|
||||
> [!TIP]
|
||||
> **This model is reproducible!**
|
||||
>
|
||||
> See the [README](reproduce/README.md) in the `reproduce` directory for more information.
|
||||
"""
|
||||
else:
|
||||
reproducibility_instructions = ""
|
||||
|
||||
return f"""# This is a decensored version of {
|
||||
model_link
|
||||
}, made using [Heretic](https://github.com/p-e-w/heretic) v{version_info.version}
|
||||
|
||||
}, made using [Heretic](https://heretic-project.org) v{version("heretic-llm")}
|
||||
{reproducibility_instructions}
|
||||
## Abliteration parameters
|
||||
|
||||
| Parameter | Value |
|
||||
@@ -304,9 +275,9 @@ def get_readme_intro(
|
||||
| Metric | This model | Original model ({model_link}) |
|
||||
| :----- | :--------: | :---------------------------: |
|
||||
| **KL divergence** | {trial.user_attrs["kl_divergence"]:.4f} | 0 *(by definition)* |
|
||||
| **Refusals** | {trial.user_attrs["refusals"]}/{len(bad_prompts)} | {base_refusals}/{
|
||||
len(bad_prompts)
|
||||
} |
|
||||
| **Refusals** | {trial.user_attrs["refusals"]}/{trial.user_attrs["n_bad_prompts"]} | {
|
||||
trial.user_attrs["base_refusals"]
|
||||
}/{trial.user_attrs["n_bad_prompts"]} |
|
||||
|
||||
-----
|
||||
|
||||
@@ -315,265 +286,304 @@ def get_readme_intro(
|
||||
|
||||
def generate_config_toml(settings: Settings) -> str:
|
||||
"""Serializes the full Settings object to TOML."""
|
||||
|
||||
return tomli_w.dumps(settings.model_dump(exclude_none=True))
|
||||
|
||||
|
||||
def generate_requirements_txt() -> str:
|
||||
"""Collects direct project dependencies as a formatted string."""
|
||||
requirements = get_requirements_dict()
|
||||
sorted_requirements = sorted(
|
||||
[f"{name}=={version}" for name, version in requirements.items()],
|
||||
key=lambda x: x.lower(),
|
||||
)
|
||||
return "\n".join(sorted_requirements) + "\n"
|
||||
|
||||
requirements = [
|
||||
f"{package}=={version}" for package, version in get_requirements_dict().items()
|
||||
]
|
||||
return "\n".join(requirements) + "\n"
|
||||
|
||||
|
||||
def set_seed(seed: int):
|
||||
"""Sets the seed for all RNGs."""
|
||||
random.seed(seed)
|
||||
np.random.seed(seed)
|
||||
torch.manual_seed(seed)
|
||||
def format_hf_link(
|
||||
path: str,
|
||||
commit: str | None = None,
|
||||
is_dataset: bool = False,
|
||||
) -> str:
|
||||
prefix = "datasets/" if is_dataset else ""
|
||||
base_url = f"https://huggingface.co/{prefix}{path}"
|
||||
link = f"[{path}]({base_url})"
|
||||
|
||||
if commit:
|
||||
commit_url = f"{base_url}/commit/{commit}"
|
||||
link += f" (Commit: [`{commit[:7]}`]({commit_url}))"
|
||||
|
||||
return link
|
||||
|
||||
|
||||
def generate_reproduce_readme(
|
||||
settings: Settings,
|
||||
checkpoint_filename: str,
|
||||
trial: Trial,
|
||||
timestamp: str | None = None,
|
||||
base_model_commit: str | None = None,
|
||||
trial: Trial | FrozenTrial,
|
||||
include_system_information: bool,
|
||||
) -> str:
|
||||
"""Generates a README.md for the reproduce/ folder."""
|
||||
torch_version = torch.__version__
|
||||
install_hint = f"pip install torch=={torch_version}"
|
||||
if "+" in torch_version:
|
||||
suffix = torch_version.split("+")[1]
|
||||
if suffix:
|
||||
install_hint += f" --index-url https://download.pytorch.org/whl/{suffix}"
|
||||
"""Generates the contents of a README.md for the reproduce/ folder."""
|
||||
|
||||
heterogeneous_warning = ""
|
||||
if torch.cuda.is_available():
|
||||
count = torch.cuda.device_count()
|
||||
if count > 1:
|
||||
device_names = {torch.cuda.get_device_name(i) for i in range(count)}
|
||||
if len(device_names) > 1:
|
||||
heterogeneous_warning = """
|
||||
|
||||
if include_system_information:
|
||||
if torch.cuda.is_available():
|
||||
count = torch.cuda.device_count()
|
||||
if count > 1:
|
||||
device_names = {torch.cuda.get_device_name(i) for i in range(count)}
|
||||
if len(device_names) > 1:
|
||||
heterogeneous_warning = """
|
||||
> [!WARNING]
|
||||
> **Heterogeneous GPUs Detected!**
|
||||
> This system uses multiple non-identical GPUs. When operations are distributed across different GPUs (e.g. via `device_map='auto'`), non-deterministic behavior can occur. **Reproducibility ***cannot*** be guaranteed in this environment.**
|
||||
> **Heterogeneous GPUs**
|
||||
>
|
||||
> This model was generated using multiple non-identical GPUs. When operations are distributed across different GPUs
|
||||
> (e.g. via `device_map='auto'`), non-deterministic behavior can occur.
|
||||
>
|
||||
> Reproducibility *cannot* be guaranteed in this environment.
|
||||
"""
|
||||
|
||||
version_info = get_heretic_version_info()
|
||||
origin_warning = ""
|
||||
if not version_info.is_standard_pypi:
|
||||
if version_info.origin and version_info.origin.startswith("Git"):
|
||||
repo_info = version_info.origin.split("Git (")[1].strip(")")
|
||||
origin_warning = f"""
|
||||
> [!NOTE]
|
||||
> **Git Installation Detected**
|
||||
> This system installed `heretic-llm` from source repository: `{repo_info}`.
|
||||
> To reproduce these results, you must install Heretic from this exact repository and commit.
|
||||
"""
|
||||
elif version_info.origin == "Local":
|
||||
origin_warning = """
|
||||
> [!WARNING]
|
||||
> **Local Code Detected!**
|
||||
> This system installed `heretic-llm` from a local directory or wheel. Uncommitted or experimental code may have been executed. **Reproducibility ***cannot*** be guaranteed in this environment.**
|
||||
"""
|
||||
cpu = get_cpu_info_dict()
|
||||
python_env = get_python_env_info_dict()
|
||||
|
||||
accelerators = get_accelerator_info_dict()
|
||||
if accelerators["type"] is None:
|
||||
accelerator_report = "**No GPU or other accelerator detected.**"
|
||||
else:
|
||||
origin_warning = """
|
||||
> [!WARNING]
|
||||
> **Non-Standard Installation Detected!**
|
||||
> This system installed `heretic-llm` from an unknown non-standard source. **Reproducibility ***cannot*** be guaranteed in this environment.**
|
||||
"""
|
||||
devices = accelerators["devices"]
|
||||
total_vram = sum(device.get("vram_gb", 0) for device in devices)
|
||||
vram_suffix = f" ({total_vram:.2f} GB total VRAM)" if total_vram > 0 else ""
|
||||
accelerator_lines = [
|
||||
f"- **{accelerators['type']}:** Detected {len(devices)} device(s){vram_suffix}"
|
||||
]
|
||||
|
||||
def format_hf_link(
|
||||
name: str, commit: str | None = None, is_dataset: bool = False
|
||||
) -> str:
|
||||
if Path(name).exists():
|
||||
return f"`{name}` (Local)"
|
||||
if accelerators.get("api_name") and accelerators.get("api_version"):
|
||||
accelerator_lines.append(
|
||||
f" - **{accelerators['api_name']}:** {accelerators['api_version']}"
|
||||
)
|
||||
|
||||
prefix = "datasets/" if is_dataset else ""
|
||||
base_url = f"https://huggingface.co/{prefix}{name}"
|
||||
link = f"[{name}]({base_url})"
|
||||
if commit:
|
||||
commit_url = f"{base_url}/commit/{commit}"
|
||||
link += f" (Commit: [{commit[:7]}]({commit_url}))"
|
||||
return link
|
||||
if accelerators.get("driver_version"):
|
||||
accelerator_lines.append(
|
||||
f" - **Driver Version:** {accelerators['driver_version']}"
|
||||
)
|
||||
|
||||
model_link = format_hf_link(settings.model, base_model_commit)
|
||||
dataset_info = f"""## Dataset Information
|
||||
accelerator_lines.append("- **Devices:**")
|
||||
for i, device in enumerate(devices):
|
||||
vram = f" ({device['vram_gb']:.2f} GB)" if device.get("vram_gb") else ""
|
||||
accelerator_lines.append(
|
||||
f" - **{accelerators['type']} {i}:** {device['name']}{vram}"
|
||||
)
|
||||
accelerator_report = "\n".join(accelerator_lines)
|
||||
|
||||
- **Good Prompts:** {format_hf_link(settings.good_prompts.dataset, settings.good_prompts.commit, is_dataset=True)}
|
||||
- **Bad Prompts:** {format_hf_link(settings.bad_prompts.dataset, settings.bad_prompts.commit, is_dataset=True)}
|
||||
- **Good Evaluation Prompts:** {format_hf_link(settings.good_evaluation_prompts.dataset, settings.good_evaluation_prompts.commit, is_dataset=True)}
|
||||
- **Bad Evaluation Prompts:** {format_hf_link(settings.bad_evaluation_prompts.dataset, settings.bad_evaluation_prompts.commit, is_dataset=True)}"""
|
||||
system_report = f"""## System
|
||||
|
||||
timestamp_str = f"- **Run started at (UTC):** `{timestamp}`" if timestamp else ""
|
||||
|
||||
# System and Accelerator info using structured dictionaries.
|
||||
cpu = get_cpu_info_dict()
|
||||
python_env = get_python_env_info_dict()
|
||||
accelerator = get_accelerator_info_dict()
|
||||
|
||||
# Build System Environment section.
|
||||
system_env_lines = [
|
||||
f"- **OS:** `{platform.platform()}` (`{platform.machine()}`)",
|
||||
f"- **CPU:** `{cpu['brand'] or 'Unknown CPU'}`",
|
||||
f" - **Information:** Family `{cpu['family']}`, Model `{cpu['model']}`, Stepping `{cpu['stepping']}`",
|
||||
]
|
||||
|
||||
system_env_lines.extend(
|
||||
[
|
||||
f"- **Python:** `{python_env['version']}` (`{python_env['implementation']}`, `{python_env['compiler']}`) [`{python_env['environment']}`]",
|
||||
f"- **Heretic:** `v{version_info.version}`"
|
||||
+ (f" (Origin: `{version_info.origin}`)" if version_info.origin else ""),
|
||||
f"- **PyTorch:** `{torch.__version__}`",
|
||||
]
|
||||
)
|
||||
system_environment_report = "\n".join(system_env_lines)
|
||||
|
||||
# Build Accelerators section.
|
||||
if accelerator["type"] is None:
|
||||
accelerator_report = "> [!WARNING]\n> **No GPU or other accelerator detected.**"
|
||||
else:
|
||||
devices = accelerator["devices"]
|
||||
total_vram = sum(d.get("vram_gb", 0) for d in devices)
|
||||
vram_suffix = f" (`{total_vram:.2f} GB` total VRAM)" if total_vram > 0 else ""
|
||||
accelerator_lines = [
|
||||
f"- **{accelerator['type']}:** Detected `{len(devices)}` device(s){vram_suffix}"
|
||||
]
|
||||
|
||||
if accelerator.get("api_name") and accelerator.get("api_version"):
|
||||
accelerator_lines.append(
|
||||
f" - **{accelerator['api_name']}:** `{accelerator['api_version']}`"
|
||||
)
|
||||
|
||||
if accelerator.get("driver_version"):
|
||||
accelerator_lines.append(
|
||||
f" - **Driver Version:** `{accelerator['driver_version']}`"
|
||||
)
|
||||
|
||||
accelerator_lines.append("- **Devices:**")
|
||||
for i, dev in enumerate(devices):
|
||||
vram = f" (`{dev['vram_gb']:.2f} GB`)" if dev.get("vram_gb") else ""
|
||||
accelerator_lines.append(
|
||||
f" - **{accelerator['type']} {i}:** `{dev['name']}`{vram}"
|
||||
)
|
||||
accelerator_report = "\n".join(accelerator_lines)
|
||||
|
||||
return f"""# Reproduction Guide
|
||||
|
||||
This directory contains the necessary information and assets to reproduce the results obtained during this Heretic run.{heterogeneous_warning}{origin_warning}
|
||||
|
||||
## Model Information
|
||||
|
||||
- **Base Model:** {model_link}
|
||||
{timestamp_str}
|
||||
|
||||
{dataset_info}
|
||||
|
||||
## Selected Trial
|
||||
|
||||
- **Trial Number:** `#{trial.user_attrs["index"]}`
|
||||
- **Refusal Count:** `{trial.user_attrs.get("refusals")}/{trial.user_attrs.get("total_refusal_prompts")}`
|
||||
- **KL Divergence:** `{trial.user_attrs.get("kl_divergence", 0):.6f}`
|
||||
|
||||
## System Environment
|
||||
|
||||
{system_environment_report}
|
||||
- **Python:** {python_env["version"]} ({python_env["implementation"]}, {python_env["compiler"]}) [{python_env["environment"]}]
|
||||
- **Operating system:** {platform.platform()} ({platform.machine()})
|
||||
- **CPU:** {cpu["brand"] or "Unknown"}
|
||||
|
||||
### Accelerators
|
||||
|
||||
{accelerator_report}
|
||||
|
||||
## Contents
|
||||
"""
|
||||
system_instructions = (
|
||||
"1. Ensure your system matches the specifications in the **System** section above. "
|
||||
"Exact reproducibility is only guaranteed if all aspects of your system are identical to the one the model was originally generated on.\n"
|
||||
)
|
||||
else:
|
||||
system_report = ""
|
||||
system_instructions = ""
|
||||
|
||||
- **config.toml**: The exact configuration used, including the seed `{settings.seed}`.
|
||||
- **requirements.txt**: The exact versions of all installed Python packages.
|
||||
- **{checkpoint_filename}**: The Optuna study journal containing the history of all trials.
|
||||
- **reproduce.json**: A machine-readable version of this report.
|
||||
- **SHA256SUMS**: Cryptographic hashes for all uploaded weight files (if applicable).
|
||||
version_info = get_heretic_version_info()
|
||||
origin_warning = ""
|
||||
if not version_info.is_standard_pypi:
|
||||
if version_info.origin and version_info.origin.startswith("Git"):
|
||||
repo_info = version_info.origin.split("Git (")[1].rstrip(")")
|
||||
origin_warning = f"""
|
||||
> [!IMPORTANT]
|
||||
> **Git installation**
|
||||
>
|
||||
> This system installed Heretic from a Git repository: {repo_info}
|
||||
>
|
||||
> To reproduce the model, you must install Heretic from this exact repository and commit.
|
||||
"""
|
||||
elif version_info.origin == "Local":
|
||||
origin_warning = """
|
||||
> [!WARNING]
|
||||
> **Local code**
|
||||
>
|
||||
> This system installed Heretic from a local directory or wheel. Uncommitted or experimental code may have been executed.
|
||||
>
|
||||
> Reproducibility *cannot* be guaranteed in this environment.
|
||||
"""
|
||||
else:
|
||||
origin_warning = """
|
||||
> [!WARNING]
|
||||
> **Non-standard installation**
|
||||
>
|
||||
> This system installed Heretic from an unknown non-standard source.
|
||||
>
|
||||
> Reproducibility *cannot* be guaranteed in this environment.
|
||||
"""
|
||||
|
||||
## How to Reproduce
|
||||
pytorch_version = torch.__version__
|
||||
pytorch_install_command = f"pip install torch=={pytorch_version}"
|
||||
if "+" in pytorch_version:
|
||||
suffix = pytorch_version.split("+")[1]
|
||||
if suffix:
|
||||
pytorch_install_command += (
|
||||
f" --index-url https://download.pytorch.org/whl/{suffix}"
|
||||
)
|
||||
|
||||
1. Ensure your hardware and environment match the specifications in the **System Environment** section above.
|
||||
2. Install the exact package versions listed in `requirements.txt`.
|
||||
3. Place the provided `config.toml` in your working directory.
|
||||
4. Run `heretic` without any additional arguments.
|
||||
5. Verify the integrity of the reproduced files by comparing their SHA256 hashes against the manifest in `SHA256SUMS`.
|
||||
return f"""# Reproduction guide
|
||||
|
||||
This directory contains the necessary information and assets to reproduce the results obtained during this Heretic run.{heterogeneous_warning}{origin_warning}
|
||||
|
||||
## Models
|
||||
|
||||
- **Base model:** {format_hf_link(settings.model, settings.model_commit)}
|
||||
|
||||
## Datasets
|
||||
|
||||
- **Good prompts:** {format_hf_link(settings.good_prompts.dataset, settings.good_prompts.commit, is_dataset=True)}
|
||||
- **Bad prompts:** {format_hf_link(settings.bad_prompts.dataset, settings.bad_prompts.commit, is_dataset=True)}
|
||||
- **Good evaluation prompts:** {format_hf_link(settings.good_evaluation_prompts.dataset, settings.good_evaluation_prompts.commit, is_dataset=True)}
|
||||
- **Bad evaluation prompts:** {format_hf_link(settings.bad_evaluation_prompts.dataset, settings.bad_evaluation_prompts.commit, is_dataset=True)}
|
||||
|
||||
## Selected trial
|
||||
|
||||
- **Trial number:** {trial.user_attrs["index"]}
|
||||
- **KL divergence:** {trial.user_attrs["kl_divergence"]:.6f}
|
||||
- **Refusals:** {trial.user_attrs["refusals"]}/{trial.user_attrs["n_bad_prompts"]}
|
||||
|
||||
{system_report}## Environment
|
||||
|
||||
- **Heretic:** v{version_info.version}{f" (Origin: {version_info.origin})" if version_info.origin else ""}
|
||||
- **PyTorch:** {pytorch_version}
|
||||
- **Other dependencies:** See [`requirements.txt`](requirements.txt).
|
||||
|
||||
## Contents of this directory
|
||||
|
||||
- [`requirements.txt`](requirements.txt): The exact versions of all Python packages.
|
||||
- [`config.toml`](config.toml): The exact configuration used, including the RNG seed.
|
||||
- [`{checkpoint_filename}`]({checkpoint_filename}): The Optuna study journal containing the history of all trials.
|
||||
- [`SHA256SUMS`](SHA256SUMS): Cryptographic hashes for all weight files.
|
||||
- [`reproduce.json`](reproduce.json): A machine-readable file containing all reproducibility information.
|
||||
|
||||
## How to reproduce
|
||||
|
||||
> [!TIP]
|
||||
> To use the included Optuna study journal `{checkpoint_filename}`, place it in a `checkpoints/` directory before running `heretic` on the same model.
|
||||
> You can automate this process, including all verification steps, by downloading the `reproduce.json` file and running
|
||||
> `heretic --reproduce reproduce.json`.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Make sure to install correct PyTorch version from: `{install_hint}`
|
||||
{system_instructions}1. Install the exact version of Heretic indicated in the **Environment** section above, from its original source.
|
||||
1. Install the packages listed in `requirements.txt`: `pip install -r requirements.txt`
|
||||
1. Install the correct version of PyTorch: `{pytorch_install_command}`
|
||||
1. Place the provided `config.toml` in your working directory.
|
||||
1. Run Heretic without any additional arguments: `heretic`
|
||||
1. Wait for the run to finish, then select trial **{trial.user_attrs["index"]}** and export the model.
|
||||
1. Verify that the weight files have been exactly reproduced by comparing their SHA-256 hashes against those in `SHA256SUMS`:
|
||||
`sha256sum -c SHA256SUMS` (or look at the hashes online if you uploaded to Hugging Face)
|
||||
|
||||
> [!TIP]
|
||||
> To use the included Optuna study journal `{checkpoint_filename}`, place it in the checkpoints directory (usually `checkpoints/`) before running Heretic.
|
||||
>
|
||||
> This allows you to export other models from the Pareto front, or to run additional trials without having to re-run the stored trials.
|
||||
"""
|
||||
|
||||
|
||||
def generate_reproduce_json(
|
||||
settings: Settings,
|
||||
trial: Trial,
|
||||
timestamp: str | None = None,
|
||||
base_model_commit: str | None = None,
|
||||
uploaded_model_hashes: dict[str, str] | None = None,
|
||||
trial: Trial | FrozenTrial,
|
||||
timestamp: str,
|
||||
uploaded_model_hashes: dict[str, str],
|
||||
include_system_information: bool,
|
||||
) -> str:
|
||||
"""Generates a reproduce.json file for the reproduce/ folder."""
|
||||
"""Generates the contents of a reproduce.json file for the reproduce/ folder."""
|
||||
|
||||
version_info = get_heretic_version_info()
|
||||
|
||||
data = {
|
||||
"base_model": {
|
||||
"id": settings.model,
|
||||
"commit_hash": base_model_commit,
|
||||
},
|
||||
"system": {
|
||||
"os": {"platform": platform.platform(), "machine": platform.machine()},
|
||||
"cpu": get_cpu_info_dict(),
|
||||
"python": get_python_env_info_dict(),
|
||||
"version": "2", # Version number of the reproduce.json file format, to allow for future changes.
|
||||
"timestamp": timestamp,
|
||||
"system": None, # Defined here to preserve insertion order.
|
||||
"environment": {
|
||||
"heretic": {
|
||||
"version": version_info.version,
|
||||
"is_standard_pypi": version_info.is_standard_pypi,
|
||||
"metadata": version_info.metadata,
|
||||
},
|
||||
"pytorch_version": torch.__version__,
|
||||
"accelerator": get_accelerator_info_dict(),
|
||||
"requirements": get_requirements_dict(),
|
||||
},
|
||||
"requirements": get_requirements_dict(),
|
||||
"settings": settings.model_dump(exclude_none=True),
|
||||
"trial": {
|
||||
"direction_index": trial.user_attrs.get("direction_index"),
|
||||
"parameters": trial.user_attrs.get("parameters"),
|
||||
"metrics": {
|
||||
"refusals": trial.user_attrs.get("refusals"),
|
||||
"total_refusal_prompts": trial.user_attrs.get("total_refusal_prompts"),
|
||||
"kl_divergence": trial.user_attrs.get("kl_divergence"),
|
||||
},
|
||||
"settings": settings.model_dump(),
|
||||
"parameters": {
|
||||
"direction_index": trial.user_attrs["direction_index"],
|
||||
"abliteration_parameters": trial.user_attrs["parameters"],
|
||||
},
|
||||
"timestamp": timestamp,
|
||||
"uploaded_model_hashes": uploaded_model_hashes or {},
|
||||
"metrics": {
|
||||
"kl_divergence": trial.user_attrs["kl_divergence"],
|
||||
"refusals": trial.user_attrs["refusals"],
|
||||
"base_refusals": trial.user_attrs["base_refusals"],
|
||||
"n_bad_prompts": trial.user_attrs["n_bad_prompts"],
|
||||
},
|
||||
"hashes": uploaded_model_hashes,
|
||||
}
|
||||
|
||||
if include_system_information:
|
||||
data["system"] = {
|
||||
"python": get_python_env_info_dict(),
|
||||
"os": {
|
||||
"platform": platform.platform(),
|
||||
"machine": platform.machine(),
|
||||
},
|
||||
"cpu": get_cpu_info_dict(),
|
||||
"accelerators": get_accelerator_info_dict(),
|
||||
}
|
||||
else:
|
||||
del data["system"]
|
||||
|
||||
return json.dumps(data, indent=4)
|
||||
|
||||
|
||||
def generate_sha256sums(hashes: dict[str, str]) -> str:
|
||||
"""Generates a GNU Coreutils compatible SHA256SUMS file content."""
|
||||
"""Generates GNU Coreutils compatible SHA256SUMS file content."""
|
||||
|
||||
lines = []
|
||||
|
||||
for filename, sha256 in sorted(hashes.items()):
|
||||
# Use '*' to indicate binary mode for model weights.
|
||||
lines.append(f"{sha256} *{filename}")
|
||||
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
# TODO: Replace this with hashlib.file_digest when we drop support for Python 3.10.
|
||||
def get_file_sha256(file_path: str | Path) -> str:
|
||||
hash = hashlib.sha256()
|
||||
|
||||
with open(file_path, "rb") as file:
|
||||
# Read the file in 64 kB blocks.
|
||||
for block in iter(lambda: file.read(65536), b""):
|
||||
hash.update(block)
|
||||
|
||||
return hash.hexdigest()
|
||||
|
||||
|
||||
def create_reproduce_folder(
|
||||
path: Path,
|
||||
settings: Settings,
|
||||
checkpoint_path: str | Path,
|
||||
trial: Trial,
|
||||
uploaded_model_hashes: dict[str, str] | None = None,
|
||||
) -> None:
|
||||
trial: Trial | FrozenTrial,
|
||||
uploaded_model_hashes: dict[str, str],
|
||||
include_system_information: bool,
|
||||
):
|
||||
reproduce_dir = path / "reproduce"
|
||||
reproduce_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
checkpoint_filename = Path(checkpoint_path).name
|
||||
|
||||
# Fetch commit hash for the base model.
|
||||
settings.model_commit = huggingface_hub.model_info(settings.model).sha
|
||||
|
||||
# Fetch commit hashes for all HF datasets to ensure reproducibility.
|
||||
for spec in [
|
||||
settings.good_prompts,
|
||||
@@ -581,50 +591,46 @@ def create_reproduce_folder(
|
||||
settings.good_evaluation_prompts,
|
||||
settings.bad_evaluation_prompts,
|
||||
]:
|
||||
if not Path(spec.dataset).exists():
|
||||
# Fail if the dataset is missing or unreachable.
|
||||
spec.commit = huggingface_hub.dataset_info(spec.dataset).sha
|
||||
|
||||
# Fetch commit hash for the base model if it's on HF.
|
||||
base_model_commit = None
|
||||
if not Path(settings.model).exists():
|
||||
try:
|
||||
base_model_commit = huggingface_hub.model_info(settings.model).sha
|
||||
except Exception:
|
||||
pass
|
||||
spec.commit = huggingface_hub.dataset_info(spec.dataset).sha
|
||||
|
||||
# Strip microseconds and timezone for a clean format.
|
||||
timestamp = (
|
||||
datetime.now(timezone.utc).replace(microsecond=0, tzinfo=None).isoformat()
|
||||
)
|
||||
|
||||
(reproduce_dir / "config.toml").write_text(
|
||||
generate_config_toml(settings), encoding="utf-8"
|
||||
)
|
||||
(reproduce_dir / "requirements.txt").write_text(
|
||||
generate_requirements_txt(), encoding="utf-8"
|
||||
)
|
||||
(reproduce_dir / "README.md").write_text(
|
||||
generate_reproduce_readme(
|
||||
settings,
|
||||
checkpoint_filename,
|
||||
trial,
|
||||
timestamp=timestamp,
|
||||
base_model_commit=base_model_commit,
|
||||
),
|
||||
generate_requirements_txt(),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
(reproduce_dir / "config.toml").write_text(
|
||||
generate_config_toml(settings),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
if uploaded_model_hashes:
|
||||
(reproduce_dir / "SHA256SUMS").write_text(
|
||||
generate_sha256sums(uploaded_model_hashes), encoding="utf-8"
|
||||
generate_sha256sums(uploaded_model_hashes),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
(reproduce_dir / "reproduce.json").write_text(
|
||||
generate_reproduce_json(
|
||||
settings,
|
||||
trial,
|
||||
timestamp=timestamp,
|
||||
base_model_commit=base_model_commit,
|
||||
uploaded_model_hashes=uploaded_model_hashes,
|
||||
include_system_information=include_system_information,
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
(reproduce_dir / "README.md").write_text(
|
||||
generate_reproduce_readme(
|
||||
settings,
|
||||
checkpoint_filename,
|
||||
trial,
|
||||
include_system_information=include_system_information,
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
@@ -640,23 +646,26 @@ def upload_reproduce_folder(
|
||||
settings: Settings,
|
||||
token: str,
|
||||
checkpoint_path: str | Path,
|
||||
trial: Trial,
|
||||
) -> None:
|
||||
trial: Trial | FrozenTrial,
|
||||
include_system_information: bool,
|
||||
):
|
||||
api = huggingface_hub.HfApi()
|
||||
info = api.model_info(repo_id=repo_id, files_metadata=True, token=token)
|
||||
|
||||
if not info.siblings:
|
||||
raise RuntimeError("Could not fetch uploaded model hashes.")
|
||||
|
||||
# For weights, we only care about safetensors.
|
||||
weight_extensions = (".safetensors",)
|
||||
|
||||
uploaded_model_hashes = {}
|
||||
try:
|
||||
api = huggingface_hub.HfApi()
|
||||
info = api.model_info(repo_id=repo_id, files_metadata=True, token=token)
|
||||
# For weights, we only care about safetensors.
|
||||
weight_extensions = (".safetensors",)
|
||||
if info.siblings is not None:
|
||||
for file in info.siblings:
|
||||
if file.rfilename.endswith(weight_extensions):
|
||||
sha256 = getattr(file, "lfs", {}).get("sha256")
|
||||
if sha256:
|
||||
uploaded_model_hashes[file.rfilename] = sha256
|
||||
except Exception as e:
|
||||
# Fail if integrity checks cannot be completed.
|
||||
raise RuntimeError(f"Could not fetch uploaded model hashes: {e}") from e
|
||||
|
||||
for file in info.siblings:
|
||||
if file.rfilename.endswith(weight_extensions):
|
||||
sha256 = getattr(file, "lfs", {}).get("sha256")
|
||||
if not sha256:
|
||||
raise RuntimeError("Could not fetch uploaded model hashes.")
|
||||
uploaded_model_hashes[file.rfilename] = sha256
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
tmp_path = Path(tmpdir)
|
||||
@@ -666,6 +675,7 @@ def upload_reproduce_folder(
|
||||
checkpoint_path=checkpoint_path,
|
||||
trial=trial,
|
||||
uploaded_model_hashes=uploaded_model_hashes,
|
||||
include_system_information=include_system_information,
|
||||
)
|
||||
|
||||
reproduce_dir = tmp_path / "reproduce"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
Run the tests with
|
||||
|
||||
```sh
|
||||
uv run run_tests.py
|
||||
```
|
||||
|
||||
To update the hashes after a logic change, run the tests, then execute
|
||||
|
||||
```sh
|
||||
cd TEST_DIR/model
|
||||
sha256sum -b * > ../SHA256SUMS.LABEL
|
||||
```
|
||||
|
||||
where `LABEL` describes the type of system you are running the tests on.
|
||||
Since PyTorch does not guarantee exact cross-system reproducibility regardless of configuration,
|
||||
multiple valid hashes can be provided for each output file. The above update must be performed
|
||||
for each `TEST_DIR` and on each type of system.
|
||||
@@ -0,0 +1,7 @@
|
||||
2f1b4d75d067bae3fe44e676721c7f077d243bc007156cb9c2f8b5836613d082 *chat_template.jinja
|
||||
ca80080dfa4ec6ba87152fa2b9afe70b90c400e5c4b1d6bdc3aa3114467ca68f *config.json
|
||||
70070bac883cf9c39b5992450d6b23cd160eaf33099e24c654e0359d2f87c760 *generation_config.json
|
||||
f3f4ec19504f182486459cf4e255ece265c25f827840d63b6a9d4058b8e4877a *model.safetensors
|
||||
32bdf45d2ad4cc29a0822ddd157a182de76644f0419a6228d151495256e9813c *processor_config.json
|
||||
cc8d3a0ce36466ccc1278bf987df5f71db1719b9ca6b4118264f45cb627bfe0f *tokenizer.json
|
||||
a1bab8c81ed15fa6ce912ec993c66cb49392e0487fb1ea5f5f11ea3618683627 *tokenizer_config.json
|
||||
@@ -0,0 +1,7 @@
|
||||
2f1b4d75d067bae3fe44e676721c7f077d243bc007156cb9c2f8b5836613d082 *chat_template.jinja
|
||||
ca80080dfa4ec6ba87152fa2b9afe70b90c400e5c4b1d6bdc3aa3114467ca68f *config.json
|
||||
70070bac883cf9c39b5992450d6b23cd160eaf33099e24c654e0359d2f87c760 *generation_config.json
|
||||
53c4ee891dce23c0ac85bebc2c4d48301469750fafbb3e6e024c15786d94db8b *model.safetensors
|
||||
32bdf45d2ad4cc29a0822ddd157a182de76644f0419a6228d151495256e9813c *processor_config.json
|
||||
cc8d3a0ce36466ccc1278bf987df5f71db1719b9ca6b4118264f45cb627bfe0f *tokenizer.json
|
||||
a1bab8c81ed15fa6ce912ec993c66cb49392e0487fb1ea5f5f11ea3618683627 *tokenizer_config.json
|
||||
@@ -0,0 +1,7 @@
|
||||
2f1b4d75d067bae3fe44e676721c7f077d243bc007156cb9c2f8b5836613d082 *chat_template.jinja
|
||||
ca80080dfa4ec6ba87152fa2b9afe70b90c400e5c4b1d6bdc3aa3114467ca68f *config.json
|
||||
70070bac883cf9c39b5992450d6b23cd160eaf33099e24c654e0359d2f87c760 *generation_config.json
|
||||
effe36925f85ecb1e29bba84501a456bb49df21e4047be8b7ea3f6f88181fb65 *model.safetensors
|
||||
32bdf45d2ad4cc29a0822ddd157a182de76644f0419a6228d151495256e9813c *processor_config.json
|
||||
cc8d3a0ce36466ccc1278bf987df5f71db1719b9ca6b4118264f45cb627bfe0f *tokenizer.json
|
||||
a1bab8c81ed15fa6ce912ec993c66cb49392e0487fb1ea5f5f11ea3618683627 *tokenizer_config.json
|
||||
@@ -0,0 +1,7 @@
|
||||
b16d3228a775c549ba97af41233a54e9de8dd2b65250f78346661d18b936a8b5 *chat_template.jinja
|
||||
0094ad598a8043f84d82ad5c886547bca1d1d7f302d82f1491f83d388e89acd4 *config.json
|
||||
1a019c5d688d54cf01318eab88cb4345dfa52135eb1d83c2f54125469eb88d5c *generation_config.json
|
||||
effe36925f85ecb1e29bba84501a456bb49df21e4047be8b7ea3f6f88181fb65 *model.safetensors
|
||||
24d00232e58cfa179fe8b3911c788d4aad9a6279d778ebe4c72e82623b6197f9 *processor_config.json
|
||||
cc8d3a0ce36466ccc1278bf987df5f71db1719b9ca6b4118264f45cb627bfe0f *tokenizer.json
|
||||
8044bbbddaee8dc47e6b5660e013ba92224d4a5392b2939c59699aa0105f5c8b *tokenizer_config.json
|
||||
@@ -0,0 +1,41 @@
|
||||
model = "tiny-random/gemma-4e"
|
||||
model_commit = "3a207ada2c2cd95e9671942e84cf47ea58f0f6af"
|
||||
|
||||
seed = 12345
|
||||
print_debug_information = true
|
||||
|
||||
batch_size = 2
|
||||
max_response_length = 10
|
||||
kl_divergence_target = 0
|
||||
n_trials = 2
|
||||
n_startup_trials = 1
|
||||
|
||||
export_strategy = "merge"
|
||||
checkpoint_action = "restart"
|
||||
trial_index = 0
|
||||
model_action = "save"
|
||||
save_directory = "model"
|
||||
|
||||
[good_prompts]
|
||||
dataset = "mlabonne/harmless_alpaca"
|
||||
commit = "02c6a92cfcf11bb0c387334f8146d149d65b587f"
|
||||
split = "train[:5]"
|
||||
column = "text"
|
||||
|
||||
[bad_prompts]
|
||||
dataset = "mlabonne/harmful_behaviors"
|
||||
commit = "01cead01398926d81f7c52bdb790ee8cf77ebba7"
|
||||
split = "train[:5]"
|
||||
column = "text"
|
||||
|
||||
[good_evaluation_prompts]
|
||||
dataset = "mlabonne/harmless_alpaca"
|
||||
commit = "02c6a92cfcf11bb0c387334f8146d149d65b587f"
|
||||
split = "test[:5]"
|
||||
column = "text"
|
||||
|
||||
[bad_evaluation_prompts]
|
||||
dataset = "mlabonne/harmful_behaviors"
|
||||
commit = "01cead01398926d81f7c52bdb790ee8cf77ebba7"
|
||||
split = "test[:5]"
|
||||
column = "text"
|
||||
@@ -0,0 +1,7 @@
|
||||
39f03c383413f531fd302c06c7e982ad98c83f0657a8339ae25478ccb81fdcda *chat_template.jinja
|
||||
f69f84977a47c8fea9ce9fc26b7de379216cb01146ea726a87996d3554cfcd19 *config.json
|
||||
34dfa6012ca9ac5f57e5521d8dbaecbc7ab7f7ab0fd96ec020b543aab5f265d9 *generation_config.json
|
||||
876c6691eb85e3e5e11771e589529830fb454ab26344e1271ae550661e312b50 *model.safetensors
|
||||
84be30b124b50749c56d25fdbec5ccedf564446f6b3b035e88e1e07b986d2491 *processor_config.json
|
||||
c3a8d92e371b92a2cd6e678e31ebc27d0235e929a51fbf290f74742b341fa96f *tokenizer.json
|
||||
7b29c843c0043622d28fd4638451cbb0a609d99a0762ffbff3b92b4b2fee4d94 *tokenizer_config.json
|
||||
@@ -0,0 +1,7 @@
|
||||
39f03c383413f531fd302c06c7e982ad98c83f0657a8339ae25478ccb81fdcda *chat_template.jinja
|
||||
f69f84977a47c8fea9ce9fc26b7de379216cb01146ea726a87996d3554cfcd19 *config.json
|
||||
34dfa6012ca9ac5f57e5521d8dbaecbc7ab7f7ab0fd96ec020b543aab5f265d9 *generation_config.json
|
||||
6febb813086f253e5ec0fcda02fdfc849c551a7dba54681b37ac5bc402e4eed6 *model.safetensors
|
||||
84be30b124b50749c56d25fdbec5ccedf564446f6b3b035e88e1e07b986d2491 *processor_config.json
|
||||
c3a8d92e371b92a2cd6e678e31ebc27d0235e929a51fbf290f74742b341fa96f *tokenizer.json
|
||||
7b29c843c0043622d28fd4638451cbb0a609d99a0762ffbff3b92b4b2fee4d94 *tokenizer_config.json
|
||||
@@ -0,0 +1,7 @@
|
||||
39f03c383413f531fd302c06c7e982ad98c83f0657a8339ae25478ccb81fdcda *chat_template.jinja
|
||||
f69f84977a47c8fea9ce9fc26b7de379216cb01146ea726a87996d3554cfcd19 *config.json
|
||||
34dfa6012ca9ac5f57e5521d8dbaecbc7ab7f7ab0fd96ec020b543aab5f265d9 *generation_config.json
|
||||
29aff97d5633dead9e1ccd29a2cc153b4b7431d22f63c8d6cf60bc6547681cc9 *model.safetensors
|
||||
84be30b124b50749c56d25fdbec5ccedf564446f6b3b035e88e1e07b986d2491 *processor_config.json
|
||||
c3a8d92e371b92a2cd6e678e31ebc27d0235e929a51fbf290f74742b341fa96f *tokenizer.json
|
||||
7b29c843c0043622d28fd4638451cbb0a609d99a0762ffbff3b92b4b2fee4d94 *tokenizer_config.json
|
||||
@@ -0,0 +1,7 @@
|
||||
72f84af4ea36b82409c35e31b584361534305ef7c0d90fce20d0dc38a7efead8 *chat_template.jinja
|
||||
e4c5278b361c57621253c27a2c3db358e1580aec8a14be8e19d4420a224137cf *config.json
|
||||
8dde85c000ae807be907421465826c7c63a39f6acf6d04a5a84efaf116ed4ef7 *generation_config.json
|
||||
29aff97d5633dead9e1ccd29a2cc153b4b7431d22f63c8d6cf60bc6547681cc9 *model.safetensors
|
||||
20e7a6dcde0a6f60ea3b4fb08f6f7afa62532dda93a3111e28384ba5150575f9 *processor_config.json
|
||||
c3a8d92e371b92a2cd6e678e31ebc27d0235e929a51fbf290f74742b341fa96f *tokenizer.json
|
||||
60a8042e29b4b20e884e48375aa1b9ac0025547371d50e60f6d55e6a9675e868 *tokenizer_config.json
|
||||
@@ -0,0 +1,41 @@
|
||||
model = "tiny-random/mistral-3"
|
||||
model_commit = "931aa2e5c9668fc3679e56aa44972fe18597d55d"
|
||||
|
||||
seed = 12345
|
||||
print_debug_information = true
|
||||
|
||||
batch_size = 2
|
||||
max_response_length = 10
|
||||
kl_divergence_target = 0
|
||||
n_trials = 2
|
||||
n_startup_trials = 1
|
||||
|
||||
export_strategy = "merge"
|
||||
checkpoint_action = "restart"
|
||||
trial_index = 0
|
||||
model_action = "save"
|
||||
save_directory = "model"
|
||||
|
||||
[good_prompts]
|
||||
dataset = "mlabonne/harmless_alpaca"
|
||||
commit = "02c6a92cfcf11bb0c387334f8146d149d65b587f"
|
||||
split = "train[:5]"
|
||||
column = "text"
|
||||
|
||||
[bad_prompts]
|
||||
dataset = "mlabonne/harmful_behaviors"
|
||||
commit = "01cead01398926d81f7c52bdb790ee8cf77ebba7"
|
||||
split = "train[:5]"
|
||||
column = "text"
|
||||
|
||||
[good_evaluation_prompts]
|
||||
dataset = "mlabonne/harmless_alpaca"
|
||||
commit = "02c6a92cfcf11bb0c387334f8146d149d65b587f"
|
||||
split = "test[:5]"
|
||||
column = "text"
|
||||
|
||||
[bad_evaluation_prompts]
|
||||
dataset = "mlabonne/harmful_behaviors"
|
||||
commit = "01cead01398926d81f7c52bdb790ee8cf77ebba7"
|
||||
split = "test[:5]"
|
||||
column = "text"
|
||||
@@ -0,0 +1,7 @@
|
||||
a4aee8afcf2e0711942cf848899be66016f8d14a889ff9ede07bca099c28f715 *chat_template.jinja
|
||||
749b56d1b1e08081981169db6f2c44ab0be4fd6ebb452d15baafa5e09c21586a *config.json
|
||||
4625d1d64d41d1fa9dae7af4ba1e1d7e65a194073d4efa58acb266a916eaaa74 *generation_config.json
|
||||
5fb94c65bcd9d736735a45e50c2b0bfafd3bb09a444c49b8cff2e131ed35797e *model.safetensors
|
||||
01562eddd6f9e9ec4bc31656a3b7055284cafbf889acc6c4348dca431ae31f68 *processor_config.json
|
||||
87a7830d63fcf43bf241c3c5242e96e62dd3fdc29224ca26fed8ea333db72de4 *tokenizer.json
|
||||
2e31d1126e81bddf8d15c3f95260fb487b48c5131b24fcbb5bb9d2537e7afac0 *tokenizer_config.json
|
||||
@@ -0,0 +1,7 @@
|
||||
a4aee8afcf2e0711942cf848899be66016f8d14a889ff9ede07bca099c28f715 *chat_template.jinja
|
||||
749b56d1b1e08081981169db6f2c44ab0be4fd6ebb452d15baafa5e09c21586a *config.json
|
||||
4625d1d64d41d1fa9dae7af4ba1e1d7e65a194073d4efa58acb266a916eaaa74 *generation_config.json
|
||||
5e0fb0ac724cf079b693fc76a515e60bc16de72c32b36c107b9f078061c4f2ef *model.safetensors
|
||||
01562eddd6f9e9ec4bc31656a3b7055284cafbf889acc6c4348dca431ae31f68 *processor_config.json
|
||||
87a7830d63fcf43bf241c3c5242e96e62dd3fdc29224ca26fed8ea333db72de4 *tokenizer.json
|
||||
2e31d1126e81bddf8d15c3f95260fb487b48c5131b24fcbb5bb9d2537e7afac0 *tokenizer_config.json
|
||||
@@ -0,0 +1,7 @@
|
||||
a92e1dd97cb1cb175c9b70c0828e146bea4371c2643319b661b777e89811972e *chat_template.jinja
|
||||
b75e911805663da79fb9fbbbcc917b8f1a285d2da54d95c2c63ea7c1ffe9a05a *config.json
|
||||
2cbd9df0e99570efcced23b8d777bdf1fc692efda54b21eb59ad56ade76c9db6 *generation_config.json
|
||||
5f099b32807d0b84ed90765ca0ed53f8771da4738767bc1940486fec954570cf *model.safetensors
|
||||
0c29f9491e769aabbc389ad5912127cf6d9d5fceda2db8767f73d48131348c81 *processor_config.json
|
||||
87a7830d63fcf43bf241c3c5242e96e62dd3fdc29224ca26fed8ea333db72de4 *tokenizer.json
|
||||
4796e48d790a26d65f167bec8fc742beaa71f79f9468a6cd8b3ffa97f6e2a198 *tokenizer_config.json
|
||||
@@ -0,0 +1,41 @@
|
||||
model = "tiny-random/qwen3.5-moe"
|
||||
model_commit = "2ebfa8d9717238c5dda927008104fa172a149050"
|
||||
|
||||
seed = 12345
|
||||
print_debug_information = true
|
||||
|
||||
batch_size = 2
|
||||
max_response_length = 10
|
||||
kl_divergence_target = 0
|
||||
n_trials = 2
|
||||
n_startup_trials = 1
|
||||
|
||||
export_strategy = "merge"
|
||||
checkpoint_action = "restart"
|
||||
trial_index = 0
|
||||
model_action = "save"
|
||||
save_directory = "model"
|
||||
|
||||
[good_prompts]
|
||||
dataset = "mlabonne/harmless_alpaca"
|
||||
commit = "02c6a92cfcf11bb0c387334f8146d149d65b587f"
|
||||
split = "train[:5]"
|
||||
column = "text"
|
||||
|
||||
[bad_prompts]
|
||||
dataset = "mlabonne/harmful_behaviors"
|
||||
commit = "01cead01398926d81f7c52bdb790ee8cf77ebba7"
|
||||
split = "train[:5]"
|
||||
column = "text"
|
||||
|
||||
[good_evaluation_prompts]
|
||||
dataset = "mlabonne/harmless_alpaca"
|
||||
commit = "02c6a92cfcf11bb0c387334f8146d149d65b587f"
|
||||
split = "test[:5]"
|
||||
column = "text"
|
||||
|
||||
[bad_evaluation_prompts]
|
||||
dataset = "mlabonne/harmful_behaviors"
|
||||
commit = "01cead01398926d81f7c52bdb790ee8cf77ebba7"
|
||||
split = "test[:5]"
|
||||
column = "text"
|
||||
@@ -0,0 +1,87 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# Copyright (C) 2025-2026 Philipp Emanuel Weidmann <pew@worldwidemann.com> + contributors
|
||||
|
||||
import hashlib
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
# TODO: Replace this with hashlib.file_digest when we drop support for Python 3.10.
|
||||
def get_file_sha256(file_path: str | Path) -> str:
|
||||
hash = hashlib.sha256()
|
||||
|
||||
with open(file_path, "rb") as file:
|
||||
# Read the file in 64 kB blocks.
|
||||
for block in iter(lambda: file.read(65536), b""):
|
||||
hash.update(block)
|
||||
|
||||
return hash.hexdigest()
|
||||
|
||||
|
||||
script_directory = Path(__file__).resolve().parent
|
||||
|
||||
project_directory = script_directory.parent
|
||||
|
||||
tests_failed = False
|
||||
|
||||
for test_directory in script_directory.iterdir():
|
||||
if test_directory.is_dir():
|
||||
config_file = test_directory / "config.toml"
|
||||
hash_files = list(test_directory.glob("SHA256SUMS.*"))
|
||||
|
||||
if config_file.is_file() and hash_files:
|
||||
print("#" * 50)
|
||||
print(f"Running test {test_directory.name}")
|
||||
print("#" * 50)
|
||||
print()
|
||||
|
||||
subprocess.run(
|
||||
[
|
||||
"uv",
|
||||
"run",
|
||||
"--project",
|
||||
project_directory,
|
||||
"--directory",
|
||||
test_directory,
|
||||
"heretic",
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
|
||||
print()
|
||||
|
||||
valid_hashes: dict[str, list[str]] = {}
|
||||
|
||||
for hash_file in hash_files:
|
||||
with open(hash_file, "r", encoding="utf-8") as file:
|
||||
for line in file:
|
||||
if line.strip():
|
||||
sha256, filename = line.split()
|
||||
filename = filename.removeprefix("*")
|
||||
|
||||
if filename not in valid_hashes:
|
||||
valid_hashes[filename] = []
|
||||
|
||||
valid_hashes[filename].append(sha256.lower())
|
||||
|
||||
for filename in valid_hashes:
|
||||
sha256 = get_file_sha256(test_directory / "model" / filename)
|
||||
|
||||
if sha256.lower() not in valid_hashes[filename]:
|
||||
print(
|
||||
(
|
||||
f"Test {test_directory.name} has FAILED!\n"
|
||||
f"Output file {filename} doesn't match any valid hash.\n\n"
|
||||
f"Valid hashes:\n"
|
||||
f"{chr(10).join(valid_hashes[filename])}\n\n"
|
||||
f"Actual hash:\n"
|
||||
f"{sha256}\n"
|
||||
)
|
||||
)
|
||||
tests_failed = True
|
||||
|
||||
if tests_failed:
|
||||
sys.exit("Tests failed.")
|
||||
else:
|
||||
print("All tests passed.")
|
||||
@@ -8,7 +8,7 @@ resolution-markers = [
|
||||
]
|
||||
|
||||
[options]
|
||||
exclude-newer = "2026-04-14T22:48:57.86057843Z"
|
||||
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
|
||||
exclude-newer-span = "P7D"
|
||||
|
||||
[[package]]
|
||||
@@ -50,7 +50,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "aiohttp"
|
||||
version = "3.13.4"
|
||||
version = "3.14.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "aiohappyeyeballs" },
|
||||
@@ -60,112 +60,129 @@ dependencies = [
|
||||
{ name = "frozenlist" },
|
||||
{ name = "multidict" },
|
||||
{ name = "propcache" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
||||
{ name = "yarl" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/45/4a/064321452809dae953c1ed6e017504e72551a26b6f5708a5a80e4bf556ff/aiohttp-3.13.4.tar.gz", hash = "sha256:d97a6d09c66087890c2ab5d49069e1e570583f7ac0314ecf98294c1b6aaebd38", size = 7859748, upload-time = "2026-03-28T17:19:40.6Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/82/78/8ea7308cac6934de8c74a14f3d5f65d1c89287426688be79538d0e5c013d/aiohttp-3.14.1.tar.gz", hash = "sha256:307f2cff90a764d329e77040603fa032db89c5c24fdad50c4c15334cba744035", size = 7955794, upload-time = "2026-06-07T21:09:35.529Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/05/6817e0390eb47b0867cf8efdb535298191662192281bc3ca62a0cb7973eb/aiohttp-3.13.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6290fe12fe8cefa6ea3c1c5b969d32c010dfe191d4392ff9b599a3f473cbe722", size = 753094, upload-time = "2026-03-28T17:14:59.928Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/c1/e5b7f25f6dd1ab57da92aa9d226b2c8b56f223dd20475d3ddfddaba86ab8/aiohttp-3.13.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7520d92c0e8fbbe63f36f20a5762db349ff574ad38ad7bc7732558a650439845", size = 505213, upload-time = "2026-03-28T17:15:01.989Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/e5/8f42033c7ce98b54dfd3791f03e60231cfe4a2db4471b5fc188df2b8a6ad/aiohttp-3.13.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2710ae1e1b81d0f187883b6e9d66cecf8794b50e91aa1e73fc78bfb5503b5d9", size = 498580, upload-time = "2026-03-28T17:15:03.879Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/a4/bbc989f5362066b81930da1a66084a859a971d03faab799dc59a3ce3a220/aiohttp-3.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:717d17347567ded1e273aa09918650dfd6fd06f461549204570c7973537d4123", size = 1692718, upload-time = "2026-03-28T17:15:05.541Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/72/3775116969931f151be116689d2ae6ddafff2ec2887d8f9b4e7043f32e74/aiohttp-3.13.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:383880f7b8de5ac208fa829c7038d08e66377283b2de9e791b71e06e803153c2", size = 1660714, upload-time = "2026-03-28T17:15:08.23Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/e8/d2f1a2da2743e32fe348ebf8a4c59caad14a92f5f18af616fd33381275e1/aiohttp-3.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1867087e2c1963db1216aedf001efe3b129835ed2b05d97d058176a6d08b5726", size = 1744152, upload-time = "2026-03-28T17:15:10.828Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/a6/575886f417ac3c08e462f2ca237cc49f436bd992ca3f7ff95b7dd9c44205/aiohttp-3.13.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6234bf416a38d687c3ab7f79934d7fb2a42117a5b9813aca07de0a5398489023", size = 1836278, upload-time = "2026-03-28T17:15:12.537Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4a/4c/0051d4550fb9e8b5ca4e0fe1ccd58652340915180c5164999e6741bf2083/aiohttp-3.13.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3cdd3393130bf6588962441ffd5bde1d3ea2d63a64afa7119b3f3ba349cebbe7", size = 1687953, upload-time = "2026-03-28T17:15:14.248Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/54/841e87b8c51c2adc01a3ceb9919dc45c7899fe4c21deb70aada734ea5a38/aiohttp-3.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0d0dbc6c76befa76865373d6aa303e480bb8c3486e7763530f7f6e527b471118", size = 1572484, upload-time = "2026-03-28T17:15:15.911Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/f1/21cbf5f7fa1e267af6301f886cab9b314f085e4d0097668d189d165cd7da/aiohttp-3.13.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:10fb7b53262cf4144a083c9db0d2b4d22823d6708270a9970c4627b248c6064c", size = 1662851, upload-time = "2026-03-28T17:15:17.822Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/15/bcad6b68d7bef27ae7443288215767263c7753ede164267cf6cf63c94a87/aiohttp-3.13.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:eb10ce8c03850e77f4d9518961c227be569e12f71525a7e90d17bca04299921d", size = 1671984, upload-time = "2026-03-28T17:15:19.561Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/fa/ab316931afc7a73c7f493bb1b30fbd61e28ec2d3ea50353336e76293e8ec/aiohttp-3.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:7c65738ac5ae32b8feef699a4ed0dc91a0c8618b347781b7461458bbcaaac7eb", size = 1713880, upload-time = "2026-03-28T17:15:21.589Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/45/314e8e64c7f328174964b6db511dd5e9e60c9121ab5457bc2c908b7d03a4/aiohttp-3.13.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:6b335919ffbaf98df8ff3c74f7a6decb8775882632952fd1810a017e38f15aee", size = 1560315, upload-time = "2026-03-28T17:15:23.66Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/e7/93d5fa06fe00219a81466577dacae9e3732f3b4f767b12b2e2cc8c35c970/aiohttp-3.13.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ec75fc18cb9f4aca51c2cbace20cf6716e36850f44189644d2d69a875d5e0532", size = 1735115, upload-time = "2026-03-28T17:15:25.77Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/9f/f64b95392ddd4e204fd9ab7cd33dd18d14ac9e4b86866f1f6a69b7cda83d/aiohttp-3.13.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:463fa18a95c5a635d2b8c09babe240f9d7dbf2a2010a6c0b35d8c4dff2a0e819", size = 1673916, upload-time = "2026-03-28T17:15:27.526Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/c1/bb33be79fd285c69f32e5b074b299cae8847f748950149c3965c1b3b3adf/aiohttp-3.13.4-cp310-cp310-win32.whl", hash = "sha256:13168f5645d9045522c6cef818f54295376257ed8d02513a37c2ef3046fc7a97", size = 440277, upload-time = "2026-03-28T17:15:29.173Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/f9/7cf1688da4dd0885f914ee40bc8e1dce776df98fe6518766de975a570538/aiohttp-3.13.4-cp310-cp310-win_amd64.whl", hash = "sha256:a7058af1f53209fdf07745579ced525d38d481650a989b7aa4a3b484b901cdab", size = 463015, upload-time = "2026-03-28T17:15:30.802Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/7e/cb94129302d78c46662b47f9897d642fd0b33bdfef4b73b20c6ced35aa4c/aiohttp-3.13.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8ea0c64d1bcbf201b285c2246c51a0c035ba3bbd306640007bc5844a3b4658c1", size = 760027, upload-time = "2026-03-28T17:15:33.022Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/cd/2db3c9397c3bd24216b203dd739945b04f8b87bb036c640da7ddb63c75ef/aiohttp-3.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6f742e1fa45c0ed522b00ede565e18f97e4cf8d1883a712ac42d0339dfb0cce7", size = 508325, upload-time = "2026-03-28T17:15:34.714Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/a3/d28b2722ec13107f2e37a86b8a169897308bab6a3b9e071ecead9d67bd9b/aiohttp-3.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dcfb50ee25b3b7a1222a9123be1f9f89e56e67636b561441f0b304e25aaef8f", size = 502402, upload-time = "2026-03-28T17:15:36.409Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/d6/acd47b5f17c4430e555590990a4746efbcb2079909bb865516892bf85f37/aiohttp-3.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3262386c4ff370849863ea93b9ea60fd59c6cf56bf8f93beac625cf4d677c04d", size = 1771224, upload-time = "2026-03-28T17:15:38.223Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/af/af6e20113ba6a48fd1cd9e5832c4851e7613ef50c7619acdaee6ec5f1aff/aiohttp-3.13.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:473bb5aa4218dd254e9ae4834f20e31f5a0083064ac0136a01a62ddbae2eaa42", size = 1731530, upload-time = "2026-03-28T17:15:39.988Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/16/78a2f5d9c124ad05d5ce59a9af94214b6466c3491a25fb70760e98e9f762/aiohttp-3.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e56423766399b4c77b965f6aaab6c9546617b8994a956821cc507d00b91d978c", size = 1827925, upload-time = "2026-03-28T17:15:41.944Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/1f/79acf0974ced805e0e70027389fccbb7d728e6f30fcac725fb1071e63075/aiohttp-3.13.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8af249343fafd5ad90366a16d230fc265cf1149f26075dc9fe93cfd7c7173942", size = 1923579, upload-time = "2026-03-28T17:15:44.071Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/53/29f9e2054ea6900413f3b4c3eb9d8331f60678ec855f13ba8714c47fd48d/aiohttp-3.13.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bc0a5cf4f10ef5a2c94fdde488734b582a3a7a000b131263e27c9295bd682d9", size = 1767655, upload-time = "2026-03-28T17:15:45.911Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/57/462fe1d3da08109ba4aa8590e7aed57c059af2a7e80ec21f4bac5cfe1094/aiohttp-3.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5c7ff1028e3c9fc5123a865ce17df1cb6424d180c503b8517afbe89aa566e6be", size = 1630439, upload-time = "2026-03-28T17:15:48.11Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/4b/4813344aacdb8127263e3eec343d24e973421143826364fa9fc847f6283f/aiohttp-3.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ba5cf98b5dcb9bddd857da6713a503fa6d341043258ca823f0f5ab7ab4a94ee8", size = 1745557, upload-time = "2026-03-28T17:15:50.13Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/01/1ef1adae1454341ec50a789f03cfafe4c4ac9c003f6a64515ecd32fe4210/aiohttp-3.13.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d85965d3ba21ee4999e83e992fecb86c4614d6920e40705501c0a1f80a583c12", size = 1741796, upload-time = "2026-03-28T17:15:52.351Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/04/8cdd99af988d2aa6922714d957d21383c559835cbd43fbf5a47ddf2e0f05/aiohttp-3.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:49f0b18a9b05d79f6f37ddd567695943fcefb834ef480f17a4211987302b2dc7", size = 1805312, upload-time = "2026-03-28T17:15:54.407Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/7f/b48d5577338d4b25bbdbae35c75dbfd0493cb8886dc586fbfb2e90862239/aiohttp-3.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7f78cb080c86fbf765920e5f1ef35af3f24ec4314d6675d0a21eaf41f6f2679c", size = 1621751, upload-time = "2026-03-28T17:15:56.564Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/89/4eecad8c1858e6d0893c05929e22343e0ebe3aec29a8a399c65c3cc38311/aiohttp-3.13.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:67a3ec705534a614b68bbf1c70efa777a21c3da3895d1c44510a41f5a7ae0453", size = 1826073, upload-time = "2026-03-28T17:15:58.489Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/5c/9dc8293ed31b46c39c9c513ac7ca152b3c3d38e0ea111a530ad12001b827/aiohttp-3.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d6630ec917e85c5356b2295744c8a97d40f007f96a1c76bf1928dc2e27465393", size = 1760083, upload-time = "2026-03-28T17:16:00.677Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/19/8bbf6a4994205d96831f97b7d21a0feed120136e6267b5b22d229c6dc4dc/aiohttp-3.13.4-cp311-cp311-win32.whl", hash = "sha256:54049021bc626f53a5394c29e8c444f726ee5a14b6e89e0ad118315b1f90f5e3", size = 439690, upload-time = "2026-03-28T17:16:02.902Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/f5/ac409ecd1007528d15c3e8c3a57d34f334c70d76cfb7128a28cffdebd4c1/aiohttp-3.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:c033f2bc964156030772d31cbf7e5defea181238ce1f87b9455b786de7d30145", size = 463824, upload-time = "2026-03-28T17:16:05.058Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/bd/ede278648914cabbabfdf95e436679b5d4156e417896a9b9f4587169e376/aiohttp-3.13.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ee62d4471ce86b108b19c3364db4b91180d13fe3510144872d6bad5401957360", size = 752158, upload-time = "2026-03-28T17:16:06.901Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/de/581c053253c07b480b03785196ca5335e3c606a37dc73e95f6527f1591fe/aiohttp-3.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c0fd8f41b54b58636402eb493afd512c23580456f022c1ba2db0f810c959ed0d", size = 501037, upload-time = "2026-03-28T17:16:08.82Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/f9/a5ede193c08f13cc42c0a5b50d1e246ecee9115e4cf6e900d8dbd8fd6acb/aiohttp-3.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4baa48ce49efd82d6b1a0be12d6a36b35e5594d1dd42f8bfba96ea9f8678b88c", size = 501556, upload-time = "2026-03-28T17:16:10.63Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/10/88ff67cd48a6ec36335b63a640abe86135791544863e0cfe1f065d6cef7a/aiohttp-3.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d738ebab9f71ee652d9dbd0211057690022201b11197f9a7324fd4dba128aa97", size = 1757314, upload-time = "2026-03-28T17:16:12.498Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/15/fdb90a5cf5a1f52845c276e76298c75fbbcc0ac2b4a86551906d54529965/aiohttp-3.13.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0ce692c3468fa831af7dceed52edf51ac348cebfc8d3feb935927b63bd3e8576", size = 1731819, upload-time = "2026-03-28T17:16:14.558Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/df/28146785a007f7820416be05d4f28cc207493efd1e8c6c1068e9bdc29198/aiohttp-3.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8e08abcfe752a454d2cb89ff0c08f2d1ecd057ae3e8cc6d84638de853530ebab", size = 1793279, upload-time = "2026-03-28T17:16:16.594Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/47/689c743abf62ea7a77774d5722f220e2c912a77d65d368b884d9779ef41b/aiohttp-3.13.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5977f701b3fff36367a11087f30ea73c212e686d41cd363c50c022d48b011d8d", size = 1891082, upload-time = "2026-03-28T17:16:18.71Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/b6/f7f4f318c7e58c23b761c9b13b9a3c9b394e0f9d5d76fbc6622fa98509f6/aiohttp-3.13.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:54203e10405c06f8b6020bd1e076ae0fe6c194adcee12a5a78af3ffa3c57025e", size = 1773938, upload-time = "2026-03-28T17:16:21.125Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/06/f207cb3121852c989586a6fc16ff854c4fcc8651b86c5d3bd1fc83057650/aiohttp-3.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:358a6af0145bc4dda037f13167bef3cce54b132087acc4c295c739d05d16b1c3", size = 1579548, upload-time = "2026-03-28T17:16:23.588Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/58/e1289661a32161e24c1fe479711d783067210d266842523752869cc1d9c2/aiohttp-3.13.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:898ea1850656d7d61832ef06aa9846ab3ddb1621b74f46de78fbc5e1a586ba83", size = 1714669, upload-time = "2026-03-28T17:16:25.713Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/0a/3e86d039438a74a86e6a948a9119b22540bae037d6ba317a042ae3c22711/aiohttp-3.13.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7bc30cceb710cf6a44e9617e43eebb6e3e43ad855a34da7b4b6a73537d8a6763", size = 1754175, upload-time = "2026-03-28T17:16:28.18Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/30/e717fc5df83133ba467a560b6d8ef20197037b4bb5d7075b90037de1018e/aiohttp-3.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4a31c0c587a8a038f19a4c7e60654a6c899c9de9174593a13e7cc6e15ff271f9", size = 1762049, upload-time = "2026-03-28T17:16:30.941Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/28/8f7a2d4492e336e40005151bdd94baf344880a4707573378579f833a64c1/aiohttp-3.13.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2062f675f3fe6e06d6113eb74a157fb9df58953ffed0cdb4182554b116545758", size = 1570861, upload-time = "2026-03-28T17:16:32.953Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/45/12e1a3d0645968b1c38de4b23fdf270b8637735ea057d4f84482ff918ad9/aiohttp-3.13.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3d1ba8afb847ff80626d5e408c1fdc99f942acc877d0702fe137015903a220a9", size = 1790003, upload-time = "2026-03-28T17:16:35.468Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/0f/60374e18d590de16dcb39d6ff62f39c096c1b958e6f37727b5870026ea30/aiohttp-3.13.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b08149419994cdd4d5eecf7fd4bc5986b5a9380285bcd01ab4c0d6bfca47b79d", size = 1737289, upload-time = "2026-03-28T17:16:38.187Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/bf/535e58d886cfbc40a8b0013c974afad24ef7632d645bca0b678b70033a60/aiohttp-3.13.4-cp312-cp312-win32.whl", hash = "sha256:fc432f6a2c4f720180959bc19aa37259651c1a4ed8af8afc84dd41c60f15f791", size = 434185, upload-time = "2026-03-28T17:16:40.735Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/1a/d92e3325134ebfff6f4069f270d3aac770d63320bd1fcd0eca023e74d9a8/aiohttp-3.13.4-cp312-cp312-win_amd64.whl", hash = "sha256:6148c9ae97a3e8bff9a1fc9c757fa164116f86c100468339730e717590a3fb77", size = 461285, upload-time = "2026-03-28T17:16:42.713Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/ac/892f4162df9b115b4758d615f32ec63d00f3084c705ff5526630887b9b42/aiohttp-3.13.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:63dd5e5b1e43b8fb1e91b79b7ceba1feba588b317d1edff385084fcc7a0a4538", size = 745744, upload-time = "2026-03-28T17:16:44.67Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/a9/c5b87e4443a2f0ea88cb3000c93a8fdad1ee63bffc9ded8d8c8e0d66efc6/aiohttp-3.13.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:746ac3cc00b5baea424dacddea3ec2c2702f9590de27d837aa67004db1eebc6e", size = 498178, upload-time = "2026-03-28T17:16:46.766Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/42/07e1b543a61250783650df13da8ddcdc0d0a5538b2bd15cef6e042aefc61/aiohttp-3.13.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bda8f16ea99d6a6705e5946732e48487a448be874e54a4f73d514660ff7c05d3", size = 498331, upload-time = "2026-03-28T17:16:48.9Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/d6/492f46bf0328534124772d0cf58570acae5b286ea25006900650f69dae0e/aiohttp-3.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b061e7b5f840391e3f64d0ddf672973e45c4cfff7a0feea425ea24e51530fc2", size = 1744414, upload-time = "2026-03-28T17:16:50.968Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/4d/e02627b2683f68051246215d2d62b2d2f249ff7a285e7a858dc47d6b6a14/aiohttp-3.13.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b252e8d5cd66184b570d0d010de742736e8a4fab22c58299772b0c5a466d4b21", size = 1719226, upload-time = "2026-03-28T17:16:53.173Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/6c/5d0a3394dd2b9f9aeba6e1b6065d0439e4b75d41f1fb09a3ec010b43552b/aiohttp-3.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:20af8aad61d1803ff11152a26146d8d81c266aa8c5aa9b4504432abb965c36a0", size = 1782110, upload-time = "2026-03-28T17:16:55.362Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/2d/c20791e3437700a7441a7edfb59731150322424f5aadf635602d1d326101/aiohttp-3.13.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:13a5cc924b59859ad2adb1478e31f410a7ed46e92a2a619d6d1dd1a63c1a855e", size = 1884809, upload-time = "2026-03-28T17:16:57.734Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/94/d99dbfbd1924a87ef643833932eb2a3d9e5eee87656efea7d78058539eff/aiohttp-3.13.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:534913dfb0a644d537aebb4123e7d466d94e3be5549205e6a31f72368980a81a", size = 1764938, upload-time = "2026-03-28T17:17:00.221Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/61/3ce326a1538781deb89f6cf5e094e2029cd308ed1e21b2ba2278b08426f6/aiohttp-3.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:320e40192a2dcc1cf4b5576936e9652981ab596bf81eb309535db7e2f5b5672f", size = 1570697, upload-time = "2026-03-28T17:17:02.985Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/77/4ab5a546857bb3028fbaf34d6eea180267bdab022ee8b1168b1fcde4bfdd/aiohttp-3.13.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9e587fcfce2bcf06526a43cb705bdee21ac089096f2e271d75de9c339db3100c", size = 1702258, upload-time = "2026-03-28T17:17:05.28Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/63/d8f29021e39bc5af8e5d5e9da1b07976fb9846487a784e11e4f4eeda4666/aiohttp-3.13.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9eb9c2eea7278206b5c6c1441fdd9dc420c278ead3f3b2cc87f9b693698cc500", size = 1740287, upload-time = "2026-03-28T17:17:07.712Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/3a/cbc6b3b124859a11bc8055d3682c26999b393531ef926754a3445b99dfef/aiohttp-3.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:29be00c51972b04bf9d5c8f2d7f7314f48f96070ca40a873a53056e652e805f7", size = 1753011, upload-time = "2026-03-28T17:17:10.053Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/30/836278675205d58c1368b21520eab9572457cf19afd23759216c04483048/aiohttp-3.13.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:90c06228a6c3a7c9f776fe4fc0b7ff647fffd3bed93779a6913c804ae00c1073", size = 1566359, upload-time = "2026-03-28T17:17:12.433Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/b4/8032cc9b82d17e4277704ba30509eaccb39329dc18d6a35f05e424439e32/aiohttp-3.13.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a533ec132f05fd9a1d959e7f34184cd7d5e8511584848dab85faefbaac573069", size = 1785537, upload-time = "2026-03-28T17:17:14.721Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/7d/5873e98230bde59f493bf1f7c3e327486a4b5653fa401144704df5d00211/aiohttp-3.13.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1c946f10f413836f82ea4cfb90200d2a59578c549f00857e03111cf45ad01ca5", size = 1740752, upload-time = "2026-03-28T17:17:17.387Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/f2/13e46e0df051494d7d3c68b7f72d071f48c384c12716fc294f75d5b1a064/aiohttp-3.13.4-cp313-cp313-win32.whl", hash = "sha256:48708e2706106da6967eff5908c78ca3943f005ed6bcb75da2a7e4da94ef8c70", size = 433187, upload-time = "2026-03-28T17:17:19.523Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/c0/649856ee655a843c8f8664592cfccb73ac80ede6a8c8db33a25d810c12db/aiohttp-3.13.4-cp313-cp313-win_amd64.whl", hash = "sha256:74a2eb058da44fa3a877a49e2095b591d4913308bb424c418b77beb160c55ce3", size = 459778, upload-time = "2026-03-28T17:17:21.964Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/29/6657cc37ae04cacc2dbf53fb730a06b6091cc4cbe745028e047c53e6d840/aiohttp-3.13.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:e0a2c961fc92abeff61d6444f2ce6ad35bb982db9fc8ff8a47455beacf454a57", size = 749363, upload-time = "2026-03-28T17:17:24.044Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/7f/30ccdf67ca3d24b610067dc63d64dcb91e5d88e27667811640644aa4a85d/aiohttp-3.13.4-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:153274535985a0ff2bff1fb6c104ed547cec898a09213d21b0f791a44b14d933", size = 499317, upload-time = "2026-03-28T17:17:26.199Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/13/e372dd4e68ad04ee25dafb050c7f98b0d91ea643f7352757e87231102555/aiohttp-3.13.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:351f3171e2458da3d731ce83f9e6b9619e325c45cbd534c7759750cabf453ad7", size = 500477, upload-time = "2026-03-28T17:17:28.279Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/fe/ee6298e8e586096fb6f5eddd31393d8544f33ae0792c71ecbb4c2bef98ac/aiohttp-3.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f989ac8bc5595ff761a5ccd32bdb0768a117f36dd1504b1c2c074ed5d3f4df9c", size = 1737227, upload-time = "2026-03-28T17:17:30.587Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/b9/a7a0463a09e1a3fe35100f74324f23644bfc3383ac5fd5effe0722a5f0b7/aiohttp-3.13.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d36fc1709110ec1e87a229b201dd3ddc32aa01e98e7868083a794609b081c349", size = 1694036, upload-time = "2026-03-28T17:17:33.29Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/7c/8972ae3fb7be00a91aee6b644b2a6a909aedb2c425269a3bfd90115e6f8f/aiohttp-3.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42adaeea83cbdf069ab94f5103ce0787c21fb1a0153270da76b59d5578302329", size = 1786814, upload-time = "2026-03-28T17:17:36.035Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/01/c81e97e85c774decbaf0d577de7d848934e8166a3a14ad9f8aa5be329d28/aiohttp-3.13.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:92deb95469928cc41fd4b42a95d8012fa6df93f6b1c0a83af0ffbc4a5e218cde", size = 1866676, upload-time = "2026-03-28T17:17:38.441Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/5f/5b46fe8694a639ddea2cd035bf5729e4677ea882cb251396637e2ef1590d/aiohttp-3.13.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0c0c7c07c4257ef3a1df355f840bc62d133bcdef5c1c5ba75add3c08553e2eed", size = 1740842, upload-time = "2026-03-28T17:17:40.783Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/a2/0d4b03d011cca6b6b0acba8433193c1e484efa8d705ea58295590fe24203/aiohttp-3.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f062c45de8a1098cb137a1898819796a2491aec4e637a06b03f149315dff4d8f", size = 1566508, upload-time = "2026-03-28T17:17:43.235Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/17/e689fd500da52488ec5f889effd6404dece6a59de301e380f3c64f167beb/aiohttp-3.13.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:76093107c531517001114f0ebdb4f46858ce818590363e3e99a4a2280334454a", size = 1700569, upload-time = "2026-03-28T17:17:46.165Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/0d/66402894dbcf470ef7db99449e436105ea862c24f7ea4c95c683e635af35/aiohttp-3.13.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:6f6ec32162d293b82f8b63a16edc80769662fbd5ae6fbd4936d3206a2c2cc63b", size = 1707407, upload-time = "2026-03-28T17:17:48.825Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/eb/af0ab1a3650092cbd8e14ef29e4ab0209e1460e1c299996c3f8288b3f1ff/aiohttp-3.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5903e2db3d202a00ad9f0ec35a122c005e85d90c9836ab4cda628f01edf425e2", size = 1752214, upload-time = "2026-03-28T17:17:51.206Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/bf/72326f8a98e4c666f292f03c385545963cc65e358835d2a7375037a97b57/aiohttp-3.13.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2d5bea57be7aca98dbbac8da046d99b5557c5cf4e28538c4c786313078aca09e", size = 1562162, upload-time = "2026-03-28T17:17:53.634Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/9f/13b72435f99151dd9a5469c96b3b5f86aa29b7e785ca7f35cf5e538f74c0/aiohttp-3.13.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:bcf0c9902085976edc0232b75006ef38f89686901249ce14226b6877f88464fb", size = 1768904, upload-time = "2026-03-28T17:17:55.991Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/bc/28d4970e7d5452ac7776cdb5431a1164a0d9cf8bd2fffd67b4fb463aa56d/aiohttp-3.13.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c3295f98bfeed2e867cab588f2a146a9db37a85e3ae9062abf46ba062bd29165", size = 1723378, upload-time = "2026-03-28T17:17:58.348Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/74/b32458ca1a7f34d65bdee7aef2036adbe0438123d3d53e2b083c453c24dd/aiohttp-3.13.4-cp314-cp314-win32.whl", hash = "sha256:a598a5c5767e1369d8f5b08695cab1d8160040f796c4416af76fd773d229b3c9", size = 438711, upload-time = "2026-03-28T17:18:00.728Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/b2/54b487316c2df3e03a8f3435e9636f8a81a42a69d942164830d193beb56a/aiohttp-3.13.4-cp314-cp314-win_amd64.whl", hash = "sha256:c555db4bc7a264bead5a7d63d92d41a1122fcd39cc62a4db815f45ad46f9c2c8", size = 464977, upload-time = "2026-03-28T17:18:03.367Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/fb/e41b63c6ce71b07a59243bb8f3b457ee0c3402a619acb9d2c0d21ef0e647/aiohttp-3.13.4-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45abbbf09a129825d13c18c7d3182fecd46d9da3cfc383756145394013604ac1", size = 781549, upload-time = "2026-03-28T17:18:05.779Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/53/532b8d28df1e17e44c4d9a9368b78dcb6bf0b51037522136eced13afa9e8/aiohttp-3.13.4-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:74c80b2bc2c2adb7b3d1941b2b60701ee2af8296fc8aad8b8bc48bc25767266c", size = 514383, upload-time = "2026-03-28T17:18:08.096Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/1f/62e5d400603e8468cd635812d99cb81cfdc08127a3dc474c647615f31339/aiohttp-3.13.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c97989ae40a9746650fa196894f317dafc12227c808c774929dda0ff873a5954", size = 518304, upload-time = "2026-03-28T17:18:10.642Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/57/2326b37b10896447e3c6e0cbef4fe2486d30913639a5cfd1332b5d870f82/aiohttp-3.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dae86be9811493f9990ef44fff1685f5c1a3192e9061a71a109d527944eed551", size = 1893433, upload-time = "2026-03-28T17:18:13.121Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/b4/a24d82112c304afdb650167ef2fe190957d81cbddac7460bedd245f765aa/aiohttp-3.13.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1db491abe852ca2fa6cc48a3341985b0174b3741838e1341b82ac82c8bd9e871", size = 1755901, upload-time = "2026-03-28T17:18:16.21Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/2d/0883ef9d878d7846287f036c162a951968f22aabeef3ac97b0bea6f76d5d/aiohttp-3.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0e5d701c0aad02a7dce72eef6b93226cf3734330f1a31d69ebbf69f33b86666e", size = 1876093, upload-time = "2026-03-28T17:18:18.703Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/52/9204bb59c014869b71971addad6778f005daa72a96eed652c496789d7468/aiohttp-3.13.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8ac32a189081ae0a10ba18993f10f338ec94341f0d5df8fff348043962f3c6f8", size = 1970815, upload-time = "2026-03-28T17:18:21.858Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/b5/e4eb20275a866dde0f570f411b36c6b48f7b53edfe4f4071aa1b0728098a/aiohttp-3.13.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98e968cdaba43e45c73c3f306fca418c8009a957733bac85937c9f9cf3f4de27", size = 1816223, upload-time = "2026-03-28T17:18:24.729Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/23/e98075c5bb146aa61a1239ee1ac7714c85e814838d6cebbe37d3fe19214a/aiohttp-3.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca114790c9144c335d538852612d3e43ea0f075288f4849cf4b05d6cd2238ce7", size = 1649145, upload-time = "2026-03-28T17:18:27.269Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/c1/7bad8be33bb06c2bb224b6468874346026092762cbec388c3bdb65a368ee/aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ea2e071661ba9cfe11eabbc81ac5376eaeb3061f6e72ec4cc86d7cdd1ffbdbbb", size = 1816562, upload-time = "2026-03-28T17:18:29.847Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/10/c00323348695e9a5e316825969c88463dcc24c7e9d443244b8a2c9cf2eae/aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:34e89912b6c20e0fd80e07fa401fd218a410aa1ce9f1c2f1dad6db1bd0ce0927", size = 1800333, upload-time = "2026-03-28T17:18:32.269Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/43/9b2147a1df3559f49bd723e22905b46a46c068a53adb54abdca32c4de180/aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0e217cf9f6a42908c52b46e42c568bd57adc39c9286ced31aaace614b6087965", size = 1820617, upload-time = "2026-03-28T17:18:35.238Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/7f/b3481a81e7a586d02e99387b18c6dafff41285f6efd3daa2124c01f87eae/aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:0c296f1221e21ba979f5ac1964c3b78cfde15c5c5f855ffd2caab337e9cd9182", size = 1643417, upload-time = "2026-03-28T17:18:37.949Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/72/07181226bc99ce1124e0f89280f5221a82d3ae6a6d9d1973ce429d48e52b/aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d99a9d168ebaffb74f36d011750e490085ac418f4db926cce3989c8fe6cb6b1b", size = 1849286, upload-time = "2026-03-28T17:18:40.534Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/e6/1b3566e103eca6da5be4ae6713e112a053725c584e96574caf117568ffef/aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cb19177205d93b881f3f89e6081593676043a6828f59c78c17a0fd6c1fbed2ba", size = 1782635, upload-time = "2026-03-28T17:18:43.073Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/58/1b11c71904b8d079eb0c39fe664180dd1e14bebe5608e235d8bfbadc8929/aiohttp-3.13.4-cp314-cp314t-win32.whl", hash = "sha256:c606aa5656dab6552e52ca368e43869c916338346bfaf6304e15c58fb113ea30", size = 472537, upload-time = "2026-03-28T17:18:46.286Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/8f/87c56a1a1977d7dddea5b31e12189665a140fdb48a71e9038ff90bb564ec/aiohttp-3.13.4-cp314-cp314t-win_amd64.whl", hash = "sha256:014dcc10ec8ab8db681f0d68e939d1e9286a5aa2b993cbbdb0db130853e02144", size = 506381, upload-time = "2026-03-28T17:18:48.74Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/67/58ded4b3f2e10f94972d8928050c85330e249a31dd45a0e5f3c0e9c3fa05/aiohttp-3.14.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8f6bb621e5863cfe8fe5ff5468002d200ec31f30f1280b259dc505b02595099e", size = 766140, upload-time = "2026-06-07T21:05:37.471Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/68/4ae5b4e08943f316594bb68da89957d3baf5760588fa09509594bd777e4b/aiohttp-3.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f7215cb3933784f79ed20e5f050e15984f390424339b22375d5a53c933a0491", size = 519430, upload-time = "2026-06-07T21:05:40.751Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/c1/316c8f3549dbe5245f92bfd523ec6f32dd4d98cafe21df3f6a19b1184c75/aiohttp-3.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d9d4e294455b23a68c9b8f042d0e8e377a265bcb15332753695f6e5b6819e0ce", size = 514406, upload-time = "2026-06-07T21:05:42.111Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/ee/fb0ac28684e8d753b83c8a4eebc19a5846912aa0a4daaabb6a9936363840/aiohttp-3.14.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b238af795833d5731d049d82bc84b768ae6f8f97f0495963b3ed9935c5901cc3", size = 1703649, upload-time = "2026-06-07T21:05:43.427Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/57/aa2beab673331f111885db8a7b69dfe3ab0e53e446a0ace18ca694b4dc58/aiohttp-3.14.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e4e5e0ae56914ecdbf446493addefc0159053dd53962cef37d7839f37f73d505", size = 1675126, upload-time = "2026-06-07T21:05:44.897Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/ea/dad128abe365e79be03b16ed464198ac73e0d257e8260c6f7d6f31cbef26/aiohttp-3.14.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:092e4ce3619a7c6dee52a6bdabda973d9b34b66781f840ce93c7e0cec30cf521", size = 1771558, upload-time = "2026-06-07T21:05:46.405Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/f3/b5b4e10327cb85d34d24232c6b71b64602f190b3ccb238a043ac6b187dac/aiohttp-3.14.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bb33777ea21e8b7ecde0e6fc84f598be0a1192eab1a63bc746d75aa75d38e7bd", size = 1856631, upload-time = "2026-06-07T21:05:47.844Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/9d/93294c3045775c708ac8310eb3d3622a11d2951345ad590d532d62a1faa4/aiohttp-3.14.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23119f8fd4f5d16902ed459b63b100bcd269628075162bddac56cc7b5273b3fb", size = 1714139, upload-time = "2026-06-07T21:05:49.982Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/c4/93067c85a0373492ce8e577435203c5947c454af074ac48ed4f3a1b9dd4a/aiohttp-3.14.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:57fc6745a4b7d0f5a9eb4f40a69718be6c0bc1b8368cc9fe89e90118719f4f42", size = 1588321, upload-time = "2026-06-07T21:05:51.431Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/39/9ff91aaf02af8b7b8222a987466da539f154c3e01732c22b5f5a20a8ee66/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6fd35beba67c4183b09375c5fff9accb47524191a244a99f95fd4472f5402c2b", size = 1670375, upload-time = "2026-06-07T21:05:53.109Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/e4/77452a3676b8d99ac1375f77691d6bf65ea6e9f4b201b82ef77c916dc767/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:672b9d65f42eb877f5c3f234a4547e4e1a226ca8c2eed879bb34670a0ce51192", size = 1690933, upload-time = "2026-06-07T21:05:54.902Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/84/b0059a7c7fc05ea23f3bc1596ba91c12f79588b9450564a24cac37536d0a/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:24ba13339fed9251d9b1a1bec8c7ab84c0d1675d79d33501e11f94f8b9a84e05", size = 1740798, upload-time = "2026-06-07T21:05:56.458Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/3a/e2a513ecbfc362591caa51a7f7e011b3bfc8938b388ae44cd95560d36999/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:94da27378da0610e341c4d30de29a191672683cc82b8f9556e8f7c7212a020fe", size = 1576412, upload-time = "2026-06-07T21:05:57.953Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/10/08f1654f538f93d36dcac66310a06eefce4641cdafca83f9f0a5317be254/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:52cdac9432d8b4a719f35094a818d95adcae0f0b4fe9b9b921909e0c87de9e7d", size = 1750199, upload-time = "2026-06-07T21:05:59.488Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/e4/d91b70c57d8b8e9611e4a2e52238ca3698d3dc1c2efe25b7a9bf594ac584/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:672ac254412a24d0d0cf00a9e6c238877e4be5e5fa2d188832c1244f45f31966", size = 1699356, upload-time = "2026-06-07T21:06:01.131Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/f1/15340176f35ff61b95dbe34020bcf43f9e624a2d7bbac934715ff97d2033/aiohttp-3.14.1-cp310-cp310-win32.whl", hash = "sha256:2fe3607e71acc6ebb0ec8e492a247bf7a291226192dc0084236dfc12478916f6", size = 458939, upload-time = "2026-06-07T21:06:02.86Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/c2/a2f1ec5b37f903109e43ae2862268cfe4a67a60c1b2cf43169fcdff5995f/aiohttp-3.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:30099eda75a53c32efb0920e9c33c195314d2cc1c680fbfd30894932ac5f27df", size = 482583, upload-time = "2026-06-07T21:06:04.666Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/7a/7b56f6732ef79530afaa72aa335d41b67c8d79b946995f0b11ad72985435/aiohttp-3.14.1-cp310-cp310-win_arm64.whl", hash = "sha256:5a837f49d901f9e368651b676912bff1104ed8c1a83b280bcd7b29adccef5c9c", size = 453470, upload-time = "2026-06-07T21:06:06.322Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/dd/bf526e6f0a1120dd6f2df2e97bacfe4d358f13d17a0ff5847301a1375a51/aiohttp-3.14.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa00140699487bd435fde4342d85c94cb256b7cd3a5b9c3396c67f19922afda2", size = 765225, upload-time = "2026-06-07T21:06:07.957Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/e1/a2872aa55495a70f61310d411541c6ee23812d9a884e000c716e1bc3edbf/aiohttp-3.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1c1af67559445498b502030c35c59db59966f47041ca9de5b4e707f86bd10b5f", size = 518743, upload-time = "2026-06-07T21:06:09.749Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/e7/c60c7b209e509cc787de3cea0550a518538cfc08003e1c1e14c1c63fff71/aiohttp-3.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d44ec478e713ee7f29b439f7eb8dc2b9d4079e11ae114d2c2ac3d5daf30516c8", size = 514139, upload-time = "2026-06-07T21:06:11.26Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/8d/614ace2f579702c9840ab1e1447fd8509e35b0b904f7196418fa2f57b25d/aiohttp-3.14.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d3b1a184a9a8f548a6b73f1e26b96b052193e4b3175ed7342aaf1151a1f00a04", size = 1784088, upload-time = "2026-06-07T21:06:12.887Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/e0/726e90f99542bf292f81a96a12cc4847deb86f3ccf62c6f4014a201f4d33/aiohttp-3.14.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5f2504bc0322437c9a1ff6d3333ca56c7477b727c995f036b976ae17b98372c8", size = 1737835, upload-time = "2026-06-07T21:06:14.564Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/4b/d176d5c4db9d33dacf0543102ea59503bc1d528af4cfd0b719949ca49389/aiohttp-3.14.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:73f05ea02013e02512c3bf42714f1208c57168c779cc6fe23516e4543089d0a6", size = 1842801, upload-time = "2026-06-07T21:06:16.228Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/d6/5a99b563690ea0cbed912ae94a2ce33993a5709a651a3a4fe761e7dd973a/aiohttp-3.14.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:797457503c2d426bee06eef808d07b31ede30b65e054444e7de64cad0061b7af", size = 1929992, upload-time = "2026-06-07T21:06:17.947Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/7f/a987b14a3859094b3cea3f4825219c3e5536242564af6e3f9c2f6c994eb2/aiohttp-3.14.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b821a1f7dedf7e37450654e620038ac3b2e81e8fa6ea269337e97101978ec730", size = 1786989, upload-time = "2026-06-07T21:06:19.677Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/1a/420e5c85a3e73349372ed22ce0b6af86bfa6ce16a4b20a64a2e94608c781/aiohttp-3.14.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4cd96b5ba05d67ed0cf00b5b405c8cd99586d8e3481e8ee0a831057591af7621", size = 1640129, upload-time = "2026-06-07T21:06:22.558Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/80/18a592ed3be0a402cc03670bd72ee1f8563ddbe1d8d5542dbf868f274136/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d459b98a932296c6f0e94f87511a0b1b90a8a02c30a50e60a297619cd5a58ee", size = 1756576, upload-time = "2026-06-07T21:06:24.8Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/0b/8b3d5713373858ff71a617daf6e3b0e81ad63e79d09a3cf2f6b6b983939c/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:764457a7be60825fb770a644852ff717bcbb5042f189f2bd16df61a81b3f6573", size = 1754668, upload-time = "2026-06-07T21:06:26.528Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/49/fd564575cf225821d7ba5a117cb8bc27213d8a7e1811162afb43ae077039/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f7a16ef45b081454ef844502d87a848876c490c4cb5c650c230f6ec79ed2c1e7", size = 1817019, upload-time = "2026-06-07T21:06:28.297Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/1b/e850c9ae6fc91356552ae668bb6c51e93fa29c8aef13398a10b56678557f/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2fbc3ed048b3475b9f0cbcb9978e9d2d3511acd91ead203af26ed9f0056004cf", size = 1631638, upload-time = "2026-06-07T21:06:30.242Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/94/3c337ba72451a89806ace6f75bddc92bafc5b8d53d90115a512858024b63/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bedb0cd073cc2dc035e30aeb99444389d3cd2113afe4ef9fcd23d439f5bade85", size = 1835660, upload-time = "2026-06-07T21:06:31.943Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/9c/9c18cf367a0498212d9ba7daf990b504a5e8ae064cda4b504e2647c89c03/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b6feea921016eb3d4e04d65fc4e9ca402d1a3801f562aef94989f54694917af3", size = 1775698, upload-time = "2026-06-07T21:06:33.72Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/63/a251a9d2a6cb45065b2ddc0bde2b3dd10108740a9a42f632c66405a761a2/aiohttp-3.14.1-cp311-cp311-win32.whl", hash = "sha256:313701e488100074ce99850404ee36e741abf6330179fec908a1944ecf570126", size = 458386, upload-time = "2026-06-07T21:06:35.279Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/ca/69274c51dcd6e8947d77b2806cf47a4a15f2c846e2cbeb1882547d3da283/aiohttp-3.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:03ab4530fdcb3a543a122ba4b65ac9919da9fe9f78a03d328a6e38ff962f7aa5", size = 483406, upload-time = "2026-06-07T21:06:36.824Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/8a/c25904f77690c3688ec140f87591ef11a0cfe36bf3d5c0f1f38056fb62b3/aiohttp-3.14.1-cp311-cp311-win_arm64.whl", hash = "sha256:486f7d16ed54c39c2cbd7ca71fd8ba2b8bb7860df65bd7b6ed640bab96a38a8b", size = 452987, upload-time = "2026-06-07T21:06:38.371Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/21/151624b51cd92553d95424daf4bf19f19ce9be9002d19253e7e7ce67197b/aiohttp-3.14.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d35143e27778b4bb0fb189562d7f275bff79c62ab8e98459717c0ea617ff2480", size = 757402, upload-time = "2026-06-07T21:06:40.311Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/82/280619e0bd7bf2454987e19282616e84762255dd9c8468f62382e8c191f1/aiohttp-3.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bcfb80a2cc36fba2534e5e5b5264dc7ae6fcd9bf15256da3e53d2f499e6fa29d", size = 512310, upload-time = "2026-06-07T21:06:42.207Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/b2/2aac325583aaa1353045f96dffa586d8a34e8322e14a7ba49cffeb103ab4/aiohttp-3.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:27fd7c91e51729b4f7e1577865fa6d34c9adccbc39aabe9000285b48af9f0ec2", size = 512448, upload-time = "2026-06-07T21:06:43.813Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/72/a60607cb849faa8af8a356c9329ea2eb6f395d49e82cc82ccba1fd8deb8f/aiohttp-3.14.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:64c567bf9eaf664280116a8688f63016e6b32db2505908e2bdaca1b6438142f2", size = 1766854, upload-time = "2026-06-07T21:06:45.391Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/d3/d9fe1c9ec7557ab4d0d82bebaa728c6418f0b93295ec2f4ab015f7710cc7/aiohttp-3.14.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f5e6ff2bdbb8f4cd3fbe41f99e25bbcd58e3bf9f13d3dd31a11e7917251cc77a", size = 1740884, upload-time = "2026-06-07T21:06:47.413Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/dc/f2cecfaf9337ba3e63f181500814ff502aa3d00d9c7ec93a9d23d10a27b2/aiohttp-3.14.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2f73e01dc37122325caf079982621262f96d74823c179038a82fddfc50359264", size = 1810034, upload-time = "2026-06-07T21:06:50.165Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/d7/2ff65c5e65c0d7476daf7e15c032e0805e36811185b9623e3238ad6c763e/aiohttp-3.14.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bb2c0c80d431c0d03f2c7dbf125150fedd4f0de17366a7ca33f7ccb822391842", size = 1904054, upload-time = "2026-06-07T21:06:52.035Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/9c/d445818389df371f56d141d881153ba23183c4735a03f7356ffb43f7757d/aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e6fc1a85fa7194a1a7d19f44e8609180f4a8eb5fa4c7ed8b4355f080fad235c", size = 1790278, upload-time = "2026-06-07T21:06:54.049Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/aa/bf04cb4d865fc6101c2229a294ad744973b72e513fdc5a6b791e6983d72a/aiohttp-3.14.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:686b6c0d3911ec387b444ddf5dc62fb7f7c0a7d5186a7861626496a5ab4aff95", size = 1591795, upload-time = "2026-06-07T21:06:55.911Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/b4/4dac0038960427ba832f6609dfb4ea5437d7fd80c72001b9e48f834f428b/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c6fa4dc7ad6f8109c70bb1499e589f76b0b792baf39f9b017eb92c8a81d0a199", size = 1728397, upload-time = "2026-06-07T21:06:57.777Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/f9/7cd4e8ad7aa3b75f17d56bb5498dd604a93d4e6eece822ba0568c413fff0/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:87a5eea1b2a5e21e1ebdbb33ad4165359189327e63fc4e4894693e7f821ac817", size = 1766504, upload-time = "2026-06-07T21:07:00.009Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/df/fc01d9fcad0f73fed3f3d361f1f94f975947b50dff82919f6dc2bf4316cc/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c1421eb01d4fd608d88cc8290211d177a58532b55ad94076fb349c5bf467f0a", size = 1777806, upload-time = "2026-06-07T21:07:02.064Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/09/47e2d090bddcc8fb4ccb4c314aadc32d7c5d9bb55f50f6ad1c92fc15d501/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:34b257ec41345c1e8f2df68fa908a7952f5de932723871eb633ecbbff396c9a4", size = 1580707, upload-time = "2026-06-07T21:07:03.942Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/36/f1a4ce904ae0b6930cfe9afc96d0896f7ec1a620c400405d63783bb95a9c/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:de538791a80e5d862addbc183f70f0158ac9b9bb872bb147f1fd2a683691e087", size = 1798121, upload-time = "2026-06-07T21:07:05.987Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/0a/e0075ce9ca0279ee1d4f0c0b85f54fea02ebc83c3007651a72bece658fec/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f71173be42d3241d428f760122febb748de0623f44308a6f120d0dd9ec572e3", size = 1767580, upload-time = "2026-06-07T21:07:07.873Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3e/61/a0c0a8f327a9c52095cdd8e312391b00d3ed64ab6c72bb5c33d8ec251cf7/aiohttp-3.14.1-cp312-cp312-win32.whl", hash = "sha256:ec8dc383ee57ea3e883477dcca3f11b65d58199f1080acaf4cd6ad9a99698be4", size = 452771, upload-time = "2026-06-07T21:07:09.669Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/d9/ea367c75f16ac9c6cdc8febb25e8318fa21a2b1bc8d6514d4b2d890bface/aiohttp-3.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2aa92c87868cd13674989f9ee83e5f9f7ea4237589b728048e1f0c8f6caa3271", size = 479873, upload-time = "2026-06-07T21:07:11.538Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/64/8d96784a7851156db8a4c6c3f6f91042fdf39fb15a4cc38c8b3c14833c45/aiohttp-3.14.1-cp312-cp312-win_arm64.whl", hash = "sha256:2c840c90759922cb5e6dda94596e079a30fb5a5ba548e7e0dc00574703940847", size = 448073, upload-time = "2026-06-07T21:07:13.637Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/97/bd137012dd97e1649162b099135a80e1fd59aaa807b2430fc448d1029aff/aiohttp-3.14.1-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:b3a03285a7f9c7b016324574a6d92a1c895da6b978cb8f1deee3ac72bc6da178", size = 506882, upload-time = "2026-06-07T21:07:15.501Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/79/e5cc690e9d922a66887ceeaca53a8ffd5a7b0be3816142b7abc433742d89/aiohttp-3.14.1-cp313-cp313-android_21_x86_64.whl", hash = "sha256:2a73f487ab8ef5abbb24b7aa9b73e98eaba9e9e031804ff2416f02eca315ccaf", size = 515270, upload-time = "2026-06-07T21:07:17.53Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/22/a73ccbf9dbd6e26dda0b24d5fd5db7da92ee3383a79f47677ffb834c5c5b/aiohttp-3.14.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:915fbb7b41b115192259f8c9ae58f3ddc444d2b5579917270211858e606a4afd", size = 485841, upload-time = "2026-06-07T21:07:19.555Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/b9/57ed8eaf596321c2ad747bd480fb1700dbd7177c60dfc9e4c187f629662e/aiohttp-3.14.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:7fb4bdf95b0561a79f259f9d28fbc109728c5ee7f27aff6391f0ca703a329abe", size = 492088, upload-time = "2026-06-07T21:07:21.581Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/c0/5ebe5270a7c140d7c6f79dcb018640225f14d406c149e4eec04a7d82fe71/aiohttp-3.14.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1b9748363260121d2927704f5d4fc498150669ca3ae93625986ee89c8f80dcd4", size = 501564, upload-time = "2026-06-07T21:07:23.388Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/7f/8cdaa24fc7983865e0915153b96a9ac5bcdd3548d64c5a27d17cecccad2d/aiohttp-3.14.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:86a6dab78b0e43e2897a3bbe15745aa60dc5423ca437b7b0b164c069bf91b876", size = 751998, upload-time = "2026-06-07T21:07:25.046Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/f4/c4227aacfacc5cb0cc2d119b65301d177912a6842cd64e120c47af76064f/aiohttp-3.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4dfd6e47d3c44c2279907607f73a4240b88c69eb8b90da7e2441a8045dfd21da", size = 510918, upload-time = "2026-06-07T21:07:27.28Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/01/a2d5f96cd4e74424864d30bc0a7e44d0a12dacdcfa91b5b2d1bd3dca6bf3/aiohttp-3.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:317acd9f8602858dc7d59679812c376c7f0b97bcbbf16e0d6237f54141d8a8a6", size = 508657, upload-time = "2026-06-07T21:07:29.252Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/ed/3c0fb5c500fdd8e7ebc10d1889c04384fffa1a9163eac1356088ca9da1b1/aiohttp-3.14.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd869c427324e5cb15195793de951295710db28be7d818247f3097b4ab5d4b96", size = 1757907, upload-time = "2026-06-07T21:07:31.03Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/ab/d4c924d9bd5be3050c226612413ce68cb54c70d2c31b661bfc8d9a5b6a70/aiohttp-3.14.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93b032b5ec3255473c143627d21a69ac74ae12f7f33974cb587c564d11b1066f", size = 1737565, upload-time = "2026-06-07T21:07:33.031Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/2a/37326821ff779084020cdc33224d20b19f42f4183a500ff92022a739eda7/aiohttp-3.14.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f234b4deb12f3ad59127e037bc57c40c21e45b45282df7d3a55a0f409f595296", size = 1799018, upload-time = "2026-06-07T21:07:35.003Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/4f/6e947ba73e4ce09070761c05ed3a8ceb7c21f5e46798671d8b2aac0e4626/aiohttp-3.14.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9af6779bfb46abf124068327abcdf9ce95c9ef8287a3e8da76ccf2d0f16c28fa", size = 1894416, upload-time = "2026-06-07T21:07:36.956Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/6e/dbf1d0625dc711fb2851f4f3c3055c39ed58bae92082d8c627dbe6013736/aiohttp-3.14.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:faccab372e66bc76d5731525e7f1143c922271725b9d38c9f97edcc66266b451", size = 1783881, upload-time = "2026-06-07T21:07:39.063Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/c2/5e25098a67268ed369483ae7d1a58bd0a13d03aab860d2a0e4a6eb25b046/aiohttp-3.14.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f380468b09d2a81633ee863b0ec5648d364bd17bb8ecfb8c2f387f7ac1faf42c", size = 1587572, upload-time = "2026-06-07T21:07:41.058Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/bd/cf9cee17e140f942a3de73e658a543aa8fbf35a5fc67a9d2538d52d77f0b/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:97e704dcd26271f5bda3fa07c3ce0fb76d6d3f8659f4baa1a24442cc9ba177ca", size = 1722137, upload-time = "2026-06-07T21:07:43.014Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/6d/5684f8c59045c96f81a18cefbc1fbbd79d25b88f1c622f2a5c5c08fcb632/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:269b76ac5394092b95bc4a098f4fc6c191c083c3bd12775d1e30e663132f6a09", size = 1755953, upload-time = "2026-06-07T21:07:45.933Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/40/35caf3170f8359760740a7d9aa0fff2e344bef98e1d1186f5a0f6dec17e6/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c0b3e614340c889d575451696374c9d17affd54cd607ca0babed8f8c37b9397", size = 1766479, upload-time = "2026-06-07T21:07:48.047Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/a1/b0c61e7a137f0d81de49a82023a6df73c3c16d6fefb0f8e4a93d21639002/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:5663ee9257cfa1add7253a7da3035a02f31b6600ec48261585e1800a81533080", size = 1580077, upload-time = "2026-06-07T21:07:50.069Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/41/194ea4623693009fcefebef7aef63c141754f153e9cd0d39d3b9e36c175c/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:603a2c834142172ffddc054067f5ec0ca65d57a0aa98a71bc81952573208e345", size = 1791688, upload-time = "2026-06-07T21:07:52.106Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/45/4de841f005cfe1fd63e2a2fe011262c515e2a62aa6994b15947e7d717ac9/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cb21957bb8aca671c1765e32f58164cf0c50e6bf41c0bbbd16da20732ecaf588", size = 1761094, upload-time = "2026-06-07T21:07:54.113Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/ae/dbce10533d3896d544d5053939ed75b7dc31a1b0973d959b1b5ae21028d6/aiohttp-3.14.1-cp313-cp313-win32.whl", hash = "sha256:e509a55f681e6158c20f70f102f9cf61fb20fbc382272bc6d94b7343f2582780", size = 452662, upload-time = "2026-06-07T21:07:56.06Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/d9/0bf1a19362c32f06229da5e7ddfcec91f93474d6307f7a2d3135e9c674dc/aiohttp-3.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:1ac8531b638959718e18c2207fbfe297819875da46a740b29dfa29beba64355a", size = 479748, upload-time = "2026-06-07T21:07:58.319Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/0a/62e7232dc9484fbec112ceb32efb6a624cc7994ec6e2b019286f17c4e8f2/aiohttp-3.14.1-cp313-cp313-win_arm64.whl", hash = "sha256:250d14af67f6b6a1a4a811049b1afa69d61d617fca6bf33149b3ab1a6dbcf7b8", size = 447723, upload-time = "2026-06-07T21:08:00.154Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/a1/5fafa04e1ca91ddb47608699d60649c1c6db3cf41c99e78fc4056f9513db/aiohttp-3.14.1-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:7c106c26852ca1c2047c6b80384f17100b4e439af276f21ef3d4e2f450ae7e15", size = 508531, upload-time = "2026-06-07T21:08:02.093Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/2e/bfa02f699d87ffc86d5959270b28f1cb410add3ccaced8ed2e0b8a5238fc/aiohttp-3.14.1-cp314-cp314-android_24_x86_64.whl", hash = "sha256:20205f7f5ade7aaec9f4b500549bbc071b046453aed72f9c06dcab87896a83e8", size = 514718, upload-time = "2026-06-07T21:08:04.476Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/a5/9594ad6289eebbc97d167c44213d557807f90e59115caad24de21ad2c3b1/aiohttp-3.14.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:62a759436b29e677181a9e76bab8b8f689a29cb9c535f45f7c48c9c830d3f8c3", size = 487918, upload-time = "2026-06-07T21:08:06.377Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/61/16a32c36c3c49edec122a3dc811f2057df2f94d3b14aa107c8017d981618/aiohttp-3.14.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:2964cbf553df4d7a57348da44d961d871895fc1ee4e8c322b2a95612c7b17fba", size = 494014, upload-time = "2026-06-07T21:08:08.263Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/89/3ebcf96ed99c05bec9c434aaac6963fd3cbab4a786ae739908a144d9ce44/aiohttp-3.14.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:237651caadc3a59badd39319c54642b5299e9cc98a3a194310e55d5bb9f5e397", size = 502398, upload-time = "2026-06-07T21:08:10.244Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/3d/b74870a0c2d40c355928cd5b96c7a11fa821b8a40fc41365e64479b151fb/aiohttp-3.14.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:896e12dfdbbab9d8f7e16d2b28c6769a60126fa92095d1ebf9473d02593a2448", size = 758018, upload-time = "2026-06-07T21:08:12.447Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/66/f42f5c984d99e49c6cff5f26f590750f2e2f7ef1fcfb99966ab5be1b632e/aiohttp-3.14.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d03f281ed22579314ba00821ce20115a7c0ac430660b4cc05704a3f818b3e004", size = 512462, upload-time = "2026-06-07T21:08:14.624Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/a7/248e1aebe0c7810b0271e021a0f2a5eb6e78a051885b3c9df49f42a5802d/aiohttp-3.14.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:07eabb979d236335fed927e137a928c9adfb7df3b9ec7aa31726f133a62be983", size = 512824, upload-time = "2026-06-07T21:08:16.572Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/97/2aa0e5ba0727dc3bd5aaebb7ccbc510f7dfb7fb961ec87497cd496635ab1/aiohttp-3.14.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4fe1f1087cbadb280b5e1bb054a4f00d1423c74d6626c5e48400d871d34ecefe", size = 1749898, upload-time = "2026-06-07T21:08:18.635Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/8d/e97f6c96c891d457c8479d92a514ba194d0412f981d72c70341ee18488ed/aiohttp-3.14.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:367a9314fdc79dab0fac96e216cb41dd73c85bdca85306ce8999118ba7e0f333", size = 1710114, upload-time = "2026-06-07T21:08:20.892Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/e6/aa8d7e863048c8fceb5cd6ce74017311cec3ead07847387e12265fb4444e/aiohttp-3.14.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a24f677ebe83749039e7bdf862ff0bbb16818ae4193d4ef96505e269375bcce0", size = 1802541, upload-time = "2026-06-07T21:08:23.044Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/a8/72193137de57fda4ebfae4563182d082c8856e3b6e9871d0b46f028fb369/aiohttp-3.14.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c83afe0ba876be7e943d2e0ba645809ad441575d2840c895c21ee5de93b9377a", size = 1875776, upload-time = "2026-06-07T21:08:25.288Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/18/938441025db6769a3464596b2410af3afde0b21eb2f204c6f766f68af4bd/aiohttp-3.14.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:634e385930fb6d2d479cf3aa66515955863b77a5e3c2b5894ca259a25b308602", size = 1760329, upload-time = "2026-06-07T21:08:27.363Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/29/bf2496b4065e76e09fe48015aaffe5ce161d8f089b06ac6982070f653076/aiohttp-3.14.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeea07c4397bbc57719c4eed8f9c284874d4f175f9b6d57f7a1546b976d455ca", size = 1587293, upload-time = "2026-06-07T21:08:29.805Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/a2/2136674d52123b1354bd05dd5753c318db47dc0c927cc70b27bab3755456/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:335c0cc3e3545ce98dcb9cfcb836f40c3411f43fa03dab757597d80c89af8a35", size = 1714756, upload-time = "2026-06-07T21:08:32.094Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/b9/e5fd2e6f915503081c0f9b1e8540947037929c70c191da2e4d54b31a21a1/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:ae6be797afdef264e8a84864a85b196ca06045586481b3df8a967322fd2fa844", size = 1721052, upload-time = "2026-06-07T21:08:34.167Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/5a/2833e324a2263e104e31e2e91bc5bbee81bc499afd32203faee048a883f0/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:8560b4d712474335d08907db7973f71912d3a9a8f1dee992ec06b5d2fe359496", size = 1766888, upload-time = "2026-06-07T21:08:36.95Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/fa/dea6511870913162f3b2e8c42a7614eb203a4540b8c2da43e0bfb0548f3c/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7edd08e0a5deb1e8564a2fcd8f4561014a3f05252334671bbf55ddd47db0e5", size = 1581679, upload-time = "2026-06-07T21:08:39.292Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/bd/3cf0d55e71784b33534e9710a67d382d900598b4787fbce6cc7317f8c42a/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:b6ff7fcee63287ae57b5df3e4f5957ce032122802509246dec1a5bcc55904c95", size = 1782021, upload-time = "2026-06-07T21:08:41.407Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/af/14bb5843eccbe234f4dfb78ab73e549d99727247e62ae5d62cbd22eaf5b0/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6ffbb2f4ec1ceaff7e07d43922954da26b223d188bf30658e561b98e23089444", size = 1742574, upload-time = "2026-06-07T21:08:43.795Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/1e/fbeb7af9210a67ac0f9c9bec0f8f4568497924e33137a3d5b48e1cf85f3f/aiohttp-3.14.1-cp314-cp314-win32.whl", hash = "sha256:a9875b46d910cff3ea2f5962f9d266b465459fe634e22556ab9bd6fc1192eea0", size = 457773, upload-time = "2026-06-07T21:08:46.168Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/2b/13e8d741a9ec5db7d900c060554cf8352ab85e44e2a4469ebb9d377bda17/aiohttp-3.14.1-cp314-cp314-win_amd64.whl", hash = "sha256:af8b4b81a960eeaf1234971ac3cd0ba5901f3cd42eae42a46b4d089a8b492719", size = 485001, upload-time = "2026-06-07T21:08:48.401Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/30/491acfa2c4d6c3ff59c49a14fc1b50be3241e25bbb0c84c09e2da4d11395/aiohttp-3.14.1-cp314-cp314-win_arm64.whl", hash = "sha256:cf4491381b1b57425c315a56a439251b1bdac07b2275f19a8c44bc57744532ec", size = 453809, upload-time = "2026-06-07T21:08:50.7Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/e3/19dbe1a1f4cc6230eb9e314de7fe68053b0992f9302b27d12141a0b5db53/aiohttp-3.14.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:819c054312f1af92947e6a55883d1b66feefab11531a7fc45e0fb9b63880b5c2", size = 793320, upload-time = "2026-06-07T21:08:52.775Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/20/1b7182219ba1b108430d6e4dc53d25ae02dcfcf5a045b33af4e8c5167527/aiohttp-3.14.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:10ee9c1753a8f706345b22496c79fbddb5be0599e0823f3738b1534058e25340", size = 529077, upload-time = "2026-06-07T21:08:55Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/c8/14ce60ec31a2e5f5274bb17d383a6f7a3aabca31ac04eee05585bbadab16/aiohttp-3.14.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1601cc37baf5750ccacae618ec2daf020769581695550e3b654a911f859c563d", size = 532476, upload-time = "2026-06-07T21:08:57.176Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/02/9ac85e081e53da2e061b02fa7758fe0a12d17b8ce2d1f5e6c7cb76730328/aiohttp-3.14.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d6e0ac9da31c9c04c84e1c0182ad8d6df35965a85cae29cd71d089621b3ae94", size = 1922347, upload-time = "2026-06-07T21:08:59.563Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/3e/d3ba07a0ab38b5389e10bec4362d21e10a4f667cba2d79ba30837b3a5059/aiohttp-3.14.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9e8f2d660c350b3d0e259c7a7e3d9b7fc8b41210cbcc3d4a7076ff0a5e5c2fdc", size = 1786465, upload-time = "2026-06-07T21:09:01.909Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/cb/e2ee978a00cfb2df829704a69528b18154eba5939f45bc1efa8f33aee4c5/aiohttp-3.14.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4691802dda97be727f79d86818acaad7eb8e9252626a1d6b519fedbb92d5e251", size = 1909423, upload-time = "2026-06-07T21:09:04.357Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/5d/1430334858b1022b58ae50399a918f0bd6fe8fa7fa183598d657ff61e040/aiohttp-3.14.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c389c482a7e9b9dc3ee2701ac46c4125297a3818875b9c305ddb603c04828fd1", size = 2001906, upload-time = "2026-06-07T21:09:06.722Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/4e/560c7472d3d198a23aa5c8b19a5115bf6a9b77b7d3e4bb363da320430ad2/aiohttp-3.14.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc0cacab7ba4e56f0f81c82a98c09bed2f39c940107b03a34b168bdf7597edd3", size = 1877095, upload-time = "2026-06-07T21:09:09.011Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/f1/4745806578d447db4a784a8591e2dae3afdfc2bcb96f8f81271b13df6543/aiohttp-3.14.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:979ed4717f59b8bb12e3963378fa285d93d367e15bcd66c721311826d3c44a6c", size = 1676222, upload-time = "2026-06-07T21:09:11.461Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/c9/48255813cca749a229ef0ab476004ec623728ad79a9c0840616f6c076325/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:38e1e7daaea81df51c952e18483f323d878499a1e2bfe564790e0f9701d6f203", size = 1842922, upload-time = "2026-06-07T21:09:14.118Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/c0/bbd054e2bee909f529523a5af3891052606af5143c09f5f183ec3b234676/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:4132e72c608fe9fecb8f409113567605915b83e9bdd3ea56538d2f9cd35002f1", size = 1825035, upload-time = "2026-06-07T21:09:16.447Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/ae/90395d4376deceb74e09ec26b6adf7d2015a6f8802d6d84446af860fef04/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:eefd9cc9b6d4a2db5f00a26bc3e4f9acf71926a6ec557cd56c9c6f27c290b665", size = 1849512, upload-time = "2026-06-07T21:09:18.742Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/bd/fb25f3049957553d4ce0ba6ae480aa2f592a6985497fca590837d16c1be0/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:b165790117eea512d7f3fb22f1f6dad3d55a7189571993eb015591c1401276d1", size = 1668571, upload-time = "2026-06-07T21:09:21.458Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/22/7f73303d64dd567ff3addca90b556690ed1233a47b8f55d242fb90af3681/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:ed09c7eb1c391271c2ed0314a51903e72a3acb653d5ccfc264cdf3ef11f8269d", size = 1881159, upload-time = "2026-06-07T21:09:23.813Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/be/0474c5a8b5640e1e4aa1923430a91f4151be82e511373fe764189b89aef5/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:99abd37084b82f5830c635fddd0b4993b9742a66eb746dacf433c8590e8f9e3c", size = 1841409, upload-time = "2026-06-07T21:09:26.207Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/3c/bb4a7cba26956cb3da4553cc2056cf67be5b5ff6e6d8fa4fbdff73bfb7ae/aiohttp-3.14.1-cp314-cp314t-win32.whl", hash = "sha256:47ddf841cdecc810749921d25606dee45857d12d2ad5ddb7b5bd7eab12e4b365", size = 494166, upload-time = "2026-06-07T21:09:28.505Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/84/ec80c2c1f66a952555a9f86df6b33af65108a6febfa0471b69013a12f807/aiohttp-3.14.1-cp314-cp314t-win_amd64.whl", hash = "sha256:5e78b522b7a6e27e0b25d19b247b75039ac4c94f99823e3c9e53ae1603a9f7e9", size = 530255, upload-time = "2026-06-07T21:09:30.843Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/71/6e22be134a4061ada85a92951b842f2657f17d926b727f3f94c56ae963d6/aiohttp-3.14.1-cp314-cp314t-win_arm64.whl", hash = "sha256:90d53f1609c29ccc2193945ef732428382a28f78d0456ae4d3daf0d48b74f0f6", size = 469640, upload-time = "2026-06-07T21:09:33.028Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -931,16 +948,14 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "heretic-llm"
|
||||
version = "1.2.0"
|
||||
version = "1.4.0"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "accelerate" },
|
||||
{ name = "bitsandbytes" },
|
||||
{ name = "datasets" },
|
||||
{ name = "hf-transfer" },
|
||||
{ name = "huggingface-hub" },
|
||||
{ name = "immutabledict" },
|
||||
{ name = "kernels" },
|
||||
{ name = "langdetect" },
|
||||
{ name = "lm-eval", extra = ["hf"] },
|
||||
{ name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
||||
@@ -953,8 +968,10 @@ dependencies = [
|
||||
{ name = "questionary" },
|
||||
{ name = "rich" },
|
||||
{ name = "tomli-w" },
|
||||
{ name = "torch" },
|
||||
{ name = "torchvision" },
|
||||
{ name = "tqdm" },
|
||||
{ name = "transformers" },
|
||||
{ name = "transformers", extra = ["kernels"] },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
@@ -979,18 +996,16 @@ requires-dist = [
|
||||
{ name = "bitsandbytes", specifier = "~=0.49" },
|
||||
{ name = "datasets", specifier = "~=4.7" },
|
||||
{ name = "geom-median", marker = "extra == 'research'", specifier = "~=0.1" },
|
||||
{ name = "hf-transfer", specifier = "~=0.1" },
|
||||
{ name = "huggingface-hub", specifier = "~=1.7" },
|
||||
{ name = "imageio", marker = "extra == 'research'", specifier = "~=2.37" },
|
||||
{ name = "immutabledict", specifier = "~=4.3" },
|
||||
{ name = "kernels", specifier = "~=0.12" },
|
||||
{ name = "langdetect", specifier = "~=1.0" },
|
||||
{ name = "lm-eval", extras = ["hf"], specifier = "~=0.4" },
|
||||
{ name = "matplotlib", marker = "extra == 'research'", specifier = "~=3.10" },
|
||||
{ name = "numpy", specifier = "~=2.2" },
|
||||
{ name = "optuna", specifier = "~=4.7" },
|
||||
{ name = "pacmap", marker = "extra == 'research'", specifier = "~=0.8" },
|
||||
{ name = "peft", specifier = "~=0.18" },
|
||||
{ name = "peft", specifier = "~=0.19" },
|
||||
{ name = "psutil", specifier = "~=7.2" },
|
||||
{ name = "py-cpuinfo", specifier = "~=9.0" },
|
||||
{ name = "pydantic-settings", specifier = "~=2.13" },
|
||||
@@ -998,8 +1013,10 @@ requires-dist = [
|
||||
{ name = "rich", specifier = "~=14.3" },
|
||||
{ name = "scikit-learn", marker = "extra == 'research'", specifier = "~=1.7" },
|
||||
{ name = "tomli-w", specifier = "~=1.2" },
|
||||
{ name = "torch" },
|
||||
{ name = "torchvision" },
|
||||
{ name = "tqdm", specifier = "~=4.67" },
|
||||
{ name = "transformers", specifier = "~=5.3" },
|
||||
{ name = "transformers", extras = ["kernels"], specifier = "~=5.6" },
|
||||
]
|
||||
provides-extras = ["research"]
|
||||
|
||||
@@ -1009,38 +1026,6 @@ dev = [
|
||||
{ name = "ty", specifier = ">=0.0.5" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hf-transfer"
|
||||
version = "0.1.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1a/eb/8fc64f40388c29ce8ce3b2b180a089d4d6b25b1d0d232d016704cb852104/hf_transfer-0.1.9.tar.gz", hash = "sha256:035572865dab29d17e783fbf1e84cf1cb24f3fcf8f1b17db1cfc7fdf139f02bf", size = 25201, upload-time = "2025-01-07T10:05:12.947Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/78/0dce00208f585fae675f40033ef9a30dedfa83665d5ac79f16beb4a0a6c2/hf_transfer-0.1.9-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:6e94e8822da79573c9b6ae4d6b2f847c59a7a06c5327d7db20751b68538dc4f6", size = 1386084, upload-time = "2025-01-07T10:04:47.874Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/2e/3d60b1a9e9f29a2152aa66c823bf5e399ae7be3fef310ff0de86779c5d2d/hf_transfer-0.1.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ebc4ab9023414880c8b1d3c38174d1c9989eb5022d37e814fa91a3060123eb0", size = 1343558, upload-time = "2025-01-07T10:04:42.313Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/38/130a5ac3747f104033591bcac1c961cb1faadfdc91704f59b09c0b465ff2/hf_transfer-0.1.9-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8674026f21ed369aa2a0a4b46000aca850fc44cd2b54af33a172ce5325b4fc82", size = 3726676, upload-time = "2025-01-07T10:04:11.539Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/a1/f4e27c5ad17aac616ae0849e2aede5aae31db8267a948c6b3eeb9fd96446/hf_transfer-0.1.9-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a736dfbb2c84f5a2c975478ad200c0c8bfcb58a25a35db402678fb87ce17fa4", size = 3062920, upload-time = "2025-01-07T10:04:16.297Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/0d/727abdfba39bc3f1132cfa4c970588c2c0bb0d82fe2d645cc10f4e2f8e0b/hf_transfer-0.1.9-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:504b8427fd785dd8546d53b9fafe6e436bd7a3adf76b9dce556507650a7b4567", size = 3578681, upload-time = "2025-01-07T10:04:29.702Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/d0/2b213eb1ea8b1252ccaf1a6c804d0aba03fea38aae4124df6a3acb70511a/hf_transfer-0.1.9-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c7fc1b85f4d0f76e452765d7648c9f4bfd0aedb9ced2ae1ebfece2d8cfaf8e2", size = 3398837, upload-time = "2025-01-07T10:04:22.778Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/8a/79dbce9006e0bd6b74516f97451a7b7c64dbbb426df15d901dd438cfeee3/hf_transfer-0.1.9-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d991376f0eac70a60f0cbc95602aa708a6f7c8617f28b4945c1431d67b8e3c8", size = 3546986, upload-time = "2025-01-07T10:04:36.415Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/f7/9ac239b6ee6fe0bad130325d987a93ea58c4118e50479f0786f1733b37e8/hf_transfer-0.1.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e6ac4eddcd99575ed3735ed911ddf9d1697e2bd13aa3f0ad7e3904dd4863842e", size = 4071715, upload-time = "2025-01-07T10:04:53.224Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/a3/0ed697279f5eeb7a40f279bd783cf50e6d0b91f24120dcf66ef2cf8822b4/hf_transfer-0.1.9-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:57fd9880da1ee0f47250f735f791fab788f0aa1ee36afc49f761349869c8b4d9", size = 3388081, upload-time = "2025-01-07T10:04:57.818Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/eb/47e477bdf1d784f31c7540db6cc8c354b777e51a186897a7abda34517f36/hf_transfer-0.1.9-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:5d561f0520f493c66b016d99ceabe69c23289aa90be38dd802d2aef279f15751", size = 3658654, upload-time = "2025-01-07T10:05:03.168Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/07/6661e43fbee09594a8a5e9bb778107d95fe38dac4c653982afe03d32bd4d/hf_transfer-0.1.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a5b366d34cd449fe9b20ef25941e6eef0460a2f74e7389f02e673e1f88ebd538", size = 3690551, upload-time = "2025-01-07T10:05:09.238Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/f5/461d2e5f307e5048289b1168d5c642ae3bb2504e88dff1a38b92ed990a21/hf_transfer-0.1.9-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e66acf91df4a8b72f60223059df3003062a5ae111757187ed1a06750a30e911b", size = 1393046, upload-time = "2025-01-07T10:04:51.003Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/ba/8d9fd9f1083525edfcb389c93738c802f3559cb749324090d7109c8bf4c2/hf_transfer-0.1.9-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:8669dbcc7a3e2e8d61d42cd24da9c50d57770bd74b445c65123291ca842a7e7a", size = 1348126, upload-time = "2025-01-07T10:04:45.712Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/a2/cd7885bc9959421065a6fae0fe67b6c55becdeda4e69b873e52976f9a9f0/hf_transfer-0.1.9-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8fd0167c4407a3bc4cdd0307e65ada2294ec04f1813d8a69a5243e379b22e9d8", size = 3728604, upload-time = "2025-01-07T10:04:14.173Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/2e/a072cf196edfeda3310c9a5ade0a0fdd785e6154b3ce24fc738c818da2a7/hf_transfer-0.1.9-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee8b10afedcb75f71091bcc197c526a6ebf5c58bbbadb34fdeee6160f55f619f", size = 3064995, upload-time = "2025-01-07T10:04:18.663Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/84/aec9ef4c0fab93c1ea2b1badff38c78b4b2f86f0555b26d2051dbc920cde/hf_transfer-0.1.9-cp38-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5828057e313de59300dd1abb489444bc452efe3f479d3c55b31a8f680936ba42", size = 3580908, upload-time = "2025-01-07T10:04:32.834Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/63/b560d39651a56603d64f1a0212d0472a44cbd965db2fa62b99d99cb981bf/hf_transfer-0.1.9-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc6bd19e1cc177c66bdef15ef8636ad3bde79d5a4f608c158021153b4573509d", size = 3400839, upload-time = "2025-01-07T10:04:26.122Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/d8/f87ea6f42456254b48915970ed98e993110521e9263472840174d32c880d/hf_transfer-0.1.9-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdca9bfb89e6f8f281890cc61a8aff2d3cecaff7e1a4d275574d96ca70098557", size = 3552664, upload-time = "2025-01-07T10:04:40.123Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/56/1267c39b65fc8f4e2113b36297320f102718bf5799b544a6cbe22013aa1d/hf_transfer-0.1.9-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:89a23f58b7b7effbc047b8ca286f131b17728c99a9f972723323003ffd1bb916", size = 4073732, upload-time = "2025-01-07T10:04:55.624Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/1a/9c748befbe3decf7cb415e34f8a0c3789a0a9c55910dea73d581e48c0ce5/hf_transfer-0.1.9-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:dc7fff1345980d6c0ebb92c811d24afa4b98b3e07ed070c8e38cc91fd80478c5", size = 3390096, upload-time = "2025-01-07T10:04:59.98Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/85/4c03da147b6b4b7cb12e074d3d44eee28604a387ed0eaf7eaaead5069c57/hf_transfer-0.1.9-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:1a6bd16c667ebe89a069ca163060127a794fa3a3525292c900b8c8cc47985b0d", size = 3664743, upload-time = "2025-01-07T10:05:05.416Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/6e/e597b04f753f1b09e6893075d53a82a30c13855cbaa791402695b01e369f/hf_transfer-0.1.9-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d2fde99d502093ade3ab1b53f80da18480e9902aa960dab7f74fb1b9e5bc5746", size = 3695243, upload-time = "2025-01-07T10:05:11.411Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/89/d4e234727a26b2546c8fb70a276cd924260d60135f2165bf8b9ed67bb9a4/hf_transfer-0.1.9-cp38-abi3-win32.whl", hash = "sha256:435cc3cdc8524ce57b074032b8fd76eed70a4224d2091232fa6a8cef8fd6803e", size = 1086605, upload-time = "2025-01-07T10:05:18.873Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/14/f1e15b851d1c2af5b0b1a82bf8eb10bda2da62d98180220ba6fd8879bb5b/hf_transfer-0.1.9-cp38-abi3-win_amd64.whl", hash = "sha256:16f208fc678911c37e11aa7b586bc66a37d02e636208f18b6bc53d29b5df40ad", size = 1160240, upload-time = "2025-01-07T10:05:14.324Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hf-xet"
|
||||
version = "1.4.2"
|
||||
@@ -1123,11 +1108,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.11"
|
||||
version = "3.15"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc", size = 199245, upload-time = "2026-05-12T22:45:57.011Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8", size = 72340, upload-time = "2026-05-12T22:45:55.733Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1508,14 +1493,14 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "mako"
|
||||
version = "1.3.10"
|
||||
version = "1.3.12"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "markupsafe" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9e/38/bd5b78a920a64d708fe6bc8e0a2c075e1389d53bef8413725c63ba041535/mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28", size = 392474, upload-time = "2025-04-10T12:44:31.16Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/00/62/791b31e69ae182791ec67f04850f2f062716bbd205483d63a215f3e062d3/mako-1.3.12.tar.gz", hash = "sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a", size = 400219, upload-time = "2026-04-28T19:01:08.512Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59", size = 78509, upload-time = "2025-04-10T12:50:53.297Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/b1/a0ec7a5a9db730a08daef1fdfb8090435b82465abbf758a596f0ea88727e/mako-1.3.12-py3-none-any.whl", hash = "sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9", size = 78521, upload-time = "2026-04-28T19:01:10.393Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2365,7 +2350,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "peft"
|
||||
version = "0.18.0"
|
||||
version = "0.19.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "accelerate" },
|
||||
@@ -2380,9 +2365,9 @@ dependencies = [
|
||||
{ name = "tqdm" },
|
||||
{ name = "transformers" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4b/0c/f2938db546ac7fc961ab5917cd50fcf5d0d70b406de93e3faccaa504e152/peft-0.18.0.tar.gz", hash = "sha256:c81c80b2056ab40c23d58ef25f74daab417ac653970718589a11a8af28218588", size = 634141, upload-time = "2025-11-13T11:13:06.603Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/86/cf/037f1e3d5186496c05513a6754639e2dab3038a05f384284d49a9bd06a2d/peft-0.19.1.tar.gz", hash = "sha256:0d97542fe96dcdaa20d3b81c06f26f988618f416a73544ab23c3618ccb674a40", size = 763738, upload-time = "2026-04-16T15:46:45.105Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/55/481bf25613d40ef53534f664deba7b138fe566356b6ca10304e2b3b2529c/peft-0.18.0-py3-none-any.whl", hash = "sha256:624f69ca6393b765ccc6734adda7ca57d80b238f0900a42c357d8b67a03d62ff", size = 556427, upload-time = "2025-11-13T11:13:03.664Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/b6/f54d676ed93cc2dd2234c3b172ea9c8c3d7d29361e66b1b23dec57a67465/peft-0.19.1-py3-none-any.whl", hash = "sha256:2113f72a81621b5913ef28f9022204c742df111890c5f49d812716a4a301e356", size = 680692, upload-time = "2026-04-16T15:46:42.886Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2660,59 +2645,59 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "pyarrow"
|
||||
version = "22.0.0"
|
||||
version = "23.0.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151, upload-time = "2025-10-24T12:30:00.762Z" }
|
||||
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/d9/9b/cb3f7e0a345353def531ca879053e9ef6b9f38ed91aebcf68b09ba54dec0/pyarrow-22.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:77718810bd3066158db1e95a63c160ad7ce08c6b0710bc656055033e39cdad88", size = 34223968, upload-time = "2025-10-24T10:03:31.21Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/41/3184b8192a120306270c5307f105b70320fdaa592c99843c5ef78aaefdcf/pyarrow-22.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:44d2d26cda26d18f7af7db71453b7b783788322d756e81730acb98f24eb90ace", size = 35942085, upload-time = "2025-10-24T10:03:38.146Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/3d/a1eab2f6f08001f9fb714b8ed5cfb045e2fe3e3e3c0c221f2c9ed1e6d67d/pyarrow-22.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:b9d71701ce97c95480fecb0039ec5bb889e75f110da72005743451339262f4ce", size = 44964613, upload-time = "2025-10-24T10:03:46.516Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/46/a1d9c24baf21cfd9ce994ac820a24608decf2710521b29223d4334985127/pyarrow-22.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:710624ab925dc2b05a6229d47f6f0dac1c1155e6ed559be7109f684eba048a48", size = 47627059, upload-time = "2025-10-24T10:03:55.353Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/4c/f711acb13075c1391fd54bc17e078587672c575f8de2a6e62509af026dcf/pyarrow-22.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f963ba8c3b0199f9d6b794c90ec77545e05eadc83973897a4523c9e8d84e9340", size = 47947043, upload-time = "2025-10-24T10:04:05.408Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/70/1f3180dd7c2eab35c2aca2b29ace6c519f827dcd4cfeb8e0dca41612cf7a/pyarrow-22.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bd0d42297ace400d8febe55f13fdf46e86754842b860c978dfec16f081e5c653", size = 50206505, upload-time = "2025-10-24T10:04:15.786Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/07/fea6578112c8c60ffde55883a571e4c4c6bc7049f119d6b09333b5cc6f73/pyarrow-22.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:00626d9dc0f5ef3a75fe63fd68b9c7c8302d2b5bbc7f74ecaedba83447a24f84", size = 28101641, upload-time = "2025-10-24T10:04:22.57Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/b7/18f611a8cdc43417f9394a3ccd3eace2f32183c08b9eddc3d17681819f37/pyarrow-22.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:3e294c5eadfb93d78b0763e859a0c16d4051fc1c5231ae8956d61cb0b5666f5a", size = 34272022, upload-time = "2025-10-24T10:04:28.973Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/5c/f259e2526c67eb4b9e511741b19870a02363a47a35edbebc55c3178db22d/pyarrow-22.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:69763ab2445f632d90b504a815a2a033f74332997052b721002298ed6de40f2e", size = 35995834, upload-time = "2025-10-24T10:04:35.467Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/8d/281f0f9b9376d4b7f146913b26fac0aa2829cd1ee7e997f53a27411bbb92/pyarrow-22.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:b41f37cabfe2463232684de44bad753d6be08a7a072f6a83447eeaf0e4d2a215", size = 45030348, upload-time = "2025-10-24T10:04:43.366Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/e5/53c0a1c428f0976bf22f513d79c73000926cb00b9c138d8e02daf2102e18/pyarrow-22.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:35ad0f0378c9359b3f297299c3309778bb03b8612f987399a0333a560b43862d", size = 47699480, upload-time = "2025-10-24T10:04:51.486Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/e1/9dbe4c465c3365959d183e6345d0a8d1dc5b02ca3f8db4760b3bc834cf25/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8382ad21458075c2e66a82a29d650f963ce51c7708c7c0ff313a8c206c4fd5e8", size = 48011148, upload-time = "2025-10-24T10:04:59.585Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/b4/7caf5d21930061444c3cf4fa7535c82faf5263e22ce43af7c2759ceb5b8b/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1a812a5b727bc09c3d7ea072c4eebf657c2f7066155506ba31ebf4792f88f016", size = 50276964, upload-time = "2025-10-24T10:05:08.175Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/f3/cec89bd99fa3abf826f14d4e53d3d11340ce6f6af4d14bdcd54cd83b6576/pyarrow-22.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ec5d40dd494882704fb876c16fa7261a69791e784ae34e6b5992e977bd2e238c", size = 28106517, upload-time = "2025-10-24T10:05:14.314Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/63/ba23862d69652f85b615ca14ad14f3bcfc5bf1b99ef3f0cd04ff93fdad5a/pyarrow-22.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bea79263d55c24a32b0d79c00a1c58bb2ee5f0757ed95656b01c0fb310c5af3d", size = 34211578, upload-time = "2025-10-24T10:05:21.583Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/d0/f9ad86fe809efd2bcc8be32032fa72e8b0d112b01ae56a053006376c5930/pyarrow-22.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:12fe549c9b10ac98c91cf791d2945e878875d95508e1a5d14091a7aaa66d9cf8", size = 35989906, upload-time = "2025-10-24T10:05:29.485Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/a8/f910afcb14630e64d673f15904ec27dd31f1e009b77033c365c84e8c1e1d/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:334f900ff08ce0423407af97e6c26ad5d4e3b0763645559ece6fbf3747d6a8f5", size = 45021677, upload-time = "2025-10-24T10:05:38.274Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/95/aec81f781c75cd10554dc17a25849c720d54feafb6f7847690478dcf5ef8/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c6c791b09c57ed76a18b03f2631753a4960eefbbca80f846da8baefc6491fcfe", size = 47726315, upload-time = "2025-10-24T10:05:47.314Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/d4/74ac9f7a54cfde12ee42734ea25d5a3c9a45db78f9def949307a92720d37/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c3200cb41cdbc65156e5f8c908d739b0dfed57e890329413da2748d1a2cd1a4e", size = 47990906, upload-time = "2025-10-24T10:05:58.254Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/71/fedf2499bf7a95062eafc989ace56572f3343432570e1c54e6599d5b88da/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ac93252226cf288753d8b46280f4edf3433bf9508b6977f8dd8526b521a1bbb9", size = 50306783, upload-time = "2025-10-24T10:06:08.08Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/ed/b202abd5a5b78f519722f3d29063dda03c114711093c1995a33b8e2e0f4b/pyarrow-22.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:44729980b6c50a5f2bfcc2668d36c569ce17f8b17bccaf470c4313dcbbf13c9d", size = 27972883, upload-time = "2025-10-24T10:06:14.204Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/d6/d0fac16a2963002fc22c8fa75180a838737203d558f0ed3b564c4a54eef5/pyarrow-22.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e6e95176209257803a8b3d0394f21604e796dadb643d2f7ca21b66c9c0b30c9a", size = 34204629, upload-time = "2025-10-24T10:06:20.274Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/9c/1d6357347fbae062ad3f17082f9ebc29cc733321e892c0d2085f42a2212b/pyarrow-22.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:001ea83a58024818826a9e3f89bf9310a114f7e26dfe404a4c32686f97bd7901", size = 35985783, upload-time = "2025-10-24T10:06:27.301Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/c0/782344c2ce58afbea010150df07e3a2f5fdad299cd631697ae7bd3bac6e3/pyarrow-22.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:ce20fe000754f477c8a9125543f1936ea5b8867c5406757c224d745ed033e691", size = 45020999, upload-time = "2025-10-24T10:06:35.387Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/8b/5362443737a5307a7b67c1017c42cd104213189b4970bf607e05faf9c525/pyarrow-22.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e0a15757fccb38c410947df156f9749ae4a3c89b2393741a50521f39a8cf202a", size = 47724601, upload-time = "2025-10-24T10:06:43.551Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/4d/76e567a4fc2e190ee6072967cb4672b7d9249ac59ae65af2d7e3047afa3b/pyarrow-22.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cedb9dd9358e4ea1d9bce3665ce0797f6adf97ff142c8e25b46ba9cdd508e9b6", size = 48001050, upload-time = "2025-10-24T10:06:52.284Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/5e/5653f0535d2a1aef8223cee9d92944cb6bccfee5cf1cd3f462d7cb022790/pyarrow-22.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:252be4a05f9d9185bb8c18e83764ebcfea7185076c07a7a662253af3a8c07941", size = 50307877, upload-time = "2025-10-24T10:07:02.405Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/f8/1d0bd75bf9328a3b826e24a16e5517cd7f9fbf8d34a3184a4566ef5a7f29/pyarrow-22.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:a4893d31e5ef780b6edcaf63122df0f8d321088bb0dee4c8c06eccb1ca28d145", size = 27977099, upload-time = "2025-10-24T10:08:07.259Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/81/db56870c997805bf2b0f6eeeb2d68458bf4654652dccdcf1bf7a42d80903/pyarrow-22.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:f7fe3dbe871294ba70d789be16b6e7e52b418311e166e0e3cba9522f0f437fb1", size = 34336685, upload-time = "2025-10-24T10:07:11.47Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/98/0727947f199aba8a120f47dfc229eeb05df15bcd7a6f1b669e9f882afc58/pyarrow-22.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:ba95112d15fd4f1105fb2402c4eab9068f0554435e9b7085924bcfaac2cc306f", size = 36032158, upload-time = "2025-10-24T10:07:18.626Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/b4/9babdef9c01720a0785945c7cf550e4acd0ebcd7bdd2e6f0aa7981fa85e2/pyarrow-22.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c064e28361c05d72eed8e744c9605cbd6d2bb7481a511c74071fd9b24bc65d7d", size = 44892060, upload-time = "2025-10-24T10:07:26.002Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/ca/2f8804edd6279f78a37062d813de3f16f29183874447ef6d1aadbb4efa0f/pyarrow-22.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:6f9762274496c244d951c819348afbcf212714902742225f649cf02823a6a10f", size = 47504395, upload-time = "2025-10-24T10:07:34.09Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/f0/77aa5198fd3943682b2e4faaf179a674f0edea0d55d326d83cb2277d9363/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a9d9ffdc2ab696f6b15b4d1f7cec6658e1d788124418cb30030afbae31c64746", size = 48066216, upload-time = "2025-10-24T10:07:43.528Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/87/a1937b6e78b2aff18b706d738c9e46ade5bfcf11b294e39c87706a0089ac/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ec1a15968a9d80da01e1d30349b2b0d7cc91e96588ee324ce1b5228175043e95", size = 50288552, upload-time = "2025-10-24T10:07:53.519Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/ae/b5a5811e11f25788ccfdaa8f26b6791c9807119dffcf80514505527c384c/pyarrow-22.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:bba208d9c7decf9961998edf5c65e3ea4355d5818dd6cd0f6809bec1afb951cc", size = 28262504, upload-time = "2025-10-24T10:08:00.932Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/b0/0fa4d28a8edb42b0a7144edd20befd04173ac79819547216f8a9f36f9e50/pyarrow-22.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:9bddc2cade6561f6820d4cd73f99a0243532ad506bc510a75a5a65a522b2d74d", size = 34224062, upload-time = "2025-10-24T10:08:14.101Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/a8/7a719076b3c1be0acef56a07220c586f25cd24de0e3f3102b438d18ae5df/pyarrow-22.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e70ff90c64419709d38c8932ea9fe1cc98415c4f87ea8da81719e43f02534bc9", size = 35990057, upload-time = "2025-10-24T10:08:21.842Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/3c/359ed54c93b47fb6fe30ed16cdf50e3f0e8b9ccfb11b86218c3619ae50a8/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:92843c305330aa94a36e706c16209cd4df274693e777ca47112617db7d0ef3d7", size = 45068002, upload-time = "2025-10-24T10:08:29.034Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/fc/4945896cc8638536ee787a3bd6ce7cec8ec9acf452d78ec39ab328efa0a1/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:6dda1ddac033d27421c20d7a7943eec60be44e0db4e079f33cc5af3b8280ccde", size = 47737765, upload-time = "2025-10-24T10:08:38.559Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/5e/7cb7edeb2abfaa1f79b5d5eb89432356155c8426f75d3753cbcb9592c0fd/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:84378110dd9a6c06323b41b56e129c504d157d1a983ce8f5443761eb5256bafc", size = 48048139, upload-time = "2025-10-24T10:08:46.784Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/c6/546baa7c48185f5e9d6e59277c4b19f30f48c94d9dd938c2a80d4d6b067c/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:854794239111d2b88b40b6ef92aa478024d1e5074f364033e73e21e3f76b25e0", size = 50314244, upload-time = "2025-10-24T10:08:55.771Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/79/755ff2d145aafec8d347bf18f95e4e81c00127f06d080135dfc86aea417c/pyarrow-22.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:b883fe6fd85adad7932b3271c38ac289c65b7337c2c132e9569f9d3940620730", size = 28757501, upload-time = "2025-10-24T10:09:59.891Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/d2/237d75ac28ced3147912954e3c1a174df43a95f4f88e467809118a8165e0/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7a820d8ae11facf32585507c11f04e3f38343c1e784c9b5a8b1da5c930547fe2", size = 34355506, upload-time = "2025-10-24T10:09:02.953Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/2c/733dfffe6d3069740f98e57ff81007809067d68626c5faef293434d11bd6/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:c6ec3675d98915bf1ec8b3c7986422682f7232ea76cad276f4c8abd5b7319b70", size = 36047312, upload-time = "2025-10-24T10:09:10.334Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/2b/29d6e3782dc1f299727462c1543af357a0f2c1d3c160ce199950d9ca51eb/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:3e739edd001b04f654b166204fc7a9de896cf6007eaff33409ee9e50ceaff754", size = 45081609, upload-time = "2025-10-24T10:09:18.61Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/42/aa9355ecc05997915af1b7b947a7f66c02dcaa927f3203b87871c114ba10/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:7388ac685cab5b279a41dfe0a6ccd99e4dbf322edfb63e02fc0443bf24134e91", size = 47703663, upload-time = "2025-10-24T10:09:27.369Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/62/45abedde480168e83a1de005b7b7043fd553321c1e8c5a9a114425f64842/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f633074f36dbc33d5c05b5dc75371e5660f1dbf9c8b1d95669def05e5425989c", size = 48066543, upload-time = "2025-10-24T10:09:34.908Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/e9/7878940a5b072e4f3bf998770acafeae13b267f9893af5f6d4ab3904b67e/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4c19236ae2402a8663a2c8f21f1870a03cc57f0bef7e4b6eb3238cc82944de80", size = 50288838, upload-time = "2025-10-24T10:09:44.394Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/03/f335d6c52b4a4761bcc83499789a1e2e16d9d201a58c327a9b5cc9a41bd9/pyarrow-22.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0c34fe18094686194f204a3b1787a27456897d8a2d62caf84b61e8dfbc0252ae", size = 29185594, upload-time = "2025-10-24T10:09:53.111Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/a8/24e5dc6855f50a62936ceb004e6e9645e4219a8065f304145d7fb8a79d5d/pyarrow-23.0.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:3fab8f82571844eb3c460f90a75583801d14ca0cc32b1acc8c361650e006fd56", size = 34307390, upload-time = "2026-02-16T10:08:08.654Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/8e/4be5617b4aaae0287f621ad31c6036e5f63118cfca0dc57d42121ff49b51/pyarrow-23.0.1-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:3f91c038b95f71ddfc865f11d5876c42f343b4495535bd262c7b321b0b94507c", size = 35853761, upload-time = "2026-02-16T10:08:17.811Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/08/3e56a18819462210432ae37d10f5c8eed3828be1d6c751b6e6a2e93c286a/pyarrow-23.0.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:d0744403adabef53c985a7f8a082b502a368510c40d184df349a0a8754533258", size = 44493116, upload-time = "2026-02-16T10:08:25.792Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/82/c40b68001dbec8a3faa4c08cd8c200798ac732d2854537c5449dc859f55a/pyarrow-23.0.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:c33b5bf406284fd0bba436ed6f6c3ebe8e311722b441d89397c54f871c6863a2", size = 47564532, upload-time = "2026-02-16T10:08:34.27Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/bc/73f611989116b6f53347581b02177f9f620efdf3cd3f405d0e83cdf53a83/pyarrow-23.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ddf743e82f69dcd6dbbcb63628895d7161e04e56794ef80550ac6f3315eeb1d5", size = 48183685, upload-time = "2026-02-16T10:08:42.889Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/cc/6c6b3ecdae2a8c3aced99956187e8302fc954cc2cca2a37cf2111dad16ce/pyarrow-23.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e052a211c5ac9848ae15d5ec875ed0943c0221e2fcfe69eee80b604b4e703222", size = 50605582, upload-time = "2026-02-16T10:08:51.641Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/94/d359e708672878d7638a04a0448edf7c707f9e5606cee11e15aaa5c7535a/pyarrow-23.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:5abde149bb3ce524782d838eb67ac095cd3fd6090eba051130589793f1a7f76d", size = 27521148, upload-time = "2026-02-16T10:08:58.077Z" },
|
||||
{ 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" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/a5/da83046273d990f256cb79796a190bbf7ec999269705ddc609403f8c6b06/pyarrow-23.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:813d99f31275919c383aab17f0f455a04f5a429c261cc411b1e9a8f5e4aaaa05", size = 47586063, upload-time = "2026-02-16T10:10:17.95Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/3c/b7d2ebcff47a514f47f9da1e74b7949138c58cfeb108cdd4ee62f43f0cf3/pyarrow-23.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bf5842f960cddd2ef757d486041d57c96483efc295a8c4a0e20e704cbbf39c67", size = 48173045, upload-time = "2026-02-16T10:10:25.363Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/b2/b40961262213beaba6acfc88698eb773dfce32ecdf34d19291db94c2bd73/pyarrow-23.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564baf97c858ecc03ec01a41062e8f4698abc3e6e2acd79c01c2e97880a19730", size = 50621741, upload-time = "2026-02-16T10:10:33.477Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/70/1fdda42d65b28b078e93d75d371b2185a61da89dda4def8ba6ba41ebdeb4/pyarrow-23.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:07deae7783782ac7250989a7b2ecde9b3c343a643f82e8a4df03d93b633006f0", size = 27620678, upload-time = "2026-02-16T10:10:39.31Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/10/2cbe4c6f0fb83d2de37249567373d64327a5e4d8db72f486db42875b08f6/pyarrow-23.0.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:6b8fda694640b00e8af3c824f99f789e836720aa8c9379fb435d4c4953a756b8", size = 34210066, upload-time = "2026-02-16T10:10:45.487Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/4f/679fa7e84dadbaca7a65f7cdba8d6c83febbd93ca12fa4adf40ba3b6362b/pyarrow-23.0.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:8ff51b1addc469b9444b7c6f3548e19dc931b172ab234e995a60aea9f6e6025f", size = 35825526, upload-time = "2026-02-16T10:10:52.266Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/63/d2747d930882c9d661e9398eefc54f15696547b8983aaaf11d4a2e8b5426/pyarrow-23.0.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:71c5be5cbf1e1cb6169d2a0980850bccb558ddc9b747b6206435313c47c37677", size = 44473279, upload-time = "2026-02-16T10:11:01.557Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/93/10a48b5e238de6d562a411af6467e71e7aedbc9b87f8d3a35f1560ae30fb/pyarrow-23.0.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:9b6f4f17b43bc39d56fec96e53fe89d94bac3eb134137964371b45352d40d0c2", size = 47585798, upload-time = "2026-02-16T10:11:09.401Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/20/476943001c54ef078dbf9542280e22741219a184a0632862bca4feccd666/pyarrow-23.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fc13fc6c403d1337acab46a2c4346ca6c9dec5780c3c697cf8abfd5e19b6b37", size = 48179446, upload-time = "2026-02-16T10:11:17.781Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/b6/5dd0c47b335fcd8edba9bfab78ad961bd0fd55ebe53468cc393f45e0be60/pyarrow-23.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5c16ed4f53247fa3ffb12a14d236de4213a4415d127fe9cebed33d51671113e2", size = 50623972, upload-time = "2026-02-16T10:11:26.185Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/09/a532297c9591a727d67760e2e756b83905dd89adb365a7f6e9c72578bcc1/pyarrow-23.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:cecfb12ef629cf6be0b1887f9f86463b0dd3dc3195ae6224e74006be4736035a", size = 27540749, upload-time = "2026-02-16T10:12:23.297Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/8e/38749c4b1303e6ae76b3c80618f84861ae0c55dd3c2273842ea6f8258233/pyarrow-23.0.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:29f7f7419a0e30264ea261fdc0e5fe63ce5a6095003db2945d7cd78df391a7e1", size = 34471544, upload-time = "2026-02-16T10:11:32.535Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/73/f237b2bc8c669212f842bcfd842b04fc8d936bfc9d471630569132dc920d/pyarrow-23.0.1-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:33d648dc25b51fd8055c19e4261e813dfc4d2427f068bcecc8b53d01b81b0500", size = 35949911, upload-time = "2026-02-16T10:11:39.813Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/86/b912195eee0903b5611bf596833def7d146ab2d301afeb4b722c57ffc966/pyarrow-23.0.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:cd395abf8f91c673dd3589cadc8cc1ee4e8674fa61b2e923c8dd215d9c7d1f41", size = 44520337, upload-time = "2026-02-16T10:11:47.764Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/c2/f2a717fb824f62d0be952ea724b4f6f9372a17eed6f704b5c9526f12f2f1/pyarrow-23.0.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:00be9576d970c31defb5c32eb72ef585bf600ef6d0a82d5eccaae96639cf9d07", size = 47548944, upload-time = "2026-02-16T10:11:56.607Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/a7/90007d476b9f0dc308e3bc57b832d004f848fd6c0da601375d20d92d1519/pyarrow-23.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c2139549494445609f35a5cda4eb94e2c9e4d704ce60a095b342f82460c73a83", size = 48236269, upload-time = "2026-02-16T10:12:04.47Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/3f/b16fab3e77709856eb6ac328ce35f57a6d4a18462c7ca5186ef31b45e0e0/pyarrow-23.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:7044b442f184d84e2351e5084600f0d7343d6117aabcbc1ac78eb1ae11eb4125", size = 50604794, upload-time = "2026-02-16T10:12:11.797Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/a1/22df0620a9fac31d68397a75465c344e83c3dfe521f7612aea33e27ab6c0/pyarrow-23.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a35581e856a2fafa12f3f54fce4331862b1cfb0bef5758347a858a4aa9d6bae8", size = 27660642, upload-time = "2026-02-16T10:12:17.746Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/1b/6da9a89583ce7b23ac611f183ae4843cd3a6cf54f079549b0e8c14031e73/pyarrow-23.0.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:5df1161da23636a70838099d4aaa65142777185cc0cdba4037a18cee7d8db9ca", size = 34238755, upload-time = "2026-02-16T10:12:32.819Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/b5/d58a241fbe324dbaeb8df07be6af8752c846192d78d2272e551098f74e88/pyarrow-23.0.1-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:fa8e51cb04b9f8c9c5ace6bab63af9a1f88d35c0d6cbf53e8c17c098552285e1", size = 35847826, upload-time = "2026-02-16T10:12:38.949Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/a5/8cbc83f04aba433ca7b331b38f39e000efd9f0c7ce47128670e737542996/pyarrow-23.0.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:0b95a3994f015be13c63148fef8832e8a23938128c185ee951c98908a696e0eb", size = 44536859, upload-time = "2026-02-16T10:12:45.467Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/2e/c0f017c405fcdc252dbccafbe05e36b0d0eb1ea9a958f081e01c6972927f/pyarrow-23.0.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:4982d71350b1a6e5cfe1af742c53dfb759b11ce14141870d05d9e540d13bc5d1", size = 47614443, upload-time = "2026-02-16T10:12:55.525Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/6b/2314a78057912f5627afa13ba43809d9d653e6630859618b0fd81a4e0759/pyarrow-23.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c250248f1fe266db627921c89b47b7c06fee0489ad95b04d50353537d74d6886", size = 48232991, upload-time = "2026-02-16T10:13:04.729Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/f2/1bcb1d3be3460832ef3370d621142216e15a2c7c62602a4ea19ec240dd64/pyarrow-23.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5f4763b83c11c16e5f4c15601ba6dfa849e20723b46aa2617cb4bffe8768479f", size = 50645077, upload-time = "2026-02-16T10:13:14.147Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/3f/b1da7b61cd66566a4d4c8383d376c606d1c34a906c3f1cb35c479f59d1aa/pyarrow-23.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:3a4c85ef66c134161987c17b147d6bffdca4566f9a4c1d81a0a01cdf08414ea5", size = 28234271, upload-time = "2026-02-16T10:14:09.397Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/78/07f67434e910a0f7323269be7bfbf58699bd0c1d080b18a1ab49ba943fe8/pyarrow-23.0.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:17cd28e906c18af486a499422740298c52d7c6795344ea5002a7720b4eadf16d", size = 34488692, upload-time = "2026-02-16T10:13:21.541Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/76/34cf7ae93ece1f740a04910d9f7e80ba166b9b4ab9596a953e9e62b90fe1/pyarrow-23.0.1-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:76e823d0e86b4fb5e1cf4a58d293036e678b5a4b03539be933d3b31f9406859f", size = 35964383, upload-time = "2026-02-16T10:13:28.63Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/90/459b827238936d4244214be7c684e1b366a63f8c78c380807ae25ed92199/pyarrow-23.0.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:a62e1899e3078bf65943078b3ad2a6ddcacf2373bc06379aac61b1e548a75814", size = 44538119, upload-time = "2026-02-16T10:13:35.506Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/a1/93a71ae5881e99d1f9de1d4554a87be37da11cd6b152239fb5bd924fdc64/pyarrow-23.0.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:df088e8f640c9fae3b1f495b3c64755c4e719091caf250f3a74d095ddf3c836d", size = 47571199, upload-time = "2026-02-16T10:13:42.504Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/a3/d2c462d4ef313521eaf2eff04d204ac60775263f1fb08c374b543f79f610/pyarrow-23.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:46718a220d64677c93bc243af1d44b55998255427588e400677d7192671845c7", size = 48259435, upload-time = "2026-02-16T10:13:49.226Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/f1/11a544b8c3d38a759eb3fbb022039117fd633e9a7b19e4841cc3da091915/pyarrow-23.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a09f3876e87f48bc2f13583ab551f0379e5dfb83210391e68ace404181a20690", size = 50629149, upload-time = "2026-02-16T10:13:57.238Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/f2/c0e76a0b451ffdf0cf788932e182758eb7558953f4f27f1aff8e2518b653/pyarrow-23.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce", size = 28365807, upload-time = "2026-02-16T10:14:03.892Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3757,6 +3742,47 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/db/2b/f7818f6ec88758dfd21da46b6cd46af9d1b3433e53ddbb19ad1e0da17f9b/torch-2.9.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c88d3299ddeb2b35dcc31753305612db485ab6f1823e37fb29451c8b2732b87e", size = 111163659, upload-time = "2025-11-12T15:23:20.009Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "torchvision"
|
||||
version = "0.24.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
||||
{ name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
{ name = "pillow" },
|
||||
{ name = "torch" },
|
||||
]
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/09/d51aadf8591138e08b74c64a6eb783630c7a31ca2634416277115a9c3a2b/torchvision-0.24.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ded5e625788572e4e1c4d155d1bbc48805c113794100d70e19c76e39e4d53465", size = 1891441, upload-time = "2025-11-12T15:25:01.687Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/49/a35df863e7c153aad82af7505abd8264a5b510306689712ef86bea862822/torchvision-0.24.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:54ed17c3d30e718e08d8da3fd5b30ea44b0311317e55647cb97077a29ecbc25b", size = 2386226, upload-time = "2025-11-12T15:25:05.449Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/20/f2d7cd1eea052887c1083afff0b8df5228ec93b53e03759f20b1a3c6d22a/torchvision-0.24.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:f476da4e085b7307aaab6f540219617d46d5926aeda24be33e1359771c83778f", size = 8046093, upload-time = "2025-11-12T15:25:09.425Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/cf/0ff4007c09903199307da5f53a192ff5d62b45447069e9ef3a19bdc5ff12/torchvision-0.24.1-cp310-cp310-win_amd64.whl", hash = "sha256:fbdbdae5e540b868a681240b7dbd6473986c862445ee8a138680a6a97d6c34ff", size = 3696202, upload-time = "2025-11-12T15:25:10.657Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/69/30f5f03752aa1a7c23931d2519b31e557f3f10af5089d787cddf3b903ecf/torchvision-0.24.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:056c525dc875f18fe8e9c27079ada166a7b2755cea5a2199b0bc7f1f8364e600", size = 1891436, upload-time = "2025-11-12T15:25:04.3Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/69/49aae86edb75fe16460b59a191fcc0f568c2378f780bb063850db0fe007a/torchvision-0.24.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:1e39619de698e2821d71976c92c8a9e50cdfd1e993507dfb340f2688bfdd8283", size = 2387757, upload-time = "2025-11-12T15:25:06.795Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/c9/1dfc3db98797b326f1d0c3f3bb61c83b167a813fc7eab6fcd2edb8c7eb9d/torchvision-0.24.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a0f106663e60332aa4fcb1ca2159ef8c3f2ed266b0e6df88de261048a840e0df", size = 8047682, upload-time = "2025-11-12T15:25:21.125Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/bb/cfc6a6f6ccc84a534ed1fdf029ae5716dd6ff04e57ed9dc2dab38bf652d5/torchvision-0.24.1-cp311-cp311-win_amd64.whl", hash = "sha256:a9308cdd37d8a42e14a3e7fd9d271830c7fecb150dd929b642f3c1460514599a", size = 4037588, upload-time = "2025-11-12T15:25:14.402Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/af/18e2c6b9538a045f60718a0c5a058908ccb24f88fde8e6f0fc12d5ff7bd3/torchvision-0.24.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e48bf6a8ec95872eb45763f06499f87bd2fb246b9b96cb00aae260fda2f96193", size = 1891433, upload-time = "2025-11-12T15:25:03.232Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/43/600e5cfb0643d10d633124f5982d7abc2170dfd7ce985584ff16edab3e76/torchvision-0.24.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:7fb7590c737ebe3e1c077ad60c0e5e2e56bb26e7bccc3b9d04dbfc34fd09f050", size = 2386737, upload-time = "2025-11-12T15:25:08.288Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/b1/db2941526ecddd84884132e2742a55c9311296a6a38627f9e2627f5ac889/torchvision-0.24.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:66a98471fc18cad9064123106d810a75f57f0838eee20edc56233fd8484b0cc7", size = 8049868, upload-time = "2025-11-12T15:25:13.058Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/98/16e583f59f86cd59949f59d52bfa8fc286f86341a229a9d15cbe7a694f0c/torchvision-0.24.1-cp312-cp312-win_amd64.whl", hash = "sha256:4aa6cb806eb8541e92c9b313e96192c6b826e9eb0042720e2fa250d021079952", size = 4302006, upload-time = "2025-11-12T15:25:16.184Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/97/ab40550f482577f2788304c27220e8ba02c63313bd74cf2f8920526aac20/torchvision-0.24.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:8a6696db7fb71eadb2c6a48602106e136c785642e598eb1533e0b27744f2cce6", size = 1891435, upload-time = "2025-11-12T15:25:28.642Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/65/ac0a3f9be6abdbe4e1d82c915d7e20de97e7fd0e9a277970508b015309f3/torchvision-0.24.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:db2125c46f9cb25dc740be831ce3ce99303cfe60439249a41b04fd9f373be671", size = 2338718, upload-time = "2025-11-12T15:25:26.19Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/b5/5bba24ff9d325181508501ed7f0c3de8ed3dd2edca0784d48b144b6c5252/torchvision-0.24.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:f035f0cacd1f44a8ff6cb7ca3627d84c54d685055961d73a1a9fb9827a5414c8", size = 8049661, upload-time = "2025-11-12T15:25:22.558Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/ec/54a96ae9ab6a0dd66d4bba27771f892e36478a9c3489fa56e51c70abcc4d/torchvision-0.24.1-cp313-cp313-win_amd64.whl", hash = "sha256:16274823b93048e0a29d83415166a2e9e0bf4e1b432668357b657612a4802864", size = 4319808, upload-time = "2025-11-12T15:25:17.318Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/f3/a90a389a7e547f3eb8821b13f96ea7c0563cdefbbbb60a10e08dda9720ff/torchvision-0.24.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e3f96208b4bef54cd60e415545f5200346a65024e04f29a26cd0006dbf9e8e66", size = 2005342, upload-time = "2025-11-12T15:25:11.871Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/fe/ff27d2ed1b524078164bea1062f23d2618a5fc3208e247d6153c18c91a76/torchvision-0.24.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:f231f6a4f2aa6522713326d0d2563538fa72d613741ae364f9913027fa52ea35", size = 2341708, upload-time = "2025-11-12T15:25:25.08Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/b9/d6c903495cbdfd2533b3ef6f7b5643ff589ea062f8feb5c206ee79b9d9e5/torchvision-0.24.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:1540a9e7f8cf55fe17554482f5a125a7e426347b71de07327d5de6bfd8d17caa", size = 8177239, upload-time = "2025-11-12T15:25:18.554Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/2b/ba02e4261369c3798310483028495cf507e6cb3f394f42e4796981ecf3a7/torchvision-0.24.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d83e16d70ea85d2f196d678bfb702c36be7a655b003abed84e465988b6128938", size = 4251604, upload-time = "2025-11-12T15:25:34.069Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/42/84/577b2cef8f32094add5f52887867da4c2a3e6b4261538447e9b48eb25812/torchvision-0.24.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cccf4b4fec7fdfcd3431b9ea75d1588c0a8596d0333245dafebee0462abe3388", size = 2005319, upload-time = "2025-11-12T15:25:23.827Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/34/ecb786bffe0159a3b49941a61caaae089853132f3cd1e8f555e3621f7e6f/torchvision-0.24.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:1b495edd3a8f9911292424117544f0b4ab780452e998649425d1f4b2bed6695f", size = 2338844, upload-time = "2025-11-12T15:25:32.625Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/99/a84623786a6969504c87f2dc3892200f586ee13503f519d282faab0bb4f0/torchvision-0.24.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:ab211e1807dc3e53acf8f6638df9a7444c80c0ad050466e8d652b3e83776987b", size = 8175144, upload-time = "2025-11-12T15:25:31.355Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/ba/8fae3525b233e109317ce6a9c1de922ab2881737b029a7e88021f81e068f/torchvision-0.24.1-cp314-cp314-win_amd64.whl", hash = "sha256:18f9cb60e64b37b551cd605a3d62c15730c086362b40682d23e24b616a697d41", size = 4234459, upload-time = "2025-11-12T15:25:19.859Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/33/481602c1c72d0485d4b3a6b48c9534b71c2957c9d83bf860eb837bf5a620/torchvision-0.24.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec9d7379c519428395e4ffda4dbb99ec56be64b0a75b95989e00f9ec7ae0b2d7", size = 2005336, upload-time = "2025-11-12T15:25:27.225Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/7f/372de60bf3dd8f5593bd0d03f4aecf0d1fd58f5bc6943618d9d913f5e6d5/torchvision-0.24.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:af9201184c2712d808bd4eb656899011afdfce1e83721c7cb08000034df353fe", size = 2341704, upload-time = "2025-11-12T15:25:29.857Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/9b/0f3b9ff3d0225ee2324ec663de0e7fb3eb855615ca958ac1875f22f1f8e5/torchvision-0.24.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:9ef95d819fd6df81bc7cc97b8f21a15d2c0d3ac5dbfaab5cbc2d2ce57114b19e", size = 8177422, upload-time = "2025-11-12T15:25:37.357Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/ab/e2bcc7c2f13d882a58f8b30ff86f794210b075736587ea50f8c545834f8a/torchvision-0.24.1-cp314-cp314t-win_amd64.whl", hash = "sha256:480b271d6edff83ac2e8d69bbb4cf2073f93366516a50d48f140ccfceedb002e", size = 4335190, upload-time = "2025-11-12T15:25:35.745Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tqdm"
|
||||
version = "4.67.1"
|
||||
@@ -3771,7 +3797,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "transformers"
|
||||
version = "5.3.0"
|
||||
version = "5.6.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "huggingface-hub" },
|
||||
@@ -3785,9 +3811,14 @@ dependencies = [
|
||||
{ name = "tqdm" },
|
||||
{ name = "typer" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fc/1a/70e830d53ecc96ce69cfa8de38f163712d2b43ac52fbd743f39f56025c31/transformers-5.3.0.tar.gz", hash = "sha256:009555b364029da9e2946d41f1c5de9f15e6b1df46b189b7293f33a161b9c557", size = 8830831, upload-time = "2026-03-04T17:41:46.119Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a4/e9/c6c80a07690142a7d05444271f47b9f3c8aac7dea01d52e1137ee480ad78/transformers-5.6.2.tar.gz", hash = "sha256:e657134c3e5a6bc00a3c35f4e2674bb51adfcd89898495b788a18552bac2b91a", size = 8311867, upload-time = "2026-04-23T18:33:29.332Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/88/ae8320064e32679a5429a2c9ebbc05c2bf32cefb6e076f9b07f6d685a9b4/transformers-5.3.0-py3-none-any.whl", hash = "sha256:50ac8c89c3c7033444fb3f9f53138096b997ebb70d4b5e50a2e810bf12d3d29a", size = 10661827, upload-time = "2026-03-04T17:41:42.722Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/95/0b0218149b0d6f14df35f5b8f676fa83df4f19ed253c3cc447107ef86eca/transformers-5.6.2-py3-none-any.whl", hash = "sha256:f8d3a1bb96778fed9b8aabfd0dd6e19843e4b0f2bb6b59f32b8a92051b0f348f", size = 10364898, upload-time = "2026-04-23T18:33:26.081Z" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
kernels = [
|
||||
{ name = "kernels" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3895,11 +3926,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.6.3"
|
||||
version = "2.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in New Issue
Block a user