Repository navigation
[FEAT] Capture fixed-depth speculative decode with CUDA Graphs - #48
Conversation
c97b61e to
9f75a08
Compare
Signed-off-by: 0z5a <dezhen.lu@student.uni-tuebingen.de>
Signed-off-by: 0z5a <dezhen.lu@student.uni-tuebingen.de>
Signed-off-by: 0z5a <dezhen.lu@student.uni-tuebingen.de>
Signed-off-by: 0z5a <dezhen.lu@student.uni-tuebingen.de>
Signed-off-by: 0z5a <dezhen.lu@student.uni-tuebingen.de>
9f75a08 to
9a1670e
Compare
Signed-off-by: 0z5a <dezhen.lu@student.uni-tuebingen.de>
27abc9d to
b574eb3
Compare
|
Tested speculative decoding with CUDA Graphs enabled/disabled on a B300 using Ouro-1.4B, BF16 and FA4. Following the README workload methodology: 1,024 input tokens, 128 output tokens, 2× concurrency requests with closed-loop replacement. Timing includes prefill and drain, excluding loading and warmup. Both arms use synchronous speculation with draft depth 2, target depth 4 and K=4. Throughput (output tokens/s; higher is better):
Improvement = (Graph on / Graph off − 1) × 100%, computed from the corresponding throughput percentiles. Sample-size note: these are percentiles across only three measured runs per configuration after two warmups, calculated with linear interpolation. P95/P99 are descriptive of these three runs, not reliable tail estimates or request-latency percentiles. C32 eager had one slow run (292.39 vs. 539.35–541.12 tokens/s), so its improvement remains preliminary. Generated token IDs and exit depths matched across all measured pairs. Three additional FA4 correctness tests passed, covering packed metadata updates, graph reuse, and fallback behavior. Configuration details: graph limits were raised to 640 rows / 64 shapes, rather than the README defaults. Capture occurred during warmup; caches were frozen for measured runs with eager fallback allowed. At C128, recurrent graphs recorded 888 replays and 1,076 fallbacks per run. Tested commit: One potential follow-up optimization is improving graph coverage at high concurrency: at C128, only 45.2% of recurrent calls used graph replay (888 replays vs. 1,076 eager fallbacks per run). Tracking fallback reasons and shape frequencies could help identify whether a different shape-cache policy or shape bucketing would improve coverage. This can be considered future work. |
|
plz remove benchmarks & results dirs. |
Keep runtime and test changes intact; the measured summary remains in the PR description. Signed-off-by: 0z5a <dezhen.lu@student.uni-tuebingen.de>
done |
Scope
Implements the CUDA Graph feature claimed by @0z5a in #43 on top of #44. Fixed-depth synchronous speculation captures recurrent loops and the LM head. Shape/position changes use matching graph keys or eager fallback; sampling and request bookkeeping remain outside capture.
RTX 5090 E2E
Ouro-1.4B, BF16/Triton, d=2/D=4, K=4, 64 output tokens, one resident model, five warmups per arm and five alternating paired trials. Both arms used one OMP/MKL/OpenBLAS CPU thread. Every output token and exit depth matched.
Recurrent graphs: 11 captures / 5,400 replays. LM-head graphs: 11 captures / 2,240 replays. Eager fallbacks: zero. The single-request repeated prompt is sensitive to host scheduling; a separate run during host load around 162/128 logical CPUs had substantial timing drift. The table above summarizes the recorded trials.
Verification and limits
/home/gongji/0z5aenvironment inside Docker with a verified 96 GiB RAM cap.Built on merged #44. This PR contains only the CUDA Graph work claimed in #43.
CUDA Graph capture cleanup
Recurrent and coda graphs now share one warmup/capture helper. Their graph keys, eager fallbacks, and steady-state replay behavior are unchanged. Post-change verification: CPU suite 286 passed, 11 skipped, 111 GPU cases deselected; RTX 5090 Triton CUDA Graph suite 12 passed, 14 deselected; Ruff check/format passed. The latest stacked scheduler run also exercised this Graph parent with exact output matches and zero eager fallbacks.