Skip to content

Commit aed7a94

Browse files
TheTomclaude
andcommitted
feat: block size 32 β€” 77.7 tok/s MoE (91% of q8_0), 17.0 Qwopus (97%) πŸŽ‰
Changed QK_TURBO3 from 128 to 32 (storage block size). Rotation still operates on 128-element groups (QK_TURBO3_GROUP=128). SET_ROWS kernel processes 4 blocks per rotation group. Flash attention nl_k changed from 32 to 8 (matching q4_0). Block struct: 14 bytes per 32 values = 3.5 bits/val β†’ 4.6Γ— compression. Results: - MoE gen: 62.2 β†’ 77.7 tok/s (91% of q8_0 at 85.5) - MoE prompt: 200 β†’ 218.5 tok/s (98% of q8_0) - Qwopus gen: 15.5 β†’ 17.0 tok/s (97% of q8_0 at 17.6) - Qwopus prompt: 83 β†’ 89.5 tok/s (108% of q8_0 β€” FASTER) Target was 75+ tok/s. Exceeded. Co-Authored-By: tturney@psyguard.ai Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a1230c8 commit aed7a94

3 files changed

Lines changed: 106 additions & 201 deletions

File tree

β€Žggml/src/ggml-common.hβ€Ž

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -266,18 +266,20 @@ typedef struct {
266266
} block_tq2_0;
267267
static_assert(sizeof(block_tq2_0) == sizeof(ggml_half) + QK_K / 4, "wrong tq2_0 block size/padding");
268268

269-
// TurboQuant 3-bit: 2-bit PolarQuant indices + 1-bit QJL signs
270-
// Block size = 128 (matches typical head_dim for optimal rotation Gaussianization)
271-
// Per block: norm(fp16) + residual_norm(fp16) + 2-bit indices (32 bytes) + 1-bit signs (16 bytes)
272-
// = 52 bytes per 128 values = 3.25 bits/value β†’ 4.9Γ— compression vs fp16
273-
#define QK_TURBO3 128
269+
// TurboQuant 3-bit MSE-only: 3-bit PolarQuant indices (no QJL)
270+
// Storage block size = 32 (matches q4_0 for optimal GPU parallelism)
271+
// Transform group size = 128 (head_dim, for rotation Gaussianization)
272+
// Per block: norm(fp16) + 2-bit indices (8 bytes) + 1-bit extra (4 bytes) = 14 bytes per 32 values
273+
// = 3.5 bits/value β†’ 4.6Γ— compression vs fp16
274+
// The 3-bit index is split: lower 2 bits in qs[], upper 1 bit in signs[]
275+
#define QK_TURBO3 32
276+
#define QK_TURBO3_GROUP 128 // rotation group size = head_dim
274277
typedef struct {
275278
ggml_half norm; // 2 bytes: vector L2 norm (for rescaling)
276-
ggml_half rnorm; // 2 bytes: QJL residual L2 norm
277-
uint8_t qs[QK_TURBO3 / 4]; // 32 bytes: 2-bit PolarQuant indices (4 per byte)
278-
uint8_t signs[QK_TURBO3 / 8]; // 16 bytes: 1-bit QJL signs (8 per byte)
279-
} block_turbo3_0; // 52 bytes total
280-
static_assert(sizeof(block_turbo3_0) == 2*sizeof(ggml_half) + QK_TURBO3/4 + QK_TURBO3/8, "wrong turbo3_0 block size/padding");
279+
uint8_t qs[QK_TURBO3 / 4]; // 8 bytes: lower 2-bit indices (4 per byte)
280+
uint8_t signs[QK_TURBO3 / 8]; // 4 bytes: upper 1-bit of 3-bit index (8 per byte)
281+
} block_turbo3_0; // 14 bytes total
282+
static_assert(sizeof(block_turbo3_0) == sizeof(ggml_half) + QK_TURBO3/4 + QK_TURBO3/8, "wrong turbo3_0 block size/padding");
281283

282284
// TurboQuant 4-bit: 3-bit PolarQuant indices + 1-bit QJL signs
283285
// Per block: norm(fp16) + residual_norm(fp16) + 3-bit indices (48 bytes) + 1-bit signs (16 bytes)

0 commit comments

Comments
Β (0)