RTX 5090 1枚のローカル動画生成。半分は拾い物、半分は自分たちで見つけた高速化の記録です。
技術的な手順やツールはGitHubに置きました:matsuo-koya/minimax-h3-notes

前回、Sunoなどで作った楽曲を放り込むと歌詞入りMV(ミュージックビデオ)が出てくる自宅スタジオ「LaViale」の話を書きました。
あれから3週間、私はやはり一行もコードを書いていないのですが、スタジオの中身はだいぶ速くなりました。
どのくらいかというと、1280×704で5秒ちょっとの長さの動画1本が、
素の設定(20ステップ)で4分半ほど
公式のTurbo LoRAで125秒
先週入れたINT8アテンションで79秒
で生成されます。リップシンクの1区間(参照画像つき・7.6秒)は127秒 → 69秒。28区間あるMVは、以前は5090 1台で3.8時間かかっていましたが、いまなら2分の楽曲のMVが40分ほどで完成する計算になります。
この3週間でやったことを振り返ると、半分は「誰かが作って配っていたものを入れて測った」ことで、もう半分は「入れようとして中を覗いたら、自分たちで見つけてしまった」ものでした。後者には、Mac側で起きていた謎の不具合の原因や、公開されている高速化ノードの作者が書いていない性質も含まれています。効かなかったものも含めて、順番に書いていきます。


