Repository navigation
fix(#4621): QK-norm models take the FP16 batched prefill when it fits (D3-SPLIT B, stacked on #4620) - #4624
fix(#4621): QK-norm models take the FP16 batched prefill when it fits (D3-SPLIT B, stacked on #4620)#4624noahgift wants to merge 7 commits into
Conversation
… (root 2) Qwen3-family models were forced onto the serial prefill by disable_fp8_for_qk_norm (#3413/#3483); serial scales super-linearly and the 1.7B 20k cell ran past 600 s. They now keep FP8 off but take the FP16 batched prefill, which #4620 made chunked. A model whose weights + FP16 cache + KV + prefill reserve exceed free VRAM keeps serial (Qwen3-8B on 24 GB, which OOMed into a CPU fallback without this check); BATCHED_PREFILL=1 still overrides. The resident estimate walks the projection tensors themselves (bytes and in x out elements) instead of a dims formula, so it cannot drift from the model. Stacked on #4620. Refs #3715 Agent: aprender-ec Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nto B Agent: aprender-e6 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
quorum-review (AD-04): NOT agreed (auto_merge: checked=true was_armed=false disarmed=false) {
"ticket": "PMAT-4621",
"head": "451bc77c528822417a53b25190d7670dadd813eb",
"width": 3,
"executor": "agy",
"agreed": false,
"auto_merge": {
"checked": true,
"was_armed": false,
"disarmed": false,
"note": "auto-merge not armed"
},
"lanes": [
{
"lane": 1,
"verdict": "PASS",
"findings": 2
},
{
"lane": 2,
"verdict": "FAIL",
"findings": 1
},
{
"lane": 3,
"verdict": "NO-VERDICT",
"findings": 0
}
]
} |
|
quorum-review (AD-04): NOT agreed (auto_merge: checked=true was_armed=false disarmed=false) {
"ticket": "PMAT-4621",
"head": "451bc77c528822417a53b25190d7670dadd813eb",
"width": 3,
"executor": "agy",
"agreed": false,
"auto_merge": {
"checked": true,
"was_armed": false,
"disarmed": false,
"note": "auto-merge not armed"
},
"lanes": [
{
"lane": 1,
"verdict": "FAIL",
"findings": 3
},
{
"lane": 2,
"verdict": "FAIL",
"findings": 3
},
{
"lane": 3,
"verdict": "PASS",
"findings": 0
}
]
} |
Agent: aprender-e6 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
quorum-review (AD-04): three PASS — agreed (auto_merge: checked=true was_armed=false disarmed=false) {
"ticket": "PMAT-4621",
"head": "1c97bea00e1f42564a6c1eeadb3a254c6ecd8e2f",
"width": 3,
"executor": "agy",
"agreed": true,
"auto_merge": {
"checked": true,
"was_armed": false,
"disarmed": false,
"note": "auto-merge not armed"
},
"lanes": [
{
"lane": 1,
"verdict": "PASS",
"findings": 2
},
{
"lane": 2,
"verdict": "PASS",
"findings": 0
},
{
"lane": 3,
"verdict": "PASS",
"findings": 1
}
]
} |
…) into B Agent: aprender-e6 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
quorum-review (AD-04): NOT agreed (auto_merge: checked=true was_armed=false disarmed=false) {
"ticket": "PMAT-4621",
"head": "dcee3dd3ae9286ad88a1a7f4311c126000dccb4a",
"width": 3,
"executor": "agy",
"agreed": false,
"auto_merge": {
"checked": true,
"was_armed": false,
"disarmed": false,
"note": "auto-merge not armed"
},
"lanes": [
{
"lane": 1,
"verdict": "PASS",
"findings": 0
},
{
"lane": 2,
"verdict": "NO-VERDICT",
"findings": 0
},
{
"lane": 3,
"verdict": "PASS",
"findings": 0
}
]
} |
|
quorum-review (AD-04): NOT agreed (auto_merge: checked=true was_armed=false disarmed=false) {
"ticket": "PMAT-4621",
"head": "dcee3dd3ae9286ad88a1a7f4311c126000dccb4a",
"width": 3,
"executor": "agy",
"agreed": false,
"auto_merge": {
"checked": true,
"was_armed": false,
"disarmed": false,
"note": "auto-merge not armed"
},
"lanes": [
{
"lane": 1,
"verdict": "PASS",
"findings": 2
},
{
"lane": 2,
"verdict": "FAIL",
"findings": 1
},
{
"lane": 3,
"verdict": "PASS",
"findings": 2
}
]
} |
Agent: aprender-e6 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
quorum-review (AD-04): NOT agreed (auto_merge: checked=true was_armed=false disarmed=false) {
"ticket": "PMAT-4621",
"head": "a6abbede70bb7b9d15013fd09e8c75d2341eef3b",
"width": 3,
"executor": "agy",
"agreed": false,
"auto_merge": {
"checked": true,
"was_armed": false,
"disarmed": false,
"note": "auto-merge not armed"
},
"lanes": [
{
"lane": 1,
"verdict": "PASS",
"findings": 2
},
{
"lane": 2,
"verdict": "FAIL",
"findings": 3
},
{
"lane": 3,
"verdict": "PASS",
"findings": 0
}
]
} |
Agent: aprender-e6 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…op 11:03Z) The tree is exactly devont/k1-kv-only (origin/main + K1 #4603, D5 #4614 and the KV budget core). The other stack rows (#3715 serial prefill / for_session, #3413 message, #4620, #4623, #4624) stay on their ec parents for a later PR; nothing is deleted there. A merge, not a rebase or force-push. Agent: aprender-00 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Closed with a pointer to #4623 (0.70.2 backlog, aprender-78): this PR's #4621 fix (QK-norm models take the FP16 batched prefill, root 2) is carried by #4623 as cd324d0. Measured: crates/aprender-serve/src/cuda/executor/layers/prefill.rs and crates/aprender-serve/src/gguf/cuda/resident.rs are byte-identical on both heads. The three further commits on this branch (596b6bb, 6cac047, 17f499b) change the mutants gate. They belong to the mutants workstream, not to chat KV, so they are not folded into #4623. Branch ec/4621-fit-and-chat-kv is kept with them. |
D3-SPLIT B of #4620: QK-norm models take the FP16 batched prefill when it fits (root 2)
Stacked on #4620 (A), and C (
ec/4621-chat-session-kv,apr chatdevice KV) is stacked on this PR. The base branch isec/3715-lambda-cells, soci.ymldoes not run here. It runs once A merges and this PR retargets tomain. The mutant cap is verified in that run.What changes
GpuProfile::disable_fp8_for_qk_normstill turns FP8 off for a QK-norm model (Qwen3: the FP8 batched prefill fails CPU parity, FP8 batched prefill fails CPU parity at the post-prompt decode step — catastrophic on per-head-QK-norm models (Qwen3-8B cos −0.10), marginal on Qwen2.5 (0.92) #3483). It no longer forces the serial prefill. Serial is oneforward_gpu_residentper prompt token: Qwen3-1.7B could not prefill a 20k prompt within the 600 s cell timeout. The batched prefill is now chunked (fix(cuda): #3715 lambda run/chat cells: chunked prefill, chat KV, Qwen3.5 F16/IQ4_XS dequant, 8B fit #4620), and chunking is what bounded the old OOM.GpuProfile::serial_when_fp16_prefill_does_not_fit: a QK-norm model keeps the serial prefill when weights + FP16 cache + KV + prefill reserve exceed free VRAM. Qwen3-8B on 24 GB is the case that OOMed into a CPU fallback without this check.BATCHED_PREFILLset explicitly still overrides.OwnedQuantizedModelCuda::resident_estimateand the newgguf/cuda/resident.rsread the projection tensors themselves (bytes, in×out), not a dims formula, so the estimate cannot drift from the model.Evidence
--features cuda --lib): 17910 passed, 6 failed, 76 ignored. All 6 failures are device or ptxas tests (test_new_device_0,test_num_devices,test_cov002_cuda_likely_available,test_cuda_executor_new,gemm_bt_tiled_ptx_…,every_emitted_kernel_assembles), and intel has no NVIDIA driver (nvidia-smifails), so they say nothing about this diff.fmt --checkpasses.--features cuda -D warnings: 2borrow_deref_referrors atcuda/executor/residual.rs:314,343, already on main (from perf(qwen35-cuda): DP4A requant staleness (#4258) + argmax first-of-ties (#4259) + allocation-free decode plumbing (#4215) — replaces #4322 #4332 #4439), outside this diff. The receipt ec ran on the B files alone (resident:: pmat3477 fit_check gpu_profile) is 40/40.handoff/3715-fix-ec.md(ec, combined binary apr-fix4). The tensor-walk refactor of the resident estimate has not been re-measured on a device.Refs #4621, Refs #3715. This PR does not close #4621: C closes it when it merges last.
Agent: aprender-e6 (split owner; code by aprender-ec)
🤖 Generated with Claude Code