orbitquant 0.2.0__tar.gz → 0.2.1__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.2.0 → orbitquant-0.2.1}/.github/workflows/publish-pypi.yml +1 -1
- {orbitquant-0.2.0 → orbitquant-0.2.1}/PKG-INFO +4 -3
- {orbitquant-0.2.0 → orbitquant-0.2.1}/README.md +3 -2
- {orbitquant-0.2.0 → orbitquant-0.2.1}/docs/paper-methodology-audit.md +3 -1
- {orbitquant-0.2.0 → orbitquant-0.2.1}/pyproject.toml +1 -1
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/__init__.py +1 -1
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/model_card.py +78 -5
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/prompts.py +89 -25
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/report.py +8 -5
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_artifact_writer.py +3 -1
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_cli.py +8 -8
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_eval_prompts.py +7 -1
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_eval_report.py +4 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_model_card.py +36 -1
- {orbitquant-0.2.0 → orbitquant-0.2.1}/uv.lock +1 -1
- {orbitquant-0.2.0 → orbitquant-0.2.1}/.github/workflows/ci.yml +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/.gitignore +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/LICENSE +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/docs/kernel-audit.md +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/CARD.md +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/benchmarks/benchmark.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/build.toml +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/example.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/flake.lock +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/flake.nix +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/orbitquant_packed_matmul_cuda/packed_matmul.cu +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/orbitquant_packed_matmul_metal/packed_matmul.metal +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/orbitquant_packed_matmul_metal/packed_matmul.mm +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/tests/__init__.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/tests/test_packed_matmul.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/torch-ext/orbitquant_packed_matmul/__init__.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/torch-ext/torch_binding.cpp +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/torch-ext/torch_binding.h +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/scripts/run_cuda_kernel_checks.sh +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/scripts/run_hf_compat_checks.sh +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/scripts/run_mps_kernel_checks.sh +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/scripts/run_paper_methodology_checks.sh +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/scripts/runpod_ssh_health.sh +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/scripts/verify_hf_kernel_model_artifact.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/adaln.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/__init__.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/assets.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/benchmark.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/checksums.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/comparisons.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/loader.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/manifest.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/refresh.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/repair.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/validator.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/artifacts/writer.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/benchmarks.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/cli/__init__.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/cli/main.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/codebooks/__init__.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/codebooks/lloyd_max.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/config.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/errors.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/__init__.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/assets.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/external_export.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/external_metrics.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/external_plan.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/metrics.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/native_plan.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/native_runner.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/eval/native_settings.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/functional.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/hub.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/kernels/__init__.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/kernels/dispatch.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/kernels/mps.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/kernels/native_packed_matmul.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/kernels/triton_cuda.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/layers.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/linear_adapters.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/modeling.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/packing/__init__.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/packing/bitpack.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/pipeline.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/policies/__init__.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/policies/flux.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/policies/flux2.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/policies/generic_dit.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/policies/wan.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/policies/z_image.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/quantizer.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/recipes.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/rotations/__init__.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/rotations/fwht.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/rotations/rpbh.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/src/orbitquant/transformers_ops.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_adaln_rtn.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_benchmarks.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_bitpack.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_ci.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_cli_report.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_codebooks.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_config.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_diffusers_modelmixin_integration.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_distribution.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_documentation.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_eval_assets.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_external_eval_plan.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_external_export.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_hub.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_kernel_model_verifier.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_kernels.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_linear_adapters.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_manifest.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_model_quantization.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_native_kernel_package.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_native_packed_matmul.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_native_runner.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_native_settings.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_optional_dependencies.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_orbit_linear.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_paper_alignment.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_paper_methodology.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_pipeline_helpers.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_policies.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_prompt_jobs.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_prompt_selection.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_quantizer_adapter.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_rpbh.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_target_policies.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_transformers_pretrained_integration.py +0 -0
- {orbitquant-0.2.0 → orbitquant-0.2.1}/tests/test_universal_transformers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: orbitquant
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Calibration-free OrbitQuant for transformer linear projections
|
|
5
5
|
Project-URL: Homepage, https://github.com/iamwavecut/OrbitQuant
|
|
6
6
|
Project-URL: Repository, https://github.com/iamwavecut/OrbitQuant
|
|
@@ -232,8 +232,9 @@ save_quantized_pipeline_component(
|
|
|
232
232
|
```
|
|
233
233
|
|
|
234
234
|
Published FLUX, Z-Image, and Wan repositories are compact Diffusers component
|
|
235
|
-
artifacts.
|
|
236
|
-
generation settings
|
|
235
|
+
artifacts. Image model cards contain the matching pipeline code, native
|
|
236
|
+
generation settings, and a ten-prompt full-resolution BF16-vs-OrbitQuant
|
|
237
|
+
comparison matrix.
|
|
237
238
|
|
|
238
239
|
Load a published component artifact together with its recorded source pipeline:
|
|
239
240
|
|
|
@@ -188,8 +188,9 @@ save_quantized_pipeline_component(
|
|
|
188
188
|
```
|
|
189
189
|
|
|
190
190
|
Published FLUX, Z-Image, and Wan repositories are compact Diffusers component
|
|
191
|
-
artifacts.
|
|
192
|
-
generation settings
|
|
191
|
+
artifacts. Image model cards contain the matching pipeline code, native
|
|
192
|
+
generation settings, and a ten-prompt full-resolution BF16-vs-OrbitQuant
|
|
193
|
+
comparison matrix.
|
|
193
194
|
|
|
194
195
|
Load a published component artifact together with its recorded source pipeline:
|
|
195
196
|
|
|
@@ -143,7 +143,9 @@ Native artifact readiness is separate from full GenEval or VBench scoring.
|
|
|
143
143
|
Those runs prove metric-table claims. The required artifact-readiness evidence
|
|
144
144
|
is:
|
|
145
145
|
|
|
146
|
-
-
|
|
146
|
+
- Ten-prompt native-resolution BF16-vs-OrbitQuant comparison matrix for image
|
|
147
|
+
artifacts, including dense composition, fine detail, artistic style, and
|
|
148
|
+
Latin, Russian, Japanese, and Chinese typography stress cases.
|
|
147
149
|
- Same prompt and seed for BF16 and OrbitQuant.
|
|
148
150
|
- Native settings from `src/orbitquant/eval/native_settings.py`.
|
|
149
151
|
- Finite, nonblank output checks.
|
|
@@ -4,6 +4,7 @@ from typing import Any
|
|
|
4
4
|
|
|
5
5
|
from orbitquant.artifacts.manifest import OrbitQuantManifest
|
|
6
6
|
from orbitquant.eval.native_settings import NativeSuite, list_native_suites
|
|
7
|
+
from orbitquant.eval.prompts import default_prompt_payload
|
|
7
8
|
|
|
8
9
|
_GENEVAL_METRICS = (
|
|
9
10
|
"geneval_overall",
|
|
@@ -65,7 +66,7 @@ def _install_snippet() -> str:
|
|
|
65
66
|
return "\n".join(
|
|
66
67
|
[
|
|
67
68
|
"```bash",
|
|
68
|
-
"pip install \"orbitquant[hf]\"",
|
|
69
|
+
"pip install \"orbitquant[hf,kernels]>=0.2.0\"",
|
|
69
70
|
"```",
|
|
70
71
|
]
|
|
71
72
|
)
|
|
@@ -343,6 +344,70 @@ def _native_validation_proof_section(
|
|
|
343
344
|
return lines
|
|
344
345
|
|
|
345
346
|
|
|
347
|
+
def _comparison_prompt_section(
|
|
348
|
+
source_model_id: str,
|
|
349
|
+
benchmark_summary: dict[str, Any] | None,
|
|
350
|
+
) -> list[str]:
|
|
351
|
+
suite = _native_suite_for_source_model(source_model_id)
|
|
352
|
+
if suite is None or suite.frames is not None or not isinstance(benchmark_summary, dict):
|
|
353
|
+
return []
|
|
354
|
+
proof = benchmark_summary.get("native_smoke")
|
|
355
|
+
if not isinstance(proof, dict):
|
|
356
|
+
return []
|
|
357
|
+
prompt_payload = default_prompt_payload(
|
|
358
|
+
{
|
|
359
|
+
"flux2-native": "flux2",
|
|
360
|
+
"flux1-schnell-native": "flux",
|
|
361
|
+
"z-image-native": "z_image",
|
|
362
|
+
}[suite.name]
|
|
363
|
+
)
|
|
364
|
+
prompts = prompt_payload["prompts"]
|
|
365
|
+
if proof.get("paired_prompt_seed_count") != len(prompts):
|
|
366
|
+
return []
|
|
367
|
+
paired_keys = proof.get("paired_prompt_seed_keys")
|
|
368
|
+
if not isinstance(paired_keys, list):
|
|
369
|
+
return []
|
|
370
|
+
paired_prompt_ids = {
|
|
371
|
+
str(item[2])
|
|
372
|
+
for item in paired_keys
|
|
373
|
+
if isinstance(item, list) and len(item) == 3
|
|
374
|
+
}
|
|
375
|
+
if paired_prompt_ids != {str(prompt["id"]) for prompt in prompts}:
|
|
376
|
+
return []
|
|
377
|
+
|
|
378
|
+
required_text = {
|
|
379
|
+
"english-text-rendering": "ORBIT QUANT; DATA WITHOUT CALIBRATION",
|
|
380
|
+
"cyrillic-text-rendering": "КВАНТОВАЯ ОРБИТА; МОСКВА 2049; КВАНТОВАНИЕ",
|
|
381
|
+
"style-heavy": "量子の軌道; 東京の未来",
|
|
382
|
+
"occlusion-reflection": "量子轨道; 未来之城",
|
|
383
|
+
}
|
|
384
|
+
lines = [
|
|
385
|
+
"## Comparison Prompt Set",
|
|
386
|
+
"",
|
|
387
|
+
f"The matrix uses all ten prompts from `{prompt_payload['prompt_pack']}` at "
|
|
388
|
+
f"`{suite.width}x{suite.height}`. BF16 and OrbitQuant use the same seed for "
|
|
389
|
+
"each row.",
|
|
390
|
+
"",
|
|
391
|
+
"| # | Stress case | Exact required text |",
|
|
392
|
+
"| ---: | --- | --- |",
|
|
393
|
+
]
|
|
394
|
+
for index, prompt in enumerate(prompts, start=1):
|
|
395
|
+
text = required_text.get(str(prompt["id"]), "-")
|
|
396
|
+
lines.append(f"| {index} | {prompt['title']} | {text} |")
|
|
397
|
+
lines.extend(
|
|
398
|
+
[
|
|
399
|
+
"",
|
|
400
|
+
"<details>",
|
|
401
|
+
"<summary>Exact comparison prompts</summary>",
|
|
402
|
+
"",
|
|
403
|
+
]
|
|
404
|
+
)
|
|
405
|
+
for index, prompt in enumerate(prompts, start=1):
|
|
406
|
+
lines.append(f"{index}. **{prompt['title']}**: {prompt['prompt']}")
|
|
407
|
+
lines.extend(["", "</details>", ""])
|
|
408
|
+
return lines
|
|
409
|
+
|
|
410
|
+
|
|
346
411
|
def render_model_card(
|
|
347
412
|
manifest: OrbitQuantManifest,
|
|
348
413
|
*,
|
|
@@ -356,6 +421,9 @@ def render_model_card(
|
|
|
356
421
|
data["source_model_id"], benchmark_summary
|
|
357
422
|
)
|
|
358
423
|
native_validation_proof_lines = _native_validation_proof_section(benchmark_summary)
|
|
424
|
+
comparison_prompt_lines = _comparison_prompt_section(
|
|
425
|
+
data["source_model_id"], benchmark_summary
|
|
426
|
+
)
|
|
359
427
|
adaln_group_size = int(data.get("adaln_group_size", 64))
|
|
360
428
|
adaln_default_note = (
|
|
361
429
|
"- AdaLN group-size note: paper default."
|
|
@@ -425,14 +493,19 @@ def render_model_card(
|
|
|
425
493
|
_usage_snippet(data["source_model_id"], bits),
|
|
426
494
|
"",
|
|
427
495
|
"`runtime_mode=\"auto_fused\"` is the default optimized runtime. On "
|
|
428
|
-
"CUDA
|
|
429
|
-
"
|
|
430
|
-
"
|
|
431
|
-
"
|
|
496
|
+
"CUDA, the `kernels` extra provides the Triton packed fallback; a "
|
|
497
|
+
"locally built native CUDA package is preferred automatically when "
|
|
498
|
+
"installed. On MPS, build and install the native Metal package from "
|
|
499
|
+
"the OrbitQuant source tree. See the [OrbitQuant runtime instructions]"
|
|
500
|
+
"(https://github.com/iamwavecut/OrbitQuant/blob/main/docs/"
|
|
501
|
+
"kernel-audit.md#local-native-package). Use "
|
|
502
|
+
"`runtime_mode=\"dequant_bf16\"` only as an explicit compatibility/"
|
|
503
|
+
"debug reference path.",
|
|
432
504
|
"",
|
|
433
505
|
*native_settings_lines,
|
|
434
506
|
*validation_status_lines,
|
|
435
507
|
*native_validation_proof_lines,
|
|
508
|
+
*comparison_prompt_lines,
|
|
436
509
|
"## Quantization",
|
|
437
510
|
"",
|
|
438
511
|
f"- Method: `{data['quant_method']}`",
|
|
@@ -8,62 +8,126 @@ from typing import Any
|
|
|
8
8
|
IMAGE_VISUAL_PROMPTS = [
|
|
9
9
|
{
|
|
10
10
|
"id": "simple-object",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
11
|
+
"title": "01 Fine-detail astrolabe",
|
|
12
|
+
"category": "fine_detail",
|
|
13
|
+
"prompt": (
|
|
14
|
+
"A museum-grade macro photograph of a single ornate brass astronomical clock, "
|
|
15
|
+
"covered with interlocking gears, engraved constellations, enamel moon phases, "
|
|
16
|
+
"hair-thin hands, tiny screws, worn gilt edges, and dust caught in the mechanisms; "
|
|
17
|
+
"dramatic Rembrandt lighting, black velvet background, extreme material detail, "
|
|
18
|
+
"large-format photography, every cog mechanically coherent"
|
|
19
|
+
),
|
|
13
20
|
},
|
|
14
21
|
{
|
|
15
22
|
"id": "two-object-composition",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
23
|
+
"title": "02 Layered character composition",
|
|
24
|
+
"category": "layered_character_composition",
|
|
25
|
+
"prompt": (
|
|
26
|
+
"A lacquered white android and an elderly watchmaker facing each other across a "
|
|
27
|
+
"crowded Art Nouveau workshop, jointly repairing a mechanical hummingbird; the "
|
|
28
|
+
"android is on the left, the watchmaker on the right, the bird centered between "
|
|
29
|
+
"them, hundreds of tools and clock parts in the midground, rain and a tram visible "
|
|
30
|
+
"through the window, coherent mirror reflections, cinematic tungsten and cyan light, "
|
|
31
|
+
"intricate faces and hands, editorial realism"
|
|
32
|
+
),
|
|
18
33
|
},
|
|
19
34
|
{
|
|
20
35
|
"id": "counting",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
36
|
+
"title": "03 Exact counting and choreography",
|
|
37
|
+
"category": "counting_and_choreography",
|
|
38
|
+
"prompt": (
|
|
39
|
+
"Exactly seven masked dancers performing on seven separate illuminated platforms "
|
|
40
|
+
"inside a vast flooded opera house, no extra dancers; alternating crimson and ivory "
|
|
41
|
+
"costumes from left to right, each dancer in a distinct pose, balconies reflected in "
|
|
42
|
+
"the water, floating candles, volumetric stage haze, baroque theatrical photography, "
|
|
43
|
+
"sharp foreground and readable background architecture"
|
|
44
|
+
),
|
|
23
45
|
},
|
|
24
46
|
{
|
|
25
47
|
"id": "color-binding",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
48
|
+
"title": "04 Dense color and object binding",
|
|
49
|
+
"category": "dense_color_binding",
|
|
50
|
+
"prompt": (
|
|
51
|
+
"An elaborate surreal fashion tableau with three models: the left model wears a "
|
|
52
|
+
"cobalt-blue coat and holds a yellow glass sphere, the center model wears a saffron "
|
|
53
|
+
"dress and holds a green ceramic pyramid, the right model wears an emerald suit and "
|
|
54
|
+
"holds a red velvet cube; rococo greenhouse, rare orchids, patterned tile floor, "
|
|
55
|
+
"prismatic sunlight, magazine-cover precision, preserve every color-object pairing"
|
|
56
|
+
),
|
|
28
57
|
},
|
|
29
58
|
{
|
|
30
59
|
"id": "spatial-relationship",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
60
|
+
"title": "05 Nested spatial relationships",
|
|
61
|
+
"category": "nested_spatial_relationships",
|
|
62
|
+
"prompt": (
|
|
63
|
+
"A meticulous cutaway diorama of a vertical city: a glass greenhouse sits directly "
|
|
64
|
+
"above a silver subway car, a red fox stands inside the greenhouse beneath a hanging "
|
|
65
|
+
"moon lamp, a violinist waits below the subway platform, and a yellow airship passes "
|
|
66
|
+
"behind the entire structure; isometric perspective, architectural-section drawing "
|
|
67
|
+
"mixed with photoreal materials, dozens of tiny rooms, stairs and people, clean depth"
|
|
68
|
+
),
|
|
33
69
|
},
|
|
34
70
|
{
|
|
35
71
|
"id": "long-prompt",
|
|
36
|
-
"
|
|
72
|
+
"title": "06 Cinematic night-market panorama",
|
|
73
|
+
"category": "cinematic_panorama",
|
|
37
74
|
"prompt": (
|
|
38
|
-
"A
|
|
39
|
-
"
|
|
40
|
-
"the
|
|
75
|
+
"A sweeping cinematic panorama of a rain-soaked floating night market at blue hour: "
|
|
76
|
+
"in the foreground a chef plates translucent dumplings under a red silk canopy; in "
|
|
77
|
+
"the midground children chase paper lanterns across narrow bridges while merchants "
|
|
78
|
+
"unload exotic fruit from wooden boats; in the background a terraced megacity rises "
|
|
79
|
+
"through mist beneath a storm, with hundreds of warm windows, wet reflections, steam, "
|
|
80
|
+
"umbrellas, ropes and signage; deep focus, anamorphic highlights, realistic faces, "
|
|
81
|
+
"coherent perspective, painterly color grading with documentary-level detail"
|
|
41
82
|
),
|
|
42
83
|
},
|
|
43
84
|
{
|
|
44
85
|
"id": "english-text-rendering",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
86
|
+
"title": "07 Editorial Latin typography",
|
|
87
|
+
"category": "latin_typography",
|
|
88
|
+
"prompt": (
|
|
89
|
+
"A sophisticated Swiss International Style exhibition poster photographed behind "
|
|
90
|
+
"slightly reflective museum glass, with the exact large headline \"ORBIT QUANT\" and "
|
|
91
|
+
"the exact smaller subtitle \"DATA WITHOUT CALIBRATION\"; strict modular grid, red, "
|
|
92
|
+
"black and white screenprint, tiny registration marks, embossed paper fibers, sharp "
|
|
93
|
+
"letterforms, dramatic gallery shadows, no other text"
|
|
94
|
+
),
|
|
47
95
|
},
|
|
48
96
|
{
|
|
49
97
|
"id": "cyrillic-text-rendering",
|
|
50
|
-
"
|
|
51
|
-
"
|
|
98
|
+
"title": "08 Russian Constructivist typography",
|
|
99
|
+
"category": "russian_typography",
|
|
100
|
+
"prompt": (
|
|
101
|
+
"A richly detailed Russian Constructivist science-fiction poster with the exact "
|
|
102
|
+
"Cyrillic headline \"КВАНТОВАЯ ОРБИТА\", the exact subtitle \"МОСКВА 2049\", and a "
|
|
103
|
+
"small exact stamp \"КВАНТОВАНИЕ\"; diagonal red and black geometry, cream paper, "
|
|
104
|
+
"cosmonaut portrait, orbital diagrams, halftone grain, folded corners, layered ink, "
|
|
105
|
+
"museum archival photograph, all letters crisp and correctly ordered"
|
|
106
|
+
),
|
|
52
107
|
},
|
|
53
108
|
{
|
|
54
109
|
"id": "style-heavy",
|
|
55
|
-
"
|
|
110
|
+
"title": "09 Japanese typography and mixed style",
|
|
111
|
+
"category": "japanese_typography",
|
|
56
112
|
"prompt": (
|
|
57
|
-
"
|
|
58
|
-
"
|
|
113
|
+
"An elaborate Japanese art magazine cover combining Edo woodblock printing with a "
|
|
114
|
+
"futuristic Tokyo skyline, with the exact vertical title \"量子の軌道\" and the exact "
|
|
115
|
+
"subtitle \"東京の未来\"; giant indigo waves curl around glass towers, red-crowned "
|
|
116
|
+
"cranes cross a gold moon, tiny pedestrians and trains fill the lower streets, visible "
|
|
117
|
+
"washi fibers, layered spot colors, precise Japanese glyphs, balanced editorial layout"
|
|
59
118
|
),
|
|
60
119
|
},
|
|
61
120
|
{
|
|
62
121
|
"id": "occlusion-reflection",
|
|
63
|
-
"
|
|
122
|
+
"title": "10 Chinese typography, reflection, occlusion",
|
|
123
|
+
"category": "chinese_typography_reflection_occlusion",
|
|
64
124
|
"prompt": (
|
|
65
|
-
"A
|
|
66
|
-
"
|
|
125
|
+
"A luxurious Chinese retro-futurist department-store window at night with the exact "
|
|
126
|
+
"gold title \"量子轨道\" and the exact red subtitle \"未来之城\"; a curved chrome "
|
|
127
|
+
"robot "
|
|
128
|
+
"is partly occluded by peonies and blue-and-white porcelain, the calligraphy and neon "
|
|
129
|
+
"street must appear coherently reflected across its body, multiple glass layers, silk "
|
|
130
|
+
"textures, passing bicycles, cinematic rain, fine product-photography detail"
|
|
67
131
|
),
|
|
68
132
|
},
|
|
69
133
|
]
|
|
@@ -152,7 +216,7 @@ def default_prompt_payload(target_policy: str) -> dict[str, Any]:
|
|
|
152
216
|
"prompts": deepcopy(VIDEO_VISUAL_PROMPTS),
|
|
153
217
|
}
|
|
154
218
|
return {
|
|
155
|
-
"prompt_pack": "
|
|
219
|
+
"prompt_pack": "image_visual_v2",
|
|
156
220
|
"media_type": "image",
|
|
157
221
|
"target_policy": target_policy,
|
|
158
222
|
"prompts": deepcopy(IMAGE_VISUAL_PROMPTS),
|
|
@@ -308,6 +308,8 @@ def _write_comparison_matrix(
|
|
|
308
308
|
items: list[dict[str, Any]],
|
|
309
309
|
*,
|
|
310
310
|
title: str,
|
|
311
|
+
tile_size: tuple[int, int] = (208, 214),
|
|
312
|
+
lossless: bool = False,
|
|
311
313
|
) -> Path | None:
|
|
312
314
|
if not items:
|
|
313
315
|
return None
|
|
@@ -320,12 +322,11 @@ def _write_comparison_matrix(
|
|
|
320
322
|
return None
|
|
321
323
|
|
|
322
324
|
by_cell = {(item["row_key"], item["col_key"]): item for item in items}
|
|
323
|
-
row_label_width = 210
|
|
324
|
-
col_width =
|
|
325
|
+
row_label_width = 260 if tile_size[0] >= 512 else 210
|
|
326
|
+
col_width = tile_size[0] + 12
|
|
325
327
|
title_height = 34
|
|
326
328
|
header_height = 66
|
|
327
|
-
row_height =
|
|
328
|
-
tile_size = (col_width - 12, row_height - 16)
|
|
329
|
+
row_height = tile_size[1] + 16
|
|
329
330
|
width = row_label_width + col_width * len(col_keys)
|
|
330
331
|
height = title_height + header_height + row_height * len(row_keys)
|
|
331
332
|
sheet = Image.new("RGB", (width, height), "white")
|
|
@@ -364,7 +365,7 @@ def _write_comparison_matrix(
|
|
|
364
365
|
x = row_label_width + col_index * col_width + 6
|
|
365
366
|
tile = _thumbnail(item["path"], size=tile_size)
|
|
366
367
|
sheet.paste(tile, (x, y + 8))
|
|
367
|
-
sheet.save(path)
|
|
368
|
+
sheet.save(path, lossless=lossless, method=6)
|
|
368
369
|
return path
|
|
369
370
|
|
|
370
371
|
|
|
@@ -408,6 +409,8 @@ def _write_report_comparison_matrices(
|
|
|
408
409
|
output_path,
|
|
409
410
|
items,
|
|
410
411
|
title=f"OrbitQuant {media} generation comparison matrix",
|
|
412
|
+
tile_size=(1024, 1024) if media == "image" else (208, 214),
|
|
413
|
+
lossless=media == "image",
|
|
411
414
|
)
|
|
412
415
|
if result is not None:
|
|
413
416
|
created[media] = result
|
|
@@ -143,7 +143,7 @@ def test_save_orbitquant_artifact_writes_manifest_readme_weights_and_checksums(t
|
|
|
143
143
|
codebook_tensors = load_file(tmp_path / "orbitquant_codebooks.safetensors")
|
|
144
144
|
rotation_tensors = load_file(tmp_path / "orbitquant_rotations.safetensors")
|
|
145
145
|
assert any(name.endswith("packed_weight_indices") for name in tensors)
|
|
146
|
-
assert prompts["prompt_pack"] == "
|
|
146
|
+
assert prompts["prompt_pack"] == "image_visual_v2"
|
|
147
147
|
assert prompts["media_type"] == "image"
|
|
148
148
|
assert len(prompts["prompts"]) >= 10
|
|
149
149
|
assert {item["id"] for item in prompts["prompts"]} >= {
|
|
@@ -159,6 +159,8 @@ def test_save_orbitquant_artifact_writes_manifest_readme_weights_and_checksums(t
|
|
|
159
159
|
"occlusion-reflection",
|
|
160
160
|
}
|
|
161
161
|
assert any("КВАНТОВАНИЕ" in item["prompt"] for item in prompts["prompts"])
|
|
162
|
+
assert any("量子の軌道" in item["prompt"] for item in prompts["prompts"])
|
|
163
|
+
assert any("量子轨道" in item["prompt"] for item in prompts["prompts"])
|
|
162
164
|
assert benchmark_summary["status"] == "not_run"
|
|
163
165
|
assert benchmark_summary["source_model_id"] == "example/model"
|
|
164
166
|
assert benchmark_summary["codebook_version"] == 2
|
|
@@ -14,6 +14,7 @@ from orbitquant.artifacts.checksums import write_sha256sums_from_manifest
|
|
|
14
14
|
from orbitquant.cli.main import main
|
|
15
15
|
from orbitquant.config import OrbitQuantConfig
|
|
16
16
|
from orbitquant.eval import get_native_suite
|
|
17
|
+
from orbitquant.eval.prompts import default_prompt_payload, select_prompt_record
|
|
17
18
|
from orbitquant.modeling import quantize_linear_modules
|
|
18
19
|
|
|
19
20
|
|
|
@@ -1566,10 +1567,10 @@ def test_cli_generate_dry_run_selects_prompt_from_artifact_pack(capsys, tmp_path
|
|
|
1566
1567
|
|
|
1567
1568
|
output = json.loads(capsys.readouterr().out)
|
|
1568
1569
|
assert output["prompt_record"]["id"] == "english-text-rendering"
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1570
|
+
expected_prompt = select_prompt_record(
|
|
1571
|
+
default_prompt_payload("flux2"), prompt_id="english-text-rendering"
|
|
1572
|
+
)["prompt"]
|
|
1573
|
+
assert output["pipeline_kwargs"]["prompt"] == expected_prompt
|
|
1573
1574
|
|
|
1574
1575
|
|
|
1575
1576
|
def test_cli_generate_with_artifact_loads_component_and_records_metrics(
|
|
@@ -2614,10 +2615,9 @@ def test_cli_generate_pack_resume_existing_skips_completed_outputs(
|
|
|
2614
2615
|
{
|
|
2615
2616
|
"suite": "flux2-native",
|
|
2616
2617
|
"model_id": "example/artifact-model",
|
|
2617
|
-
"prompt": (
|
|
2618
|
-
"
|
|
2619
|
-
|
|
2620
|
-
),
|
|
2618
|
+
"prompt": select_prompt_record(
|
|
2619
|
+
default_prompt_payload("flux2"), prompt_id="simple-object"
|
|
2620
|
+
)["prompt"],
|
|
2621
2621
|
"seed": 3,
|
|
2622
2622
|
"height": 1024,
|
|
2623
2623
|
"width": 1024,
|
|
@@ -10,7 +10,7 @@ from orbitquant.eval.prompts import (
|
|
|
10
10
|
def test_default_prompt_payload_uses_image_visual_pack_for_image_policies():
|
|
11
11
|
payload = default_prompt_payload("flux2")
|
|
12
12
|
|
|
13
|
-
assert payload["prompt_pack"] == "
|
|
13
|
+
assert payload["prompt_pack"] == "image_visual_v2"
|
|
14
14
|
assert payload["media_type"] == "image"
|
|
15
15
|
assert len(payload["prompts"]) >= 10
|
|
16
16
|
assert {item["id"] for item in payload["prompts"]} >= {
|
|
@@ -25,6 +25,12 @@ def test_default_prompt_payload_uses_image_visual_pack_for_image_policies():
|
|
|
25
25
|
"style-heavy",
|
|
26
26
|
"occlusion-reflection",
|
|
27
27
|
}
|
|
28
|
+
assert all(item.get("title") for item in payload["prompts"])
|
|
29
|
+
assert min(len(item["prompt"]) for item in payload["prompts"]) >= 350
|
|
30
|
+
prompts = "\n".join(item["prompt"] for item in payload["prompts"])
|
|
31
|
+
assert "КВАНТОВАЯ ОРБИТА" in prompts
|
|
32
|
+
assert "量子の軌道" in prompts
|
|
33
|
+
assert "量子轨道" in prompts
|
|
28
34
|
|
|
29
35
|
|
|
30
36
|
def test_default_prompt_payload_uses_video_visual_pack_for_wan_policy():
|
|
@@ -86,6 +86,10 @@ def test_generate_native_eval_report_writes_markdown_and_tables(tmp_path):
|
|
|
86
86
|
assert (report_dir / "tables" / "assets.csv").is_file()
|
|
87
87
|
assert (report_dir / "tables" / "missing_required_metrics.csv").is_file()
|
|
88
88
|
assert (report_dir / "assets" / "image_generation_comparison_matrix.webp").is_file()
|
|
89
|
+
with Image.open(
|
|
90
|
+
report_dir / "assets" / "image_generation_comparison_matrix.webp"
|
|
91
|
+
) as matrix:
|
|
92
|
+
assert matrix.size == (2332, 1140)
|
|
89
93
|
|
|
90
94
|
report = result.report_path.read_text()
|
|
91
95
|
image_table = (report_dir / "tables" / "image_geneval.csv").read_text()
|
|
@@ -192,7 +192,7 @@ def test_model_card_renders_imported_vbench_release_metrics():
|
|
|
192
192
|
def test_model_card_contains_install_command_not_workflow_log_language():
|
|
193
193
|
card = render_model_card(_manifest_for_model("black-forest-labs/FLUX.1-schnell"))
|
|
194
194
|
|
|
195
|
-
assert 'pip install "orbitquant[hf]"' in card
|
|
195
|
+
assert 'pip install "orbitquant[hf,kernels]>=0.2.0"' in card
|
|
196
196
|
assert "git+https://github.com/iamwavecut/OrbitQuant.git" not in card
|
|
197
197
|
for forbidden in (
|
|
198
198
|
"reports/",
|
|
@@ -206,6 +206,41 @@ def test_model_card_contains_install_command_not_workflow_log_language():
|
|
|
206
206
|
assert forbidden not in card
|
|
207
207
|
|
|
208
208
|
|
|
209
|
+
def test_model_card_lists_all_ten_complex_comparison_prompts_only_with_complete_proof():
|
|
210
|
+
manifest = _manifest_for_model("black-forest-labs/FLUX.1-schnell")
|
|
211
|
+
prompt_ids = [
|
|
212
|
+
"simple-object",
|
|
213
|
+
"two-object-composition",
|
|
214
|
+
"counting",
|
|
215
|
+
"color-binding",
|
|
216
|
+
"spatial-relationship",
|
|
217
|
+
"long-prompt",
|
|
218
|
+
"english-text-rendering",
|
|
219
|
+
"cyrillic-text-rendering",
|
|
220
|
+
"style-heavy",
|
|
221
|
+
"occlusion-reflection",
|
|
222
|
+
]
|
|
223
|
+
benchmark_summary = {
|
|
224
|
+
"native_smoke": {
|
|
225
|
+
"paired_prompt_seed_count": 10,
|
|
226
|
+
"paired_prompt_seed_keys": [
|
|
227
|
+
["flux1-schnell-native", "0", prompt_id] for prompt_id in prompt_ids
|
|
228
|
+
],
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
card = render_model_card(manifest, benchmark_summary=benchmark_summary)
|
|
233
|
+
|
|
234
|
+
assert "## Comparison Prompt Set" in card
|
|
235
|
+
assert "`image_visual_v2`" in card
|
|
236
|
+
assert "01 Fine-detail astrolabe" in card
|
|
237
|
+
assert "10 Chinese typography, reflection, occlusion" in card
|
|
238
|
+
assert "КВАНТОВАЯ ОРБИТА; МОСКВА 2049; КВАНТОВАНИЕ" in card
|
|
239
|
+
assert "量子の軌道; 東京の未来" in card
|
|
240
|
+
assert "量子轨道; 未来之城" in card
|
|
241
|
+
assert "<summary>Exact comparison prompts</summary>" in card
|
|
242
|
+
|
|
243
|
+
|
|
209
244
|
def test_model_card_embeds_only_promoted_comparison_matrix_assets():
|
|
210
245
|
card = render_model_card(_manifest_for_model("black-forest-labs/FLUX.1-schnell"))
|
|
211
246
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{orbitquant-0.2.0 → orbitquant-0.2.1}/native-kernels/orbitquant-packed-matmul/tests/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|