You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Per-module alphas of kohya text encoder LoRAs collapse to the most common alpha (alpha_pattern keys stop at the parent module) #14970
When a kohya-format SDXL/SD1.5 LoRA has different .alpha values across text encoder modules, every text encoder module ends up with the most common alpha. The minority modules get the wrong scale.
get_peft_kwargs builds the text encoder alpha_pattern with ".".join(k.split(".down.")[0].split(".")[:-1]) (peft_utils.py#L189). For a network alpha key such as text_model.encoder.layers.1.self_attn.to_k_lora.down.weight.alpha, that yields text_model.encoder.layers.1.self_attn, which is the parent attention block and not the k_proj module. PEFT's get_pattern_key matches pattern keys against the end of the module name, so the key matches no LoRA module and the default lora_alpha (the most common value) applies everywhere.
The UNet branch keeps the module name, so the UNet is not affected. The same result occurs with a text encoder that still has the text_model level (e.g. CLIPTextModelWithProjection), so this is independent of #14872.
For scale: in a library of ~8.9k SDXL kohya LoRAs, 59 have per-module text encoder alphas (values from 0.5 to 6 at the same rank, mostly character LoRAs), so their text encoder modules can be off by up to 12x.
Reproduction
importtorchfromdiffusersimportStableDiffusionXLPipelinefromtransformersimportCLIPTextConfig, CLIPTextModelconfig=CLIPTextConfig(
hidden_size=8, intermediate_size=16, num_hidden_layers=2, num_attention_heads=2,
vocab_size=50, max_position_embeddings=8, bos_token_id=0, eos_token_id=1, pad_token_id=1,
)
text_encoder=CLIPTextModel(config)
rank=4defkohya_module(name, alpha):
return {
f"lora_te1_text_model_{name}.lora_down.weight": torch.ones(rank, 8),
f"lora_te1_text_model_{name}.lora_up.weight": torch.ones(8, rank),
f"lora_te1_text_model_{name}.alpha": torch.tensor(alpha),
}
# Two modules with alpha 1.0 (the most common value) and one with alpha 4.0.lora= {
**kohya_module("encoder_layers_0_self_attn_q_proj", 1.0),
**kohya_module("encoder_layers_0_self_attn_out_proj", 1.0),
**kohya_module("encoder_layers_1_self_attn_k_proj", 4.0),
}
state_dict, network_alphas=StableDiffusionXLPipeline.lora_state_dict(lora)
StableDiffusionXLPipeline.load_lora_into_text_encoder(
state_dict, network_alphas, text_encoder=text_encoder, prefix="text_encoder", adapter_name="test"
)
k_proj=text_encoder.encoder.layers[1].self_attn.k_projprint("k_proj scaling:", k_proj.scaling["test"], "expected:", 4.0/rank)
print("peft alpha_pattern:", text_encoder.peft_config["test"].alpha_pattern)
Thanks, @sayakpaul! Since #14972 already fixes it and I verified it against the reproduction (see my comment there), I'm happy for that one to go ahead. I'll take you up on the offer for the next one.
Activity
sayakpaul commentedon Oct 6, 2026
Thanks for the report! Would you like to contribute a fix? If so, feel free to also propose the fix, so that we can discuss.
akhil9tiet commentedon Oct 6, 2026
I'd like to work on this — please assign it to me. I'll open a PR shortly.
sayakpaul commentedon Oct 7, 2026
@akhil9tiet please at least wait for @andre-menutole to reply.
andre-menutole commentedon Oct 7, 2026
Thank you, @sayakpaul and @akhil9tiet! Next time, I'll try to contribute a fix too!
sayakpaul commentedon Oct 7, 2026
You are welcome to contribute the fix for this too because you are the one that analyzed the issue and reported it.
andre-menutole commentedon Oct 7, 2026
Thanks, @sayakpaul! Since #14972 already fixes it and I verified it against the reproduction (see my comment there), I'm happy for that one to go ahead. I'll take you up on the offer for the next one.
akhil9tiet commentedon Oct 8, 2026
@sayakpaul apologies. Next time I'll wait.