prismaquant 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.
Files changed (223) hide show
  1. prismaquant-0.2.0/LICENSE +17 -0
  2. prismaquant-0.2.0/PKG-INFO +249 -0
  3. prismaquant-0.2.0/README.md +212 -0
  4. prismaquant-0.2.0/prismaquant/__init__.py +169 -0
  5. prismaquant-0.2.0/prismaquant/_fast_kernel_guard.py +92 -0
  6. prismaquant-0.2.0/prismaquant/activation_sampling.py +64 -0
  7. prismaquant-0.2.0/prismaquant/allocator.py +2756 -0
  8. prismaquant-0.2.0/prismaquant/allocator_candidates.py +1424 -0
  9. prismaquant-0.2.0/prismaquant/allocator_solver.py +670 -0
  10. prismaquant-0.2.0/prismaquant/artifact_registry.py +254 -0
  11. prismaquant-0.2.0/prismaquant/aura_additivity_gate.py +138 -0
  12. prismaquant-0.2.0/prismaquant/aura_cost.py +944 -0
  13. prismaquant-0.2.0/prismaquant/autoscale.py +487 -0
  14. prismaquant-0.2.0/prismaquant/block_output_match.py +269 -0
  15. prismaquant-0.2.0/prismaquant/build_production_cache.py +776 -0
  16. prismaquant-0.2.0/prismaquant/build_rtn_cache.py +598 -0
  17. prismaquant-0.2.0/prismaquant/calibration_data.py +102 -0
  18. prismaquant-0.2.0/prismaquant/collapse_config_groups.py +83 -0
  19. prismaquant-0.2.0/prismaquant/cross_layer_residual.py +360 -0
  20. prismaquant-0.2.0/prismaquant/decision_units.py +446 -0
  21. prismaquant-0.2.0/prismaquant/expert_empirical_cost.py +411 -0
  22. prismaquant-0.2.0/prismaquant/export_batched_gptq.py +539 -0
  23. prismaquant-0.2.0/prismaquant/export_gguf.py +512 -0
  24. prismaquant-0.2.0/prismaquant/export_gguf_direct.py +398 -0
  25. prismaquant-0.2.0/prismaquant/export_native_compressed.py +8395 -0
  26. prismaquant-0.2.0/prismaquant/footprint.py +705 -0
  27. prismaquant-0.2.0/prismaquant/format_registry.py +969 -0
  28. prismaquant-0.2.0/prismaquant/fp8_dynamic.py +119 -0
  29. prismaquant-0.2.0/prismaquant/gguf_formats.py +586 -0
  30. prismaquant-0.2.0/prismaquant/gguf_gptq.py +144 -0
  31. prismaquant-0.2.0/prismaquant/gguf_iq_formats.py +579 -0
  32. prismaquant-0.2.0/prismaquant/gpu_guard.py +15 -0
  33. prismaquant-0.2.0/prismaquant/incremental_measure_quant_cost.py +1259 -0
  34. prismaquant-0.2.0/prismaquant/incremental_probe.py +3659 -0
  35. prismaquant-0.2.0/prismaquant/incremental_shards.py +22 -0
  36. prismaquant-0.2.0/prismaquant/kernels/nvfp4_fused.py +393 -0
  37. prismaquant-0.2.0/prismaquant/kl_fisher.py +135 -0
  38. prismaquant-0.2.0/prismaquant/kl_measurement.py +5612 -0
  39. prismaquant-0.2.0/prismaquant/kl_sensitivity_probe.py +3711 -0
  40. prismaquant-0.2.0/prismaquant/layer_config.py +117 -0
  41. prismaquant-0.2.0/prismaquant/layer_state_cache.py +602 -0
  42. prismaquant-0.2.0/prismaquant/layer_streaming.py +1899 -0
  43. prismaquant-0.2.0/prismaquant/measure_quant_cost.py +1885 -0
  44. prismaquant-0.2.0/prismaquant/memory_management.py +392 -0
  45. prismaquant-0.2.0/prismaquant/model_profiles/__init__.py +64 -0
  46. prismaquant-0.2.0/prismaquant/model_profiles/base.py +1013 -0
  47. prismaquant-0.2.0/prismaquant/model_profiles/deepseek_v4.py +306 -0
  48. prismaquant-0.2.0/prismaquant/model_profiles/default.py +79 -0
  49. prismaquant-0.2.0/prismaquant/model_profiles/gemma4.py +136 -0
  50. prismaquant-0.2.0/prismaquant/model_profiles/hy_v3.py +105 -0
  51. prismaquant-0.2.0/prismaquant/model_profiles/lfm2_moe.py +172 -0
  52. prismaquant-0.2.0/prismaquant/model_profiles/minimax_m2.py +153 -0
  53. prismaquant-0.2.0/prismaquant/model_profiles/qwen3.py +50 -0
  54. prismaquant-0.2.0/prismaquant/model_profiles/qwen3_5.py +139 -0
  55. prismaquant-0.2.0/prismaquant/model_profiles/qwen3_5_dense.py +106 -0
  56. prismaquant-0.2.0/prismaquant/model_profiles/qwen3_moe.py +34 -0
  57. prismaquant-0.2.0/prismaquant/model_profiles/registry.py +165 -0
  58. prismaquant-0.2.0/prismaquant/model_profiles/specs/deepseek_v4.json +94 -0
  59. prismaquant-0.2.0/prismaquant/model_profiles/specs/gemma4.json +144 -0
  60. prismaquant-0.2.0/prismaquant/model_profiles/specs/hy_v3.json +68 -0
  61. prismaquant-0.2.0/prismaquant/model_profiles/specs/lfm2_moe.json +71 -0
  62. prismaquant-0.2.0/prismaquant/model_profiles/specs/qwen3.json +25 -0
  63. prismaquant-0.2.0/prismaquant/model_profiles/specs/qwen3_5.json +140 -0
  64. prismaquant-0.2.0/prismaquant/model_profiles/specs/qwen3_5_dense.json +116 -0
  65. prismaquant-0.2.0/prismaquant/model_profiles/specs/qwen3_moe.json +40 -0
  66. prismaquant-0.2.0/prismaquant/model_profiles/structure.py +630 -0
  67. prismaquant-0.2.0/prismaquant/model_profiles/validate.py +429 -0
  68. prismaquant-0.2.0/prismaquant/model_profiles/vllm_registry.py +195 -0
  69. prismaquant-0.2.0/prismaquant/mse_promotion.py +633 -0
  70. prismaquant-0.2.0/prismaquant/mtp_module.py +214 -0
  71. prismaquant-0.2.0/prismaquant/mx_formats.py +122 -0
  72. prismaquant-0.2.0/prismaquant/observers/__init__.py +7 -0
  73. prismaquant-0.2.0/prismaquant/perturbed_x_cache.py +1347 -0
  74. prismaquant-0.2.0/prismaquant/pipeline.py +1178 -0
  75. prismaquant-0.2.0/prismaquant/production_recache.py +591 -0
  76. prismaquant-0.2.0/prismaquant/production_render_cost.py +545 -0
  77. prismaquant-0.2.0/prismaquant/production_weight_cache.py +3656 -0
  78. prismaquant-0.2.0/prismaquant/propagated_sensitivity_costs.py +293 -0
  79. prismaquant-0.2.0/prismaquant/render_score.py +379 -0
  80. prismaquant-0.2.0/prismaquant/run-pipeline.sh +1411 -0
  81. prismaquant-0.2.0/prismaquant/runtime_shape_validators.py +52 -0
  82. prismaquant-0.2.0/prismaquant/saturation_select.py +253 -0
  83. prismaquant-0.2.0/prismaquant/schemas.py +232 -0
  84. prismaquant-0.2.0/prismaquant/select_validated_frontier.py +729 -0
  85. prismaquant-0.2.0/prismaquant/sensitivity_coverage.py +108 -0
  86. prismaquant-0.2.0/prismaquant/sensitivity_probe.py +3015 -0
  87. prismaquant-0.2.0/prismaquant/sensitivity_response.py +416 -0
  88. prismaquant-0.2.0/prismaquant/serving_profile_specs/gguf.json +39 -0
  89. prismaquant-0.2.0/prismaquant/serving_profile_specs/research.json +34 -0
  90. prismaquant-0.2.0/prismaquant/serving_profile_specs/vllm_packed_moe.json +47 -0
  91. prismaquant-0.2.0/prismaquant/serving_profile_specs/vllm_qwen3_5_packed_moe.json +7 -0
  92. prismaquant-0.2.0/prismaquant/serving_profiles.py +757 -0
  93. prismaquant-0.2.0/prismaquant/source_prefetch.py +225 -0
  94. prismaquant-0.2.0/prismaquant/streaming_model.py +977 -0
  95. prismaquant-0.2.0/prismaquant/streaming_production_cache.py +545 -0
  96. prismaquant-0.2.0/prismaquant/validate_assignments_kl.py +1418 -0
  97. prismaquant-0.2.0/prismaquant/validate_native_export.py +190 -0
  98. prismaquant-0.2.0/prismaquant/validate_quantized_model.py +555 -0
  99. prismaquant-0.2.0/prismaquant/validation_harness.py +1019 -0
  100. prismaquant-0.2.0/prismaquant/vendored/__init__.py +112 -0
  101. prismaquant-0.2.0/prismaquant/vendored/dsv4_probe_experts.py +120 -0
  102. prismaquant-0.2.0/prismaquant/vendored/transformers_deepseek_v4/__init__.py +27 -0
  103. prismaquant-0.2.0/prismaquant/vendored/transformers_deepseek_v4/configuration_deepseek_v4.py +204 -0
  104. prismaquant-0.2.0/prismaquant/vendored/transformers_deepseek_v4/modeling_deepseek_v4.py +1353 -0
  105. prismaquant-0.2.0/prismaquant/vendored/transformers_deepseek_v4/modular_deepseek_v4.py +1238 -0
  106. prismaquant-0.2.0/prismaquant/vendored/transformers_qwen3/__init__.py +21 -0
  107. prismaquant-0.2.0/prismaquant/vendored/transformers_qwen3/modeling_qwen3.py +579 -0
  108. prismaquant-0.2.0/prismaquant/weight_session.py +517 -0
  109. prismaquant-0.2.0/prismaquant.egg-info/PKG-INFO +249 -0
  110. prismaquant-0.2.0/prismaquant.egg-info/SOURCES.txt +221 -0
  111. prismaquant-0.2.0/prismaquant.egg-info/dependency_links.txt +1 -0
  112. prismaquant-0.2.0/prismaquant.egg-info/requires.txt +18 -0
  113. prismaquant-0.2.0/prismaquant.egg-info/top_level.txt +1 -0
  114. prismaquant-0.2.0/pyproject.toml +59 -0
  115. prismaquant-0.2.0/setup.cfg +4 -0
  116. prismaquant-0.2.0/tests/test_allocator_byte_budget_selection.py +420 -0
  117. prismaquant-0.2.0/tests/test_allocator_kneedle.py +314 -0
  118. prismaquant-0.2.0/tests/test_allocator_main_enforcement.py +88 -0
  119. prismaquant-0.2.0/tests/test_allocator_packed_group_units.py +751 -0
  120. prismaquant-0.2.0/tests/test_allocator_pareto_seed_export.py +203 -0
  121. prismaquant-0.2.0/tests/test_allocator_shape_mask.py +187 -0
  122. prismaquant-0.2.0/tests/test_allocator_sibling_aggregation.py +865 -0
  123. prismaquant-0.2.0/tests/test_allocator_solver_bins.py +147 -0
  124. prismaquant-0.2.0/tests/test_artifact_registry.py +111 -0
  125. prismaquant-0.2.0/tests/test_aura_cost.py +431 -0
  126. prismaquant-0.2.0/tests/test_aura_cost_auto_dtype.py +49 -0
  127. prismaquant-0.2.0/tests/test_autoscale_act_width.py +72 -0
  128. prismaquant-0.2.0/tests/test_autoscale_fp8_resident.py +152 -0
  129. prismaquant-0.2.0/tests/test_bit_attribution.py +134 -0
  130. prismaquant-0.2.0/tests/test_bit_exact_cost_pricing.py +510 -0
  131. prismaquant-0.2.0/tests/test_bitrate_select.py +171 -0
  132. prismaquant-0.2.0/tests/test_block_output_match.py +259 -0
  133. prismaquant-0.2.0/tests/test_build_rtn_cache.py +87 -0
  134. prismaquant-0.2.0/tests/test_build_sensitivity_ablation_assignments.py +108 -0
  135. prismaquant-0.2.0/tests/test_calibration_loader.py +35 -0
  136. prismaquant-0.2.0/tests/test_cost_surrogate_calibration_anchors.py +70 -0
  137. prismaquant-0.2.0/tests/test_cross_layer_residual.py +84 -0
  138. prismaquant-0.2.0/tests/test_decision_units.py +134 -0
  139. prismaquant-0.2.0/tests/test_deepseek_v4_profile.py +176 -0
  140. prismaquant-0.2.0/tests/test_diverse_calibration_builder.py +89 -0
  141. prismaquant-0.2.0/tests/test_docs_entrypoints.py +40 -0
  142. prismaquant-0.2.0/tests/test_docs_staleness.py +61 -0
  143. prismaquant-0.2.0/tests/test_dsv4_layer_streaming_rename.py +172 -0
  144. prismaquant-0.2.0/tests/test_expert_cost_subsample.py +112 -0
  145. prismaquant-0.2.0/tests/test_expert_empirical_cost.py +207 -0
  146. prismaquant-0.2.0/tests/test_export_batched_gptq.py +425 -0
  147. prismaquant-0.2.0/tests/test_export_cache_resume.py +182 -0
  148. prismaquant-0.2.0/tests/test_export_inline_expert_gptq.py +263 -0
  149. prismaquant-0.2.0/tests/test_fast_kernel_guard.py +66 -0
  150. prismaquant-0.2.0/tests/test_fisher_normalization.py +433 -0
  151. prismaquant-0.2.0/tests/test_footprint.py +629 -0
  152. prismaquant-0.2.0/tests/test_format_menu_expansion.py +183 -0
  153. prismaquant-0.2.0/tests/test_format_registry.py +312 -0
  154. prismaquant-0.2.0/tests/test_gemma4_rotary_init.py +78 -0
  155. prismaquant-0.2.0/tests/test_gguf_formats.py +207 -0
  156. prismaquant-0.2.0/tests/test_gguf_gptq.py +70 -0
  157. prismaquant-0.2.0/tests/test_gguf_iq_formats.py +230 -0
  158. prismaquant-0.2.0/tests/test_gpu_guard.py +19 -0
  159. prismaquant-0.2.0/tests/test_incomplete_fused_group.py +89 -0
  160. prismaquant-0.2.0/tests/test_incomplete_fused_ignore.py +36 -0
  161. prismaquant-0.2.0/tests/test_incremental_measure_quant_cost.py +379 -0
  162. prismaquant-0.2.0/tests/test_incremental_probe.py +125 -0
  163. prismaquant-0.2.0/tests/test_incremental_probe_kv_shared_guard.py +48 -0
  164. prismaquant-0.2.0/tests/test_incremental_shards.py +30 -0
  165. prismaquant-0.2.0/tests/test_jso_scale_levels.py +65 -0
  166. prismaquant-0.2.0/tests/test_kl_fisher.py +96 -0
  167. prismaquant-0.2.0/tests/test_kl_measurement_override_cache.py +64 -0
  168. prismaquant-0.2.0/tests/test_kl_measurement_teacher_pairing.py +141 -0
  169. prismaquant-0.2.0/tests/test_kl_sensitivity_probe.py +1047 -0
  170. prismaquant-0.2.0/tests/test_layer_config.py +127 -0
  171. prismaquant-0.2.0/tests/test_layer_state_cache.py +236 -0
  172. prismaquant-0.2.0/tests/test_layer_streaming.py +117 -0
  173. prismaquant-0.2.0/tests/test_layer_streaming_fp8.py +216 -0
  174. prismaquant-0.2.0/tests/test_layer_streaming_mxfp4.py +487 -0
  175. prismaquant-0.2.0/tests/test_m4_frontier_expert_selection.py +449 -0
  176. prismaquant-0.2.0/tests/test_measure_quant_cost_packed_experts.py +303 -0
  177. prismaquant-0.2.0/tests/test_measure_vllm_full_kl.py +119 -0
  178. prismaquant-0.2.0/tests/test_memory_management.py +348 -0
  179. prismaquant-0.2.0/tests/test_meta_init_fla_priming.py +87 -0
  180. prismaquant-0.2.0/tests/test_model_structure.py +582 -0
  181. prismaquant-0.2.0/tests/test_moe_expert_projection_names.py +104 -0
  182. prismaquant-0.2.0/tests/test_mse_promotion.py +564 -0
  183. prismaquant-0.2.0/tests/test_mtp_module_arch.py +132 -0
  184. prismaquant-0.2.0/tests/test_multilayer_rope_forward.py +167 -0
  185. prismaquant-0.2.0/tests/test_nvfp4_fused_kernel.py +160 -0
  186. prismaquant-0.2.0/tests/test_nvfp4_served_act_emulation.py +97 -0
  187. prismaquant-0.2.0/tests/test_packed_expert_cross_domain_gate.py +222 -0
  188. prismaquant-0.2.0/tests/test_packed_expert_per_token_fisher.py +470 -0
  189. prismaquant-0.2.0/tests/test_packed_experts_moe_interface_probe.py +73 -0
  190. prismaquant-0.2.0/tests/test_packed_probe_estimator_guard.py +46 -0
  191. prismaquant-0.2.0/tests/test_paper_claims.py +59 -0
  192. prismaquant-0.2.0/tests/test_per_expert_packing.py +175 -0
  193. prismaquant-0.2.0/tests/test_perturbed_x_cache.py +377 -0
  194. prismaquant-0.2.0/tests/test_pipeline_contracts.py +366 -0
  195. prismaquant-0.2.0/tests/test_prismaquant_export_native_compressed.py +3936 -0
  196. prismaquant-0.2.0/tests/test_prismaquant_native_math.py +532 -0
  197. prismaquant-0.2.0/tests/test_prismaquant_visual_format.py +278 -0
  198. prismaquant-0.2.0/tests/test_prismaquant_visual_phase2.py +610 -0
  199. prismaquant-0.2.0/tests/test_probe_shard_reuse.py +436 -0
  200. prismaquant-0.2.0/tests/test_production_render_cost.py +176 -0
  201. prismaquant-0.2.0/tests/test_production_weight_cache.py +1335 -0
  202. prismaquant-0.2.0/tests/test_profile_detection_and_calibration.py +76 -0
  203. prismaquant-0.2.0/tests/test_propagated_sensitivity_costs.py +209 -0
  204. prismaquant-0.2.0/tests/test_qwen_moe_profile.py +30 -0
  205. prismaquant-0.2.0/tests/test_render_score.py +103 -0
  206. prismaquant-0.2.0/tests/test_run_pipeline_defaults.py +88 -0
  207. prismaquant-0.2.0/tests/test_saturation_select.py +18 -0
  208. prismaquant-0.2.0/tests/test_schema_validation.py +102 -0
  209. prismaquant-0.2.0/tests/test_select_validated_frontier.py +498 -0
  210. prismaquant-0.2.0/tests/test_sensitivity_coverage.py +77 -0
  211. prismaquant-0.2.0/tests/test_sensitivity_response.py +99 -0
  212. prismaquant-0.2.0/tests/test_serving_profiles.py +483 -0
  213. prismaquant-0.2.0/tests/test_smoke_graph_memory_seed.py +38 -0
  214. prismaquant-0.2.0/tests/test_source_prefetch.py +51 -0
  215. prismaquant-0.2.0/tests/test_streaming_production_cache.py +466 -0
  216. prismaquant-0.2.0/tests/test_validate_assignments_kl.py +143 -0
  217. prismaquant-0.2.0/tests/test_validate_assignments_kl_bpp.py +109 -0
  218. prismaquant-0.2.0/tests/test_validate_native_export.py +32 -0
  219. prismaquant-0.2.0/tests/test_validate_quantized_model.py +382 -0
  220. prismaquant-0.2.0/tests/test_validated_frontier_holdout.py +64 -0
  221. prismaquant-0.2.0/tests/test_validation_harness.py +306 -0
  222. prismaquant-0.2.0/tests/test_vendored_qwen3.py +92 -0
  223. prismaquant-0.2.0/tests/test_weight_session.py +169 -0
