一、一个看起来很简单的需求
最近接到一个典型的视频处理需求:
批量去除用户上传视频中的水印 / 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 |
|---|---|
| 原始 PyTorch | 2 FPS |
| ONNX Runtime | 5 FPS |
| TensorRT FP16 | 11 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 FPS | 11 FPS |
| 显存占用 | 高频 OOM | 稳定运行 |
系统能够在单张 T4 GPU 上稳定处理 1080p 视频任务。
在真实业务环境中,这类稳定性提升往往比单帧视觉质量更加重要。
九、最终工程成果
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 推理速度 | 2 FPS | 11 FPS |
| GPU 利用率 | 30% | 85% |
| 显存占用 | 满载 | ↓60% |
| 稳定性 | 不稳定 | 可生产 |
| 成功在单张 T4 GPU 上稳定运行 1080p 视频修复。 |
十、一些真实经验
这次工程化最大的体会:
-
视频问题本质是时间序列问题
-
AI 模型默认并不面向生产
-
推理优化比模型选择更重要
类似能力目前已经广泛应用在 AI 视频后处理场景中,
例如 Sora 视频水印移除、生成视频增强等任务。
十一、结语
AI 视频修复正在逐步替代传统音视频处理方案。
未来竞争重点,很可能在:
- 视频后处理能力
- 推理效率
- 工程稳定性