Repository navigation
[Model] Support every Decision 3.0 size (d3-flash, d3-mini, d3-nano, d3-lite, d3-edge) - #61778
Conversation
…d3-lite, d3-edge) d3-nano ships its backbone as a single model.safetensors without a weight index, so the default loader also read readout.safetensors in the backbone pass and stopped on its root `weight` tensor. D3ForSequenceClassification now marks that tensor unused, so the shard is skipped there; the readout still loads as the score head through secondary_weights. Test d3-nano next to d3-edge, and list every size in the test registry and the docs. Signed-off-by: Xunzhuo Liu <xunzhuo.liu@amd.com>
|
Documentation preview: https://vllm--61778.org.readthedocs.build/en/61778/ |
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
|
/ci run |
|
❌ @Xunzhuo, A reviewer with write access must run |
|
Thanks @noooop , anyone can take a look at vllm-project/recipes#1124? |
|
/ci run --allow-stale |
|
✅ Triggered Buildkite CI #95083 for commit
|
|
looks like some flaky tests met again |
…d3-lite, d3-edge) (vllm-project#61778) Signed-off-by: Xunzhuo Liu <xunzhuo.liu@amd.com>
Overview
Make every Decision 3.0 model work in vLLM:
vllm serve vllm-sr/d3-nanostopped while loading weights, and d3-flash, d3-lite, d3-mini and d3-edge had no published validation on current vLLM. Follow-up to #61565, which added Decision 3.0 and validated d3, d3-mini and d3-edge; its "Follow-ups" section promised this PR.Claims
model.safetensorsand no weight index, so the default loader also readreadout.safetensorsas a backbone file and stopped withValueError: There is no module or parameter named 'weight' in D3ForSequenceClassification.D3ForSequenceClassificationnow names the readout's only tensor inis_unused_checkpoint_weight, so the backbone pass skips that file; the readout still loads as the FP32scorehead throughsecondary_weights.vllm serve vllm-sr/<model>and no flags, on one AMD Instinct MI300X: 0 to 2 of 416 decisions changed per model, all near-ties (the reference's two most likely answers within 0.015 of each other), with a median probability difference of 0.003 (table below).Validation
Setup: one AMD Instinct MI300X (ROCm 7.2), a new
rocm/dev-ubuntu-24.04:7.2.3-completecontainer with empty caches. vLLM is the ROCm nightly wheel0.32.0rc1.dev190+g3f1bcfd82(it contains #61565, and every file on the Decision 3.0 path is identical tomain) with this PR'sd3.pycopied over the installed one; no kernels were built. The reference is the checkpoint's own runtime,AutoModel.from_pretrained(..., trust_remote_code=True), with the versions itsrequirements.txtpins (torch 2.13.0+rocm7.1, transformers 5.17.0, flash-linear-attention 0.5.2), in its own venv on the same GPU. Checkpoints at their currentmain:vllm-sr/d3-edge@ cab71e6a,vllm-sr/d3-lite@ 9c107031,vllm-sr/d3-nano@ aeb70d4d,vllm-sr/d3-mini@ 97dd054d,vllm-sr/d3-flash@ 8b35c853.Reproducer: in the same container, the unchanged nightly fails on d3-nano and this PR loads it:
Answers vs the reference: the same 416 questions as #61565 (3 states x 128 typed questions, 1-, 4- and 16-question text, a 4-question JSON state, a 40-option choice, an image with 1 and 4 questions, and a 10 s 1080p video). The decision is the top choice,
noul >= 0.5, or a score's most likely level; |dp| is the largest absolute probability difference over a question's options.Throughput: closed loop, 20 s per level after an 8 s warm-up, over the mix of #61565 (40 % one-question text, 20 % four-question text, 10 % four-question JSON, 10 % 40-option choice, 15 % new 1.6 MP image, 5 % new 10 s 1080p video; every image and video carries new bytes). The checkpoint server is the package's
d3_server.py(AutoModel behind HTTP). Each cell gives req/s and p50 / p90 latency in ms:Start-up: vLLM's launch to the first answer from empty caches, the model download included: 132 to 172 s (d3-edge 140 s, d3-lite 136 s, d3-nano 132 s, d3-mini 163 s, d3-flash 172 s).
Tests
pytest tests/models/multimodal/pooling/test_d3.py(MI300X, this PR):[vllm-sr/d3-edge]PASSED,[vllm-sr/d3-nano]PASSED (2 passed in 270 s). Without this PR, d3-nano fails at load as in the reproducer.pytest tests/config/test_model_arch_config.py tests/models/test_registry.py tests/entrypoints/generate/structured_decisions/test_strategies.py -k "decision_config or joint_head or D3 or d3 or strategy_selection"(MI300X, this PR): 13 passed.DefaultModelLoader.get_all_weightson a d3-nano-like layout (model.safetensorswith backbone tensors plusreadout.safetensors, no index): on main the backbone pass yields the readout's rootweight; with this PR it yields only the backbone tensors, andscore.weightstill comes fromsecondary_weights.test_d3.py[vllm-sr/d3-edge]and[vllm-sr/d3-nano]PASSED; the d3-nano run logsSkipped 1/2 safetensors shard(s) holding no weights the model loads.pre-commit run --from-ref origin/main --to-ref HEAD: all hooks pass (actionlint skipped locally; no workflow files changed).Details
model.safetensors.index.json,DefaultModelLoader._prepare_weightskeeps every*.safetensorsfile of the repo (filter_duplicate_safetensors_filesreturns them all when the index is missing), soreadout.safetensors({weight: [255, hidden]}) joins the backbone pass. Its root keyweightmatches no module, andAutoWeightsLoaderraises. The other five checkpoints ship an index that lists only the backbone shards, so the index filter already drops the readout there. d3-nano is the only Decision 3.0 repo without an index.is_unused_checkpoint_weightis the existing hook the default loader passes tofilter_safetensors_files_by_weight_namefor the primary weights only; it drops a safetensors file when every tensor in it is unused. The readout file holds a single tensor namedweight, which no backbone checkpoint has at the root. Its ownsecondary_weightssource sets no such rule and keeps loading it under thescore.prefix. For indexed checkpoints nothing changes beyond reading the shard headers, which the loader already does for pooling models (their protocol default returns False).allow_patterns_overrides=["model*.safetensors"]would also skip the index filter and depend on file names; adding an index to the Hub repo fixes only that copy of the checkpoint.test_d3.pyruns in the optional "Multimodal Models (Extended Pooling)" step; d3-nano adds a 4.5 GB checkpoint there. d3-lite, d3-mini and d3-flash take the same code path as d3-edge and d3-nano and are covered by the measurements above rather than CI, to keep the step's downloads and run time small.vllm-sr/d3, d3-nano,D3ForSequenceClassification,decision_config); [Model] Support Decision 3.0 decision models (vllm-sr/d3) #61565 is merged.Pull Request Checklist
I used vLLM's
/pr-checklistskill. (Mandatory for agents, optional for humans).AI assistance was used during the creation of this PR.
Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.
Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.
Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.
Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.