惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Blog — PlanetScale
Blog — PlanetScale
Webroot Blog
Webroot Blog
T
Troy Hunt's Blog
S
Secure Thoughts
S
Security @ Cisco Blogs
S
Security Affairs
Forbes - Security
Forbes - Security
W
WeLiveSecurity
H
Hacker News: Front Page
T
Threatpost
Google Online Security Blog
Google Online Security Blog
S
Schneier on Security
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - Franky
腾讯CDC
IT之家
IT之家
博客园 - 聂微东
L
LINUX DO - 最新话题
罗磊的独立博客
Hacker News - Newest:
Hacker News - Newest: "LLM"
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 三生石上(FineUI控件)
Hacker News: Ask HN
Hacker News: Ask HN
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
C
CERT Recently Published Vulnerability Notes
Know Your Adversary
Know Your Adversary
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园_首页
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Cisco Talos Blog
Cisco Talos Blog
S
SegmentFault 最新的问题
酷 壳 – CoolShell
酷 壳 – CoolShell
Hugging Face - Blog
Hugging Face - Blog
L
LINUX DO - 热门话题
美团技术团队
G
GRAHAM CLULEY
T
The Exploit Database - CXSecurity.com
AI
AI
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Jina AI
Jina AI
Help Net Security
Help Net Security
N
News | PayPal Newsroom
月光博客
月光博客
Spread Privacy
Spread Privacy
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
N
News and Events Feed by Topic

Пусть этот камень будет более крепким, чем человек

【琐记】烟火与尘埃 【Triton】Triton实现矩阵乘 【LLM推理加速】FlashAttention 【LLM推理加速】PagedAttention 【LLM推理加速】Online Softmax LLM基础知识【1】 Transformer模型 【AI编译】LayerGroup Tiling Tile的疑惑和思考 【AI编译】深度优先的Tile调度,万事大吉? 【AI编译】多级流水线Tile调度策略 【CUDA C++】GPU内存使用【3】 【AI编译】Cache缓存地址映射 【CUDA C++】GPU存储【2】 【CUDA C++】GPU基本介绍【1】 【00】0序章-不受欢迎的来客 【转载】我来了——持续低熵 【Halide】调度优化【2】 【感想】写作进度报告5 【Halide】调度优化【1】 【转载】北大中文男足战报2 【BYOC】TVM切分子图 【转载】北大中文男足战报1 【AI编译】张量生命周期管理 SystemC 用寄存器同步建模方法 【脉动阵列】脉动阵列类型 【im2col】AScend conv accelerate 【感想】写作进度报告4 【BYOC】TVM添加自定义编译器 ccompiler 【感想】写作进度报告3 【Tengine】推理流程脑图【2】 【Tengine】推理流程脑图【1】 【NCNN】学习ncnn模型转换 【编译器】使用llvm编译自定义语言【3】编译 object 【编译器】使用llvm编译自定义语言【2】转llvm IR 【编译器】使用llvm编译自定义语言【1】构建AST 【AI编译】如何进行内存分配 【感想】写作进度报告2 【AI编译】layer-group之后如何tiling 【AI编译】如何进行layer-group 【量化】连续卷积层首尾量化的可行性 【Gemm】内存对齐 【gemm】Gemm计算加速 【TVM】通过代码学习编译流程【5】FuseOps 【TVM】通过代码学习编译流程【6】CodeGen 【TVM】通过代码学习类【3.5】Pass 【TVM】通过代码学习编译流程【4】BuildRelay 【AI编译】Tiling操作能优化什么时间 【TVM】通过代码学习编译流程【3】模型编译 【TVM】通过代码学习编译流程【2】模型转换 【TVM】通过代码学习编译流程【1】必要知识 【感想】写作进度报告1 【Winograd】卷积加速算法原理及实现 SystemC 等待异步事件解决方案 【TVM】Python脚本实现模型编译和保存 【推理引擎】常见AI推理框架 【3D建模】T110E3卡迪夫蓝调皮肤模型 【TVM】C++部署运行TVM 【推理引擎】NCNN和Tengine量化推理逻辑对比 【3D建模】IS-7攻城锤流纹岩皮肤展示 【TVM】根据例子走通代码库 博客汇总目录 【Im2Col】卷积加速算法【1】 NCHW openBlas库的安装与简单使用 C语言工程调用Cpp库解决方案 foo Hello World
【Im2Col】卷积加速算法【2】NHWC
Post author: XianMu@Пусть этот камень будет более крепким, чем ч · 2024-05-23 · via Пусть этот камень будет более крепким, чем человек

