Files
product/research-notes.md
T
2026-03-27 10:49:34 +08:00

15 KiB
Raw Blame History

数字人视频生成 — 研究与验证记录

本文档记录了从零开始探索「单图 + 音频 → 说话视频」的完整过程, 包括工具选型、环境踩坑、最终跑通的完整流程,以及对产品化的建议。

日期:2026-03-25 硬件:RTX 5090 (Blackwell, sm_120), CUDA 12.9, WSL2


一、目标

给定一张人物图片和一段音频,生成该人物"说话"的视频:

  • 嘴型与音频内容同步
  • 头部有自然动作(非僵硬的照片)
  • 可扩展至实时/直播场景

二、工具选型过程

2.1 最初方向:LivePortrait

  • 项目https://github.com/KlingTeam/LivePortrait(快手)
  • 本质:视频驱动的人脸动画,需要一个"驱动视频"来控制人物表情和头部运动
  • 误区澄清:网上有描述称 LivePortrait 支持"音频驱动",这是不准确的。它只能从驱动视频中提取音频附加到输出,无法用音频生成嘴型
  • 结论LivePortrait 适合生成头部动作底片,不能单独完成任务

2.2 调研其他工具

工具 厂商 核心能力 实时性 结论
LatentSync 1.6 字节跳动 扩散模型唇形同步,512x512 约4fps 质量好,但太慢
MuseTalk 1.5 腾讯 单步推理唇形同步 ⚠️ 约7fps 速度可接受,质量好
Live Avatar 阿里 140B 扩散模型 需集群 单卡不可行
SadTalker 开源 音频驱动全脸动画 未测试
Sonic 腾讯 音频驱动 未知 项目在 /home/xsl/work/Sonic,未测试

2.3 最终方案

两阶段流水线:

hairstyle-result.jpg
        ↓
  [LivePortrait]  ←  驱动视频 (d3.mp4, 自然头部动作)
        ↓
  头动底片视频 (hairstyle-result--d3.mp4, 11.8s)
        ↓
   [MuseTalk]  ←  音频 (test_speech_10s.wav)
        ↓
  最终视频 (嘴型同步 + 头部运动)

三、环境配置(重要踩坑记录)

3.1 RTX 5090 的核心问题

RTX 5090 是 Blackwell 架构(sm_120),PyTorch 稳定版(2.6 及以下)不支持。 所有项目都必须使用 PyTorch nightly cu128

pip install --pre torch torchvision torchaudio \
  --index-url https://download.pytorch.org/whl/nightly/cu128
# 已验证版本:torch-2.12.0.dev20260324+cu128

这是最先要做的事,否则所有 CUDA 推理都会报错:

CUDA error: no kernel image is available for execution on the device

3.2 HuggingFace CLI 命令名

在某些 conda 环境中,命令名是 hf 而不是 huggingface-cli

which hf          # /home/xsl/miniconda3/envs/MuseTalk/bin/hf
hf --version      # 1.7.2

下载需要 Token

export HF_TOKEN=<your_token>
hf download <repo> <file> --local-dir <dir>

四、LivePortrait 部署

4.1 环境

conda create -n LivePortrait python=3.10 -y
conda activate LivePortrait
pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu128
cd /home/xsl/work/LivePortrait
pip install -r requirements.txt

4.2 权重

# 约 1.1GB
huggingface-cli download KlingTeam/LivePortrait \
  --local-dir pretrained_weights \
  --exclude "*.git*" "README.md" "docs"

目录结构:

pretrained_weights/
├── insightface/        (~21MB)
├── liveportrait/       (~608MB)
└── liveportrait_animals/ (~500MB)

4.3 生成头动底片

conda activate LivePortrait
cd /home/xsl/work/LivePortrait

python inference.py \
  -s /path/to/portrait.jpg \
  -d assets/examples/driving/d3.mp4 \
  --flag_crop_driving_video \
  -o /home/xsl/work/head_motion_base

驱动视频参考(位于 assets/examples/driving/):

文件 时长 特点
d3.mp4 11.8s 自然说话动作,与10s音频匹配
d6.mp4 33.6s 长片段,适合循环
d10.mp4 15.0s 较长

