数日前、ラボのレンダリングパイプラインで時間のかかる奇妙な症状が発生した:GPU1(RTX 5060 Ti 16GB)上の flux ジョブはステップごとに 2 分以上かかったが、同じジョブを GPU0(同一モデルのカード)で実行すると全体で約 54 秒で完了した。3 回再現テストを実施 — ランダムな現象ではない。
シグネチャを正しく読むこと
最初にやったのは、ジョブが停止している間に 6 回 nvidia-smi のサンプルを取得することだった。結果はすべてを物語っていた:
| 停止中の値 | 測定値 |
|---|---|
| SM utilization | 96–99%(「激しく動作中」に見える) |
| メモリ利用 | 0–1%(データ転送なし) |
| カード消費電力 | 38W(サンプリングとしては異常に低い) |
| ステップ時間 | >120 秒(通常は約 4 秒) |
SM が満杯だがメモリがゼロ + 電力が低い = カードは実際に計算していない。スピンウェイトでループしているのだ。これはランタイムのライブロックであり、モデルの負荷ではない。通常のジョブでは、実際のシグネチャは SM 96–99% + メモリ利用 18–41% + 電力 115–143W である。
変化した変数は一つだけ
GPU0 と GPU1 は同一モデルのカードを使用し、同じモデル(flux1-dev fp8)だが、ランタイムが異なる:
- GPU0 (:8188) — imgfactory python_embeded, torch 2.13.0+cu130
- GPU1 (:8190) — venv Python 3.12, torch 2.7.1+cu128
その夜の唯一の仮説:ランタイム 2.7.1+cu128 は、5060 Ti の Blackwell アーキテクチャとデクアンタイズ負荷の重いワークロードで互換性がない。検証は簡単だった — GPU0 の検証済みのランタイムを CUDA_VISIBLE_DEVICES=1 で GPU1 上で実行し、モデルやワークロードには一切触れない。
ランタイム切り替え後の結果
start_gpu1_v2(imgfactory python_embeded、torch 2.13.0+cu130、8188 との競合を避けるため出力/入力/DB ディレクトリを完全に分離)に切り替えた後:
| ゲート | 結果 |
|---|---|
| 単一ジョブ(job 85917) | 54.4 秒 — 正常に回復 |
| 連続 8 ジョブ | 50.7–127.4 秒、すべて通過 |
| 10 ジョブ合計 | 10/10 PASS · 中央値 54.15 秒 |
| 同時期の GPU0 と比較 | パリティ 100.3%(バンド ±50%) |
| GPU0 への副作用 | なし — 8188 は同じ期間中も動作し画像を公開し続けた |
修正後の GPU1 の実測スループット = 30.5 ジョブ/時間(10 ジョブ / 1,182 秒)
私たちがしなかったこと(すべきでないこと)
- 古い venv は削除していない — E:\ComfyUI に「移動はするが削除しない」という規則に従って残し、schtask を新しいランチャーを指すように変更しただけ
- かつて双子プロセスを生み出すまで再起動を助けていた古い idle_watchdog に触れていない — すでに削除済みで、必要時に手動で呼び出す heal で対処
- 他の作業には一切触れていない:ワークロード、パラメータ、モデル、キュー順序 — すべてバイト単位で同じ
ラボの教訓
GPU が「遅い」と感じたら、すぐにモデルを責めたり VRAM を増やしたりするな — まずこの 3 つの値を読み解け:SM、メモリ利用、ワット数。SM が満杯だがメモリがゼロなら、問題はほぼ確実にランタイムにある。正しい検証は、一つの変数(ランタイム)だけ切り替え、残りはすべてそのままにして、10 ジョブの結果を測定すること — 最初に推測して新しいドライバを探し始めることではない。