ProPainter 工程化实录:从跑不起来到 GPU 稳定推理

0 阅读5分钟

一、一个看起来很简单的需求

最近接到一个典型的视频处理需求:

批量去除用户上传视频中的水印 / Logo / 字幕。

需求听起来不复杂,但要求却非常现实:

  • 修复结果必须自然
  • 视频不能闪烁
  • 支持 1080p
  • GPU 成本可控
  • 能真正运行在生产环境

第一反应当然是 —— FFmpeg。毕竟音视频处理领域几乎绕不开它。于是很快使用 delogo 滤镜进行了测试。水印确实消失了,但问题马上出现。

二、FFmpeg 为什么解决不了视频修复?

上线测试后发现:

视频虽然“去掉了水印”,但几乎无法使用。

原因其实非常本质。

FFmpeg delogo 本质做的事情是:

模糊覆盖(把问题遮住)

而不是:

内容重建(恢复真实画面)

当遇到以下场景时效果迅速崩溃:

  • 摄像机移动
  • 背景纹理复杂
  • 人物运动
  • 动态水印

最终表现通常是:

  • 一块持续移动的模糊区域
  • 明显视觉破坏
  • 视频闪烁

FFmpeg 在隐藏问题,而 AI 在重建内容。

事实上,在处理 AI 生成视频(尤其是 Sora 视频)时, 传统滤镜方案几乎无法满足真实可用需求。

如果体验过一些基于 AI 的 video watermark remover 方案,会发现它们并不是简单模糊处理,而是依赖视频时序一致性的内容重建能力。这也是我后来转向 AI 视频修复模型的原因。

三、为什么选择 ProPainter?

在调研多个方案后,最终选择了 ProPainter(CVPR 2023)

它真正解决的是视频处理中的核心难题:

时间一致性(Temporal Consistency)

传统 AI 修复流程通常是:

flowchart LR
    A[Video Input] --> B[Frame Extraction]
    B --> C[Single Frame Inpainting]
    C --> D[Frame Reconstruction]
    D --> E[Video Reassembly]

问题在于:每一帧都是独立生成。

结果就是:

Flickering(画面闪烁)

ProPainter 的核心思想(工程视角)

可以简单理解为三件事:

1️⃣ 像素运动追踪(Optical Flow)

模型先理解:

当前区域在下一帧移动到了哪里。

而不是重新生成。

2️⃣ 时间信息传播(Temporal Propagation)

修复结果在帧之间共享。

前一帧结果会影响下一帧。

从根本上降低闪烁。

3️⃣ 视频内容补全(Video Inpainting)

模型真正生成被遮挡区域的纹理与结构。

不是模糊,而是重建。

整体 Pipeline:

flowchart TD
    A[Video Input] --> B[Motion Estimation]
    B --> C[Temporal Feature Propagation]
    C --> D[Inpainting Network]
    D --> E[Stable Video Output]

理论看起来很完美,直到真正开始工程化部署。

四、第一个大坑:环境配置地狱

Clone 官方 Repo 后运行推理脚本。

迎接我的第一条报错:

随后进入经典循环:

- PyTorch 版本冲突
- CUDA 不匹配
- cuDNN 报错
- torchvision 不兼容

实测稳定组合:

- Python 3.9  
- PyTorch 1.12  
- CUDA 11.7  

经验总结只有一句:

> **不要在宿主机硬装 AI 环境。**

直接 Docker 化。

```dockerfile
FROM nvidia/cuda:11.7.1-cudnn8-runtime-ubuntu20.04

RUN apt update && apt install -y python3 python3-pip
COPY requirements.txt .
RUN pip install -r requirements.txt

五、第二个大坑:推理速度慢到无法上线

模型终于跑起来。新的问题来了,测试结果:

10 秒视频推理耗时接近 3 分钟。

GPU 使用率却只有约 30%。原因包括:

  • PyTorch eager execution

  • Kernel 调度碎片化

  • Tensor 未融合

GPU 并没有被真正利用。

优化路径:ONNX + TensorRT

导出 ONNX:

torch.onnx.export(model, dummy_input, "propainter.onnx")

TensorRT 推理优化:

trtexec --onnx=propainter.onnx --fp16

性能变化:

推理方式FPS
原始 PyTorch2 FPS
ONNX Runtime5 FPS
TensorRT FP1611 FPS

AI 模型能运行,不代表它能进入生产环境。****

六、第三个大坑:GPU 显存爆炸

处理高分辨率视频时常见错误:

CUDA out of memory

原因:

ProPainter 默认加载完整视频序列。

解决方案:Sliding Window 推理

核心思路:不要一次处理整段视频,改为窗口滑动:

flowchart LR
    A[Frame 0-10] --> B[Frame 5-15]
    B --> C[Frame 10-20]
    C --> D[Frame 15-25]

并共享时间特征,优化结果:

  • 显存降低约 60%
  • 长视频稳定运行
  • 推理连续性保持

七、生产环境架构改造

AI Demo 能跑 ≠ 服务能跑。

最终生产架构:

flowchart LR

    A[User Upload] --> B[API Gateway]

    B --> C[Task Queue]

    C --> D1[GPU Worker 1]

    C --> D2[GPU Worker 2]

    C --> D3[GPU Worker N]

    D1 --> E[Inference Service]

    D2 --> E

    D3 --> E

    E --> F[Video Assembly]

    F --> G[Object Storage]

    G --> H[Download Result]

关键优化:

  • GPU Worker 常驻

  • 模型只加载一次

  • 队列控制并发

GPU 利用率显著提升。

八、工程验证与稳定性观察

在模型完成工程化改造后,更重要的问题并不是 “单次修复效果如何”,而是:

该方案是否能够在真实生产环境中长期稳定运行。

相比离线 Demo,在线视频处理场景通常面临:

  • 不同分辨率输入
  • 长视频任务
  • 多任务并发
  • GPU 资源竞争

因此我们重点关注以下指标。

1️⃣ 推理稳定性

在连续任务压力测试中:

  • 未出现 GPU Memory Leak
  • Worker 可持续运行
  • 长视频任务无中断

Sliding Window 推理机制有效避免了显存峰值问题。

2️⃣ 时间一致性表现

在动态场景下观察:

  • 背景区域保持连续
  • 无明显 Flickering
  • 修复区域不存在帧跳变

这验证了 Temporal Propagation 在实际场景中的有效性。

3️⃣ GPU 利用率表现

工程优化后:

指标优化前优化后
GPU 利用率~30%~85%
推理速度2 FPS11 FPS
显存占用高频 OOM稳定运行

系统能够在单张 T4 GPU 上稳定处理 1080p 视频任务。

在真实业务环境中,这类稳定性提升往往比单帧视觉质量更加重要。

九、最终工程成果

指标优化前优化后
推理速度2 FPS11 FPS
GPU 利用率30%85%
显存占用满载↓60%
稳定性不稳定可生产
成功在单张 T4 GPU 上稳定运行 1080p 视频修复。

十、一些真实经验

这次工程化最大的体会:

  1. 视频问题本质是时间序列问题

  2. AI 模型默认并不面向生产

  3. 推理优化比模型选择更重要

类似能力目前已经广泛应用在 AI 视频后处理场景中,

例如 Sora 视频水印移除、生成视频增强等任务。

十一、结语

AI 视频修复正在逐步替代传统音视频处理方案。

未来竞争重点,很可能在:

  • 视频后处理能力
  • 推理效率
  • 工程稳定性