技巧:选择时长接近音频时长的驱动视频;--flag_crop_driving_video 会自动裁剪驱动视频。

4.4 已知警告(可忽略)

[E:onnxruntime] Failed to load library libonnxruntime_providers_cuda.so

onnxruntime-gpu 依赖 CUDA 11.x,与系统 CUDA 12.9 不兼容,人脸检测自动回退 CPU,不影响结果。


五、LatentSync 部署(已验证,非推荐方案)

结论:质量好,但速度太慢(4fps),不适合产品化。作为备选方案保留。

5.1 环境

conda create -y -n latentsync python=3.10.13
conda activate latentsync
conda install -y -c conda-forge ffmpeg

pip install -r /home/xsl/work/LatentSync/requirements.txt

# RTX 5090 必须卸载稳定版再装 nightly
pip uninstall torch torchvision torchaudio -y
pip install --pre torch torchvision torchaudio \
  --index-url https://download.pytorch.org/whl/nightly/cu128

5.2 权重(约 4.9GB

cd /home/xsl/work/LatentSync
huggingface-cli download ByteDance/LatentSync-1.6 whisper/tiny.pt --local-dir checkpoints
huggingface-cli download ByteDance/LatentSync-1.6 latentsync_unet.pt --local-dir checkpoints

5.3 输入准备

LatentSync 需要视频(非图片)+ WAV 音频

# 图片 → 视频
ffmpeg -loop 1 -i portrait.jpg \
  -t <duration> \
  -vf "scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2" \
  -r 25 -c:v libx264 -pix_fmt yuv420p input_video.mp4 -y

# mp3 → wav
ffmpeg -i audio.mp3 -ar 16000 -ac 1 input_audio.wav -y

5.4 推理

conda activate latentsync
cd /home/xsl/work/LatentSync
python -m scripts.inference \
    --unet_config_path "configs/unet/stage2_512.yaml" \
    --inference_ckpt_path "checkpoints/latentsync_unet.pt" \
    --inference_steps 20 \
    --guidance_scale 1.5 \
    --enable_deepcache \
    --video_path "assets/input_video.mp4" \
    --audio_path "assets/input_audio.wav" \
    --video_out_path "video_out.mp4"

六、MuseTalk 部署(推荐方案)

6.1 项目路径

/home/xsl/work/MuseTalk

6.2 环境搭建(完整步骤,含所有踩坑修复)

conda create -y -n MuseTalk python=3.10
conda activate MuseTalk
conda install -y -c conda-forge ffmpeg

# 1. PyTorch nightlyRTX 5090 必须)
pip install --pre torch torchvision torchaudio \
  --index-url https://download.pytorch.org/whl/nightly/cu128

# 2. 项目依赖
cd /home/xsl/work/MuseTalk
pip install -r requirements.txt

# 3. 修复 chumpy 构建问题
pip install --no-build-isolation chumpy

# 4. MMLab(版本必须严格匹配,不可随意升降)
pip install mmengine
MMCV_WITH_OPS=1 pip install mmcv==2.1.0 --no-build-isolation  # 需要系统 nvcc
pip install "mmdet>=3.3.0"        # ≥3.3.0 才兼容 mmcv 2.1.0
pip install "mmpose>=1.3.0"       # ≥1.3.0 才兼容 mmcv 2.1.0
pip install xtcocotools json-tricks munkres

# 5. 更新 transformers(旧版与 huggingface-hub 1.x 冲突)
pip install "transformers>=4.45.0"

6.3 MMLab 版本兼容矩阵(关键)

mmcv 2.1.0  ←→  mmdet ≥3.3.0  ←→  mmpose ≥1.3.0
踩坑 原因 修复
mmcv 构建失败 nightly PyTorch 没有预编译轮子 MMCV_WITH_OPS=1 pip install mmcv==2.1.0 --no-build-isolation(需系统 nvcc
MMCV==2.1.0 is used but incompatible mmdet 3.1.0 要求 mmcv < 2.1.0 升级到 mmdet ≥3.3.0
mmpose 1.1.0 incompatible 同上 升级到 mmpose ≥1.3.0
transformers ImportError huggingface-hub 1.x 与旧 transformers 冲突 升级 transformers ≥4.45.0

6.4 权重下载

cd /home/xsl/work/MuseTalk
export HF_TOKEN=<your_token>

# 注意:此环境中命令是 hf,不是 huggingface-cli
hf download TMElyralab/MuseTalk \
  "musetalkV15/musetalk.json" "musetalkV15/unet.pth" \
  --local-dir models

hf download stabilityai/sd-vae-ft-mse \
  config.json diffusion_pytorch_model.bin \
  --local-dir models/sd-vae

hf download yzd-v/DWPose \
  dw-ll_ucoco_384.pth \
  --local-dir models/dwpose

hf download openai/whisper-tiny \
  config.json pytorch_model.bin preprocessor_config.json \
  --local-dir models/whisper

hf download ByteDance/LatentSync \
  latentsync_syncnet.pt \
  --local-dir models/syncnet

# face-parse 权重(不在 HuggingFace
pip install gdown
gdown --id 154JgKpzCPW82qINcVieuPH3fZ2e0P812 -O models/face-parse-bisent/79999_iter.pth
curl -L https://download.pytorch.org/models/resnet18-5c106cde.pth \
  -o models/face-parse-bisent/resnet18-5c106cde.pth

权重总大小约 5GB

models/
├── musetalkV15/
│   ├── unet.pth         (3.2GB)
│   └── musetalk.json
├── sd-vae/
│   ├── diffusion_pytorch_model.bin  (320MB)
│   └── config.json
├── dwpose/
│   └── dw-ll_ucoco_384.pth  (389MB)
├── whisper/
│   └── pytorch_model.bin    (145MB)
├── syncnet/
│   └── latentsync_syncnet.pt  (1.4GB)
└── face-parse-bisent/
    ├── 79999_iter.pth     (51MB)
    └── resnet18-5c106cde.pth  (45MB)

6.5 PyTorch 2.6+ 兼容性补丁(必须)

PyTorch 2.6+ 将 torch.loadweights_only 默认值改为 True,导致 MuseTalk 加载旧格式权重失败。 已在 scripts/inference.py 中加入 monkey-patch

# 在 inference.py 开头的 import torch 后面加入:
_orig_torch_load = torch.load
def _patched_torch_load(f, *args, **kwargs):
    kwargs.setdefault('weights_only', False)
    return _orig_torch_load(f, *args, **kwargs)
torch.load = _patched_torch_load

同样的补丁也需要加到 scripts/realtime_inference.py(如果使用实时模式)。

6.6 推理配置文件

创建 YAML 配置文件(configs/inference/my_task.yaml):

task_0:
 video_path: "/path/to/head_motion_video.mp4"
 audio_path: "/path/to/audio.wav"
 bbox_shift: 0   # 可选:调整嘴部区域位置,负值下移,正值上移

6.7 运行推理

conda activate MuseTalk
cd /home/xsl/work/MuseTalk

python -m scripts.inference \
  --inference_config configs/inference/my_task.yaml \
  --result_dir results/output \
  --unet_model_path models/musetalkV15/unet.pth \
  --unet_config models/musetalkV15/musetalk.json \
  --version v15

输出路径:results/output/v15/<video_name>.mp4


七、完整流水线(已验证示例)

输入

  • 图片:/home/xsl/work/LivePortrait/hairstyle-result.jpg1080x1920,正面人像)
  • 音频:/home/xsl/work/LivePortrait/test_speech_10s.mp311.8秒,中文语音)

