Maximize decode throughput for Qwen3.5-27B (Dense, hybrid DeltaNet + GQA) on NVIDIA B200 using pure Triton kernels. No quantization, no vLLM.
Baseline target: ~45-55 tok/s (HuggingFace BF16 default) Optimized target: 85-110 tok/s (1.7-2.2x speedup)
- 208 SMs, 8 TB/s HBM3e bandwidth, 192GB HBM3e
- 96MB L2 cache, 256KB SRAM per SM
- BF16 tensor cores: 2,250 TFLOPS
- Theoretical decode floor: 54GB / 8TB/s = 6.7ms = ~149 tok/s
- Perfect wave sizes: 208 / 416 / 624 blocks
File: forge/kernels/triton_rmsnorm.py
Usage: 128x per token (2 norms x 64 layers)
Strategy: Single kernel replaces 7 PyTorch ops (cast, pow, mean, rsqrt, mul, mul, cast)
BLOCK_N: 8192 (next power-of-2 for hidden_size=5120)
| Metric | Before | After | Delta |
|---|---|---|---|
| Kernel launches per norm | 7 | 1 | -6 |
| HBM round-trips | 7 | 1 | -6 |
Status: Ported from qwen-benchmark. Awaiting B200 validation.
File: forge/kernels/triton_rmsnorm_gated.py
Usage: 48x per token (DeltaNet output gate normalization)
Strategy: Fuses rmsnorm(hidden) * silu(gate) into 1 kernel (~10 ops -> 1)
Status: New kernel. Awaiting B200 validation.
File: forge/kernels/triton_bf16_gemv.py
Usage: Every linear projection in every layer
Strategy: Split-K for B200 SM utilization, target 416 blocks (2 waves)
Key shapes:
- MLP gate/up: [5120, 17408], 178MB per layer
- MLP down: [17408, 5120], 178MB per layer
- lm_head: [5120, 248320], 2.4GB, 1x per token
Variants:
- Standard GEMM (for M > 1 prefill)
- Split-K GEMM (for small N with M=1)
- Specialized GEMV (M=1, no tl.dot, uses vector-matrix multiply)
- Split-K GEMV (M=1, more blocks)
Status: Implemented with B200 autotune configs. Awaiting benchmark vs cuBLAS.
File: forge/kernels/triton_deltanet_recurrent.py
Usage: 48x per token (all DeltaNet layers)
Strategy: Fuses entire recurrent step into 1 kernel per head
State per head: [128, 128] = 32KB BF16, fits in B200's 256KB SRAM.
Math:
S *= exp(g) # gate decay
residual = v - S^T @ k # delta rule
delta = beta * residual
S += outer(k, delta) # rank-1 update
o = S^T @ q # output
Two-pass design:
- Pass 1: Load S, apply decay, accumulate S^T@k
- Pass 2: Compute delta, update S, accumulate S^T@q
Variants:
- V1: Row-by-row processing (register-friendly), IMPLEMENTED
- V2: Tiled processing (for larger states), IMPLEMENTED
- V3: Multi-head per block (TODO)
Correctness: Must verify 1000 decode steps without state drift.
Status: Two variants implemented. Awaiting correctness validation.
File: forge/kernels/triton_causal_conv1d.py
Usage: 48x per token (DeltaNet conv on projected QKV)
Strategy: Shift + insert + dot product + SiLU in one kernel
Grid: (8192 channels, B) per layer = 8192 blocks, ~40 waves on B200.
Status: Implemented. Awaiting validation.
File: forge/kernels/triton_silu_mlp.py
Usage: 64x per token (every layer)
Strategy: Fuses SiLU(gate) * up elementwise (saves 70KB HBM per layer)
Variants:
- Elementwise fusion only (separate GEMVs + fused activation), IMPLEMENTED
- Fully fused dual-GEMV + SiLU (experimental), IMPLEMENTED
Status: Both variants implemented. Must benchmark A vs B.
File: forge/kernels/triton_fused_qkv_rope.py
Usage: 16x per token (full attention layers only)
Strategy: Single GEMV for concatenated Q+K+V + inline partial RoPE
Reads x once (10KB) instead of 3 times. RoPE on first 64 of 256 dims.
Status: Implemented. Awaiting validation.
File: forge/kernels/triton_lm_head_topk.py
Usage: 1x per token
Strategy: Never materializes full 248K logits vector.
Each GEMV tile computes local max, reduce kernel finds global argmax.
Saves ~500KB HBM write+read per token. CUDA graph compatible (deterministic shape).
Status: Implemented. Awaiting validation.
Model patcher: forge/llm/patch_qwen35.py
- Monkey-patches all 64 layers
- DeltaNet forward: fused proj + conv1d + recurrent + norm_gated + output
- Attention forward: fused norm + GEMV QKV + SDPA + output
Cache: forge/llm/cache.py
- HybridCache: DeltaNet (conv_state + recurrent_state) + KV cache
- Total: ~72MB DeltaNet + KV cache
Generation: forge/llm/generate.py
- Eager decode loop with CUDA event timing
- CUDA graph capture after warmup
- Eliminates ~640 kernel launches per token
| Source | Expected Speedup | Notes |
|---|---|---|
| CUDA graph | +40-50% | Eliminates 3ms of 7ms launch overhead |
| Fused DeltaNet recurrent | +10-15% | 1 kernel vs 5+ per layer |
| Fused RMSNorm/Gated | +5-8% | 128 fusion points per token |
| Fused SiLU MLP | +3-5% | Eliminates intermediate writes |
| BF16 GEMV split-K | +5-10% | Better SM utilization vs cuBLAS |
- Run baseline benchmark on B200
- Validate all 8 kernels (correctness + cosine > 0.9999)
- Run optimized benchmark
- Evolve top 3 kernels
- DeltaNet 1000-step drift test
- E2E correctness check (patched vs unpatched greedy decode)
- Profile optimized model, identify remaining bottlenecks
- Iterate: evolve kernels, re-benchmark