Repository navigation
fix(engine): upload cuda graphs at capture so a stream wait cannot block the first launch - #697
Merged
Merged
Conversation
…ock the first launch
27 of 42 tasks
pretor
pushed a commit
to pretor/FreeToken
that referenced
this pull request
Oct 16, 2026
…e) and GGUF updates
KarrAcaRn
pushed a commit
to KarrAcaRn/FreeToken-ByAI
that referenced
this pull request
Oct 17, 2026
Upstream 0bca88f..11c1adb: GGUF on vendored ggml (FlashML-org#690 and the per-arch loaders), MoE slot pools (FlashML-org#689, FlashML-org#700), GGUF experts on the cpu/hybrid executor (FlashML-org#704), the NVFP4 MoE prefill GEMM rewrite (FlashML-org#723), triton decode split-k by context length (FlashML-org#729), graph upload at capture (FlashML-org#697), transformers 5.18. Resolution: - GGUF: upstream's stack replaces ours (dense llama/qwen2/qwen3, qwen3moe, qwen35moe loaders, q4_0/gguf expert banks, our ggml kernels and their tests). Re-ported on top: rope-only --hf-overrides (YaRN) for the llama/qwen2/qwen3/qwen3moe GGUF parsers, and the scalar head_count_kv of Gemma-4 GGUFs (upstream PR FlashML-org#190). Gemma-4 E2B/E4B GGUF is not re-ported. - offload cache: upstream's pooled cache, with our disk tier (one pool only), fill_slots preload per pool, sync-free prefill invalidation for a contiguous staging range, hit-D2D-by-default wording and the HIP graph per-bank copy. - NVFP4 prefill: upstream's GEMM and per-GPU tuning supersede our sm_89 tile config and JOIN_B. - triton decode attention: upstream's split-k over our fp8/nvfp4 KV paths and HIP head padding; DFlash verify graphs are uploaded at capture too. - embedding: upstream's embedding quant method, with --embed-device cpu in front and the tied head's kernel choice kept for unquantized tables. - engine: DFlash, --kv-reserve-share, shrink-first rebuild, startup hybrid split and the WSL pin probe combined with the slot pools. GPU-checked on the RTX 4090: full suite green; Qwen3.6-35B-A3B NVFP4 prefill ~13.2k / decode ~131 tok/s (baseline 13.6k / 131), Qwen3-30B-A3B Q4_K_M GGUF 14.6k / 259 (was 8.3k / 225). Assisted-by: Claude Opus 5.5
This was referenced Oct 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
With
--ple-backend diskin wait-sync mode (Qwen3.8-Flash-Next), the captured decode graph waits on a host flag at the PLE lookup, and the engine signals that flag only afterreplay()returns. torch captures the graph without uploading it, so the firstreplay()of each batch size also uploads it. When enough kernels follow the wait, that firstreplay()never returns: the engine thread stays incuGraphLaunch, so the flag is never signaled. The Flash-Next GGUF decode graph on main does not hang as is; with 4000 more kernels after the lookup it does.Reproduce
Put this
sitecustomize.pyonPYTHONPATHto add 4000 kernels after the PLE lookup in the captured graphs:Serve ISTA-DASLab/Qwen3.8-Flash-Next-GSQ-RCO-GGUF IQ3_XXS with
--moe-strategy fused --ple-backend diskand send one chat request. On main the request gets no response, GPU utilization stays at 0%, and py-spy shows the engine thread inGraphRunner.replay -> cudaGraphLaunch -> cuGraphLaunch -> sched_yield.Fix
Upload each graph with
cuGraphUploadright after capture, so the firstreplay()does not upload it. Linux with CUDA only (throughctypesonlibcuda.so.1); Windows and ROCm are unchanged.With the patch above, this branch answers the request, and its greedy output matches the run without the patch. Without the patch, greedy output and decode speed match main. Tested on H100 80GB, torch 2.14.1+cu130.