RX 6800でComfyUIを動かす:INT8、GPU VAE、VRAM不足の修正

rx6800780mcomfyuirocm

ティール色の光が縁を走る3連ファンのデスクトップ用グラフィックカードと、その下の小型PC。背後に暖色の光

Radeon RX 6800には16GBの専用VRAMがある。780Mでの音楽生成やQwen-Imageの比較で使ったワークフローを動かすと、最初はエラーや遅いGPUカーネルに悩まされた。MiniMax Music 3は最初のINT8行列積で失敗した。FP32で代用すると動いたものの、1トークンに約7.2秒かかり、20秒の曲を作るにも約1時間かかる見込みだった。

処理経路を修正した後は、20秒のMusicワークフローが178秒で完了した。2分の曲は19.3分で完成し、780Mでは48.1分だった。H3やLTX、画像生成、Hunyuan3Dも、両GPUで条件を揃えて測り直した。

計測した環境

両GPUは同じWindows PCに接続して使い、利用可能なシステムRAMは約28.8GiBだった。RX 6800はgfx1030、780Mはgfx1103。RX用のComfyUIを別のディレクトリに用意し、モデルの追加検索パスを設定して既存のファイルを共有した。

RX 6800Radeon 780M
ComfyUI / Python0.37.2 / 3.12.100.37.2 / 3.12.10
PyTorch2.12.0+rocm10.2.0a202609292.12.0+rocm7.15.0a20260728
起動オプション--cuda-device 1 --use-pytorch-cross-attention --reserve-vram 2--use-pytorch-cross-attention --reserve-vram 6
VAEGPUGPU
加えた修正RX用ノード、comfy_kitchenの変更、共有するComfyUI-GGUFローダーの変更既存のTheRock環境と、共有するH3用GGUFローダーの変更

ROCmのビルドやVRAMの予約量が違い、RX側には後述の修正が入っている。それぞれのGPUで動作するように整えた環境での結果だ。

生成は片方ずつ行った。780Mの計測中はRXサーバーを停止した。RXでH3を測る前には、780Mサーバーが保持していたモデルもComfyUIの/freeで解放した。生成していないサーバーでもRAMを使い続ける。モデルを解放せずにRXでH3を動かすと、システムRAMのページングが起き、726〜1127秒かかった。

同じワークフローでの結果

モデル、プロンプト、解像度、サンプリング設定を両GPUで揃えた。シードも基本的に同じだが、MiniMax Musicの2行は例外だ。ComfyUIのキャッシュを避けるため、RXの検証では20秒の曲に527121、120秒の曲に527124を使い、780Mでは両方とも527001を使った。2分の実行は両GPUで2986フレーム、20秒の実行は501トークンを生成した。保存先も変えた。

時間はWebSocket経由のComfyUI実行イベントから取得した。実行開始から最後のノードまでを測っており、キューで待つ時間は含まない。表にはそれぞれ1回の実行時間を載せた。作業中に繰り返したRXの実行では、最大で約10%の差があった。LTX 2.3は119.5秒と107.1秒、H3 Q3は233.0秒と221.7秒だった。

ワークフローRX 6800780M速度比
MiniMax Music 3、20秒、拡散30ステップ178.2秒470.5秒2.6倍
MiniMax Music 3、120秒、拡散30ステップ1157.9秒2886.4秒2.5倍
H3 Q3_K_XL、640×384、56フレーム、turbo 6ステップ233.0秒636.0秒2.7倍
H3 Q2_K、768×448、56フレーム、turbo 6ステップ353.2秒825.1秒2.3倍
Hunyuan3D-2mini、30ステップ、octree 384102.3秒171.7秒1.7倍
Qwen-Image-2512 Q4_K_M、1216×640、20ステップ、CFG 2.5345.7秒1093.2秒3.2倍
Qwen-Image 2.1 INT8、1216×640、25ステップ104.7秒208.8秒2.0倍
LTX 2.3 Q2_K、512×288、97フレーム、音声あり、8ステップ119.5秒288.9秒2.4倍
LTX 2.5 Q3_K_S、512×288、97フレーム、音声あり、25ステップ290.2秒784.5秒2.7倍

