ComfyUIで作った動画を4Kにアップスケールしようとしたら、PCのメモリ使用量が一気に天井近くまで跳ね上がって全体が固まった。あるいは、長い動画を流したら15分以上処理した末に「メモリが足りない」とエラーを吐いて、待った時間ごと無駄になった ── そんな経験はないだろうか。
結論から先に言う。ComfyUIで8秒・4K・60fpsの動画をアップスケールすると、システムRAMを67〜77GBも食う。メモリが足りなければ、15分以上処理した末にエラー(OOM)で落ちる。筆者はAdobe Stock向けに8秒・4K・60fpsの動画を毎日量産していて、このメモリ問題にさんざん苦しめられてきた。加えて、Topaz Video AIのような有料の動画アップスケールソフトにお金をかけるのも避けたかった ── ComfyUIで使い慣れたESRGANモデルが手元にあるのだから、できればそれで済ませたい、と。
たどり着いた答えが、ComfyUIを介さず同じESRGANモデルを直接動かす「スタンドアロン」方式だ。ガワを外しただけで、数字はこう変わった。
- 消費RAM:67〜77GB → 1.4GB(約48分の1。16GBのPCでも回る)
- 処理時間:19分 → 7分(RTX 5080実測、2.6倍速)
- 安定性:メモリ不足で落ちる → 何秒の動画でも確実に完走
使っているモデルは同じなので、画質は一切変わらない。有料ソフトに乗り換える必要もない。落ちる・遅い・メモリを食う、の3つを、追加コストゼロで一度に解決できる。
この記事では、なぜComfyUI内のアップスケールがメモリを食い潰すのかを仕組みから噛み砕き、そのうえでComfyUIの外でESRGANを動かす方法を、実際に動くコードと、2枚のGPUでの総当たり実測付きで解説する。GPUが1枚あれば誰でも再現できる。なお、ComfyUI内のノードで手軽にアップスケールする基本手順は別記事「LTX 1動画を4Kアップスケールする」で解説しているので、まずGUIで試したい人はそちらから読んでほしい。本記事はその発展編にあたる。
そもそも「スタンドアロン」とは?
ComfyUIやStable Diffusion WebUIのような統合GUI環境を介さず、必要な処理だけを単体で動かす独立したプログラムのことを指す。本記事では、ComfyUIが内部で使っているESRGANモデルを、ComfyUIを起動せずにPythonスクリプトから直接呼び出す方式を「スタンドアロン」と呼んでいる。GUIの便利さと引き換えに抱える「重さ」を取り払い、必要な処理だけを最小構成で回すイメージだ。
この記事で分かること
- ComfyUIの動画アップスケールが、なぜシステムRAMを67〜77GBも食うのか(仕組みから)
- ComfyUIを使わずESRGANを直接動かす方法 ── コピペで動くコード付き
- スタンドアロン vs ComfyUI を2種類のGPUで総当たりした実測(メモリ・速度・GPU稼働率)
- 自分の用途ではどちらが向いているか
- eGPU(Oculink)の帯域やGPU指定など、実際に詰まりやすい落とし穴
なぜComfyUI内のアップスケールはメモリを食い潰すのか
ComfyUIは、一度実行したノードの結果をメモリ上にキャッシュして、次の実行を速くする設計になっている。中間テンソル、デコード済みのフレーム、各ノードの出力 ── これらが処理の間ずっとメモリに残る。静止画を1枚ずつ触っているうちは、この「全部覚えておく」挙動が快適さにつながる。問題は動画だ。
動画のアップスケールワークフローは、たいてい全フレームを一度メモリに展開してからノード間を流す。8秒・60fpsの動画なら481フレーム。これを4K(3840×2160)まで引き上げると、出力は1フレームあたり約35MBになる。481フレーム分をまとめて抱えれば、それだけで十数GB。さらにComfyUIのアップスケールノード(ImageUpscaleWithModel)は、タイルに分割してVRAMを節約しながら処理したあと、最後に全フレームの4K出力を1つの巨大なテンソルにまとめてCPUメモリに書き戻す。このまとめる瞬間に、メモリ要求がピークに達する。
実際に測ると、8秒・4KアップスケールでComfyUIはシステムRAMを67〜77GB消費した。RTX 5080の環境(RAM 96GB)では、96GBをほぼ使い切ってギリギリ完走している。動画自体はちゃんと完成するが、消費量が尋常ではない。そして、メモリに余裕がない状態でこれをやると、最後のまとめ段階でこう落ちる。
RuntimeError: [enforce fail at alloc_cpu.cpp:121] DefaultCPUAllocator:
not enough memory: you tried to allocate 68089282560 bytes.
「68,089,282,560バイト=約68GBを確保しようとして失敗した」というエラーだ。たちが悪いのは、これが15分以上処理した末の最終段階で起きること。途中までは普通に進むので気づけず、待った15分がまるごと無駄になる。フレーム数が増えれば必要メモリも青天井に増えるので、長い動画ほど詰まりやすい。
これはComfyUIの欠陥ではない。GUIで何でも自由に繋げられる汎用性と引き換えのトレードオフだ。だが「決まった処理を大量に回す」量産フェーズでは、この汎用性のコストが重くのしかかる。筆者のように毎日何十本も処理する用途では、致命的になりかねない。
筆者がスタンドアロン自作に行き着くまで
最初は素直にComfyUIの中で何とかしようとした。タイルサイズを下げてVRAMを節約し、フレーム数を分割し、メモリ管理系のカスタムノードも試した。VRAM側はそれで収まる。だが、最後にCPUメモリへ全フレームを集約する一括確保だけはどうにもならなかった。タイルはあくまでVRAM(GPU側)の節約策で、最終出力をRAMにまとめる設計そのものは変わらないからだ。
ここで発想を変えた。アップスケールの本体はESRGANというニューラルネットのモデルで、ComfyUIはそれを呼び出す「ガワ」にすぎない。だったら、ガワを外してモデルだけを直接動かせばいい。全フレームを抱え込まず、1枚処理しては書き出し、また1枚 ── と流していけば、メモリは一定に保てるはずだ。実際にそれを実装したら、RAM消費は1.4GBで頭打ちになり、しかもComfyUIより速くなった。以下、その作り方を順に示す。
spandrelとは何か ── ComfyUIの「中身」を直接借りる
鍵になるのが spandrel というライブラリだ。これはESRGANやSwinIR、HATといった超解像モデルを、アーキテクチャを自動判別して読み込み、実行してくれる。実はComfyUI自身もアップスケールの内部でこのspandrelを使っている。つまりComfyUIの中身そのものを、ComfyUIなしで直接呼べるということだ。
うれしいのは、ComfyUIの models/upscale_models/ に置いてある .pth ファイル(4x-UltraSharp.pth など)をそのまま使える点。モデルを買い直したり変換したりする必要は一切ない。普段ComfyUIで使っているモデル資産が、そっくりそのまま動く。
作り方 ── 1枚のGPUで動画を4Kアップスケールするスタンドアロンを組む
必要なものは3つだけだ。
- ComfyUIのembedded Python(
torchとspandrelが入っている。普段ComfyUIを使っているなら追加インストール不要) - アップスケールモデル(
4x-UltraSharp.pthなど、models/upscale_models/のもの) - ffmpeg / ffprobe(動画のフレーム入出力に使う)
このあとのコードで ハイライトした部分 が、自分の環境に合わせて書き換える場所(フォルダのパスやモデルのパスなど)だ。それ以外はそのままコピペでよい。
なお、ここで載せるのは仕組みをつかみやすいよう要点に絞った簡易版だ。生成AI動画やCGのようにフレーム間が安定した素材なら、これで実用十分の仕上がりになる。さらに凝った仕上げを足していく余地も残しているので、まずはこの最小構成で動かしてみてほしい。
ステップ1:モデルを読み込む
spandrelでモデルを読むのは数行で済む。fp16(半精度)にしておくとVRAMが減り、速度も上がる。
import torch
import spandrel
# モデルは絶対パスで指定する(例: D:/ComfyUI/ComfyUI/models/upscale_models/4x-UltraSharp.pth)
loaded = spandrel.ModelLoader(device="cuda:0").load_from_file("4x-UltraSharp.pth")
model = loaded.model.eval().half() # fp16 で省メモリ・高速化
print(f"scale={loaded.scale}x") # 4x-UltraSharp なら 4
これだけで、4倍アップスケール用のモデルがGPUに乗る。loaded.scale に拡大倍率(4x-UltraSharpなら4)が入っているので、後の計算に使える。このあと出てくる scale=4 や W*4 の「4」は、使うモデルの倍率に合わせて変えること(2倍のモデルなら2。loaded.scale を渡せば自動で揃う)。
ステップ2:1フレームをタイルに分割してアップスケールする
4Kクラスのフレームをそのままモデルに通すと、16GBのVRAMでも足りなくなる。そこで1フレームを 768pxのタイル に区切って順に処理し、結果を貼り合わせる。タイルの境目が目立たないよう、隣どうしを32px重ねて(パディング)処理するのがコツだ。
def upscale_frame(img, model, tile=768, pad=32, scale=4):
# img: [1, 3, H, W] の fp16 テンソル(GPU上)
_, _, H, W = img.shape
if H <= tile and W <= tile: # 小さければそのまま
with torch.inference_mode():
return model(img)
out = torch.zeros((1, 3, H*scale, W*scale), dtype=img.dtype, device=img.device)
for y in range(0, H, tile):
for x in range(0, W, tile):
# パディング付きでタイルを切り出す
ys, xs = max(y-pad, 0), max(x-pad, 0)
ye, xe = min(y+tile+pad, H), min(x+tile+pad, W)
with torch.inference_mode():
up = model(img[:, :, ys:ye, xs:xe])
# パディング分を除いて、出力の正しい位置に貼る
top, left = (y-ys)*scale, (x-xs)*scale
dy, dx = y*scale, x*scale
h = min(tile, H-y) * scale
w = min(tile, W-x) * scale
out[:, :, dy:dy+h, dx:dx+w] = up[:, :, top:top+h, left:left+w]
return out
タイルを小さくすればVRAM消費はさらに減り、大きくすれば速くなる。VRAM 16GBのGPUなら768pxがちょうど良いバランスで、実測のVRAMピークは13GBに収まった。
ステップ3:フレームを「流しながら」処理する(ここが一番の違い)
ComfyUIと決定的に違うのがこの部分だ。全フレームを抱え込まず、ffmpegから1枚ずつ受け取って→アップスケールして→すぐffmpegに書き出す。処理の流れはこうなる。
- producer:ffmpegが動画を生のRGBフレームに分解し、パイプで1枚ずつ吐き出す
- GPU:受け取ったフレームをタイル処理でアップスケール
- consumer:別のffmpegが、アップスケール済みフレームを受け取って4K動画にエンコードする
この3つを別スレッドで並列に走らせ、間を小さなキュー(入力64フレーム・出力16フレーム程度)でつなぐ。キューの上限を固定しているので、動画が8秒だろうと5分だろうと、メモリ上限は変わらない。同時にGPUが入出力待ちで遊ぶ時間も消える。コードにすると、次のようになる。
import subprocess, threading, queue, numpy as np
def upscale_video(src, dst, W, H, fps=60, model=model):
out_w, out_h = W*4, H*4
# producer: 入力動画 → 生RGBフレーム
dec = subprocess.Popen(["ffmpeg", "-i", src, "-f", "rawvideo",
"-pix_fmt", "rgb24", "-v", "error", "pipe:1"],
stdout=subprocess.PIPE)
# consumer: 生RGBフレーム → 4K h264
enc = subprocess.Popen(["ffmpeg", "-y", "-f", "rawvideo", "-pix_fmt", "rgb24",
"-s", f"{out_w}x{out_h}", "-r", str(fps), "-i", "pipe:0",
"-c:v", "libx264", "-crf", "8", "-pix_fmt", "yuv420p", dst],
stdin=subprocess.PIPE)
q = queue.Queue(maxsize=64) # 入力バッファ(上限固定)
frame_bytes = W * H * 3
def reader(): # producer スレッド
while True:
buf = dec.stdout.read(frame_bytes)
if len(buf) < frame_bytes:
break
q.put(np.frombuffer(buf, np.uint8).reshape(H, W, 3).copy()) # .copy() で書込可能に(警告回避)
q.put(None) # 終端マーカー
threading.Thread(target=reader, daemon=True).start()
while True: # GPU(メイン)
frame = q.get()
if frame is None:
break
t = torch.from_numpy(frame).to("cuda:0").half().permute(2,0,1)[None] / 255.0
up = upscale_frame(t, model) # ステップ2の関数
out = (up[0].permute(1,2,0).clamp(0,1) * 255).byte().cpu().numpy()
enc.stdin.write(out.tobytes()) # consumer へ
enc.stdin.close(); enc.wait()
ポイントは queue.Queue(maxsize=64) の maxsize。これがメモリの蓋になっている。読み込みが速すぎてもキューが64枚で詰まり、そこで待つので、メモリは一定以上膨らまない。今回検証した動画アップスケール構成では、ComfyUIが「全部読んでから処理する」のに対し、こちらは「読みながら処理して捨てる」── この差がメモリ48分の1を生んだ。なお、ComfyUIはワークフローや設定によって挙動が変わるので、これはあくまで本記事で測ったアップスケール構成での比較である点は補足しておく。
ステップ4:入力フォルダに入れた動画を、まとめて4K化する
1本ずつ指定してもいいが、せっかくなら「入力フォルダに動画を入れて実行すれば、出力フォルダに4K化されて並ぶ」形にしよう。これなら何本でも放り込むだけで処理が回り、量産がぐっと楽になる。ここまでのコード(ステップ1〜3)の後ろに、次を足すだけだ。
import json, glob, os
INPUT_DIR = "input" # 入力動画が入っているフォルダのパス(例 C:/Users/you/videos/input)。ここに動画を入れる
OUTPUT_DIR = "output" # 出力先フォルダのパス(例 C:/Users/you/videos/output)。ここに4K動画ができる
os.makedirs(OUTPUT_DIR, exist_ok=True)
for src in sorted(glob.glob(os.path.join(INPUT_DIR, "*.mp4"))):
name = os.path.basename(src)
dst = os.path.join(OUTPUT_DIR, name)
# 入力動画の幅・高さを ffprobe で取得
probe = subprocess.run(["ffprobe", "-v", "error", "-select_streams", "v:0",
"-show_entries", "stream=width,height", "-of", "json", src],
capture_output=True, text=True).stdout
W = json.loads(probe)["streams"][0]["width"]
H = json.loads(probe)["streams"][0]["height"]
print(f"処理中: {name} ({W}x{H} → {W*4}x{H*4})")
upscale_video(src, dst, W, H)
print("すべて完了")
ステップ1〜4をまとめて1つのファイル(例 upscale.py)として保存し、ComfyUI同梱のPythonで実行する。普段のpythonではなく、ComfyUIのembedded Pythonを使うのがポイントだ(torchやspandrelが入っているため)。
"C:\ComfyUI\python_embeded\python.exe" upscale.py
あとは input フォルダにアップスケールしたい動画を放り込んで実行するだけ。output フォルダに、同じ名前で4K化された動画が次々とできあがる。10本入れれば10本まとめて処理される ── これが「フォルダに入れておけば勝手に4K化されている」という、量産の自動化だ。1本ずつ流して処理するので、何本入れてもメモリは一定のまま増えない。
画質やサイズの調整は、ステップ3のエンコード側ffmpegで行う。-crf 8 が高画質設定で、4倍した結果が大きすぎる場合は -vf "scale=3840:2160:flags=lanczos" を足して4Kジャストに整えるとよい。Adobe Stockのような投稿用途では、ここを高品質寄りにしておく。音声は扱わないので、必要なら最後にffmpegで元動画の音声を合成する(FAQ参照)。
実測 ── ComfyUIとスタンドアロンのメモリ・速度を比較する
同じ8秒動画(1152×640 / 60fps / 481フレーム)を4K化する処理を、スタンドアロンとComfyUIで、さらにRTX 5080(PCIe直結)とRTX 5060 Ti(Oculink eGPU)で総当たりに測った。モデルはどれも同じ4x-UltraSharpだ。
| 構成 | 方式 | 処理時間 | RAMピーク | GPU使用率 |
|---|---|---|---|---|
| RTX 5080(直結) | スタンドアロン | 約7分(443秒) | 1.4GB | 96%(フル稼働) |
| RTX 5080(直結) | ComfyUI | 約19分(1140秒) | 76.6GB | 80〜97%(谷あり) |
| RTX 5060 Ti(Oculink) | スタンドアロン | 約15分(928秒) | 1.4GB | 断続的(帯域待ち) |
| RTX 5060 Ti(Oculink) | ComfyUI | 約36分(2186秒) | 67.8GB | 断続的 |
この表が言いたいことを、読者の実用に翻訳するとこうなる。
メモリ48〜55倍は「動くPCの幅」が変わるということ。 スタンドアロンはGPUに関係なくRAM 1.4GBで頭打ち。一方ComfyUIは67〜77GBを要求する。つまりComfyUIで安心して8秒・4Kを回すには、実質的に96GBクラスのRAMが要る。スタンドアロンなら16GBのPCでも同じ動画が処理できる。メモリが理由でアップスケールを諦めていた人にこそ効く差だ。
2倍以上速いのは予想と逆だった。 同じGPUで、5080はスタンドアロン443秒に対しComfyUIは1140秒(2.6倍)、5060Tiは928秒に対し2186秒(2.4倍)。筆者は当初「ComfyUIは全フレームをまとめてGPUに送るから、転送が一度で済んで速いはず」と思っていた。実測は真逆だった。全フレームを抱える方式は、巨大なメモリの確保と出し入れ自体がオーバーヘッドになり、かえって遅い。「読みながら捨てる」方が、メモリも時間も得をする。
GPUを遊ばせない。 5080直結でのスタンドアロンのGPU使用率は平均96%で、ほぼ張り付いていた。読み込み・処理・書き出しを並列に流すので、GPUが入出力待ちで止まらない。対してComfyUIは「全部読む→全部処理する→全部書く」と段階が分かれていて、段階の切り替えやメモリ管理のたびにGPUに谷ができる(使用率80〜97%で上下する)。GPUという一番高い部品を遊ばせないのは、量産では効いてくる。
eGPU(Oculink)は帯域に注意。 5060Tiは方式に関わらず、GPU使用率が断続的(ギザギザ)になった。Oculink(PCIe 4.0 x4、約8GB/s)の転送帯域が、4K出力(1フレーム約35MB)の往復に追いつかず、GPUが転送待ちで手を止めるからだ。PCIe 5.0 x16直結(約63GB/s)の5080では起きない。外付けGPUでアップスケールを回すなら、純粋な演算性能差以上に、この帯域ペナルティ(5080比でおよそ2倍の処理時間)を見込んでおくとよい。
どちらを選ぶべきか ── 向いている人で考える
ここまで読むとスタンドアロン一択に見えるかもしれないが、ComfyUIが劣っているわけではない。用途次第で向き不向きがはっきり分かれる、というのが正直なところだ。
ComfyUI内のアップスケールが向いている人
- まずGUIで手軽に試してみたい
- 処理するのは月に数本程度
- コードは書きたくない・触りたくない
スタンドアロンが向いている人
- 毎日のように動画を処理する
- Adobe Stockなどに動画を量産している
- 長尺の動画を扱う(メモリが青天井に膨らむのを避けたい)
- RAMに余裕がない(16〜32GBで4Kを回したい)
数本試すだけならGUIの手軽さが勝るし、量産フェーズに入ればスタンドアロンの省メモリ・高速・確実完走が効いてくる。筆者自身、まずGUIで手順を固めてから、量産に移るタイミングでスタンドアロン化した。この順番が一番無理がない。
動画に合わせてモデルを自動で選ぶ
ESRGAN系のモデルには、それぞれ得意分野がある。UltraSharpはシャープでディテール重視、Remacriは自然で有機的な質感、RealESRGANはノイズ除去に強い。どの動画にどれを当てるかを毎回手で選ぶのは面倒だし、判断もぶれる。
そこで、動画の視覚的な特徴(明るさ・エッジの量・ノイズ・彩度)を数フレームから数値化して、モデルを自動で振り分けている。ノイズが強ければRealESRGAN、暗くてのっぺりした場面もRealESRGAN、シャープで色が鮮やかならUltraSharp、それ以外の滑らかな映像はRemacri、といった具合だ。
筆者の場合、アップスケール前に必ずマルチモーダル検品にかけていて、その段階で「この動画は明るいのか暗いのか、ノイズが多いのか」といった中身をすでに見ている。だからモデルの選定も、この検品のタイミングでやるのが自然な流れになった。検品で出た判定をそのままモデル選びに渡せば、人手をかけずに動画ごとに合ったモデルを当てられる。さらに大きいのは、検品では画質が基準に届かない「失敗作」もこの段階で弾けることだ。アップスケールは1本に十数分かかる重い処理だから、ダメな動画を先に落としておけば、その分の無駄なアップスケールそのものを丸ごと減らせる。
ただし、これは筆者があらかじめ検品と仕分けの仕組みを組んでいるから成り立つ流れで、どの環境でもすぐ自動化できるわけではない。本記事ではその仕組みづくりまでは踏み込まないが、「検品とアップスケールはセットで設計すると無駄が減る」という考え方は知っておくと役に立つ。検品そのものについては「マルチモーダル検品とは何か」で詳しく書いている。
つまずきやすいポイント
「2枚目のGPUで動かしたい」のに別のGPUで動く
複数GPUの環境で cuda:1 を指定しても、意図と違うGPUが使われることがある。CUDAのデフォルトのデバイス順(FASTEST_FIRST)が、nvidia-smiの番号(PCIバス順)と一致しないためだ。同世代のGPUを2枚挿していると、どちらが cuda:0 に割り当てられるかが直感と食い違うことがある。対策は、起動前に環境変数で順序を固定すること。
set CUDA_DEVICE_ORDER=PCI_BUS_ID
rem 特定の1枚だけ使うなら、これが最も確実
set CUDA_VISIBLE_DEVICES=1
恥ずかしい話だが、筆者はこれを忘れて、5060Tiを指定したつもりが5080で測定してしまい、計測をやり直す羽目になった。GPU番号は思い込まず、処理中に nvidia-smi で実際にどちらが動いているか確認することを強く勧める。
VRAMとRAMは別物 ── タイルを下げてもRAMは減らない
つまずきやすいのが、VRAM(GPUのメモリ)とRAM(システムのメモリ)の混同だ。タイル処理が節約するのはVRAMの方で、ComfyUIが67〜77GBも使うのはRAMの方。だから「メモリが足りないからタイルを下げよう」としても、RAM側の膨張は止まらない。VRAMはGPUの中、RAMはマザーボード上 ── 別の場所のメモリで、タイルはGPU側、出力の一括確保はシステム側で起きている。スタンドアロンがメモリ問題に効くのは、このRAM側の集約そのものをなくすからだ。VRAMが足りないならタイルを下げる、RAMが足りないなら処理方式を変える ── 切り分けて対処したい。
その他のよくある詰まり
- モデルが見つからない →
.pthのパスを確認(ComfyUIのmodels/upscale_models/) - VRAMが足りない → タイルサイズを下げる(768 → 512)
- ffmpegが見つからない → フルパスで指定するか、PATHを通す
応用:GPUが2枚あるなら並列で量産する
動画を何十本も処理する量産フェーズでは、2枚のGPUに動画を1本ずつ振り分けて並列に走らせると、スループットが上がる。筆者の環境(RTX 5080 + RTX 5060 Ti)では、各GPUに1本ずつ流す並列で体感1.5〜2倍になった(ただし5060Ti側は前述のOculink帯域ペナルティを受ける)。これは2枚挿し環境が前提の話なので、まずは1枚で上の手順を完結させてほしい。デュアルGPUでの並列処理やVRAMの扱いは「ComfyUI デュアルGPU運用ガイド」で詳しく検証している。
まとめ
ComfyUI内のアップスケールが長尺でメモリを食い潰すのは、全フレームの4K出力を最後に一括確保する設計のためだ(実測67〜77GB、メモリ逼迫時はOOMで落ちる)。アップスケールの本体であるESRGANモデルを、spandrelでComfyUIの外から直接動かし、フレームを1枚ずつ流しながら処理すれば、この問題は根本から消える。
- メモリ:動画の長さに関わらず一定(実測1.4GB=ComfyUIの約48〜55分の1)。16GBのPCでも回る
- 速度:同じGPUで2.4〜2.6倍速。GPUを96%張り付かせて遊ばせない
- 画質:同じ
.pthを使うのでComfyUIと同等(動画ごとにモデルを自動で選ぶ最適化も可能だが、それは事前に検品で仕分けの仕組みを用意した場合の話。本記事ではそこまでは踏み込まない)
「ComfyUIでも作れるが、莫大なメモリと時間がかかる。スタンドアロンならその両方を劇的に削れる」── これが実測から見えた結論だ。まずComfyUIのノードで手順を掴みたい人は「LTX 1動画を4Kアップスケールする」から、本記事のスタンドアロン化はその次のステップとして試してみてほしい。
よくある質問(FAQ)
Q. ComfyUIで使っているモデル以外(SwinIRやSUPIRなど)も動きますか?
A. spandrelが対応しているアーキテクチャなら動きます。ESRGAN系(4x-UltraSharp / Remacri / RealESRGAN)はもちろん、SwinIRやHATなども同じコードでロードできます。spandrelがモデル形式を自動判別してくれるので、アーキテクチャごとにコードを書き換える必要はありません。
Q. 画質はComfyUIと本当に同じですか?
A. 同じです。使う .pth モデルもタイル処理の考え方もComfyUIと同一なので、出力画質は変わりません。実際、筆者はこのスタンドアロン構成で出力した動画でAdobe Stockの審査を通しています。「ガワ」がComfyUIかスクリプトかの違いだけで、中身(ESRGANの推論)は同じものが動いています。
Q. Topaz Video AIのような有料ソフトと比べて画質はどうですか?
A. 用途次第です。Topaz Video AIは動画専用に学習した独自モデルを持ち、実写映像のノイズ除去やディテール復元に強みがあります。一方、本記事の方式はComfyUIと同じ静止画向けESRGANモデルをフレーム単位で適用するもので、CG・アニメ・生成AI動画のようにフレーム間が安定した素材ではTopazに引けを取りません。実写の難しい映像ならTopaz、生成系やAdobe Stock向けのクリップなら無料のスタンドアロンで十分、という使い分けが現実的です。筆者は後者の用途なので、追加費用なしで完結しています。
Q. RAM 16GBや32GBのPCでも動きますか?
A. 動きます。スタンドアロンはRAM 1.4GBで頭打ちなので、16GBのPCでも8秒・4Kが問題なく処理できます。むしろメモリの少ないPCこそ、この方式の恩恵が大きいです(ComfyUIだと67GB超を要求するため、同じことは現実的に難しい)。
Q. 縦動画(9:16)でもいけますか?
A. いけます。処理は解像度に依存しないので、横でも縦でも同じコードで動きます。タイル処理が自動でフレームを分割するため、アスペクト比は問いません。
Q. 音声は残りますか?
A. 本記事のコードは映像だけを処理します。音声を残したい場合は、最後にffmpegで元動画の音声トラックをコピーして合成すれば大丈夫です(-i 元動画 -i アップスケール済み -map 1:v -map 0:a -c copy のように音声を移植する)。
Q. 何秒の動画まで処理できますか?
A. 長さの上限はありません。スタンドアロンはフレームを1枚ずつ流すのでメモリが一定で、何分の動画でもRAMは増えません。処理時間だけがフレーム数に比例して伸びます。ComfyUIは長いほどメモリが膨らんでOOMに近づくので、長尺ほど両者の差が開きます。
Q. ComfyUIを起動したままでも使えますか?
A. 同じGPUを使う場合は、VRAMが取り合いになるので避けた方が無難です。ComfyUI側のモデルをアンロードするか、別のGPUを割り当ててください(GPU指定は前述の CUDA_DEVICE_ORDER に注意)。
Q. Windows以外(Mac / Linux)でも動きますか?
A. spandrelとPyTorchが動く環境なら動きます。本記事はWindows+NVIDIA(CUDA)での実測ですが、Linux+CUDAでも同様です。MacはCUDAが使えないため、デバイス指定を mps に変えるなどの調整が必要です。
