chore: update dependencies

This commit is contained in:
Philipp Emanuel Weidmann
2026-10-02 14:00:50 +05:30
parent 662e4ba27e
commit 8cac604223
32 changed files with 3071 additions and 2232 deletions
+34 -15
View File
@@ -14,7 +14,6 @@ classifiers = [
"Environment :: Console", "Environment :: Console",
"Environment :: GPU", "Environment :: GPU",
"Intended Audience :: Science/Research", "Intended Audience :: Science/Research",
"License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
"Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Scientific/Engineering :: Artificial Intelligence",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.10",
@@ -22,32 +21,32 @@ classifiers = [
"Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.12",
] ]
dependencies = [ dependencies = [
"accelerate~=1.13", "accelerate~=1.15",
"bitsandbytes~=0.49", "bitsandbytes~=0.50",
"datasets~=4.7", "datasets~=5.0",
"huggingface-hub~=1.7", "huggingface-hub~=1.33",
"immutabledict~=4.3", "immutabledict~=4.3",
"langdetect~=1.0", "langdetect~=1.0",
"lm-eval[hf]~=0.4", "lm-eval[hf]~=0.4",
"numpy~=2.2", "numpy~=2.2",
"optuna~=4.7", "optuna~=5.0",
"peft~=0.19", "peft~=0.21",
"psutil~=7.2", "psutil~=7.2",
"py-cpuinfo~=9.0", "py-cpuinfo~=9.0",
"pydantic-settings~=2.13", "pydantic-settings~=2.15",
"questionary~=2.1", "questionary~=2.1",
"rich~=14.3", "rich~=15.0",
"tomli-w~=1.2", "tomli-w~=1.2",
"torch", # version deliberately unspecified "torch", # version deliberately unspecified
"torchvision", # version deliberately unspecified "torchvision", # version deliberately unspecified
"tqdm~=4.67", "tqdm~=4.70",
"transformers[kernels]~=5.6", "transformers[kernels]~=5.18",
] ]
[dependency-groups] [dependency-groups]
dev = [ dev = [
"ruff>=0.14.5", "ruff>=0.16.9",
"ty>=0.0.5", "ty>=0.0.84",
] ]
[project.urls] [project.urls]
@@ -61,11 +60,31 @@ Changelog = "https://github.com/p-e-w/heretic/releases"
heretic = "heretic.main:main" heretic = "heretic.main:main"
[build-system] [build-system]
requires = ["uv_build>=0.8.11,<0.9.0"] requires = ["uv_build>=0.12.21,<0.13.0"]
build-backend = "uv_build" build-backend = "uv_build"
[tool.ruff.lint]
ignore = [
"B023", # "Function definition does not bind loop variable"
"BLE001", # "Do not catch blind exception"
"TRY002", # "Create your own exception"
"SIM117", # "Use a single `with` statement with multiple contexts instead of nested `with` statements"
]
[tool.uv] [tool.uv]
exclude-newer = "7 days" # TODO: Re-enable before 2.0 release!
#exclude-newer = "7 days"
[tool.uv.sources]
torch = { index = "pytorch" }
torchvision = { index = "pytorch" }
[[tool.uv.index]]
# Default to CPU wheels for PyTorch to avoid issues in CI.
# Can be overridden by passing `--index pytorch=<url>` to uv.
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
[tool.uv.build-backend] [tool.uv.build-backend]
module-name = "heretic" module-name = "heretic"
+3 -3
View File
@@ -2,7 +2,7 @@
# Copyright (C) 2025-2026 Philipp Emanuel Weidmann <pew@worldwidemann.com> + contributors # Copyright (C) 2025-2026 Philipp Emanuel Weidmann <pew@worldwidemann.com> + contributors
from enum import Enum from enum import Enum
from typing import Dict, Literal, TypeAlias from typing import Literal, TypeAlias
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
@@ -254,12 +254,12 @@ class Settings(BaseSettings):
), ),
) )
device_map: str | Dict[str, int | str] = Field( device_map: str | dict[str, int | str] = Field(
default="auto", default="auto",
description="Device map to pass to Accelerate when loading the model.", description="Device map to pass to Accelerate when loading the model.",
) )
max_memory: Dict[str, str] | None = Field( max_memory: dict[str, str] | None = Field(
default=None, default=None,
description='Maximum memory to allocate per device (e.g., { "0" = "20GB", "cpu" = "64GB" }).', description='Maximum memory to allocate per device (e.g., { "0" = "20GB", "cpu" = "64GB" }).',
) )
+5 -17
View File
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (C) 2025-2026 Philipp Emanuel Weidmann <pew@worldwidemann.com> + contributors # Copyright (C) 2025-2026 Philipp Emanuel Weidmann <pew@worldwidemann.com> + contributors
# ruff: noqa: E402
import sys import sys
# Ensure standard output/error use UTF-8 instead of system default charmap (e.g. cp1252 on Windows). # Ensure standard output/error use UTF-8 instead of system default charmap (e.g. cp1252 on Windows).
@@ -23,7 +21,7 @@ def _is_help_invocation() -> bool:
# Parse and handle CLI help before importing heavyweight ML/runtime dependencies. # Parse and handle CLI help before importing heavyweight ML/runtime dependencies.
if _is_help_invocation(): if _is_help_invocation():
Settings() # ty:ignore[missing-argument] Settings()
# FIXME: Rich progress bars are currently disabled because of rendering issues # FIXME: Rich progress bars are currently disabled because of rendering issues
# when used from multiple threads in parallel (e.g. by huggingface_hub). # when used from multiple threads in parallel (e.g. by huggingface_hub).
@@ -223,7 +221,7 @@ def run():
try: try:
# The required argument "model" must be provided by the user, # The required argument "model" must be provided by the user,
# either on the command line or in the configuration file. # either on the command line or in the configuration file.
settings = Settings() # ty:ignore[missing-argument] settings = Settings()
except ValidationError as error: except ValidationError as error:
print(f"[red]Configuration contains [bold]{error.error_count()}[/] errors:[/]") print(f"[red]Configuration contains [bold]{error.error_count()}[/] errors:[/]")
@@ -251,13 +249,11 @@ def run():
if reproduction_information["version"] != "4": if reproduction_information["version"] != "4":
print( print(
(
f"[red]Unsupported file format version: [bold]{reproduction_information['version']}[/].[/] " f"[red]Unsupported file format version: [bold]{reproduction_information['version']}[/].[/] "
"This version of Heretic reads version 4 (plugin-based) reproduce.json files. " "This version of Heretic reads version 4 (plugin-based) reproduce.json files. "
"Older files were produced before the introduction of the plugin system and are not supported. " "Older files were produced before the introduction of the plugin system and are not supported. "
"Please install Heretic 1.4 to use these files." "Please install Heretic 1.4 to use these files."
) )
)
return return
if not check_environment(settings, reproduction_information): if not check_environment(settings, reproduction_information):
@@ -339,13 +335,11 @@ def run():
if settings.checkpoint_action is None: if settings.checkpoint_action is None:
print() print()
print( print(
(
"[green]You have already processed this model.[/] " "[green]You have already processed this model.[/] "
"You can show the results from the previous run, allowing you to export models or to run additional trials. " "You can show the results from the previous run, allowing you to export models or to run additional trials. "
"Alternatively, you can ignore the previous run and start from scratch. " "Alternatively, you can ignore the previous run and start from scratch. "
"This will delete the checkpoint file and all results from the previous run." "This will delete the checkpoint file and all results from the previous run."
) )
)
choices.append( choices.append(
Choice( Choice(
@@ -357,13 +351,11 @@ def run():
if settings.checkpoint_action is None: if settings.checkpoint_action is None:
print() print()
print( print(
(
"[yellow]You have already processed this model, but the run was interrupted.[/] " "[yellow]You have already processed this model, but the run was interrupted.[/] "
"You can continue the previous run from where it stopped. This will override any specified settings. " "You can continue the previous run from where it stopped. This will override any specified settings. "
"Alternatively, you can ignore the previous run and start from scratch. " "Alternatively, you can ignore the previous run and start from scratch. "
"This will delete the checkpoint file and all results from the previous run." "This will delete the checkpoint file and all results from the previous run."
) )
)
choices.append( choices.append(
Choice( Choice(
@@ -771,13 +763,11 @@ def run():
if settings.trial_index is None: if settings.trial_index is None:
print() print()
print( print(
(
"The following trials resulted in Pareto optimal combinations of the optimization objectives. " "The following trials resulted in Pareto optimal combinations of the optimization objectives. "
"After selecting a trial, you will be able to save the model, upload it to Hugging Face, " "After selecting a trial, you will be able to save the model, upload it to Hugging Face, "
"chat with it to test how well it works, or run standard benchmarks on it. " "chat with it to test how well it works, or run standard benchmarks on it. "
"You can return to this menu later to select a different trial. " "You can return to this menu later to select a different trial. "
) )
)
while trial_loop_active: while trial_loop_active:
# Ensure a predefined trial is only processed once. # Ensure a predefined trial is only processed once.
@@ -1077,14 +1067,12 @@ def run():
if is_reproducible: if is_reproducible:
if settings.upload_reproducibility_information is None: if settings.upload_reproducibility_information is None:
print( print(
(
"Heretic can add information to the repository that allows others to reproduce the model. " "Heretic can add information to the repository that allows others to reproduce the model. "
"This is optional, but valuable to the community as both a learning tool and to preserve computational work already done. " "This is optional, but valuable to the community as both a learning tool and to preserve computational work already done. "
"Guaranteeing reproducibility requires basic system information (Python and OS version, CPU and GPU/accelerator info) " "Guaranteeing reproducibility requires basic system information (Python and OS version, CPU and GPU/accelerator info) "
"as tensor operations can give different results in different system environments. " "as tensor operations can give different results in different system environments. "
"[bold]The information does not include any file system paths or other private data.[/]" "[bold]The information does not include any file system paths or other private data.[/]"
) )
)
reproducibility_information = ask_if_unset( reproducibility_information = ask_if_unset(
settings.upload_reproducibility_information, settings.upload_reproducibility_information,
@@ -1115,7 +1103,7 @@ def run():
if strategy == ExportStrategy.ADAPTER: if strategy == ExportStrategy.ADAPTER:
print("Uploading LoRA adapter...") print("Uploading LoRA adapter...")
model.model.push_to_hub( model.model.push_to_hub(
repo_id, repo_id, # ty: ignore[invalid-argument-type]
private=private, private=private,
max_shard_size=settings.max_shard_size, max_shard_size=settings.max_shard_size,
token=token, token=token,
@@ -1124,7 +1112,7 @@ def run():
print("Uploading merged model...") print("Uploading merged model...")
merged_model = model.get_merged_model() merged_model = model.get_merged_model()
merged_model.push_to_hub( merged_model.push_to_hub(
repo_id, repo_id, # ty: ignore[invalid-argument-type]
private=private, private=private,
max_shard_size=settings.max_shard_size, max_shard_size=settings.max_shard_size,
token=token, token=token,
@@ -1319,7 +1307,7 @@ def run():
benchmark_original_model = scope == "Benchmark both models" benchmark_original_model = scope == "Benchmark both models"
hflm = HFLM( hflm = HFLM(
pretrained=model.model, # ty:ignore[invalid-argument-type] pretrained=model.model,
tokenizer=model.tokenizer, # ty:ignore[invalid-argument-type] tokenizer=model.tokenizer, # ty:ignore[invalid-argument-type]
batch_size="auto", batch_size="auto",
) )
+36 -29
View File
@@ -1,8 +1,9 @@
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (C) 2025-2026 Philipp Emanuel Weidmann <pew@worldwidemann.com> + contributors # Copyright (C) 2025-2026 Philipp Emanuel Weidmann <pew@worldwidemann.com> + contributors
from collections.abc import Callable
from contextlib import suppress from contextlib import suppress
from typing import Any, Callable, Type, TypeAlias, cast from typing import Any, TypeAlias, cast
import torch import torch
from peft import LoraConfig, PeftModel, get_peft_model from peft import LoraConfig, PeftModel, get_peft_model
@@ -23,7 +24,7 @@ from transformers import (
TextStreamer, TextStreamer,
) )
from transformers.generation import ( from transformers.generation import (
GenerateDecoderOnlyOutput, # ty:ignore[possibly-missing-import] GenerateDecoderOnlyOutput,
) )
from .config import QuantizationMethod, Settings from .config import QuantizationMethod, Settings
@@ -33,10 +34,10 @@ from .utils import Prompt, batchify, format_exception, print
def get_model_class( def get_model_class(
model: str, model: str,
) -> Type[AutoModelForImageTextToText] | Type[AutoModelForCausalLM]: ) -> type[AutoModelForImageTextToText] | type[AutoModelForCausalLM]:
configs = PretrainedConfig.get_config_dict(model) configs = PretrainedConfig.get_config_dict(model)
if any([("vision_config" in config) for config in configs]): if any(("vision_config" in config) for config in configs):
return AutoModelForImageTextToText return AutoModelForImageTextToText
else: else:
return AutoModelForCausalLM return AutoModelForCausalLM
@@ -68,9 +69,14 @@ class Model:
print() print()
print(f"Loading model [bold]{settings.model}[/]...") print(f"Loading model [bold]{settings.model}[/]...")
self.tokenizer = AutoTokenizer.from_pretrained( # PreTrainedTokenizerBase is the "base class for all tokenizer backends"
# according to the documentation.
self.tokenizer = cast(
PreTrainedTokenizerBase,
AutoTokenizer.from_pretrained(
settings.model, settings.model,
**self.revision_kwargs, **self.revision_kwargs,
),
) )
# Multimodal models have a processor we'll want to save. # Multimodal models have a processor we'll want to save.
@@ -90,7 +96,7 @@ class Model:
# after the prompt and thinks the sequence is complete. # after the prompt and thinks the sequence is complete.
self.tokenizer.padding_side = "left" self.tokenizer.padding_side = "left"
self.model = None # ty:ignore[invalid-assignment] self.model = None
self.max_memory = ( self.max_memory = (
{int(k) if k.isdigit() else k: v for k, v in settings.max_memory.items()} {int(k) if k.isdigit() else k: v for k, v in settings.max_memory.items()}
if settings.max_memory if settings.max_memory
@@ -143,7 +149,7 @@ class Model:
max_new_tokens=1, max_new_tokens=1,
) )
except Exception as error: except Exception as error:
self.model = None # ty:ignore[invalid-assignment] self.model = None
empty_cache() empty_cache()
formatted = format_exception(error) formatted = format_exception(error)
@@ -315,7 +321,7 @@ class Model:
return True return True
# Purge existing model object from memory to make space. # Purge existing model object from memory to make space.
self.model = None # ty:ignore[invalid-assignment] self.model = None
empty_cache() empty_cache()
quantization_config = self._get_quantization_config( quantization_config = self._get_quantization_config(
@@ -352,10 +358,10 @@ class Model:
# Most multimodal models. # Most multimodal models.
with suppress(Exception): with suppress(Exception):
return model.model.language_model.layers return model.model.language_model.layers # ty: ignore[unresolved-attribute, invalid-return-type]
# Text-only models. # Text-only models.
return model.model.layers return model.model.layers # ty: ignore[unresolved-attribute, invalid-return-type]
def get_layer_modules(self, layer_index: int) -> dict[str, list[Module]]: def get_layer_modules(self, layer_index: int) -> dict[str, list[Module]]:
layer = self.get_layers()[layer_index] layer = self.get_layers()[layer_index]
@@ -376,50 +382,50 @@ class Model:
# Standard self-attention out-projection (most models). # Standard self-attention out-projection (most models).
with suppress(Exception): with suppress(Exception):
try_add("attn.o_proj", layer.self_attn.o_proj) # ty:ignore[possibly-missing-attribute] try_add("attn.o_proj", layer.self_attn.o_proj) # ty: ignore[unresolved-attribute]
# Qwen3.5 MoE hybrid layers use GatedDeltaNet (linear attention) instead of # 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. # standard self-attention, so self_attn.o_proj doesn't exist on those layers.
with suppress(Exception): with suppress(Exception):
try_add("attn.o_proj", layer.linear_attn.out_proj) # ty:ignore[possibly-missing-attribute] try_add("attn.o_proj", layer.linear_attn.out_proj) # ty: ignore[unresolved-attribute]
# Most dense models. # Most dense models.
with suppress(Exception): with suppress(Exception):
try_add("mlp.down_proj", layer.mlp.down_proj) # ty:ignore[possibly-missing-attribute] try_add("mlp.down_proj", layer.mlp.down_proj) # ty: ignore[unresolved-attribute]
# Some MoE models (e.g. Qwen3). # Some MoE models (e.g. Qwen3).
with suppress(Exception): with suppress(Exception):
for expert in layer.mlp.experts: # ty:ignore[possibly-missing-attribute, not-iterable] for expert in layer.mlp.experts: # ty:ignore[not-iterable, unresolved-attribute]
try_add("mlp.down_proj", expert.down_proj) # ty:ignore[possibly-missing-attribute] try_add("mlp.down_proj", expert.down_proj) # ty: ignore[unresolved-attribute]
# Phi-3.5-MoE (and possibly others). # Phi-3.5-MoE (and possibly others).
with suppress(Exception): with suppress(Exception):
for expert in layer.block_sparse_moe.experts: # ty:ignore[possibly-missing-attribute, not-iterable] for expert in layer.block_sparse_moe.experts: # ty:ignore[not-iterable, unresolved-attribute]
try_add("mlp.down_proj", expert.w2) # ty:ignore[possibly-missing-attribute] try_add("mlp.down_proj", expert.w2) # ty: ignore[unresolved-attribute]
# LFM dense operator blocks. # LFM dense operator blocks.
with suppress(Exception): with suppress(Exception):
try_add("attn.o_proj", layer.conv.out_proj) # ty:ignore[possibly-missing-attribute] try_add("attn.o_proj", layer.conv.out_proj) # ty: ignore[unresolved-attribute]
with suppress(Exception): with suppress(Exception):
try_add("mlp.down_proj", layer.feed_forward.w2) # ty:ignore[possibly-missing-attribute] try_add("mlp.down_proj", layer.feed_forward.w2) # ty: ignore[unresolved-attribute]
# LFM transformer blocks. # LFM transformer blocks.
with suppress(Exception): with suppress(Exception):
try_add("attn.o_proj", layer.self_attn.out_proj) # ty:ignore[possibly-missing-attribute] try_add("attn.o_proj", layer.self_attn.out_proj) # ty: ignore[unresolved-attribute]
with suppress(Exception): with suppress(Exception):
for expert in layer.feed_forward.experts: # ty:ignore[possibly-missing-attribute, not-iterable] for expert in layer.feed_forward.experts: # ty:ignore[not-iterable, unresolved-attribute]
try_add("mlp.down_proj", expert.w2) # ty:ignore[possibly-missing-attribute] try_add("mlp.down_proj", expert.w2) # ty: ignore[unresolved-attribute]
# Granite MoE Hybrid - attention layers with shared_mlp. # Granite MoE Hybrid - attention layers with shared_mlp.
with suppress(Exception): with suppress(Exception):
try_add("mlp.down_proj", layer.shared_mlp.output_linear) # ty:ignore[possibly-missing-attribute] try_add("mlp.down_proj", layer.shared_mlp.output_linear) # ty: ignore[unresolved-attribute]
# Granite MoE Hybrid - MoE layers with experts. # Granite MoE Hybrid - MoE layers with experts.
with suppress(Exception): with suppress(Exception):
for expert in layer.moe.experts: # ty:ignore[possibly-missing-attribute, not-iterable] for expert in layer.moe.experts: # ty:ignore[not-iterable, unresolved-attribute]
try_add("mlp.down_proj", expert.output_linear) # ty:ignore[possibly-missing-attribute] try_add("mlp.down_proj", expert.output_linear) # ty: ignore[unresolved-attribute]
# We need at least one module across all components for abliteration to work. # We need at least one module across all components for abliteration to work.
total_modules = sum(len(mods) for mods in modules.values()) total_modules = sum(len(mods) for mods in modules.values())
@@ -512,11 +518,12 @@ class Model:
responses = [] responses = []
for batch in batchify(prompts, self.settings.batch_size): for batch in batchify(prompts, self.settings.batch_size):
for response in self.get_responses( responses.extend(
self.get_responses(
batch, batch,
skip_special_tokens=skip_special_tokens, skip_special_tokens=skip_special_tokens,
): )
responses.append(response) )
return responses return responses
@@ -809,7 +816,7 @@ class Model:
# The TextStreamer constructor annotates this parameter with the AutoTokenizer # The TextStreamer constructor annotates this parameter with the AutoTokenizer
# type, which makes no sense because AutoTokenizer is a factory class, # type, which makes no sense because AutoTokenizer is a factory class,
# not a base class that tokenizers inherit from. # not a base class that tokenizers inherit from.
self.tokenizer, # ty:ignore[invalid-argument-type] self.tokenizer,
skip_prompt=True, skip_prompt=True,
skip_special_tokens=True, skip_special_tokens=True,
) )
+1 -1
View File
@@ -32,7 +32,7 @@ class Serializable(Protocol):
Parameters = TypeVar("Parameters", bound=Serializable) Parameters = TypeVar("Parameters", bound=Serializable)
class Modifier(Generic[Parameters], Plugin, ABC): class Modifier(Plugin, ABC, Generic[Parameters]):
""" """
Abstract base class for modifier plugins. Abstract base class for modifier plugins.
+4 -11
View File
@@ -6,7 +6,7 @@ from dataclasses import asdict, dataclass
from enum import Enum from enum import Enum
from typing import Any, cast from typing import Any, cast
import bitsandbytes as bnb import bitsandbytes.functional as BNB_F
import torch import torch
import torch.linalg as LA import torch.linalg as LA
import torch.nn.functional as F import torch.nn.functional as F
@@ -332,9 +332,7 @@ class Abliteration(Modifier[Parameters]):
weight_distribution = parameters.weight_distributions[component] weight_distribution = parameters.weight_distributions[component]
# Type inference fails here for some reason. # Type inference fails here for some reason.
distance = cast( distance = abs(layer_index - weight_distribution.max_weight_position)
float, abs(layer_index - weight_distribution.max_weight_position)
)
# Don't orthogonalize layers that are more than # Don't orthogonalize layers that are more than
# min_weight_distance away from max_weight_position. # min_weight_distance away from max_weight_position.
@@ -390,15 +388,10 @@ class Abliteration(Modifier[Parameters]):
W = base_weight.to(torch.float32) W = base_weight.to(torch.float32)
else: else:
# 4-bit quantization. # 4-bit quantization.
# This cast is always valid. Type inference fails here because the W = BNB_F.dequantize_4bit(
# bnb.functional module is not found by ty for some reason.
W = cast(
Tensor,
bnb.functional.dequantize_4bit( # ty:ignore[possibly-missing-attribute]
base_weight.data, base_weight.data,
quant_state, quant_state,
).to(torch.float32), ).to(torch.float32)
)
# Flatten weight matrix to (out_features, in_features). # Flatten weight matrix to (out_features, in_features).
W = W.view(W.shape[0], -1) W = W.view(W.shape[0], -1)
+3 -6
View File
@@ -7,7 +7,7 @@
from dataclasses import asdict, dataclass from dataclasses import asdict, dataclass
from typing import Any, cast from typing import Any, cast
import bitsandbytes as bnb import bitsandbytes.functional as BNB_F
import torch import torch
import torch.linalg as LA import torch.linalg as LA
import torch.nn.functional as F import torch.nn.functional as F
@@ -264,13 +264,10 @@ class ARA(Modifier[Parameters]):
W_base = base_weight.to(torch.float32) W_base = base_weight.to(torch.float32)
else: else:
# Use the original dequantization logic from bitsandbytes. # Use the original dequantization logic from bitsandbytes.
W_base = cast( W_base = BNB_F.dequantize_4bit(
Tensor,
bnb.functional.dequantize_4bit( # ty:ignore[possibly-missing-attribute]
base_weight.data, base_weight.data,
quant_state, quant_state,
).to(torch.float32), ).to(torch.float32)
)
# Pre-calculate the original row norms to preserve them. # Pre-calculate the original row norms to preserve them.
# See https://huggingface.co/blog/grimjim/norm-preserving-biprojected-abliteration # See https://huggingface.co/blog/grimjim/norm-preserving-biprojected-abliteration
+1 -1
View File
@@ -362,4 +362,4 @@ class Plugin:
Override this in subclasses to do one-time setup (e.g. load prompts, compute Override this in subclasses to do one-time setup (e.g. load prompts, compute
baselines). baselines).
""" """
return None return
+1 -7
View File
@@ -81,7 +81,7 @@ def collect_reproducibles(path: str):
found += 1 found += 1
commit_hash = paths_info[0].last_commit.oid commit_hash = paths_info[0].last_commit.oid # ty: ignore[unresolved-attribute]
file_path = ( file_path = (
Path(path) Path(path)
@@ -285,13 +285,11 @@ def check_environment(
else: else:
print( print(
(
"[yellow]The provided JSON file does not contain system information. " "[yellow]The provided JSON file does not contain system information. "
"Some system parameters can affect reproducibility, but due to the lack of 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. " "Heretic is unable to verify that those parameters match the original environment. "
"Reproduction may or may not produce a byte-for-byte identical model.[/]" "Reproduction may or may not produce a byte-for-byte identical model.[/]"
) )
)
requirements = get_requirements_dict() requirements = get_requirements_dict()
requirements["heretic-llm"] = format_version_information( requirements["heretic-llm"] = format_version_information(
@@ -321,11 +319,9 @@ def check_environment(
if system_mismatches or package_mismatches: if system_mismatches or package_mismatches:
print() print()
print( print(
(
"[yellow]Your local environment doesn't perfectly match the environment " "[yellow]Your local environment doesn't perfectly match the environment "
"used to produce the original model. The following components differ:[/]" "used to produce the original model. The following components differ:[/]"
) )
)
if system_mismatches: if system_mismatches:
table = Table() table = Table()
@@ -358,13 +354,11 @@ def check_environment(
if system_mismatches or package_mismatches: if system_mismatches or package_mismatches:
print() print()
print( print(
(
f"There is a {cast(MismatchSeverity, mismatch_severity).__rich__()} chance " f"There is a {cast(MismatchSeverity, mismatch_severity).__rich__()} chance "
"that reproduction won't produce a byte-for-byte identical model. " "that reproduction won't produce a byte-for-byte identical model. "
"However, the resulting model will very likely still behave similarly " "However, the resulting model will very likely still behave similarly "
"to the original model." "to the original model."
) )
)
if settings.ignore_mismatches is None: if settings.ignore_mismatches is None:
print() print()
+1 -1
View File
@@ -44,7 +44,7 @@ class BenchmarkScore(Scorer):
model = ctx.get_model() model = ctx.get_model()
self.hflm = HFLM( self.hflm = HFLM(
pretrained=model.model, # ty:ignore[invalid-argument-type] pretrained=model.model,
tokenizer=model.tokenizer, # ty:ignore[invalid-argument-type] tokenizer=model.tokenizer, # ty:ignore[invalid-argument-type]
batch_size="auto", batch_size="auto",
) )
+4 -4
View File
@@ -96,7 +96,7 @@ def get_amdgpu_driver_version() -> str | None:
if os.path.exists(version_path): if os.path.exists(version_path):
with open(version_path, "r", encoding="utf-8") as f: with open(version_path, "r", encoding="utf-8") as f:
return f.read().strip() return f.read().strip()
except Exception: except Exception: # noqa: S110
pass pass
return None return None
@@ -249,7 +249,7 @@ def get_accelerator_info_dict() -> dict[str, Any]:
info: dict[str, Any] = { info: dict[str, Any] = {
"type": "ROCm" if is_rocm else "CUDA", "type": "ROCm" if is_rocm else "CUDA",
"api_name": "HIP Version" if is_rocm else "CUDA Version", "api_name": "HIP Version" if is_rocm else "CUDA Version",
"api_version": torch.version.hip if is_rocm else torch.version.cuda, # ty:ignore[unresolved-attribute] "api_version": torch.version.hip if is_rocm else torch.version.cuda,
"driver_version": get_amdgpu_driver_version() "driver_version": get_amdgpu_driver_version()
if is_rocm if is_rocm
else get_nvidia_driver_version(), else get_nvidia_driver_version(),
@@ -264,13 +264,13 @@ def get_accelerator_info_dict() -> dict[str, Any]:
return info return info
if is_xpu_available(): if is_xpu_available():
count = torch.xpu.device_count() # ty:ignore[unresolved-attribute] count = torch.xpu.device_count()
return { return {
"type": "XPU", "type": "XPU",
"api_name": None, "api_name": None,
"api_version": None, "api_version": None,
"driver_version": get_xpu_driver_version(), "driver_version": get_xpu_driver_version(),
"devices": [{"name": torch.xpu.get_device_name(i)} for i in range(count)], # ty:ignore[unresolved-attribute] "devices": [{"name": torch.xpu.get_device_name(i)} for i in range(count)],
} }
if is_mlu_available(): if is_mlu_available():
-7
View File
@@ -1,7 +0,0 @@
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
-7
View File
@@ -1,7 +0,0 @@
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
-7
View File
@@ -1,7 +0,0 @@
2f1b4d75d067bae3fe44e676721c7f077d243bc007156cb9c2f8b5836613d082 *chat_template.jinja
ca80080dfa4ec6ba87152fa2b9afe70b90c400e5c4b1d6bdc3aa3114467ca68f *config.json
70070bac883cf9c39b5992450d6b23cd160eaf33099e24c654e0359d2f87c760 *generation_config.json
9ff0593e3fbd0ba463bbc980ebb3ed34798e562b606f90cd93c2df5403732c7b *model.safetensors
32bdf45d2ad4cc29a0822ddd157a182de76644f0419a6228d151495256e9813c *processor_config.json
cc8d3a0ce36466ccc1278bf987df5f71db1719b9ca6b4118264f45cb627bfe0f *tokenizer.json
a1bab8c81ed15fa6ce912ec993c66cb49392e0487fb1ea5f5f11ea3618683627 *tokenizer_config.json
+2 -2
View File
@@ -1,6 +1,6 @@
2f1b4d75d067bae3fe44e676721c7f077d243bc007156cb9c2f8b5836613d082 *chat_template.jinja 2f1b4d75d067bae3fe44e676721c7f077d243bc007156cb9c2f8b5836613d082 *chat_template.jinja
ca80080dfa4ec6ba87152fa2b9afe70b90c400e5c4b1d6bdc3aa3114467ca68f *config.json c128bc8647a505e343c8cdff9bdd188b1a4a3f81938148685cbf90dff9827268 *config.json
70070bac883cf9c39b5992450d6b23cd160eaf33099e24c654e0359d2f87c760 *generation_config.json 58678fb2b8ae1b96652dffa43f864ad1c1c59e49c889bab4264ba0844c4a23b8 *generation_config.json
effe36925f85ecb1e29bba84501a456bb49df21e4047be8b7ea3f6f88181fb65 *model.safetensors effe36925f85ecb1e29bba84501a456bb49df21e4047be8b7ea3f6f88181fb65 *model.safetensors
32bdf45d2ad4cc29a0822ddd157a182de76644f0419a6228d151495256e9813c *processor_config.json 32bdf45d2ad4cc29a0822ddd157a182de76644f0419a6228d151495256e9813c *processor_config.json
cc8d3a0ce36466ccc1278bf987df5f71db1719b9ca6b4118264f45cb627bfe0f *tokenizer.json cc8d3a0ce36466ccc1278bf987df5f71db1719b9ca6b4118264f45cb627bfe0f *tokenizer.json
-7
View File
@@ -1,7 +0,0 @@
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
+2 -2
View File
@@ -1,6 +1,6 @@
f8d9255777615591a7cc1a7c932f5a69e181128902295e1b81221d20d983cac7 *chat_template.jinja f8d9255777615591a7cc1a7c932f5a69e181128902295e1b81221d20d983cac7 *chat_template.jinja
91d2a5190c7ea0f74ed499428d4ad62b5208d63b36f7bbb562d15f4be25bd5c2 *config.json 22d559dde87f1a0faf02efed3062af2b1fc8a1721a55b952cd5f5d8c356b4feb *config.json
dd6034a30113decdfaf8886622e20eb9e2e02d3f774918d474a4e26cfd7fbba8 *generation_config.json 523e422e425e7a7ba23d85cc0faeef143dc5da37b72bfc649df5a8d83ee95beb *generation_config.json
aefe8b9c4b4969f6d13c5d778760f3dce4e25134324b33677934550d9df02a7c *model.safetensors aefe8b9c4b4969f6d13c5d778760f3dce4e25134324b33677934550d9df02a7c *model.safetensors
fce342a4642cb8afc42d8d89cfa21198b64a43458ded7f6ff28d1151a08c9cda *tokenizer.json fce342a4642cb8afc42d8d89cfa21198b64a43458ded7f6ff28d1151a08c9cda *tokenizer.json
9ba5fa877168e24823cb583c55b4c2e4df0331f30084953c7cf07de294640384 *tokenizer_config.json 9ba5fa877168e24823cb583c55b4c2e4df0331f30084953c7cf07de294640384 *tokenizer_config.json
@@ -1,6 +1,6 @@
7451a05cf1e28a79d97d7c0bc951028c0b1915119bf9046acd06a0e3d931f47c *chat_template.jinja 7451a05cf1e28a79d97d7c0bc951028c0b1915119bf9046acd06a0e3d931f47c *chat_template.jinja
fe6fd41d9f2ce5d6486748cf0330b574f37bf7d4e915f7b39d1af1a185cac3c3 *config.json de44f54b200f63c8ccb7899965bc9aaf21b23d35164c7de9a3cc3394530e3821 *config.json
c4c2ef5ae4a4e2dd10655a3b99d801a8a50497286ddd042ba35bcfefc44ad349 *generation_config.json 12d96814a0cd1a72cae14392b04b9644353e8600614faa6eb7ee5edbf9452ec1 *generation_config.json
1535a9b7a91b2cb39ad280dbd9a940e2609a0b423d5b924df4d664e579912802 *model.safetensors 1535a9b7a91b2cb39ad280dbd9a940e2609a0b423d5b924df4d664e579912802 *model.safetensors
ad92aaa8d3032c98a9158b8c5e8682bed10027ed6463e4fb1320fe5384210873 *tokenizer.json ad92aaa8d3032c98a9158b8c5e8682bed10027ed6463e4fb1320fe5384210873 *tokenizer.json
3ad32522c384dbe35192bb69de9befbf3f523e99d4bb3f95da757671d4c28281 *tokenizer_config.json 3ad32522c384dbe35192bb69de9befbf3f523e99d4bb3f95da757671d4c28281 *tokenizer_config.json
-6
View File
@@ -1,6 +0,0 @@
d8db3ff45c4c68a0ba9dee962ff1a0adde9a2be55e0895306f6bd2b2756f5adb *chat_template.jinja
a9d6f64bb9d0c02b553119e475615153af625b5c2a16ccb8fb8b3c2cc348f465 *config.json
0e7611a1e8fd0a06a139b0572b2c55b885ba9fb7db2022873c3508aebfb488aa *generation_config.json
411d95f42d3e31aef41c28314c8f0431c980687a97904d32b4ef57c42199720f *model.safetensors
ad92aaa8d3032c98a9158b8c5e8682bed10027ed6463e4fb1320fe5384210873 *tokenizer.json
aa083f3da10340925734e876e41e235c459329294ecd35d7511ec5868c1f14e3 *tokenizer_config.json
-7
View File
@@ -1,7 +0,0 @@
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
-7
View File
@@ -1,7 +0,0 @@
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
+4 -4
View File
@@ -1,7 +1,7 @@
39f03c383413f531fd302c06c7e982ad98c83f0657a8339ae25478ccb81fdcda *chat_template.jinja 39f03c383413f531fd302c06c7e982ad98c83f0657a8339ae25478ccb81fdcda *chat_template.jinja
f69f84977a47c8fea9ce9fc26b7de379216cb01146ea726a87996d3554cfcd19 *config.json b2cfd8a9da09efc97040f3839fe629f3925db856a44b58314301dc5e11345ec8 *config.json
34dfa6012ca9ac5f57e5521d8dbaecbc7ab7f7ab0fd96ec020b543aab5f265d9 *generation_config.json 338d303c3c3df6884030cf5be24560f6e973fc183220d14acfb9364cd0e070e4 *generation_config.json
29aff97d5633dead9e1ccd29a2cc153b4b7431d22f63c8d6cf60bc6547681cc9 *model.safetensors 8244162ecb6ce7bad7b10fe4f015889d76a09c7749dc7ac8c4d957f0864b2e82 *model.safetensors
84be30b124b50749c56d25fdbec5ccedf564446f6b3b035e88e1e07b986d2491 *processor_config.json a05f93a41b7e42ccc18461b540fb54490c3ffa13aef79c800bbe7942e02e360f *processor_config.json
c3a8d92e371b92a2cd6e678e31ebc27d0235e929a51fbf290f74742b341fa96f *tokenizer.json c3a8d92e371b92a2cd6e678e31ebc27d0235e929a51fbf290f74742b341fa96f *tokenizer.json
7b29c843c0043622d28fd4638451cbb0a609d99a0762ffbff3b92b4b2fee4d94 *tokenizer_config.json 7b29c843c0043622d28fd4638451cbb0a609d99a0762ffbff3b92b4b2fee4d94 *tokenizer_config.json
-7
View File
@@ -1,7 +0,0 @@
72f84af4ea36b82409c35e31b584361534305ef7c0d90fce20d0dc38a7efead8 *chat_template.jinja
e4c5278b361c57621253c27a2c3db358e1580aec8a14be8e19d4420a224137cf *config.json
8dde85c000ae807be907421465826c7c63a39f6acf6d04a5a84efaf116ed4ef7 *generation_config.json
20b5a820b38438202c64e4fc9807bd19e29678bebd678d29b2ee2d2f5bf71587 *model.safetensors
20e7a6dcde0a6f60ea3b4fb08f6f7afa62532dda93a3111e28384ba5150575f9 *processor_config.json
c3a8d92e371b92a2cd6e678e31ebc27d0235e929a51fbf290f74742b341fa96f *tokenizer.json
60a8042e29b4b20e884e48375aa1b9ac0025547371d50e60f6d55e6a9675e868 *tokenizer_config.json
-6
View File
@@ -1,6 +0,0 @@
cd8e9439f0570856fd70470bf8889ebd8b5d1107207f67a5efb46e342330527f *chat_template.jinja
45134b857367fdcb97c0179199848c353fc28f8b95ac2244ac8f45cca448d864 *config.json
e81e23e025c38e825dcf8375861e26a90e804276e4db9ee390122a4fdc95dae7 *generation_config.json
e616cbeb5a913015eb3db96e001030048df2db560df363d4cf688f0c1b2c96de *model.safetensors
f7f96da3a872b5e901575b2067c744ad336c3a3d77a21584d20024557b1bd7f0 *tokenizer.json
04b1682c59acbd057f4c9072297faa73d56fc9de053094c659cdb4c464f58f86 *tokenizer_config.json
@@ -1,6 +1,6 @@
cd8e9439f0570856fd70470bf8889ebd8b5d1107207f67a5efb46e342330527f *chat_template.jinja cd8e9439f0570856fd70470bf8889ebd8b5d1107207f67a5efb46e342330527f *chat_template.jinja
45134b857367fdcb97c0179199848c353fc28f8b95ac2244ac8f45cca448d864 *config.json 6b517667960a5e39a692eb8277be7260ac02c22d9c7eda9c7aa1bbab21517fc1 *config.json
e81e23e025c38e825dcf8375861e26a90e804276e4db9ee390122a4fdc95dae7 *generation_config.json 64cf6f4e0016154cae45628221d77e3925961876125fe68bd942303ec7cca40f *generation_config.json
bd86541d817978c896bd3579e69ae6d41b6382eaf1646accf83d6feb16acb703 *model.safetensors bd86541d817978c896bd3579e69ae6d41b6382eaf1646accf83d6feb16acb703 *model.safetensors
f7f96da3a872b5e901575b2067c744ad336c3a3d77a21584d20024557b1bd7f0 *tokenizer.json f7f96da3a872b5e901575b2067c744ad336c3a3d77a21584d20024557b1bd7f0 *tokenizer.json
04b1682c59acbd057f4c9072297faa73d56fc9de053094c659cdb4c464f58f86 *tokenizer_config.json 04b1682c59acbd057f4c9072297faa73d56fc9de053094c659cdb4c464f58f86 *tokenizer_config.json
-6
View File
@@ -1,6 +0,0 @@
8aa40ce145adb73cb3a75194dc0224702a95850ec5275cabb728496bbd749fc6 *chat_template.jinja
e8f2fcd2681eb92233c0902866441f79a207b235f0b03364d41ebf8c53df62a0 *config.json
3fec6d7004e5ae311864de130b62e32dac87569874c91b3fe9c46e9309345c1c *generation_config.json
bd86541d817978c896bd3579e69ae6d41b6382eaf1646accf83d6feb16acb703 *model.safetensors
f7f96da3a872b5e901575b2067c744ad336c3a3d77a21584d20024557b1bd7f0 *tokenizer.json
154e5ff1e7c152d964edf30da854ea62465c767719ac8e97e58babf2d4fa9079 *tokenizer_config.json
-7
View File
@@ -1,7 +0,0 @@
a4aee8afcf2e0711942cf848899be66016f8d14a889ff9ede07bca099c28f715 *chat_template.jinja
749b56d1b1e08081981169db6f2c44ab0be4fd6ebb452d15baafa5e09c21586a *config.json
4625d1d64d41d1fa9dae7af4ba1e1d7e65a194073d4efa58acb266a916eaaa74 *generation_config.json
2b3e575ac065f11ae5d4a7c3740efccbed294b646f1645239191ee8393354e03 *model.safetensors
01562eddd6f9e9ec4bc31656a3b7055284cafbf889acc6c4348dca431ae31f68 *processor_config.json
87a7830d63fcf43bf241c3c5242e96e62dd3fdc29224ca26fed8ea333db72de4 *tokenizer.json
2e31d1126e81bddf8d15c3f95260fb487b48c5131b24fcbb5bb9d2537e7afac0 *tokenizer_config.json
+6 -6
View File
@@ -1,7 +1,7 @@
a4aee8afcf2e0711942cf848899be66016f8d14a889ff9ede07bca099c28f715 *chat_template.jinja a4aee8afcf2e0711942cf848899be66016f8d14a889ff9ede07bca099c28f715 *chat_template.jinja
749b56d1b1e08081981169db6f2c44ab0be4fd6ebb452d15baafa5e09c21586a *config.json 4b501bef0727793de90d446fcfdc7757a9f8d19efc42ceaa3d26e90db4f876d5 *config.json
4625d1d64d41d1fa9dae7af4ba1e1d7e65a194073d4efa58acb266a916eaaa74 *generation_config.json 532190619b0b243e0558a846257cc62883c26df812d456f8133e7b1043c69ad8 *generation_config.json
5e0fb0ac724cf079b693fc76a515e60bc16de72c32b36c107b9f078061c4f2ef *model.safetensors 4c29b8ce99c59c90eca59aa6453029bda87165efa57cabc2c668599c02afc31a *model.safetensors
01562eddd6f9e9ec4bc31656a3b7055284cafbf889acc6c4348dca431ae31f68 *processor_config.json 3814737f2d4bfdd153a82364b3850f1be5dbc6f074a55c8d5fbf4d40127c3e87 *processor_config.json
87a7830d63fcf43bf241c3c5242e96e62dd3fdc29224ca26fed8ea333db72de4 *tokenizer.json a5cd9732badce41de57e6efce8302930ded1c1188c5f81feb2bd6c24c4a1941f *tokenizer.json
2e31d1126e81bddf8d15c3f95260fb487b48c5131b24fcbb5bb9d2537e7afac0 *tokenizer_config.json 5e55dc6b9d9d28d49b6b2b80d2a2f2558a0b6e0e7b194bbca8664fc269ab3ebc *tokenizer_config.json
-7
View File
@@ -1,7 +0,0 @@
a92e1dd97cb1cb175c9b70c0828e146bea4371c2643319b661b777e89811972e *chat_template.jinja
b75e911805663da79fb9fbbbcc917b8f1a285d2da54d95c2c63ea7c1ffe9a05a *config.json
2cbd9df0e99570efcced23b8d777bdf1fc692efda54b21eb59ad56ade76c9db6 *generation_config.json
6061519a9595326df41abcdd093892463793d4d026d6fd23548f1792f622a252 *model.safetensors
0c29f9491e769aabbc389ad5912127cf6d9d5fceda2db8767f73d48131348c81 *processor_config.json
87a7830d63fcf43bf241c3c5242e96e62dd3fdc29224ca26fed8ea333db72de4 *tokenizer.json
4796e48d790a26d65f167bec8fc742beaa71f79f9468a6cd8b3ffa97f6e2a198 *tokenizer_config.json
+6 -8
View File
@@ -53,7 +53,7 @@ for test_directory in script_directory.iterdir():
print() print()
valid_hashes: dict[str, list[str]] = {} valid_hashes: dict[str, set[str]] = {}
for hash_file in hash_files: for hash_file in hash_files:
with open(hash_file, "r", encoding="utf-8") as file: with open(hash_file, "r", encoding="utf-8") as file:
@@ -63,26 +63,24 @@ for test_directory in script_directory.iterdir():
filename = filename.removeprefix("*") filename = filename.removeprefix("*")
if filename not in valid_hashes: if filename not in valid_hashes:
valid_hashes[filename] = [] valid_hashes[filename] = set()
valid_hashes[filename].append(sha256.lower()) valid_hashes[filename].add(sha256.lower())
# Track which specific files failed within this test directory. # Track which specific files failed within this test directory.
failed_files: list[str] = [] failed_files: list[str] = []
for filename in valid_hashes: for filename, hashes in valid_hashes.items():
sha256 = get_file_sha256(test_directory / "model" / filename) sha256 = get_file_sha256(test_directory / "model" / filename)
if sha256.lower() not in valid_hashes[filename]: if sha256.lower() not in hashes:
print( print(
(
f"Test {test_directory.name} has FAILED!\n" f"Test {test_directory.name} has FAILED!\n"
f"Output file {filename} doesn't match any valid hash.\n\n" f"Output file {filename} doesn't match any valid hash.\n\n"
f"Valid hashes:\n" f"Valid hashes:\n"
f"{chr(10).join(valid_hashes[filename])}\n\n" f"{chr(10).join(hashes)}\n\n"
f"Actual hash:\n" f"Actual hash:\n"
f"{sha256}\n" f"{sha256}\n"
) )
)
failed_files.append(filename) failed_files.append(filename)
if failed_files: if failed_files:
+2 -2
View File
@@ -1,6 +1,6 @@
39a23a1a28f68acd747373fa688bea630021ec4db2bc8dec2fd3962240fb0418 *chat_template.jinja 39a23a1a28f68acd747373fa688bea630021ec4db2bc8dec2fd3962240fb0418 *chat_template.jinja
35e3ad5aeaa78984629ceba6c22a4236b4c21d6959485900da2a5a98ea7e4062 *config.json 45d58c7316e9dab89e918b9ca1c141b8c7f5250d55e0f9be76f2f452903aeef8 *config.json
2ec7a17f55287d482ca956f5acff44d9e88f6c7fd5ec06c7c33d641afa9af330 *generation_config.json 02b35dff3057b998f224a3a5599dc7737ba028e3b4181ba89ba74ba1e707a5dc *generation_config.json
0cdea9064dcbe6db666f9d42a283d664c133d4c67a2f6ea0fd863a54f522160c *model.safetensors 0cdea9064dcbe6db666f9d42a283d664c133d4c67a2f6ea0fd863a54f522160c *model.safetensors
3cf3a6d9520f195638a36f0194239d817de7288710bca55f1f5753de226748f7 *tokenizer.json 3cf3a6d9520f195638a36f0194239d817de7288710bca55f1f5753de226748f7 *tokenizer.json
388b47e61cb40f2fd51a89999053686ab4c45b40b43c0329d15645f5910d069e *tokenizer_config.json 388b47e61cb40f2fd51a89999053686ab4c45b40b43c0329d15645f5910d069e *tokenizer_config.json
Generated
+2908 -1984
View File
File diff suppressed because it is too large Load Diff