feat(multimodal): CUDA-graph bucket ladder (Dynamo-side target_bucket) + Qwen3-VL ViT example#11039
Closed
furionw wants to merge 1 commit into
Closed
feat(multimodal): CUDA-graph bucket ladder (Dynamo-side target_bucket) + Qwen3-VL ViT example#11039furionw wants to merge 1 commit into
furionw wants to merge 1 commit into
Conversation
fa42f16 to
4be49c4
Compare
a15907b to
f853fa4
Compare
4be49c4 to
3c1f269
Compare
f853fa4 to
aa90a19
Compare
3c1f269 to
729398f
Compare
…) + Qwen3-VL ViT example PR4 of the custom vision-encoder series, stacked on PR3. Introduces bucket-wise graph support on the Dynamo side and a real graphed encoder example. - ThreadedMicroBatcher: optional `buckets` ladder. When set, the batcher rounds a batch's packed sum(cost) UP to the nearest rung and passes it as `target_bucket` to fn(items, target_bucket). With max_batch_cost=None it derives the ceiling as max(buckets); buckets=None stays eager / pass-through (PR3 behavior unchanged). - AsyncVisionEncoder passes backend.buckets to the batcher. - Qwen3VLViTEncoder example: loads the real Qwen3-VL vision tower (build(model_id), picks its own device), captures one CUDA graph per rung via torch.compile(reduce-overhead), and in forward_batch pads sum(cost) up to target_bucket, replays, slices the real images back out (CPU). Hardcodes image_token_id via the Qwen base. The author owns padding; Dynamo only picks the rung. `buckets`/`target_bucket` were forward-compat in the contract since PR1; this PR makes them live. Tests: target_bucket rounding (boundary + eager None + buckets-derive + ladder-covers-budget). Graph smoke validated on the integration branch. Deepstack limitation: Qwen3-VL deepstack features are not carried by the one-tensor-per-image contract — this exercises the mechanism, not accuracy. Note: based on the series' validated merge-base; rebase onto main before merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
729398f to
4f361b7
Compare
aa90a19 to
fc9b5d2
Compare
Contributor
Author
|
we don't need this feature for now as it's not requested |
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.
Summary
PR4 of 4 in the custom vision-encoder series, stacked on PR3 (#11037).
Introduces bucket-wise graph support on the Dynamo side and a real graphed
encoder example.
buckets/target_bucketwere defined-but-unused since PR1;this PR makes them live.
What's here
ThreadedMicroBatchergains an optionalbucketsladder. When set, the batcher rounds a batch's packedsum(cost)up to the nearest rung and passes it astarget_buckettofn(items, target_bucket)._validate_bucketsrequiresmax(buckets) >= max_batch_cost.buckets=Nonestays eager (target_bucket=None) — PR3 behavior is unchanged.AsyncVisionEncoderpassesbackend.bucketsto the batcher.Qwen3VLViTEncoderexample — loads the real Qwen3-VL vision tower, captures one CUDA graph per rung viatorch.compile(reduce-overhead)inbuild(), and inforward_batchpadssum(cost)up totarget_bucket(whole dummy images), replays that rung's graph, and slices the real images back out (one tensor per item, input order). This is vLLM'sEncoderCudaGraphManagerscheme — a bounded ladder + pad-to-rung, deliberately not SGLang's per-exact-shape capture.The author owns padding; Dynamo only picks the rung.
Test plan
target_bucketrounding: exact-rung, sub-rung → next rung, eagerNone, and themax(buckets) >= max_batch_costvalidation.[256, 512, 1024, 2048, 4096]; a 5-image batch (cost 1280) padded to the 2048 rung (3 dummy images), replayed, and sliced back to 5(256, hidden)tensors —GRAPH_SMOKE_OK.Known limitation
Qwen3-VL injects per-layer deepstack features that the one-tensor-per-image
contract does not carry, so this example exercises the encoder + batcher + graph
mechanism, not Qwen3-VL accuracy. A contract extension for deepstack-style
auxiliary features is future work.
Note
Based on the series' validated merge-base; rebase onto
mainbefore merge.Stacked series
PR1 (contract) → PR2 (eager, no batcher) → PR3 (ThreadedMicroBatcher) → PR4 (this).
🤖 Generated with Claude Code