Capicua25x commited on
Commit
dcaf079
Β·
verified Β·
1 Parent(s): eab3544

Add calibrated KV-cache scales (51 F32 scalars, weights unchanged)

Browse files

model-kvscales.safetensors: {q,k,v}_scale for the 16 full-attention layers + the MTP draft.
Captured at --kv-cache-dtype auto on Attention.forward (post-norm, post-RoPE) over 1.4M tokens
/ 170,905 calls; scale = amax*1.1/{200,200,100}. Weight shards are byte-identical -- only the
index gains 51 entries. Inert under bf16 KV; active only with --kv-cache-dtype fp8.
Largest amax is 147 vs e4m3's 448, so scale-1.0 was never clipping: this is hygiene, not a
quality fix. Vision tower not calibrated (text-only corpus); no accuracy re-run yet.

README.md CHANGED
@@ -123,6 +123,52 @@ branch `rdna4-port-0.26.1`. `VLLM_RDNA_MXFP4_FP8=0` falls back to the weight-onl
123
  Sampling follows the base model card: thinking `temp 1.0, top_p 0.95, top_k 20, min_p 0`;
124
  non-thinking `temp 0.7, top_p 0.8, top_k 20, presence_penalty 1.5`.
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  ## What it took to run this on RDNA4
127
 
128
  These weights are the small half of the work. RDNA4 (gfx1200/gfx1201) is outside the official ROCm
@@ -335,6 +381,8 @@ will be revised as they land; the commit history is the record of what was known
335
  ## Reproducing the quantisation
336
 
337
  Data-free, CPU-only, file-to-file β€” no calibration set, no GPU, ~3 minutes for this model.
 
 
338
 
339
  ```python
340
  from quark.torch.export.api import direct_quantize_checkpoint
 
123
  Sampling follows the base model card: thinking `temp 1.0, top_p 0.95, top_k 20, min_p 0`;
124
  non-thinking `temp 0.7, top_p 0.8, top_k 20, presence_penalty 1.5`.
125
 
126
+ ## KV-cache scales (added 2026-08-18)
127
+
128
+ The weight shards are **unchanged**. This repo additionally carries **51 F32 KV-cache scalars** in
129
+ `model-kvscales.safetensors` (5,708 bytes) plus matching `model.safetensors.index.json` entries β€”
130
+ `{q,k,v}_scale` for each of the 16 full-attention layers and for the MTP draft layer.
131
+
132
+ **They do nothing unless you serve with `--kv-cache-dtype fp8`.** Under the default bf16 KV cache β€”
133
+ which is every number elsewhere on this card β€” they load and sit unused. Without them vLLM falls back
134
+ to `k_scale = v_scale = q_scale = 1.0` and logs `Using KV cache scaling factor 1.0 for fp8_e4m3`:
135
+ correct bytes, wrong numbers. With them, that line is **absent**, and its absence is the only reliable
136
+ proof they loaded β€” `.q_scale/.k_scale/.v_scale` are in vLLM's `_ignore_unexpected_suffixes`, so a
137
+ mis-named scale is dropped silently instead of erroring.
138
+
139
+ **How they were captured.** Served at `--kv-cache-dtype auto` with a recorder on `Attention.forward`
140
+ taking a running amax of q/k/v *as the cache sees them* β€” post `q_norm`/`k_norm`, post-RoPE β€” over
141
+ **1.4M tokens / 170,905 attention calls**: 354 requests spanning long documents (8k–96k), multi-subject
142
+ QA, maths, code, instruction-following and a Spanish business slice, plus production traffic. Both
143
+ tensor-parallel ranks recorded, per-layer maximum taken. `scale = amax Γ— 1.1 / {200, 200, 100}` for
144
+ q/k/v, matching vLLM's `Q/K/V_SCALE_CONSTANT`.
145
+
146
+ | | q | k | v |
147
+ |---|---|---|---|
148
+ | range over the 16 attention layers | 11.50 – 19.50 | 12.19 – 23.12 | 8.44 – **147.00** |
149
+ | MTP draft layer | 19.50 | 20.88 | 51.50 |
150
+
151
+ `v` grows monotonically with depth (12.06 at layer 3 β†’ 147.00 at layer 63).
152
+
153
+ **What this is worth β€” read this before assuming it is an upgrade.** The largest amax anywhere is
154
+ **147 against e4m3's maximum of 448**, so the uncalibrated cache was never *clipping*. The scales shift
155
+ where the distribution sits rather than rescue it, and on a float format that is a small effect β€”
156
+ consistent with the published finding of ≀0.7 points from an uncalibrated fp8 KV cache on a model of
157
+ this class. Treat this as hygiene that closes a question, not as a quality fix.
158
+
159
+ **Not measured, not covered:**
160
+
161
+ * **No accuracy re-run of the calibrated build** (GSM8K / long-context / task suites). The numbers under
162
+ *Quality* below are the bf16-KV build and are unaffected by this addition.
163
+ * **The vision tower is not calibrated** β€” the capture corpus is text-only.
164
+ * **No `prob_scale` is shipped.** No v1 ROCm attention backend consumes one, so vLLM's
165
+ `…and/or prob_scale 1.0 with fp8 attention` warning still fires and can be ignored.
166
+ * **fp8 KV doubles the attention block on this architecture.** vLLM aligns the attention page to the
167
+ mamba page, so halving the bytes per token pushes the block from 800 to 1600 tokens, which coarsens
168
+ prefix-cache reuse: only whole blocks are reused. If your requests share a long prefix, pad it to a
169
+ multiple of the block size β€” otherwise the remainder is recomputed on every request. Measured here on
170
+ a 7,299-token prompt: 99 tokens recomputed at block 800 vs 899 at block 1600.
171
+
172
  ## What it took to run this on RDNA4
173
 
174
  These weights are the small half of the work. RDNA4 (gfx1200/gfx1201) is outside the official ROCm
 
381
  ## Reproducing the quantisation
382
 
383
  Data-free, CPU-only, file-to-file β€” no calibration set, no GPU, ~3 minutes for this model.
384
+ (This describes the **weights**. The KV-cache scalars above are the one calibrated artefact in the
385
+ repo and came from a separate capture pass on the served model; they do not touch the shards.)
386
 
387
  ```python
388
  from quark.torch.export.api import direct_quantize_checkpoint
model-kvscales.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a8e738b76c92943bcccbccf2f204e0d327caff970fabc889a6daee6e01107aaa
3
+ size 5708
model.safetensors.index.json CHANGED
The diff for this file is too large to render. See raw diff