GGUF Q2_K / Q2_K_S (2-bit K-quant)
Fields
quantization/gguf-q2-kNotes
CORRECTED 2026-10-04: was 256. 256 is the SUPER-BLOCK size (QK_K), not the scale-sharing group. dequantize_row_q2_K applies one (scale,min) pair per 16 values (`dl = d*(sc & 0xF); ml = min*(sc>>4); for l<16`), 16 sub-blocks per 256-value super-block, each sub-block's 4-bit scale and 4-bit min themselves sitting on the fp16 d/dmin super-block scales. Q2_K is the plain (non-mixed) 2-bit k-quant; Q2_K_S is the mixed variant. BIT LAYOUT, verified from ggml/src/ggml-common.h (not from any blog): the K-quant super-block is QK_K = 256 values. block_q2_K = { uint8_t scales[QK_K/16]; // 16 scales AND 16 mins, 4-bit each, packed 2 per byte = 16 bytes uint8_t qs[QK_K/4]; // 64 bytes of 2-bit quants ggml_half d; // super-block scale FOR THE QUANTIZED SCALES ggml_half dmin; } // super-block scale FOR THE QUANTIZED MINS }. So it is 16 blocks of 16 elements, each block x = a*q + b with a and b both 4-bit quantized and themselves scaled by fp16 d/dmin: 64 bytes quants + 16 bytes scales/mins + 4 bytes fp16 = 84 bytes per 256 values = 2.625 bpw, matching the header comment. This is the two-level-scale design that distinguishes the k-quants: the per-16 scale is not fp16 like legacy q4_0, it is 4-bit and sits on a second fp16 scale. MIXTURE (from src/llama-quant.cpp): Q2_K is not a single type. attn_v -> Q4_K if n_gqa>=4 else Q3_K; ffn_down -> Q3_K; attn_output -> Q3_K. Q2_K_S additionally bumps ffn_down in the first n_layer/8 layers to Q4_K and, if n_gqa>=4, attn_v to Q4_K. For the plain Q2_K, ffn_down is forced to Q3_K and attn_output to Q3_K - i.e. 'Q2_K' is genuinely ~3.16 bpw despite the name. Weight-only: activations stay fp16/bf16 at runtime, so there is no 2-bit-activation hardware claim to make. ggml has a bespoke dequantize_row_q2_K + mul_mat kernel per backend but no accelerator has a GGUF k-quant path in silicon; everything is dequantized on the fly. vLLM labels its GGUF support experimental/under-optimized and positions it as a memory-footprint tool. NATIVE_SUPPORT CLASSIFIED 2026-10-04: this field is still [] and that is CORRECT, but the empty list used to be ambiguous between three different states and now is not. Reason class on this record: LLAMA.CPP INTEGER STORAGE TYPE, SO STRUCTURALLY ABSENT. Every GGUF type here is a packed integer block format read by a dequant kernel (dequantize_row_*) and then executed as FP16; ggml publishes no int4 or sub-8-bit tensor-core path that consumes these blocks directly. The llama.cpp CUDA and Vulkan backends both run these formats by dequantizing. Consequence for a reader: nothing further to verify - and note the contrast with nvfp4/mxfp4/mxfp8 in this repo, which ARE hardware formats on Blackwell and carry populated native_support lists, so '4-bit' alone does not predict this field. The full statement of the three-way distinction, and the worked list of all 72 empty records by class, is in gotcha quant-native-support-empty-means-three-different-things. Rule of thumb for this field everywhere in the repo: if the bits field carries an 'a16', or the scheme is KV-cache-only or a llama.cpp integer storage type, an empty native_support is a DEFINITION and needs no verification; only a W4A4/W8A8/sub-8-bit format with research kernels can have an empty list that is a real finding.