Repository navigation
[Quantization] Keep deleted and renamed params registered after process_weights_after_loading - #62407
Merged
simon-mo merged 19 commits intoOct 28, 2026
Merged
Conversation
aoshen02
requested review from
AndreasKaratzas,
LucasWilkinson,
MatthewBonanni,
bnellnm,
dllehr-amd,
mgoin,
pavanimajety,
robertgshaw2-redhat,
shen-shanshan,
tjtanaa,
tlrmchlsmth,
wzhao18,
yewentao256 and
zyongye
as code owners
October 19, 2026 06:53
1 of 6 tasks
aoshen02
force-pushed
the
wu/keep-param-object-del-rename
branch
5 times, most recently
from
October 19, 2026 13:55
e6c81bb to
a693c5e
Compare
Collaborator
|
/ci run |
|
✅ Triggered Buildkite CI #97799 for commit |
Collaborator
|
/ci run |
|
✅ Triggered Buildkite CI #97876 for commit |
hao-aaron
approved these changes
Oct 28, 2026
Collaborator
|
/ci run |
|
✅ Triggered Buildkite CI #98031 for commit |
Contributor
|
Hi @aoshen02, the pre-commit checks have failed. Please run: uv pip install pre-commit>=4.5.1
pre-commit install
pre-commit run --all-filesThen, commit the changes and push to your branch. For future commits, |
… fit check - Humming NVFP4: when Quark has already retired its loaded input_scale_2, write the global input scale into that param instead of aliasing input_global_scale onto the name (which raised ValueError). - RoutedExperts.get_expert_weights: list live params under their runtime names (kernel_parameters), so an aliased checkpoint name such as w13_weight_packed no longer bypasses localized_freed_full_weight_names and retired params are not rearranged by EPLB. - _in_own_storage: only copy into a param whose span is its own elements, so a strided view never overwrites a neighbour in a shared buffer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Aaron Hao <hao-aaron@users.noreply.github.com>
Collaborator
|
/ci run |
|
✅ Triggered Buildkite CI #98047 for commit |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Aaron Hao <hao-aaron@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Aaron Hao <hao-aaron@users.noreply.github.com>
hao-aaron
force-pushed
the
wu/keep-param-object-del-rename
branch
from
October 28, 2026 18:59
9055550 to
93bbe8f
Compare
Collaborator
|
/ci run |
|
✅ Triggered Buildkite CI #98058 for commit |
hao-aaron
added a commit
to hao-aaron/vllm
that referenced
this pull request
Oct 28, 2026
Resolve conflicts with vllm-project#62407 (_in_own_storage) and vllm-project#61457 (kernel_parameters import); both sides kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Aaron Hao <aaronhao@inferact.ai>
6 tasks done
6 tasks done
6 tasks done
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.
Overview
Part 3 of 3 of keeping the loaded parameter objects through
process_weights_after_loading(PWAL). After #62326 and #62405 (both merged), a loaded param can still disappear when PWAL deletes or renames it. This PR keeps those params registered, so after PWAL every loader-visible param is still registered under the same name, as the same object, and keeps its loaded data unless that would cost real memory.Claims
move_parameter(layer, src, dst)registers thesrcparam object underdstas well and recordsdstas its runtime name. The loader writes through the checkpoint name and kernels read the runtime name, both pointing at one storage, so a laterreplace_parameteron either name updates both and no extra memory is used. This covers:*_weight_packed(linear, NVFP4/MXFP4/W4A8 MoE);weight_scale_invtoweight_scale.retire_parameter). This covers:None, which unregistered them. The method now leaves them registered and passesNoneto the MoE quant config.replace_parameter(layer, name, t.new_empty(0))). Their data was converted into a different-layout kernel tensor, so keeping it would double that memory. This covers:qzeros(Conch, CPU, Marlin, Zentorch viaMPLinearKernel._release_unused_zp; int8 scaled-mm; Quark int8 linear and MoE);kv_cache.py, compressed-tensors KV);dispatch_cpu_unquantized_gemmkeepsmain's freshParameter(empty(0))on release, since the released weight can be a tied lm_head shared withembed_tokens.kernel_parameters(layer)returns the live params, each object once under its runtime name.get_live_paramtreats retired or empty params as absent. Humming uses both helpers.<name>_tritonattribute read viatriton_weight(), so it no longer takes over the param name.main, 1786 rows split across the three PRs): 73 delete/rename sites fixed here, plus 36 sites converted together with them (Humming's delete-then-recreate pattern), plus 7 n/a rows inside the changed hunks.Validation
pre-commitpasses.On GB200 (rebased on
main), the tests of every changed file:tests/quantization/(all),tests/model_executor/test_utils.py,model_loader/test_reload.py, and the kernel/MoE/LoRA/model tests that import changed modules: 1609 passed.mainin the same image: Int8 cutlass on SM100, Hopper-only Machete/W4A8, gated repos, DeepGEMM UE8M0int32scales on SM100 (fp8_block_enabled[auto],fp8_pb_wo_checkpoint_setup), qutlass forward, int4 per-token KV kernel, AutoRound MXFP8 MoENotImplementedError, andtest_kv_scale_reload.test_keep_param_objects.pyruns ModelOpt and compressed-tensors NVFP4 linear and MoE with Marlin and Humming forced;test_utils.pycovers aliasing, retiring, and the runtime name.End-to-end on GB200 (before the rebase),
mainvs the stack with this PR. Each run is a cold start with GSM8K (1319 questions, 5-shot), greedy decoding, a byte digest of every post-PWAL tensor, and an object census of loader-visible params:*_weight_packed→*_weight)mainruns agree on about 390 of 1319 GSM8K outputs, so their rows show three runs per arm.Direct load of W1 into the live params (
model.load_weights, no PWAL): every checkpoint name now resolves.main, ModelOpt NVFP4 with Marlin or Humming fails withhas no parameter 'w2_input_scale', and compressed-tensors MXFP4 MoE fails withhas no parameter 'w2_weight_packed'.main; layerwise reload is the supported path.Layerwise reload W0 → W1:
main8/8.Earlier runs of the stack ([Quantization] replace_parameter keeps the parameter object by default #62326) gave
tests/model_executor/model_loader/test_reload.py: 74 passed, 1 failed (test_kv_scale_reload), the same as onmain.Details
layer._parameters, so both alias names are restored, and a param kept empty is never handed to aweight_loader.replace_parameter. Leftovers are skipped if they alias a replaced param, retired if small, and emptied if large.mainuses none.state_dict(), so the UVA offloader and elastic-EP scale-up copy it twice (no data change).weight_scale, AutoGPTQ placeholder MoE biases, and torchao tensor subclasses.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.
AI assistance: prepared with Claude Code; review passes by Codex, Kimi K3 and Claude Fable.
🤖 Generated with Claude Code
Update: loaded storage is never shrunk, emptied or split (0dcd74c..682db58)
A loader-visible param now keeps the checkpoint bytes it had at
create_weightsafter PWAL. Its storage is never emptied. When two names refer to the same bytes, they are registered as one Parameter object. This supersedes the "kept with empty storage" item above for every site that has a plain tensor to back.replace_parametercopies a smaller result into a prefix view of the param's own storage instead of rebinding it to a new, smaller allocation. Results of equal or larger size are still rebound. Online quantization (uses_meta_device) still frees its bf16 source. This covers:w13_weight_scale_2/w13_input_scale([E,2]→[E]);[3]→[1]or scalar: Humming NVFP4weight_scale_2, CT NVFP4weight_global_scale/input_global_scale, FP8input_scale.max());replace_parameter.triton_kernelstensor points at it, so no second copy is kept.move_parameter). This applies when the tensor lives in that param's storage or replaces a large leftover; other leftovers are retired with their data.w13/w2_weight_scaleand NVFP4input_scale_2had over*_weight_scale_inv/input_global_scale.*_weight_packed.wo_apack, CT W4A8 int8 MoE and CT WNA8O8 put the repacked tensor into the loaded param's storage. The K3 gfx942 MXFP4 repack no longer empties its source.scaled_mm/cpu.py) anddispatch_cpu_unquantized_gemm;kv_b_proj;git grepfor release and alias patterns.replace_parameterrows are covered by the shrink rule..datarebinds there keep the same or a larger size, except the two converted above.Census on GB200 (verify-generic-restore census: C1 = storage ≥ checkpoint bytes, C2 = another param or buffer overlapping the bytes). Before = a693c5e; after = 682db58. 4-layer slices; gpt-oss-20b full.
In every config, all loader params are still registered as the same object (
missing=0), and generation works.model_executor/test_utils.py,quantization/test_keep_param_objects.py(now also asserts storage ≥ loaded bytes and no two param objects on one storage),test_moe_wna16,test_zen_da8w4,test_gpt_oss_triton_kernels,test_gfx942_int4,test_auto_round,test_cpu_wna16,test_triton_w4a16,test_cutlass_w4a16,test_reload, and the MXFP4 / scaled-mm kernel selection tests.main: Hopper-only Machete, AutoRound MXFP8 MoE, andtest_kv_scale_reload.pre-commitpasses.main(200/200 vs amainrepeat), accuracy 0.675.🤖 Generated with Claude Code