Stable Diffusion A1111系WebUIまとめ④ ~性能編(Loraあり)~
「Stable Diffusion A1111系WebUIまとめ③ ~性能編(Loraなし)~」の続きです。
Forge Classic(以下、Classic)の "Persistent LoRA Patching" 機能がポイントだと考えていたのですが、この機能の効果やClassicの優位性は確認できませんでした。
理屈や原因は究明できていませんが、とりあえず結果をまとめましたのでツール選択と知識の補強にはなるかと思います。
関連記事一覧
① 基本編
② 機能編
③ 性能編(Loraなし)
④ 性能編(Loraあり) ※この記事
⑤ 画像比較編
最初に結論
いろいろ試しましたが私の環境と検証内容では "Persistent LoRA Patching" の効果を確認することはできませんでした。
Classicで "Persistent LoRA Patching" を有効/無効で切り替えたり、A1111、Forge、reForgeと比較したり、PyTorchも2.9.1と2.7.0で変えて試したのですが、Loraの処理内容や生成時間に目立った変化はなし。
おまじない程度には効果があるかもしれませんが、この機能を理由にForge Classicを使うのは止めたほうがよいと思います。
Persistent LoRA Patchingとは
ClassicのPersistent LoRA Patching機能について、GithubのReadmeや実装のPull Requestで以下のように説明されています。


生成毎のLoraのPatch処理において、Loraのweightを変更しない場合に1秒程度削減できるということです。
Classicで "--persistent-patches" という引数を付けて起動すると、起動時に以下メッセージが出力され機能が有効になることが確認できます。
[Experimental] Persistent Patches: True対象とするWebUI、検証環境
以下のA1111系WebUIを対象とします。
Stable Diffusion WebUI Forge - Classic ※Classicと省略
Stable Diffusion WebUI reForge ※reForgeと省略
Stable Diffusion WebUI Forge ※Forgeと省略
Stable Diffusion web UI (dev) ※A1111-dev、またはA1111と省略
それぞれStability Matrix (v2.15.5) のデフォルト設定で2026年1月14日時点での最新リリース版(リリースがないものは最終コミット)を新規インストールした状態をベースとし、Classicはtorchを2.8.0から2.9.1にバージョンアップしています。
前回記事からreForgeのみ少しバージョンアップされており、その中で "--pin-shared-memory" の問題が修正されたため、今回は "--pin-shared-memory" を付けています。
$$
\begin{array}
{c|c|c|c|c|l}
\text{ツール名} & \text{更新日} & \text{version /} & \text{python} & \text{torch} & \text{最適化} \\
& & \text{commit} & & & \\
\hline
\text{Classic} & \text{2025/12/16} & \text{v1.13} & \text{3.11.13} & \text{2.9.1+cu128} & \text{sageattention} \\
\hline
\text{reForge} & \text{2026/1/13} & \text{7c3938a} & \text{3.10.18} & \text{2.9.1+cu128} & \text{sageattention} \\
\hline
\text{Forge} & \text{2025/6/27} & \text{dfdcbab} & \text{3.10.18} & \text{2.9.1+cu128} & \text{pytorch attention} \\
\hline
\text{A1111-dev} & \text{2025/12/18} & \text{fd68e0c} & \text{3.10.18} & \text{2.9.1+cu128} & \text{pytorch attention} \\
\hline
\text{A1111-dev} & \text{2025/12/18} & \text{fd68e0c} & \text{3.10.18} & \text{2.7.0+cu128} & \text{Doggettx attention} \\
\hline
\end{array}
$$
検証環境は前回記事からNVIDIAドライバーのみGame Ready 591.74 WHQLにバージョンアップしています。
検証方法
手持ちのLoraから適当に10個を選び、それらすべてを使って画像生成します。
$$
\begin{array}
{r|l|r|r|r|r}
& \text{種別} & \text{サイズ} & \text{Unet keys} & \text{CLIP keys} & \text{合計keys} \\
\hline
\text{1} & \text{キャラLora} & \text{54.8 MB} & \text{722} & \text{264} & \text{986} \\
\hline
\text{2} & \text{キャラLora} & \text{54.8 MB} & \text{722} & \text{264} & \text{986} \\
\hline
\text{3} & \text{服装Lora} & \text{193.3 MB} & \text{722} & \text{88} & \text{810} \\
\hline
\text{4} & \text{キャラLora} & \text{217.9 MB} & \text{722} & \text{264} & \text{986} \\
\hline
\text{5} & \text{キャラLora} & \text{218.6 MB} & \text{788} & \text{88} & \text{876} \\
\hline
\text{6} & \text{キャラLora} & \text{109.1 MB} & \text{722} & \text{264} & \text{986} \\
\hline
\text{7} & \text{キャラLora} & \text{217.9 MB} & \text{722} & \text{264} & \text{986} \\
\hline
\text{8} & \text{構図Lora} & \text{58.4 MB} & \text{788} & \text{264} & \text{1052} \\
\hline
\text{9} & \text{画風Lora} & \text{217.9 MB} & \text{722} & \text{264} & \text{986} \\
\hline
\text{10} & \text{キャラLora} & \text{54.8 MB} & \text{722} & \text{264} & \text{986} \\
\hline
& \text{合計} & \text{1397.4 MB} & \text{7352} & \text{2288} & \text{9640} \\
\end{array}
$$
生成内容はプロンプトでLoraを読み込むタグを10個追加している以外、前回記事の「1.832×1216:神里綾華ベンチマーク」と同じです。
CheckpointモデルとLoraモデルを読み込むために何度か画像生成し、安定したところでLoraのweightを変更しながら生成して処理内容と生成時間を確認します。
生成1回目:Loraのweightを変更して生成
生成2回目:Loraのweightはそのままで生成
生成3回目:Loraのweightを変更して生成
生成4回目:Loraのweightはそのままで生成
ちなみに生成される画像はこんなのです。怖い。
Loraを混ぜすぎですね。