Step 1:生成头动底片

conda activate LivePortrait
cd /home/xsl/work/LivePortrait

python inference.py \
  -s /home/xsl/work/LivePortrait/hairstyle-result.jpg \
  -d assets/examples/driving/d3.mp4 \
  --flag_crop_driving_video \
  -o /home/xsl/work/head_motion_base

输出:/home/xsl/work/head_motion_base/hairstyle-result--d3.mp411.8s, 2.1MB

Step 2:音频转 WAV

ffmpeg -i /home/xsl/work/LivePortrait/test_speech_10s.mp3 \
  -ar 16000 -ac 1 /tmp/input_audio.wav -y

Step 3MuseTalk 嘴型同步

conda activate MuseTalk
cd /home/xsl/work/MuseTalk

cat > configs/inference/hairstyle.yaml << 'EOF'
task_0:
 video_path: "/home/xsl/work/head_motion_base/hairstyle-result--d3.mp4"
 audio_path: "/tmp/input_audio.wav"
EOF

python -m scripts.inference \
  --inference_config configs/inference/hairstyle.yaml \
  --result_dir results/hairstyle \
  --unet_model_path models/musetalkV15/unet.pth \
  --unet_config models/musetalkV15/musetalk.json \
  --version v15

输出:/home/xsl/work/MuseTalk/results/hairstyle/v15/hairstyle-result--d3_input_audio.mp4

