☰
OpenDLSS-NR 的 71 个 Block 网络地图:6 级 U-net、Swin 位移窗口与 ViT 瓶颈完整解析
2026/10/23 7:22:03 网站建设 项目流程

【免费下载链接】OpenDLSS-NR

A Vulkan reimplementation of NVIDIA's DLSS 5 Neural Rendering network, bit-exact against the original.

项目地址:https://gitcode.com/gh_mirrors/op/OpenDLSS-NR
点击查看免费下载

OpenDLSS-NR 是 NVIDIA DLSS 5 Neural Rendering(神经渲染)网络的 Vulkan 重新实现,与官方原版 bit-exact(逐位一致)。本文将带你绘制这张由 71 个 Block 组成的网络地图:6 级 U-net 分辨率金字塔、Swin 位移窗口注意力机制,以及位于底部的 ViT 全局注意力瓶颈,并解释它为什么是"生成式渲染器"而不是超分辨率放大。

🧩 先认识 OpenDLSS-NR:它到底在做什么?

一句话:DLSS-NR 不是超分,它是"重渲染"。网络接收引擎已经画好的一帧(一个低动态范围 proxy 代理图 + 3 通道高斯噪声 + 上一帧重投影的历史 + 5 个条件标量),输出同样是原始分辨率,但细节由注入的噪声"生成"出来,同时按 style 设置调整色调、结构与皮肤质感。

这个仓库的几个关键事实:

  • 与 DLSS-NR 310.8.0 相同的 71-block Swin / ViT 网络,在 tensor core 上跑 FP8(E4M3 激活 + FP16 累加),权重共 141 MiB
  • 中间结果也一致:所有 75 个 block 边界逐字节匹配原版,而不是只有最终图片对得上
  • 每条跨越 kernel 边界的值都是 E4M3 字节或 IEEE half——网络的"身份"就是这一连串舍入序列,因此 bit-exact 意味着匹配舍入顺序,而非误差上界
  • 完整的文档入口在 docs/README.md,网络图全貌在 docs/network.md

🗺️ 网络总览:71 个 Block 的分布地图

整个网络是一个带位移窗口的 Transformer U-net,底部放一个全局 ViT。71 个 Block 按"下采样—瓶颈—上采样"对称排布,通道数随深度翻倍再折回:

阶段Block 编号通道数分辨率级别作用
全分辨率入口032原始 field输入适配 + 第一个窗口块
编码器 L01–4321/2窗口注意力
编码器 L15–8641/4窗口注意力
编码器 L29–141281/8窗口注意力
编码器 L315–222561/16窗口注意力
编码器 L423–305121/32窗口注意力
ViT 瓶颈31–3810241/64全局注意力
解码器 L4→L039–69512→32逐层上采样与编码器 skip 连接
全分辨率出口7032原始 field输出 head

每个编码器 stage 与同级的解码器 stage 之间通过 skip connection 相连;下采样是 2x2 池化 + 通道翻倍 GEMM,上采样是通道减半 GEMM + 最近邻 2x 放大,再叠加 skip 的缩放。

分辨率金字塔是怎么算出来的

网络要求"6 次整除减半"后解码器能精确落回编码器尺寸,因此输入图像会先被 pad 成一个field(补零填充场)。比如:

有效尺寸填充后 fieldlevel 0 → level 5
512x512576x512288x256 → 12x8
1920x10801920x1152960x576 → 32x20

这个填充不只是内存对齐——它决定了哪些 token 存在,是算术的一部分。规则细节见 docs/network.md 的 "The padded field" 一节。

🔬 解剖一个 Block:FFN → QKV → 窗口注意力 → 投影

每个 Block 的数据流(按"发布"顺序):

state x (E4M3) ├─ FFN(x) ─────────────┐ ├─ x * ffnScale ──→ (+)→ y ──→ 发布为 E4M3 │ │ └─ Proj(WindowAttention(QKV(y))) ─┐ y * attnScale ───────────────→ (+)→ out

要点只有三个:

  1. 两次缩放 skip:ffnScale和attnScale是逐通道学习的 f16 向量,skip 不是事后相加,而是作为首个矩阵乘的累加操作数"种进"累加器——因为舍入位置不同,结果也不同
  2. FP8 GEMM 是 prologue 而非 epilogue:正因 skip 要先进累加器,残差处理必须放在乘法链开头
  3. 一个微妙不对称:32 通道的 Block 用 FFN 的原始 f16结果做注意力 skip,更宽的 Block 用其E4M3 发布值——两种都被原生实现固定了

FFN 的形态随通道数变化,这也是理解权重布局的关键:

通道数 CFFN 结构
32稠密32→128→32,第一层后 SiLU
64 / 128 / 256C/32条并行"专家"路径,各C→128→32,拼回 C 后接一个C→C的 W3 层(无路由,不是 MoE,是分组瓶颈 FFN)
5128 条 64 宽分支(64→256→64,仅 256 宽中间层有 SiLU)+512→512收缩层
1024(ViT)稠密1024→4096→1024

🪟 Swin 位移窗口:4 个相位,而不是通常的 2 个

窗口注意力的基本单元是8x8 token 的窗口。为了让窗口"看到"边界外的信息,Swin 风格的做法是移动窗口网格。这个网络用了4 个相位而非通常交替的 2 个——把对角偏移拆成 x、y 两个轴:

phase窗口原点偏移
0(0, 0)
1(-4, -4)
2(-4, 0)
3(0, -4)

两条容易忽略的规则:

  • 相位按 Block 推进,且解码器接着编码器的计数继续。例如 L2 有 6 个编码器块(相位 0,1,2,3,0,1),它的 6 个解码器块就从相位 2 开始。全分辨率级别上:block 0 用相位 0,block 70 用相位 1
  • 越界窗口不裁剪:负原点或伸出边缘的窗口,其域外 token 是零向量,key/value 贡献为零,但它们的prior + 0分数仍进入 softmax 分母——这不是近似,把它们 mask 掉会得到不同的结果

注意力本身用的是缩放余弦注意力:q、k 先做 f16 余弦归一化再乘逐头学习的 f32 温度,logit 变为有界余弦相似度——这正是 FP16 累加器加 3 位尾数权重能跑通的原因,也解释了为什么 softmax 前没有 max 减除。指数函数不用超越函数,而是 half 位操作技巧:把仿射值 clamp 后左移位域指数位,一步得到exp(s)(差一个 softmax 会除掉的比例常数)。

🧠 ViT 全局注意力:真正的瓶颈

Block 31–38 是 1024 通道的 8 个 ViT Block,工作在 level 5(1/64 分辨率)上,对全部 token 做全局注意力,而窗口块只看 8x8。它和窗口块有 4 处"猜不到"的差异:

差异点窗口块ViT 块
attention prior每头学习的 64x64 偏置无
Q 缩放q * norm * learnedq * norm * sqrt(32) * learned,三次独立的 half 乘法
平方和归一化fma(v, v, f16(high²))半精度路径低位平方用 f32,高位平方先舍入到 half 再求和
softmax权重先归一化再乘 P V权重不归一化:倒数事后乘到 value 累加器上,且分母要扣掉 padding 行的exp(0)

它的指数位技巧常数也不同(有效 clamp 范围约 [-3, +3],窗口是 [-6, +6])。token 数 pad 到 64 的倍数,padding 行有零 K/V 并拿到同样的exp(0)权重,由上述分母修正移除。

由于 level 5 尺寸很小(1080p 下仅 32x20),全局注意力的"token 数"不多,但1024 通道的稠密1024→4096→1024FFN是整张网络最重的部分,加上全 token 打分矩阵,构成了性能瓶颈——这也是 PTX 路径为它专门做了 split-K 与流式变体的原因(见 docs/execution.md)。

📡 输入 16 通道 → 输出 4 通道

输入(16 个 f32 通道,按序):3 通道高斯噪声(Box-Muller,用padding 后坐标哈希)→ 常数 1 → proxy 颜色(居中(c-0.5)/8)→ 重投影的历史输出 → style id/128 → 局部色调 → 结构/皮肤/自动 mask 三元组 → 0。有效矩形之外的采样是镜像而非 clamp,但噪声哈希仍用 padded 坐标。

输出(head):block 70 的原始 f16 输出经32→4f16 GEMM 得到:

  • 通道 0–2:RGB 残差,neural = clamp(proxy + rgb/4, 0, 1)
  • 通道 3:时间混合 logit,weight = clamp(sigmoid(logit) * blendScale, 0, 1),与重投影历史做 lerp

这个 4 通道的 head 是网络"生成"与"记忆"之间的逐像素仲裁者——遮挡等复杂情况就交给它自己的混合权重处理。完整帧管线(proxy、运动向量、历史重建、合成)在 docs/frame.md。

📂 进一步阅读:关键文件清单

内容路径
设计总纲(表示、不变量、"无推导"清单)docs/README.md
网络全图(block 结构、窗口相位、field 规则)docs/network.md
bit-exact 契约(舍入、softmax、E4M3 发布)docs/numerics.md
模型目录与权重布局(153 条张量记录)docs/weights.md
Vulkan 执行、kernel 集合、无 barrier 链式调度docs/execution.md
帧管线:从渲染图到像素docs/frame.md
网络图录制(71 个 Block 的组装)src/nr_graph.cpp
模型加载与权重重排布src/nr_model.cpp
CPU 参考实现(bit-exact 的算术移植)src/reference.cpp
GLSL 参考 kernel 集shaders/
PTX 快速路径生成器(Swin 算术只写一次)scripts/ptx/
Filament 实时 demo(含时间历史回路)demo/

✅ 小结

OpenDLSS-NR 的价值在于把一张"黑盒网络"彻底摊开:71 个 Block、6 级 U-net、4 相位 Swin 位移窗口、8 个 ViT 全局瓶颈块——每一处结构、每一个常数、每一种舍入顺序都被文档化为"被原生实现指定的语义"或"本实现的优化选择"。配合parity工具的逐字节比对,这是理解 DLSS 5 神经渲染最完整的公开解剖图。

【免费下载链接】OpenDLSS-NR

A Vulkan reimplementation of NVIDIA's DLSS 5 Neural Rendering network, bit-exact against the original.

项目地址:https://gitcode.com/gh_mirrors/op/OpenDLSS-NR
点击查看免费下载

相关推荐

上一篇:Remotely远程脚本执行详解:自动化管理100+设备的秘密
下一篇:Nexa SDK模型格式转换教程:GGUF到Nexa格式的完整流程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询