vllm.v1.attention.ops.rocm_octave
¶
Octave KV-cache format: layout, rotations and a PyTorch reference.
Each (token, KV head) is stored in one byte slot. V is always quantized whole; K has two layouts:
- Block K (
octave_k3v4,octave_k3v3): random sign flips plus a Walsh-Hadamard transform over each 64-dim block. The RoPE blocks get 4-bit codes, the NoPE blocks 3-bit codes, and every block has its own scale. - Compact K (
octave_k3v3_compact): sign flips plus one Hadamard transform over all dims, 3-bit codes, one scale. Spreading the RoPE dims over the whole head lets them share the 3-bit budget. - V: sign flips plus one Hadamard transform over all dims,
v_bitscodes.
The rotated coordinates are close to Gaussian, so each code indexes a
Lloyd-Max codebook for N(0, 1), stored as int8 (LUT): a code c of a
block with scale s stands for LUT[c] * s / LUT_ONE. The scale makes
x . x_hat = |x|^2: a least-squares fit would shrink every reconstructed
vector, which flattens the softmax and scales down the attention output.
Everything is computed on the fly; there is no calibration.
Scores are computed in the rotated space (the query is rotated like K) and the attention output is rotated back once per query head.
Slot layout (bytes)::
[k_rope codes][k_nope codes][v codes][fp16 scales][pad to 8]
Compact K has no 4-bit part and pads to 4 bytes.
4-bit codes: each little-endian uint32 covers 8 dims; byte j holds dim j in
its low nibble and dim j + 4 in its high nibble, so w & 0x0F0F0F0F and
(w >> 4) & 0x0F0F0F0F give dims 0..3 and 4..7 as bytes.
3-bit codes: a 2-bit plane (uint32 per 16 dims; (w >> 2i) & 0x03030303
gives dims 4i..4i+3) followed by a 1-bit plane (uint32 per 32 dims;
(w >> i) & 0x01010101 gives dims 4i..4i+3). code = lo + 4 * hi.
Scales (fp16): one per 64-dim K block (one in total for compact K), then V.
Classes:
Functions:
-
fwht_blocks–Orthonormal Walsh-Hadamard transform over consecutive blocks of the
-
reference_attention–Per-query-token attention over a Octave paged cache.
-
reference_dequantize–(T, H, slot) slots -> fp32 K and V of shape (T, H, D).
-
reference_quantize–(T, H, D) K and V -> (T, H, slot_bytes) uint8 slots.
-
sign_bits–The sign pattern as int32 words, bit i set where the sign is -1.
-
signs–Fixed ±1 pattern applied before the Hadamard transform.
-
v_block–V is rotated as one block when head_size is a power of two.
OctaveFormat
dataclass
¶
Attributes:
-
k_wide_dim(int) –K dims stored with ROPE_BITS codes (the rest use NOPE_BITS).
-
kernel_code(int) –Format id the kernels take: V bits, plus 16 for compact K.
Source code in vllm/v1/attention/ops/rocm_octave.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | |
_pack(codes, bits)
¶
codes: (..., n) uint8 -> (..., n * bits / 8) uint8, layout above.
Source code in vllm/v1/attention/ops/rocm_octave.py
_quantize_lut(x, bits)
¶
Nearest Lloyd-Max code on the block RMS; the scale keeps
x . x_hat = |x|^2.
Returns (codes uint8 in [0, 2**bits), scale) with x ≈ LUT[codes] * scale / LUT_ONE.
Source code in vllm/v1/attention/ops/rocm_octave.py
fwht_blocks(x, block=HADAMARD_BLOCK)
¶
Orthonormal Walsh-Hadamard transform over consecutive blocks of the last dim.
Source code in vllm/v1/attention/ops/rocm_octave.py
reference_attention(query, cache, block_table, q_to_req, q_to_klen, fmt, scale)
¶
Per-query-token attention over a Octave paged cache.
query: (Q, Hq, D). cache: (num_blocks, Hkv, block_size, slot) uint8.
Query token i attends to the first q_to_klen[i] tokens of request
q_to_req[i].
Source code in vllm/v1/attention/ops/rocm_octave.py
reference_dequantize(slots, fmt, rotated=False)
¶
(T, H, slot) slots -> fp32 K and V of shape (T, H, D).
With rotated=True K and V stay in the rotated space, which is what
the kernels consume.
Source code in vllm/v1/attention/ops/rocm_octave.py
reference_quantize(key, value, fmt)
¶
(T, H, D) K and V -> (T, H, slot_bytes) uint8 slots.
Source code in vllm/v1/attention/ops/rocm_octave.py
sign_bits(n)
¶
The sign pattern as int32 words, bit i set where the sign is -1.
Source code in vllm/v1/attention/ops/rocm_octave.py
signs(n, device_str)
cached
¶
Fixed ±1 pattern applied before the Hadamard transform.
v_block(head_size)
¶
V is rotated as one block when head_size is a power of two.