summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pyproject.toml2
-rw-r--r--script/smoke_matrix.py304
-rw-r--r--src/mcp_sd15/pipeline_factory.py21
-rw-r--r--tests/test_pipeline_factory.py4
-rw-r--r--uv.lock130
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",
diff --git a/uv.lock b/uv.lock
index c41195a..c84563a 100644
--- a/uv.lock
+++ b/uv.lock
@@ -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" }