実行結果
各WebUIでコンソールに出力されたメッセージの抜粋です。
それぞれ出力メッセージが異なりますが、生成開始から終了までの時間、そしてLoraのclipとunetを読み込む処理が確認できます。
1.Classic "--persistent-patches" なし
※生成1回目(weight変更)
2026-01-14 11:19:11 INFO [modules.shared_state] Starting job task(v87mxvljgm9d2qe)
Loading Model: SDXLClipModel
Moving model(s) has taken 4.79 seconds
Loading Model: SDXL
Moving model(s) has taken 1.99 seconds
2026-01-14 11:19:22 INFO [modules.shared_state] Ending job task(v87mxvljgm9d2qe) (11.50 seconds)
※生成2回目(weightそのまま)
2026-01-14 11:19:25 INFO [modules.shared_state] Starting job task(672mzj1ig7f4ntw)
2026-01-14 11:19:28 INFO [modules.shared_state] Ending job task(672mzj1ig7f4ntw) (3.04 seconds)
※生成3回目(weight変更)
2026-01-14 11:19:31 INFO [modules.shared_state] Starting job task(ahzcmr5vk5ekeib)
Loading Model: SDXLClipModel
Moving model(s) has taken 4.62 seconds
Loading Model: SDXL
Moving model(s) has taken 1.94 seconds
2026-01-14 11:19:43 INFO [modules.shared_state] Ending job task(ahzcmr5vk5ekeib) (11.17 seconds)
※生成4回目(weightそのまま)
2026-01-14 11:19:44 INFO [modules.shared_state] Starting job task(71yixoyof0uldar)
2026-01-14 11:19:47 INFO [modules.shared_state] Ending job task(71yixoyof0uldar) (3.00 seconds)weightを変更したときはLoraを読み込みますが、weightを変更しなかったときは読み込まないため生成時間が短くなっています。
これが "Persistent LoRA Patching" の効果だと思っていましたが、"Persistent LoRA Patching" を有効にしていません。どういうことでしょうか?
2.Classic "--persistent-patches" あり
※生成1回目(weight変更)
2026-01-14 11:15:07 INFO [modules.shared_state] Starting job task(4ngwz8pwamd9z4i)
Loading Model: SDXLClipModel
Moving model(s) has taken 4.75 seconds
Loading Model: SDXL
Moving model(s) has taken 1.92 seconds
2026-01-14 11:15:18 INFO [modules.shared_state] Ending job task(4ngwz8pwamd9z4i) (11.29 seconds)
※生成2回目(weightそのまま)
2026-01-14 11:15:22 INFO [modules.shared_state] Starting job task(yu9ebeen5hwqpqg)
2026-01-14 11:15:25 INFO [modules.shared_state] Ending job task(yu9ebeen5hwqpqg) (3.00 seconds)
※生成3回目(weight変更)
2026-01-14 11:15:31 INFO [modules.shared_state] Starting job task(3xmcb945a7jd5im)
Loading Model: SDXLClipModel
Moving model(s) has taken 4.66 seconds
Loading Model: SDXL
Moving model(s) has taken 1.93 seconds
2026-01-14 11:15:42 INFO [modules.shared_state] Ending job task(3xmcb945a7jd5im) (11.25 seconds)
※生成4回目(weightそのまま)
2026-01-14 11:15:45 INFO [modules.shared_state] Starting job task(5xkicbzrvx0o7nh)
2026-01-14 11:15:48 INFO [modules.shared_state] Ending job task(5xkicbzrvx0o7nh) (3.03 seconds)"--persistent-patches" なしの場合と同じような処理内容、生成時間に思えます。
3.reForge
※生成1回目(weight変更)
2026-01-14 15:50:53 INFO [modules.shared_state] Starting job task(rjndbgxxj9a2v9m)
2026-01-14 15:50:55 INFO [root] Requested to load SDXLClipModel
2026-01-14 15:50:55 INFO [root] loaded completely 24309.488999176025 2521.853515625 True
2026-01-14 15:50:55 INFO [root] Requested to load SDXL
2026-01-14 15:50:57 INFO [root] loaded completely 27447.973110961913 4897.0483474731445 True
2026-01-14 15:51:00 INFO [modules.shared_state] Ending job task(rjndbgxxj9a2v9m) (6.76 seconds)
※生成2回目(weightそのまま)
2026-01-14 15:51:02 INFO [modules.shared_state] Starting job task(lgq4ufq1ej1f7dn)
2026-01-14 15:51:05 INFO [modules.shared_state] Ending job task(lgq4ufq1ej1f7dn) (2.89 seconds)
※生成3回目(weight変更)
2026-01-14 15:53:55 INFO [modules.shared_state] Starting job task(5gmn5qtodqn6mg1)
2026-01-14 15:53:56 INFO [root] Requested to load SDXLClipModel
2026-01-14 15:53:57 INFO [root] loaded completely 24305.488999176025 2521.853515625 True
2026-01-14 15:53:57 INFO [root] Requested to load SDXL
2026-01-14 15:53:59 INFO [root] loaded completely 27443.973110961913 4897.0483474731445 True
2026-01-14 15:54:02 INFO [modules.shared_state] Ending job task(5gmn5qtodqn6mg1) (6.84 seconds)
※生成4回目(weightそのまま)
2026-01-14 15:54:04 INFO [modules.shared_state] Starting job task(pz2e5aa95954n42)
2026-01-14 15:54:07 INFO [modules.shared_state] Ending job task(pz2e5aa95954n42) (2.93 seconds)Classicよりも速いですね。
4.Forge
※生成1回目(weight変更)
2026-01-14 11:27:14 INFO [modules.shared_state] Starting job task(9eysus0vc0awc08)
Moving model(s) has taken 1.29 seconds
Moving model(s) has taken 3.46 seconds
2026-01-14 11:27:23 INFO [modules.shared_state] Ending job task(9eysus0vc0awc08) (9.04 seconds)
※生成2回目(weightそのまま)
2026-01-14 11:27:25 INFO [modules.shared_state] Starting job task(xggavy2n2hh6ljw)
2026-01-14 11:27:29 INFO [modules.shared_state] Ending job task(xggavy2n2hh6ljw) (3.21 seconds)
※生成3回目(weight変更)
2026-01-14 11:27:33 INFO [modules.shared_state] Starting job task(v8f1guakg7h6vvx)
Moving model(s) has taken 1.05 seconds
Moving model(s) has taken 3.49 seconds
2026-01-14 11:27:42 INFO [modules.shared_state] Ending job task(v8f1guakg7h6vvx) (8.64 seconds)
※生成4回目(weightそのまま)
2026-01-14 11:28:02 INFO [modules.shared_state] Starting job task(5qccinwqcc2p5iq)
2026-01-14 11:28:05 INFO [modules.shared_state] Ending job task(5qccinwqcc2p5iq) (3.36 seconds)Classicよりも速いですね。5.A1111
※生成1回目(weight変更)
2026-01-14 11:36:54 INFO [modules.shared_state] Starting job task(bvqldukt4vbwuzn)
2026-01-14 11:37:04 INFO [modules.shared_state] Ending job task(bvqldukt4vbwuzn) (10.13 seconds)
※生成2回目(weightそのまま)
2026-01-14 11:37:07 INFO [modules.shared_state] Starting job task(i7bxq1kv836f485)
2026-01-14 11:37:15 INFO [modules.shared_state] Ending job task(i7bxq1kv836f485) (8.29 seconds)
※生成3回目(weight変更)
2026-01-14 11:37:19 INFO [modules.shared_state] Starting job task(eg55kk37420xkm9)
2026-01-14 11:37:29 INFO [modules.shared_state] Ending job task(eg55kk37420xkm9) (10.40 seconds)
※生成4回目(weightそのまま)
2026-01-14 11:37:32 INFO [modules.shared_state] Starting job task(abpa2ba48gldc72)
2026-01-14 11:37:40 INFO [modules.shared_state] Ending job task(abpa2ba48gldc72) (7.73 seconds)表にまとめると以下のとおりです。
右端に前回記事において同じ最適化引数で測定した結果を載せています(条件が少し異なるためあくまで参考値です)。
$$
\begin{array}
{l|c|r|r|r|r}
& \text{weight} & \text{SDXL} & \text{SDXL} & \text{生成時間} & \text{Loraなし}\\
& & \text{Clip} & \text{Unet} & & \text{(参考)} \\
\hline
\text{Classic} & \text{変更} & \text{4.79 秒} & \text{1.99 秒} & \text{11.50 秒} & \text{3.08 秒}\\
\text{sageattention} & \text{-} & \text{-} & \text{-} & \text{3.04 秒} \\
\text{(Persistentなし)} & \text{変更} & \text{4.62 秒} & \text{1.94 秒} & \text{11.17 秒} \\
& \text{-} & \text{-} & \text{-} & \text{3.00 秒} \\
\hline
\text{Classic} & \text{変更} & \text{4.75 秒} & \text{1.92 秒} & \text{11.29 秒} & \text{3.08 秒}\\
\text{sageattention} & \text{-} & \text{-} & \text{-} & \text{3.00 秒} \\
\text{(Persistentあり)} & \text{変更} & \text{4.66 秒} & \text{1.93 秒} & \text{11.25 秒} \\
& \text{-} & \text{-} & \text{-} & \text{3.03 秒} \\
\hline
\text{reForge} & \text{変更} & \text{約1秒} & \text{約2秒} & \text{6.76 秒} & \text{2.96 秒}\\
\text{sageattention} & \text{-} & \text{-} & \text{-} & \text{2.89 秒} \\
& \text{変更} & \text{約1秒} & \text{約2秒} & \text{6.84 秒} \\
& \text{-} & \text{-} & \text{-} & \text{2.93 秒} \\
\hline
\text{Forge} & \text{変更} & \text{1.29 秒} & \text{3.46 秒} & \text{9.04 秒} & \text{3.23 秒}\\
\text{Pytorch attention} & \text{-} & \text{-} & \text{-} & \text{3.21 秒} \\
& \text{変更} & \text{1.05 秒} & \text{3.49 秒} & \text{8.64 秒} \\
& \text{-} & \text{-} & \text{-} & \text{3.36 秒} \\
\hline
\text{A1111} & \text{変更} & \text{?秒} & \text{?秒} & \text{7.78 秒} & \text{4.53 秒}\\
\text{Pytorch attention} & \text{-} & \text{-} & \text{-} & \text{5.23 秒} \\
& \text{変更} & \text{?秒} & \text{?秒} & \text{7.56 秒} \\
& \text{-} & \text{-} & \text{-} & \text{5.07 秒} \\
\hline
\text{A1111} & \text{変更} & \text{?秒} & \text{?秒} & \text{10.13 秒} & \text{ 7.52 秒}\\
\text{Doggettx attention} & \text{-} & \text{-} & \text{-} & \text{8.29 秒} \\
& \text{変更} & \text{?秒} & \text{?秒} & \text{10.40 秒} \\
& \text{-} & \text{-} & \text{-} & \text{7.73 秒} \\
\end{array}
$$
reForgeはLora読み込み時間が個別に出力されないため、時刻からおおよそで計算した値です。
A1111はモデル読み込みの処理メッセージ自体が出力されません。weightの変更あり/なし時の生成時間比やLoraあり/なしでの生成時間比から考えても、そもそもLoraの処理方式がForge系と違うのかもしれません。
ということで、なんとClassicはweightを変更した直後の生成ではA1111のDoggettx attentionにすら負ける結果となりました。
Classicの "Persistent LoRA Patching" の有効/無効での差は確認できず、そもそもClassic以外のWebUIでもweightを変更しないで続けて生成した場合はLoraを読み込まないようで生成時間が短いです。
Loraの一覧表に示したUnetとClipのKey数、reForgeとForgeのLora読み込み時間と比べても、ClassicのClip読み込み時間は長すぎると思いますので、何か問題があるのかもしれません。
まとめ
Classicの "Persistent LoRA Patching" 機能の効果を確認するつもりの検証でしたが、効果を確認できないだけでなくLora読み込みでのClassicの遅さが際立つ結果となりました。
もしも原因の究明か切り分けができたらIssueとして報告するかもしれません。
このような感じで、あまり体系的に整理や理解されていない技術的な内容を分かりやすく無料で解説しています。「スキ」「フォロー」「チップ」で応援よろしくお願いします。