@@ -0,0 +1,17 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Copyright 2026 Rob Tand.
@@ -0,0 +1,249 @@
1
+ Metadata-Version: 2.4
2
+ Name: prismaquant
3
+ Version: 0.2.0
4
+ Summary: Mixed-precision quantization allocator for LLMs: every layer refracts into a different format based on its sensitivity.
5
+ Author: Rob Tand
6
+ License: Apache-2.0
7
+ Project-URL: Repository, https://github.com/RobTand/prismaquant
8
+ Keywords: llm,quantization,nvfp4,mxfp8,fisher,moe,mtp,compressed-tensors,vllm
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Requires-Python: >=3.11
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: torch>=2.6
21
+ Requires-Dist: numpy>=1.26
22
+ Requires-Dist: safetensors>=0.4
23
+ Requires-Dist: transformers>=5.0
24
+ Requires-Dist: datasets>=3.0
25
+ Requires-Dist: accelerate>=0.30
26
+ Requires-Dist: compressed-tensors>=0.15
27
+ Requires-Dist: gguf>=0.17
28
+ Requires-Dist: pillow>=10.0
29
+ Requires-Dist: tqdm
30
+ Provides-Extra: serve
31
+ Requires-Dist: vllm>=0.19; extra == "serve"
32
+ Provides-Extra: test
33
+ Requires-Dist: pytest>=8; extra == "test"
34
+ Requires-Dist: pytest-cov>=5; extra == "test"
35
+ Requires-Dist: pytest-timeout>=2.3; extra == "test"
36
+ Dynamic: license-file
37
+
38
+ # PrismaQuant
39
+
40
+ **Mixed-precision LLM quantization that chooses the right format for every weight matrix, selected on real end-to-end KL — shipped as artifacts that stock inference engines serve with no forked runtime and no custom kernels.**
41
+
42
+ PrismaQuant's allocator is **AURA** (*Production-Faithful KL–Fisher Allocation*): a per-Linear cost model built from KL-Fisher probes of the full model multiplied against the *production-rendered* weight error — the exact bytes that ship — solved as a multi-choice knapsack, and gated by real KL measured on a held-out split before anything is published. Two output containers:
43
+
44
+ - **`compressed-tensors`** — vanilla vLLM serves it natively (`vllm serve $WORK_DIR/exported`). NVFP4 / FP8 / BF16 per Linear, CUTLASS kernels on Blackwell.
45
+ - **GGUF** — llama.cpp *and* vLLM (via the GGUF plugin) serve the same file. Full k-quant + IQ menu, per-tensor mixed, imatrix-weighted. This is how a 295B MoE fits on one 128 GB box.
46
+
47
+ ---
48
+
49
+ ## Headlines
50
+
51
+ All quality numbers below are **served-artifact measurements** (exact vLLM KL-vs-BF16 on held-out text, or deterministic benchmark runs on the served endpoint) — never local screens.
52
+
53
+ **Qwen3.6-27B PrismaAURA 5.5 bpp — tool-use fidelity above full precision.**
54
+
55
+ | Artifact | ToolEvalBench (hardmode, temp 0, same seed) |
56
+ |---|---:|
57
+ | **Qwen3.6-27B PrismaAURA 5.5 (23 GB)** | **91 / 100** |
58
+ | Qwen3.6-27B BF16 (full precision) | 86 / 100 |
59
+ | Qwen3.6-27B prior flagship (5.31 bpp) | 85 / 100 |
60
+
61
+ Served KL-vs-BF16 0.0342 — a −40.9% reduction over the prior AURA build at the same bpp, from adding the FP8 middle rung to the menu plus render/export fidelity fixes. [`rdtand/Qwen3.6-27B-PrismaAURA-5.5bit-vllm`](https://huggingface.co/rdtand/Qwen3.6-27B-PrismaAURA-5.5bit-vllm)
62
+
63
+ **Ornith-1.0-35B-A3B PrismaAURA 4.75 bpp — 70 GB → 23 GB, KL 0.0143.**
64
+
65
+ Served confident KL-vs-BF16 **0.0143** (top-1 agreement 98.6%), with a grafted MTP head for speculative decoding (91.3% acceptance at position 0). [`rdtand/Ornith-1.0-35B-PrismaAURA-4.75bit-vllm-MTP`](https://huggingface.co/rdtand/Ornith-1.0-35B-PrismaAURA-4.75bit-vllm-MTP)
66
+
67
+ **Qwen3.6-35B-A3B 4.75 bpp — wins 8 of 9 zero-shot metrics vs uniform NVFP4.**
68
+
69
+ Against RedHatAI's uniform NVFP4 quantization (342 hand-picked BF16 ignores), the measured allocation ships **2 GB smaller with ~90 fewer Linears in BF16** and lands ~4× closer to BF16 on mean zero-shot delta (−0.56 pp vs −2.21 pp). Uniform precision collapses the ~5% of genuinely sensitive Linears; measurement finds them. [`rdtand/Qwen3.6-35B-A3B-PrismaQuant-4.75bit-vllm`](https://huggingface.co/rdtand/Qwen3.6-35B-A3B-PrismaQuant-4.75bit-vllm)
70
+
71
+ **Tencent Hy3 295B-A21B → 103.7 GB GGUF — serves on a single DGX Spark.**
72
+
73
+ A 295B/21B-active MoE quantized from the BF16 source to 2.80 bpp by measured allocation over the GGUF k-quant + IQ menu (streaming probe — the model never fits in memory; byte-budget selection targets the box, not a curve heuristic). **No quality claims** — models at this scale can't be KL-validated against their BF16 teacher on the target hardware; validation is load + coherent-generation smokes and bit-exact packing. [`rdtand/Hy3-295B-A21B-PrismaQuant-2.8bit-gguf-vllm`](https://huggingface.co/rdtand/Hy3-295B-A21B-PrismaQuant-2.8bit-gguf-vllm), plus a [5.3-bit `compressed-tensors` variant with MTP for two Sparks](https://huggingface.co/rdtand/Hy3-295B-A21B-PrismaQuant-5.3bit-2xSpark-vllm).
74
+
75
+ The artifact family is at **~400k downloads** on Hugging Face ([`rdtand`](https://huggingface.co/rdtand)).
76
+
77
+ ---
78
+
79
+ ## Quick start
80
+
81
+ **compressed-tensors lane (vLLM):**
82
+
83
+ ```bash
84
+ export MODEL_PATH=/path/to/model
85
+ export WORK_DIR=./dq-runs/mymodel
86
+ export FORMATS=NVFP4,FP8_DYNAMIC,BF16 # the production menu — FP8 belongs in every recipe
87
+ export TARGET_BITS=4.75
88
+ export COST_MODE=aura # AURA cost (default: production-render-score)
89
+ export SELECTION_MODE=validated-surrogate # real-KL frontier selection (default: surrogate)
90
+
91
+ ./prismaquant/run-pipeline.sh
92
+ vllm serve $WORK_DIR/exported --quantization compressed-tensors
93
+ ```
94
+
95
+ **GGUF lane (llama.cpp + vLLM):**
96
+
97
+ ```bash
98
+ export EXPORT_CONTAINER=gguf TARGET_PROFILE=gguf COST_MODE=local
99
+ export PRODUCTION_CACHE=0 PRODUCTION_RECACHE=0
100
+ export FORMATS=IQ2_XS,IQ3_XXS,IQ4_XS,Q4_K,Q5_K,Q6_K,Q8_0
101
+ export TARGET_BITS=2.9
102
+
103
+ ./prismaquant/run-pipeline.sh
104
+ ```
105
+
106
+ Every stage is also runnable on its own; the allocator takes the same menu as a
107
+ flag, so a re-solve against existing probe/cost artifacts needs no re-measurement:
108
+
109
+ ```bash
110
+ python -m prismaquant.allocator --formats NVFP4,FP8_DYNAMIC,BF16 \
111
+ --probe $WORK_DIR/artifacts/probe.pkl \
112
+ --costs $WORK_DIR/artifacts/cost.pkl \
113
+ --layer-config $WORK_DIR/artifacts/layer_config.json \
114
+ --pareto-csv $WORK_DIR/artifacts/pareto.csv \
115
+ --target-bits 4.75
116
+ ```
117
+
118
+ The pipeline runs probe → cost → allocator → export → serve-smoke end-to-end, with fail-fast gates on any configuration that would break the measurement contract (it will tell you exactly why and what to set). Models too large for memory (200B+ MoE) run the streaming layer-by-layer path — peak memory is bounded by ~1 layer + a tunable cache.
119
+
120
+ ---
121
+
122
+ ## How AURA works
123
+
124
+ Mixed-precision quantization splits into two orthogonal questions:
125
+
126
+ - **Local (well-studied):** given a fixed format, how do you round this one Linear best? GPTQ, scale search, activation ordering — the per-tensor toolkit runs *under* whatever format is chosen.
127
+ - **Global (PrismaQuant's contribution):** how many bits should each Linear get, and in which hardware format? A per-Linear allocation of a total bit budget across the format menu.
128
+
129
+ AURA answers the global question with three commitments:
130
+
131
+ **1. A KL-faithful per-Linear cost.** The classical additive cost is `½ · H_trace · MSE_W` — a Fisher-diagonal trace times weight round-trip error. AURA replaces both halves: the sensitivity comes from KL-Fisher probes of the full model (the adjoint of the end-to-end KL objective, not a layer-local proxy), and the error term is measured on the **production-rendered** weights — GPTQ, joint scale optimization, activation ordering, the exact render that ships — not a raw round-trip. On served A/Bs at matched bpp this cost beats the strong `h_trace × output_mse` baseline by **−38% KL on a 4B model and −17.9% on 27B** (replicated across two calibration corpora).
132
+
133
+ **2. Production-faithfulness as an invariant.** The cost the allocator measures, the KL the validator measures, and the bytes the exporter ships all come from **one weight cache** — no rendering confound anywhere in the loop. On the GGUF lane the same contract holds through the imatrix: the calibration weighting used to measure a format's cost is byte-identical to the weighting used to pack it (enforced bit-exact against gguf-py, the llama.cpp reference decoder).
134
+
135
+ **3. Surrogates generate, real KL selects.** The additive surrogate is a candidate generator, never the ship decision. The allocator renders a Pareto sweep of candidates, each is measured with **real end-to-end KL on a held-out split** (disjoint from everything the cost stage saw), and the shipping point is picked on the measured `(bpp, KL)` frontier. Outside the surrogate's trust region, bpp order ≠ KL order: on the 27B, the surrogate's own knee picks 5.86 bpp / KL 0.056 while validated selection picks 5.31 bpp / KL 0.015 — smaller *and* 3.7× better, which is what end-to-end measurement buys over trusting the model of the cost.
136
+
137
+ **MoE hybrid.** Smooth per-Linear costs are structurally blind to router flips: quantizing a routed expert can change *which* experts fire, and no local error term sees that. AURA therefore allocates non-expert weights from the smooth cost and packed routed experts from **measured empirical unit-KL** (each expert-tier choice scored end-to-end), merged into one knapsack.
138
+
139
+ **What we measured and dropped.** The cross-layer-interaction literature (CLADO's pairwise IQP, HAWQ-V3's second-order ILP, cooperative-game formulations) models the coupling between Linears. We built the full L2 perturbed-activation cascade and ran the head-to-head on the served metric: cross-layer modeling bought **−1.5%**; AURA's better per-Linear cost bought **−38.5%** on the same A/B. Per-Linear cost fidelity was the lever; interaction modeling was not. That experiment — and the rest of the rejected-methods catalog (pairwise QUBO, Lagrangian λ-bisection as a selector, top-K Hessian covering, polish DPs that regress under the real-KL gate) — is documented in the paper. Negative results are recorded with their durable lesson; we don't re-litigate them silently.
140
+
141
+ Full derivations, the additivity/cancellation analysis, and the served evidence: [`paper/main.pdf`](paper/main.pdf).
142
+
143
+ ---
144
+
145
+ ## Pipeline
146
+
147
+ ```
148
+ incremental_probe ──────► probe.pkl (KL-Fisher sensitivity per Linear; streaming for 200B+)
149
+
150
+ cost stage ─────────────► cost.pkl (COST_MODE=aura: KL-Fisher × production-rendered dW;
151
+ │ MoE hybrid merges measured expert unit-KL)
152
+ allocator ──────────────► layer_config.json + Pareto candidates
153
+ │ (multi-choice knapsack; fused-sibling & packed-MoE
154
+ │ format coherence via union-find promotion)
155
+ validate_assignments_kl ► held-out real-KL per candidate
156
+ select_validated_frontier► the shipping point, picked on measured (bpp, KL)
157
+
158
+ export ─────────────────► exported/ (compressed-tensors OR GGUF via export_gguf)
159
+
160
+ validate_native_export ─► engine load + greedy-decode smoke (eager and graph mode)
161
+ validate_quantized_model► PPL / p99 per-prompt NLL / MTP-acceptance ship gate
162
+ ```
163
+
164
+ Every hot path is GPU-bound by design; the pipeline refuses to run on CPU.
165
+
166
+ ---
167
+
168
+ ## Formats
169
+
170
+ **compressed-tensors container (vLLM-native):**
171
+
172
+ | Format | Role |
173
+ |---|---|
174
+ | NVFP4 | W4A4, group-16 FP8 block scales; CUTLASS on Blackwell — the 4-bit workhorse |
175
+ | FP8_DYNAMIC / FP8_E4M3 | the 8-bit rung — on the menu in every production recipe; it's what bends the rate-distortion curve into a knee |
176
+ | BF16 | passthrough only (never synthesized from a quantized source) |
177
+ | FP8_SOURCE | byte-exact passthrough of natively-FP8 checkpoints (lossless at ~8 bpp) |
178
+ | MXFP4/6/8, INT4/INT8, NVFP4A16 | registry-supported research rungs, excluded from defaults where a served kernel or a Pareto case is missing |
179
+
180
+ **GGUF container (llama.cpp + vLLM GGUF plugin):**
181
+
182
+ | Format | bpw |
183
+ |---|---|
184
+ | Q2_K / Q3_K / Q4_K / Q5_K / Q6_K / Q8_0 | 2.625 / 3.44 / 4.5 / 5.5 / 6.56 / 8.5 |
185
+ | IQ2_XXS / IQ2_XS / IQ2_S / IQ3_XXS / IQ3_S / IQ4_XS / IQ4_NL | 2.06 – 4.5 (E8-lattice codebooks; the sub-Q2_K regime) |
186
+
187
+ GGUF quantizers are PrismaQuant's own GPU implementations (imatrix-weighted grid/least-squares search, exhaustive codeword search for IQ), validated bit-exact against gguf-py. GPTQ-under-frozen-scales is available for the k-quants as a research lever. The allocator is serving-profile-aware in both containers: it never picks a format the target engine can't serve at that tensor's shape.
188
+
189
+ ---
190
+
191
+ ## Architectures
192
+
193
+ First-class profiles in-tree:
194
+
195
+ - **Qwen3 / 3.5 / 3.6** — dense + packed-3D MoE + MTP heads, Gated-DeltaNet hybrids
196
+ - **Tencent Hy3** (`hy_v3`) — 295B/21B-active, 192-expert MoE + MTP sidecar
197
+ - **DeepSeek-V4-Flash** (vendored transformer + profile) — 671B-class, per-expert-Linear MoE
198
+ - **MiniMax M2 / M2.7** — nested per-expert MoE, native-FP8 source
199
+ - **Gemma4** — multi-layer-type rope, KV sharing, visual/text profiles
200
+ - **LFM2.5** — per-expert MoE + short-conv layers
201
+
202
+ A new architecture is a `model_profiles/` registration (structure spec JSON + a small profile class); most of the fused-group and naming plumbing is auto-derived from the vLLM model class, so ports land in ~30–200 LoC.
203
+
204
+ ---
205
+
206
+ ## Published artifacts
207
+
208
+ | Model | Artifact |
209
+ |---|---|
210
+ | Qwen3.6-27B | [PrismaAURA 5.5 bpp](https://huggingface.co/rdtand/Qwen3.6-27B-PrismaAURA-5.5bit-vllm) · [5.31 bpp prior flagship](https://huggingface.co/rdtand/Qwen3.6-27B-PrismaSCOUT-Blackwell-NVFP4-BF16-vllm) (DOI 10.57967/hf/8656) · [v1 5.5 bpp](https://huggingface.co/rdtand/Qwen3.6-27B-PrismaQuant-5.5bit-vllm) |
211
+ | Qwen3.6-35B-A3B | [4.75 bpp](https://huggingface.co/rdtand/Qwen3.6-35B-A3B-PrismaQuant-4.75bit-vllm) |
212
+ | Ornith-1.0-35B | [PrismaAURA 4.75 bpp + MTP](https://huggingface.co/rdtand/Ornith-1.0-35B-PrismaAURA-4.75bit-vllm-MTP) |
213
+ | Tencent Hy3 295B-A21B | [2.8 bpp GGUF, single Spark](https://huggingface.co/rdtand/Hy3-295B-A21B-PrismaQuant-2.8bit-gguf-vllm) · [5.3 bpp CT + MTP, 2× Spark](https://huggingface.co/rdtand/Hy3-295B-A21B-PrismaQuant-5.3bit-2xSpark-vllm) |
214
+ | Qwen3.5-122B-A10B | [4.75 bpp](https://huggingface.co/rdtand/Qwen3.5-122B-A10B-PrismaQuant-4.75bit-vllm) |
215
+ | Mistral-Medium-3.5-128B | [4.75 bpp](https://huggingface.co/rdtand/Mistral-Medium-3.5-128B-PrismaQuant-4.75-vllm) |
216
+ | MiniMax-M2.7 | [3.20 bpp](https://huggingface.co/rdtand/MiniMax-M2.7-PrismaQuant-3.20bit-vllm) |
217
+ | Gemma4-31B-IT | [6 bpp](https://huggingface.co/rdtand/Gemma4-31B-IT-PrismaQuant-6bit-vllm) · [5.5 bpp](https://huggingface.co/rdtand/Gemma4-31B-IT-PrismaQuant-5.5bit-vllm) |
218
+ | LFM2.5-8B-A1B | [6.5 bpp](https://huggingface.co/rdtand/LFM2.5-8B-A1B-PrismaQuant-6.5bit-vllm) |
219
+
220
+ ---
221
+
222
+ ## Method discipline
223
+
224
+ The rules this project holds itself to, because low-bit quantization results are unusually easy to overstate:
225
+
226
+ - **Promote on the serving metric, not the screen.** A win counts only when it holds on exact full-vocab vLLM KL-vs-BF16 and direct perplexity *on the served artifact* at matched bpp. We have watched local-PPL "wins" invert on the served A/B more than once; those methods are archived with the lesson, not quietly dropped.
227
+ - **KL screens, it doesn't ship alone.** Lower mean KL can hide a heavier tail; candidates also clear direct PPL, p99 per-prompt NLL, and tool-use benchmarks before publication.
228
+ - **Held-out means held-out.** Selection KL uses text the cost stage never saw.
229
+ - **No hand-tuned bans.** If the allocator picks something that breaks, the cost model is wrong — fix the measurement, don't constrain the optimizer. The only constants allowed are ones derived from a dtype's numerical precision.
230
+ - **No quality claims we can't back.** The 295B artifact ships with an explicit "no quality claims" section because its teacher can't be measured on the target hardware. Provenance (git commit, calibration hash, assignment hash) is baked into every artifact's metadata.
231
+
232
+ ---
233
+
234
+ ## Citation
235
+
236
+ ```bibtex
237
+ @software{prismaquant2026,
238
+ title = {PrismaQuant: Mixed-Precision LLM Quantization Selected on Real End-to-End KL},
239
+ author = {Tand, Robert},
240
+ year = {2026},
241
+ url = {https://github.com/RobTand/prismaquant},
242
+ }
243
+ ```
244
+
245
+ The AURA paper (*AURA: Production-Faithful KL–Fisher Allocation*) is at [`paper/main.pdf`](paper/main.pdf) (source: [`paper/main.tex`](paper/main.tex)). Contact: robert.tand@icloud.com.
246
+
247
+ ## Acknowledgements
248
+
249
+ PrismaQuant is assembled on top of a decade of quantization research. Key influences: CLADO (Deng et al. 2023) for the cross-layer decision-unit framing (whose interaction-modeling half our head-to-head then retired); HAWQ-V1–V3 (Dong et al. 2019–2021), CoopQ, and AMQ on mixed-precision allocation; GPTQ (Frantar et al. 2022) and its Babai-nearest-plane interpretation (Chen et al. 2026) for rounding; the llama.cpp/ggml project for the GGUF formats and reference implementations; Kneedle (Satopää et al. 2011); and Cover & Thomas ch. 13 on rate-distortion bit allocation. Full bibliography in [`paper/main.tex`](paper/main.tex).
@@ -0,0 +1,212 @@
1
+ # PrismaQuant
2
+
3
+ **Mixed-precision LLM quantization that chooses the right format for every weight matrix, selected on real end-to-end KL — shipped as artifacts that stock inference engines serve with no forked runtime and no custom kernels.**
4
+
5
+ PrismaQuant's allocator is **AURA** (*Production-Faithful KL–Fisher Allocation*): a per-Linear cost model built from KL-Fisher probes of the full model multiplied against the *production-rendered* weight error — the exact bytes that ship — solved as a multi-choice knapsack, and gated by real KL measured on a held-out split before anything is published. Two output containers:
6
+
7
+ - **`compressed-tensors`** — vanilla vLLM serves it natively (`vllm serve $WORK_DIR/exported`). NVFP4 / FP8 / BF16 per Linear, CUTLASS kernels on Blackwell.
8
+ - **GGUF** — llama.cpp *and* vLLM (via the GGUF plugin) serve the same file. Full k-quant + IQ menu, per-tensor mixed, imatrix-weighted. This is how a 295B MoE fits on one 128 GB box.
9
+
10
+ ---
11
+
12
+ ## Headlines
13
+
14
+ All quality numbers below are **served-artifact measurements** (exact vLLM KL-vs-BF16 on held-out text, or deterministic benchmark runs on the served endpoint) — never local screens.
15
+
16
+ **Qwen3.6-27B PrismaAURA 5.5 bpp — tool-use fidelity above full precision.**
17
+
18
+ | Artifact | ToolEvalBench (hardmode, temp 0, same seed) |
19
+ |---|---:|
20
+ | **Qwen3.6-27B PrismaAURA 5.5 (23 GB)** | **91 / 100** |
21
+ | Qwen3.6-27B BF16 (full precision) | 86 / 100 |
22
+ | Qwen3.6-27B prior flagship (5.31 bpp) | 85 / 100 |
23
+
24
+ Served KL-vs-BF16 0.0342 — a −40.9% reduction over the prior AURA build at the same bpp, from adding the FP8 middle rung to the menu plus render/export fidelity fixes. [`rdtand/Qwen3.6-27B-PrismaAURA-5.5bit-vllm`](https://huggingface.co/rdtand/Qwen3.6-27B-PrismaAURA-5.5bit-vllm)
25
+
26
+ **Ornith-1.0-35B-A3B PrismaAURA 4.75 bpp — 70 GB → 23 GB, KL 0.0143.**
27
+
28
+ Served confident KL-vs-BF16 **0.0143** (top-1 agreement 98.6%), with a grafted MTP head for speculative decoding (91.3% acceptance at position 0). [`rdtand/Ornith-1.0-35B-PrismaAURA-4.75bit-vllm-MTP`](https://huggingface.co/rdtand/Ornith-1.0-35B-PrismaAURA-4.75bit-vllm-MTP)
29
+
30
+ **Qwen3.6-35B-A3B 4.75 bpp — wins 8 of 9 zero-shot metrics vs uniform NVFP4.**
31
+
32
+ Against RedHatAI's uniform NVFP4 quantization (342 hand-picked BF16 ignores), the measured allocation ships **2 GB smaller with ~90 fewer Linears in BF16** and lands ~4× closer to BF16 on mean zero-shot delta (−0.56 pp vs −2.21 pp). Uniform precision collapses the ~5% of genuinely sensitive Linears; measurement finds them. [`rdtand/Qwen3.6-35B-A3B-PrismaQuant-4.75bit-vllm`](https://huggingface.co/rdtand/Qwen3.6-35B-A3B-PrismaQuant-4.75bit-vllm)
33
+
34
+ **Tencent Hy3 295B-A21B → 103.7 GB GGUF — serves on a single DGX Spark.**
35
+
36
+ A 295B/21B-active MoE quantized from the BF16 source to 2.80 bpp by measured allocation over the GGUF k-quant + IQ menu (streaming probe — the model never fits in memory; byte-budget selection targets the box, not a curve heuristic). **No quality claims** — models at this scale can't be KL-validated against their BF16 teacher on the target hardware; validation is load + coherent-generation smokes and bit-exact packing. [`rdtand/Hy3-295B-A21B-PrismaQuant-2.8bit-gguf-vllm`](https://huggingface.co/rdtand/Hy3-295B-A21B-PrismaQuant-2.8bit-gguf-vllm), plus a [5.3-bit `compressed-tensors` variant with MTP for two Sparks](https://huggingface.co/rdtand/Hy3-295B-A21B-PrismaQuant-5.3bit-2xSpark-vllm).
37
+
38
+ The artifact family is at **~400k downloads** on Hugging Face ([`rdtand`](https://huggingface.co/rdtand)).
39
+
40
+ ---
41
+
42
+ ## Quick start
43
+
44
+ **compressed-tensors lane (vLLM):**
45
+
46
+ ```bash
47
+ export MODEL_PATH=/path/to/model
48
+ export WORK_DIR=./dq-runs/mymodel
49
+ export FORMATS=NVFP4,FP8_DYNAMIC,BF16 # the production menu — FP8 belongs in every recipe
50
+ export TARGET_BITS=4.75
51
+ export COST_MODE=aura # AURA cost (default: production-render-score)
52
+ export SELECTION_MODE=validated-surrogate # real-KL frontier selection (default: surrogate)
53
+
54
+ ./prismaquant/run-pipeline.sh
55
+ vllm serve $WORK_DIR/exported --quantization compressed-tensors
56
+ ```
57
+
58
+ **GGUF lane (llama.cpp + vLLM):**
59
+
60
+ ```bash
61
+ export EXPORT_CONTAINER=gguf TARGET_PROFILE=gguf COST_MODE=local
62
+ export PRODUCTION_CACHE=0 PRODUCTION_RECACHE=0
63
+ export FORMATS=IQ2_XS,IQ3_XXS,IQ4_XS,Q4_K,Q5_K,Q6_K,Q8_0
64
+ export TARGET_BITS=2.9
65
+
66
+ ./prismaquant/run-pipeline.sh
67
+ ```
68
+
69
+ Every stage is also runnable on its own; the allocator takes the same menu as a
70
+ flag, so a re-solve against existing probe/cost artifacts needs no re-measurement:
71
+
72
+ ```bash
73
+ python -m prismaquant.allocator --formats NVFP4,FP8_DYNAMIC,BF16 \
74
+ --probe $WORK_DIR/artifacts/probe.pkl \
75
+ --costs $WORK_DIR/artifacts/cost.pkl \
76
+ --layer-config $WORK_DIR/artifacts/layer_config.json \
77
+ --pareto-csv $WORK_DIR/artifacts/pareto.csv \
78
+ --target-bits 4.75
79
+ ```
80
+
81
+ The pipeline runs probe → cost → allocator → export → serve-smoke end-to-end, with fail-fast gates on any configuration that would break the measurement contract (it will tell you exactly why and what to set). Models too large for memory (200B+ MoE) run the streaming layer-by-layer path — peak memory is bounded by ~1 layer + a tunable cache.
82
+
83
+ ---
84
+
85
+ ## How AURA works
86
+
87
+ Mixed-precision quantization splits into two orthogonal questions:
88
+
89
+ - **Local (well-studied):** given a fixed format, how do you round this one Linear best? GPTQ, scale search, activation ordering — the per-tensor toolkit runs *under* whatever format is chosen.
90
+ - **Global (PrismaQuant's contribution):** how many bits should each Linear get, and in which hardware format? A per-Linear allocation of a total bit budget across the format menu.
91
+
92
+ AURA answers the global question with three commitments:
93
+
94
+ **1. A KL-faithful per-Linear cost.** The classical additive cost is `½ · H_trace · MSE_W` — a Fisher-diagonal trace times weight round-trip error. AURA replaces both halves: the sensitivity comes from KL-Fisher probes of the full model (the adjoint of the end-to-end KL objective, not a layer-local proxy), and the error term is measured on the **production-rendered** weights — GPTQ, joint scale optimization, activation ordering, the exact render that ships — not a raw round-trip. On served A/Bs at matched bpp this cost beats the strong `h_trace × output_mse` baseline by **−38% KL on a 4B model and −17.9% on 27B** (replicated across two calibration corpora).
95
+
96
+ **2. Production-faithfulness as an invariant.** The cost the allocator measures, the KL the validator measures, and the bytes the exporter ships all come from **one weight cache** — no rendering confound anywhere in the loop. On the GGUF lane the same contract holds through the imatrix: the calibration weighting used to measure a format's cost is byte-identical to the weighting used to pack it (enforced bit-exact against gguf-py, the llama.cpp reference decoder).
97
+
98
+ **3. Surrogates generate, real KL selects.** The additive surrogate is a candidate generator, never the ship decision. The allocator renders a Pareto sweep of candidates, each is measured with **real end-to-end KL on a held-out split** (disjoint from everything the cost stage saw), and the shipping point is picked on the measured `(bpp, KL)` frontier. Outside the surrogate's trust region, bpp order ≠ KL order: on the 27B, the surrogate's own knee picks 5.86 bpp / KL 0.056 while validated selection picks 5.31 bpp / KL 0.015 — smaller *and* 3.7× better, which is what end-to-end measurement buys over trusting the model of the cost.
99
+
100
+ **MoE hybrid.** Smooth per-Linear costs are structurally blind to router flips: quantizing a routed expert can change *which* experts fire, and no local error term sees that. AURA therefore allocates non-expert weights from the smooth cost and packed routed experts from **measured empirical unit-KL** (each expert-tier choice scored end-to-end), merged into one knapsack.
101
+
102
+ **What we measured and dropped.** The cross-layer-interaction literature (CLADO's pairwise IQP, HAWQ-V3's second-order ILP, cooperative-game formulations) models the coupling between Linears. We built the full L2 perturbed-activation cascade and ran the head-to-head on the served metric: cross-layer modeling bought **−1.5%**; AURA's better per-Linear cost bought **−38.5%** on the same A/B. Per-Linear cost fidelity was the lever; interaction modeling was not. That experiment — and the rest of the rejected-methods catalog (pairwise QUBO, Lagrangian λ-bisection as a selector, top-K Hessian covering, polish DPs that regress under the real-KL gate) — is documented in the paper. Negative results are recorded with their durable lesson; we don't re-litigate them silently.
103
+
104
+ Full derivations, the additivity/cancellation analysis, and the served evidence: [`paper/main.pdf`](paper/main.pdf).
105
+
106
+ ---
107
+
108
+ ## Pipeline
109
+
110
+ ```
111
+ incremental_probe ──────► probe.pkl (KL-Fisher sensitivity per Linear; streaming for 200B+)
112
+
113
+ cost stage ─────────────► cost.pkl (COST_MODE=aura: KL-Fisher × production-rendered dW;
114
+ │ MoE hybrid merges measured expert unit-KL)
115
+ allocator ──────────────► layer_config.json + Pareto candidates
116
+ │ (multi-choice knapsack; fused-sibling & packed-MoE
117
+ │ format coherence via union-find promotion)
118
+ validate_assignments_kl ► held-out real-KL per candidate
119
+ select_validated_frontier► the shipping point, picked on measured (bpp, KL)
120
+
121
+ export ─────────────────► exported/ (compressed-tensors OR GGUF via export_gguf)
122
+
123
+ validate_native_export ─► engine load + greedy-decode smoke (eager and graph mode)
124
+ validate_quantized_model► PPL / p99 per-prompt NLL / MTP-acceptance ship gate
125
+ ```
126
+
127
+ Every hot path is GPU-bound by design; the pipeline refuses to run on CPU.
128
+
129
+ ---
130
+
131
+ ## Formats
132
+
133
+ **compressed-tensors container (vLLM-native):**
134
+
135
+ | Format | Role |
136
+ |---|---|
137
+ | NVFP4 | W4A4, group-16 FP8 block scales; CUTLASS on Blackwell — the 4-bit workhorse |
138
+ | FP8_DYNAMIC / FP8_E4M3 | the 8-bit rung — on the menu in every production recipe; it's what bends the rate-distortion curve into a knee |
139
+ | BF16 | passthrough only (never synthesized from a quantized source) |
140
+ | FP8_SOURCE | byte-exact passthrough of natively-FP8 checkpoints (lossless at ~8 bpp) |
141
+ | MXFP4/6/8, INT4/INT8, NVFP4A16 | registry-supported research rungs, excluded from defaults where a served kernel or a Pareto case is missing |
142
+
143
+ **GGUF container (llama.cpp + vLLM GGUF plugin):**
144
+
145
+ | Format | bpw |
146
+ |---|---|
147
+ | Q2_K / Q3_K / Q4_K / Q5_K / Q6_K / Q8_0 | 2.625 / 3.44 / 4.5 / 5.5 / 6.56 / 8.5 |
148
+ | IQ2_XXS / IQ2_XS / IQ2_S / IQ3_XXS / IQ3_S / IQ4_XS / IQ4_NL | 2.06 – 4.5 (E8-lattice codebooks; the sub-Q2_K regime) |
149
+
150
+ GGUF quantizers are PrismaQuant's own GPU implementations (imatrix-weighted grid/least-squares search, exhaustive codeword search for IQ), validated bit-exact against gguf-py. GPTQ-under-frozen-scales is available for the k-quants as a research lever. The allocator is serving-profile-aware in both containers: it never picks a format the target engine can't serve at that tensor's shape.
151
+
152
+ ---
153
+
154
+ ## Architectures
155
+
156
+ First-class profiles in-tree:
157
+
158
+ - **Qwen3 / 3.5 / 3.6** — dense + packed-3D MoE + MTP heads, Gated-DeltaNet hybrids
159
+ - **Tencent Hy3** (`hy_v3`) — 295B/21B-active, 192-expert MoE + MTP sidecar
160
+ - **DeepSeek-V4-Flash** (vendored transformer + profile) — 671B-class, per-expert-Linear MoE
161
+ - **MiniMax M2 / M2.7** — nested per-expert MoE, native-FP8 source
162
+ - **Gemma4** — multi-layer-type rope, KV sharing, visual/text profiles
163
+ - **LFM2.5** — per-expert MoE + short-conv layers
164
+
165
+ A new architecture is a `model_profiles/` registration (structure spec JSON + a small profile class); most of the fused-group and naming plumbing is auto-derived from the vLLM model class, so ports land in ~30–200 LoC.
166
+
167
+ ---
168
+
169
+ ## Published artifacts
170
+
171
+ | Model | Artifact |
172
+ |---|---|
173
+ | Qwen3.6-27B | [PrismaAURA 5.5 bpp](https://huggingface.co/rdtand/Qwen3.6-27B-PrismaAURA-5.5bit-vllm) · [5.31 bpp prior flagship](https://huggingface.co/rdtand/Qwen3.6-27B-PrismaSCOUT-Blackwell-NVFP4-BF16-vllm) (DOI 10.57967/hf/8656) · [v1 5.5 bpp](https://huggingface.co/rdtand/Qwen3.6-27B-PrismaQuant-5.5bit-vllm) |
174
+ | Qwen3.6-35B-A3B | [4.75 bpp](https://huggingface.co/rdtand/Qwen3.6-35B-A3B-PrismaQuant-4.75bit-vllm) |
175
+ | Ornith-1.0-35B | [PrismaAURA 4.75 bpp + MTP](https://huggingface.co/rdtand/Ornith-1.0-35B-PrismaAURA-4.75bit-vllm-MTP) |
176
+ | Tencent Hy3 295B-A21B | [2.8 bpp GGUF, single Spark](https://huggingface.co/rdtand/Hy3-295B-A21B-PrismaQuant-2.8bit-gguf-vllm) · [5.3 bpp CT + MTP, 2× Spark](https://huggingface.co/rdtand/Hy3-295B-A21B-PrismaQuant-5.3bit-2xSpark-vllm) |
177
+ | Qwen3.5-122B-A10B | [4.75 bpp](https://huggingface.co/rdtand/Qwen3.5-122B-A10B-PrismaQuant-4.75bit-vllm) |
178
+ | Mistral-Medium-3.5-128B | [4.75 bpp](https://huggingface.co/rdtand/Mistral-Medium-3.5-128B-PrismaQuant-4.75-vllm) |
179
+ | MiniMax-M2.7 | [3.20 bpp](https://huggingface.co/rdtand/MiniMax-M2.7-PrismaQuant-3.20bit-vllm) |
180
+ | Gemma4-31B-IT | [6 bpp](https://huggingface.co/rdtand/Gemma4-31B-IT-PrismaQuant-6bit-vllm) · [5.5 bpp](https://huggingface.co/rdtand/Gemma4-31B-IT-PrismaQuant-5.5bit-vllm) |
181
+ | LFM2.5-8B-A1B | [6.5 bpp](https://huggingface.co/rdtand/LFM2.5-8B-A1B-PrismaQuant-6.5bit-vllm) |
182
+
183
+ ---
184
+
185
+ ## Method discipline
186
+
187
+ The rules this project holds itself to, because low-bit quantization results are unusually easy to overstate:
188
+
189
+ - **Promote on the serving metric, not the screen.** A win counts only when it holds on exact full-vocab vLLM KL-vs-BF16 and direct perplexity *on the served artifact* at matched bpp. We have watched local-PPL "wins" invert on the served A/B more than once; those methods are archived with the lesson, not quietly dropped.
190
+ - **KL screens, it doesn't ship alone.** Lower mean KL can hide a heavier tail; candidates also clear direct PPL, p99 per-prompt NLL, and tool-use benchmarks before publication.
191
+ - **Held-out means held-out.** Selection KL uses text the cost stage never saw.
192
+ - **No hand-tuned bans.** If the allocator picks something that breaks, the cost model is wrong — fix the measurement, don't constrain the optimizer. The only constants allowed are ones derived from a dtype's numerical precision.
193
+ - **No quality claims we can't back.** The 295B artifact ships with an explicit "no quality claims" section because its teacher can't be measured on the target hardware. Provenance (git commit, calibration hash, assignment hash) is baked into every artifact's metadata.
194
+
195
+ ---
196
+
197
+ ## Citation
198
+
199
+ ```bibtex
200
+ @software{prismaquant2026,
201
+ title = {PrismaQuant: Mixed-Precision LLM Quantization Selected on Real End-to-End KL},
202
+ author = {Tand, Robert},
203
+ year = {2026},
204
+ url = {https://github.com/RobTand/prismaquant},
205
+ }
206
+ ```
207
+
208
+ The AURA paper (*AURA: Production-Faithful KL–Fisher Allocation*) is at [`paper/main.pdf`](paper/main.pdf) (source: [`paper/main.tex`](paper/main.tex)). Contact: robert.tand@icloud.com.
209
+
210
+ ## Acknowledgements
211
+
212
+ PrismaQuant is assembled on top of a decade of quantization research. Key influences: CLADO (Deng et al. 2023) for the cross-layer decision-unit framing (whose interaction-modeling half our head-to-head then retired); HAWQ-V1–V3 (Dong et al. 2019–2021), CoopQ, and AMQ on mixed-precision allocation; GPTQ (Frantar et al. 2022) and its Babai-nearest-plane interpretation (Chen et al. 2026) for rounding; the llama.cpp/ggml project for the GGUF formats and reference implementations; Kneedle (Satopää et al. 2011); and Cover & Thomas ch. 13 on rate-distortion bit allocation. Full bibliography in [`paper/main.tex`](paper/main.tex).
@@ -0,0 +1,169 @@
1
+ """PrismaQuant: mixed-native quantization policy engine for LLMs.
2
+
3
+ Current production path:
4
+ 1. incremental_probe.py stream Fisher and activation shards
5
+ 2. incremental_measure_quant_cost.py build per-Linear format costs
6
+ 3. allocator.py choose Pareto layer-format assignments
7
+ 4. validate_assignments_kl.py measure held-out KL for candidates
8
+ 5. export_native_compressed.py write compressed-tensors artifacts
9
+ 6. validate_native_export.py run vLLM load/generation smoke
10
+ 7. validate_quantized_model.py run downstream quality checks
11
+
12
+ Older cross-layer allocators are archived under archive/cross_layer_2026-05-09
13
+ for artifact replay and comparison.
14
+ """
15
+ from .format_registry import FormatSpec, REGISTRY, register_format
16
+
17
+ # Resolved from installed metadata rather than duplicated here, so
18
+ # pyproject.toml stays the single source of truth (the release pipeline asserts
19
+ # the git tag matches the built version). A source checkout that was never
20
+ # installed has no metadata; report that honestly instead of guessing a number.
21
+ try: # pragma: no cover - trivial metadata lookup
22
+ from importlib.metadata import PackageNotFoundError, version as _pkg_version
23
+
24
+ __version__ = _pkg_version("prismaquant")
25
+ except PackageNotFoundError: # pragma: no cover
26
+ __version__ = "0.0.0+unknown"
27
+ del _pkg_version, PackageNotFoundError
28
+
29
+
30
+ def _ensure_triton_cache_writable() -> None:
31
+ """Keep Triton-backed model code from falling back to CPU.
32
+
33
+ Some of the Qwen linear-attention dependencies import FLA, which asks
34
+ Triton for the active CUDA target at import time. If Triton cannot write
35
+ its cache, FLA catches the exception, decides the platform is CPU-only,
36
+ and later crashes in the CUDA forward path. Respect an explicit
37
+ TRITON_CACHE_DIR; otherwise redirect only when the default cache is not
38
+ writable by this user.
39
+ """
40
+ import os
41
+ import tempfile
42
+ from pathlib import Path
43
+
44
+ def _is_writable_dir(path: Path) -> bool:
45
+ try:
46
+ path.mkdir(parents=True, exist_ok=True)
47
+ with tempfile.NamedTemporaryFile(
48
+ prefix=".prismaquant-write-",
49
+ dir=path,
50
+ delete=True,
51
+ ):
52
+ pass
53
+ return True
54
+ except Exception:
55
+ return False
56
+
57
+ configured = os.environ.get("TRITON_CACHE_DIR")
58
+ if configured:
59
+ try:
60
+ Path(configured).mkdir(parents=True, exist_ok=True)
61
+ except Exception:
62
+ pass
63
+ return
64
+
65
+ default = Path.home() / ".triton" / "cache"
66
+ if _is_writable_dir(default):
67
+ return
68
+
69
+ base = Path(os.environ.get("XDG_CACHE_HOME", Path.home() / ".cache"))
70
+ fallback = base / "prismaquant" / "triton"
71
+ fallback.mkdir(parents=True, exist_ok=True)
72
+ os.environ["TRITON_CACHE_DIR"] = str(fallback)
73
+
74
+
75
+ # Transformers compatibility polyfill.
76
+ # Some remote modeling files (e.g. MiniMax-M2/M2.7's modeling_minimax_m2.py)
77
+ # import `OutputRecorder` from `transformers.utils.generic`. In
78
+ # transformers 5.x that symbol moved to `transformers.modeling_utils`.
79
+ # Re-expose the 4.x import path so remote code that matches the checkpoint
80
+ # tensor naming still loads. Idempotent — no-op if the symbol is already
81
+ # there (4.x or future 5.x that re-exports it).
82
+ def _polyfill_transformers() -> None:
83
+ try:
84
+ # OutputRecorder: transformers.utils.generic → transformers.modeling_utils
85
+ import transformers.utils.generic as _gen
86
+ if not hasattr(_gen, "OutputRecorder"):
87
+ import transformers.modeling_utils as _mu
88
+ if hasattr(_mu, "OutputRecorder"):
89
+ _gen.OutputRecorder = _mu.OutputRecorder
90
+ except Exception:
91
+ pass
92
+ try:
93
+ # `_init_weights` is wasted work across every prismaquant
94
+ # model-load path: we build a meta skeleton via `from_config`
95
+ # then immediately overwrite every parameter from the
96
+ # checkpoint via `_materialize` / `_fast_install`. Running
97
+ # `_init_weights` in between costs bounded real time on small
98
+ # models and is a compatibility landmine on remote modeling
99
+ # files — transformers 5.x's `_init_weights` now expects
100
+ # rotary modules to expose `compute_default_rope_parameters`,
101
+ # which older remote modeling files (MiniMax M2/M2.7) don't
102
+ # provide. No-op it globally at import time.
103
+ import transformers.modeling_utils as _mu
104
+ if hasattr(_mu, "PreTrainedModel") and \
105
+ not getattr(_mu.PreTrainedModel, "_prismaquant_init_noop", False):
106
+ _mu.PreTrainedModel._initialize_weights = (
107
+ lambda self, *a, **kw: None)
108
+ _mu.PreTrainedModel._prismaquant_init_noop = True
109
+ except Exception:
110
+ pass
111
+ try:
112
+ # Transformers 5.x's fine-grained-FP8 quantizer's
113
+ # `validate_environment` has an operator-precedence bug —
114
+ # the `"disk" in device_map.values()` check is not gated on
115
+ # `pre_quantized`, so it rejects disk-device-map loads even
116
+ # for pre-quantized checkpoints. Override with a bypass:
117
+ # prismaquant's streaming loader (for probe/cost) REQUIRES
118
+ # disk-device-map to offload body layers, and our caller
119
+ # guarantees the checkpoint is pre-quantized (it's the
120
+ # source on disk) so this rejection is a false positive.
121
+ from transformers.quantizers.quantizer_finegrained_fp8 import (
122
+ FineGrainedFP8HfQuantizer as _FP8Q,
123
+ )
124
+ if not getattr(_FP8Q, "_prismaquant_validator_bypass", False):
125
+ def _bypass_validate(self, *a, **kw):
126
+ return None
127
+ _FP8Q.validate_environment = _bypass_validate
128
+ _FP8Q._prismaquant_validator_bypass = True
129
+ except Exception:
130
+ pass
131
+ try:
132
+ # ROPE_INIT_FUNCTIONS['default'] was removed in transformers 5.x
133
+ # (renamed to 'linear', which takes a 'factor' kwarg the old
134
+ # default never needed). Remote modeling files from older
135
+ # checkpoints still look up 'default'. Re-register the old
136
+ # implementation verbatim — a ~6-line function computing the
137
+ # standard rotary inv_freq schedule with no scaling.
138
+ from transformers.modeling_rope_utils import ROPE_INIT_FUNCTIONS
139
+ if "default" not in ROPE_INIT_FUNCTIONS:
140
+ import torch as _torch
141
+ def _compute_default_rope_parameters(config=None, device=None, **_):
142
+ base = config.rope_theta
143
+ partial = getattr(config, "partial_rotary_factor", 1.0)
144
+ head_dim = getattr(
145
+ config, "head_dim",
146
+ config.hidden_size // config.num_attention_heads)
147
+ dim = int(head_dim * partial)
148
+ inv_freq = 1.0 / (base ** (
149
+ _torch.arange(0, dim, 2, dtype=_torch.int64)
150
+ .to(dtype=_torch.float32, device=device) / dim))
151
+ return inv_freq, 1.0
152
+ ROPE_INIT_FUNCTIONS["default"] = _compute_default_rope_parameters
153
+ except Exception:
154
+ pass
155
+ try:
156
+ # Qwen3 upstream recomputes rotary cos/sin with a per-forward
157
+ # FP32 BMM. Under deterministic cuBLAS plus PrismaQuant imports,
158
+ # that BMM can produce NaNs after model.cuda(). Route Qwen3
159
+ # AutoModel loads to the vendored cached-RoPE copy.
160
+ from .vendored import register_qwen3 as _register_qwen3
161
+ _register_qwen3()
162
+ except Exception:
163
+ pass
164
+
165
+
166
+ _ensure_triton_cache_writable()
167
+ _polyfill_transformers()
168
+ del _ensure_triton_cache_writable
169
+ del _polyfill_transformers