両GPUともサーバー起動後の最初のジョブをH3 Q3、その次をQ2にした。約13GBのH3テキストエンコーダーは毎回読み直した。Q2のほうが解像度も高いため、Q3との時間差には量子化方式と解像度の両方が影響している。

両GPU用のAPIグラフ、RX用の補助ノード、ComfyUI-GGUF向けの2つのパッチは、rx6800-comfyuiリポジトリにまとめた。リンク先はv2026-10-01のスナップショットだ。ComfyUIやROCmの別のビルドで使う場合は、パッチの修正が必要になるかもしれない。Musicのグラフは元のシード527001を保持し、表のRX実行で使ったシードの変更はmeasured-runs.jsonに記録した。LTXは元の実行で保存した条件付けテンソルに依存するが、このテンソルとモデルの重みはリポジトリに含めていない。

表の計測では、RXの仮想環境内にあるcomfy_kitchenを直接修正していた。公開した補助ノードは、起動時に同じ変更を適用する。このノードと未変更のcomfy_kitchenで測り直すと、20秒のMusicワークフローは183.6秒、Qwen-Image 2.1は105.6秒だった。作業レポートには途中の測定も残してある。

rocBLAS経由ならINT8が動いた

失敗したのは、このビルドでhipBLASLtを使うtorch._int_mmだった。HIPBLAS_STATUS_INVALID_VALUEが出て、ログにはTensileLibrary_lazy_gfx1030.datが見つからないと記録されていた。FP32の代替処理は遅すぎたが、重みをFP16へ変換してから行列積を計算すると、曲やQwen-Image 2.1の画像を生成できる速度になった。

さらに調べると、インストール済みの通常のrocBLASにはgfx1030用のINT8×INT8→INT32カーネルがあり、汎用の「fallback」ビルドと記されていた。ctypesからrocblas_gemm_exを呼ぶと使えた。RX側のパッチはGPUごとにハンドルを保持し、PyTorchが使う実行ストリームを設定する。GPUの処理を記録して繰り返し実行するHIPグラフを使うと、毎回の起動にかかる負担を減らせる。その記録中にrocBLASがメモリを確保しないよう、64MBの作業領域も先に用意した。

これでモデル本来の計算へ戻せた。入力を行ごとにINT8へ量子化し、整数行列積を求めてからスケールを適用する。整数行列積の結果は参照値と完全に一致した。浮動小数点の参照値と比べた層全体の相対誤差は約0.9%で、入力の量子化によるものだ。780Mで実際に使われたINT8カーネルの経路は確認していない。先に使ったFP16経路は誤差が小さかったので、INT8へ戻すと生成音声も変わった。

大きな行列積ではINT8が約30〜31TOPS、FP16が25〜27TFLOPSだった。このサイズでの速度差が約1.2倍に留まる背景には、汎用のfallbackビルドを使っていることもある。2行の入力と24576×4096の重み行列の積は、INT8で1.04ms、FP16で2.11ms。この変更を比較した途中の測定では、Qwen-Image 2.1が137.0秒から105.3秒へ短縮した。

VAEとアテンションの処理も修正した

GPUでの動画デコードがHIPのunspecified launch failureで落ちたため、最初はVAEをCPUへ移していた。その後の計測で、このMIOpenビルドではgfx1030上の一部の畳み込みが遅いと分かった。

ストライド1でグループを使わない3D畳み込みを、時間方向のカーネルの各位置で2D畳み込みを行い、その結果を足す処理に置き換えた。LTX 2.3の512×288、97フレームを単独でデコードすると、CPUの44秒からGPUの1.9秒へ短縮した。CPU出力との差は3e-6以内だった。これはデコーダーだけの測定で、表にあるワークフロー全体の時間とは別だ。

MiniMaxの音声VAEでは、間隔を空けて入力を参照する1D畳み込みも遅かった。入力を参照する間隔が9の代表的な層(dilation 9)はMIOpenで436msかかり、カーネルごとの行列積へ分けると9msになった。サーバー起動直後の20秒の曲では、音声デコードが125.4秒から2.5秒へ縮んだ。以前のGPUエラーにはWindowsのタイムアウトが関係した可能性があるが、原因を確定したわけではない。

