Expand description
BitNet b1.58 ternary quantization codec — STELLAR §A compression (task #12).
Ternary packing of weights ∈ {-1, 0, +1} with a per-tensor absmean scale (BitNet 1.58b):
it replaces fused multiply-adds with hardware adds/subtracts in the GEMM kernels and shrinks the
weights to ≈ 1.6 bits each. This module is the reusable codec; it is applied during
transcode by crate::p64_weight::transcode_safetensor_to_p64_ternary so a P64 image ships
compressed, not as a verbatim blob.
§Encoding
- Quantize (per tensor):
scale = mean(|w|);t_i = clamp(round(w_i / scale), -1, +1). - Dequantize:
w_i ≈ scale · t_i. - Packing: five trits per byte in base-3 (
3⁵ = 243 ≤ 256) →8 bits / 5 trits = 1.6 bits/weight. A trit{-1,0,+1}is offset to a digit{0,1,2}; a byte isd₀ + 3·d₁ + 9·d₂ + 27·d₃ + 81·d₄.
The hot-path dequant (dequantize_ternary) is zero-heap (it streams base-3 digits straight
into the caller’s f32 buffer — no intermediate trit Vec). The encode path runs at ingest
(cold), where a working Vec is acceptable.
Constants§
- GGML_
TYPE_ TERNARY_ 158 - Engine element-type code for a BitNet-1.58b ternary tensor (well outside the GGML code range,
so it never collides with
F32=0 / F16=1 / Q8_0=8 / Q4_K=12 / BF16=30). Mnemonic: “1.58b”. - TERNARY_
GEMM_ 2BIT_ WGSL - The branchless 2-bit WGSL ternary-GEMM kernel; CPU oracle is
ternary_gemm_cpu_2bit. - TERNARY_
GEMM_ WGSL - The WGSL ternary-GEMM compute kernel (STELLAR §A). Its CPU parity reference is
ternary_gemm_cpu, which mirrors it byte-for-byte (same trit extraction, add/subtract, end-scale). The GPU pipeline binds:0activations (f32),1packed trits (u32words),2TernaryParamsuniform,3output (f32). - TRITS_
PER_ BYTE - Trits packed per byte (
3⁵ = 243 ≤ 256). - TRITS_
PER_ BYTE_ 2BIT - Trits packed 4-per-byte, 2 bits each:
0b00 = 0,0b01 = +1,0b10 = -1(0b11unused).
Functions§
- dequantize_
blob - Decode a
ternary_blobofcountweights intoout(zero-heap dequant). - dequantize_
ternary - Dequantize packed ternary →
f32weights (scale · trit) intoout. Zero-heap: digits are streamed straight from the bytes (no intermediate trit allocation). Writesout.len()values. - pack_
trits - Pack ternary values (
i8 ∈ {-1,0,+1}) into bytes (5 trits/byte, base-3). The final partial group is zero-padded (decodes back to the requestedcountviaunpack_trits_into). - pack_
trits_ 2bit - Pack ternary values into 2-bit codes, 4 per byte.
- packed_
trit_ len - Bytes needed to pack
counttrits (5 per byte). - packed_
trit_ len_ 2bit - Bytes to pack
counttrits at 2 bits each (4/byte). - quantize_
ternary - BitNet 1.58b quantize: per-tensor absmean
scale+ ternary values∈ {-1,0,+1}. A zero (or empty) tensor yieldsscale = 0.0and all-zero trits. - rebake_
ternary_ blob_ to_ 2bit - Rebake an on-disk base-3
ternary_blob([scale f32 LE][5-trits/byte]) into the runtime 2-bit branchless VRAM layout consumed by [ternary_gemm_2bit.wgsl] /ternary_gemm_cpu_2bit. - ternary_
blob - Encode a weight tensor to a self-describing ternary blob:
[scale: f32 LE][packed trits]. (The element count is recovered from the tensor’s shape in the container manifest.) - ternary_
blob_ len - Total ternary-blob length for
countweights: a 4-bytef32scale + the packed trits. - ternary_
gemm_ cpu - CPU oracle for
ternary_gemm.wgsl. Computesout[m][i] = scale · Σ_j trit(W[i][j])·act[m][j]wherepackedholds the row-major trits of an(n_out × n_in)weight matrix. The weight contributes by add/subtract only (the BitNet win); the per-tensorscaleis applied once per output element. Zero-heap. Strides default to dense (n_in/n_out) when0. - ternary_
gemm_ cpu_ 2bit - CPU oracle for
ternary_gemm_2bit.wgsl— same math asternary_gemm_cpu, 2-bit packing + branchless accumulation. - trit_at
- Extract the ternary value
{-1,0,+1}at linear weight indexkfrom packed trits — the exact operationternary_gemm.wgsl::trit_atperforms (5 trits/byte, base-3). - trit_
at_ 2bit - Trit value
{-1,0,+1}at linear indexkfrom 2-bit packing — the branchless mirror ofternary_gemm_2bit.wgsl::pair_at((code==1) - (code==2)). - unpack_
trits_ into - Unpack
out.len()trits from packed bytes into the caller’s buffer (zero-heap). Returns the number written (min(out.len(), packed capacity)).