mirror of
https://github.com/elder-plinius/OBLITERATUS.git
synced 2026-08-30 06:30:37 +02:00
fix: validate Qwen hybrid runtime placement
This commit is contained in:
@@ -549,12 +549,14 @@ obliteratus obliterate Qwen/Qwen3.8-27B --dtype bfloat16
|
||||
obliteratus obliterate Qwen/Qwen3.8-27B --dtype float16 --quantization 4bit
|
||||
```
|
||||
|
||||
> **Qwen3.8 safety status:** loading the native BF16 checkpoint is supported, but
|
||||
> permanent abliteration of its Qwen3.5 hybrid Gated DeltaNet/attention layout is
|
||||
> currently unvalidated. The pipeline checks pristine perplexity and coherence,
|
||||
> then stops before modifying weights with an unsupported-architecture error.
|
||||
> Qwen3.8 is not considered surgery-supported until projection-family validation
|
||||
> and a real post-surgery regression pass are published.
|
||||
> **Qwen3.8 safety status:** Qwen3.8's hybrid Gated DeltaNet runtime requires the
|
||||
> supported FLA and causal-conv1d CUDA kernels for correct pristine logits. The
|
||||
> generic PyTorch fallback and automatic multi-GPU layer sharding are rejected.
|
||||
> OBLITERATUS places the complete text model on one CUDA device with 15% headroom
|
||||
> and stops before allocation if that contract cannot be met. Install a
|
||||
> PyTorch/CUDA-compatible kernel build with `pip install -e ".[qwen-hybrid]"`.
|
||||
> The pristine and post-edit quality gates remain mandatory; a failed pristine
|
||||
> checkpoint is never modified.
|
||||
|
||||
Install the optional backend before selecting a bitsandbytes mode:
|
||||
|
||||
|
||||
@@ -86,6 +86,27 @@ uv pip check --python .venv/bin/python
|
||||
.venv/bin/python scripts/run_conditional_gate.py bitsandbytes-runtime
|
||||
```
|
||||
|
||||
### Qwen3.5/Qwen3.8 hybrid runtime
|
||||
|
||||
The Qwen3.5/Qwen3.8 Gated DeltaNet path requires both FLA and causal-conv1d.
|
||||
Install the optional extra only after selecting the CUDA build of PyTorch:
|
||||
|
||||
```bash
|
||||
CUDA_HOME=/usr/local/cuda uv sync --locked --extra dev --extra qwen-hybrid
|
||||
.venv/bin/python -c 'import torch, fla, causal_conv1d; print(torch.__version__)'
|
||||
```
|
||||
|
||||
`causal-conv1d` wheels are keyed to the Python, PyTorch, CUDA, platform, and C++
|
||||
ABI combination. Prefer an exact upstream wheel when one exists. A source build
|
||||
must use a `CUDA_HOME` whose major version matches `torch.version.cuda`; the
|
||||
system-default `nvcc` may point at a different toolkit. OBLITERATUS fails before
|
||||
weight allocation if either extension cannot be imported.
|
||||
|
||||
The complete Qwen hybrid text model must fit one CUDA device with 15% free-memory
|
||||
headroom. Generic `device_map="auto"` layer sharding is deliberately disabled for
|
||||
this architecture because the recurrent-state execution path has not been
|
||||
validated across devices.
|
||||
|
||||
Use the virtual environment interpreter directly after replacing Torch. A subsequent
|
||||
`uv run` or `uv sync` without the CUDA override may restore the portable CPU wheel
|
||||
from the lock. The agentic developer installer automates this ordering and performs
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
@@ -19,6 +20,7 @@ from obliteratus.runtime_contracts import (
|
||||
effective_model_memory_gb,
|
||||
quantized_model_fits_gpu,
|
||||
resolve_model_load_policy,
|
||||
select_single_cuda_device,
|
||||
should_snapshot_model,
|
||||
validate_model_load_request,
|
||||
)
|
||||
@@ -619,6 +621,40 @@ def _available_gpu_memory_gb() -> float:
|
||||
return dev.get_total_free_gb()
|
||||
|
||||
|
||||
def _require_qwen_hybrid_kernels() -> None:
|
||||
"""Fail before allocation when Qwen's validated DeltaNet kernels are absent."""
|
||||
missing = []
|
||||
for package, module_name in (
|
||||
("flash-linear-attention", "fla"),
|
||||
("causal-conv1d", "causal_conv1d"),
|
||||
):
|
||||
try:
|
||||
importlib.import_module(module_name)
|
||||
except (ImportError, OSError, RuntimeError):
|
||||
missing.append(package)
|
||||
if missing:
|
||||
raise RuntimeError(
|
||||
"Qwen3.5/Qwen3.8 requires its validated CUDA DeltaNet fast path; "
|
||||
f"missing or incompatible: {', '.join(missing)}. Install a PyTorch/CUDA-"
|
||||
"compatible build with `pip install -e '.[qwen-hybrid]'`. The generic "
|
||||
"PyTorch fallback is not used because it produced invalid pristine logits."
|
||||
)
|
||||
|
||||
|
||||
def _qwen_single_device(estimate_gb: float, quantization: str | None) -> int:
|
||||
"""Choose one CUDA device for a Qwen hybrid text model."""
|
||||
if not dev.is_cuda() or torch.cuda.device_count() <= 0:
|
||||
raise RuntimeError("Qwen3.5/Qwen3.8 validated surgery requires an NVIDIA CUDA device")
|
||||
free_gb = [
|
||||
torch.cuda.mem_get_info(index)[0] / (1024 ** 3)
|
||||
for index in range(torch.cuda.device_count())
|
||||
]
|
||||
return select_single_cuda_device(
|
||||
free_gb,
|
||||
effective_model_memory_gb(estimate_gb, quantization),
|
||||
)
|
||||
|
||||
|
||||
def _hf_token() -> str | None:
|
||||
"""Resolve the optional Hugging Face read token."""
|
||||
return resolve_secret("HF_TOKEN")
|
||||
@@ -809,20 +845,25 @@ def load_model(
|
||||
if task == "classification":
|
||||
config.num_labels = num_labels
|
||||
load_kwargs["config"] = config
|
||||
if task == "causal_lm" and getattr(config, "model_type", "") == "qwen3_5":
|
||||
is_qwen_hybrid = task == "causal_lm" and getattr(config, "model_type", "") == "qwen3_5"
|
||||
qwen_device_index = None
|
||||
if is_qwen_hybrid:
|
||||
import transformers
|
||||
|
||||
version_match = re.match(r"^(\d+)\.(\d+)", transformers.__version__)
|
||||
version = tuple(map(int, version_match.groups())) if version_match else (0, 0)
|
||||
if version < (5, 15):
|
||||
if version < (5, 8):
|
||||
raise RuntimeError(
|
||||
"Qwen3.8 requires transformers>=5.15 for the validated hybrid "
|
||||
"runtime and multidimensional-position fixes"
|
||||
"Qwen3.8 requires transformers>=5.8 for the validated hybrid runtime"
|
||||
)
|
||||
_require_qwen_hybrid_kernels()
|
||||
qwen_device_index = _qwen_single_device(est_gb, quantization)
|
||||
load_kwargs["attn_implementation"] = "sdpa"
|
||||
logger.info(
|
||||
"Loading Qwen3.8 through AutoModelForCausalLM as an explicit text-only "
|
||||
"derivative; vision and MTP checkpoint tensors are not part of the output."
|
||||
"derivative on cuda:%d; vision and MTP checkpoint tensors are not part "
|
||||
"of the output.",
|
||||
qwen_device_index,
|
||||
)
|
||||
|
||||
# Quantization support (requires bitsandbytes)
|
||||
@@ -866,6 +907,11 @@ def load_model(
|
||||
if "device_map" not in load_kwargs and load_policy.use_device_map_auto:
|
||||
load_kwargs["device_map"] = "auto"
|
||||
|
||||
if qwen_device_index is not None:
|
||||
# Generic layer sharding is not a validated execution path for the
|
||||
# recurrent DeltaNet state. Keep the complete text model on one GPU.
|
||||
load_kwargs["device_map"] = {"": qwen_device_index}
|
||||
|
||||
# Offload support: provide a folder for disk offloading when GPU memory is insufficient
|
||||
_offload_dir = None
|
||||
_owns_offload_dir = False
|
||||
|
||||
@@ -180,6 +180,39 @@ def effective_model_memory_gb(estimate_gb: float, quantization: str | None) -> f
|
||||
return estimate_gb / factor
|
||||
|
||||
|
||||
def select_single_cuda_device(
|
||||
free_memory_gb: Collection[float],
|
||||
required_memory_gb: float,
|
||||
*,
|
||||
max_utilization: float = 0.85,
|
||||
) -> int:
|
||||
"""Select one CUDA device that can hold a model with bounded headroom.
|
||||
|
||||
Hybrid recurrent models cannot be assumed safe under Accelerate's generic
|
||||
layer sharding. Selection is deterministic: choose the device with the
|
||||
most free memory, then the lowest index on ties.
|
||||
"""
|
||||
if not math.isfinite(required_memory_gb) or required_memory_gb <= 0:
|
||||
raise ValueError("required_memory_gb must be a positive finite number")
|
||||
if not math.isfinite(max_utilization) or not 0 < max_utilization <= 1:
|
||||
raise ValueError("max_utilization must be in (0, 1]")
|
||||
candidates = [
|
||||
(float(free_gb), index)
|
||||
for index, free_gb in enumerate(free_memory_gb)
|
||||
if math.isfinite(float(free_gb))
|
||||
and float(free_gb) > 0
|
||||
and required_memory_gb <= float(free_gb) * max_utilization
|
||||
]
|
||||
if not candidates:
|
||||
available = ", ".join(f"cuda:{i}={float(value):.1f} GiB" for i, value in enumerate(free_memory_gb))
|
||||
raise RuntimeError(
|
||||
"Qwen3.5/Qwen3.8 requires the complete text model on one CUDA device; "
|
||||
f"need {required_memory_gb:.1f} GiB with headroom, available: "
|
||||
f"{available or 'no CUDA devices'}"
|
||||
)
|
||||
return max(candidates, key=lambda item: (item[0], -item[1]))[1]
|
||||
|
||||
|
||||
def quantized_model_fits_gpu(
|
||||
estimate_gb: float,
|
||||
quantization: str | None,
|
||||
|
||||
@@ -51,6 +51,11 @@ dev = [
|
||||
"ruff==0.16.2",
|
||||
]
|
||||
quantization = ["bitsandbytes>=0.46.1"]
|
||||
qwen-hybrid = [
|
||||
"transformers>=5.8",
|
||||
"flash-linear-attention>=0.5.2",
|
||||
"causal-conv1d>=1.7.0",
|
||||
]
|
||||
spaces = ["gradio>=6.7,<7.0"]
|
||||
|
||||
[dependency-groups]
|
||||
|
||||
@@ -512,19 +512,67 @@ def test_mistral3_load_uses_image_text_class_and_keeps_remote_code_disabled(
|
||||
loader_boundary.model_class.from_pretrained.assert_not_called()
|
||||
|
||||
|
||||
def test_qwen35_load_is_explicit_text_only_sdpa(loader_boundary, caplog):
|
||||
def test_qwen35_load_is_explicit_text_only_sdpa(
|
||||
loader_boundary, caplog, monkeypatch,
|
||||
):
|
||||
caplog.set_level("INFO")
|
||||
loader_boundary.config.model_type = "qwen3_5"
|
||||
loader_boundary.config.architectures = ["Qwen3_5ForConditionalGeneration"]
|
||||
monkeypatch.setattr(loader, "_require_qwen_hybrid_kernels", Mock())
|
||||
monkeypatch.setattr(loader, "_qwen_single_device", Mock(return_value=2))
|
||||
|
||||
handle = loader.load_model("Qwen/Qwen3.8-27B", skip_snapshot=True)
|
||||
|
||||
assert handle.architecture == "qwen3_5"
|
||||
kwargs = loader_boundary.model_class.from_pretrained.call_args.kwargs
|
||||
assert kwargs["attn_implementation"] == "sdpa"
|
||||
assert kwargs["device_map"] == {"": 2}
|
||||
assert "device_map" not in kwargs or kwargs["device_map"] != "auto"
|
||||
assert "text-only derivative" in caplog.text
|
||||
|
||||
|
||||
def test_qwen35_missing_fast_kernels_fails_before_weight_load(
|
||||
loader_boundary, monkeypatch,
|
||||
):
|
||||
loader_boundary.config.model_type = "qwen3_5"
|
||||
monkeypatch.setattr(
|
||||
loader,
|
||||
"_require_qwen_hybrid_kernels",
|
||||
Mock(side_effect=RuntimeError("missing or incompatible: causal-conv1d")),
|
||||
)
|
||||
|
||||
with pytest.raises(RuntimeError, match="causal-conv1d"):
|
||||
loader.load_model("Qwen/Qwen3.8-27B", skip_snapshot=True)
|
||||
|
||||
loader_boundary.model_class.from_pretrained.assert_not_called()
|
||||
|
||||
|
||||
def test_qwen_kernel_probe_reports_each_incompatible_extension(monkeypatch):
|
||||
def import_module(name):
|
||||
if name == "fla":
|
||||
raise ImportError("missing")
|
||||
raise OSError("ABI mismatch")
|
||||
|
||||
monkeypatch.setattr(loader.importlib, "import_module", import_module)
|
||||
|
||||
with pytest.raises(RuntimeError, match="flash-linear-attention, causal-conv1d"):
|
||||
loader._require_qwen_hybrid_kernels()
|
||||
|
||||
|
||||
def test_qwen_single_device_uses_per_device_free_memory(monkeypatch):
|
||||
monkeypatch.setattr(loader.dev, "is_cuda", lambda: True)
|
||||
monkeypatch.setattr(loader.torch.cuda, "device_count", lambda: 3)
|
||||
free = [40, 76, 72]
|
||||
monkeypatch.setattr(
|
||||
loader.torch.cuda,
|
||||
"mem_get_info",
|
||||
lambda index: (free[index] * 1024 ** 3, 80 * 1024 ** 3),
|
||||
)
|
||||
|
||||
assert loader._qwen_single_device(54.0, None) == 1
|
||||
assert loader._qwen_single_device(216.0, "4bit") == 1
|
||||
|
||||
|
||||
def test_model_handle_metadata_snapshot_restore_summary_and_cleanup(tmp_path):
|
||||
model = _model()
|
||||
nested = SimpleNamespace(
|
||||
|
||||
@@ -15,6 +15,7 @@ from obliteratus.runtime_contracts import (
|
||||
norm_restoration_ratio,
|
||||
quantized_model_fits_gpu,
|
||||
resolve_model_load_policy,
|
||||
select_single_cuda_device,
|
||||
should_snapshot_model,
|
||||
supports_bfloat16_target,
|
||||
validate_model_load_request,
|
||||
@@ -499,3 +500,26 @@ def test_bfloat16_capability_boundaries(
|
||||
cuda_major=cuda_major,
|
||||
torch_version=version,
|
||||
) is expected
|
||||
|
||||
|
||||
def test_single_cuda_device_prefers_most_free_memory_then_lowest_index():
|
||||
assert select_single_cuda_device([64.0, 80.0, 80.0], 54.0) == 1
|
||||
|
||||
|
||||
def test_single_cuda_device_requires_one_device_to_fit_with_headroom():
|
||||
with pytest.raises(RuntimeError, match=r"complete text model on one CUDA device"):
|
||||
select_single_cuda_device([60.0, 63.0], 54.0)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("required", "utilization", "message"),
|
||||
[
|
||||
(0.0, 0.85, "required_memory_gb"),
|
||||
(float("nan"), 0.85, "required_memory_gb"),
|
||||
(1.0, 0.0, "max_utilization"),
|
||||
(1.0, 1.1, "max_utilization"),
|
||||
],
|
||||
)
|
||||
def test_single_cuda_device_rejects_invalid_policy(required, utilization, message):
|
||||
with pytest.raises(ValueError, match=message):
|
||||
select_single_cuda_device([80.0], required, max_utilization=utilization)
|
||||
|
||||
@@ -15,7 +15,7 @@ resolution-markers = [
|
||||
]
|
||||
|
||||
[options]
|
||||
exclude-newer = "2026-08-19T00:05:48.361273363Z"
|
||||
exclude-newer = "2026-08-24T05:10:12.868014219Z"
|
||||
exclude-newer-span = "P3D"
|
||||
|
||||
[manifest]
|
||||
@@ -410,6 +410,18 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/84/c2/80633736cd183ee4a62107413def345f7e6e3c01563dbca1417363cf957e/build-1.2.2.post1-py3-none-any.whl", hash = "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", size = 22950, upload-time = "2024-10-06T17:22:23.299Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "causal-conv1d"
|
||||
version = "1.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "ninja" },
|
||||
{ name = "packaging" },
|
||||
{ name = "torch", version = "2.13.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
|
||||
{ name = "torch", version = "2.13.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f4/d1/eba27735f31bd5527d39a3c7f693e6ded7b844cab275db719a15ad37b6cd/causal_conv1d-1.7.0.tar.gz", hash = "sha256:3202758494eaa7b597ce1c282dfa188889506bfcb92cad3c407d26736bfcd32b", size = 30328, upload-time = "2026-08-20T10:54:15.808Z" }
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2026.7.22"
|
||||
@@ -976,6 +988,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/32/91/30151a39f7570f448ed84529390628a651d7f27c87d73c9b887f8189695e/docutils-0.23-py3-none-any.whl", hash = "sha256:25d013af9bf23bc1c7b2b093dff4208166c53a94786c9e447808335ef1185fea", size = 634701, upload-time = "2026-05-27T17:40:58.442Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "einops"
|
||||
version = "0.8.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/2c/77/850bef8d72ffb9219f0b1aac23fbc1bf7d038ee6ea666f331fa273031aa2/einops-0.8.2.tar.gz", hash = "sha256:609da665570e5e265e27283aab09e7f279ade90c4f01bcfca111f3d3e13f2827", size = 56261, upload-time = "2026-01-26T04:13:17.638Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/09/f8d8f8f31e4483c10a906437b4ce31bdf3d6d417b73fe33f1a8b59e34228/einops-0.8.2-py3-none-any.whl", hash = "sha256:54058201ac7087911181bfec4af6091bb59380360f069276601256a76af08193", size = 65638, upload-time = "2026-01-26T04:13:18.546Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exceptiongroup"
|
||||
version = "1.3.1"
|
||||
@@ -1013,6 +1034,31 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/e8/72f8cef9fdfeffe06213fe8508039396ee48daa0e3259457ed766173bfd6/filelock-3.32.2-py3-none-any.whl", hash = "sha256:87dd94cf281e586d135fa51132b8e3d9a598b316e90377a288663c9321036c82", size = 98830, upload-time = "2026-07-29T22:46:03.52Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fla-core"
|
||||
version = "0.5.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "einops" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/94/85/20bdc0fbbbaeec27b5b198e0dbbbc51161a267066a4aebd9e4b413637c6c/fla_core-0.5.2.tar.gz", hash = "sha256:9360fc412f784c1c8f05c320ec2902d5d968764178c9b8a92efc919e17a39680", size = 587835, upload-time = "2026-07-27T18:26:19.424Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/ed/dfe19c4da779957eb6a42a26812f9b4e2280bf757a17a71933ff59ffcb98/fla_core-0.5.2-py3-none-any.whl", hash = "sha256:5e830c85bad3d0d34677f98ac7074d08687a3756f0f0499d95ceb96eb6920761", size = 819225, upload-time = "2026-07-27T18:26:16.147Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flash-linear-attention"
|
||||
version = "0.5.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "fla-core" },
|
||||
{ name = "transformers" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d2/76/c180949eae5161b9fcf4c928cab52f0c257ce84c1a59b4462b1d2b6e5883/flash_linear_attention-0.5.2.tar.gz", hash = "sha256:c053d3a75c8f5b725063f719ae6bce0f4d9dac6da32735be8ae7d485a6c9820f", size = 208110, upload-time = "2026-07-27T18:26:20.536Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/90/d2/2070e3cf2148c5cce99ca4876633c4b7b89ec085323600bd3d47aeacd306/flash_linear_attention-0.5.2-py3-none-any.whl", hash = "sha256:dcf405d81f5426393b59037097aa700d0f4a841465d5028d5aa543f4502f2400", size = 399590, upload-time = "2026-07-27T18:26:17.912Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fonttools"
|
||||
version = "4.63.0"
|
||||
@@ -2366,6 +2412,32 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/e5/7cafee2f0413ca4cb0ef3bd111e94d408a48810008b283ad8aee00dd1809/nh3-0.3.6-cp38-abi3-win_arm64.whl", hash = "sha256:69f365963f63a1e9bff53bdbb3c542c7c2efed3e163c9d5d83a772a2ac468c21", size = 603060, upload-time = "2026-06-22T00:47:00.596Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ninja"
|
||||
version = "1.13.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/43/73/79a0b22fc731989c708068427579e840a6cf4e937fe7ae5c5d0b7356ac22/ninja-1.13.0.tar.gz", hash = "sha256:4a40ce995ded54d9dc24f8ea37ff3bf62ad192b547f6c7126e7e25045e76f978", size = 242558, upload-time = "2025-08-11T15:10:19.421Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/74/d02409ed2aa865e051b7edda22ad416a39d81a84980f544f8de717cab133/ninja-1.13.0-py3-none-macosx_10_9_universal2.whl", hash = "sha256:fa2a8bfc62e31b08f83127d1613d10821775a0eb334197154c4d6067b7068ff1", size = 310125, upload-time = "2025-08-11T15:09:50.971Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/de/6e1cd6b84b412ac1ef327b76f0641aeb5dcc01e9d3f9eee0286d0c34fd93/ninja-1.13.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3d00c692fb717fd511abeb44b8c5d00340c36938c12d6538ba989fe764e79630", size = 177467, upload-time = "2025-08-11T15:09:52.767Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/83/49320fb6e58ae3c079381e333575fdbcf1cca3506ee160a2dcce775046fa/ninja-1.13.0-py3-none-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:be7f478ff9f96a128b599a964fc60a6a87b9fa332ee1bd44fa243ac88d50291c", size = 187834, upload-time = "2025-08-11T15:09:54.115Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/c7/ba22748fb59f7f896b609cd3e568d28a0a367a6d953c24c461fe04fc4433/ninja-1.13.0-py3-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:60056592cf495e9a6a4bea3cd178903056ecb0943e4de45a2ea825edb6dc8d3e", size = 202736, upload-time = "2025-08-11T15:09:55.745Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/22/d1de07632b78ac8e6b785f41fa9aad7a978ec8c0a1bf15772def36d77aac/ninja-1.13.0-py3-none-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:1c97223cdda0417f414bf864cfb73b72d8777e57ebb279c5f6de368de0062988", size = 179034, upload-time = "2025-08-11T15:09:57.394Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa", size = 180716, upload-time = "2025-08-11T15:09:58.696Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/28/938b562f9057aaa4d6bfbeaa05e81899a47aebb3ba6751e36c027a7f5ff7/ninja-1.13.0-py3-none-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4be9c1b082d244b1ad7ef41eb8ab088aae8c109a9f3f0b3e56a252d3e00f42c1", size = 146843, upload-time = "2025-08-11T15:10:00.046Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/fb/d06a3838de4f8ab866e44ee52a797b5491df823901c54943b2adb0389fbb/ninja-1.13.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:6739d3352073341ad284246f81339a384eec091d9851a886dfa5b00a6d48b3e2", size = 154402, upload-time = "2025-08-11T15:10:01.657Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/bf/0d7808af695ceddc763cf251b84a9892cd7f51622dc8b4c89d5012779f06/ninja-1.13.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:11be2d22027bde06f14c343f01d31446747dbb51e72d00decca2eb99be911e2f", size = 552388, upload-time = "2025-08-11T15:10:03.349Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/70/c99d0c2c809f992752453cce312848abb3b1607e56d4cd1b6cded317351a/ninja-1.13.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:aa45b4037b313c2f698bc13306239b8b93b4680eb47e287773156ac9e9304714", size = 472501, upload-time = "2025-08-11T15:10:04.735Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/43/c217b1153f0e499652f5e0766da8523ce3480f0a951039c7af115e224d55/ninja-1.13.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5f8e1e8a1a30835eeb51db05cf5a67151ad37542f5a4af2a438e9490915e5b72", size = 638280, upload-time = "2025-08-11T15:10:06.512Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/45/9151bba2c8d0ae2b6260f71696330590de5850e5574b7b5694dce6023e20/ninja-1.13.0-py3-none-musllinux_1_2_ppc64le.whl", hash = "sha256:3d7d7779d12cb20c6d054c61b702139fd23a7a964ec8f2c823f1ab1b084150db", size = 642420, upload-time = "2025-08-11T15:10:08.35Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/fb/95752eb635bb8ad27d101d71bef15bc63049de23f299e312878fc21cb2da/ninja-1.13.0-py3-none-musllinux_1_2_riscv64.whl", hash = "sha256:d741a5e6754e0bda767e3274a0f0deeef4807f1fec6c0d7921a0244018926ae5", size = 585106, upload-time = "2025-08-11T15:10:09.818Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/31/aa56a1a286703800c0cbe39fb4e82811c277772dc8cd084f442dd8e2938a/ninja-1.13.0-py3-none-musllinux_1_2_s390x.whl", hash = "sha256:e8bad11f8a00b64137e9b315b137d8bb6cbf3086fbdc43bf1f90fd33324d2e96", size = 707138, upload-time = "2025-08-11T15:10:11.366Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/6f/5f5a54a1041af945130abdb2b8529cbef0cdcbbf9bcf3f4195378319d29a/ninja-1.13.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b4f2a072db3c0f944c32793e91532d8948d20d9ab83da9c0c7c15b5768072200", size = 581758, upload-time = "2025-08-11T15:10:13.295Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/97/51359c77527d45943fe7a94d00a3843b81162e6c4244b3579fe8fc54cb9c/ninja-1.13.0-py3-none-win32.whl", hash = "sha256:8cfbb80b4a53456ae8a39f90ae3d7a2129f45ea164f43fadfa15dc38c4aef1c9", size = 267201, upload-time = "2025-08-11T15:10:15.158Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/45/c0adfbfb0b5895aa18cec400c535b4f7ff3e52536e0403602fc1a23f7de9/ninja-1.13.0-py3-none-win_amd64.whl", hash = "sha256:fb8ee8719f8af47fed145cced4a85f0755dd55d45b2bddaf7431fa89803c5f3e", size = 309975, upload-time = "2025-08-11T15:10:16.697Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/93/a7b983643d1253bb223234b5b226e69de6cda02b76cdca7770f684b795f5/ninja-1.13.0-py3-none-win_arm64.whl", hash = "sha256:3c0b40b1f0bba764644385319028650087b4c1b18cdfa6f45cb39a3669b81aa9", size = 290806, upload-time = "2025-08-11T15:10:18.018Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "2.2.6"
|
||||
@@ -2633,6 +2705,11 @@ dev = [
|
||||
quantization = [
|
||||
{ name = "bitsandbytes" },
|
||||
]
|
||||
qwen-hybrid = [
|
||||
{ name = "causal-conv1d" },
|
||||
{ name = "flash-linear-attention" },
|
||||
{ name = "transformers" },
|
||||
]
|
||||
spaces = [
|
||||
{ name = "gradio" },
|
||||
]
|
||||
@@ -2656,7 +2733,9 @@ requires-dist = [
|
||||
{ name = "accelerate", specifier = ">=0.24" },
|
||||
{ name = "bitsandbytes", marker = "extra == 'quantization'", specifier = ">=0.46.1" },
|
||||
{ name = "build", marker = "extra == 'dev'", specifier = "==1.2.2.post1" },
|
||||
{ name = "causal-conv1d", marker = "extra == 'qwen-hybrid'", specifier = ">=1.7.0" },
|
||||
{ name = "datasets", specifier = ">=2.14" },
|
||||
{ name = "flash-linear-attention", marker = "extra == 'qwen-hybrid'", specifier = ">=0.5.2" },
|
||||
{ name = "gradio", marker = "extra == 'spaces'", specifier = ">=6.7,<7.0" },
|
||||
{ name = "hypothesis", marker = "extra == 'dev'", specifier = "==6.165.3" },
|
||||
{ name = "matplotlib", specifier = ">=3.7" },
|
||||
@@ -2675,8 +2754,9 @@ requires-dist = [
|
||||
{ name = "torch", marker = "sys_platform == 'linux' or sys_platform == 'win32'", specifier = ">=2.0", index = "https://download.pytorch.org/whl/cpu" },
|
||||
{ name = "tqdm", specifier = ">=4.64" },
|
||||
{ name = "transformers", specifier = ">=4.40" },
|
||||
{ name = "transformers", marker = "extra == 'qwen-hybrid'", specifier = ">=5.8" },
|
||||
]
|
||||
provides-extras = ["dev", "quantization", "spaces"]
|
||||
provides-extras = ["dev", "quantization", "qwen-hybrid", "spaces"]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
ci = [
|
||||
|
||||
Reference in New Issue
Block a user