[Bugfix]: Fix LoRA loading failure for modules with numeric indices (e.g., to_out.0 in Diffusion Transformers) - #35732
Conversation
…_out.0) When loading PEFT LoRA checkpoints targeting modules inside nn.Sequential or nn.ModuleList (e.g., to_out.0), two issues occur: 1. check_unexpected_modules extracts the numeric index '0' as the module suffix instead of the actual module name 'to_out', causing a false ValueError. 2. _get_lora_layer_weights uses exact-match only, so weights stored under 'to_out.0' cannot match the vLLM model's module 'to_out', causing the LoRA weights to be silently ignored. Fix: - Add _get_effective_module_suffix() to correctly resolve numeric indices to their parent module name during validation. - Add get_lora_by_indexed_name() fallback in weight lookup, following the same pattern as the existing pooling-model fallback. Affected models: Diffusion Transformers (Qwen-Image-Edit, Flux, etc.) with nn.ModuleList attention projections.
There was a problem hiding this comment.
Code Review
This pull request addresses a bug that caused LoRA loading to fail for modules with numeric indices, such as those found in nn.Sequential or nn.ModuleList. The fix is well-structured, addressing both the validation and weight lookup failures. A new helper function correctly extracts the effective module suffix, and a fallback mechanism is added to locate LoRA weights for indexed modules. The changes are accompanied by a comprehensive set of new tests that cover the new logic and various edge cases. The implementation appears correct and effectively resolves the issue.
|
Hi @Wang-Shengyuan, the pre-commit checks have failed. Please run: uv pip install pre-commit
pre-commit install
pre-commit run --all-filesThen, commit the changes and push to your branch. For future commits, Tip Is
|
|
Could you please provide the reproduce script? |
|
Thank you for your reply! The reproduce script can be like with configs |
|
The lora adapter is trained with peft in a standard practice. The architecture of the adapter is as follows ( |
|
Hi @Wang-Shengyuan, the pre-commit checks have failed. Please run: uv pip install pre-commit
pre-commit install
pre-commit run --all-filesThen, commit the changes and push to your branch. For future commits, Tip Is
|
|
This pull request has been automatically marked as stale because it has not had any activity within 90 days. It will be automatically closed if no further activity occurs within 30 days. Leave a comment if you feel this pull request should remain open. Thank you! |
|
This pull request has been automatically closed due to inactivity. Please feel free to reopen if you intend to continue working on it. Thank you! |
#35734
Describe the bug
When loading a PEFT LoRA checkpoint that targets modules inside
nn.Sequentialornn.ModuleList(e.g.,to_out.0), vLLM has two related failures:check_unexpected_modulesraisesValueError, incorrectly treating the module as unexpected._get_lora_layer_weightscannot match the LoRA weight keyto_out.0to the vLLM model's module nameto_out, so the LoRA weights are silently ignored.Error message (failure 1)
Root cause
Validation (
lora_model.py,check_unexpected_modules):For
transformer_blocks.0.attn.to_out.0,rsplit(".", 1)[-1]returns"0", which is the numericModuleListindex — not the actual module nameto_out.Weight lookup (
model_manager.py,_get_lora_layer_weights):The lookup is exact-match only. When the LoRA checkpoint stores weights under
to_out.0but the vLLM model registers the layer asto_out, the lookup fails and returnsNone.How to reproduce
Affected models
Any model where LoRA targets a layer inside
nn.Sequential/nn.ModuleList:attn.to_out = ModuleList([Linear, Dropout])nn.Sequential(Linear, ...)Model structure reference
Expected behavior
LoRA should load and be applied successfully. When the module suffix is a numeric index, vLLM should resolve it to the parent module name.
Workaround
Manually rename
to_out.0→to_outin the saved checkpoint weight keys — error-prone and inconvenient.Root Cause
When PEFT trains a LoRA on a layer inside
nn.ModuleList, the weight key includes a numeric index (e.g.,to_out.0.lora_A.weight). Afterparse_fine_tuned_lora_name, the module name becomestransformer_blocks.0.attn.to_out.0.Problem 1 – Validation:
Problem 2 – Weight lookup:
Changes
vllm/lora/lora_model.py_get_effective_module_suffix(new static method) — Extracts the effective module suffix. When the last segment is purely numeric, returns the parent segment instead.get_lora_by_indexed_name(new method) — Searches for LoRA weights stored under{module_name}.{digit}. Used as a fallback when exact-match lookup fails.check_unexpected_modules— Replaced inline suffix extraction with_get_effective_module_suffix.vllm/lora/model_manager.py_get_lora_layer_weights— Added indexed-name fallback after exact match, following the same pattern as the existing pooling-model fallback.