📝 この記事は forge.workstyle.tech に掲載した記事の転載です。
InfiniteTalk は、1枚の絵と音声から、口の動く動画を作るモデルだ。ComfyUI から呼んで、似顔絵の縦動画を50本ほど作った。1本10〜12分。その間に踏んだものを書いておく。
動きを弱めると、後半で背景が変色する
主役の人物に、頭をあまり振らせたくなかった。口の動きの強さ(audio_scale)を 0.62 に下げた。
合成すると、9秒あたりから頭のまわりに四角い汚れが出た。生成した動画の四隅の色を時刻ごとに取ると、こうなっていた。
2.0秒 #f9f9e1 (クリーム)
9.3秒 #bcc4b6 (緑がかった灰)
背景が後半で別の色に変わっていた。 合成では背景を1つの色として抜くので、変わった部分は抜けずに残る。
0.72 に上げて作り直すと安定した。
2.0秒 #fafae3
6.0秒 #f8fae3
9.3秒 #f7fce6
10.5秒 #f7fae7
0.6 未満にするとノイズが出やすい、というのは以前から分かっていた。0.62 はその境目に近すぎた。頭の動きを抑えたいなら、この値ではなく生成プロンプトで「very small head movement」と指示するほうが安全だった。
コマ数が合わないのは、壊れていない
生成した動画のコマ数が、頼んだ数と合わないことがある。
頼んだ 149コマ → 出てきた 153コマ
頼んだ 325コマ → 出てきた 369コマ
最初、これを失敗とみなして5本捨てた。実際は、処理単位の倍数に繰り上がっているだけで、先頭から使えば正常だった。1本10分以上かかる生成を5本、無駄にした。
回収の処理にはこう書いておいた。
def collect(sid):
"""出力のコマ数は処理単位に繰り上がる(149→153、325→369)。
長さが合わないのは異常ではない。先頭から必要な長さだけ使う。"""
中断は POST でないと効かない
GPUが詰まったとき、実行中の生成を止めたかった。
urllib.request.urlopen(HOST + "/interrupt") # → 404
urllib はデータを渡さないと GET になる。中断は POST でしか受け付けない。
urllib.request.urlopen(urllib.request.Request(HOST + "/interrupt", data=b"{}"))
メモリを解放する /free は、このビルドには存在しなかった。
喋っていないときは、止める
2人の会話で、聞き手の口パク動画をそのまま使うと、聞いている間も目や頭が動く。喋っているように見える。
台詞の区間だけ動画を使い、それ以外は止めた。
喋っている区間 … 口パク動画
喋っていない区間 … その時点の表情のまま、閉じた口の静止画
区間の前後に少し余裕を持たせる(開始の0.12秒前から、終わりの0.3秒後まで)と、口の開き始めと閉じ終わりが切れない。
待機中もメモリを抱えている
ComfyUI は、生成していない間も約11GBのメモリを保持していた。同じマシンで別の重い処理(今回は Codex)を動かすと、そちらがメモリ不足で落ちた。生成しない間は止め、使うときに起動する。起動は数十秒で済む。
まとめ
- 動きの強さを下げすぎると、後半で背景が変色する。抑えたいならプロンプトで
- コマ数の繰り上がりは正常。捨てる前に先頭を確かめる
- 中断は POST
- 喋っていない人物は止める。区間の前後に余裕を持たせる
- 待機中もメモリを使う。使わない間は止める
