orbitquant 0.1.6__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {orbitquant-0.1.6 → orbitquant-0.2.0}/.github/workflows/publish-pypi.yml +1 -1
- orbitquant-0.2.0/PKG-INFO +340 -0
- orbitquant-0.2.0/README.md +296 -0
- orbitquant-0.2.0/docs/kernel-audit.md +192 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/docs/paper-methodology-audit.md +35 -28
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/CARD.md +17 -1
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/benchmarks/benchmark.py +1 -1
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/orbitquant_packed_matmul_cuda/packed_matmul.cu +123 -33
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/orbitquant_packed_matmul_metal/packed_matmul.metal +97 -7
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/orbitquant_packed_matmul_metal/packed_matmul.mm +38 -6
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/tests/test_packed_matmul.py +48 -5
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/torch-ext/orbitquant_packed_matmul/__init__.py +4 -2
- {orbitquant-0.1.6 → orbitquant-0.2.0}/pyproject.toml +2 -2
- {orbitquant-0.1.6 → orbitquant-0.2.0}/scripts/run_cuda_kernel_checks.sh +3 -3
- {orbitquant-0.1.6 → orbitquant-0.2.0}/scripts/run_paper_methodology_checks.sh +3 -1
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/__init__.py +13 -3
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/adaln.py +28 -13
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/config.py +11 -1
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/kernels/native_packed_matmul.py +3 -2
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/kernels/triton_cuda.py +9 -7
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/layers.py +45 -20
- orbitquant-0.2.0/src/orbitquant/linear_adapters.py +146 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/modeling.py +63 -8
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/policies/generic_dit.py +68 -9
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/quantizer.py +17 -3
- orbitquant-0.2.0/src/orbitquant/recipes.py +33 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/transformers_ops.py +11 -6
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_ci.py +2 -1
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_config.py +20 -0
- orbitquant-0.2.0/tests/test_documentation.py +35 -0
- orbitquant-0.2.0/tests/test_linear_adapters.py +115 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_model_quantization.py +4 -1
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_native_kernel_package.py +4 -3
- orbitquant-0.2.0/tests/test_universal_transformers.py +187 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/uv.lock +1 -1
- orbitquant-0.1.6/PKG-INFO +0 -584
- orbitquant-0.1.6/README.md +0 -540
- orbitquant-0.1.6/docs/kernel-audit.md +0 -282
- orbitquant-0.1.6/docs/kernel-hub-approval-request.md +0 -300
- orbitquant-0.1.6/docs/publication-checklist.md +0 -133
- orbitquant-0.1.6/docs/release-0.1.0.md +0 -154
- orbitquant-0.1.6/docs/release-0.1.1.md +0 -31
- orbitquant-0.1.6/docs/release-0.1.2.md +0 -28
- orbitquant-0.1.6/docs/release-0.1.3.md +0 -25
- orbitquant-0.1.6/docs/release-0.1.4.md +0 -36
- orbitquant-0.1.6/docs/release-0.1.6.md +0 -37
- orbitquant-0.1.6/docs/release-gates.md +0 -532
- orbitquant-0.1.6/tests/test_readme.py +0 -91
- orbitquant-0.1.6/tests/test_release_gates.py +0 -954
- {orbitquant-0.1.6 → orbitquant-0.2.0}/.github/workflows/ci.yml +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/.gitignore +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/LICENSE +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/build.toml +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/example.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/flake.lock +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/flake.nix +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/tests/__init__.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/torch-ext/torch_binding.cpp +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/native-kernels/orbitquant-packed-matmul/torch-ext/torch_binding.h +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/scripts/run_hf_compat_checks.sh +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/scripts/run_mps_kernel_checks.sh +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/scripts/runpod_ssh_health.sh +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/scripts/verify_hf_kernel_model_artifact.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/__init__.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/assets.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/benchmark.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/checksums.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/comparisons.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/loader.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/manifest.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/model_card.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/refresh.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/repair.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/validator.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/artifacts/writer.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/benchmarks.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/cli/__init__.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/cli/main.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/codebooks/__init__.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/codebooks/lloyd_max.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/errors.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/__init__.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/assets.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/external_export.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/external_metrics.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/external_plan.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/metrics.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/native_plan.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/native_runner.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/native_settings.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/prompts.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/eval/report.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/functional.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/hub.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/kernels/__init__.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/kernels/dispatch.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/kernels/mps.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/packing/__init__.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/packing/bitpack.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/pipeline.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/policies/__init__.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/policies/flux.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/policies/flux2.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/policies/wan.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/policies/z_image.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/rotations/__init__.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/rotations/fwht.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/src/orbitquant/rotations/rpbh.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_adaln_rtn.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_artifact_writer.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_benchmarks.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_bitpack.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_cli.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_cli_report.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_codebooks.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_diffusers_modelmixin_integration.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_distribution.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_eval_assets.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_eval_prompts.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_eval_report.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_external_eval_plan.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_external_export.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_hub.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_kernel_model_verifier.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_kernels.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_manifest.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_model_card.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_native_packed_matmul.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_native_runner.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_native_settings.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_optional_dependencies.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_orbit_linear.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_paper_alignment.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_paper_methodology.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_pipeline_helpers.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_policies.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_prompt_jobs.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_prompt_selection.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_quantizer_adapter.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_rpbh.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_target_policies.py +0 -0
- {orbitquant-0.1.6 → orbitquant-0.2.0}/tests/test_transformers_pretrained_integration.py +0 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: orbitquant
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Calibration-free OrbitQuant for transformer linear projections
|
|
5
|
+
Project-URL: Homepage, https://github.com/iamwavecut/OrbitQuant
|
|
6
|
+
Project-URL: Repository, https://github.com/iamwavecut/OrbitQuant
|
|
7
|
+
Project-URL: Issues, https://github.com/iamwavecut/OrbitQuant/issues
|
|
8
|
+
Project-URL: Paper, https://arxiv.org/abs/2607.02461
|
|
9
|
+
Author: WaveCut
|
|
10
|
+
License-Expression: Apache-2.0
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: diffusers,diffusion,orbitquant,quantization,transformers
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: huggingface-hub>=0.33
|
|
23
|
+
Requires-Dist: numpy>=2.0
|
|
24
|
+
Requires-Dist: packaging>=24.0
|
|
25
|
+
Requires-Dist: safetensors>=0.5
|
|
26
|
+
Requires-Dist: torch>=2.5
|
|
27
|
+
Requires-Dist: tqdm>=4.66
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest-xdist>=3.8; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=8.4; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.12; extra == 'dev'
|
|
32
|
+
Provides-Extra: eval
|
|
33
|
+
Requires-Dist: imageio-ffmpeg>=0.6; extra == 'eval'
|
|
34
|
+
Requires-Dist: imageio>=2.37; extra == 'eval'
|
|
35
|
+
Requires-Dist: pillow>=11.0; extra == 'eval'
|
|
36
|
+
Provides-Extra: hf
|
|
37
|
+
Requires-Dist: accelerate>=1.8; extra == 'hf'
|
|
38
|
+
Requires-Dist: diffusers>=0.35; extra == 'hf'
|
|
39
|
+
Requires-Dist: transformers>=4.53; extra == 'hf'
|
|
40
|
+
Provides-Extra: kernels
|
|
41
|
+
Requires-Dist: kernels>=0.16; extra == 'kernels'
|
|
42
|
+
Requires-Dist: triton>=3.5; (platform_system == 'Linux') and extra == 'kernels'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# OrbitQuant
|
|
46
|
+
|
|
47
|
+
OrbitQuant is a calibration-free post-training quantizer for transformer linear
|
|
48
|
+
projections. It implements the method from
|
|
49
|
+
[OrbitQuant: Data-Agnostic Quantization for Image and Video Diffusion Transformers](https://arxiv.org/abs/2607.02461)
|
|
50
|
+
and exposes it through Hugging Face Transformers, Diffusers, and a direct
|
|
51
|
+
PyTorch API.
|
|
52
|
+
|
|
53
|
+
The implementation is clean-room and Apache-2.0 licensed.
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
- Automatic coverage of registered linear-compatible modules in transformer
|
|
58
|
+
backbones, independent of model class or modality.
|
|
59
|
+
- Built-in support for `torch.nn.Linear` and Hugging Face `Conv1D` projections.
|
|
60
|
+
- Public adapters for custom `F.linear`-equivalent module types and transposed
|
|
61
|
+
weight layouts.
|
|
62
|
+
- RPBH rotation, exact unit-sphere Lloyd-Max codebooks, packed 2/3/4/6/8-bit
|
|
63
|
+
weights, and online activation quantization without calibration data.
|
|
64
|
+
- Model-specific policies for paper-sensitive AdaLN and output-layer handling.
|
|
65
|
+
- Compact `safetensors` artifacts and Hugging Face `save_pretrained()` /
|
|
66
|
+
`from_pretrained()` integration.
|
|
67
|
+
- Packed-weight CUDA, Triton, and Metal inference paths that avoid a full
|
|
68
|
+
dequantized weight matrix.
|
|
69
|
+
|
|
70
|
+
Embeddings, timestep modules, task heads, and common final projections are
|
|
71
|
+
kept in source precision by default. Every automatic decision is available as
|
|
72
|
+
a machine-readable inventory before quantization.
|
|
73
|
+
|
|
74
|
+
## Install
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install "orbitquant[hf]"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Install the CUDA/Triton and local-kernel loader dependencies with:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install "orbitquant[hf,kernels]"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Quantize A Transformers Model
|
|
87
|
+
|
|
88
|
+
Importing `orbitquant` registers the backend with supported Transformers and
|
|
89
|
+
Diffusers versions. The default `target_policy="auto"` selects a known
|
|
90
|
+
paper policy where applicable and otherwise uses the universal policy.
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import torch
|
|
94
|
+
import orbitquant
|
|
95
|
+
from transformers import AutoModelForCausalLM
|
|
96
|
+
|
|
97
|
+
config = orbitquant.recipe(
|
|
98
|
+
"w4a4",
|
|
99
|
+
runtime_mode="auto_fused",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
model = AutoModelForCausalLM.from_pretrained(
|
|
103
|
+
"your-org/your-transformer",
|
|
104
|
+
dtype=torch.bfloat16,
|
|
105
|
+
quantization_config=config,
|
|
106
|
+
)
|
|
107
|
+
model.save_pretrained("./your-transformer-orbitquant-w4a4")
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Load the packed model after importing the backend:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
import orbitquant
|
|
114
|
+
from transformers import AutoModelForCausalLM
|
|
115
|
+
|
|
116
|
+
model = AutoModelForCausalLM.from_pretrained(
|
|
117
|
+
"./your-transformer-orbitquant-w4a4",
|
|
118
|
+
device_map="auto",
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Named recipes are `w4a4`, `w3a3`, `w2a4`, `w2a3`, and `w4a6`. They create a
|
|
123
|
+
normal `OrbitQuantConfig`, so every field can be overridden.
|
|
124
|
+
|
|
125
|
+
## Inspect Coverage
|
|
126
|
+
|
|
127
|
+
Inspect a model before replacing modules:
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from orbitquant import inspect_linear_module_policy, recipe
|
|
131
|
+
from transformers import AutoModel
|
|
132
|
+
|
|
133
|
+
model = AutoModel.from_pretrained("your-org/your-transformer")
|
|
134
|
+
report = inspect_linear_module_policy(model, recipe("w4a4"))
|
|
135
|
+
|
|
136
|
+
print(report["action_counts"])
|
|
137
|
+
print(report["quantized_modules"])
|
|
138
|
+
print(report["skipped_modules"])
|
|
139
|
+
print(report["unsupported_linear_modules"])
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The universal policy quantizes every registered linear-compatible module except
|
|
143
|
+
known embeddings, timestep modules, task/output heads, and explicit skips. It
|
|
144
|
+
does not depend on names such as `layers`, `blocks`, or a particular model
|
|
145
|
+
class.
|
|
146
|
+
|
|
147
|
+
Use `modules_to_convert` as an allowlist and define AdaLN/skips with exact names,
|
|
148
|
+
substrings, or glob patterns:
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
from orbitquant import OrbitQuantConfig
|
|
152
|
+
|
|
153
|
+
config = OrbitQuantConfig(
|
|
154
|
+
modules_to_convert=["backbone.*.projection"],
|
|
155
|
+
modules_to_use_adaln=["backbone.*.modulation"],
|
|
156
|
+
modules_to_not_convert=["*.sensitive_output"],
|
|
157
|
+
)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Explicit dtype overrides remain available through `modules_dtype_dict`.
|
|
161
|
+
|
|
162
|
+
## Quantize An Instantiated Module
|
|
163
|
+
|
|
164
|
+
For ordinary PyTorch models or frameworks that do not use Hugging Face loading
|
|
165
|
+
hooks:
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from orbitquant import quantize_model, recipe
|
|
169
|
+
|
|
170
|
+
summary = quantize_model(
|
|
171
|
+
model,
|
|
172
|
+
recipe("w4a4"),
|
|
173
|
+
quantization_device="cuda",
|
|
174
|
+
)
|
|
175
|
+
print(summary.quantized_modules)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The replacement supports arbitrary leading dimensions and treats the final
|
|
179
|
+
dimension as `in_features`, including sequence, image-token, and video-token
|
|
180
|
+
layouts.
|
|
181
|
+
|
|
182
|
+
## Custom Linear Modules
|
|
183
|
+
|
|
184
|
+
Register a module whose forward operation is equivalent to `F.linear`. The
|
|
185
|
+
adapter describes only its source weight layout and feature attributes:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
from orbitquant import register_linear_adapter
|
|
189
|
+
|
|
190
|
+
register_linear_adapter(
|
|
191
|
+
MyLinear,
|
|
192
|
+
weight_layout="in_out",
|
|
193
|
+
in_features_attr="input_size",
|
|
194
|
+
out_features_attr="output_size",
|
|
195
|
+
)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
OrbitQuant stores every replacement in canonical `[out_features, in_features]`
|
|
199
|
+
layout. Modules with additional routing, tensor-parallel communication, sparse
|
|
200
|
+
expert selection, or non-linear forward semantics need an architecture-aware
|
|
201
|
+
adapter; the inspection report lists unregistered linear candidates instead of
|
|
202
|
+
silently replacing them.
|
|
203
|
+
|
|
204
|
+
## Diffusers
|
|
205
|
+
|
|
206
|
+
Quantize the denoiser component of a pipeline:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
import torch
|
|
210
|
+
from diffusers import DiffusionPipeline
|
|
211
|
+
from orbitquant import quantize_pipeline, recipe, save_quantized_pipeline_component
|
|
212
|
+
|
|
213
|
+
pipe = DiffusionPipeline.from_pretrained(
|
|
214
|
+
"black-forest-labs/FLUX.2-klein-4B",
|
|
215
|
+
torch_dtype=torch.bfloat16,
|
|
216
|
+
)
|
|
217
|
+
config = recipe("w4a4", target_policy="flux2")
|
|
218
|
+
summary = quantize_pipeline(
|
|
219
|
+
pipe,
|
|
220
|
+
config,
|
|
221
|
+
component="transformer",
|
|
222
|
+
quantization_device="cuda",
|
|
223
|
+
)
|
|
224
|
+
save_quantized_pipeline_component(
|
|
225
|
+
pipe,
|
|
226
|
+
"./flux2-klein-orbitquant-w4a4",
|
|
227
|
+
config=config,
|
|
228
|
+
component="transformer",
|
|
229
|
+
source_model_id="black-forest-labs/FLUX.2-klein-4B",
|
|
230
|
+
summary=summary,
|
|
231
|
+
)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Published FLUX, Z-Image, and Wan repositories are compact Diffusers component
|
|
235
|
+
artifacts. Their model cards contain the matching pipeline code and native
|
|
236
|
+
generation settings.
|
|
237
|
+
|
|
238
|
+
Load a published component artifact together with its recorded source pipeline:
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
import torch
|
|
242
|
+
from huggingface_hub import snapshot_download
|
|
243
|
+
from orbitquant import load_quantized_pipeline_from_artifact
|
|
244
|
+
|
|
245
|
+
artifact_dir = snapshot_download(
|
|
246
|
+
"WaveCut/FLUX.1-schnell-OrbitQuant-W4A4",
|
|
247
|
+
repo_type="model",
|
|
248
|
+
)
|
|
249
|
+
pipe = load_quantized_pipeline_from_artifact(
|
|
250
|
+
artifact_dir,
|
|
251
|
+
torch_dtype=torch.bfloat16,
|
|
252
|
+
runtime_mode="auto_fused",
|
|
253
|
+
)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Packed Runtime
|
|
257
|
+
|
|
258
|
+
`runtime_mode="auto_fused"` is the default:
|
|
259
|
+
|
|
260
|
+
| Device | Dispatch |
|
|
261
|
+
| --- | --- |
|
|
262
|
+
| CUDA | Native packed CUDA package, then Triton packed matmul |
|
|
263
|
+
| MPS | Native packed Metal package |
|
|
264
|
+
| CPU | PyTorch reference path |
|
|
265
|
+
|
|
266
|
+
CUDA and MPS do not silently materialize a full BF16/FP16 weight matrix in
|
|
267
|
+
`auto_fused`. If no packed backend is available, the error includes the missing
|
|
268
|
+
backend and installation guidance.
|
|
269
|
+
|
|
270
|
+
Use the explicit reference path for compatibility or numerical debugging:
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
config = orbitquant.recipe("w4a4", runtime_mode="dequant_bf16")
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Build the ABI3 native package locally without Kernel Hub:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
cd native-kernels/orbitquant-packed-matmul
|
|
280
|
+
nix --option sandbox relaxed run .#build-and-copy -L
|
|
281
|
+
export PYTHONPATH="$PWD/build/<matching-torch-backend-platform-variant>:$PYTHONPATH"
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
The variant must match the Torch minor version, CUDA or Metal backend, C++ ABI,
|
|
285
|
+
architecture, and operating system. See
|
|
286
|
+
[`docs/kernel-audit.md`](docs/kernel-audit.md) for tested shapes, benchmark
|
|
287
|
+
methodology, and local package verification.
|
|
288
|
+
|
|
289
|
+
## Validated Architecture Coverage
|
|
290
|
+
|
|
291
|
+
The integration suite instantiates and inventories encoder-only, decoder-only,
|
|
292
|
+
encoder-decoder, causal LM, and vision transformer families:
|
|
293
|
+
|
|
294
|
+
| Family | Projection type |
|
|
295
|
+
| --- | --- |
|
|
296
|
+
| BERT | `torch.nn.Linear` |
|
|
297
|
+
| GPT-2 | Hugging Face `Conv1D` with transposed source weights |
|
|
298
|
+
| Llama | `torch.nn.Linear`, including GQA projections |
|
|
299
|
+
| T5 | encoder and decoder `torch.nn.Linear` projections |
|
|
300
|
+
| ViT | vision transformer `torch.nn.Linear` projections |
|
|
301
|
+
|
|
302
|
+
The paper-aligned release artifacts remain FLUX.1-schnell, Z-Image-Turbo, and
|
|
303
|
+
Wan 2.1 T2V. FLUX.2 Klein is an additional validated diffusion target.
|
|
304
|
+
|
|
305
|
+
Architecture coverage means the model can be discovered, quantized, executed,
|
|
306
|
+
saved, and restored without model-name-specific code. It does not guarantee a
|
|
307
|
+
quality-preserving bit setting. OrbitQuant was evaluated in the paper on image
|
|
308
|
+
and video diffusion transformers; language and classification models can be
|
|
309
|
+
more sensitive, and their quality must be measured before publishing a
|
|
310
|
+
checkpoint. The library exposes module overrides for such recipes but does not
|
|
311
|
+
silently substitute a different quantization algorithm.
|
|
312
|
+
|
|
313
|
+
## Method Conformance
|
|
314
|
+
|
|
315
|
+
The implementation follows the paper's shared data-agnostic basis:
|
|
316
|
+
|
|
317
|
+
- RPBH permutation, Rademacher signs, block FWHT, and orthonormal scaling.
|
|
318
|
+
- Offline folded weight rotation with BF16 row norms and quantized unit
|
|
319
|
+
directions.
|
|
320
|
+
- Online per-token norm, normalized activation rotation, nearest-centroid
|
|
321
|
+
quantization, and rescaling.
|
|
322
|
+
- One fixed codebook per `(input dimension, bit width, algorithm version)` and
|
|
323
|
+
no prompt, timestep, or calibration statistics.
|
|
324
|
+
- INT4 group-64 RTN for model policies that identify dynamic AdaLN projections.
|
|
325
|
+
|
|
326
|
+
The detailed requirement matrix is in
|
|
327
|
+
[`docs/paper-methodology-audit.md`](docs/paper-methodology-audit.md).
|
|
328
|
+
|
|
329
|
+
## Development
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
uv sync --extra hf --extra dev
|
|
333
|
+
uv run pytest -q
|
|
334
|
+
uv run ruff check .
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## License
|
|
338
|
+
|
|
339
|
+
OrbitQuant is licensed under Apache-2.0. Model artifacts retain the license and
|
|
340
|
+
provenance of their source checkpoints.
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# OrbitQuant
|
|
2
|
+
|
|
3
|
+
OrbitQuant is a calibration-free post-training quantizer for transformer linear
|
|
4
|
+
projections. It implements the method from
|
|
5
|
+
[OrbitQuant: Data-Agnostic Quantization for Image and Video Diffusion Transformers](https://arxiv.org/abs/2607.02461)
|
|
6
|
+
and exposes it through Hugging Face Transformers, Diffusers, and a direct
|
|
7
|
+
PyTorch API.
|
|
8
|
+
|
|
9
|
+
The implementation is clean-room and Apache-2.0 licensed.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Automatic coverage of registered linear-compatible modules in transformer
|
|
14
|
+
backbones, independent of model class or modality.
|
|
15
|
+
- Built-in support for `torch.nn.Linear` and Hugging Face `Conv1D` projections.
|
|
16
|
+
- Public adapters for custom `F.linear`-equivalent module types and transposed
|
|
17
|
+
weight layouts.
|
|
18
|
+
- RPBH rotation, exact unit-sphere Lloyd-Max codebooks, packed 2/3/4/6/8-bit
|
|
19
|
+
weights, and online activation quantization without calibration data.
|
|
20
|
+
- Model-specific policies for paper-sensitive AdaLN and output-layer handling.
|
|
21
|
+
- Compact `safetensors` artifacts and Hugging Face `save_pretrained()` /
|
|
22
|
+
`from_pretrained()` integration.
|
|
23
|
+
- Packed-weight CUDA, Triton, and Metal inference paths that avoid a full
|
|
24
|
+
dequantized weight matrix.
|
|
25
|
+
|
|
26
|
+
Embeddings, timestep modules, task heads, and common final projections are
|
|
27
|
+
kept in source precision by default. Every automatic decision is available as
|
|
28
|
+
a machine-readable inventory before quantization.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install "orbitquant[hf]"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Install the CUDA/Triton and local-kernel loader dependencies with:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install "orbitquant[hf,kernels]"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quantize A Transformers Model
|
|
43
|
+
|
|
44
|
+
Importing `orbitquant` registers the backend with supported Transformers and
|
|
45
|
+
Diffusers versions. The default `target_policy="auto"` selects a known
|
|
46
|
+
paper policy where applicable and otherwise uses the universal policy.
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
import torch
|
|
50
|
+
import orbitquant
|
|
51
|
+
from transformers import AutoModelForCausalLM
|
|
52
|
+
|
|
53
|
+
config = orbitquant.recipe(
|
|
54
|
+
"w4a4",
|
|
55
|
+
runtime_mode="auto_fused",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
model = AutoModelForCausalLM.from_pretrained(
|
|
59
|
+
"your-org/your-transformer",
|
|
60
|
+
dtype=torch.bfloat16,
|
|
61
|
+
quantization_config=config,
|
|
62
|
+
)
|
|
63
|
+
model.save_pretrained("./your-transformer-orbitquant-w4a4")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Load the packed model after importing the backend:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
import orbitquant
|
|
70
|
+
from transformers import AutoModelForCausalLM
|
|
71
|
+
|
|
72
|
+
model = AutoModelForCausalLM.from_pretrained(
|
|
73
|
+
"./your-transformer-orbitquant-w4a4",
|
|
74
|
+
device_map="auto",
|
|
75
|
+
)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Named recipes are `w4a4`, `w3a3`, `w2a4`, `w2a3`, and `w4a6`. They create a
|
|
79
|
+
normal `OrbitQuantConfig`, so every field can be overridden.
|
|
80
|
+
|
|
81
|
+
## Inspect Coverage
|
|
82
|
+
|
|
83
|
+
Inspect a model before replacing modules:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from orbitquant import inspect_linear_module_policy, recipe
|
|
87
|
+
from transformers import AutoModel
|
|
88
|
+
|
|
89
|
+
model = AutoModel.from_pretrained("your-org/your-transformer")
|
|
90
|
+
report = inspect_linear_module_policy(model, recipe("w4a4"))
|
|
91
|
+
|
|
92
|
+
print(report["action_counts"])
|
|
93
|
+
print(report["quantized_modules"])
|
|
94
|
+
print(report["skipped_modules"])
|
|
95
|
+
print(report["unsupported_linear_modules"])
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The universal policy quantizes every registered linear-compatible module except
|
|
99
|
+
known embeddings, timestep modules, task/output heads, and explicit skips. It
|
|
100
|
+
does not depend on names such as `layers`, `blocks`, or a particular model
|
|
101
|
+
class.
|
|
102
|
+
|
|
103
|
+
Use `modules_to_convert` as an allowlist and define AdaLN/skips with exact names,
|
|
104
|
+
substrings, or glob patterns:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from orbitquant import OrbitQuantConfig
|
|
108
|
+
|
|
109
|
+
config = OrbitQuantConfig(
|
|
110
|
+
modules_to_convert=["backbone.*.projection"],
|
|
111
|
+
modules_to_use_adaln=["backbone.*.modulation"],
|
|
112
|
+
modules_to_not_convert=["*.sensitive_output"],
|
|
113
|
+
)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Explicit dtype overrides remain available through `modules_dtype_dict`.
|
|
117
|
+
|
|
118
|
+
## Quantize An Instantiated Module
|
|
119
|
+
|
|
120
|
+
For ordinary PyTorch models or frameworks that do not use Hugging Face loading
|
|
121
|
+
hooks:
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from orbitquant import quantize_model, recipe
|
|
125
|
+
|
|
126
|
+
summary = quantize_model(
|
|
127
|
+
model,
|
|
128
|
+
recipe("w4a4"),
|
|
129
|
+
quantization_device="cuda",
|
|
130
|
+
)
|
|
131
|
+
print(summary.quantized_modules)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The replacement supports arbitrary leading dimensions and treats the final
|
|
135
|
+
dimension as `in_features`, including sequence, image-token, and video-token
|
|
136
|
+
layouts.
|
|
137
|
+
|
|
138
|
+
## Custom Linear Modules
|
|
139
|
+
|
|
140
|
+
Register a module whose forward operation is equivalent to `F.linear`. The
|
|
141
|
+
adapter describes only its source weight layout and feature attributes:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from orbitquant import register_linear_adapter
|
|
145
|
+
|
|
146
|
+
register_linear_adapter(
|
|
147
|
+
MyLinear,
|
|
148
|
+
weight_layout="in_out",
|
|
149
|
+
in_features_attr="input_size",
|
|
150
|
+
out_features_attr="output_size",
|
|
151
|
+
)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
OrbitQuant stores every replacement in canonical `[out_features, in_features]`
|
|
155
|
+
layout. Modules with additional routing, tensor-parallel communication, sparse
|
|
156
|
+
expert selection, or non-linear forward semantics need an architecture-aware
|
|
157
|
+
adapter; the inspection report lists unregistered linear candidates instead of
|
|
158
|
+
silently replacing them.
|
|
159
|
+
|
|
160
|
+
## Diffusers
|
|
161
|
+
|
|
162
|
+
Quantize the denoiser component of a pipeline:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
import torch
|
|
166
|
+
from diffusers import DiffusionPipeline
|
|
167
|
+
from orbitquant import quantize_pipeline, recipe, save_quantized_pipeline_component
|
|
168
|
+
|
|
169
|
+
pipe = DiffusionPipeline.from_pretrained(
|
|
170
|
+
"black-forest-labs/FLUX.2-klein-4B",
|
|
171
|
+
torch_dtype=torch.bfloat16,
|
|
172
|
+
)
|
|
173
|
+
config = recipe("w4a4", target_policy="flux2")
|
|
174
|
+
summary = quantize_pipeline(
|
|
175
|
+
pipe,
|
|
176
|
+
config,
|
|
177
|
+
component="transformer",
|
|
178
|
+
quantization_device="cuda",
|
|
179
|
+
)
|
|
180
|
+
save_quantized_pipeline_component(
|
|
181
|
+
pipe,
|
|
182
|
+
"./flux2-klein-orbitquant-w4a4",
|
|
183
|
+
config=config,
|
|
184
|
+
component="transformer",
|
|
185
|
+
source_model_id="black-forest-labs/FLUX.2-klein-4B",
|
|
186
|
+
summary=summary,
|
|
187
|
+
)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Published FLUX, Z-Image, and Wan repositories are compact Diffusers component
|
|
191
|
+
artifacts. Their model cards contain the matching pipeline code and native
|
|
192
|
+
generation settings.
|
|
193
|
+
|
|
194
|
+
Load a published component artifact together with its recorded source pipeline:
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
import torch
|
|
198
|
+
from huggingface_hub import snapshot_download
|
|
199
|
+
from orbitquant import load_quantized_pipeline_from_artifact
|
|
200
|
+
|
|
201
|
+
artifact_dir = snapshot_download(
|
|
202
|
+
"WaveCut/FLUX.1-schnell-OrbitQuant-W4A4",
|
|
203
|
+
repo_type="model",
|
|
204
|
+
)
|
|
205
|
+
pipe = load_quantized_pipeline_from_artifact(
|
|
206
|
+
artifact_dir,
|
|
207
|
+
torch_dtype=torch.bfloat16,
|
|
208
|
+
runtime_mode="auto_fused",
|
|
209
|
+
)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Packed Runtime
|
|
213
|
+
|
|
214
|
+
`runtime_mode="auto_fused"` is the default:
|
|
215
|
+
|
|
216
|
+
| Device | Dispatch |
|
|
217
|
+
| --- | --- |
|
|
218
|
+
| CUDA | Native packed CUDA package, then Triton packed matmul |
|
|
219
|
+
| MPS | Native packed Metal package |
|
|
220
|
+
| CPU | PyTorch reference path |
|
|
221
|
+
|
|
222
|
+
CUDA and MPS do not silently materialize a full BF16/FP16 weight matrix in
|
|
223
|
+
`auto_fused`. If no packed backend is available, the error includes the missing
|
|
224
|
+
backend and installation guidance.
|
|
225
|
+
|
|
226
|
+
Use the explicit reference path for compatibility or numerical debugging:
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
config = orbitquant.recipe("w4a4", runtime_mode="dequant_bf16")
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Build the ABI3 native package locally without Kernel Hub:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
cd native-kernels/orbitquant-packed-matmul
|
|
236
|
+
nix --option sandbox relaxed run .#build-and-copy -L
|
|
237
|
+
export PYTHONPATH="$PWD/build/<matching-torch-backend-platform-variant>:$PYTHONPATH"
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The variant must match the Torch minor version, CUDA or Metal backend, C++ ABI,
|
|
241
|
+
architecture, and operating system. See
|
|
242
|
+
[`docs/kernel-audit.md`](docs/kernel-audit.md) for tested shapes, benchmark
|
|
243
|
+
methodology, and local package verification.
|
|
244
|
+
|
|
245
|
+
## Validated Architecture Coverage
|
|
246
|
+
|
|
247
|
+
The integration suite instantiates and inventories encoder-only, decoder-only,
|
|
248
|
+
encoder-decoder, causal LM, and vision transformer families:
|
|
249
|
+
|
|
250
|
+
| Family | Projection type |
|
|
251
|
+
| --- | --- |
|
|
252
|
+
| BERT | `torch.nn.Linear` |
|
|
253
|
+
| GPT-2 | Hugging Face `Conv1D` with transposed source weights |
|
|
254
|
+
| Llama | `torch.nn.Linear`, including GQA projections |
|
|
255
|
+
| T5 | encoder and decoder `torch.nn.Linear` projections |
|
|
256
|
+
| ViT | vision transformer `torch.nn.Linear` projections |
|
|
257
|
+
|
|
258
|
+
The paper-aligned release artifacts remain FLUX.1-schnell, Z-Image-Turbo, and
|
|
259
|
+
Wan 2.1 T2V. FLUX.2 Klein is an additional validated diffusion target.
|
|
260
|
+
|
|
261
|
+
Architecture coverage means the model can be discovered, quantized, executed,
|
|
262
|
+
saved, and restored without model-name-specific code. It does not guarantee a
|
|
263
|
+
quality-preserving bit setting. OrbitQuant was evaluated in the paper on image
|
|
264
|
+
and video diffusion transformers; language and classification models can be
|
|
265
|
+
more sensitive, and their quality must be measured before publishing a
|
|
266
|
+
checkpoint. The library exposes module overrides for such recipes but does not
|
|
267
|
+
silently substitute a different quantization algorithm.
|
|
268
|
+
|
|
269
|
+
## Method Conformance
|
|
270
|
+
|
|
271
|
+
The implementation follows the paper's shared data-agnostic basis:
|
|
272
|
+
|
|
273
|
+
- RPBH permutation, Rademacher signs, block FWHT, and orthonormal scaling.
|
|
274
|
+
- Offline folded weight rotation with BF16 row norms and quantized unit
|
|
275
|
+
directions.
|
|
276
|
+
- Online per-token norm, normalized activation rotation, nearest-centroid
|
|
277
|
+
quantization, and rescaling.
|
|
278
|
+
- One fixed codebook per `(input dimension, bit width, algorithm version)` and
|
|
279
|
+
no prompt, timestep, or calibration statistics.
|
|
280
|
+
- INT4 group-64 RTN for model policies that identify dynamic AdaLN projections.
|
|
281
|
+
|
|
282
|
+
The detailed requirement matrix is in
|
|
283
|
+
[`docs/paper-methodology-audit.md`](docs/paper-methodology-audit.md).
|
|
284
|
+
|
|
285
|
+
## Development
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
uv sync --extra hf --extra dev
|
|
289
|
+
uv run pytest -q
|
|
290
|
+
uv run ruff check .
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## License
|
|
294
|
+
|
|
295
|
+
OrbitQuant is licensed under Apache-2.0. Model artifacts retain the license and
|
|
296
|
+
provenance of their source checkpoints.
|