「Stable Diffusion」の呪文(15) Automatic1111 hires.fixの拡大アルゴリズム(Latentとか)
初めに
APIについて整理しなおしたいのだが、謎のAPIが増えすぎたり、細部がこっそり変わっていたり、調べるのが大変なので後回し。オープンソース化したStable Diffusionの面白いところは、お絵かきAIの本来の目的である文章から画像が作るが、順不同にならべたコンマ区切りの単語に置き換わり、画風はモデルを丸ごと切り替えることで切り替える様になっている。つまりお絵かきAIが本来目指した方向性と逆方向に進化している点。つまり使い手がAIに求めているのは、文章の意味を汲み取ることより断片的な情報から目的を察しろと言う事。文章生成AIが正確な文章を必要とする限りAIによって人の仕事は減れど無くなりはしない。次世代AIが空気を読める用になると本格的に晴耕雨読の生活を模索しないと行けないかも。
本稿では、hires.fixの拡大アルゴリズムの本来の性質を調べることを目的としている。拡大アルゴリズムを使った結果については考察しない。それはモデルや2step目の設定で大分変わるからだ。それには試行錯誤が必須になると思う。
hires.fixに関してのおさらい
hires.fixは、txt2imgで作成した画像をimg2imgで拡大し細部を補完するテクニックである。これはStable Diffusion 1. xが512x512(正確には違うが)を超える画像を作成すると出力がおかしくなりだすところから産まれている。また大きな画像を生成するとメモリを消費し、時間がかかる。場合によってはメモリ不足でエラーになる。そのため小さなサイズで絵を作成し、その絵を拡大してから細部を書き足す方が完成までの時間が短くできる。512x512で40steps、拡大して1024x1024で10stepsの方がいきなり1024x1024で40steps実行するより速い。
そしてhires.fixはupscalerを何にするかで結果が変わる。
Denoising strengthとは
元の絵に新しい絵をどれだけ反映するかと言う係数になる。1. 0の場合は完全に上書きになり、0. 0の場合は元の絵そのままになる。img2imgの係数と同じ。hires.fixが実装された時期にDenoising strengthがバグっていたようでhires.fix実装当時(None)の検証では0. 4ぐらいが妥当で、0.7は使えなかった。しかしLatentで再検証すると0.6-0.7あたりにしないと拡大ノイズが消えないためupscalerを変更する場合、Denoising strengthも調整する必要がある。
どうやらLatentは、Denoising strength0.6以上にしないと使い物にならない。
Noneでは、最初の絵柄を活かそうとするとDenoising strength 0.4-0.5あたりが最適値になる。
Upscaler以外の係数も出力に大きく影響するため、結局Upscalerは最終的に目的や好みの問題になるため検証する意味は薄い(hires stepsの影響を調べようとしたら、x1.5ぐらいでは影響が分からなかった)
Latentとは
しかしAUTOMATIC1111のtxt2imgでhires.fixに設定されているupscaler(拡大アルゴリズム)のデフォルトに設定されているLatentとは何であろう。直訳すると「潜在的」であり意味が分からない。そのため調査することにした。
AUTOMATIC1111のソースコードは構造が怪奇で追いかけるのが大変なのだが、ついにとある1行に辿り着いた
samples = torch.nn.functional.interpolate(samples, size=(target_height // opt_f, target_width // opt_f), mode=latent_scale_mode["mode"], antialias=latent_scale_mode["antialias"])
結論を言うと、PyTouch(AI用の基本ライブラリの一つ)の組込関数 torch.nn.functional.interpolate(interploateは補完すると言う意味)で潜在空間(画像生成用の元ネタ。基本的に乱数で作られる)に拡大したイメージを利用するのがLatentである。そして従来のhires.fixと異なりimg2imgではなくtxt2imgを再実行している。それ以外の場合、Pillow(Pythonでよく使われている画像処理ライブラリ)のImage.resizeかAIのノイズ除去ライブラリを使って拡大(Noneの場合なにもしない)してからimg2imgを実行している。
ここで注意する点はLatentは潜在空間を拡大してimg2imgではなくtxt2imgを再実行している点。そのためDenoising strengthが小さいとボケてしまう。生成速度を優先したい場合はLatent以外を使い、hires stepsをギリギリまで減らす方がおすすめになろう(ちなみにモデルやプロンプトで変わる。収束が早いケースでテストしたらどれも3-4で十分だった……)
なお、PyTourchのドキュメントをみるとLanscos3は実装されていないのでLatentにLancosは無い。
Latentの意味するところは以下になる
Latent バイリニア
Latent (antialiased) バイリニア+アンチエイリアス
Latent (bicubic) バイキュービック
Latent (bicubic antialiased) バイキュービック+アンチエイリアス
Latent (Nearest) ニアレストネイバー
Latent (Nearest-exact) 正確なニアレストネイバー
Nearest-exactは、厳密に距離を計算して近くのピクセルを計算する。実験した結果、Nearestと比較した場合、整数倍だと結果はかわらないが小数倍の場合かなり結果が変わる。NearestとNearest-exactはアンチエイリアスを設定すると関数がエラーになるので実装されていない。
拡大アルゴリズムについて
ちなみ自力で実装したものが
https://mith-mmk.github.io/wasm/ この辺に置いてある。しかしBicubicとLancos3の差があまり出ない。基本的にはアフィン変換してから隙間を補完アルゴリズムで埋める。その補完アルゴリズムのことを拡大アルゴズムと読んでいる。ただし、アフィン変換は変換式を行列に変換してから変換式を計算してから実行するため、例えば、縮小1/10、拡大20倍と設定した場合、1/10 * 20 = 2で拡大2倍のみ実行される。
元画像をx6倍したのが以下の結果。
ニアレストネイバーは非整数倍の場合汚くなるが、テストは整数倍なのでブロック感が強くなるだけ。1.6倍などの場合はバイリニアを使った方が良い。
AIアルゴリズム
ESRGAN_4x, LDSR, ScuNET, ScuNET PSNR, SwinIR_4xと言ったアルゴリズムは当然Pillowに実装されていない。これらはAIを使ったノイズ除去アルゴリズムである。その分、動作も遅い。しかも補完アルゴリズムと言うよりノイズ除去のようである。拡大で欠落した情報をAIで補完すると言うよりノイズを除去する。なおピンボケの写真には弱かった。適切なアルゴリズムはモデルにより変わるので注意。
ESRGAN_4xは https://github.com/cszn/KAIR/ の下にあるモデルを使うらしい。
LDSRのモデルはドイツのハイデルブルク大学のサイトに転がっているようで。Latent Diffusionを使うらしい。かなり重くモデルもかなり大きい。
SCUNet(Swin-Conv-UNet)もノイズ除去のモデルらしい。https://github.com/cszn/SCUNet このモデルは比較的軽い。
SwinIRはコーネル大学で開発されたノイズ除去のモデルだ。モデル自体は小さいがかなり遅い。
デフォルトでメニューに出てこない拡大アルゴリズムはreal-ESRGAN(https://github.com/xinntao/Real-ESRGAN)を使って居るらしい。
そんな訳でノイズ除去AIらしいのでノイズの多い画像を用意した方が良い気がしてきた……。
AIアルゴリズムの比較
本来の用途がノイズ除去なのでスケール1. 0でサイズを変更しないのが本来の使い方の様である。そのため、わかり安くわざとノイズをのせた画像でテストしてみた。フィルタにより得意なノイズが違う気がするので複数のノイズを用意した方が良いかも。強いノイズ除去はノイズは除去される代わり画像がぼやけたりのっぺりしたりする。つまり元の絵から離れていくのでアップスケール後のimg2imgのsteps数やDenoising strengthの値が重要になりそう。
このテストはわざとノイズをのせた画像がどこまで元の画像に戻せるかをテストしている。つまりhires.fixでのupscalerの使い方とは異なる。
このタイプのノイズには弱い。ノイズ除去の設定が弱いのだろうか?倍に拡大するぐらいの用途なら適正なのかも?
ノイズ除去はやや弱め。hires.fixの場合、img2imgが続くので、この程度で十分かも。しかし最大の問題はモデルが大きく重いこと。GPUのメモリが少ない環境では遅くてまともに動かないかメモリ不足を起こす。
ノイズはほぼ除去できているがディテールが潰れている
x2より強い。ピンボケしている。
アニメ塗りに変換してる気がする。のっぺりするのでhires.fixで使う場合、細部はほぼ書き直しになると考えられる。
この手のノイズに弱いらしい。ほぼ効いていない。
x4に近いが、ディテールの潰れ方も弱い
ノイズを除去するというより拡散してノイズ感を薄めている感じ
R-ESRGANx2に近い。変換は速い。
SuNetとの違いがよく分からない、違いはメモリ利用効率や速度か?
R-ESRGANx2とx4の間ぐらいか?
#StableDiffusionWebUI #AI #StableDiffusion #hires .fix #アルゴリズム
この記事が気に入ったらサポートをしてみませんか?