code wiki / (root) / nx_quant_policy.nx

nx_quant_policy.nx

buildroot/runtime/nx_quant_policy.nx

14999 B364 linesdepth 4pulls 4 transitivereach 0 importersview sourcekind tooltopic quant
docsdependenciesstructsconstsfunctions

about

nx_quant_policy.nx -- per-layer mixed-precision quantization policy. Ships VRAM-track Q-003 per docs/VRAM_OPTIMIZATION_REALISTIC_TRACKING.md. Pure composition over the three quantizers already shipped: nx_quant_block.nx -- q4_0 (4-bit symmetric, 10.67x compression) nx_quant_block_q8.nx -- q8_0 (8-bit symmetric, 6.4x compression) nx_quant_q4k.nx -- q4_K (4-bit k-quants w/ per-group scales) The model loader consults this policy to decide WHICH quantizer to apply per-layer. Not every layer is equally sensitive to quantization loss; cheap-to-compress layers (FFN up/down/gate) go aggressive (q4_K), expensive-to-compress layers (Q/K/V projections, embeddings, final output) stay safer (q8_0 or passthrough at f16). Sensitivity heuristic literature: - Frantar 2022 _GPTQ_: per-channel scale, calibration-data-driven - Lin et al. 2023 _AWQ_: activation-aware -- protect outlier channels at higher precision - Xiao et al. 2023 _SmoothQuant_: pre-shift activation outliers into weights so weights can be quantized further without activation-side accuracy loss - ggml q-mix presets 2024: practitioner-tuned per-tensor-name defaults for Llama/Mistral/Qwen The substrate ships the POLICY TABLE structure + a default heuristic. Per-model calibration (the AWQ pass) is a separate workstream that fills the table with measured sensitivities. VRAM impact composition: * 70% of params at q4_K (4-bit + k-quant overhead): ~3.5x save * 25% of params at q8_0: ~1.4x save * 5% of params at f16 passthrough: ~0.5x save * Aggregate: ~3.0x save Per the bounded-loop cardinal: every loop here uses the LoopVerdict pattern from nx_loop.nx. genealogy_id: gptq_frantar_2022 + awq_lin_2023 + smoothquant_xiao_2023 + ggml_quant_mix_presets_2024

dependencies 3 imports · 0 importers

nx_syscalls.nx nx_tier.nx nx_loop.nx nx_quant_policy.nx

imports: nx_syscalls.nxnx_tier.nxnx_loop.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main nx_qp_select_kind nx_qp_bytes_per_param_q14 nx_qp_alloc sys_mmap nx_qp_register nx_qp_select_kind ↻ sys_mmap ↻ nx_qp_compression_ratio_q1 nx_qp_total_bytes_dense_f1 nx_qp_total_bytes nx_qp_bytes_per_param_q14 ↻

structs

103struct NxQuantPolicyEntry
160struct NxQuantPolicy

consts

58const NX_QP_F16: nx_int = 0 // passthrough (no quantization)
59const NX_QP_Q8_0: nx_int = 1 // 8-bit symmetric, ~6.4x compression
60const NX_QP_Q4_K: nx_int = 2 // 4-bit k-quant, ~8.5x compression (with super-block overhead)
61const NX_QP_Q4_0: nx_int = 3 // 4-bit symmetric legacy, ~10.7x compression
62const NX_QP_F32: nx_int = 4 // full precision (rare, debug)
63const NX_QP_N_KINDS: nx_int = 5
77const NX_QR_UNKNOWN: nx_int = 0
78const NX_QR_EMBED: nx_int = 1 // token / position embeddings
79const NX_QR_ATTN_Q: nx_int = 2 // Q projection
80const NX_QR_ATTN_K: nx_int = 3 // K projection
81const NX_QR_ATTN_V: nx_int = 4 // V projection
82const NX_QR_ATTN_O: nx_int = 5 // output projection (after attention)
83const NX_QR_FFN_UP: nx_int = 6 // up-projection
84const NX_QR_FFN_DOWN: nx_int = 7 // down-projection
85const NX_QR_FFN_GATE: nx_int = 8 // gate projection (Llama-style)
86const NX_QR_NORM: nx_int = 9 // LayerNorm / RMSNorm scale
87const NX_QR_OUTPUT: nx_int = 10 // final output projection / lm_head
88const NX_QR_BIAS: nx_int = 11 // bias vectors (always small, keep f16)
89const NX_QR_N_ROLES: nx_int = 12
110const NX_QP_ENTRY_BYTES: nx_int = 32 // 4 fields * 8
166const NX_QP_REG_BYTES: nx_int = 24

functions

65func nx_qp_is_valid(k: nx_int) -> nx_int
91func nx_qr_is_valid(r: nx_int) -> nx_int
126func nx_qp_select_kind(role: nx_int, depth_from_first: nx_int, depth_from_last: nx_int) -> nx_int
called by 2: nx_qp_registermain
168func nx_qp_alloc(cap: nx_int) -> *NxQuantPolicy
called by 1: main calls 1: sys_mmap
176func nx_qp_register(p: *NxQuantPolicy,
called by 1: main calls 1: nx_qp_select_kind
204func nx_qp_bytes_per_param_q14(kind: nx_int) -> nx_int
220func nx_qp_total_bytes(p: *NxQuantPolicy, params_per_entry: *i64) -> nx_int
236func nx_qp_total_bytes_dense_f16(params_per_entry: *i64, n: nx_int) -> nx_int
250func nx_qp_compression_ratio_q10(p: *NxQuantPolicy, params_per_entry: *i64) -> nx_int
270func main() -> i64