Repository navigation
[MM][V2] Enable encoder-only ViT CUDA graph capture - #56922
Conversation
Co-authored-by: GPT-6 <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Co-authored-by: GPT-6 <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Co-authored-by: GPT-6 <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Co-authored-by: GPT-6 <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Co-authored-by: GPT-6 <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Co-authored-by: GPT-6 <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Co-authored-by: GPT-6 <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Co-authored-by: GPT-6 <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
|
Documentation preview: https://vllm--56922.org.readthedocs.build/en/56922/ |
Track the unresolved NaN propagation in vllm-project#57136 and avoid zeroing ordinary eager attention outputs. Co-authored-by: Codex <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Remove the temporary attention workaround and its regression test. Exercise E-only capture with Triton and document the backend comparison in vllm-project#57136. Co-authored-by: Codex <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
|
During validation with Qwen2.5-VL-3B on H20 (BF16), we observed NaN encoder embeddings when replaying a 1196-token image through the 2048-token graph in a multi-budget shared pool. This reproduced with both FA3 and FA4, while ordinary eager execution remained finite. FLASHINFER and Triton did not reproduce the issue in the same tested configuration. The investigation is tracked in #57136. The earlier attention-output zero-initialization avoided the observed failure, but it was a temporary workaround rather than a fully established root-cause fix. In particular, isolated tests showed that NaNs in the unused V tail can contaminate valid FA3/FA4 outputs even in eager execution; the full propagation path and the appropriate fix still need investigation. I have removed the padding workaround and its dedicated test from this PR. This PR now focuses on enabling E-only encoder graph capture; the FA NaN fix will be handled separately under #57136. The E-only functional tests and Mooncake CI explicitly use Triton, without changing the product's default backend selection. @gty111 |
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
|
@Isotr0py can also take a look |
|
/ci run |
|
❌ This PR is 149 commits behind upstream |
|
/ci run |
|
✅ Triggered Buildkite CI #89352 for commit |
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
Head branch was pushed to by a user without write access
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
|
/ci run |
|
✅ Triggered Buildkite CI #89497 for commit |
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com>
|
/ci run |
|
❌ This PR is 12 commits behind upstream |
|
/ci run |
|
✅ Triggered Buildkite CI #89555 for commit |
Signed-off-by: jiangkuaixue123 <jiangxiaozhou111@163.com> Co-authored-by: Codex <noreply@openai.com>

Purpose
Enable vision encoder CUDA graph capture for ModelRunnerV2 encoder-only instances. #49852 added encoder graph support to the ordinary V2 GPUModelRunner, but MMEncoderModelRunner overrides
capture_modelwith an immediate return, so E-only instances do not capture those graphs.Call the existing EncoderRunner capture path from the E-only runner, with GC handling, capture-memory accounting, and workspace locking. Reuse existing budget selection, replay, eager fallback, output copies, and EC transfer. The feature remains opt-in, independent of decoder graph mode, and disabled by
enforce_eager.Add E-only configuration/lifecycle/model tests, Mooncake graph-hit assertions, and CI configuration. The attention-padding zero-initialization workaround, its capture context, and its dedicated padding regression test have been removed. The production change is confined to MMEncoderModelRunner; this PR does not change attention kernels or default backend selection.
Known FA backend issue and backend validation
The separate NaN issue is tracked in #57136. With the workaround disabled, H20 / Qwen2.5-VL-3B / BF16 / head_dim=80 / TP=1 testing of nine encoder graph budgets sharing one pool produced:
Backend/version selection was inspected on the actual attention layers; there was no silent fallback. Each backend ran three small -> large -> small sequences, with nine graph hits and zero misses. Tail-injection tests covered capacity/active lengths 256/128 and 2048/1196, using fixed atol=rtol=0.016 against unpadded FP32 SDPA. FLASHINFER used its required offset metadata and interleaved QKV layout. All backends leave some output padding unwritten, but only FA3/FA4 propagated V-tail NaNs in these tests. The complete full-model propagation chain and interface-contract responsibility remain under investigation in #57136.
FLASHINFER and Triton did not reproduce this issue in the tested configuration; this is not a universal guarantee across models and shapes. FA3/FA4 remain affected in that configuration, and this PR does not fix or close #57136. All E-only model test cases (Qwen2.5-VL, Qwen3-VL, and Qwen3.5) select FLASHINFER. Mooncake CI selects TRITON_ATTN. Users can set
--mm-encoder-attn-backend TRITON_ATTNorFLASHINFERwhen using encoder graphs on supported configurations; the integration script exposesE_MM_ENCODER_ATTN_BACKEND.Environment: NVIDIA H20-3e, driver 580.105.08, Python 3.12, Torch 2.13.0+cu132; FLASHINFER 0.6.17, cuDNN package 9.20.0.48. Model revision: 66285546d2b821cf421d4f5eb2576359d3770cd3. Backend comparisons used 53a766f with the workaround disabled before worker initialization; the final change removes that workaround entirely. Existing precompiled extensions were reused. Multi-GPU, V1, RDMA, LoRA, and broad model-quality benchmarks were not evaluated in this follow-up. No performance improvement is claimed.
Test Plan
Test Result
Code validation revision 05c72d0: pre-commit (including shellcheck and documentation checks) and manual mypy-3.12 passed. H20 rerun on this revision: combined attention/encoder/EC suites 132 passed, 14 skipped (27.85s; ROCm/AITER-only skips). Qwen2.5-VL and Qwen3-VL E-only tests using TRITON_ATTN: 2 passed (123.19s), covering images, video, budget fallback, and retained-output integrity. The backend comparisons above were completed without the workaround. The updated Mooncake CI backend configuration has not yet been run end-to-end on this revision; earlier EPD results with the workaround are not presented as validation of this final version.
The subsequent documentation-only commit 31993e3 removes all changes to
docs/features/disagg_encoder.md; its pre-commit checks passed. Production code and tests are unchanged from the validated revision above.Duplicate-work checks and human review
Open PR searches for E-only/encoder-only graphs, encoder cudagraph, and padding NaNs found no competing E-only capture implementation. #49852 is the merged infrastructure reused here. #55929 addresses input normalization; #52230 addresses V1 non-first PP ranks. The independent FA NaN issue is tracked in #57136 rather than fixed in this PR.
AI assistance (OpenAI Codex) was used for implementation, testing, and review. This PR remains a draft pending the human submitter's required review and test confirmation:
E-only model test backend follow-up
All three parameterized E-only model test cases now use FLASHINFER. The H20 FLASHINFER rerun described below covers Qwen2.5-VL; Qwen3-VL and Qwen3.5 await validation with this backend. Buildkite 89352 failed that case with TRITON_ATTN on H200 MIG (finite outputs, but maximum absolute difference 3.40625). On H20 at the same cc04b48 source revision, the isolated test passed with TRITON_ATTN and with a test-only FLASHINFER override: 1 passed in 88.82s and 57.55s respectively, both with maximum absolute error 0, seven graph hits and one fallback. These durations include startup and are not a backend performance comparison. Pre-commit passed for the committed backend change; the new CI result remains pending.