H3とHunyuan3Dは、PyTorchのSDPA(scaled dot-product attention)で大きなアテンションスコア行列を作っていた。SDPAは、クエリとキーのベクトルを比べ、その対応の強さに応じて情報を重み付けしてまとめる処理だ。この環境では通常の行列演算で計算していた。H3では共有メモリを14.5GB使い、1ステップに約6分かかった。クエリを分割して計算すると、最初のQ2設定では約34秒まで短縮した。

Q3の重み9.3GBはすべてVRAMに収まったが、一時バッファが約1.2GBあふれ、共有メモリを使っていた。1回に作るスコアを2億5600万要素から6400万要素へ減らした実験では、最初のステップが約300秒から28秒になった。その代わり、Hunyuan3Dのデコードは約4秒遅くなった。

長い曲の後もメモリに残るモデル

MiniMaxは自己回帰モデル、拡散モデル、音声VAEを順に使う。このWindows/ROCm環境では、mem_get_infoが十分な空きメモリを報告し、ComfyUIは前の段階のモデルを保持したまま次へ進んだ。長い曲を生成した後はデコード用バッファが共有メモリへあふれ、普段は2秒で終わる20秒の曲のデコードに、16〜22秒かかった。サーバーを再起動すると元に戻った。

RX用ノードは、MiniMaxの拡散処理と音声デコードの前に使っていないモデルを解放する。動画VAEの前にも同じ処理を入れ、LTXも改善した。余分なメモリを保持していた箇所は特定できていないが、今回の連続実行では、この変更後もデコード時間が安定していた。

同じサーバーで順に実行自己回帰拡散デコード合計
20秒の曲115.0秒59.7秒2.2秒178.2秒
120秒の曲743.5秒403.5秒9.9秒1157.9秒
その後の20秒の曲113.3秒59.7秒2.0秒175.2秒
もう一度20秒の曲113.2秒59.7秒2.1秒175.2秒

音楽生成では、小さなdepth decoder(フレーム内の音声コードを生成する部分)の量子化された重みを、生成中だけFP16で保持する変更も効いた。約1.1GB使うが、このデコーダーは音声1フレームごとに7回動く。独立した拡散ウィンドウをまとめて処理すると、20秒の曲では約9%短縮した。長い曲では、約3000フレームを扱うeinsumがgfx1030上でrocBLASカーネルの起動エラーを起こしたため、重み付き和の計算も置き換えた。

120秒のベンチマークには、2分の構成に合わせた長さの歌詞を書いた。両GPUで2986フレーム、自己回帰の段階で約119秒分の音声コードが得られた。短い歌詞のまま最大時間だけ増やした以前の実行は、約15〜65秒分を生成したところで停止した。保存ファイルの長さだけでは、この違いを見落とす。

生成したサンプル

小型PCの上に琥珀色の画像パネルが浮かび、青緑のフレームと左側の暗い余白があるQwen-Image-2512の出力。

Qwen-Image-2512には既存のOGPワークフローを使った。1216×640で、暗いスレート色、琥珀色の光、タイトル用の左側の余白を指定している。最後に両GPUで生成した画像を比べると、平均画素差は0〜255の尺度で3.0だった。Qwen-Image 2.1では1.1だった。

琥珀色と青緑の照明の下、小型PCとガラス板の上の赤いポーション瓶を描いたQwen-Image 2.1の出力。

H3 Q3の動画は24fps、56フレームで音声を含む。同じシードでも、GPUによって生成される場面は違った。計算時のデータ型やカーネルの差はサンプリングに影響する。動画は目視で確認したが、画質を数値で評価していない。LTX 2.5のeuler_ancestralも途中でノイズを加える。このモデルの音声は、以前のCPU VAEと新しいGPU VAEの両方でほぼ無音だった。

2分のMusic 3出力も試聴用に置いた。全体の音質を聴き、歌詞の一部の行を、実際に歌われた内容と照らし合わせて確認した。問題は見つからなかったが、全行の照合はしていない。短い曲では、780Mの出力はRXより音量が小さかった。2分の曲では両GPUの全体のRMSが約0.152で揃った。