Skip to content

Fix LoRA loading for flattened CLIP text encoders - #14872

Merged
sayakpaul merged 2 commits into
huggingface:mainfrom
BeyondBirthday07:fix-lora-loading
Sep 28, 2026
Merged

sayakpaul merged 2 commits into
huggingface:mainfrom
BeyondBirthday07:fix-lora-loading

Conversation

@BeyondBirthday07

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes #14860

CLIPTextModel is flattened in newer transformers versions, so its module names no longer start with text_model.. Older LoRA checkpoints can still contain this prefix.

Because of that, the text encoder rank lookup does not find the LoRA keys, leaving rank empty and causing an IndexError.

This strips the text_model. prefix when loading into a flattened text encoder.

Added a regression test for this case. I also tested the fix with the LoRA checkpoint shared in #14860.

No new dependencies.

Tests

python -m pytest tests/lora/test_peft_utils.py tests/lora/test_lora_loader_utils.py -q
python -m ruff check src/diffusers/loaders/lora_base.py tests/lora/test_lora_loader_utils.py
python -m ruff format --check src/diffusers/loaders/lora_base.py tests/lora/test_lora_loader_utils.py

Before submitting

  • Did you use an AI agent (Claude Code, Codex, Cursor, etc.) to help with this PR? If so:
    • Did you read the Coding with AI agents guide?
    • Did you run the self-review skill on the diff?
    • Did you share the final self-review notes in the PR description or a comment?
  • Did you read the contributor guideline?
  • Did you read our philosophy doc? (important for complex PRs)
  • Was this discussed/approved via a GitHub issue or the forum? Please add a link to it if that's the case.
  • Did you make sure to update the documentation with your changes? Here are the
    documentation guidelines, and
    here are tips on formatting docstrings.
  • Did you write any new necessary tests?
  • Are you the author (or part of the team) of the model/pipeline (only applicable for model/pipeline related PRs)?

Who can review?

Anyone in the community is free to review the PR once the tests have passed. Feel free to tag
members/contributors who may be interested in your PR.

@sayakpaul @BenjaminBossan

@github-actions github-actions Bot added fixes-issue lora tests size/S PR with diff < 50 LOC and removed fixes-issue labels Sep 25, 2026
Comment thread src/diffusers/loaders/lora_base.py
"text_encoder.text_model.encoder.layers.0.self_attn.q_proj.lora_B.weight": lora_b,
}

StableDiffusionLoraLoaderMixin.load_lora_into_text_encoder(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, a test should be closer to how a user would load such a checkpoint via a pipeline, using the mixin class directly is not normally done. If the maintainers are fine with this, I won't object though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree with you, @BenjaminBossan. However, internally, the call gets dispatched to load_lora_into_text_encoder from load_lora_weights(). So, seems okay to me as a minimal and self-contained use case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I kept the test at the loader level since load_lora_weights() ends up calling the same path anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, internally, the call gets dispatched to load_lora_into_text_encoder from load_lora_weights(). So, seems okay to me as a minimal and self-contained use case.

Your call, Sayak, so if you're fine with this, I have no complaint. Personally, I'd prefer the tests not to rely on implementation details and go through the same motions as the user, but I can't tell how much more complex it would require to make the test to achieve the same coverage, so the tradeoff might be worthwhile.

@BenjaminBossan BenjaminBossan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers from my side, thanks for the PR.

@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rank_dict.values() list index out of range in diffuser v0.40

4 participants