Repository navigation
Seedvr2在ncnn-valkan后端上的推理实现 #7001
czwdysj
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
SeedVR2 NCNN Vulkan:从 PyTorch 模型到纯 C++ 端侧视频推理
本文是一份面向开发者的项目技术 Discussion。它说明项目解决了什么问题、为什么
不能只依赖 pnnx 自动转换、当前实现的关键设计、RTX 5090 实测结果。文中性能数据来自真实完整程序,
项目链接:[czwdysj/seedvr2-ncnn-valkan](https://github.com/czwdysj/seedvr2-ncnn-valkan)
推理结果
以下结果由 RTX 5090 上的 Release 版本使用 Vulkan resident 模式、1 step、
CFG 1.0 和 seed 666 实际生成。输入首帧按模型规则中心裁剪到
480x256,因此修复前后图片具有完全相同的尺寸和画面范围。
seedvr2_demo_input.mp4
seedvr2_demo_output.mp4
动态效果:
可直接打开或下载完整媒体:
本次完整模型推理约
5.78-5.85 s,其中 VAE encode 约1.20-1.26 s、DiT 约
2.29 s、VAE decode 约2.28 s;峰值显存为19538 MiB,宿主最大RSS 约
2.0 GiB。更完整的测试环境、口径和图片/视频结果见第 5 节。1. 项目结论
本项目已经把 SeedVR2 3B 从 PyTorch 研究代码整理为可独立构建和运行的 NCNN Vulkan
工程。用户在 Linux/WSL2 NVIDIA 环境中可以完成以下闭环:
运行时是纯 C++,不依赖 Python、PyTorch 或 CUDA Toolkit。模型计算、CFG 和 Euler
采样的大张量在一次推理中持续使用
VkMat,仅在输入边界集中上传、在最终输出边界下载一次。
这不是“pnnx 一键转换”的包装。项目完成了模型拆分、动态形状恢复、六类模型语义层、
NCNN Convolution3D Vulkan 后端、跨子网络 GPU 数据流、数值对齐工具和 Linux 发布链路。
2. 推理架构
flowchart LR A["ffmpeg 解码"] --> B["CPU 预处理与可复现噪声"] B --> C["集中上传 VkMat"] C --> D["动态 VAE Encoder"] D --> E["posterior sample"] E --> F["DiT input head"] F --> G["32 个 Transformer Block"] G --> H["DiT output head"] H --> I["CFG 与 Euler sampler"] I -->|"下一采样步"| F I --> J["动态 VAE Decoder"] J --> K["最终 VkMat 下载"] K --> L["CPU 后处理与 H.264 编码"]公开接口只暴露
SeedVR2Engine。VAE、DiT、sampler、预处理、后处理和 Vulkan 资源管理均位于内部模块,调用方不需要理解 34 个 DiT 子模型或自定义层注册细节。
DiT 支持两种权重调度:
resident:32 个 block 常驻显存,适合 32GB 级 GPU,也是当前性能主路径。streaming:逐 block 加载和释放,降低常驻显存,但权重 I/O 和 pipeline 重建很慢。3. 已完成的核心工作
3.1 PyTorch 到 NCNN 的结构化转换
模型不是作为一个巨大静态图转换,而是按运行时职责拆为:
.param/.bin.param/.bin.param/.bin拆分使 3B 模型既能 resident,也能按 block 流式执行;同时每个边界都可单独与 PyTorch
参考张量比较,避免只能观察最终视频、无法定位误差来源。
3.2 六类自定义层
静态 NCNN 图无法完整表达 SeedVR2 的运行时语义,因此实现了六类 CPU/Vulkan 自定义层:
DynamicFramewiseGroupNormDynamicFramewiseSpatialAttentionDynamicSpaceTimeShuffleSeedVR2DiTInputSeedVR2DiTBlockSeedVR2DiTOutput此外,NCNN 原生
Convolution3D原本没有本项目需要的 Vulkan 实现。项目以独立补丁增加了 pack1 Vulkan 后端,并进一步实现四输出通道并行、权重 pack4 和 workgroup 调优。
3.3 动态输入
VAE 和 DiT 都不绑定导出时的固定宽高。当前规则是:
4n+1时复制末帧,输出再裁回原始帧数;这使同一份模型可以处理多种 T/H/W,而不需要为 320x240、480x270 分别导出模型。
3.4 多模态窗口 Attention 对齐
Transformer Block 是转换中最难的语义模块。实现包含:
mmrope3d坐标构造和 Q/K 旋转;一次完整尺寸误差曾达到约
0.21 NRMSE。通过导出 QKV、Q/K Norm、RoPE 后 Q/K、attention 和 projection 等中间张量,最终定位到 Vulkan shader 错用了视频分支的
Q/K Norm gamma 处理文本分支。修复后,关键单 block 对 PyTorch 的最坏 NRMSE 降至
7.66201e-4。3.5 Engine 级 VkMat 常驻
早期实现虽然每个 Net 可以使用 Vulkan,但 Net 之间仍以 CPU
Mat传递,导致隐式下载、同步和再次上传。当前实现引入共享
VulkanExecutionContext,统一 Vulkandevice、blob allocator 和 staging allocator:
上述大型中间张量全程保持
VkMat。当前传输审计为:入口一次批量上传、模型内部零 feature tensor 下载、出口一次最终视频下载。
3.6 可复现的 Linux 工程闭环
build.sh检查工具链、Vulkan loader/header、硬件 GPU,并幂等应用 ncnn 补丁;download-models.sh支持断点续传、manifest 和 SHA256 完整性验证;一个重要的构建约束是:不能绕过
build.sh直接对未打补丁的 ncnn 执行 CMake。否则最终
Convolution3D会回退 CPU,extract(VkMat&)无法得到 GPU 输出。当前 VAE和 Engine 已增加输出契约检查,会明确报告补丁问题,而不是在
record_download()中崩溃。
4. 数值正确性
4.1 VAE Mat/VkMat 边界
2026-09-14 在 RTX 5090 上使用
T=5,H=64,W=64复测:1.19209e-71.02.95788e-61.04.2 DiT 对 PyTorch
0.01804030.9998372620.008070380.9999674370.01402610.999901629完整 32 层误差包含 FP16 权重、BF16 attention 舍入和不同 GEMM 累加顺序的累计;
关键单 block 均低于
8e-4 NRMSE,resident 与 streaming 输出逐元素一致,未发现窗口、RoPE、文本融合或残差语义错误。
4.3 自动化测试
新服务器正式应用 ncnn 补丁后,Release 构建的 10 项 smoke test 全部通过,覆盖 CLI、
运行时、三个 VAE 动态层、三个 DiT 层、Convolution3D 和 sampler。完整模型文件的
manifest、数量和 SHA256 也全部通过。
5. RTX 5090 最终实例 Benchmark
5.1 环境与口径
Vulkan pipeline 创建、ffmpeg 解码和编码。
5.2 实测结果
5 帧视频复测的峰值数据:
19538 MiB;2.0 GiB;0.86 frame/s;5.3 性能解读
对 5 帧样例,纯推理中 DiT 和 VAE decode 各约占 39%,VAE encode 约占 22%。因此
当前继续优化时不能只盯住 decoder;attention 和 decoder 已经是并列热点。
墙钟比纯推理多约 27 秒,主要是每次新进程加载 7.3GB 权重和创建 Vulkan 资源。
长驻服务可以摊薄这部分成本,CLI 冷启动则需要模型映射、pipeline cache 等专项优化。
VAE Convolution3D 的既有独立 benchmark 显示,四输出并行和权重 pack4 已将
5x256x480decoder 从6529.968 ms降到2245.263 ms,约2.91x。本次完整Engine 的 5 帧 decode 为约
2.28 s,与该独立结果相互印证。6. 项目的技术优势
依赖体积和版本耦合。
是只对最终视频做主观判断。
CPU,这是推理框架工程中容易被忽略的一层。
将算法错误与 GPU 精度差异分开。
未应用和冲突状态。
文档均在同一仓库中。
7. 最突出的技术难点
7.1 动态视频图转换
模型包含 Python cache、动态 slice、list flatten/unflatten 和变长联合 attention,无法
直接冻结成一个可靠静态图。难点不在格式转换,而在选择稳定的图边界,并把动态语义
收敛到少量可测试的自定义层。
7.2 时空因果 VAE
3D 卷积本身不带 mask。因果性由时间方向的
Concat/Croppadding 结构实现;下采样可继续使用原生层,而上采样还需要动态时空 shuffle。错误一个时间索引就会造成帧错位,
且最终图像仍可能“看起来正常”,所以必须使用张量级验证。
7.3 视频与文本联合窗口 Attention
窗口局部坐标、shift、文本复制/归并、两套 Q/K Norm、三轴 RoPE、BF16 边界和 32 层
残差会共同放大微小错误。项目采用中间张量逐阶段二分定位,而不是反复调整最终误差
阈值。
7.4 Vulkan 资源与跨网络生命周期
34 个独立 Net 必须共享兼容的 device 和 allocator,
VkMat又必须存活到后续组件完成。同时 resident 和 streaming 对权重、workspace 和同步生命周期的要求不同。只把每个
layer 写成 Vulkan 并不能自动得到无往返的 Engine。
7.5 可用构建与“能编译”的差别
Convolution3D 补丁、固定 ncnn/glslang 提交、Vulkan loader 与 NVIDIA ICD 版本必须一致。
本次新服务器最初的 Vulkan 1.3 loader 无法加载声明 Vulkan 1.4 的驱动;升级 loader 后,
又通过 VAE 边界测试发现直接 CMake 漏打补丁。两次问题都说明发布验收必须从干净环境
执行真实模型,而不能只依赖
--help或单层 smoke test。8. 当前限制
9. 后续开发优先级
17帧分块、5帧重叠、时序一致的融合、磁盘 checkpoint和中断恢复;这是可处理真实长视频的前提。
并减少 block 之间的 queue submit/wait。
连续保持 pack4,避免层间 pack/unpack。
All reactions