-
Notifications
You must be signed in to change notification settings - Fork 897
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Lora Block Weight (LBW) to svd_merge_lora.py #1575
Conversation
Thank you for this! This is really nice feature. However, stable-diffusion-webui is licensed under AGPL, and the license for hako-mikan's code is also unclear. So it seems we can't use the code as is in this repository, and we'll need to rewrite it into our own code. In addition, currently we are determining whether it is a v2 model from metadata, but it seems safer to give it as an argument like in your code. However, I think I can make these changes myself, but it will take some time. |
XL対応のLoRAやデータモデル開発を行っている十条と申します。 |
Thanks for the reply. |
I think Lines 719 to 755 in 65b8a06
Or the following function may be able to use for SD1/2: sd-scripts/library/model_util.py Line 675 in de25945
|
Thanks to show me the pointer! |
41357a4
to
b6d633d
Compare
I rewrote the code using the |
Sorry, Please wait a moment while I prepare the conversion code. |
I'm sorry. I was misunderstood about the function. |
I also noticed that Hakomikan's layer selection criteria is to have attention blocks. lora = safetensors.safe_open(r"sdxl.safetensors", framework="pt")
s = []
for key in lora.keys():
if "lora_down" not in key:
continue
if "attn" in key:
m = re.search(r"_(\d+)_(\d)_", key)
if m:
s.append(key[0:m.end()])
print(sorted(list(set(s))))
"""
[
'lora_unet_input_blocks_4_1_',
'lora_unet_input_blocks_5_1_',
'lora_unet_input_blocks_7_1_',
'lora_unet_input_blocks_8_1_',
'lora_unet_output_blocks_0_1_',
'lora_unet_output_blocks_1_1_',
'lora_unet_output_blocks_2_1_',
'lora_unet_output_blocks_3_1_',
'lora_unet_output_blocks_4_1_',
'lora_unet_output_blocks_5_1_'
]
""" So, maybe, BASE has 'encoder', MID has 'middle', and other target layers have 'attn'. Thus, if the key contains strings like 'lora_unet_input_blocks_4_1_', Is it okay to consider this key as the target? alternative implementation |
I think the reason why hakomikan checks only the attention block is to extract only one LoRA key per block, so I don't think we need to worry too much about it.
That's absolutely true. SDXL LoRA keys are based on CompVis (SAI) so they are easy to convert, but SD LoRA keys are based on Diffusers so they are difficult to convert. I believe the below script will give us the correct lbw block index, can you please confirm?
The output should look like this:
|
本件ご対応進めていただいておりますところですが、LoRA同士のマージのほか、XLモデルへのLoRAマージ時(sdxl_merge_lora.py)でもlbws指定ができるとデータモデル開発において大変はかどります。 |
Thank you for correcting the function! It seems to work well. About the |
sdxl_merge_lora.pyでもLBWに対応いたしました。動作をご確認いただければ幸いです。 |
いつもスクリプトにお世話になっております。 現在、素材となる4つのLoRAを、強度・LBWそれぞれ個別にマージして1個の完成形LoRAにまとめようとしています。
これを今回の機能を用いてマージしようとしており、svd_merge_loraへ与える引数はこのようにしています。
これを動作させると、LoRAはできあがるのですが、それを適用した結果が、上記プロンプト(LoRA4個指定)で生成した場合と大きく異なったものになってしまいました。 続いて、SuperMergerを使って、「 このため、lbwsを使った場合の計算結果に何か私の意図しているものと異なる結果が生じる部分があるようなのですが、何かわかることなどはございますでしょうか? |
LBWの値を26個に変換するとき、LoRA Block Weightのコードでは初期値0で指定部のみ値を設定しているようです。 svd_merge_lora.pyの現在の実装では初期値1のようです。 sd-scripts/networks/svd_merge_lora.py Lines 279 to 283 in b755ebd
もしかしたらこの違いかもしれません。試しに26個の値を引数で指定して比較してみていただけますでしょうか。 |
ご確認いただきありがとうございます。 |
lbw26個指定のLoRAを作ってみましたが、出力結果はlbw20個指定で出したものと同じでした。 |
すみません、12個か20個で指定しないとSDXL扱いではなくなるので、block indexがおかしくなりますね。 SuperMergerの"same to Strength"オプションは指定されているでしょうか。こちらが指定されていると、数式が変わってくるようです。 SuperMergerのコードを見ているのですが、非常に難解でちょっと原因がわかりかねています……。 |
他にも旺盛な開発活動をされている中で調査ご対応いただきありがとうございます。 ただ、今回のケース、上述した方法でLBWだけ制限したLoRAを生成する場合、強度は1.0で、1.0だと当該オプションはオンでもオフでも生成されたLoRAの適用結果画像はピクセルパーフェクトで全く同一になるようでした。 |
ありがとうございます。SuperMergerのコードを見ても、ratioが1.0の場合、"same to Strength"がONでもOFFでも、同じ結果になるようです。 となるとsvd_merge_lora.pyのratioの扱いには問題なく、LBWの重みの指定の方に問題がありそうです。 SuperMergerの以下のいずれかにprint文を入れて、値を確認していただくことは可能でしょうか。 以下のように追加していただければ、LoRAのキーごとの、block indexが確認できると思います。
|
かしこまりました。早速ログを取ってみました。(添付) 「AAAA:2:0,0,1,1,1,1,1,1,1,0,0,0」を入力とした場合のデータになります。試しに強度は2.0にしてあります。 |
なお、もし現物データがあったほうがよいようでしたらご提供可能です。 |
ありがとうございます。ログを拝見したところ、input_blocks 1~8が2~9、middleが13、output_blocks 0~8が14~22、というマッピングになっているようですね。このあたりがsvd_merge_lora.pyのLAYER20などの処理で正しく反映されているか、確認してみます。 |
Oops, maybe my mistake. if lbw:
index = get_lbw_block_index(key, is_sdxl)
is_lbw_target = index in LBW_TARGET_IDX
if is_lbw_target:
- scale *= lbw_weights[index] # keyがlbwの対象であれば、lbwの重みを掛ける
+ up_weight *= lbw_weights[index] # lbwの対象であれば、up_weightにlbwの重みを掛ける |
I apologize. I had incorrectly recalled the details of the research that was conducted when I made my tool. |
|
どうもLBWのSDXLのblock indexは値が飛ぶ特殊な番号になっているようです。LBWと一致するように修正してみましたので、お試しいただけますでしょうか。 |
早速最新コミットで試してみました。 |
ちなみに、sdxl_merge_loraでモデルにLoRAをマージする場合についても同様の問題はございましたでしょうか? |
無事に動いたようで幸いです。
block indexを取得する処理が共通ですので、同じ問題があったはずですが、今回の修正で同時に修正されたかと思います。 |
承知しました。引き続き活用させていただきます。 |
追伸ですが、今回修正版でマージしたLoRAは、私の最初の報告の最後の手順(あらかじめSuperMergerで階層だけ制限しておいたLoRAを強度だけ指定でマージ)で作ったLoRAとハッシュが完全一致しておりました。 |
I had added support that lora block weight to svd_merge_lora.py.
--sd2 and--lbws options are added.--sd2 option is used to parse key names from diffusers format to compvis format.(removed)