-
Notifications
You must be signed in to change notification settings - Fork 907
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
SD1.5のlora学習の際に--network_train_unet_onlyを指定すると、unetのdown側(IN1〜IN8)のlora_up.weightの値が0になる #821
Comments
lora_upの重みの初期値は0のため、場合によっては0のままとなることは起こりえるようです(学習データが単純な場合、またはステップ数が少ない場合、fp16の場合など)。 こちらでは同一の条件(U-Netのみの学習、gradient checkpointing有効)でも、IN1~IN8は学習されているようでした。 可能なら、floatまたはbf16にしていただく、または他のデータで試すなどしてお試しいただけますでしょうか。 |
確認ありがとうございます。こちらのほうでも追加で検証してみました。 まず、Google Colabのほうで、先に報告した例をfloatで試してみましたが、問題は再現しました。つまり、 次に、 bf16では試していませんが、floatでも問題が再現したので、値の絶対値が小さ過ぎて0に押し潰されたわけではなさそうですし、訓練データが単純だったから零行列になったというわけでもなさそうに思われます。 今回報告している検証の範囲では、高々610ステップしか試していませんが、この問題自体は私が最近まで気付いていなかっただけで、私が初めてunetのみで訓練した今年の6月頭の時点で発生していたようでした。このとき概算で5000ステップほど実行していたようなので、ステップ数の問題でもないように思われます。なお、このときは、推論結果だけを見てもIN1〜IN8のlora_upの値が零になっていることには気付きませんでした。この5000ステップの例ではないのですが、 一方で、kohyaさんのほうでは問題が再現しなかったということなので、環境の問題を疑い、まずGoogle Colabのほうで神経質にバージョンを合わせて確認してみました(pythonのバージョンを 3.10.6に合わせて、torch==1.12.1+cu116 torchvision==0.13.1+cu116 を使用し、xformersのバージョンを気にしたくないので--xformersを無効にし、bitsandbytesのバージョンを気にしたくないので--optimizer_type=AdamWを使いました)が、結果は変わらず、問題は再現しました。 Google Colabのほうではこれ以上できることはないと思い、仕方ないので、Windowsのほうでも検証してみました。 なお、このときは、accelerate config でCPU onlyを選び、 mixed precisionはnoにし、
を実行し、--gradient_checkpointing無しのときは
を実行しました。訓練データには最初の報告で使ったカエルの画像を1枚だけ使い、4ステップだけ実行しましたが、 結果も貼り付けておきます。--gradient_checkpointing有りの場合は、IN1〜IN8に相当するlora_unet_downで始まる行のテンソルの絶対値の最大値が0になっているにもかかわらず、--gradient_checkpointing無しの場合は、対応する個所が非0の値になっていることに着目ください。MIDおよびOUT3〜OUT11の値も載せています。lora_downのほうの値は載せていません。 --network_train_unet_only かつ --gradient_checkpointing有りの場合、
--network_train_unet_only かつ --gradient_checkpointing無しの場合、
以上をまとめますと、私が確認した限り(Google Colab T4およびWindowsのCPUでの実行の範囲では)、
という結果が再現し、それはfp16の問題や、訓練データの問題、ステップ数の問題ではないように思われますし、環境の問題だとも言い切れないように思います。 ただ、kohyaさんのほうで問題が再現されないというのであれば、私は--network_train_unet_onlyを--gradient_checkpointingと併用しさえすれば問題が再現すると思ったのですが、もしかしたら条件の指定が不足しているのかもしれません。 以下、雑多な補足情報です。
|
詳細に追加検証いただき、ありがとうございます。再度確認したところ手元のSDXL版のLoRAで検証しておりました。失礼いたしました。時間が取れ次第、SD1.5で同一条件で確認しいたします。 お手数をお掛けし、大変申し訳ありません。よろしくお願いいたします。 |
SD1.5で確認したところ、お書きいただいた事象が再現できました。ご確認にお手を煩わせてしまい申し訳ありませんでした。 まったく学習できないか、エラーが発生するならまだしも、IN1〜IN8だけ学習できない原因は不明ですが、U-Netの最初のパラメータに対して mainブランチを更新することも可能ですが、sdxlブランチに対して修正を行い、mainブランチにマージすることで対応したいと思います。 よろしくお願いいたします。 |
#846 で対応し、mainにもマージ済みです。ご確認いただければ幸いです。報告が遅くなり申し訳ありません。よろしくお願いいたします。 |
最初に報告した例について、問題が解消されていることを確認しました。対応ありがとうございました。 |
SD1.5のlora学習の際、--network_train_unet_onlyを指定してunetだけトレーニングしたときに、unetのdown側(IN1〜IN8)のlora_up.weightの値が全て0になっている(零行列になっている)ことに気づきました。
私の理解では、loraは、二つに分解した行列を乗算して計算に使っていると思うのですが、ここで一方の行列が零だと、掛けた結果も零になり、結局このloraは、unetのdown側(IN1〜IN8)が何も学習されていないのと同じ状態になっているのかなと思います。
こちら側で検証してみた結果、どうも、--network_train_unet_onlyを--gradient_checkpointingと併用するとこの現象が発生するようでした。
検証に使った内容は以下の通りです。
実行結果は以下の通りになります。
--gradient_checkpointingの有無によって結果が変わるので、この部分の処理に何かしらの不具合があるのではないかと思います。
何か抜けや間違い、勘違い等がありましたらすみません。
The text was updated successfully, but these errors were encountered: