ComfyUI の公式ブログは MiniMax H3 について「RTX 3060 のような GPU でローカル実行できる」と書いている。RTX 3060 は 12GB。手元の RTX 2070 SUPER は 8GB しかない。動いた。画素を4%増やしてもピーク VRAM は同じ 7.8GB の帯に載ったままで、1本にかかる時間だけが 29分から 78分になった。
MiniMax H3 は、映像とステレオ音声を1パスで同時に出す動画生成モデルになる。波の音も打鍵音も、映像と同じサンプリングの中で作られる。音声トラックを後から合成する工程が無い。試したくなったが、筆者の GPU は 8GB。最小 VRAM を明示した記述は、モデル本家の README にも公式ブログにも見当たらない。やってみるしかない。
結論から書くと、8GB で回すなら解像度 800×448・スケジューラ simple・20ステップを天井に据えるのがいい。124フレーム(5.17秒)まで通って29.3分。天井を決めているのは VRAM の残りではない。待ち時間になる。画素を4%増やしたら78分かかった。800×448 は音も聴いて確かめた。理由は全部このあとの実測にある。
先に、VRAM の話に隠れやすい要件を1つ。システム RAM が 64GB 要る。モデルは RAM 側にステージされてから GPU へ渡るので、VRAM より先にこちらが詰まる。8GB の GPU があっても、RAM が 32GB なら別の壁に当たる。
そして規約の話をする。ここを読み飛ばすと、環境を作った後で全部が無駄になりかねない。
目次
先に規約を確認する
踏むライセンスは1つではない。重みが MiniMax H3 Community License Agreement(独自規約)、テキストエンコーダの Qwen3-VL-32B が Apache 2.0、ComfyUI 本体が GPL-3.0、後段のアップスケールに使う 4x-UltraSharp が CC BY-NC-SA 4.0。4本ある。
実務に効くのは2点になる。H3 の規約は EU・英国・韓国・米国を除外している(日本は許諾範囲内なので申請は要らない)。そして 4x-UltraSharp は非商用で、この制限は H3 の規約をいくら読んでも出てこない。
条文の突き合わせと、生成した動画を当サイトに載せていない理由はMiniMax H3 のライセンスを条文まで読んだに分けて書いた。環境を作る前にそちらを読んでほしい。
既存の ComfyUI に入れず、別インスタンスを立てた
MiniMax H3 は ComfyUI 0.30.0 以上を要求する。筆者の環境で動いていた ComfyUI は 0.19.1 で、カスタムノードが18個ぶら下がっていた。サイトのアイキャッチ生成の保険経路もそこを向いている。
11マイナー版ぶんの破壊的変更を持ち込む理由が見つからず、H3 専用の ComfyUI をもう1つ立てた。ポートは 8189 にして既存の 8188 と分けてある。同時に起動できる。
重みは共有した。63.5GB を二重に持ちたくない。既存側は models がモデル置き場へのジャンクション、新しい側は extra_model_paths.yaml で同じ場所を指す。撤去は新しいフォルダを削除するだけで済む。
導入の手順
4ステップになる。筆者の環境で実際に通ったコマンドをそのまま置く。Windows での実行になる。
1. ComfyUI をクローンする
git clone --depth 1 https://github.com/comfyanonymous/ComfyUI.git comfyui_h3
cd comfyui_h3
既存の ComfyUI とは別のフォルダに置く。0.30.0 以上が要る。shallow にしたので git log は1件しか出ない。実際に動いているコミットは git rev-parse --short HEAD で見る。
2. 仮想環境と PyTorch を入れる
uv venv --python 3.12 .venv
uv pip install --python .venv\Scripts\python.exe torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126
uv pip install --python .venv\Scripts\python.exe -r requirements.txt
パッケージ管理に uv を使っている。標準の python -m venv と pip でも同じことができる。2行目が長いが、シェルごとに継続文字が違って壊れやすいので1行のままにしている。
cu126 を明示しているのは、Turing(RTX 20系)で要る sm_75 を含むビルドを取るため。新しいビルドは古いアーキテクチャを落としていることがある。
3. 重み5点を置く
配布元は Comfy-Org/MiniMax-H3 の再パッケージ版になる。直リンクを探し回る必要はない。テンプレートに「Model Links」というノートが付いていて、huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/... の直リンクがそこに並んでいる。
ただしノートに載っているのは4点で、R2V 用の ref2va が入っていない。T2V のテンプレートなので当然ではある。R2V も試すなら同じリポジトリの diffusion_models/ から自分で取る。
ファイル名と置き場所の対応はこうなる。
models/
├── diffusion_models/
│ ├── minimax_h3_fl2va_pruned_int8_convrot.safetensors T2V / I2V
│ └── minimax_h3_ref2va_pruned_int8_convrot.safetensors R2V
├── text_encoders/
│ └── qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors
└── vae/
├── minimax_h3_video_vae_fp16.safetensors
└── minimax_h3_audio_vae_fp32.safetensors
4. モデル置き場を指して起動する
手順3のツリーどおりリポジトリ直下の models/ に置いたなら、この手順は要らない。別のドライブに置いているときだけ、リポジトリ直下に extra_model_paths.yaml を作って場所を教える。両方やる必要はない。筆者は既存インスタンスと同じ実体を共有したかったので、こちらを使っている。
comfyui_shared:
base_path: E:/ModelCache/ComfyUI_models
is_default: true
vae: vae/
text_encoders: text_encoders/
diffusion_models: diffusion_models/
upscale_models: upscale_models/
.venv\Scripts\python.exe -u main.py --port 8189 --lowvram
ポートを 8189 にしているのは既存の 8188 と分けるためで、必須ではない。--lowvram は 8GB では要る。
ワークフローは公式テンプレートのままでいい
起動したら http://127.0.0.1:8189 を開いて、Template Library > Video > MiniMax H3 の T2V を選ぶ。自分でノードを組む必要はない。
テンプレートの中身を結線まで追ったら、既定値がほとんどそのまま使えた。サンプラー res_multistep、スケジューラ simple、20ステップ、fps 24、そしてフレーム数 124。このあと筆者が実測で選び直した設定と、5つが一致している。8GB のために変えるのは解像度1箇所だけになる。
解像度 864 x 480 -> 800 x 448
その他 変更なし(res_multistep / simple / 20step / fps24 / 124フレーム)
ここで一度読み違えた。ノードのウィジェットには 1344 と 768、フレーム数 73 と表示されている。それを既定値だと思って書きかけたが、この3つは入力に接続されていて実行時に上書きされる。表示されている数字は効いていない。
実際に効いているのはトップレベルの ResolutionSelector で、16:9 / 0.4MP / 32の倍数 の設定から 864×480 を計算して流し込んでいる。中身は計算ノードで、megapixels × 1024² の画素数を縦横比に割り付けて 32 の倍数へ丸める。同梱の換算表は 0.2MP の 608×352 から最大 1920×1088 まで14段あるが、0.2 から 1.0 までは 0.1MP 刻みなので 0.3MP の 736×416(306,176画素)と 0.4MP の 864×480(414,720画素)のあいだが空いていて、358,400画素の 800×448 は表に出てこない。縦横比のせいではない。800×448 の 1.786 は、表に載っている 864×480 の 1.800 より 16:9(1.778)に近い。
800×448 を出すには、ResolutionSelector の接続を外して width と height に直接入れる。megapixels に 0.35 と打てば済みそうに見えるが、UI のテキスト入力は刻み 0.1 に丸められて 0.35 は 0.3 になる(実測)。0.3 のまま回すと出てくるのは 736×416 で、この記事の設定と違うものができあがる。ワークフローを API 形式の JSON で投げるなら丸めは掛からず、0.35 で 800×448 が出る(これも実測)。
既定の 864×480(0.4MP)のまま回すと何分かかるかは測っていない。ただし、それより画素の少ない 832×448(372,736画素)が崖を越えて 78.1分だったので、少なくとも 800×448 の 29.3分では済まない。崖の先の 74.6〜78.1分と同程度か、それより掛かるとみている(未検証)。はしごの次の段は 0.5MP の 960×544(522,240画素)で、これも測っていない。
フレーム数のほうは触らないほうがいい。秒数から ComfyMathExpression で計算していて、式が長さを17の倍数+5に丸める。5 / 22 / 39 / 56 / 73 / 90 / 107 / 124 / 141 …と飛び飛びの値しか取れない。既定の5秒がちょうど 124 になる。5.2秒と指定すると 141 に跳ねるが、141フレームは一度も測っていないので通るかどうか分からない(未検証)。なお5秒と指定しても実尺は 5.17秒になる(124 ÷ 24)。
筆者の構成。
| 要素 | 値 |
|---|---|
| GPU | RTX 2070 SUPER / VRAM 8GB(Turing・sm_75) |
| システム RAM | 64GB。実質的な要件で、生成中はここが先に埋まる(下の実測) |
| ComfyUI | master 2340099(自己申告のバージョンは 0.30.0 のまま。タグが更新されていないので、実体は git rev-parse --short HEAD で見る) |
| Python | 3.12.13(uv で管理) |
| PyTorch | 2.13.0+cu126(sm_75 を含むビルド) |
| 起動フラグ | --lowvram |
| ポート | 8189 |
extra_model_paths.yaml は ComfyUI の .gitignore に入っていて、リポジトリには残らない。これが無いまま起動すると、リポジトリ内の空の models\ を見にいって重みを1つも解決できない。起動バッチが毎回この yaml を確認し、無ければ生成し、モデル置き場のドライブが見えなければ起動前に止まるようにした。
重みは5点。fl2va と ref2va の取り違えに注意する
落とすファイルは5つ、合計 63.5GB。
| 種別 | ファイル | サイズ | 用途 |
|---|---|---|---|
| diffusion_models | minimax_h3_fl2va_pruned_int8_convrot |
20,970,379,616 B | T2V / I2V |
| diffusion_models | minimax_h3_ref2va_pruned_int8_convrot |
20,970,379,616 B | R2V |
| text_encoders | qwen3vl_32b_minimax_h3_nvfp4_awq |
15,687,142,551 B | 全モード共通 |
| vae | minimax_h3_video_vae_fp16 |
5,207,808,496 B | 全モード共通 |
| vae | minimax_h3_audio_vae_fp32 |
605,254,808 B | 全モード共通 |
公式チュートリアルのダウンロード一覧には T2V ぶんしか載っていない。R2V を試すつもりなら ref2va も要る。どの重みを読むかは、インストール先の comfyui_workflow_templates_json にあるテンプレート JSON で確認できる。
この2つには罠がある。中身は別物なのにサイズが1バイトも違わない。safetensors のヘッダも 95,416 バイトまで完全に同一で、量子化レベルを変えてもサイズは一致し続ける。コピーやリネームで取り違えても、ファイルサイズを見る検査では絶対に気づけない。中身のサンプルを SHA256 で照合して、ようやく検出できるようにした。
量子化はどれを選ぶか
拡散モデルは int8_convrot を選んだ。ComfyUI が起動時に演算経路を報告してくれる。
Native ops: convrot_w4a4, int8_tensorwise
emulated ops: mxfp8, float8_e4m3fn, nvfp4, float8_e5m2
Turing でも convrot と int8 はネイティブ経路に乗る。テキストエンコーダに選んだ nvfp4 のほうはエミュレーションで、NVFP4 のネイティブ実行は Blackwell 以降になる。int8_convrot 版のテキストエンコーダ(27GB)に差し替える手もあるが、筆者は試していない。もう27GB 落とす気になれなかった、というだけの理由になる。エンコーダ側の量子化差は体感に出ないという報告は見かけるが、筆者は測っていないので「効かない」とは書けない。15.7GB のまま使っている。
8GB 用の設定
結論の設定を先に置く。
scheduler: simple 音声込みなら simple 固定(normal は音声が壊れる)
sampler: res_multistep
steps: 20 25 に上げても改善しなかった
解像度: 800x448 16:9 の実用上限(29.3分)。音も聴いて正常だった
※ 幅も高さも 32 の倍数であること
フレーム数: 124 5.17秒。ここは削らなくていい
起動: --lowvram
解像度のグリッドは32なので、768x432 は通らない(432 ÷ 32 = 13.5)。この付近で 16:9 に近い有効値は 800x448(1.786。16:9 = 1.778 との差 0.008)と 736x416(1.769・差 0.009)でほぼ横並びになる。768x448(1.714)は比率では一歩譲る。グリッド上に厳密な 16:9 も存在する。512x288 と 1024x576 がちょうど割り切れる。前者は 640×352 より下の位置づけで、後者は 589,824 画素で筆者が測った範囲の外にある。
VRAM より先に RAM が埋まる
ここは見落とされやすいので、測り直した数字を置く。この節の GB と MB は 1,024 進(GiB / MiB)で、psutil が返すバイト数をそれぞれ 1,024 で3回・2回割ったものになる。VRAM の MB も nvidia-smi が返す MiB になる。物理 63.7GB のマシンで、ComfyUI にモデルを解放させた状態の使用量が 26.4GB(27,035MB・ブラウザなど他のアプリ込み)。そこから最小の 416×224 で生成を回すと、ピークが 60.4GB(61,821MB)まで上がった。空きは 3.3GB 残る。
増分は 34.0GB になる。内訳はモデルのステージングで、テキストエンコーダ 14,956MB と拡散モデル 21,603MB を足すと 35.7GB。ほぼ一致する。生成そのものが 34GB 前後の RAM を要求するということになる。
32GB のマシンでは、VRAM が足りていてもここで止まる。8GB の GPU で動かす話をしているのに、実際にきついのは RAM のほうだった。64GB を要件として見ておいたほうがいい。
768×448 でも測った。ピークは 59.7GB(61,088MB)で、最小の 60.4GB との差は1%。画素数は3.7倍だが RAM はほぼ動かない。埋めているのはモデルの常駐分(35.7GB)で、解像度で増えるぶんはその横では小さい。あとから足した 800×448 と 768×512 は 58.0GB / 57.9GB(59,429MB / 59,275MB)で、最小の 60.4GB より4%ほど低い。解像度を上げて増えることはなかった。下がった理由までは測っていない(測定時のベースラインの差が効いているとみている)。
後段のアップスケールは軽い。同じ測り方でピーク RAM 23.4GB(23,988MB)、VRAM 4,979MB、312秒で済んだ。重いのは生成の本体になる。別の回では 4,886MB・323秒だったので、この工程も1割ほどはぶれる。
フレーム数が VRAM に効くかどうかは、解像度で変わる
最初、筆者は「フレーム数を増やせば VRAM が足りなくなって OOM する」と思っていた。640×352 で測ったら、逆の結果が出た。
| 条件 | サンプリング | 総時間 | ピーク VRAM |
|---|---|---|---|
| 640×352 / 39f / 20step | 8.59 s/it | 210秒 | 7,470 MB |
| 640×352 / 124f / 20step | 41.3 s/it | 900秒(15.0分) | 6,788 MB |
フレーム数を3.18倍にして、VRAM は下がった。長い系列はチャンクに割って処理されているとみられる。代わりにサンプリングが 8.59 から 41.3 s/it へ4.8倍、総時間は 210秒から900秒へ4.3倍に伸びた。なお 39f の回のピーク 7,470MB は3秒間隔サンプリングでの値になる。
ここで話を止めていたら間違えていた。同じ比較を 768×448 でやると結果がひっくり返る。
| 条件(768×448 / 20step / simple) | ピーク VRAM |
|---|---|
| 39f | 6,886 MB |
| 124f | 7,906 MB |
解像度もステップ数も揃えて、フレーム数だけで約1,020MB 増えている。640×352 では増えなかったものが、768×448 では増える。
この2行は 39f が旧コード、124f が新コードでの測定になる。旧コード同士でも 6,886MB → 7,921MB の +1,035MB なので、どちらの組み合わせでも増加は約1GB。結論は変わらない。キャンバスが大きいほどチャンク1つあたりの中間テンソルも大きくなるからだと考えているが、内訳は測っていない。
実務上はこう読むことにした。解像度から近づいてもフレーム数から近づいても、同じ 7.8GB 付近で頭打ちになる。640×352 のように帯より下にいるあいだは、フレーム数を伸ばしても VRAM は増えない。帯に入ると、どちらの軸も VRAM を押し上げるように見える。768×448 の124フレームは残り286MB で通っている。筆者はこの残りを「天井までの距離」だと読んだが、それが誤りだった(次節)。
解像度そのものは、VRAM にも時間にも効く。
| 解像度(124f / 20step) | サンプリング | 総時間 | ピーク VRAM |
|---|---|---|---|
| 640×352 | 41.3 s/it | 15.0分 | 6,788 MB |
| 704×384 | 未測定 | 17.6〜17.9分 | 6,950〜7,065 MB |
| 768×448 | 84.2 s/it | 26.1〜29.3分 | 7,784〜7,921 MB(95.0〜96.7%) |
| 800×448 | 未記録 | 29.3分 | 7,831 MB(95.6%) |
| 832×448 | 未記録 | 78.1分 | 7,922 MB(96.7%) |
| 768×512 | 未記録 | 74.6分 | 7,828 MB(95.6%) |
この表もコード版が揃っていない。640×352 は旧コード、704×384 は新コード、768×448 は新旧あわせて3本(新コードで 28.3分・7,906MB と 26.1分・7,784MB、旧コードで 29.3分・7,921MB)になる。下3行は新コードで、この記事のために測り足した。s/it を記録できているのは旧コードの回だけで、レンジ全体の代表ではない。サンプリング間隔も揃っていない。下3行だけ2秒間隔で、他は10秒間隔になる。10秒間隔に揃えると 800×448 = 7,800MB / 832×448 = 7,916MB / 768×512 = 7,822MB。3本とも 768×448 の3本が散らばる 7,784〜7,921MB の幅に収まる。画素を増やしてもピークがこの幅から出ない。
同じ設定を繰り返すと、時間は1割ぶれるが、ピーク VRAM は1.5%しか動かない(768×448 で 7,906 と 7,784MB、416×224 で 7,203 と 7,123MB)。帯の位置は安定している。
画素が1.53倍になると時間がおよそ2倍、VRAM が1,100MB ほど増える。8,192MB のうち残りは 270〜410MB。ここから画素あたりの増え方を出して上の段を外挿し、「768×512 は +460MB で届かない、800×448 は +135MB で賭けになる」と書いていた。その計算は間違っていた。基点にした 640×352 は旧コードでの測定で、当てた先の 768×448 は新コードでの測定になる。版をまたいで1本の直線を引いていた。
両方とも実際に回した。
| 解像度(124f / 20step) | 外挿の予測 | 実測ピーク | 実測時間 |
|---|---|---|---|
| 800×448 | 8,041 MB | 7,831 MB | 29.3分 |
| 768×512 | 8,369 MB(OOM 見込み) | 7,828 MB | 74.6分 |
どちらも OOM しない。2本のピーク VRAM の差は3MB。768×512 の画素は 800×448 より 9.7% 多いのに、である。増えたぶんは全部時間に出た。29.3分が 74.6分になっている。
この3MB を額面どおり受け取らないでほしい。ピーク VRAM は nvidia-smi を2秒間隔で叩いた最大値で、GPU 全体(デスクトップの描画込み)の値になる。短いスパイクは取りこぼす。3MB は測定の分解能より小さいので、言えるのは「同じ帯に載った」までになる。既存の測定値は10秒間隔なので、そちらに間引いた値も出した(800×448 = 7,800MB / 768×512 = 7,822MB)。どちらで読んでも結論は動かない。時間のほうも各1本ずつで、同一設定でも1割ぶれる。2.55倍という比は 2.3〜2.8倍と読むのが正しい。
RAM で説明がつくかも見た。大きいキャンバスでページングに入っただけなら、時間はこうやって伸びる。ピーク RAM は 800×448 が 58.0GB、768×512 が 57.9GB。ほぼ同じうえに 5.7GB 空いていた。測ったのは空き容量であってページ I/O ではないので言えるのはここまでだが、RAM 不足によるスワップでは説明がつかない。
VRAM が動かず、時間だけが伸びる理由
20GB のモデルを 8GB のカードで動かしている以上、常駐できる重みの量は空き VRAM が決める。解像度を上げると中間テンソルがその空きを食い、押し出された重みは RAM から毎ステップ流し込まれる。ピーク VRAM が 7.8GB 付近から動かないのは、これが理由だとみている。内訳までは測っていないので、機構そのものは断定しない。
張り付いて見えるのは上の帯だけ、という点は押さえておきたい。640×352 は 6,788MB、704×384 は 6,950〜7,065MB で、帯より 0.7〜1.1GB 低い(実測レンジ 719〜1,133MB。10秒間隔の値で統一した)。344,064 画素あたりから上で頭打ちになるという話で、解像度と無関係に一定なのではない。この比較は 124フレーム・20ステップに揃えたときの話になる。
読み替えるとこうなる。測った範囲(393,216 画素まで)では、上限を決めているのは待ち時間になる。VRAM の残りではない。1本30分を境目に置くなら、筆者が確かめた中で収まる最大は 800x448 になる。
崖の位置も測った。832x448(372,736 画素。800×448 から +4.0%)が 78.1分かかった。ピーク VRAM は 7,922MB で帯の中になる。768×448 から 800×448 へ 4.2% 増やしても時間はほぼ横ばい(26.1〜29.3分 → 29.3分)だったのに、そこから 4.0% で 2.7倍に跳ねる。崖は 358,400〜372,736 画素の間にある。崖の先の2点は 78.1分(832×448)と 74.6分(768×512・393,216 画素)で、画素の多いほうがむしろ速い。差の 4.5% は同一設定でも出る1割のぶれに収まるので、この2点では区別できない。2点のあいだと、その上がどうなるかは測っていない。832×448 そのものを狙う価値は薄い。縦横比 1.857 は今回並べた有効値の中で 16:9 からいちばん遠く、時間は 2.7倍かかる。崖の位置を確かめるためだけの1本になる。
768x512 は VRAM には入る。16:9 が要るなら不利になる。3:2 なので 16:9 に切ると 768x432 まで落ちるが、432 ÷ 32 = 13.5 でグリッドに乗らないから生成時には指定できず、後段でクロップして 331,776 画素になる。800x448 の 358,400 画素を下回る(800x448 のほうを厳密な 16:9 に切っても 796×448 = 356,608 画素で、まだ上回る)。75分待って画素が減るので、筆者は使いどころを見つけられなかった。16:9 に縛られないなら話は変わる。3:2 のまま使うぶんには 768×512 のほうが画素は 9.7% 多い。
音も聴いた。800×448・832×448・768×512 で作った3本とも正常に鳴っていた。scheduler は simple で回している。これで解像度の升は3つ埋まり、simple で聴いて正常だった本数は16本になる。
解像度を変えるときは 5フレーム・4ステップの試走を先に挟むことにしていた。768×448 の試走で 101秒。30分走らせて捨てるより安い。
この試走も、解像度の判定には使えなかった。800×448 の試走が 7,355MB、768×512 の試走が 7,378MB。画素は 34,816 も違うのに、差は 23MB しかない。5フレームだとテキストエンコーダを読み込む段がピークになり、サンプリング段がそこへ届かないためとみている。試走で分かるのはグラフが最後まで通ることまでで、本番のピークは本番でしか測れない。以前ここに「試走値に1GB 足したあたりを本番の目安にする」と書いていたが、その目安だと 800×448 は 8,355MB と読めて除外されてしまう。実測は 7,831MB で通る。
スケジューラを normal にすると音声が壊れる
これが一番手こずった。ある時期の出力の音声が、全部ざらついたノイズになっていた。
最初は解像度の限界だと考えて、そう書いた。次にコードのバージョンが古いせいだと考えて、そう書き直した。どちらも外れていた。
外した原因はどちらも同じで、比べた2本の条件が2つ以上ずれていたことになる。解像度もフレーム数もコードのバージョンも同時に違う出力を並べて、そこから1つの原因を名指ししていた。
スケジューラだけを変えて他を完全に揃えた2本を作り直して、ようやく決着した。同じシード・同じプロンプト・768×448・39フレーム・同じコードで、simple は正常、normal はノイズ。聴いた範囲では normal が全数ノイズ、normal 以外は17本すべて正常だった(simple 16・beta 1)。この17本は題材が数種類しかないので、独立した17試行というより「同じ系統のプロンプトで条件を振った17本」になる。σ スケジュールを変える系が軒並み壊れるのかとも考えたが、beta は正常だった。normal 固有の症状になる。
計測の道具にも引っかかった。音量(volumedetect)はノイズと実音を区別しない。スペクトル平坦度も駄目だった。スケジューラ以外を完全に揃えた2本で測ると、正常なほうが 0.1269、ノイズのほうが 0.1281。ノイズのほうがわずかに高いだけで、実質同じ値になる。雑音と判定済みのファイル群は 0.116〜0.17 に散らばっていて、正常な出力の値と帯域が重なる。
それでも「0.4を超えたら疑わしい」くらいの粗いふるいには使えるだろうと考えて、しばらくそう書いていた。この記事のために測り直したら、これも外れた。聴いて正常だと確認済みのクリップが 0.5100 を示した。雨の音を含む題材で、雨のような広帯域音はもともとスペクトルが平坦になる。閾値は題材をまたいだ瞬間に成立しなくなる。
音質の判定に使える機械的な指標を、筆者はまだ見つけられていない。最後は自分の耳で聴くしかない。
映像だけを見れば normal のほうが鮮鋭ではある。
| 条件(768×448 / 39f・1変数のみ変更) | 時間 | ピーク VRAM | 鮮鋭度 | 音声 |
|---|---|---|---|---|
20step / simple |
354秒 | 6,886 MB | 61.6 | 正常 |
25step / simple |
430秒(+21%) | 7,021 MB | 59.0 | 正常 |
20step / beta |
359秒 | 6,793 MB | 77.1 | 正常 |
20step / normal |
359秒 | 7,014 MB | 92.2 | ノイズ |
音を使わないなら normal でいい。音込みなら simple にする。解像感が欲しいときの代替は beta だが、音声を1本しか聴いていないので本番前に毎回確かめている。
ステップ数を25に上げても鮮鋭度は上がらなかった。21%長く待って差が見えない。20のままにしている。
参考事例: 同じ題材を最低画質と高品質で作った
ここまでの設定でどれくらい差が出るのか、同じプロンプト・同じシードで2本作った。題材は「雨の夜の作業デスク、メカニカルキーボードを打つ手元」。窓を叩く雨、打鍵音、遠くの雷と、音のほうにも判断材料が残るものを選んだ。ロゴ・可読テキスト・人物の顔はプロンプトで除外している。ブランドや実在の人物が写り込むと、規約以前に著作権と肖像の問題になる。
動画そのものは載せていない。生成物を許諾地域の外で表示することを禁じる条項があり、当サイトは全世界から見えるためになる。判断の経緯はライセンス編に書いた。数字で読んでほしい。
| 最低画質 | 高品質 | 高品質+アップスケール | |
|---|---|---|---|
| 解像度 | 416×224 | 768×448 | 1536×896 |
| ステップ数 | 4 | 20 | 後段処理 |
| 尺 / フレーム | 5.167秒 / 124 | 5.167秒 / 124 | 5.167秒 / 124 |
| 所要時間 | 2分1秒 | 28分16秒 | +5分23秒 |
| ピーク VRAM | 7,203 MB | 7,906 MB | 4,886 MB |
| ファイルサイズ | 588,010 B | 430,845 B | 1,239,122 B |
| 鮮鋭度(768×448換算) | 129.6 | 172.7 | 383.2 |
| 音声 | 3本とも aac / 32kHz / ステレオ2ch・聴取して正常(アップスケール版は元の音のコピー) | ||
時間が14倍になる。読み取るところはそこだ。
ピーク VRAM の差は703MBしかなかった。画素数は3.7倍違うのに、である。ただしこの2本はステップ数も 4 と 20 で違うので、差を解像度だけに帰せるわけではない(ステップ数の寄与は別の A/B で 20→25 のとき135MB)。内訳は測っていない。読み取れるのはこうなる。解像度を下げても VRAM はさほど空かない。下げて得られるのは時間のほうになる。
ファイルサイズが逆転しているのも面白かった。画素が3分の1以下の最低画質版のほうが、高品質版より157KB大きい。4ステップの出力は粒状のノイズを多く含んでいて、ノイズは圧縮が効かないからだとみている。ファイルが小さいことは品質が低いことを意味しない。
鮮鋭度の数字は扱いに注意が要る。解像度が違う動画の Laplacian 分散をそのまま比べると画素密度の差が混ざるので、上の表では全部を 768×448 に揃えてから測っている。ネイティブのまま測ると最低画質版が 1190.5 を出すが、これは画素あたりの階調差が大きいだけで精細さではない。アップスケール後の 383.2 も同じで、4x-UltraSharp がエッジのコントラストを立てたぶん上がっている。増えたのは輪郭の強さで、元の映像に無かった情報が戻るわけではない。
音は3本とも聴いた。うちアップスケール版は元の音のコピーなので、独立した確認は2本ぶんになる。どちらもまともに鳴っていた。4ステップまで落としても音声は崩れなかった。映像は見るからに粗いのに、窓を叩く雨も打鍵音も破綻していない。
これで原因がスケジューラだけに確定したわけではない。normal を4ステップで回したことは一度も無いし、いま比べた2本は解像度もステップ数も違う。言えるのは「simple のもとでは 4 / 20 / 25 ステップのどれでも音は正常だった」までになる。低ステップが雑音を招く、という候補が1つ消えただけで、設定を変えたら聴くという手順は変えていない。
ついでに、機械指標が当てにならないことがもう一度確認できた。最低画質版の平坦度は 0.3945。聴いて正常と分かっている3本が 0.1269・0.3945・0.5100 と、目盛りのほぼ全域に散らばっている。正常な出力がこれだけ広がるなら、どこに線を引いても雑音は分けられない。
調べて捨てた選択肢
効かなかったもの、やってはいけないもの、判断を保留したものを並べておく。同じ道を辿らなくて済むはずになる。
- Sage Attention は使わない。H3 では映像も音声も純粋なノイズになる(ComfyUI の Issue #15263)。
- 推論だけなら非 pruned 版(34GB)は要らない。本家の README によると、33B のうち約13B は AdaLN 系の分岐にあり、その変調出力は事前計算してキャッシュできるので推論時に読み込む必要がない。サイズも合う。非 pruned の int8 が約34GB、pruned が 20,970,379,616 B ≒21GB で、差の約13GB が落ちた13B ぶんになる。ただし本家はファインチューニング用に完全な重みを出しているので、学習させるなら34GB のほうが要る。
- テキストエンコーダの int8_convrot(27GB)は未検証。効かないと書いている記事を見かけるが、筆者は落としていないので判断を持っていない。
--cpu-vaeやタイル分割デコードでは解像度を上げられない。VRAM のボトルネックは VAE デコードではなくサンプリングにある。実測差は 65MB だった。
解像度を上げる代わりに使えるのが後段のアップスケールになる。LoadVideo → GetVideoComponents → ImageUpscaleWithModel → ImageScale → CreateVideo → SaveVideo と繋いで 4x-UltraSharp で4倍にし、1536×896 へ落とす。124フレームで323秒・ピーク 4,886MBだった。音声は GetVideoComponents の AUDIO 出力をそのまま繋げば維持される。ただし音質は元のままコピーされるので、ノイズが乗った動画をアップスケールしても直らない。実際に試して、元がノイズなら結果もノイズだった。
この後段だけはライセンスが別物になる。4x-UltraSharp は CC BY-NC-SA 4.0 で、表示・非商用・継承の3条件が付く。仕事の成果物に使うなら、ここは外すか商用可のアップスケーラに差し替える必要がある。H3 側の規約をいくら読んでも、この制限は出てこない。
環境が壊れていないことを毎回確かめる
この構成は壊れ方が静かになる。yaml が1行ずれるだけで別のファイルを読み、それでも生成は成功してしまう。環境の不変条件を検査するスクリプトを書いて、生成前に走らせている。
この検査は6回書き直した。全部「検査自体が偽の合格を出す」欠陥だった。効いた直しを並べる。
- ファイル名の一覧で判定するのをやめ、ComfyUI 自身に解決させた絶対パスを照合する。前方一致や「ルート配下か」の包含判定では
ComfyUI_models_oldやbackup\vae\を通してしまう。 - サイズ一致は内容の同一性を証明しない(前述の fl2va / ref2va)。内容サンプルの SHA256 で照合する。
- 検査項目のキーが実ファイル名とずれると、その検査が黙ってスキップされて合格が出ていた。実行件数を期待値と突き合わせる。
サーバは yaml を起動時にしか読まないので、yaml のほうが新しければ失格にする鮮度検査も足した。今は ALL CHECKS PASSED (29 checks) と件数つきで返る。わざと壊す引数もあり、壊して検出されなければ検査が素通しになっていると分かる。
8GB で使うかどうか
筆者は使わない。少なくとも仕事では使わない。
止めているのは VRAM でも30分でもない。規約になる。生成物の側にまで地域制限が伸びていて(§V.4)、全世界から見える媒体に出すと除外地域での “display” に当たりうる。商用の製品・サービスなら UI に “MiniMax H3” を目立つ形で出す義務(§IV.2)が付き、他者にアクセスを渡すなら受領者を同等以上の条件で縛る義務(§V.2)まで来る。画質を上げようとして後段に足した 4x-UltraSharp は CC BY-NC-SA 4.0 で、そもそも商用不可だった。条文を1件ずつ突き合わせた表はライセンス編にある。
商用で動画を作るなら、筆者は Higgsfield のようなクラウド側のサービスを MCP 経由で叩くほうを選ぶ。20GB のモデルを2本落として 8GB のカードに押し込み、RAM を 60GB 使って30分待つ工程が丸ごと消える。読む規約が消えるわけではない。そちらの利用規約は別途自分で確かめることになる。
ローカルで回す価値が無いとは思っていない。日本国内で回して自分で見るぶんには地域制限に掛からないので、仕組みを理解する・映像と音が1パスで噛み合って出てくるところを自分の目で確かめる、という用途は残る。筆者がこの環境を作ったのもそこまでになる。
これから試すなら、まず 640×352 で1本回して自分の GPU での所要時間を測る。次に 800×448 の本番を1本通す。試走のピーク VRAM は解像度の判定に使えないので、本番で測るしかない。スケジューラは simple から動かさない。そして出来上がったら音を聴く。設定を1つでも変えたら、そのたびに聴く。
そして最初に、LICENSE 本文を自分で開いて読んでほしい。規約は改訂されるし、Exhibit A は随時更新すると本文にある。この記事は2026年8月8日に取得したファイルに基づいている。
ライセンス本文まで確かめる話はClaude Codeのトークンを削るOSS 11本でも書いた。GitHub のライセンス欄が3本で判定不能だった話。ローカルでモデルを走らせる側ならTranscription Studio の作り方が近い。
