Skip to main content

Module q4_k

Module q4_k 

Source
Expand description

The Q4_K weight encoder: a transcription of llama.cpp b7650’s quantize_row_q4_K_ref (ggml/src/ggml-quants.c:1280), not a reimplementation of it.

A K-quant is NOT min/max over a block. Q4_K’s 256-element super-block is fitted in three stages, all of which live in super::fit because Q5_K’s fit is the same three stages with four numbers changed:

  1. Each of the 8 sub-blocks of 32 gets an iterative affine fit (make_qkx2_quants): 21 candidate inverse scales are tried, each one re-solves a weighted least-squares for (scale, min) from the integer codes it produced, and the lowest weighted squared error wins. The weights are sqrt(mean(x^2)) + |x|, so a sub-block’s large values pull the fit toward themselves.
  2. The 8 scales and 8 mins are themselves quantized to 6 bits against the super-block’s d/dmin and packed into 12 bytes.
  3. The 4-bit codes are then recomputed against the 6-bit-rounded scale and min, not against the fit from stage 1 – so stage 3 sees a slightly different affine map than stage 1 did.

A naive min/max encoder skips all three and produces a file that loads and generates measurably worse text. That is the failure this module exists to not ship, so the arithmetic in super::fit is deliberately the same shape as the C, down to the operation order in the least-squares accumulation.

What is left HERE is only what is Q4_K’s own: the candidate grid it passes to the shared fit, and the nibble packing.

Functions§

encode_block_q4_k
Encodes one Q4_K super-block (exactly Q4_K_BLOCK_ELEMS values) and appends its Q4_K_BLOCK_BYTES bytes to out.
encode_row_q4_k
Encodes a whole row (or any slice whose length is a multiple of Q4_K_BLOCK_ELEMS) into Q4_K super-blocks, appending to out.