code wiki / (root) / nx_quant_block.nx

nx_quant_block.nx

buildroot/runtime/nx_quant_block.nx

9616 B256 linesdepth 3pulls 3 transitivereach 29 importersview sourcekind librarytopic quant
docsdependenciesstructsconstsfunctions

about

nx_quant_block.nx -- 4-bit block quantization on i64 substrate. Algo-led memory win per the min-hardware-floor cardinal. Modern LLMs and diffusion models DO NOT fit on small hardware at f32 precision; q4_K-style quantization is what makes Llama-3 70B run on a 24 GB consumer GPU and what makes Z-Image fit on a 16 GB card. On a $50 SBC with 4-8 GB total RAM, quantization is the difference between "model loads" and "model OOMs." v1 shape: q4_0-style symmetric quantization on i64 substrate. * Block size: 32 values per block (standard) * Per-block scale: one i64 (Q-format multiplier) * Values: 4-bit signed nibbles in [-7, 7]; packed two per byte * Storage per block: 8 bytes (scale) + 16 bytes (nibbles) = 24 bytes * Dense storage: 32 i64 = 256 bytes * Compression: 256 / 24 ~ 10.67x When the compiler-I2 f-types land, this slots in q4_K (k-means per- group scales) + q5_K + q8_0 without API change. The block layout is the contract; the per-block calibration is the dtype. Algorithmic precision note (the audit-honest answer): * Per-value max rounding error = scale/2 = max_abs/14 * Relative error per value ≤ 1/14 ≈ 7.1% in the worst case * Mean error across a uniform-distribution block is ~1/28 ≈ 3.6% * Oracle round-trip uses eps_q10 = 102 (10%) -- well above mean error, below worst-case, so failures here are real corruption not normal quantization noise. genealogy_id: q4_0_ggml_2023 + q4_K_ggml_2024 + lloyd_max_1957 + jacob_kligys_2018_8bit_quant lineage_id: substrate_quant_block_v1

dependencies 3 imports · 4 importers

nx_syscalls.nx nx_tier.nx nx_tensor.nx nx_quant_block.nx nx_embedding.nx nx_quant_block_test.nx nx_quant_q4k.nx nx_quant_q4k_test.nx

imports: nx_syscalls.nxnx_tier.nxnx_tensor.nx

imported by: nx_embedding.nxnx_quant_block_test.nxnx_quant_q4k.nxnx_quant_q4k_test.nx

structs

67struct NxQuantBlock

consts

44const NX_QB_BLOCK_SIZE: nx_int = 32 // values per block
45const NX_QB_NIBBLE_MAX: nx_int = 7 // [-7..+7]
46const NX_QB_NIBBLES_PER_BYTE: nx_int = 2
49const NX_QB_BYTES_PER_BLOCK: nx_int = 24
53const NX_QB_OK: nx_int = 0
54const NX_QB_ERR_BAD_LEN: nx_int = 1 // n not multiple of BLOCK_SIZE
55const NX_QB_ERR_BAD_DTYPE: nx_int = 2 // input not i64
56const NX_QB_ERR_SHAPE_MISMATCH: nx_int = 3 // dequant target wrong shape
57const NX_QB_N_VERDICTS: nx_int = 4
74const NX_QB_STRUCT_BYTES: nx_int = 32 // 4 fields * 8

functions

59func nx_qb_verdict_is_valid(v: nx_int) -> nx_int
called by 1: main
76func nx_qb_alloc(n_values: nx_int) -> *NxQuantBlock
105func _qb_pack_nibble(qb: *NxQuantBlock, value_idx: nx_int, signed_nib: nx_int) -> nx_int
called by 1: nx_qb_quantize
126func _qb_unpack_nibble(qb: *NxQuantBlock, value_idx: nx_int) -> nx_int
called by 1: nx_qb_dequantize
152func _qb_abs(x: nx_int) -> nx_int
called by 1: nx_qb_quantize
157func nx_qb_quantize(values: *i64, n: nx_int, qb: *NxQuantBlock) -> nx_int
211func nx_qb_dequantize(qb: *NxQuantBlock, values_out: *i64, n: nx_int) -> nx_int
229func nx_qb_compression_ratio_q10(qb: *NxQuantBlock) -> nx_int
called by 1: main
240func nx_qb_quantize_tensor(t: *NxTensor) -> *NxQuantBlock
251func nx_qb_dequantize_tensor(qb: *NxQuantBlock, t: *NxTensor) -> nx_int