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

推荐订阅源

Cloudbric
Cloudbric
D
Docker
F
Fortinet All Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Announcements
Recent Announcements
月光博客
月光博客
B
Blog RSS Feed
Help Net Security
Help Net Security
L
LINUX DO - 最新话题
Recorded Future
Recorded Future
Stack Overflow Blog
Stack Overflow Blog
Webroot Blog
Webroot Blog
Y
Y Combinator Blog
N
News and Events Feed by Topic
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
I
InfoQ
Microsoft Azure Blog
Microsoft Azure Blog
Microsoft Security Blog
Microsoft Security Blog
J
Java Code Geeks
美团技术团队
P
Privacy & Cybersecurity Law Blog
H
Help Net Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
酷 壳 – CoolShell
酷 壳 – CoolShell
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园 - 聂微东
Scott Helme
Scott Helme
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
The Hacker News
The Hacker News
腾讯CDC
H
Hackread – Cybersecurity News, Data Breaches, AI and More
G
GRAHAM CLULEY
S
SegmentFault 最新的问题
爱范儿
爱范儿
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
CXSECURITY Database RSS Feed - CXSecurity.com
D
DataBreaches.Net
博客园_首页
V
Vulnerabilities – Threatpost
PCI Perspectives
PCI Perspectives
S
Security @ Cisco Blogs
GbyAI
GbyAI
Schneier on Security
Schneier on Security
The Last Watchdog
The Last Watchdog
The Register - Security
The Register - Security
WordPress大学
WordPress大学
T
Tor Project blog
A
About on SuperTechFans
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org

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

【琐记】烟火与尘埃 【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 【量化】连续卷积层首尾量化的可行性 【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】卷积加速算法【2】NHWC 【Im2Col】卷积加速算法【1】 NCHW openBlas库的安装与简单使用 C语言工程调用Cpp库解决方案 foo Hello World
【AI编译】layer-group之后如何tiling
Post author: XianMu@Пусть этот камень будет более крепким, чем ч · 2025-01-15 · via Пусть этот камень будет более крепким, чем человек

# 前言

本篇讲解笔者实现 tiling 算法的一些经验。
前述文章 《如何进行 layer-group》讲解了 layer group 的内容。《Tiling 操作能优化哪些时间》提到 Tiling 的概念和作用。感兴趣的话可以阅读。

本篇文章参考过 《超强干货!地平线编译器大牛的编译优化实践总结》《Arm 周易编译器工程》《算能 TPU layer group 讲解》《算能 TPU 视频讲解》 等文章和工程,欢迎大家参考。

作为初学者,错误在所难免,还望不吝赐教。

# 回顾

回顾流程

如图所示,AI 编译优化的基本流程是 1. 图优化 (算子融合,常量折叠等) 2. 拆分 (layer group 和 tiling) 3. 并行和调度。最后得到当前编译的时间消耗。

分支结构

假设现在对某个 layer group 做 tiling,需要对当前这个 layer group 按照 tiling 块数构建平行分支。

上图来自《算能 TPU layer group 讲解》。如图所示,含有三个卷积算子的 layer group ,将其 tiling 成四块,则 group 的图结构变成右边的形状,图上也表明了 tiling 之后 tensor 的大小。可以使用 crop 算子完成 tensor 的切分,使用 concat 算子实现 tensor 的合并。图中没有画出 crop 算子和 concat 算子。

神经网络结构复杂多样,分支结构、多前序节点、多后续节点等给 tiling 的实际操作带来很大困难。根据前述的 layer group 动态搜索划分,我们可能需要在各种各样的结构上进行 tiling 操作。下图是一种较为复杂的分支结构在 tiling 前后的对比图,可以给 tiling 结构的创建带来更直观的感受。

复杂分支结构tiling

这是一个虚构的、较为复杂的分支结构。中间彩色的五个节点是当前要做 tiling 的 layer group,而上方和下方是当前 layer group 的前序节点和后续节点。
为方便,只 tiling 成两块。

tiling 后的结构如图右侧所示,原有彩色算子部分复制成两份;layer group 有几个输出端(当前 group 有两个输出端:Conv 和 Fc)就有几个 concat 节点。layer group 的输入端(Add 节点和 Relu 节点)前面要添加 crop 节点,当输入端有多个前序节点时(Add 有两个前序节点),每个都要添加 crop。

大致的结构重建就是这个样子。在实际操作中可能还有些不同,例如为保持所有节点都只能有一个输出 tensor 的原则,Crop 节点不能输出两个 tensor。

# Tiling 维度

现有方案基本都选择在 N H W,也就是批次、高度、宽度这三个维度上做 tiling。

N(批次)方向分块是最简单的方案,可以随意划分,对整个网络的运行没有影响。但是也许模型在推理的时候批次只有 1,无法 tiling。所以批次方向不是在所有情况下都适用。

高度和宽度方向 tiling,比批次方向稍复杂,需要重新 infer shape 和调整参数(下一节讲解),但好在原有的算子推理仍然适用。

基本上不考虑 C(通道)方向 tiling。通道方向分块,不仅要调整权重偏置 tensor,还需要在算子运算后加减 tensor,破坏了原有算子推理。
现有方案基本支持批次、高度、宽度这三个维度上做 tiling。

# Tiling 逆向推理

上面只完成了 layer group 在 tiling 之后的结构重建。想要实现模型的正确推理,还需要更新好多信息。

# 逆向 shape 推理

推理 shape,在 tensor 分块后,维度大小自然需要更新。下图是一个简单的分支结构的 tensor shape 推理例子。

逆向推理

图①是推理之前的网络结构,仅包含两个卷积算子(均为 3*3,pad=1)。图上已经标明了每个算子的输入输出 tensor 的大小。现在将此 group 从 H(高)维度 tiling 成两份,也就是输出端(Add 节点)的输出 tensor 设置为 5*10。

从输出端(Add 节点)开始逆序推导各个算子的输入输出 shape。如图②,普通算子如 Add,输入 tensor 的 shape 于输出 tensor 相同。而 Conv 这样的算子,需要根据参数、所在位置、输出 shape 来计算输入 tensor 的 shape。例如图②中 Conv_2 的输入变成 [6,10],参数中 pad 需要修改为 [1,0,1,1]。

现在出现一个问题:从 Add 节点直接往前推,Conv_1 的输出应该是 [5,10],而走 Add->Conv_2 路径,Conv_1 的输出应该是 [6,10]。Conv_1 不可能同时输出 [6,10] 和 [5,10] 两个 tensor。如何处理当前的歧义呢?

也许增加一个 crop 节点是个可选的方法。如图③所示,增加一个新的 Crop 节点,将 Conv_1 的输出 tensor 从 [6,10] 变成 [5,10]。

# 逆向深度优先搜索

从逆向 shape 推理过程的分析来看,更新 layer group 的 shape,需要从输出端开始,逆向深度优先搜索每个分支,更新 shape 信息,还得判断采用哪些信息(如上一节中 Conv_1 的输出是 [6,10] 还是 [5,10])。

逆向深度优先搜索每个分支的意思如下图所示:从输出端搜索到输入端的每一条通路。下图结构中有四条通路。

深度优先搜索

# 后记

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