メむンコンテンツぞスキップ
芋出し画像

Stable Diffusionモデルの砎損チェックず修埩に぀いお

    1. 抂芁

     以前より、䞀郚のStable Diffusionモデルにおいお「䞀郚のトヌクンが無芖されるバグ」、぀たり内郚デヌタの砎損があるずいう情報を耳にしおいたした。その埌、同様のモデルが他にも耇数存圚するずこずが刀明したので、本蚘事におチェックず修埩の手順を説明したす。ファむル圢匏は、「.ckpt」ず「.safetensors」のどちらにも察応しおいたす。

    参考情報

     本蚘事では手順しか説明したせんので、なるべく䞋蚘の蚘事を参照しお内容を確認しおください。


    2. 修埩の手順(1)

     先に、本蚘事ずは別の方法を玹介したす。

     AUTOMATIC1111氏のStable Diffusion web UI䞊の拡匵機胜で、砎損モデルを修埩するこずが可胜です。修埩のほか、剪定圧瞮やVAEの同梱もできるstable-diffusion-model-toolkitの利甚手順は、䞋蚘の蚘事を参照しおください。


    3. 砎損チェックの手順

     PC䞊で、AUTOMATIC1111氏のStable Diffusion web UI以䞋、web UIが利甚できるこずを前提ずしたす最近リリヌスされたWindows専甚版は陀倖。利甚開始たでの手順は、䞋蚘の蚘事にお玹介しおいたす。

    実行ファむルの準備

     たず、先に玹介した蚘事の#3から「fix_postion_ids.py」をダりンロヌドしお、適圓なディレクトリに眮いおください。私の蚘事を芋おそのたた構築された方は「\aiwork」で構いたせん。

     次に、同じディレクトリに、䞋蚘の内容でバッチファむルを䜜っおください。ファむル名は短くお打ちやすいものが良いでしょう。私は「chk.bat」にしたした。

    @echo off
    python fix_position_ids.py --model %1 --verbose

    web UIの仮想環境に切り替える

     コマンド プロンプトを開いおください。䞋蚘の䟋を参考に、web UIの仮想環境に入っおください。ディレクトリが異なる堎合は適宜倉曎しおください。バッチファむルを䜜っおおくのも良いでしょう。

    cd \aiwork
    stable-diffusion-webui\venv\Scripts\activate

     䞊蚘のコマンドを実行埌、先頭に「(venv)」の文字が付いおいれば倧䞈倫です。バッチファむルを眮いた堎所が異なる堎合は、ここで移動しおください。

    チェックの実行

    ★ディレクトリ名やファむル名に、半角スペヌスや特殊な文字が含たれおいるず正しく実行できたせん。お手数をかけたすが䞀時的に修正しおください。

     先ほどのバッチファむルの名前「chk」等を入れお、半角スペヌスを1぀入れお、チェックしたいモデルのファむルをコマンド プロンプトのりむンドりにドラッグドロップしおください。䞋蚘のような圢でファむルのフルパスが入るので、Enterキヌを抌しおください。

    (venv) C:\aiwork>chk C:\aiwork\stable-diffusion-webui\models\Stable-diffusion\sd-v1-4-full-ema.ckpt

     Enterを抌した時に「このファむルを開く方法を」の衚瀺が出おしたった堎合はそれを無芖しお、コマンド プロンプトのりむンドりでダブルクリックしおから、改めおEnterを抌しおください。

    チェック結果の衚瀺正垞

     䞋蚘は、実際の実行結果です。砎損が無い堎合はこのような衚瀺になり、芋た目もすっきりしおいたす。実際のデヌタは、䞀番䞊の「current data」の郚分のみです。倀の型がint64であるこずも、ある意味重芁です。

    loading ... sd-v1-4-full-ema.ckpt
    # current data is:
    tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
             18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
             36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
             54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
             72, 73, 74, 75, 76]])
    <class 'torch.Tensor'>
    torch.Size([1, 77])
    torch.int64
    # == if changed to torch.int64 ==
    <class 'torch.Tensor'>
    tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
             18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
             36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
             54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
             72, 73, 74, 75, 76]])
    torch.int64
    # change to:
    tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
             18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
             36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
             54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
             72, 73, 74, 75, 76]])
    <class 'torch.Tensor'>
    torch.int64
    #
    tensor([[True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True]])

    チェック結果の衚瀺砎損

     次に、砎損の報告が䞊がっおいる「Elysium_Anime_V3.safetensors」の堎合です。それぞれの配列の意味は䞊から順に、モデルが持぀倀本䟋では型がfloat32、実利甚時に䜿甚される倀int64に倉換した敎数、本来あるべき倀固定、䜿甚される倀ず本来の倀の正誀、ずなっおいたす。たた、倀がずれおいる誀の刀定の䜍眮ず、倱われた倀が末尟に瀺されおいたす。倱われた倀の䜍眮にあるトヌクンは無芖されたす。重耇した倀の䜍眮にあるトヌクンの扱いに぀いおは䞍明です。

    loading ... Elysium_Anime_V3.safetensors
    # current data is:
    tensor([[ 0.0000,  1.0000,  2.0000,  2.9995,  3.9999,  4.9985,  5.9990,  6.9994,
              7.9999,  9.0004,  9.9971, 11.0013, 11.9979, 13.0021, 13.9988, 15.0031,
             15.9998, 16.9965, 18.0007, 19.0049, 19.9942, 20.9984, 22.0025, 23.0068,
             23.9958, 25.0000, 26.0042, 26.9935, 27.9976, 29.0019, 30.0061, 30.9954,
             31.9996, 33.0037, 33.9930, 35.0121, 36.0015, 36.9907, 38.0098, 38.9991,
             39.9884, 41.0074, 41.9967, 42.9861, 44.0051, 44.9944, 46.0137, 47.0028,
             47.9917, 49.0107, 50.0000, 50.9897, 52.0084, 52.9983, 53.9869, 55.0066,
             55.9953, 56.9852, 58.0039, 58.9935, 60.0122, 61.0019, 61.9908, 63.0102,
             63.9991, 64.9880, 66.0075, 67.0262, 67.9860, 69.0047, 70.0242, 70.9832,
             72.0030, 73.0214, 73.9815, 75.0000, 76.0197]])
    <class 'torch.Tensor'>
    torch.Size([1, 77])
    torch.float32
    # == if changed to torch.int64 ==
    <class 'torch.Tensor'>
    tensor([[ 0,  0,  1,  2,  3,  4,  5,  6,  7,  9,  9, 11, 11, 13, 13, 15, 15, 16,
             18, 19, 19, 20, 22, 23, 23, 25, 26, 26, 27, 29, 30, 30, 31, 33, 33, 35,
             36, 36, 38, 38, 39, 41, 41, 42, 44, 44, 46, 47, 47, 49, 50, 50, 52, 52,
             53, 55, 55, 56, 58, 58, 60, 61, 61, 63, 63, 64, 66, 67, 67, 69, 70, 70,
             72, 73, 73, 74, 76]])
    torch.int64
    # change to:
    tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
             18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
             36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
             54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
             72, 73, 74, 75, 76]])
    <class 'torch.Tensor'>
    torch.int64
    #
    tensor([[ True, False, False, False, False, False, False, False, False,  True,
             False,  True, False,  True, False,  True, False, False,  True,  True,
             False, False,  True,  True, False,  True,  True, False, False,  True,
              True, False, False,  True, False,  True,  True, False,  True, False,
             False,  True, False, False,  True, False,  True,  True, False,  True,
              True, False,  True, False, False,  True, False, False,  True, False,
              True,  True, False,  True, False, False,  True,  True, False,  True,
              True, False,  True,  True, False, False,  True]])
    corrupt token indexes : [1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 17, 20, 21, 24, 27, 28, 31, 32, 34, 37, 39, 40, 42, 43, 45, 48, 51, 53, 54, 56, 57, 59, 62, 64, 65, 68, 71, 74, 75]
    missing token numbers : [8, 10, 12, 14, 17, 21, 24, 28, 32, 34, 37, 40, 43, 45, 48, 51, 54, 57, 59, 62, 65, 68, 71, 75]

     2番目の「1.0000」を敎数に倉換するず「0」になるのは䞍思議な気がしたすが、小数を4桁に䞞めた際に繰り䞊がっおしたったのかもしれたせん。


    4. 修埩の手順

     同じスクリプトを䜿甚しお修埩する堎合は、䞋蚘の内容でバッチファむルを䜜成しおファむル名は「fix.bat」など、チェックの時ず同じように実行しおください。䞊曞きの確認は無いので泚意しおください。

    @echo off
    python fix_position_ids.py --model %1 --out %~dp1%~n1_fix%~x1

    修埩を行う

    ★ディレクトリ名やファむル名に、半角スペヌスや特殊な文字が含たれおいるず正しく実行できたせん。お手数をかけたすが䞀時的に修正しおください。

     実行䟋です。「Elysium_Anime_V3.safetensors」を入力しお、同じディレクトリに「Elysium_Anime_V3_fix.safetensors」を出力しおいたす。

    (venv) C:\aiwork>fix C:\aiwork\stable-diffusion-webui\models\Stable-diffusion\Elysium_Anime_V3.safetensors
    loading ... Elysium_Anime_V3.safetensors
    # change to:
    tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
             18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
             36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
             54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
             72, 73, 74, 75, 76]])
    <class 'torch.Tensor'>
    torch.int64
    #
    tensor([[ True, False, False, False, False, False, False, False, False,  True,
             False,  True, False,  True, False,  True, False, False,  True,  True,
             False, False,  True,  True, False,  True,  True, False, False,  True,
              True, False, False,  True, False,  True,  True, False,  True, False,
             False,  True, False, False,  True, False,  True,  True, False,  True,
              True, False,  True, False, False,  True, False, False,  True, False,
              True,  True, False,  True, False, False,  True,  True, False,  True,
              True, False,  True,  True, False, False,  True]])
    corrupt token indexes : [1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 17, 20, 21, 24, 27, 28, 31, 32, 34, 37, 39, 40, 42, 43, 45, 48, 51, 53, 54, 56, 57, 59, 62, 64, 65, 68, 71, 74, 75]
    missing token numbers : [8, 10, 12, 14, 17, 21, 24, 28, 32, 34, 37, 40, 43, 45, 48, 51, 54, 57, 59, 62, 65, 68, 71, 75]
    Saving...

     出力されたファむルをチェックしおみるず、正垞な倀になったこずが分かりたす。

    (venv) C:\aiwork>chk C:\aiwork\stable-diffusion-webui\models\Stable-diffusion\Elysium_Anime_V3_fix.safetensors
    loading ... Elysium_Anime_V3_fix.safetensors
    # current data is:
    tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
             18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
             36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
             54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
             72, 73, 74, 75, 76]])
    <class 'torch.Tensor'>
    torch.Size([1, 77])
    torch.int64
    # == if changed to torch.int64 ==
    <class 'torch.Tensor'>
    tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
             18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
             36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
             54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
             72, 73, 74, 75, 76]])
    torch.int64
    # change to:
    tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
             18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
             36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
             54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
             72, 73, 74, 75, 76]])
    <class 'torch.Tensor'>
    torch.int64
    #
    tensor([[True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True, True, True, True, True, True, True, True,
             True, True, True, True, True]])

    修埩モデルの泚意点

     モデルを修埩したこずでプロンプトの扱いが倉化し、砎損モデルずは異なる出力が埗られるこずがありたす元の砎損具合ず䞎えるプロンプトに䟝存したす。留意の䞊でご利甚ください。たた、砎損モデルを砎棄する堎合は、修埩モデルが正しく利甚できるこずを確認しおから行っおください。

    終了の方法

     りむンドりをおもむろに閉じおも問題ないず思いたすが、仮想環境から抜ける方法も芚えおおいおください。

    deactivate

     䞊蚘のコマンドを実行するだけです。


    5. 各モデルのチェック結果

     䞋蚘の蚘事にお、実際にチェックした結果を蚘茉しおいたす。内容は曎新される堎合がありたす。


    6. おたけ

     実際に䜿っおいるスクリプトです。チェックに䜿甚するバッチファむルを䞋蚘の内容に倉曎するず、チェックしたファむルず同じディレクトリに結果を出力したす。certutilの出力が想定ず異なる堎合はハッシュ倀以倖のメッセヌゞも含たれおしたうので、findstrの凊理指定した文字が含たれる行を砎棄を修正しおください。

    @echo off
    echo %~n1%~x1 > %~dp1%~n1%~x1.txt
    certutil -hashfile %1 SHA256 | findstr /v コマンドは | findstr /v ハッシュ >> %~dp1%~n1%~x1.txt
    echo. >> %~dp1%~n1%~x1.txt
    python fix_position_ids.py --model %1 --verbose | findstr /v loading >> %~dp1%~n1%~x1.txt
    おたけの远加チェック結果の抂芁を衚瀺したす。お奜みで䞊蚘のコヌドに足しおください。
    echo.
    echo result of %~n1%~x1
    type %~dp1%~n1%~x1.txt  | findstr torch.float | findstr /v dtype
    type %~dp1%~n1%~x1.txt  | findstr token

     出力ファむルは、チェックしたファむル名に「.txt」を付加したファむル名で、内容は䞋蚘䟋のように「ファむル名、SHA256、チェック結果」です。

    testdata.ckpt 
    0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
     
    # current data is:
    tensor([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
    略
    おたけの远加を足した堎合、砎損モデルでは䞋蚘のような衚瀺が出たす。
    result of testdata.ckpt
    torch.float32
    corrupt token indexes : [7, 14, 25, 28, 29, 31, 50, 53, 56, 58, 59, 61, 62]
    missing token numbers : [7, 14, 25, 29, 31, 50, 53, 56, 59, 62]

    ★し぀こく曞きたすが、ディレクトリ名やファむル名に、半角スペヌスや特殊な文字が含たれおいるず正しく実行できたせん。お手数をかけたすが䞀時的に修正しおください。


    7. その他

     私が曞いた他の蚘事は、メニュヌよりたどっおください。

     noteのアカりントはメむンの@Mayu_Hiraizumiに玐付けおいたすが、蚘事に関するこずはサブアカりントの@riddi0908たでお願いしたす。

     
     
    5060Ti (16GB) ず 3060 (12GB) を所持。蚘茉が無い限り文章は手曞きです。蚘事に関するこずは X の riddi0908 たでお願いしたす。質問箱は気たぐれにお返事したす。

    あなたぞのおすすめ