本文为最基本的 Im2Col 算法的原理及实现。

【Im2Col】卷积加速算法 NCHW 【1】中已经讲了在输入和输出都是 nchw 排布下 Im2Col 算法的实现方式。常见的 tensor 输入有 NCHW 和 NHWC 两种内存排布方式,不同的排布方式各有优劣。排布方式不同,Im2Col 也有区别,本篇主要是在 NHWC 内存排布情况下的 Im2Col 算法原理和基本实现。

慌乱的时候全是破绽,冷静下来,能够找到对方的破绽。
------ 大家好啊 我是 暮冬 Z 羡慕

# 两种内存排布

卷积神经网络(CNN)的输入数据布局主要有两种标准:NCHW(通道、高度、宽度)和 NHWC(高度、宽度、通道)。主要深度学习框架对这两种布局的支持情况如下:

PyTorch:主要采用 NCHW 格式。这是 PyTorch 在大多数情况下的默认布局,尤其是在涉及 GPU 计算时。

Caffe:采用 NCHW 格式。Caffe 框架倾向于使用这种通道优先的布局。

TensorFlow:默认使用 NHWC 格式,特别是在早期版本中,这是由于 TensorFlow 最初设计时主要针对 CPU 进行优化,NHWC 布局在这种场景下有更好的内存访问局部性。
Keras:Keras 本身是一个高级 API,集成到 Tensorflow 之后跟随 tensorflow 的内存排布方式。

# 内存排布的优缺点

NCHW 格式的优点:

  • 1. 在 GPU 中计算卷积时,比 NHWC 要快 2.5 倍左右。这是因为在 GPU 中,NCHW 格式的数据布局更符合 GPU 的内存访问模式和计算方式。

  • 2.NCHW 格式更适合那些需要对每个通道单独做运算的操作,比如 “MaxPooling”。这是因为 NCHW 格式的同一通道的像素值连续排布,使得对每个通道的数据可以更高效地进行运算。

NCHW 格式的缺点:

  • 1.NCHW 格式需要把所有通道的数据都读取到,才能进行运算,因此在计算时需要的存储更多。这可能会限制其在一些具有限制的硬件环境下的应用。

  • 2.NCHW 格式的访存与计算的控制逻辑相对简单,这使得在一些需要精细控制访存和计算的场景下,可能不是最佳的选择。

NHWC 格式的优点:

  • 1.NHWC 格式的访存局部性更好。这意味着每三个输入像素就可以得到一个输出像素,因此在一些特定的计算操作中,可以更高效地利用硬件资源。

  • 2.NHWC 格式更适合那些需要对不同通道的同一像素做某种运算的操作,比如 “Conv1x1”。这是因为 NHWC 格式的不同通道中的同一位置元素顺序存储,使得对不同通道的数据可以进行更高效的运算。

  • 3.NHWC 格式在早期的 CPU 开发中应用较多,因此对于主要基于 CPU 开发的深度学习框架和算法,NHWC 格式可能更受欢迎。

NHWC 格式的缺点:

  • 1. 在使用 GPU 进行计算加速时,NHWC 格式不如 NCHW 格式高效。这是因为 NCHW 格式更符合 GPU 的内存访问模式和计算方式。

  • 2. 对于一些需要精细控制访存和计算的场景,NHWC 格式的控制逻辑可能相对复杂一些。

Im2col 算法是将卷积转换成两个 2D 矩阵乘运算。(kernel_2D * input_2D) 与 (input_2D * kernel_2D) 矩阵乘的顺序不同,所需要的 4D 到 2D 变换也不同,我们先将 input_2D 放在前面,也就是 (input_2D * kernel_2D),最后再讨论 kernel_2D 放在前面还是后面的区别。

