SadTalker・LatentSyncでLip Sync(リップシンク)を検証してみた
要約
音声と画像・動画からリップシンク済み動画を生成できるOSSツール「SadTalker」と「LatentSync」を実機(RTX 5090)で検証した。SadTalkerはRTX 5090ではそのままでは動かず、PyTorch 2.7.0+cu128への差し替えとbasicsrのパッチ適用が必要。--stillと--preprocess fullオプションで顔だけでなく体全体を含む動画も生成可能。ref_poseやref_eyeblinkで参照動画を渡すと姿勢・瞬き制御ができるが、今回はうまく機能せず首が大きく傾く結果になった。一方LatentSyncはGradio UIに動画と音声を投げるだけで動き、実用レベルの手軽さ。用途によって使い分けるのがベスト。
Lip Syncとは?
Lip Sync(リップシンク) とは、映像上の口の動きを音声と同期させる技術のこと。映画・アニメの吹き替えでは古くから使われてきた手法だが、近年はAI(深層学習)によって静止画や動画に対して自動でリップシンクを付与することが可能になった。
今回はその候補として以下の2つを実機検証した。
- SadTalker:静止画+音声 → 喋る動画を生成(顔アニメーション)
- LatentSync:動画+音声 → リップシンク済み動画を生成(Bytedance製)
検証環境
| 項目 | 内容 |
|---|---|
| GPU | NVIDIA RTX 5090 |
| OS | Ubuntu 22.04 |
| Python | 3.10 |
| パッケージ管理 | uv |
RTX 5090はBlackwellアーキテクチャ(sm_120)を採用しており、古いPyTorchビルドでは動作しない。この点がSadTalkerを動かす上での最大の障壁だった。詳細な修正手順は番外編を参照。
SadTalker:画像+音声から喋る動画を生成
- リポジトリ:https://github.com/OpenTalker/SadTalker
- 方式:静止画の顔+音声ファイルを入力し、音声に同期して口・頭・目が動くアニメーション動画を生成する
基本的な使い方
python inference.py \
--driven_audio /path/to/audio.wav \
--source_image /path/to/face.png \
--enhancer gfpgan
--enhancer gfpgan を付けることで、生成された顔にGFPGAN(顔超解像・補正モデル)をかけて高品質な出力が得られる。
今回使用する画像はGPTに「GPTが思う一番美しい女性」を生成していただいた。正面と側面の2パターンを用意した。
| Front | Side |
|---|---|
![]() | ![]() |
音声は日本声優統計学会を使用させていただいた。
生成結果:
ref_pose / ref_eyeblink で動き制御を試みた結果
SadTalkerには参照動画を使って**頭の姿勢(pose)やまばたき(eyeblink)**のパターンを制御するオプションがある:
python inference.py \
--driven_audio audio.wav \
--source_image face.png \
--ref_eyeblink reference_video.mp4 \
--ref_pose reference_video.mp4 \
--enhancer gfpgan
今回の結果:かなり動きが激しくなった。
考えられる原因:
- SadTalkerのpose推定が参照動画の特定フレームを強く拾いすぎた
この機能を使う場合は、なるべく同じ人物の参照を用意するのが重要かもしれない
--still と --preprocess full で体ごと生成
デフォルトのSadTalkerは顔領域をクロップして処理する。--stillと--preprocess fullを組み合わせると、体を含む全身の動画として出力できる:
python inference.py \
--driven_audio audio.wav \
--source_image full_body.png \
--still \
--preprocess full \
--enhancer gfpgan
| オプション | 効果 |
|---|---|
--still | 頭の動きを最小限に抑えてアニメーションを安定させる |
--preprocess full | 顔クロップせずに画像全体を処理対象にする |
バーチャルプレゼンターや立ち絵キャラクターのような用途に向いている。
LatentSync:動画+音声で最も手軽なLip Sync
- リポジトリ:https://github.com/bytedance/LatentSync
- 開発元:ByteDance
- 方式:既存の動画の口の動きを、入力音声に合わせて差し替える
セットアップと使い方
LatentSyncはGradio UIを立ち上げるだけで使える:
# リポジトリのREADMEに従ってセットアップ後
python gradio_app.py
ブラウザで開いたUI上に:
- 元動画(リップシンクさせたい人物が映っている動画)
- 音声ファイル(差し替えたい音声)
を投げ込むだけで、リップシンク済み動画が生成される。コードを書く必要がなく、セットアップさえ終われば誰でも使えるレベルの手軽さ。
SadTalkerとの最大の違いは、静止画ではなく動画を入力とする点。すでに人物が映っている動画の口の動きだけを差し替えるユースケースに特化している。
生成結果:
- 元動画
- 吹き替え後
SadTalker vs LatentSync 比較まとめ
| 比較項目 | SadTalker | LatentSync |
|---|---|---|
| 入力 | 静止画+音声 | 動画+音声 |
| 出力 | 顔アニメーション動画 | リップシンク済み動画 |
| 操作難易度 | やや高め(CLIベース) | 低い(Gradio UI) |
| RTX 5090対応 | 手動修正が必要 | 要確認 |
| 用途 | バーチャルプレゼンター、立ち絵キャラクター | 吹き替え、動画の口パク差し替え |
| 開発元 | OpenTalker(学術) | ByteDance |
結論:
- 静止画から動画を生成したいなら SadTalker
- 既存動画の口の動きを音声に合わせて差し替えたいなら LatentSync
FAQ
Q1. --enhancer gfpgan は必須ですか?
A. 必須ではないが、付けることで顔がシャープになり品質が上がる。GFPGANのモデルファイルが自動的にダウンロードされる(初回のみ時間がかかる)。
Q2. 商用利用は可能ですか?
A. SadTalkerもLatentSyncもApache Licenseで提供されているが、ライセンスは要確認。商用利用する場合は必ず最新のライセンス条項を確認すること。
番外編:RTX 5090でSadTalkerを動かすための修正
デフォルトの環境(torch==1.12.1+cu113)でRTX 5090上で実行すると、以下のエラーが発生する:
RuntimeError: CUDA error: no kernel image is available for execution on the device
原因:古いPyTorchがRTX 5090(Blackwell / sm_120)に対応したカーネルを持っていないため。
Step 1:Python 3.10の仮想環境を作り直す
cd /path/to/SadTalker
uv venv .venv --python 3.10 --clear
Step 2:RTX 5090対応のPyTorchスタックをインストール
uv pip install --python .venv/bin/python \
torch==2.7.0 torchvision==0.22.0 torchaudio==2.7.0 \
--index-url https://download.pytorch.org/whl/cu128
| パッケージ | バージョン |
|---|---|
| torch | 2.7.0+cu128 |
| torchvision | 0.22.0+cu128 |
| torchaudio | 2.7.0+cu128 |
Step 3:SadTalkerの依存パッケージをインストール
uv pip install --python .venv/bin/python -r requirements.txt
Step 4:basicsr の互換パッチを当てる
SadTalkerが依存するbasicsrライブラリが、新しいtorchvisionでは存在しない古いパスからインポートしようとしてエラーになる。
- ファイル:
.venv/lib/python3.10/site-packages/basicsr/data/degradations.py - 変更前:
from torchvision.transforms.functional_tensor import rgb_to_grayscale - 変更後:
from torchvision.transforms.functional import rgb_to_grayscale
ワンライナーで修正できる:
sed -i 's/from torchvision.transforms.functional_tensor import rgb_to_grayscale/from torchvision.transforms.functional import rgb_to_grayscale/' \
.venv/lib/python3.10/site-packages/basicsr/data/degradations.py
Step 5:GPU対応を確認する
uv run --python .venv/bin/python python - <<'PY'
import torch
print(torch.__version__) # 2.7.0+cu128
print(torch.version.cuda) # 12.8
print(torch.cuda.get_arch_list()) # [..., 'sm_120'] が含まれていればOK
PY
出力に sm_120 が含まれていれば、RTX 5090でSadTalkerが動作する状態になっている。
関連するブログ
この記事に近いテーマのブログをピックアップしています。
VibeVoice-ASRを量子化してDERはどう変わるか?4bit・8bit・originalを実測比較
VibeVoice-ASRを4bit・8bit量子化してDERを実測したところ、量子化が精度を下げるとは限らず、ドラマ系音声では4bitがオリジナルより8.5ポイント改善した
記事を読む →GradioでHugging Face Datasetをオフライン表示する
Hugging FaceのDataset ViewerはGradio + datasetsライブラリを使えば、ローカルキャッシュから高速に動くビューアをPythonだけで自作できる。音声・画像のインライン再生もdecode=False + base64埋め込みで実現。スクリプト1本でページネーション・Streamingモード対応まで完備する。
記事を読む →