性能数据

阶段 耗时 帧数 等效速度
LivePortrait 头动生成 ~30s 295帧 ~10fps
MuseTalk 嘴型合成 ~50s 354帧 ~7fps
总计 ~80s 生成12s视频

八、产品化建议

8.1 当前方案的局限

  1. 非实时:总体约 7fps 生成速度,12秒视频需要 80 秒处理
  2. 两套环境LivePortrait 和 MuseTalk 分别用不同 conda 环境,pipeline 不够整洁
  3. 头动单调:驱动视频固定,长时间使用会重复
  4. 图片分辨率MuseTalk 处理区域限定在 256x256 嘴部区域

8.2 提速方向

  • MuseTalk 实时模式scripts/realtime_inference.py 支持流式处理,延迟更低
  • 头动循环库:预先用 LivePortrait 生成多种头动视频(点头、摇头、思考等),运行时随机选取
  • TensorRT 量化:对 MuseTalk UNet 做 TRT 优化,预计可提速 2-3x

8.3 架构建议(产品级)

音频输入
   ↓
[ASR/VAD]  →  静音检测、分段
   ↓
[MuseTalk 实时流]  ←  头动视频循环
   ↓
[后处理:美颜/超分](可选)
   ↓
视频输出流

8.4 替代方案调研建议

在正式产品开发前,建议调研以下工具:

  • Sonic/home/xsl/work/Sonic):已有项目,未测试,可能支持更好的实时性
  • EchoMimic:阿里的音频驱动方案,支持半身动作
  • AniPortrait:同时驱动头部和嘴型

九、目录结构总览

/home/xsl/work/
├── LivePortrait/          # 头部动作驱动
│   ├── pretrained_weights/  (~1.1GB)
│   ├── hairstyle-result.jpg # 测试图片
│   ├── test_speech_10s.mp3  # 测试音频
│   └── DEPLOYMENT.md        # 详细部署笔记
│
├── LatentSync/            # 扩散模型唇形同步(备用)
│   ├── checkpoints/         (~4.9GB)
│   └── video_out.mp4        # 测试输出
│
├── MuseTalk/              # 单步推理唇形同步(推荐)
│   ├── models/              (~5GB)
│   └── results/hairstyle/v15/hairstyle-result--d3_input_audio.mp4
│
├── head_motion_base/      # LivePortrait 生成的头动底片
│   └── hairstyle-result--d3.mp4
│
└── Sonic/                 # 待调研

Conda 环境

conda env list
# LivePortrait   /home/xsl/miniconda3/envs/LivePortrait
# latentsync     /home/xsl/miniconda3/envs/latentsync
# MuseTalk       /home/xsl/miniconda3/envs/MuseTalk

十、快速复现命令(Cheat Sheet)

# === 生成一个说话视频(完整流程)===

# 1. 生成头动底片
conda activate LivePortrait && cd /home/xsl/work/LivePortrait
python inference.py -s portrait.jpg -d assets/examples/driving/d3.mp4 \
  --flag_crop_driving_video -o /tmp/head_motion

# 2. 音频转 WAV
ffmpeg -i input.mp3 -ar 16000 -ac 1 /tmp/audio.wav -y

# 3. 嘴型同步
conda activate MuseTalk && cd /home/xsl/work/MuseTalk
python -m scripts.inference \
  --inference_config <(echo "task_0:\n video_path: /tmp/head_motion/*.mp4\n audio_path: /tmp/audio.wav") \
  --result_dir /tmp/output \
  --unet_model_path models/musetalkV15/unet.pth \
  --unet_config models/musetalkV15/musetalk.json \
  --version v15