Reclaims over-reserved memory rather than spending headroom, so it honors
the conservative 0.82 / 14 GB-OS-reserve choice (still ~15 GiB free under
peak load) while closing most of the gap to the dflash pool (456k):
- int8 lm-head: build int8 on first warmup forward, then free the dead bf16
copy (~1.4 GiB) + empty_cache() so the block lands in the KV pool. Safe:
the DFlash drafter shares the one int8 lm_head module (verified one int8
build; drafter ckpt has no lm_head/embed) and tie_word_embeddings=False,
so bf16 has no reader (bias fallback = int8-GEMV + add-bias).
SPARK_KEEP_BF16_LMHEAD=1 restores keep-bf16.
- VLLM_MEMORY_PROFILER_ESTIMATE_CUDAGRAPHS=0 in serve.sh/mtp_serve.sh:
returns the CUDA-graph over-estimate (~0.6 GiB; actual capture ~0.14 GiB
from the wide 0.82 headroom). Overridable with =1.
- scripts/stress_mem.sh: drive the concurrency bank while sampling host RAM
to prove a gpu-mem setting survives peak load without swapping.
Validated: pool 426,610 tokens, coherent output, drafter acceptance 4-12,
no new swap, throughput unchanged. max-batched-tokens 8192->4096 tested as
a KV lever and rejected (only +2.5k tokens, costs prefill speed).