▲西川善司さんプロデュースの架空バンドThe NostrilsのMVをLaVialeで試作中
まず「どこで時間が消えているか」を測った
高速化の話をする前に、ひとつだけ準備がありました。ComfyUIは1本の生成にかかった合計時間しか教えてくれません。サンプリングに何秒、動画のデコードに何秒、というノード別の内訳が出ないのです。
そこでClaude Codeに、ComfyUIがWebSocketに流す「いまこのノードを実行中」というイベントの間隔を積み上げるだけの46行のプロファイラを書いてもらいました。結果は、サンプリングが84%、VAEデコード(潜在表現を画素に戻す工程)が11~17%、動画の書き出しが2%。
当たり前のようですが、これを最初に持っておいたおかげで、後で「アテンションを半分にしたらVAEデコードが次のボトルネックになる」というところまで見えました。合計だけ見ていると、固定費としてかかってくるVAEが隠れてしまいます。
拾ってきたもの(公式・コミュニティ)
int8 ConvRotの重み。ComfyUIの公式(Comfy-Org)が配っている量子化版で、21GB。これなら5090の32GBに載ります。ついでに、この量子化の誤差を測ったら0.90%でした。変換ツールのコメントにある0.17%という数字は「すでにint8になっている重みを再符号化したときの数字」で、本当の量子化誤差ではありませんでした。こういう「書いてある数字を測り直す」癖が、後で効いてきます。
Turbo LoRA(公式蒸留)。20ステップを8ステップにして2.2倍。うれしい発見は、歌詞を画面の中の看板やガラスに「描かせる」手法が、8ステップのままで日本語が読めることでした。20ステップにしても可読性は変わらず、時間だけ2.2倍になります。
FastH3 4ステップ。UC San DiegoのHao AI LabがFastVideoプロジェクトで出した蒸留LoRAで、Turbo 8ステップからさらに1.87倍(225秒 → 118秒)。顔も口の動きも崩れず、本番の30区間MVで破綻ゼロでした。
ただし、これはそのままでは使えませんでした。配られているのはdiffusers形式で、ComfyUIとはテンソルの名前も並びも違う。変換が必要で、その変換で「発見」が出ます。次の章で。
Redditの「エンドレスAIテレビ局」から拾ったINT8アテンション
先週、Redditに「ゲーミングGPU 1枚でAIテレビ局を延々流し続ける」という投稿がありました。5090 1台でH3を回し続ける構成で、うちと同じです。Claude Codeに「これはうちに役立つか調べて」と頼んだところ、一番大きい収穫はアテンションをINT8にすることでした。
H3のような動画モデルは、フレームを小さなトークンに刻んで、全トークン同士の関係を計算します(アテンション)。5秒の1280×704で3万トークン強、15秒なら9万。計算量はトークン数の2乗で増えるので、ここが時間の大半を食います。
これを8ビット整数で計算する機能が、実はComfyUIに最初から入っていました(comfy-kitchenのModelAttentionBackendノード)。有名なsageattentionは、うちの環境にはCUDAのコンパイラが無くて入らなかったのですが、こちらはインストール不要で、5090でそのまま動きます。
測った結果が、この記事の冒頭の数字です。アテンション単体で2.7倍、サンプリング全体で約2倍(99秒 → 54秒、91秒 → 45秒)。
心配だったのは画質です。8ビットに落として顔が変わらないか。うちには「本人の実写48枚との顔の一致度(ArcFace)」と「唇の開きと歌声の音量の相関」を測る道具があるので、それで見ました。顔の一致度0.322 → 0.311(同一人物の線が0.28)、リップシンクの相関は区間ごとのばらつきの範囲内。目で見ても分かりません。
ひとつ注意点があって、テキストからの生成(t2v)では、同じシードでも別の動画が出ます。量子化で乱数の経路が変わるためです。参照画像を使う生成では参照が錨になるので、ほぼ同じ絵が出ます(別マシンの4090での実測でPSNR 26.2、SSIM 0.954)。「速くしたら同じものが速く出る」とは限らない、というのは、この後何度も出てくる話です。
自分たちで見つけたこと
FastH3の変換で、1行の入れ替えが必要だった
FastH3のLoRAをComfyUI形式に変換するとき、H3にはQ・K・Vの3つの行列を1つに融合した層と、MLPのgateとupを融合した層があります。融合した層にLoRAを当てるには、分かれていたLoRAを正しい順序で並べ直さないといけない。
問題は、順序を間違えても形が同じなのでエラーが出ないことです。
Claude Codeは推測で決めるのを嫌って、同じLoRAをdiffusers形式とComfyUI形式の両方で配っている別プロジェクト(lightx2v)を正解表にして、並び方を総当たりで試しました。結果、Q・K・Vは対角ブロックに、MLPの融合層はdiffusersが[value; gate]、ComfyUIが[gate; value]で、前半と後半を入れ替える必要があると分かりました。416本のテンソルすべてがビット単位で一致するまで確かめてあります。
この「前半後半の入れ替え」は、後日、まったく別の場所で効きました。うちのMac(Apple Silicon、MLX)に同じLoRAを移植したとき、「作風は乗るのに、顔だけ別人になる。強くすると崩れる」という症状が出て、原因が分からずにいたのです。Mac側のAIとこちらのAIが郵便受けでやりとりして切り分けた末に、原因はこの入れ替えでした。形が合っているものは、順序が合っているとは限らない。以来うちでは「融合した重みは、分割してマージし直して順序まで実証してから採用」を決まりにしています。
FastH3の中身は、実はH3と同じだった
これは狙って見つけたものではありません。int8の変換を検算していたら、10個のブロックすべてで「H3とFastH3の重みの差」が「int8の量子化誤差」と小数点以下3桁まで一致したのです。つまり、4ステップ蒸留はトランスフォーマーのブロックには一切入っておらず、時刻の埋め込み(adaln)だけが違う。
さらに、うちが使っているpruned版のH3は、その時刻埋め込みを1025行 × 8列の表に畳み込んであるのですが、この表が元のネットワークからz = B silu(temb(t))で残差2.4e-6で再現できることも分かりました。これで、pruned版で学習したLoRAを元のフル版に橋渡しする式が書けます。Mac側がそれを実装して、数理は成立を確認済みです。
345フレームの崖 — 1本で決めてはいけない
4090のマシンには、1本あたり何フレームまで任せるかの上限があります。最初、345フレームを1本測って通ったので、それを上限にしました。
後で全実績を集計したら、345フレームは7本中6本が3~17倍遅かった(正常なら8分のところ、最悪2時間24分)。通ったのは「7本に1本の当たり」で、それがたまたま最初の1本だったのです。328フレームは11本すべてが882~897秒に収まっていました。
面白いのは、遅かったrunのVRAMの使われ方が正常なrunと完全に同一だったことです。メモリの飽和ではない。しかもサンプリングの進捗表示の積算と実際の経過が85分ずれている、つまり時間はサンプリングの外で消えている。原因はまだ分かっていません。分かっていないまま、上限を328に下げて実害を消してあります。
教訓は単純で、1シード、1本で決めない。同じ失敗を、別のモデルのマージ版の評価でもやっていました(1シードで「構図が変わる」と結論して、3シード見たら逆だった)。
公開ノードの「書かれていない性質」を2つ
コミュニティの高速化ノードH3-Optimizations(Zironic氏)のH3MemoryOptimizationを測りました。うちでは1.27倍(作者の環境では1.57~1.69倍)。ばらつきがほぼゼロになるのは気持ちいい。
ただし、作者が書いていないことが2つ。ひとつ、出力がビット一致しません。ノードなしは同じシードで完全に決定的(差0.000)なのに、ノードを入れると平均で2.27/255の画素差が出ます。髪と輪郭の微細な部分だけで人物も構図も同じなのですが、「同じものが速く出る」ではない。ふたつ、GGUF量子化の重みでは動きません。4090側で3024×14336という不思議な形のエラーが出て、調べると3024はQ4_K_Mが256要素を144バイトに詰めた「入れ物の形」でした(5376÷256×144)。ノードが重みの形をそのまま読んでいるためです。
要らなかったもの
「H3は続きのセグメントが暗くなる色の偏りがある」というノード(ToneCompensate)も測りました。発想は巧妙で、セグメントの重なり部分が「同じ内容の2つの描画」であることを利用して偏りを取り出す。ところが3場面で測ったら、偏りは どれも1/255未満で、向きも揃わない(夜景はむしろ明るくなった)。当てると逆に崩す恐れがあるので入れていません。
こういう「測ったら要らなかった」も、記録に残す価値があると思っています。次に同じことを調べる人の1日を節約できるので。
機械を増やす — 投げずに、取りに来させる
最後は力技で、隣にある4090マシンにも仕事を分けました。設計は「こちらから投げる」ではなく「向こうから取りに来させる」。区間の行列をサーバーに置き、空いている機械が1つずつ取っていく。速い機械が自然に多く取るので、分担比を設計に入れる必要がありません。4090側はComfyUIをネットに開かずに済みます。
効果は1.4倍(3.8時間 → 2.7時間)。細かいコツとして、参照画像ありの仕事と静止画の仕事を交互に配ると11GBのモデル積み替えが挟まって固定費が55秒 → 210秒に戻るので、同じ種類を続けて配るようにしています。
ちなみに4090側にもINT8アテンションを入れてもらったところ、そちらは1.34倍でした。5090の2倍に届かないのは、向こうの測定が短い尺(124フレーム)で、アテンション以外の割合が大きいため、と見ています。これも「同じ技術でも環境と条件で数字が変わる」の例です。
測り方の作法(3週間で4回踏んだ)
1シード、1本で決めない
対照を必ず取る(プロンプトに「日本人女性」と書くだけで顔の一致度は0.13出る。差を見ないと「顔が出た」とは言えない)
冷えた1本目を捨てる。同じワークフローを2回投げるとキャッシュに当たって0.1秒になるので、シードを変える
形が同じでも、順序は分からない
ノード別に測る。合計だけだと固定費が隠れる
どれも当たり前のことですが、当たり前のことを4回間違えたので書いておきます。
おわりに
3週間前の「4分半」が「79秒」になりました。半分はRedditやHugging FaceやGitHubに置いてあったものを拾って、測って、入れただけ。もう半分は、拾ったものを疑って中を覗いたときに出てきたものです。
拾い物を「入れて動いたからOK」で済ませず、数字を測り直す。そのついでに、作者も気づいていない性質が見つかる。これを毎回やってくれるのがClaude Codeで、私はその報告を読んで「1」か「進めて」と返しているだけ、というのが正直なところです。
数字・手順・変換ツール・プロファイラはGitHubに置きました。diffusers形式のH3 LoRAをComfyUIに持ってくる人は、fc1の入れ替えのところだけでも見ていってください。
https://github.com/matsuo-koya/minimax-h3-notes
ただし、H3高速化の決定版としてfalが自社サイトで公開しているMiniMax H3 MaxとMax Turboのオープンウェイト化が控えているので、そこでまた大きく変わってくるはずです。
その前に、ChatGPT 6 Astraにも改良可能かお伺いを立ててみました。
改良は可能です。追加の高速化だけでなく、「LoRAをより忠実に変換する」「失敗や計測誤差を見逃さない」という点に、具体的な改善余地があります。
特に有望なのは、変換器の検証強化、AdaLNの基底変換、民生GPUで動く疎アテンションの再評価です。すでに導入済みのFastH3 4step+comfy-kitchen INT8 attentionは、本番用の基準として残すのがよいと判断します。
という回答を得たのでそれをClaude Fable 5.1にフィードバックし、さらなる改良を進めています。
※この記事はClaude Codeとの対話で生まれ、それに筆者が原稿整理・加筆したものです。






