Files
matmul-analysis/req.txt
2026-08-20 14:40:44 +00:00

96 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

《BMM最优软件实现方案设计.md》的第六章给出了BMM最优性能的4大分支《BMM分块计算数学公式.html》从公式原理角度给出了分块计算的定义但是这两个之间还差一层逻辑就是如何从分块计算+最优实现推导出需要这4大分支呢请帮我好好思考分析这个问题另外《BatchMatMulV3算子分支实现分析.html》里面有当前BMM算子实现的分析供参考
-------------------------------------
需要补充修正一下在问题定义里说的BMM 的语义是元素级运算这个写的很好很清楚但是我们在NPU上是使用Cube核进行分块矩阵乘的计算请再补充一个分块矩阵乘的公式及其说明注意4个维度都可以切直接补充到《BMM分块计算数学公式.html》、《BMM分块计算数学公式.md》这两个文件里去
--------------------------------------
BMM分块计算的本质用数学公式要如何表示注意4个维度都可以切你直接输出的公式都是没有渲染的生成格式规范的markdown文档和html文件输出到本地吧
-------------------------------------
《BatchMatMulV3算子分支实现分析.html》文件的第五章逐分支详解的描述不够清晰、不够细致也没有为什么这么做为什么设置这个参数这个参数为什么是这个值的分析请把第五章好好完善首先要要把代码实现过程清晰的描述出来可以配套画一些流程图或架构图每个分支都要清晰的、详细的描述条件、实现过程、步骤并进行必要分析为什么这么做注意参考NPU知识库中的其他资料或者上网搜集其他资料辅助分析
------------------------------------
详细分析下NPU知识库中ops-nn/matmul/batch_mat_mul_v3的算子代码实现为了高性能的实现BMM算子的所有case当前BMM算子有哪些分支为什么是这些分支这些分支具体是怎么实现的形成html格式的分析说明文档输出到本地可以参考NPU知识库中的其他资料或者上网搜集其他资料辅助分析
tips1算子软件实现方案设计主要是结合芯片微架构特征和规格设计分块到各个AiC核上的搬移、计算的tiling和swizzle(所谓swizzle简单说就是分块执行的顺序以及哪个分块在哪个核上做)
--------------------------------
分析还是有漏洞,不够细致
1、在6.2的排除规则1中你说“核间再切 B/M/N 不会增加并行度,只会减少每核的 K 范围”这句话不理解当一个case输入后case本身的B\M\K\N是固定的只切K分到所有核和切K又切另外维度分到所有核相比显然前者的K会切的更小后者的K会切的更大对应的K的范围会更大才对吧怎么会“只会减少每核的 K 范围”呢例如case的B=4,K=4096如果只切K每核分得B=4K=4096/32=128如果切K又切B每核分的B=1K=512K变大了啊中间矩阵写出的次数更少了吧此时Reduce开销会比只切K时更多吗
注意在做本项目时,在分析思考时,如果有不确定的信息或困惑要多参考知识库(/storage/Users/currentUser/WorkBuddy/昇腾NPU/昇腾NPU知识库)的资料,或者从网上查询,不要局限于当前编辑的文档本身;
请进一步完善第六章
--------------------------------
分析还是不仔细不完备漏洞很多,还是重点先修改第六章的内容:
1、转普通Matmul还叫TO_MUL分支合适吗当前算子源码中TO_MUL是针对K==1且只用AIV去计算跟转普通Matmul意义差别很大转普通Matmul后只是没有B维度了如何做最优实现是另一大问题只是不在当前BMM算子下研究这个分支是将BMM的case中的某一类问题通过转换的方式借助Matmul的分析优化成果站在Matmul优化的巨人肩膀上高效实现BMM的caseBMM算子优化分析只关注相对Matmul差异化的case的最优实现
2、在第6.1章节对于分支完备性的分析还有很多欠考虑的地方ASW_Basic不只是B=1吧B较小时是不是都可以cover甚至B较大时单Batch的输出MN超过L0C的大小此时ASW_Basic核间切B\M\N的性能和IterBatch核间切B核内可切M\K\N的性能究竟哪个好要如何分辨呢
3、在第6.1章节,你说“不存在第六种独立分支——例如"同时切 K 和 M/N"是 StreamK 与 ASW_Basic 的组合,但可归入 StreamK核间切 K 后,核内自然切 M/N从完备性角度是可能存在核间同时切 K 和 M/N的从性能最优角度也可以考虑排除一些分支但为什么排除掉这个分支需要有充分理由说明当完备性角度考虑的某个分支明确明显不如性能最优角度的候选分支才可以完全排除性能最优角度列出的分支应该是完备性角度分支的子集应该是性能最优角度的全集即任何case若想达到最优性能必然要按性能最优角度的某个分支中的实现方案实现如果某些case可以在完备性的某个分支中可达到性能最优则不能排除该分支你定义的StreamK分支是严格限制只切K吗核间完全不切B\M\N那这个分支要要求K必须很大K多大合适进入StreamK分支
-----------------------------
问题还是很多,没有细致考虑数据块在硬件上流转实现的细节,还是重点先修改第六章的内容;
1、按我的设想还应该有个可转普通Matmul的分支即当左矩阵或者右矩阵中有一个的B=1即BatchA=1或BatchB=1则可以把另一个B合并到非K的维度上例如左矩阵的BatchA=1此时可以将矩阵变为[M,K]@[K,BatchB*N]这样的二维矩阵相乘只是输出后要做一个按Batch的split从而转换普通Matmul的软件实现
2、请先从系统角度分析下为什么是这几个分支这些分支可以把所有BMM的case都覆盖全面还有没有其他分支的可能理由要充分和逻辑要清晰
3、第6.3 MergeBatch 不是每次计算都“将单核负责的 全部B_core 个 batch 的 A 矩阵沿 M 维拼接为 [B_core×M, K]、B 矩阵沿 N 维拼接为 [K, B_core×N],调用一次 Matmul 得到 [B_core×M, B_core×N] 的等效大矩阵”假设单核分到B_core 个 batch Cube->L0C 单次计算时可以只进行b个batchb<=B_core假设L1上放的Batch是bL1L0上放的是bL0单次实际计算的Batch数是b那么b<=bL0<=bL1<=B_core而且核内计算和搬移时是可以切K的切K后进行[bM,kL0]@[kL0,bN]=[bM,bN]多个K可以在L0C上直接累加得到最终的[bM,bN]再取BlockTrace从L0C搬移输出到L2或GM
先基于我上面的提示,进一步完善第六章内容
----------------------------
补充几点:
1、当前文档有很多描述很不专业本机有一些昇腾NPU软硬件知识库可参考路径是 /storage/Users/currentUser/WorkBuddy/昇腾NPU/昇腾NPU知识库
2、数据可以直接从GM读取到L1(GM带宽)在L2是cache配置时会随路驻留在L2同样的数据下次AIC再需要用的时候如果L2 cache中有就可以命中并以L2的速率读取L0C可以直接写出到L2也可以直接写出到GM注意L2容量有限而且可能读写数据都会占用L2容量如果L2容量被占满了再从GM来读入或从L0C写出新数据时L2 cache的内容会发生替换L2腾空间有两个办法一是对于L2已有的L0C写出的数据要先写回GM(写GM带宽)才能腾出空间二是对之前从GM读入的在L2 cache的数据进行替换以腾出空间在L2容量足够的情况下一般只会从GM读一次数据块的重复读取会发生在从L2读取因此L1容量大小会直接影响重复读的数据量和性能
3、从GM读取数据时存在访存效率问题影响访存效率的主要有几个因素重要性依次递减一是参与核数GM带宽所有核共享并发读取才能尽量充分利用带宽至少要3/4的核并发才能达到90%以上的带宽利用率二是单核读取的数据量越大越能达到高带宽利用率三是单次搬移的数据块越大越能达到高带宽利用率四是ND2NZ指令的dValue要128Byte最好是256Byte或512Byte(例如在GM以ND排布的非转置左矩阵的K维度、非转置右矩阵的N维度上所搬移的数据量对应单次搬移的dValue)
4、BMM算子当前主要是MergeBatch、IterBatch、StreamK、ASW_Basic这几个软件实现分支
5、关于tiling和swizzle的描述可以参考当前算子结构体中的描述MatmulConfig参数说明L0C的大小影响M、N的切分
6、给定具体case要能给出最优软件实现方案并能评估端到端算子时延给定具体case并给定具体tiling和swizzle方案也要能评估端到端算子时延
另外单独补充说明下MergeBatch、IterBatch、StreamK、ASW_Basic这几个软件实现分支可参考ops-nn/matmul/batch_mat_mul_v3算子源码我要强调的是源码未必是最优的要以批判的眼光审视源码参考并优化方案
1、其中MergeBatch和IterBatch都是先按Batch分核核内计算时MergeBatch会进行[bM,K]@[K,bN]的计算,然后按[M,N]的Block取Trace会存在算力浪费不过一般访存Bound计算时延可以被掩盖浪费一点也没关系IterBatch在核内计算时就是逐个Batch的进行计算
2、StreamK是在B、M、N切分无法有效利用核数并行计算时通过切K达到多核有效计算提升核负载利用率的目的但存在核间的Reduce的额外开销
3、实践中大多数case会走ASW_Basic分支该分支不切K对于B、M、N都可以切
请参考我的补充说明重新审视并优化《BMM最优软件实现方案设计.md》
-------------------------
我想设计BMM算子在NPU(昇腾950PR)上的最优软件实现算子接口大致与batch_mat_mul_v3类似目标是任何shape、dtype的BMM case来了都能得到最优的软件实现方案所谓最优就是最终可以达成在该芯片上最短的端到端算子时延你先拿出个设计方案输出到本地要有理有据下面有一些tips供参考
tips1算子软件实现方案设计主要是结合芯片微架构特征和规格设计分块到各个AiC核上的搬移、计算的tiling和swizzle(所谓swizzle简单说就是分块执行的顺序以及哪个分块在哪个核上做)
tips2据我了解GM带宽1.6TB/s是读写共享L2的带宽5.2TB/s是读写各自独享Cube计算的输出是可以直接写到L2的所有最终输出都写到L2也算计算完成。
tips3关于核间切分的一些想法如下
核间切分
切B
读入
每个数据块都有对应的核且每个数据块只会被固定的1个核读取
每核独立读取各自的多个数据块,不会读取其他核的数据块
计算
每个最终结果数据块由每个核独立计算产生,不依赖其他核的结果
在单核内,该核的任意输入数据块可以产生该输入数据块能产生的全部输出数据块
写出
每个核只写出最终结果,没有中间结果写出
切M或N
读入
若是切M后左矩阵分块被分到不同核则存在同一右矩阵分块被不同核(重复)读取
若是切N后右矩阵分块被分到不同核则存在同一左矩阵分块被不同核(重复)读取
单核会读取多个数据块,单个数据块可能会被一个或多个核读取
计算
每个最终结果数据块由每个核独立计算产生,不依赖其他核的结果
在单核内,该核的某个输入数据块只可以产生该输入数据块能产生的部分输出数据块
写出
每个核只写出最终结果,没有中间结果写出
切K
读入
每个数据块只会被固定的1个核读取
每核独立读取各自的多个数据块,不会读取其他核的数据块
计算
每个最终结果数据块由多个核计算产生依赖多个核的结果且需要Reduce
在单核内,该核的任意输入数据块可以产生该输入数据块能产生的全部输出数据块的中间结果
写出
单核存在中间结果写出需要与其他核的中间结果一起做reduce才能产生最终输出数据分块