{"notes":[{"id":"classic-cnns/dcnv4","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"DCNv4","subtitle":"权重不设上限","author":"Z. Yuan","paperDate":"2024-01-11","publishedOn":"2025-12-29","paperTitle":"Efficient Deformable ConvNets: Rethinking Dynamic and Sparse Operator for Vision Applications","paperUrl":"https://arxiv.org/abs/2401.06197","bibliography":{"title":"Efficient Deformable ConvNets: Rethinking Dynamic and Sparse Operator for Vision Applications","authors":["Yuwen Xiong","Zhiqi Li","Yuntao Chen","Feng Wang","Xizhou Zhu","Jiapeng Luo","Wenhai Wang","Tong Lu","Hongsheng Li","Yu Qiao","Lewei Lu","Jie Zhou","Jifeng Dai"],"url":"https://arxiv.org/abs/2401.06197","pdfUrl":"https://arxiv.org/pdf/2401.06197v1","codeUrl":"https://github.com/OpenGVLab/DCNv4","preprint":{"id":"2401.06197","submittedOn":"2024-01-11","url":"https://arxiv.org/abs/2401.06197"},"publication":{"venue":"CVPR","year":2024,"kind":"conference","url":"https://openaccess.thecvf.com/content/CVPR2024/html/Xiong_Efficient_Deformable_ConvNets_Rethinking_Dynamic_and_Sparse_Operator_for_Vision_CVPR_2024_paper.html"},"citation":"@misc{classiccnnsdcnv42024,\n  title = {{Efficient Deformable ConvNets: Rethinking Dynamic and Sparse Operator for Vision Applications}},\n  author = {Yuwen Xiong and Zhiqi Li and Yuntao Chen and Feng Wang and Xizhou Zhu and Jiapeng Luo and Wenhai Wang and Tong Lu and Hongsheng Li and Yu Qiao and Lewei Lu and Jie Zhou and Jifeng Dai},\n  year = {2024},\n  eprint = {2401.06197},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/2401.06197}\n}\n","citationPath":"/content/papers/citations/classic-cnns/dcnv4.f17f87f8ee11.bib"},"thumbnail":{"src":"/content/papers/assets/fe768f9a1b9df098fd7de1ed2c34ba0713cb83936e024d45ca26e85a2b340ff1.png","width":1020,"height":522},"locale":"zh-hans","path":"/content/papers/zh-hans/classic-cnns/dcnv4.6cd84adfd6b4.md","headings":[{"id":"定义问题","text":"定义问题","depth":2},{"id":"只采样-9-个点为什么不快","text":"只采样 9 个点，为什么不快","depth":3},{"id":"softmax-是借来的","text":"softmax 是借来的","depth":3},{"id":"解决问题","text":"解决问题","depth":2},{"id":"一拿掉-softmax","text":"一、拿掉 softmax","depth":3},{"id":"二让-gpu-少搬数据","text":"二、让 GPU 少搬数据","depth":3},{"id":"讨论","text":"讨论","depth":2},{"id":"算子本身","text":"算子本身","depth":3},{"id":"flashinternimage","text":"FlashInternImage","depth":3},{"id":"换进别的网络","text":"换进别的网络","depth":3},{"id":"代价","text":"代价","depth":3},{"id":"结论","text":"结论","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"classic-cnns/internimage","relation":"referenced","topic":""},{"id":"classic-cnns/deformable-convnets","relation":"referenced","topic":""}]},{"id":"classic-cnns/internimage","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"InternImage","subtitle":"大力出奇迹？","author":"Z. Yuan","paperDate":"2022-11-10","publishedOn":"2025-09-04","world":"external/internimage","paperTitle":"InternImage: Exploring Large-Scale Vision Foundation Models with Deformable Convolutions","paperUrl":"https://arxiv.org/abs/2211.05778","bibliography":{"title":"InternImage: Exploring Large-Scale Vision Foundation Models with Deformable Convolutions","authors":["Wenhai Wang","Jifeng Dai","Zhe Chen","Zhenhang Huang","Zhiqi Li","Xizhou Zhu","Xiaowei Hu","Tong Lu","Lewei Lu","Hongsheng Li","Xiaogang Wang","Yu Qiao"],"url":"https://arxiv.org/abs/2211.05778","pdfUrl":"https://arxiv.org/pdf/2211.05778v4","codeUrl":null,"preprint":{"id":"2211.05778","submittedOn":"2022-11-10","url":"https://arxiv.org/abs/2211.05778"},"publication":{"venue":"CVPR","year":2023,"kind":"conference","url":"https://openaccess.thecvf.com/content/CVPR2023/html/Wang_InternImage_Exploring_Large-Scale_Vision_Foundation_Models_With_Deformable_Convolutions_CVPR_2023_paper.html"},"citation":"@misc{classiccnnsinternimage2022,\n  title = {{InternImage: Exploring Large-Scale Vision Foundation Models with Deformable Convolutions}},\n  author = {Wenhai Wang and Jifeng Dai and Zhe Chen and Zhenhang Huang and Zhiqi Li and Xizhou Zhu and Xiaowei Hu and Tong Lu and Lewei Lu and Hongsheng Li and Xiaogang Wang and Yu Qiao},\n  year = {2022},\n  eprint = {2211.05778},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/2211.05778}\n}\n","citationPath":"/content/papers/citations/classic-cnns/internimage.4baca0899bc9.bib"},"thumbnail":{"src":"/content/papers/assets/eb597a4ac9a7c2e5e9b05e8ff1c61a951adab71d5cc5a273796762d353a9a0e9.png","width":1012,"height":1179},"locale":"zh-hans","path":"/content/papers/zh-hans/classic-cnns/internimage.f5dfee837064.md","headings":[{"id":"定义问题","text":"定义问题","depth":2},{"id":"卷积输在哪里","text":"卷积输在哪里","depth":3},{"id":"dcnv2-为什么不能直接用","text":"DCNv2 为什么不能直接用","depth":3},{"id":"解决问题","text":"解决问题","depth":2},{"id":"dcnv3-的三个修改","text":"DCNv3 的三个修改","depth":3},{"id":"叠成网络","text":"叠成网络","depth":3},{"id":"讨论","text":"讨论","depth":2},{"id":"imagenet","text":"ImageNet","depth":3},{"id":"检测与分割","text":"检测与分割","depth":3},{"id":"消融softmax-那一项","text":"消融：softmax 那一项","depth":3},{"id":"代价","text":"代价","depth":3},{"id":"结论","text":"结论","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"classic-cnns/deformable-convnets","relation":"referenced","topic":""},{"id":"reparameterization/replknet","relation":"referenced","topic":""},{"id":"classic-cnns/slak","relation":"referenced","topic":""}]},{"id":"classic-cnns/deformable-convnets","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"Deformable ConvNets","subtitle":"凌波微步","author":"Z. Yuan","paperDate":"2017-03-17","publishedOn":"2024-05-01","world":"external/deformable-convnets","paperTitle":"Deformable Convolutional Networks","paperUrl":"https://arxiv.org/abs/1703.06211","bibliography":{"title":"Deformable Convolutional Networks","authors":["Jifeng Dai","Haozhi Qi","Yuwen Xiong","Yi Li","Guodong Zhang","Han Hu","Yichen Wei"],"url":"https://arxiv.org/abs/1703.06211","pdfUrl":"https://arxiv.org/pdf/1703.06211v3","codeUrl":null,"preprint":{"id":"1703.06211","submittedOn":"2017-03-17","url":"https://arxiv.org/abs/1703.06211"},"publication":{"venue":"ICCV","year":2017,"kind":"conference","url":"https://openaccess.thecvf.com/content_iccv_2017/html/Dai_Deformable_Convolutional_Networks_ICCV_2017_paper.html"},"citation":"@misc{classiccnnsdeformableconvnets2017,\n  title = {{Deformable Convolutional Networks}},\n  author = {Jifeng Dai and Haozhi Qi and Yuwen Xiong and Yi Li and Guodong Zhang and Han Hu and Yichen Wei},\n  year = {2017},\n  eprint = {1703.06211},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1703.06211}\n}\n","citationPath":"/content/papers/citations/classic-cnns/deformable-convnets.f724f3ff1784.bib"},"thumbnail":{"src":"/content/papers/assets/942dcd98b1119ce95e8a9a24b84ed42b780d062caafa004c66f75640c4e2584a.png","width":987,"height":633},"locale":"zh-hans","path":"/content/papers/zh-hans/classic-cnns/deformable-convnets.b75c34ef240f.md","headings":[{"id":"定义问题","text":"定义问题","depth":2},{"id":"固定的网格","text":"固定的网格","depth":3},{"id":"已经有人让网络学变形","text":"已经有人让网络学变形","depth":3},{"id":"解决问题","text":"解决问题","depth":2},{"id":"卷积的两个步骤","text":"卷积的两个步骤","depth":3},{"id":"每个点加一个偏移量","text":"每个点加一个偏移量","depth":3},{"id":"小数位置怎么取值","text":"小数位置怎么取值","depth":3},{"id":"偏移量从哪里来","text":"偏移量从哪里来","depth":3},{"id":"两个特例","text":"两个特例","depth":3},{"id":"可变形-roi-pooling","text":"可变形 RoI pooling","depth":3},{"id":"放进网络","text":"放进网络","depth":3},{"id":"讨论","text":"讨论","depth":2},{"id":"感受野真的会跟着物体变","text":"感受野真的会跟着物体变","depth":3},{"id":"要换几层","text":"要换几层","depth":3},{"id":"和空洞卷积比","text":"和空洞卷积比","depth":3},{"id":"代价","text":"代价","depth":3},{"id":"coco","text":"COCO","depth":3},{"id":"结论","text":"结论","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"classic-cnns/stn","relation":"referenced","topic":""},{"id":"object-detection/deformable-detr","relation":"referenced","topic":""}]}],"text":"InternImage 的消融实验里，DCNv3 的调制权重从 softmax 换回 sigmoid，ImageNet 准确率从 83.5% 掉到 65.7%。softmax 看起来是 DCNv3 不可或缺的一环。\n\n一年多后，大致是同一群人推出了 DCNv4，第一项改动就是把 softmax 拿掉，而且收敛得比原本更快。\n\n第一作者 Yuwen Xiong 是 2017 年第一代可变形卷积的作者之一，通信作者 Jifeng Dai 则是第一代的第一作者。这次的团队来自多伦多大学、上海人工智能实验室、清华、商汤、港中文等单位。除了 softmax，这篇另一半的篇幅在问，可变形卷积明明只采样 9 个点，为什么跑得比 7×7 的 depthwise 卷积还慢？\n\n\n> [!TIP]\n> \n> DCNv3 和 InternImage 的设计，以及第一代可变形卷积，可以先看这两篇：\n> \n> - **[[22.11] InternImage：大力出奇迹？](/blog/papers/classic-cnns/internimage)**\n> - **[[17.03] Deformable ConvNets：凌波微步](/blog/papers/classic-cnns/deformable-convnets)**\n\n\n[![原论文 Figure 1：(a) 长条图，横轴是三种输入张量大小（56×56×128、28×28×256、14×14×512），纵轴是以 DCNv3 为 1 的相对执行时间；每组有 FlashAttention、Window Attention、DWConv、DCNv3、DCNv4 五根长条，DCNv4 在前两组最短，第三组和 FlashAttention 差不多，56×56×128 那组标注比 DCNv3 快 3.76 倍。(b) 折线图，横轴是训练迭代次数（0 到 15K），纵轴是 ImageNet top-1 准确率；DCNv4 的线在前段一路领先，DWConv 与 Dense Attention 居中，DCNv3 在初期最低。](/content/papers/assets/5a7b5fe22fc3c1bf41919d57fbcca8c73c4d14c00875c73ce999527f2f9ae54e.png)](/content/papers/assets/5a7b5fe22fc3c1bf41919d57fbcca8c73c4d14c00875c73ce999527f2f9ae54e.png)\n\n*原论文 Figure 1（Xiong 等人），取自 [**PDF 第 1 页**](https://arxiv.org/pdf/2401.06197v1#page=1)。原图注未收录。*\n\n左图是速度，DCNv3 是 1，越短越快，DCNv4 在前两种大小最快，到了 14×14×512 和 FlashAttention 差不多。右图是同一个网络架构换不同算子，训练初期的准确率，DCNv4 一路领先，DCNv3 反而垫底。\n\n## 定义问题\n\n### 只采样 9 个点，为什么不快\n\n先复习一下 DCNv3。对位置 $p_0$，第 $g$ 组通道的输出是\n\n$$\ny_g(p_0)=\\sum_{k=1}^{K} m_{gk}\\, x_g\\!\\left(p_0+p_k+\\Delta p_{gk}\\right),\n$$\n\n$K=9$ 是 3×3 网格的采样点数，$\\Delta p_{gk}$ 是学出来的偏移量，$m_{gk}$ 是调制权重，在 DCNv3 里沿着 $K$ 做 softmax。偏移量和权重都从输入算出来，每个位置都不一样。\n\n照理说，只看 9 个点的稀疏算子，应该比 7×7 的 depthwise 卷积或密集的注意力快。实际上不是，问题出在内存访问。\n\n作者用 roofline 模型分析。输入输出都是 $H\\times W\\times C$ 时，DCNv3 的计算量是 $36HWC$ FLOPs，9 个采样点各要做一次双线性插值，每次牵涉 4 个像素。理想情况下，每个数值只从内存读一次，内存访问量大约是 $3.7HWC$。\n\n可是并行计算时，很多线程同时读数据，缓存没办法保证命中。最坏的情况，每个输出位置都要重新读 36 个插值用的像素、27 个偏移量和权重（9 个点各 2 个偏移、1 个权重），再写回 1 个结果，内存访问量变成 $64HWC$，是理想情况的 17 倍。\n\n计算量和内存访问量的比值只有 0.6 到 9.7，在 roofline 模型上落在内存带宽受限的那一侧，GPU 的算力再多也用不上。\n\n### softmax 是借来的\n\n另一个问题是 softmax。DCNv3 的 softmax 是向注意力机制借来的，可是注意力需要 softmax 有它的理由。\n\n缩放点积注意力是 $\\mathrm{softmax}(QK^\\top/\\sqrt{d})V$。拿掉 softmax，就可以先算 $K^\\top V$，得到一个 $d\\times d$ 的矩阵，同一个窗口里的所有查询都乘上同一个矩阵，注意力就退化成一个线性投影。\n\n卷积和 DCNv3 没有这个问题。每个位置本来就有自己的采样窗口，窗口里的值本来就各不相同，没有「key」的概念，也就不需要归一化。\n\n为了验证，作者反过来在 ConvNeXt 的 7×7 depthwise 卷积权重上加 softmax：\n\n| 模型 | 第 5 个 epoch | 第 10 个 | 第 20 个 | 第 50 个 | 第 300 个 |\n| --- | ---: | ---: | ---: | ---: | ---: |\n| ConvNeXt | 29.9% | 53.5% | 66.1% | 74.8% | 83.8% |\n| ConvNeXt + softmax | 8.5% | 25.3% | 51.1% | 69.1% | 81.6% |\n\n*表：摘自原论文 Table 1，ImageNet-1K top-1。*\n\n加了 softmax，收敛明显变慢，训练完也少了 2.2 个百分点。\n\nsoftmax 把每个权重限制在 0 到 1 之间，加总是 1，输出就只能是采样值的加权平均。加权平均永远落在最小值和最大值之间，做不出「相减」这种运算，而边缘检测这类最基本的滤波器就是在相减。我们让两种权重去学一个「右边减左边」的滤波器：\n\n```python\nimport torch\n\ntorch.manual_seed(0)\nx = torch.randn(1000, 3)                     # 一千个位置，每个位置采样左、中、右三个点\ntarget = x[:, 2] - x[:, 0]                   # 想学的是「右边减左边」，一个最简单的边缘检测\n\nfor name, to_weight in [(\"softmax 权重\", lambda z: z.softmax(0)), (\"不设限的权重\", lambda z: z)]:\n    z = torch.zeros(3, requires_grad=True)\n    opt = torch.optim.Adam([z], lr=0.1)\n    for _ in range(500):\n        loss = ((x @ to_weight(z) - target) ** 2).mean()\n        opt.zero_grad()\n        loss.backward()\n        opt.step()\n    w = to_weight(z).detach()\n    print(f\"{name}：左 {w[0]:+.2f}  中 {w[1]:+.2f}  右 {w[2]:+.2f}  误差 {loss.item():.3f}\")\nprint(f\"目标本身的方差：{target.var():.3f}\")\n```\n\n```text\nsoftmax 权重：左 +0.00  中 +0.00  右 +1.00  误差 0.995\n不设限的权重：左 -1.00  中 +0.00  右 +1.00  误差 0.000\n目标本身的方差：2.008\n```\n\n不设限的权重直接学到 $(-1, 0, 1)$。softmax 权重给不出负数，最好的选择只能把权重全押在右边那一点，误差还留着一半。\n\n[![原论文 Figure 2：四格示意图，比较同一个通道里不同位置的查询像素如何做空间聚合，左上角图例说明星号是查询像素、方格是回应像素，颜色条分成 (0, 1) 与 (−∞, +∞) 两种值域。(a) Attention：窗口 Shared/Fixed，权重 Dynamic，值域 Bounded；(b) DCNv3：窗口 Dedicated/Adaptive，权重 Dynamic，值域 Bounded；(c) Convolution：窗口 Dedicated/Fixed，权重 Static，值域 Unbounded；(d) DCNv4：窗口 Dedicated/Adaptive，权重 Dynamic，值域 Unbounded。](/content/papers/assets/fe768f9a1b9df098fd7de1ed2c34ba0713cb83936e024d45ca26e85a2b340ff1.png)](/content/papers/assets/fe768f9a1b9df098fd7de1ed2c34ba0713cb83936e024d45ca26e85a2b340ff1.png)\n\n*原论文 Figure 2（Xiong 等人），取自 [**PDF 第 3 页**](https://arxiv.org/pdf/2401.06197v1#page=3)。原图注未收录。*\n\n这张图把四种算子放在一起比。注意力的权重会变，可是有上限；卷积没有上限，可是权重固定、窗口形状固定。DCNv4 想要的是右下角，每个位置有自己会变形的窗口，权重随输入变化，而且没有上限。\n\n## 解决问题\n\n### 一、拿掉 softmax\n\n公式和 DCNv3 一样，只是 $m_{gk}$ 不再过 softmax，直接由一个线性层从输入预测，可以是任何实数。\n\nsoftmax 拿掉之后，还有一个附带的好处。原本算偏移量和算权重是两个线性层，现在可以合成一个，少一次 kernel 启动和同步。作者也把计算偏移量的子网络简化，原本是 depthwise 3×3、LayerNorm、GELU 再接线性层，现在拿掉中间的 LayerNorm 和 GELU，回到 Xception 那种单纯的可分离卷积。\n\n### 二、让 GPU 少搬数据\n\n[![原论文 Figure 3：左右两张示意图，比较 DCNv3 与 DCNv4 的线程分工。两边左侧都是 GPU 内存中的一组偏移量与权重，右侧是立方体状的输出张量（H、W、C）。(a) DCNv3 有 Thread-1 到 Thread-6 六个线程，各自负责一个通道，每个都发出一次内存读取请求；(b) DCNv4 只有 Thread-1 到 Thread-3，每个线程负责同一组里的两个通道，读取请求少了一半，右上角标注内存访问少 2 倍。](/content/papers/assets/db5cc5d4b75082f8705ba96857cd9bf56bd46cfb53a7946d53500fabcace0dd5.png)](/content/papers/assets/db5cc5d4b75082f8705ba96857cd9bf56bd46cfb53a7946d53500fabcace0dd5.png)\n\n*原论文 Figure 3（Xiong 等人），取自 [**PDF 第 4 页**](https://arxiv.org/pdf/2401.06197v1#page=4)。原图注未收录。*\n\nDCNv3 原本的 CUDA 实现开 $H\\times W\\times C$ 个线程，一个线程负责一个位置的一个通道。可是同一组的 $D=C/G$ 个通道，在同一个位置共用同一组偏移量和权重，结果 $D$ 个线程各自去内存读同样的东西，双线性插值的系数也各算一次。\n\nDCNv4 让一个线程负责同一组里的好几个通道，偏移量和权重只读一次，插值系数也只算一次。图中为了好画，一个线程负责两个通道，实际的实现是 8 个。\n\n有趣的是，光做这一步反而变慢。线程变少，并行度下降，每个线程的工作量变成 8 倍。真正的加速来自下一步。通道在内存里是连续摆放的（channel-last），相邻几个通道的值可以用一条向量化指令一次读进来，例如四个 32 位的浮点数合成一次 128 位的读取，不用一个一个读。写回结果也一样。\n\n作者把每一步的效果拆开量。输入 56×56×128，批量 64，4 组（每组 32 个通道），单位是毫秒：\n\n| 实现 | 整个模块 | CUDA 内核 |\n| --- | ---: | ---: |\n| DCNv3 原版 | 3.28 | 1.45 |\n| 精简模块设计 | 2.12 | 1.45 |\n| 一个线程处理 8 个通道 | 2.20 | 1.53 |\n| 重复使用插值系数 | 2.18 | 1.51 |\n| 向量化读写 | 1.28 | 0.606 |\n| 改用半精度 | **0.873** | **0.404** |\n\n*表：摘自原论文 Table 10。A100。*\n\n精简模块设计只动到内核以外的部分，内核时间没变；接下来两步让内核变慢了一点；向量化读写一上，内核时间少了六成。半精度每个数只有 2 个字节，同样的带宽能多搬一倍数据。作者说原本的 DCNv3 换成半精度并不会变快，新的实现才吃得到这个好处。\n\n## 讨论\n\n### 算子本身\n\n先比算子。输入 56×56×128，分别用 FP32 和 FP16 量：\n\n| 算子 | FP32（ms） | FP16（ms） |\n| --- | ---: | ---: |\n| 全局注意力（PyTorch） | 30.8 | 19.3 |\n| FlashAttention-2 | — | 2.46 |\n| 7×7 窗口注意力 | 4.05 | 1.46 |\n| 7×7 DWConv（PyTorch） | 2.02 | 1.98 |\n| 7×7 DWConv（cuDNN） | 0.981 | 0.438 |\n| DCNv3 | 1.45 | 1.52 |\n| DCNv4 | **0.606** | **0.404** |\n\n*表：摘自原论文 Table 2 的第一列。FlashAttention-2 没有 FP32 版本。*\n\nDCNv4 比 cuDNN 的 7×7 depthwise 卷积还快，FP32 时执行时间少了将近四成。DCNv3 那一行也印证了前面的说法，换成 FP16 反而慢了一点。\n\n### FlashInternImage\n\n把 InternImage 里的 DCNv3 换成 DCNv4，其他不变，作者叫它 FlashInternImage。吞吐量用 FP32 和 FP16 各量一次：\n\n| 模型 | top-1 | 吞吐量（FP32 / FP16，张／秒） |\n| --- | ---: | ---: |\n| ConvNeXt-T | 82.1% | 2485 / 4305 |\n| InternImage-T | 83.5% | 1409 / 1746 |\n| FlashInternImage-T | **83.6%** | 2316 / 3154 |\n| ConvNeXt-S | 83.1% | 1645 / 2538 |\n| InternImage-S | 84.2% | 1044 / 1321 |\n| FlashInternImage-S | **84.4%** | 1625 / 2396 |\n| ConvNeXt-B | 83.8% | 1241 / 1888 |\n| InternImage-B | 84.9% | 779 / 1030 |\n| FlashInternImage-B | **84.9%** | 1174 / 1816 |\n\n*表：摘自原论文 Table 4 的部分行。*\n\n和 InternImage 比，T 快了 64% 到 80%，准确率还稍微高一点。\n\n和 ConvNeXt 比要小心看。FlashInternImage-T 在 FP16 下还是只有 ConvNeXt-T 的七成多速度，S 和 B 也略慢，大约是 ConvNeXt 的九成五。比较公平的说法是，DCNv4 把 InternImage 拉到和 ConvNeXt 差不多的速度，准确率多了 1.1 到 1.5 个百分点。\n\n下游任务的趋势一样。COCO 上用 Mask R-CNN 训练 12 个 epoch，FlashInternImage-T 的 box AP 是 48.0，InternImage-T 是 47.2，FPS 从 54 / 69 变成 72 / 102。ADE20K 上用 UperNet，单尺度 mIoU 从 47.9 提高到 49.3。\n\n### 换进别的网络\n\n作者也试了把 DCNv4 当成零件，直接换进别的架构，其他设置和超参数都不改：\n\n- **ConvNeXt-B**：7×7 depthwise 卷积换成 DCNv4，ImageNet 从 83.8% 到 84.0%，吞吐量多了 20%（FP32）和 33%（FP16）。\n- **ViT-B**：注意力换成 DCNv4，81.8% 到 81.9%，吞吐量比用 FlashAttention-2 的原版多了 24% 和 17%。\n- **潜在扩散模型的 U-Net**：把注意力模块和一般的 3×3 卷积换掉，在 ImageNet 256×256 类别条件生成上，FID 从 2.94 降到 2.44，参数从 860M 降到 566M。\n\n这些架构原本都是为自己的算子调过的，DCNv4 直接换进去，准确率持平或略好，速度更快。生成那一项作者也说，架构和超参数不一定适合 DCNv4，还有调整的空间。\n\n### 代价\n\nDCNv4 还是一个自定义的 CUDA 算子。官方 repo 的 issue 里，编译失败、找不到模块、CPU 不支持、转 ONNX 和 TensorRT 卡关的问题占了很大一部分，repo 最后一次推送是 2024 年 5 月。\n\n也有用户反馈的结果和论文不同。有人在自己的分割任务上发现[训练比 DCNv3 还慢](https://github.com/OpenGVLab/DCNv4/issues/54)，有人用官方的测速程序在 3090 上量，[结果也比论文说的慢](https://github.com/OpenGVLab/DCNv4/issues/106)。还有好几位把 DCNv4 接进自己的模型，例如 YOLO，反馈 [loss 不降](https://github.com/OpenGVLab/DCNv4/issues/80)或[出现 NaN](https://github.com/OpenGVLab/DCNv4/issues/105)。这些反馈都没有附上完整设置，也没有官方回复，原因不明。\n\n本文的推测是，权重少了 softmax 的上限，接进别人的网络时，初始化和学习率可能要重新调。论文里的成功经验，都是在 InternImage 这类为可变形卷积设计的架构，或是作者自己调过的设置上得到的。\n\n## 结论\n\nDCNv4 做了两件事。一件是拿掉 softmax，权重和一般卷积一样不设上限，模型收敛得更快；另一件是重写 CUDA 内核，同一组的通道共用一次读取，再用向量化指令一次搬好几个通道，算子快了三倍多。\n\n已经在用 InternImage 的话，换成 FlashInternImage 几乎是免费的速度。要接进自己的模型，记得开半精度，DCNv4 在 FP16 才跑得最快；前几百步的 loss 也要多看两眼。\n\n论文标题写的是「重新思考动态与稀疏算子」。读到最后，大半的速度其实来自一个很朴素的问题，同一组通道的偏移量到底要从内存读几次。\n","imageSizes":{"/content/papers/assets/5a7b5fe22fc3c1bf41919d57fbcca8c73c4d14c00875c73ce999527f2f9ae54e.png":{"width":1020,"height":546},"/content/papers/assets/fe768f9a1b9df098fd7de1ed2c34ba0713cb83936e024d45ca26e85a2b340ff1.png":{"width":1020,"height":522},"/content/papers/assets/db5cc5d4b75082f8705ba96857cd9bf56bd46cfb53a7946d53500fabcace0dd5.png":{"width":1020,"height":426}}}
