diff options
| author | tanaka takashi <isazaka@gmail.com> | 2026-09-12 22:26:13 +0900 |
|---|---|---|
| committer | tanaka takashi <isazaka@gmail.com> | 2026-09-12 22:26:13 +0900 |
| commit | 546eca3591515b26516922860fe2cf1b573a5f82 (patch) | |
| tree | 639cb25c732ca096f576b6e56a9027562b885f24 | |
| parent | 796251e5b0da524584c9e81b8ad6e1dcc0931aa3 (diff) | |
transformersを4.x系に固定し、text encoder付きLoDA読み込み時の
IndexErrorを解消。あわせて外部VAEロードの既存バグも修正した。
問題:
kohya形式LoRA(pixelartV3, pixel_f2, pixel sprites等)のロード時に
Diffusers内部でIndexError: list index out of rangeが発生し、サーバが
起動失敗していた。LCM LoRAはtext encoderキーを含まないため成功していた。
原因:
Transformers 5.x系のCLIPTextModel.named_modules()が返すモジュール名
(encoder.layers.0.self_attn.k_proj)と、Diffusersがkohya形式LoRAを
PEFT形式へ変換後のキー(text_model.encoder.layers.0...lora_B.weight)の
間でtext_model.プレフィックスの有無が不一致となり、rank_dictが空になって
get_peft_kwargsでlist(rank_dict.values())[0]がIndexErrorになる。
Transformers 4.x系ではnamed_modules()がtext_model.プレフィックス付きの
モジュール名を返すため、PEFTキーと一致し正常にロードできる。
対応:
transformers>=4.45,<5 に固定。4.x系最新版の4.57.6を採用。
これに伴いdiffusers 0.40.0→0.39.0、huggingface-hub 1.31.0→0.36.2、
tokenizers 0.23.2→0.22.2に変更された。peft 0.20.0は変更なし。
LoDAロード処理のコードは変更せず、標準APIのpipeline.load_lora_weights()
をそのまま使用。モンキーパッチやキー書き換え等の互換性パッチは追加していない。
あわせて外部VAEロードの既存バグも修正:
AutoencoderKL.from_single_fileがネットワークからconfig.jsonを取得
しようとして失敗する問題を、_vae_config_dir()でローカルhuggingface
cache内のvae/config.jsonディレクトリを動的に見つけてconfigパラメータ
に渡すことで解消。
変更内容:
- pyproject.toml: transformers>=4.45 を transformers>=4.45,<5 に変更
- uv.lock: transformers 5.17.0→4.57.6, diffusers 0.40.0→0.39.0,
huggingface-hub 1.31.0→0.36.2, tokenizers 0.23.2→0.22.2
- pipeline_factory.py: _vae_config_dir()メソッド追加、VAEロード時に
configパラメータでローカルconfigディレクトリを指定
- tests/test_pipeline_factory.py: _vae_config_dirをモンキーパッチ、
VAE config引数の検証追加
- script/smoke_matrix.py: 10パターン網羅検証スクリプト追加
(4 checkpoint × VAE × 4種LoRA × scheduler)
検証:
- ruff format/check、pyright 0 errors、pytest 61 passed
- 実GPU・実モデルで10パターン全て成功(10 ok / 0 fail)
- 4種checkpoint単体: 全て成功
- 外部VAE差し替え: 成功
- pixel sprites / pixelartV3 / pixel_f2: 全て成功(IndexError解消)
- LCM LoRA + lcm scheduler: 成功
- animekawa + 外部VAE + pixelartV3 + euler_a: 成功
| -rw-r--r-- | pyproject.toml | 2 | ||||
| -rw-r--r-- | script/smoke_matrix.py | 304 | ||||
| -rw-r--r-- | src/mcp_sd15/pipeline_factory.py | 21 | ||||
| -rw-r--r-- | tests/test_pipeline_factory.py | 4 | ||||
| -rw-r--r-- | uv.lock | 130 |
5 files changed, 361 insertions, 100 deletions
diff --git a/pyproject.toml b/pyproject.toml index ce5350f..bb5b190 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ dependencies = [ "safetensors>=0.4", "torch==2.14.0+cu132", "torchvision==0.29.0+cu132", - "transformers>=4.45", + "transformers>=4.45,<5", ] [project.scripts] diff --git a/script/smoke_matrix.py b/script/smoke_matrix.py new file mode 100644 index 0000000..7fc3ec2 --- /dev/null +++ b/script/smoke_matrix.py @@ -0,0 +1,304 @@ +"""Run generate_image across all checkpoint/VAE/LoRA/scheduler combinations. + +For each pattern, this script writes a temporary TOML config, starts the +``mcp-sd15`` server with ``streamable-http`` transport, calls ``generate_image`` +through the HTTP endpoint, saves the PNG, and records the result. + +Usage:: + + uv run python script/smoke_matrix.py --output-dir data/outputs/matrix +""" + +from __future__ import annotations + +import argparse +import asyncio +import base64 +import json +import subprocess +import sys +import time +from pathlib import Path + +from mcp import Client +from mcp.types import ImageContent + +DEFAULT_PROMPT = "a small red cube on a white table, studio photograph, detailed" +DEFAULT_NEGATIVE = "blurry, low quality" + +PATTERNS: list[dict[str, object]] = [ + { + "name": "01_v15_base", + "checkpoint": "v1-5-pruned-emaonly.safetensors", + "vae": None, + "loras": [], + "scheduler": "dpmpp_2m_karras", + "steps": 20, + "cfg_scale": 7.0, + "prompt": DEFAULT_PROMPT, + "negative": DEFAULT_NEGATIVE, + }, + { + "name": "02_animekawa_base", + "checkpoint": "animekawa_v10.safetensors", + "vae": None, + "loras": [], + "scheduler": "dpmpp_2m_karras", + "steps": 20, + "cfg_scale": 7.0, + "prompt": DEFAULT_PROMPT, + "negative": DEFAULT_NEGATIVE, + }, + { + "name": "03_amore_base", + "checkpoint": "animeModel_amore.safetensors", + "vae": None, + "loras": [], + "scheduler": "dpmpp_2m_karras", + "steps": 20, + "cfg_scale": 7.0, + "prompt": DEFAULT_PROMPT, + "negative": DEFAULT_NEGATIVE, + }, + { + "name": "04_animepastel_base", + "checkpoint": "animePastelDream_softBakedVae_full_fp16.safetensors", + "vae": None, + "loras": [], + "scheduler": "dpmpp_2m_karras", + "steps": 20, + "cfg_scale": 7.0, + "prompt": DEFAULT_PROMPT, + "negative": DEFAULT_NEGATIVE, + }, + { + "name": "05_v15_external_vae", + "checkpoint": "v1-5-pruned-emaonly.safetensors", + "vae": "vaeKlF8Anime2_klF8Anime2VAE.safetensors", + "loras": [], + "scheduler": "dpmpp_2m_karras", + "steps": 20, + "cfg_scale": 7.0, + "prompt": DEFAULT_PROMPT, + "negative": DEFAULT_NEGATIVE, + }, + { + "name": "06_v15_lora_pixel_sprites", + "checkpoint": "v1-5-pruned-emaonly.safetensors", + "vae": None, + "loras": [{"file": "pixel sprites.safetensors", "weight": 0.8}], + "scheduler": "dpmpp_2m_karras", + "steps": 20, + "cfg_scale": 7.0, + "prompt": "pixel art, a small red cube on a white table, detailed", + "negative": DEFAULT_NEGATIVE, + }, + { + "name": "07_v15_lora_pixelartV3", + "checkpoint": "v1-5-pruned-emaonly.safetensors", + "vae": None, + "loras": [{"file": "pixelartV3.safetensors", "weight": 0.8}], + "scheduler": "dpmpp_2m_karras", + "steps": 20, + "cfg_scale": 7.0, + "prompt": "pixelart, a small red cube on a white table, detailed", + "negative": DEFAULT_NEGATIVE, + }, + { + "name": "08_v15_lora_pixel_f2", + "checkpoint": "v1-5-pruned-emaonly.safetensors", + "vae": None, + "loras": [{"file": "pixel_f2.safetensors", "weight": 0.8}], + "scheduler": "dpmpp_2m_karras", + "steps": 20, + "cfg_scale": 7.0, + "prompt": "pixel, a small red cube on a white table, detailed", + "negative": DEFAULT_NEGATIVE, + }, + { + "name": "09_v15_lcm_lora", + "checkpoint": "v1-5-pruned-emaonly.safetensors", + "vae": None, + "loras": [{"file": "LCM_LoRA_Weights_SD15.safetensors", "weight": 1.0}], + "scheduler": "lcm", + "steps": 4, + "cfg_scale": 1.0, + "prompt": DEFAULT_PROMPT, + "negative": DEFAULT_NEGATIVE, + }, + { + "name": "10_animekawa_vae_lora", + "checkpoint": "animekawa_v10.safetensors", + "vae": "vaeKlF8Anime2_klF8Anime2VAE.safetensors", + "loras": [{"file": "pixelartV3.safetensors", "weight": 0.7}], + "scheduler": "euler_a", + "steps": 20, + "cfg_scale": 7.0, + "prompt": "pixelart, a small red cube on a white table, detailed", + "negative": DEFAULT_NEGATIVE, + }, +] + + +def make_toml(pattern: dict[str, object], port: int) -> str: + lines: list[str] = [] + lines.append("[model]") + lines.append('root = "."') + lines.append(f'checkpoint = "{pattern["checkpoint"]}"') + if pattern["vae"]: + lines.append(f'vae = "{pattern["vae"]}"') + for lora in pattern["loras"]: # type: ignore[union-attr] + lines.append("[[model.lora]]") + lines.append(f'file = "{lora["file"]}"') # type: ignore[index] + lines.append(f"weight = {lora['weight']}") # type: ignore[index] + lines.append("[generation]") + lines.append(f"steps = {pattern['steps']}") + lines.append(f"cfg_scale = {pattern['cfg_scale']}") + lines.append(f'scheduler = "{pattern["scheduler"]}"') + lines.append('default_size = "square_512"') + lines.append("[output]") + lines.append("enabled = false") + lines.append("[server]") + lines.append('transport = "streamable-http"') + lines.append('host = "127.0.0.1"') + lines.append(f"port = {port}") + return "\n".join(lines) + "\n" + + +async def run_one( + pattern: dict[str, object], + config_path: Path, + output_path: Path, + port: int, +) -> dict[str, object]: + toml = make_toml(pattern, port) + config_path.write_text(toml, encoding="utf-8") + + proc = subprocess.Popen( + [sys.executable, "-m", "mcp_sd15", "--config", str(config_path)], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + bufsize=1, + ) + + result: dict[str, object] = {"name": pattern["name"], "status": "unknown"} + started = time.monotonic() + + try: + # Wait for server to be ready (up to 120s for model loading) + url = f"http://127.0.0.1:{port}/mcp" + for _wait in range(120): + if proc.poll() is not None: + # Process died; drain stdout + dead_output = "" + if proc.stdout: + dead_output = proc.stdout.read() + result["status"] = "server_died" + result["output"] = dead_output[-3000:] + return result + try: + import httpx + + resp = httpx.get(url, timeout=2.0) + if resp.status_code == 400: + break + except Exception: + pass + await asyncio.sleep(1) + else: + result["status"] = "server_timeout" + return result + + async with Client(url, raise_exceptions=True) as client: + tools = (await client.list_tools()).tools + tool_names = {tool.name for tool in tools} + if tool_names != {"generate_image", "generate_guided_image", "inpaint_image"}: + result["status"] = "wrong_tools" + result["tools"] = list(tool_names) + return result + + call_result = await client.call_tool( + "generate_image", + { + "positive_prompt": pattern["prompt"], # type: ignore[index] + "negative_prompt": pattern["negative"], # type: ignore[index] + "size": "square_512", + }, + ) + + if call_result.is_error or len(call_result.content) != 1: + result["status"] = "tool_error" + result["detail"] = str(call_result) + return result + + content = call_result.content[0] + if not isinstance(content, ImageContent) or content.mime_type != "image/png": + result["status"] = "wrong_content" + result["detail"] = str(content) + return result + + output_path.parent.mkdir(parents=True, exist_ok=True) + output_path.write_bytes(base64.b64decode(content.data, validate=True)) + elapsed = round(time.monotonic() - started, 1) + result["status"] = "ok" + result["elapsed"] = elapsed + result["output_file"] = str(output_path) + return result + except Exception as exc: + result["status"] = "exception" + result["detail"] = str(exc) + return result + finally: + proc.terminate() + try: + proc.wait(timeout=10) + except subprocess.TimeoutExpired: + proc.kill() + + +async def main(args: argparse.Namespace) -> None: + config_path = args.data_dir / "config.matrix.toml" + results: list[dict[str, object]] = [] + + for i, pattern in enumerate(PATTERNS): + name = pattern["name"] + print(f"[{i + 1}/{len(PATTERNS)}] {name} ...", flush=True) + output_path = args.output_dir / f"{name}.png" + result = await run_one(pattern, config_path, output_path, args.port + i) + status = result["status"] + if status == "ok": + print( + f" -> OK elapsed={result.get('elapsed')}s file={result.get('output_file')}", + flush=True, + ) + else: + print(f" -> FAIL status={status} detail={result.get('detail', '')}", flush=True) + results.append(result) + + config_path.unlink(missing_ok=True) + + summary_path = args.output_dir / "matrix_results.json" + summary_path.parent.mkdir(parents=True, exist_ok=True) + summary_path.write_text(json.dumps(results, indent=2, ensure_ascii=False), encoding="utf-8") + + ok = sum(1 for r in results if r["status"] == "ok") + fail = len(results) - ok + print(f"\n=== Summary: {ok} ok / {fail} fail / {len(results)} total ===", flush=True) + if fail: + print("Failures:", flush=True) + for r in results: + if r["status"] != "ok": + print(f" {r['name']}: {r['status']} {r.get('detail', '')}", flush=True) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--output-dir", type=Path, default=Path("data/outputs/matrix")) + parser.add_argument("--data-dir", type=Path, default=Path("data")) + parser.add_argument("--port", type=int, default=8130) + return parser.parse_args() + + +if __name__ == "__main__": + asyncio.run(main(parse_args())) diff --git a/src/mcp_sd15/pipeline_factory.py b/src/mcp_sd15/pipeline_factory.py index b0525ea..02fe882 100644 --- a/src/mcp_sd15/pipeline_factory.py +++ b/src/mcp_sd15/pipeline_factory.py @@ -38,11 +38,16 @@ class PipelineFactory: ) vae_path = self.config.model.vae_path() if vae_path is not None: + # from_single_file needs a Diffusers config directory to avoid + # network access. Reuse the VAE config that the base pipeline + # already resolved from the local huggingface cache. + vae_config_dir = self._vae_config_dir(cache_dir) pipeline.vae = diffusers.AutoencoderKL.from_single_file( str(vae_path), torch_dtype=torch.float16, local_files_only=True, cache_dir=cache_dir, + config=vae_config_dir, ) if getattr(pipeline, "vae", None) is None: raise ConfigError( @@ -156,3 +161,19 @@ class PipelineFactory: except KeyError as exc: raise ConfigError(f"unsupported scheduler: {name}") from exc return scheduler_class.from_config(current.config) + + @staticmethod + def _vae_config_dir(cache_dir: str) -> str: + """Find the VAE config.json inside the local huggingface cache.""" + snapshots = ( + Path(cache_dir) / "models--stable-diffusion-v1-5--stable-diffusion-v1-5" / "snapshots" + ) + if not snapshots.is_dir(): + raise ConfigError( + "cannot locate VAE config: huggingface cache snapshots directory not found" + ) + for snapshot in snapshots.iterdir(): + vae_dir = snapshot / "vae" + if (vae_dir / "config.json").is_file(): + return str(vae_dir) + raise ConfigError("cannot locate VAE config.json in the local huggingface cache") diff --git a/tests/test_pipeline_factory.py b/tests/test_pipeline_factory.py index 408133b..14b771b 100644 --- a/tests/test_pipeline_factory.py +++ b/tests/test_pipeline_factory.py @@ -91,11 +91,15 @@ def test_base_pipeline_requires_vae_and_applies_all_loras(app_config, monkeypatc external_vae = object() runtime = (SimpleNamespace(float16="float16"), fake_diffusers(pipeline, external_vae)) monkeypatch.setattr(factory, "_runtime", lambda: runtime) + monkeypatch.setattr( + PipelineFactory, "_vae_config_dir", staticmethod(lambda cache_dir: "fake_vae_config") + ) result = factory.create_base() assert result is pipeline assert pipeline.vae is external_vae + assert pipeline.vae_load["config"] == "fake_vae_config" # type: ignore[attr-defined] assert pipeline.adapters == (["configured_lora_0", "configured_lora_1"], [0.8, 0.5]) assert [item["weight_name"] for item in pipeline.lora_loads] == [ "detail.safetensors", @@ -21,15 +21,6 @@ wheels = [ ] [[package]] -name = "annotated-doc" -version = "0.0.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/8e/38aa427ed5402449e226975b649c5dc73ccadfefeb95e6aecb8f8ea4b6b6/annotated_doc-0.0.5.tar.gz", hash = "sha256:c7e58ce09192557605d8bbd92836d7e1d520ac9580096042c0bfd197efacf1bb", size = 10758, upload-time = "2026-07-28T13:50:58.129Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl", hash = "sha256:117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101", size = 5302, upload-time = "2026-07-28T13:50:57.239Z" }, -] - -[[package]] name = "annotated-types" version = "0.8.0" source = { registry = "https://pypi.org/simple" } @@ -289,7 +280,7 @@ nvtx = [ [[package]] name = "diffusers" -version = "0.40.0" +version = "0.39.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -302,9 +293,9 @@ dependencies = [ { name = "requests" }, { name = "safetensors" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/59/32/b9c6a198812e2a7d2c2828a850dba384306f9af285eac23e35e89d5b008a/diffusers-0.40.0.tar.gz", hash = "sha256:49f112ce52ff6d332ab68afec01f79a53e6489b42cb69104444c98b4a2f64af8", size = 4886420, upload-time = "2026-08-20T14:30:40.923Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/81/6095237b86a3116c4789f28c4435d5296c00c0fc74ffde99008fd6b3a36c/diffusers-0.39.0.tar.gz", hash = "sha256:14bb1d98c85a0e463d734c99aaa73b480a7bc9bad22af30fbf730ef8f09c1d67", size = 4651240, upload-time = "2026-07-03T08:48:47.904Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/df/ffb593ebed2a068d2d6be44261283f39a6b809c0fcdfdcafbd448cbeec77/diffusers-0.40.0-py3-none-any.whl", hash = "sha256:5b5da7c3ddb62152fa4afc577f02e050af688c797375c34fb2d01006da3f3541", size = 5911654, upload-time = "2026-08-20T14:30:38.422Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3f/7469c46e9d22307ea686bab687d70e6bf328722952f9d10339f5e913e608/diffusers-0.39.0-py3-none-any.whl", hash = "sha256:912aca51b5787365110806e984d5555735bf8a461073bb8459029d0bca7870ef", size = 5631176, upload-time = "2026-07-03T08:48:45.337Z" }, ] [[package]] @@ -418,22 +409,21 @@ wheels = [ [[package]] name = "huggingface-hub" -version = "1.31.0" +version = "0.36.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click" }, { name = "filelock" }, { name = "fsspec" }, - { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, - { name = "httpx" }, + { name = "hf-xet", marker = "platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, { name = "packaging" }, { name = "pyyaml" }, + { name = "requests" }, { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9b/f0/61159db90b5cd275d55516fe27920828e7d3be4053fdbdb27c3f70e5f1ef/huggingface_hub-1.31.0.tar.gz", hash = "sha256:f8e9e710a210613fa5d0f26bba6da05ef4aef9fba5a0f23f508f5ac4d08b6f90", size = 968039, upload-time = "2026-09-10T10:27:22.724Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/b7/8cb61d2eece5fb05a83271da168186721c450eb74e3c31f7ef3169fa475b/huggingface_hub-0.36.2.tar.gz", hash = "sha256:1934304d2fb224f8afa3b87007d58501acfda9215b334eed53072dd5e815ff7a", size = 649782, upload-time = "2026-02-06T09:24:13.098Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/7f/3f886a625043b77312b80da2f2bf00b5ecbf5a73061af1aa0259cd258c9d/huggingface_hub-1.31.0-py3-none-any.whl", hash = "sha256:9dbb6a503cbe2494ea666695207e7262d410659e09134059deb83e5480864667", size = 798313, upload-time = "2026-09-10T10:27:20.798Z" }, + { url = "https://files.pythonhosted.org/packages/a8/af/48ac8483240de756d2438c380746e7130d1c6f75802ef22f3c6d49982787/huggingface_hub-0.36.2-py3-none-any.whl", hash = "sha256:48f0c8eac16145dfce371e9d2d7772854a4f591bcb56c9cf548accf531d54270", size = 566395, upload-time = "2026-02-06T09:24:11.133Z" }, ] [[package]] @@ -531,18 +521,6 @@ wheels = [ ] [[package]] -name = "markdown-it-py" -version = "4.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mdurl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, -] - -[[package]] name = "markupsafe" version = "3.0.3" source = { registry = "https://pypi.org/simple" } @@ -626,7 +604,7 @@ requires-dist = [ { name = "safetensors", specifier = ">=0.4" }, { name = "torch", specifier = "==2.14.0+cu132", index = "https://download.pytorch.org/whl/cu132" }, { name = "torchvision", specifier = "==0.29.0+cu132", index = "https://download.pytorch.org/whl/cu132" }, - { name = "transformers", specifier = ">=4.45" }, + { name = "transformers", specifier = ">=4.45,<5" }, ] [package.metadata.requires-dev] @@ -651,15 +629,6 @@ wheels = [ ] [[package]] -name = "mdurl" -version = "0.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, -] - -[[package]] name = "mpmath" version = "1.3.0" source = { registry = "https://pypi.org/simple" } @@ -1189,19 +1158,6 @@ wheels = [ ] [[package]] -name = "rich" -version = "15.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, -] - -[[package]] name = "rpds-py" version = "2026.6.3" source = { registry = "https://pypi.org/simple" } @@ -1342,15 +1298,6 @@ wheels = [ ] [[package]] -name = "shellingham" -version = "1.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, -] - -[[package]] name = "sse-starlette" version = "3.4.11" source = { registry = "https://pypi.org/simple" } @@ -1418,29 +1365,28 @@ wheels = [ [[package]] name = "tokenizers" -version = "0.23.2" +version = "0.22.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/1e/bc6587c5ab643b2e17776cace9070a2ae73549c86bffac9934a600bf3c31/tokenizers-0.23.2.tar.gz", hash = "sha256:7f0f085686b9de0d0079e6f874ae053600db64c5d13049e0bbc0119926d25aac", size = 385745, upload-time = "2026-09-03T08:55:42.89Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/6f/f80cfef4a312e1fb34baf7d85c72d4411afde10978d4657f8cdd811d3ccc/tokenizers-0.22.2.tar.gz", hash = "sha256:473b83b915e547aa366d1eee11806deaf419e17be16310ac0a14077f1e28f917", size = 372115, upload-time = "2026-01-05T10:45:15.988Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/ed/8a443528baa6fac8dfe8c3b75b038c63ac92bb539bcabe311e227c718173/tokenizers-0.23.2-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:85a9a357a3764aecc904ee76bdaf8cf1ad8e5a67a1b929a487c4a39b49ed0e90", size = 3148852, upload-time = "2026-09-03T08:55:30.874Z" }, - { url = "https://files.pythonhosted.org/packages/67/49/22da045a91732384d3a3771816bf188dc5a1f702c32e635afa7c679c0bef/tokenizers-0.23.2-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:986670e43691469dcee610ea0f846f91a8f84e91fc6f7a48d4c064414c0ec2bf", size = 3101593, upload-time = "2026-09-03T08:55:28.587Z" }, - { url = "https://files.pythonhosted.org/packages/2e/4d/8f569ed49372a3ed8e57099bd515055fd48d7c95912c4307cda6973c2168/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a37039b5dfc4af84eb3ef0a92f4307e28936c8f9adccba2629d36f652e9bf7a2", size = 3516830, upload-time = "2026-09-03T08:55:14.741Z" }, - { url = "https://files.pythonhosted.org/packages/2a/de/e2f14c8919d5bf51874051d00d6c7b7e0e8bde6c6a2dbeddda7f642896ff/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b7e37ba198f24150f523e1242e83c4970de4a525480586be5dcc24d9add32c5", size = 3407975, upload-time = "2026-09-03T08:55:16.842Z" }, - { url = "https://files.pythonhosted.org/packages/c5/bd/93c69152d02ef06ce47aed8b2bf4952dcf733c935a62791873932b2934d9/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43e4f2071e3cc8d5d86421c874aebc82659bb51a68bcdef5a0da75ee89511ccb", size = 3748165, upload-time = "2026-09-03T08:55:24.769Z" }, - { url = "https://files.pythonhosted.org/packages/2d/b7/56b84b80bc96942bba8eb23751a9e8a1fce4faaf4390425e7083f721c98c/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:325fee2e0418a9dc6c9ecf736a5f5f0db7875183ace9549ae339da76f7a1fbb7", size = 4024165, upload-time = "2026-09-03T08:55:18.806Z" }, - { url = "https://files.pythonhosted.org/packages/9b/8a/0175e216f005c2fe08238292663aa41e4c802b216e71047a69a0e9fc6fa3/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:950d7c9426fa72406a0ffeacdbc0bb9985f5db20eb8b263f29c79aaf83105703", size = 3591899, upload-time = "2026-09-03T08:55:22.752Z" }, - { url = "https://files.pythonhosted.org/packages/2c/ca/ca6b93c7820df123b2662a9469e8facc826ccc94e98fdd0d615f6431e73a/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41c2f84d172449b4dadb9cdc508e3e364076613c35b16e76ecfe47a60d1e3305", size = 3386843, upload-time = "2026-09-03T08:55:26.584Z" }, - { url = "https://files.pythonhosted.org/packages/e9/a4/4f9106d317b14a80aefea9f0e3a8d07ef25f856a7607eb7f5ab894281fcb/tokenizers-0.23.2-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:12f0835dc2ee694746a76adf7b1567d4346a4a502ebe93fb1f5f80ea49799b78", size = 3577314, upload-time = "2026-09-03T08:55:20.825Z" }, - { url = "https://files.pythonhosted.org/packages/8d/6a/1552b70fb0d9ab074fd3fc961435d01364e79c9058481822c3af6e8d402c/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:eb2f9c8a24da020ea8c11a01a19c1c2547912d92121ae4a01cfbca46125dee40", size = 9967367, upload-time = "2026-09-03T08:55:33.188Z" }, - { url = "https://files.pythonhosted.org/packages/06/01/3ccb3a956c7528b2507b8a9714155c4baf86af593039db6ea375dd0c96c3/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:f486f402f6f9abee5bb032553736813af0c710a86b2e0ca592634c55cea1f835", size = 9811886, upload-time = "2026-09-03T08:55:35.642Z" }, - { url = "https://files.pythonhosted.org/packages/fa/73/7038e612d48bda1599457f712f6bd3854eae1a9dc9c13aa47f835349db48/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:bef235815a067b2648caf6dcc7a71091b0b0fff9ee8057f6451eb9335fae52ef", size = 10146224, upload-time = "2026-09-03T08:55:38.391Z" }, - { url = "https://files.pythonhosted.org/packages/b5/d8/8e9e4e0b287a338d8f88976729628c9d22e8a54cfaf9777018a7f7cb58a0/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5c56bda1511921587789163e524d196ed8284174ac23abd7685d5ea8da6c4718", size = 10256304, upload-time = "2026-09-03T08:55:40.977Z" }, - { url = "https://files.pythonhosted.org/packages/f3/1f/c79a01f671a49728ebb0b61f7ff9ea45663b66cab40bc0858e9859b25c16/tokenizers-0.23.2-cp310-abi3-win32.whl", hash = "sha256:debf978920d93ba9c219bd67cc4bbfaf912c9039e41e7a28b91ec15e3728c95a", size = 2592809, upload-time = "2026-09-03T08:55:48.02Z" }, - { url = "https://files.pythonhosted.org/packages/db/f7/0a69ac6b82dbccf3f71add938a161c497952749294b8dd6dfe03a819dc40/tokenizers-0.23.2-cp310-abi3-win_amd64.whl", hash = "sha256:2e96f5699d5249c9c64aa8412e044f727aae3a4098cf830f9901ec1afc361cde", size = 2863236, upload-time = "2026-09-03T08:55:46.193Z" }, - { url = "https://files.pythonhosted.org/packages/d7/b0/dee84cb44175be1b4c35bd2f770727494e78f0bb38e571a623ade94dbebb/tokenizers-0.23.2-cp310-abi3-win_arm64.whl", hash = "sha256:e49c394456dd9985787fec76132438ba3fb8911f857b1bf3d40119f9292d41aa", size = 2729352, upload-time = "2026-09-03T08:55:44.345Z" }, + { url = "https://files.pythonhosted.org/packages/92/97/5dbfabf04c7e348e655e907ed27913e03db0923abb5dfdd120d7b25630e1/tokenizers-0.22.2-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:544dd704ae7238755d790de45ba8da072e9af3eea688f698b137915ae959281c", size = 3100275, upload-time = "2026-01-05T10:41:02.158Z" }, + { url = "https://files.pythonhosted.org/packages/2e/47/174dca0502ef88b28f1c9e06b73ce33500eedfac7a7692108aec220464e7/tokenizers-0.22.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1e418a55456beedca4621dbab65a318981467a2b188e982a23e117f115ce5001", size = 2981472, upload-time = "2026-01-05T10:41:00.276Z" }, + { url = "https://files.pythonhosted.org/packages/d6/84/7990e799f1309a8b87af6b948f31edaa12a3ed22d11b352eaf4f4b2e5753/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2249487018adec45d6e3554c71d46eb39fa8ea67156c640f7513eb26f318cec7", size = 3290736, upload-time = "2026-01-05T10:40:32.165Z" }, + { url = "https://files.pythonhosted.org/packages/78/59/09d0d9ba94dcd5f4f1368d4858d24546b4bdc0231c2354aa31d6199f0399/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b85325d0815e86e0bac263506dd114578953b7b53d7de09a6485e4a160a7dd", size = 3168835, upload-time = "2026-01-05T10:40:38.847Z" }, + { url = "https://files.pythonhosted.org/packages/47/50/b3ebb4243e7160bda8d34b731e54dd8ab8b133e50775872e7a434e524c28/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfb88f22a209ff7b40a576d5324bf8286b519d7358663db21d6246fb17eea2d5", size = 3521673, upload-time = "2026-01-05T10:40:56.614Z" }, + { url = "https://files.pythonhosted.org/packages/e0/fa/89f4cb9e08df770b57adb96f8cbb7e22695a4cb6c2bd5f0c4f0ebcf33b66/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c774b1276f71e1ef716e5486f21e76333464f47bece56bbd554485982a9e03e", size = 3724818, upload-time = "2026-01-05T10:40:44.507Z" }, + { url = "https://files.pythonhosted.org/packages/64/04/ca2363f0bfbe3b3d36e95bf67e56a4c88c8e3362b658e616d1ac185d47f2/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df6c4265b289083bf710dff49bc51ef252f9d5be33a45ee2bed151114a56207b", size = 3379195, upload-time = "2026-01-05T10:40:51.139Z" }, + { url = "https://files.pythonhosted.org/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67", size = 3274982, upload-time = "2026-01-05T10:40:58.331Z" }, + { url = "https://files.pythonhosted.org/packages/1d/28/5f9f5a4cc211b69e89420980e483831bcc29dade307955cc9dc858a40f01/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:29c30b83d8dcd061078b05ae0cb94d3c710555fbb44861139f9f83dcca3dc3e4", size = 9478245, upload-time = "2026-01-05T10:41:04.053Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fb/66e2da4704d6aadebf8cb39f1d6d1957df667ab24cff2326b77cda0dcb85/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:37ae80a28c1d3265bb1f22464c856bd23c02a05bb211e56d0c5301a435be6c1a", size = 9560069, upload-time = "2026-01-05T10:45:10.673Z" }, + { url = "https://files.pythonhosted.org/packages/16/04/fed398b05caa87ce9b1a1bb5166645e38196081b225059a6edaff6440fac/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:791135ee325f2336f498590eb2f11dc5c295232f288e75c99a36c5dbce63088a", size = 9899263, upload-time = "2026-01-05T10:45:12.559Z" }, + { url = "https://files.pythonhosted.org/packages/05/a1/d62dfe7376beaaf1394917e0f8e93ee5f67fea8fcf4107501db35996586b/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5", size = 10033429, upload-time = "2026-01-05T10:45:14.333Z" }, + { url = "https://files.pythonhosted.org/packages/fd/18/a545c4ea42af3df6effd7d13d250ba77a0a86fb20393143bbb9a92e434d4/tokenizers-0.22.2-cp39-abi3-win32.whl", hash = "sha256:a6bf3f88c554a2b653af81f3204491c818ae2ac6fbc09e76ef4773351292bc92", size = 2502363, upload-time = "2026-01-05T10:45:20.593Z" }, + { url = "https://files.pythonhosted.org/packages/65/71/0670843133a43d43070abeb1949abfdef12a86d490bea9cd9e18e37c5ff7/tokenizers-0.22.2-cp39-abi3-win_amd64.whl", hash = "sha256:c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48", size = 2747786, upload-time = "2026-01-05T10:45:18.411Z" }, + { url = "https://files.pythonhosted.org/packages/72/f4/0de46cfa12cdcbcd464cc59fde36912af405696f687e53a091fb432f694c/tokenizers-0.22.2-cp39-abi3-win_arm64.whl", hash = "sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc", size = 2612133, upload-time = "2026-01-05T10:45:17.232Z" }, ] [[package]] @@ -1498,22 +1444,23 @@ wheels = [ [[package]] name = "transformers" -version = "5.17.0" +version = "4.57.6" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "filelock" }, { name = "huggingface-hub" }, { name = "numpy" }, { name = "packaging" }, { name = "pyyaml" }, { name = "regex" }, + { name = "requests" }, { name = "safetensors" }, { name = "tokenizers" }, { name = "tqdm" }, - { name = "typer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0e/9e/750649904a065007a838981785b2bd8d9ff26154c6c341ac67d0b7f82c68/transformers-5.17.0.tar.gz", hash = "sha256:a153be279169b55b92d8000bf4af294aed684503d091cca7804da2dd8a9de000", size = 9817878, upload-time = "2026-09-09T15:39:56.886Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/35/67252acc1b929dc88b6602e8c4a982e64f31e733b804c14bc24b47da35e6/transformers-4.57.6.tar.gz", hash = "sha256:55e44126ece9dc0a291521b7e5492b572e6ef2766338a610b9ab5afbb70689d3", size = 10134912, upload-time = "2026-01-16T10:38:39.284Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/d0/c502b60d684adbd98a8dc7d5bb866842772b816ac4354e4608be240041ae/transformers-5.17.0-py3-none-any.whl", hash = "sha256:78ec1ce21579b38dfb83950a0658cd119f87212a2fcfdff478096ce9d6c03801", size = 12295140, upload-time = "2026-09-09T15:39:53.746Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/e484ef633af3887baeeb4b6ad12743363af7cce68ae51e938e00aaa0529d/transformers-4.57.6-py3-none-any.whl", hash = "sha256:4c9e9de11333ddfe5114bc872c9f370509198acf0b87a832a0ab9458e2bd0550", size = 11993498, upload-time = "2026-01-16T10:38:31.289Z" }, ] [[package]] @@ -1535,21 +1482,6 @@ wheels = [ ] [[package]] -name = "typer" -version = "0.27.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-doc" }, - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "rich" }, - { name = "shellingham" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/16/f7/57713ba479fd405eb76de31404b2c744c289e336b2d999511ebf51e496f7/typer-0.27.2.tar.gz", hash = "sha256:269b7eb9d3c202ca84b4bc9618cb04ebb43d3d4d1e567e4c768607232c05f945", size = 204045, upload-time = "2026-08-28T10:26:55.046Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/bf/205d0004930ede8f542fb58f601526fccf4ae7626075ca1e6c4de5d3d652/typer-0.27.2-py3-none-any.whl", hash = "sha256:b3a5fc4342d5fc8fda8fc3010b1cf117e9249aab7fae800c2eff62fd3842d97d", size = 123130, upload-time = "2026-08-28T10:26:53.752Z" }, -] - -[[package]] name = "typing-extensions" version = "4.16.0" source = { registry = "https://pypi.org/simple" } |