依然采用下面这个简单的卷积样例,输入 tensor 按照 nhwc 排布,所以是一个 3 通道 5*5 的 input tensor。卷积核有 9 个,pad 为 1,因此输出是【1,5,5,9】。

卷积样例

直接展开 2D 形式,两个矩阵形式如下。

Im2Col 2D示意图

上图右边是权重 kernel_2D

  • 1. 原 kernel_4D 维度为【9,3,3,3】,拥有 9 个 kernel,将其第一个 kernel 按照【C_in, Kh, Kw】的顺序展成一列,也就是第一列绿色部分,共有 27 个数。

  • 2. 依次将余下 8 个 kernel 按照相同的方式展成一列,就得到了 kernel_2D。

  • 3.kernel_2D 维度为【27,9】

从内存排布上来看,需要将原本的 kernel_4D 进行数据重排。

上图左边是输入 input_2D

  • 1. 矩阵乘是 行 * 列;kernel_2D 一列代表一个卷积核【C_in, Kh, Kw】;所以 input_2D 的一行是 “一个卷积核滑动窗口” 对应的数据,也就是 27 个。

  • 2. 第一行橘黄色部分是第一个滑动窗口对应的数据,未填的数代表 Pad。

  • 3. 滑动窗口需要纵移 5 次,每次纵移需要横移 5 次,因此有 5*5 行数据。

  • 4. 例如第 5 行蓝色是滑动窗口在图一中向右移动到第 5 格,蓝色格子时对应的数据。由于 Input_2D 的维度是 NHWC,也就是说图一中 “0,25,50” 三个数在内存中是相邻的(分别位于同一个 HW 位置的第一、第二、第三通道)。为了减少数据的搬运,这些连续的数被搬运到一起。即:图一中 3*3 的蓝色滑动窗口中前 3 个都对应 Pad,所以图二第 5 行蓝色行先有 3*3 (channel) 个 Pad 数据。图一蓝色滑动窗口在第 4 和第 5 个格子出现数据,所以图二 9 个 Pad 后面跟着 3,28,53;4,29,54。紧接着又出现了 Pad,以此类推。

  • 5. 总结:25 次窗口滑动,每次滑动形成窗口对应的一行 27 个数据。input_2D 的维度为【25,27】

  • 6. 总结完 input_2D 的数据排布,那么 kernel_2D 每一列的数据具体怎么排也就清楚了,需要和 input_2D 的每一行一一对应。

输出 output

input_2D【25,27】* kernel_2D 【27,9】得到结果 output_2D 【25,9】,刚好是输出 output【1,5,5,9】的内存排布方式。因此输出也不需要额外的内存转换。

# 代码实现

这里没有专门写 Im2Col 在 NHWC 排布情况下的实现代码。
可以阅读文章:im2col 卷积加速算法 NCHW,参考 NCHW 排布下的代码实现,自行完成 NHWC 内存排布情况下的算法。

# 矩阵乘先后顺序的影响

以严格按照矩阵标准的 行 * 列 运算为前提,权重和输入的先后顺序会影响其内存排布。

两种排布情况下矩阵乘先后顺序不同对数据变换的影响

已经讲解了简单的 im2col 算法在 NCHW 排布上一篇文章和 NHWC 排布情况下的 2D 内存排布情况。上图总结了两种排布情况下 矩阵乘先后顺序不同对数据变换的影响。

  • NCHW 排布 kernel 在前 只需要对 input 做 im2col 变换
  • NCHW 排布 input 在前 多出来对权重的转置变换 和输出的转置变换
  • NHWC 排布 kernel 在前 需要对权重数据进行重排 以及输出进行转置
  • NHWC 排布 input 在前 需要对权重进行转置

当然,在真正运算矩阵乘时,如果有行优先货列优先的调整,就需要具体问题具体分析了。

# 后记

本博客目前以及可预期的将来都不会支持评论功能。各位大侠如若有指教和问题,可以在我的 github 项目 或随便一个项目下提出 issue,并指明哪一篇博客,我看到一定及时回复!