Skip to content

feat: Bf16 KV cache for hybrid GDN models (#27)#56

Merged
pekkah merged 1 commit into
masterfrom
feat/bf16-kv-hybrid-gdn
May 28, 2026
Merged

feat: Bf16 KV cache for hybrid GDN models (#27)#56
pekkah merged 1 commit into
masterfrom
feat/bf16-kv-hybrid-gdn

Conversation

@pekkah

@pekkah pekkah commented May 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • Default the CUDA hybrid GDN KV cache to bf16 (env SHARPI_KV_DTYPE=fp32 reverts). Arithmetic stays fp32 — bf16 → fp32 promotion happens at the kernel read sites.
  • New NVRTC kernels llm_kv_append_bf16 / llm_attention_bf16 mirror their fp32 counterparts; CudaBackend.Clear is now dtype-aware so it can't over-write the smaller bf16 buffers.
  • Parity test (CudaHybridGdnForwardPass_Qwen35Mtp_Bf16KvCache_GreedyMatchesFp32) asserts top-1 match and a < 0.5 absolute gap on top-16 logits between bf16 and fp32 cache runs.

Measured (Qwen3.6-27B-MTP Q4_K_M, --temp 0, ctx=4096, RTX 4070 Ti)

KV dtype FFN layers on GPU Free VRAM after Decode
fp32 21/64 275 MiB 4.3 t/s
bf16 22/64 394 MiB 6.4 t/s

Output is bit-identical between the two paths on this prompt. Greedy first-token parity vs the CPU/llama.cpp baseline still holds on qwen35moe with bf16 active.

Test plan

  • dotnet test tests/SharpInference.Tests.ForwardPass -c Release — all 239 tests pass, including the new Bf16KvCache_GreedyMatchesFp32 parity case
  • Smoke run on Qwen3.6-27B-MTP — bf16 produces identical text and ~49% decode speedup vs fp32
  • Smoke run on Qwen3.6-35B-A3B (MoE) — bf16 is on par with fp32 (~22 t/s decode; the CPU-MoE FFN dominates so KV-cache savings on the GPU attention layers are neutral here)

🤖 Generated with Claude Code

Default the CUDA hybrid GDN forward pass KV cache to bf16 (was fp32),
halving cache VRAM on the 16 attention layers without touching arithmetic
precision — bf16→fp32 promotion happens at the kernel read sites, fp32
accumulators throughout. SHARPI_KV_DTYPE=fp32 reverts.

On Qwen3.6-27B-MTP at ctx=4096 the freed ~128 MiB admits one more dense
FFN layer on GPU (22/64 vs 21/64), lifting --temp 0 decode 4.3 → 6.4 t/s.
Output is bit-identical vs fp32 cache. Greedy first-token parity vs the
CPU/llama.cpp baseline still holds on qwen35moe with bf16 active.

New CUDA NVRTC kernels llm_kv_append_bf16 / llm_attention_bf16 mirror
their fp32 counterparts; CudaBackend.Clear is now dtype-aware so it
doesn't over-write the smaller bf16 buffers. New parity test
CudaHybridGdnForwardPass_Qwen35Mtp_Bf16KvCache_GreedyMatchesFp32 asserts
both top-1 match and a < 0.5 absolute logit gap on top-16.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@pekkah pekkah merged commit 1e302cd into master May 28, 2026
1 check passed
@pekkah pekkah deleted the feat/bf16-kv-hybrid-gdn branch May 28, 2026 11:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant