基于Ascend C的FlashAttention算子性能优化最佳实践

 LLM的Attention部分处理给计算系统带来巨大的计算和访存压力。业界先后出现FlashAttention、FlashAttention2等算法,通过计算等价和切分有效降低HBM数据访问量。 
昇腾异构计算架构CANN针对昇腾AI处理器的片上内存和缓存大小,以及数据搬运通路,基于Ascend C算子编程语言优化实现FlashAttention融合算子,充分利用片上缓存,提升Attention处理性能。根据实测,在一些典型场景中CANN的FlashAttention算子相比小算子取得了5倍以上的性能提升,开发者可直接调用相关算子API接口使能大模型极致性能优化。
本文针对FlashAttention反向融合算子的性能优化方案展开介绍,并通过优化实现了典型场景4倍左右的性能提升,希望对开发者优化此类基于Ascend C开发的融合算子带来启发。 

FlashAttention算法简介 

在主流大模型网络模型中,大量使用典型的Multi-Head Attention结构,带来了巨大的计算和内存开销。其运行过程中,矩阵乘和softmax结果存放在片上内存会带来巨大的内存消耗,访存性能严重下降,甚至会导致模型无法正常运行,同时网络中的矩阵和向量计算串行执行,也会导致硬件算力发挥受限。

斯坦福的Tri DAO提出了FlashAttention融合算子,其原理是对attention处理过程进行切分和计算等价,使得attention的多个步骤在一个算子中完成,并且通过多重循环、每次处理一小部分数据,以近似流式的方式访问片上内存,减少了片上内存访问的总数据量,并能够将计算和数据搬运更好的重叠隐藏。

 注意力的正向计算公式为:

为方便表达,以变量S和P表示计算公式: 

注意力的反向计算公式为: 

昇腾CANN基于Ascend C编程语言实现了FlashAttention正反向融合算子,其中反向算子计算流程可参考下图所示: 

本案例对FlashAttention反向算子进行了性能优化,主要涉及的优化手段包括tiling基本块大小调整,核间负载均衡,CV流水并行,MTE2流水优化以及FixPipe流水优化等,并在Atlas A2训练系列产品/Atlas 800I A2推理产品 验证平台下收益4倍左右的性能提升。下面以如下两个输入场景为例,介绍整个优化过程。

  • 第一个场景的输入维度信息为:B=1,N1=12,N2=12,S1=6144,S2=6144,D=128,并且为casual场景,casual场景即atten_mask的形状为下三角。
  • 第二个场景的输入维度信息为:B=24,N1=5,N2=5,S1=9216,S2=9216,D=64,不带atten_mask和drop_mask输入。

tiling基本块调整 

 根据以往优化的经验,循环间可能存在一些不必要的头开销,循环越多性能可能越差;满足UB最大空间限制的情况下,UB切分的基本块越大,循环越少,算子中通过InitBuffer接口分配UB buffer大小。

pipe->InitBuffer(ubBuffer, 120 * 1024);   
pipe->InitBuffer(tmpBuffer, 30 * 1024);   
pipe->InitBuffer(vecClc3, 8 * 1024);

 如上代码所示,InitBuffer接口的第二个参数表示buffer占用的大小,所有buffer大小的和即为占用的总空间。这里120 * 1024 + 30 * 1024 + 8 * 1024 = 158KB < UB Size,没有充分利用UB空间。
接下来试图通过调整tiling基本块进行性能优化,在满足UB空间大小够用的情况下,tiling基本块切分的越大越好。下图为优化前按照(64, 128)切分计算,总共需要循环计算32次:

考虑到UB空间没有用满,基本块调整到(128, 128),如下图优化后只需循环计算16次,切分后算子性能提升一倍:

 CV流水并行

 从流水图可以看到,可以看出两侧的流水都存在大段的空隙(图中绿色为vector部分流水,橙色为cube侧流水),CV之间流水很大程度上未并行,需要考虑CV流水优化。

 由于FAG算子中cube计算比vector计算快且存在依赖性,同时为了减少CV之间的通信次数,通过缓存机制实现让matmul提前计算多块,这里的缓存机制指的是将mm一次性计算多个基本块缓存到GM上。如下代码中,SetTail设置的SingleM和SingleN大小为BaseM,BaseN的倍数,即matmul一次发起多个基本块的计算,实现matmul结果的缓存,vector侧分多次取matmul的结果。

mm3.SetTail(s2CvExtend, -1, preS1Extend);   
mm3.SetTensorA(mulWorkSpaceGm[pingpongIdx * coreNum * cubeBaseMN + cBlockIdx * cubeBaseMN], true);  
mm3.SetTensorB(queryGm[mm2aTensorOffsetCv]);   
mm3.template IterateAll<false>(dkWorkSpaceGm[bTensorOffsetCv], true);

下图是实现mm1、mm2和mm3缓存的流水图,绿色的vector流水与橙色的cube流水均变得更密集,并行度提高,cv的间隔减小,提升了算子性能:  

基于缓存mm1/mm2/mm3的优化后,在本轮Vector等Cube流水的间隔,插入下一轮循环的Vector计算,这样使Vector流水与Cube流水之间的并行度更高,反映到流水图中为Vector计算更密集: 

相关优化点实现伪代码如下所示: 

 mm1计算;
dropout();
Sub();
dropout(); // 下一轮循环的Vector计算 
Sub();  // 下一轮循环的Vector计算 
mm2计算;
Softmax();
AttenMask();
...

 核间负载均衡

对于上述场景一,casual场景下可能存在核间分布不均匀的情况,如下图经过atten mask掩码后,红色部分是算子需要计算的部分,绿色无需计算;如果不按照基本块的个数来分核,按照第一根轴的大小8(行)来分核,假设平均分到9个核上,每个核做ceil(8 / 9) = 1行,则第一个核只需做1个基本块,但是第8个核需要做8个基本块的计算,出现严重的负载不均衡: 

因此需要考虑将红色块均匀分到多个核上计算,尽量实现每个核的计算量均匀,负载均衡。优化后,红色块总共36个基本块,均分到每个核上,每个核的计算量为4块,性能提升一倍。

 FixPipe流水优化

通过对场景一的Profilling数据进行分析可以看到,aic_fixpipe_ratio占比极高,占比高达81%,出现了很严重的bound: 

同时,CAModel工具打印发现存在很多异常的128B搬运,经过代码排查,发现workspace地址未512B对齐。代码实现中使用SetGlobalBuffer接口设置workspace的起始地址,如果起始地址不是按照512B对齐,搬运效率会很低,可以强制地址512B对齐来避免这个情况,下面代码中ADDR_ALIGN_SIZE即为512:

// init workspace address   
syncGlobal.SetGlobalBuffer((__gm__ int32_t*)workspace);   
uint64_t workspaceOffsets = SYNC_GLOBAL_WORKSPACE_SIZE;   
dqWorkSpaceGm.SetGlobalBuffer((__gm__ float*)workspace + workspaceOffsets / sizeof(T2));   
workspaceOffsets = (workspaceOffsets + qPostBlockTotal * sizeof(float) + ADDR_ALIGN_SIZE) / ADDR_ALIGN_SIZE * ADDR_ALIGN_SIZE;  dkWorkSpaceGm.SetGlobalBuffer((__gm__ float*)workspace + workspaceOffsets / sizeof(T2));   
workspaceOffsets = (workspaceOffsets + kvPostBlockTotal * sizeof(float) + ADDR_ALIGN_SIZE) / ADDR_ALIGN_SIZE * ADDR_ALIGN_SIZE;  dvWorkSpaceGm.SetGlobalBuffer((__gm__ float*)workspace + workspaceOffsets / sizeof(T2));   
workspaceOffsets = (workspaceOffsets + kvPostBlockTotal * sizeof(float) + ADDR_ALIGN_SIZE) / ADDR_ALIGN_SIZE * ADDR_ALIGN_SIZE;  
// matmul1 and matmul2 workspace size   
matmulWorkspaceSize = cubeBaseMN * sizeof(float);  
mm1WorkspaceGm.SetGlobalBuffer((__gm__ T2*)(workspace + workspaceOffsets + cBlockIdx * matmulWorkspaceSize));  mm2WorkspaceGm.SetGlobalBuffer((__gm__ T2*)(workspace + workspaceOffsets + coreNum * matmulWorkspaceSize + cBlockIdx * matmulWorkspaceSize));   // drop workspace offset   
workspaceOffsets = (workspaceOffsets + coreNum * cubeBaseMN * sizeof(float) * INPUT_NUMS + ADDR_ALIGN_SIZE) / ADDR_ALIGN_SIZE * ADDR_ALIGN_SIZE;   
dropWorkSpaceGm.SetGlobalBuffer((__gm__ T1*)workspace + workspaceOffsets / sizeof(T1));    
// mul workspace offset   
workspaceOffsets = (workspaceOffsets + coreNum * cubeBaseMN * sizeof(half) * 2 + ADDR_ALIGN_SIZE) / ADDR_ALIGN_SIZE * ADDR_ALIGN_SIZE;   
mulWorkSpaceGm.SetGlobalBuffer((__gm__ T1*)workspace + workspaceOffsets / sizeof(T1));

 修改代码,workspace地址经过512B对齐后,fixpipe时间减半:

 MTE2流水优化

 从场景二采集的profiling和打点图来看,mte2_ratio占比高,cube MTE2出现了明显bound,且部分MTE2搬运时间异常。

 

将输入数据排布格式从BSH更改为BNSD后,数据搬运连续,不需要跳地址读取数据,搬运效率提升一倍,部分异常搬运时长降低了一半。 

 优化方案性能收益

  • 调整tiling基本块:理论评估vector切块越大,计算和搬运循环次数越少,同时能够充分利用搬运带宽和vector算力。基本块大小从(64, 128)增大到(128, 128)后,性能提升一倍,实测与理论分析一致。
  • CV流水并行:CV流水掩盖的时间即为提升的性能,符合预期的收益。
  • 核间负载均衡:优化前负载最多的核的计算量减少的倍数,即为预期提升的性能;案例中优化前负载最多的核的计算量大小为8块,优化后为4块,实际性能提升一倍,符合预期的收益。
  • FixPipe优化:从Profiling数据看出FixPipe占比0.8,优化后占比0.55,实测算子性能提升45%,与理论分析一致。
  • MTE2优化:从Profiling数据看出MTE2占比0.52,优化后占比减少一半,实测算子性能提升30%,与理论分析一致。

 开发者在对基于Ascend C开发的融合算子进行性能优化时,可参考此案例中的优化思路。

更多学习资源 

 了解更多Ascend C算子性能优化手段和实践案例,请访问:昇腾Ascend C-入门课程-学习资源-算子文档-昇腾社区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/698244.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

xLua(一) 环境安装笔记

为了方便查阅记录一下xLua的安装地址及方法 1.登录地址下载: https://github.com/Tencent/xLua 2.解压文件 将文件中的这些内容拷贝到项目中的Asset文件夹中 注意 : 工程项目路径不得含有中文 3.将Tools复制到Asset同级目录下 4.导入后会发现有Bug,需要导入工程 5.还有另…

AI科普 | 什么是人工智能的本质?

我们将以科普的角度深入探讨AI的本质&#xff0c;揭示其内在的基本逻辑。 我希望能够为读者提供一个简单清晰的认识&#xff0c;所以我摒弃晦涩的专用名词&#xff0c;用大白话的方式让小白也能轻松看懂&#xff0c;让大家更加了解这位改变世界的“魔法师”。 通过这篇文章&a…

Fyndiq买家号下单:自养号测评如何打造本土物理环境系统?

Fyndiq 是一个瑞典电子商务平台&#xff0c;我们通过该平台为渴望讨价还价的购物者提供一系列产品。该公司为希望以可访问的方式提高销售额的所有类型的零售商提供销售渠道。Fyndiq几乎是瑞典家喻户晓的存在&#xff0c;是瑞典折扣促销平台。以销售质优价廉的商品吸引了大量忠实…

14年后 苹果终于推出iPad原生计算器应用

迄今为止&#xff0c;在WWDC 2024大会上&#xff0c;新增的计算器应用获得了最热烈的掌声。iOS 官方计算器应用程序终于要登陆大屏幕了。该功能利用额外的屏幕空间带来了公司无法在 iPhone 上实现的新功能。其中最大的亮点是新增了"数学笔记"功能。新增的功能可以帮你…

迈向『闭环』| PlanAgent:基于MLLM的自动驾驶闭环规划新SOTA!

中科院自动化所深度强化学习团队联合理想汽车等提出了一种新的基于多模态大语言模型MLLM的自动驾驶闭环规划框架—PlanAgent。该方法以场景的鸟瞰图和基于图的文本提示为输入&#xff0c;利用多模态大语言模型的多模态理解和常识推理能力&#xff0c;进行从场景理解到横向和纵向…

黑豹程序员 堆和栈

简单变量及作用域 main()   int x1; show ()   int x2 执行步骤&#xff1a; 第1步&#xff1a;main()函数是程序入口&#xff0c;JVM先执行&#xff0c;在栈内存中开辟一个空间&#xff0c;存放int类型变量x&#xff0c;同时附值1。 第2步&#xff1a;JVM执行show()函…

轻兔推荐 —— Snipaste

via&#xff1a;轻兔推荐 - https://app.lighttools.net/ 简介 Snipaste 是一个简单但强大的截图工具&#xff0c;支持Windows和Mac&#xff0c;允许用户快速截图并进行编辑&#xff0c;如添加标注、文字和马赛克。 - 它还具有贴图功能&#xff0c;可以将截图或剪贴板内容固定…

Flash Diffusion 加速文生图模型生成;Pixart-α加速测试

参考:https://github.com/gojasper/flash-diffusion https://huggingface.co/jasperai/flash-pixart 安装包注意: diffusers 这里是官方上面有更改,参考:https://github.com/gojasper/flash-diffusion/blob/main/requirements.txt pip install -r requirements.txt dif…

第18篇 Intel FPGA Monitor Program的使用<一>

Q&#xff1a;Intel FPGA Monitor Program开发工具可以支持Terasic的FPGA开发板使用吗&#xff1f; A&#xff1a;Intel FPGA Monitor Program 是Intel提供的适用于 ARM* Cortex*-A9 处理器和 Nios II 处理器的完整软件开发环境&#xff0c;它包括编译工具以及完整的调试功能&…

如何格式化U盘?4个正确方法,记得收藏好!

“我的u盘不知道是中病毒还是什么原因&#xff0c;现在没法使用了&#xff0c;我想将它进行格式化操作&#xff0c;想问问大家应该如何格式化u盘呢&#xff1f;请帮帮我&#xff01;” U盘作为我们日常生活中不可或缺的存储设备&#xff0c;常常用于传输和保存各种重要数据。然…

【深度学习】Loss为Nan的可能原因

文章目录 1. 问题情境2. 原因分析3. 导致Loss为Nan的其他可能原因 1. 问题情境 在某个网络架构下&#xff0c;我为某个数据项引入了一个损失函数。 这个数据项是nn.Embedding类型的&#xff0c;我加入的损失函数是对nn.Embedding空间做约束。 因为我在没加入优化loss前&#x…

34、matlab输入命令汇总

1、ans:最近计算的答案 代码示例1 12ans 3 代码示例2 Brand(7)B 列 1 至 60.7060 0.3171 0.1869 0.6797 0.5853 0.95930.0318 0.9502 0.4898 0.6551 0.2238 0.54720.2769 0.0344 0.4456 0.1626 0.7513 0.13860.0462 0.4387…

比亚迪员工待遇公开:70万员工都是靠真本事拿钱,这里没有大锅饭

比亚迪 近日&#xff0c;车企巨头比亚迪的内部信被曝光。 内部信内容是关于员工待遇的&#xff0c;信中反复强调&#xff1a;比亚迪始终坚持为每一位员工提供公平合理的工作环节和回报机制&#xff0c;鼓励员工工作中展现努力施展自己的才华和价值&#xff0c;来获得更为丰厚的…

AI写作工具:提升工作效率的五大利器

不知道大家有没有发现&#xff0c;随着人工智能技术的快速发展&#xff0c;AI工具正逐渐渗透到我们日常生活的各个方面&#xff0c;极大地提高了我们的工作和学习效率。无论是AI写作、AI绘画、AI思维导图&#xff0c;还是AI幻灯片制作&#xff0c;这些工具已成为我们不可或缺的…

使用 Scapy 库编写 TCP 窗口大小探测攻击脚本

一、介绍 1.1 概述 TCP窗口大小探测攻击是一种信息收集攻击&#xff0c;攻击者通过向目标服务器发送特制的TCP数据包&#xff0c;探测目标服务器的TCP接收窗口大小&#xff08;TCP Window Size&#xff09;。了解目标服务器的TCP接收窗口大小&#xff0c;可以帮助攻击者优化后…

70N10-HG010N10L 高压场效应MOS管TO-252封装 散热好 抗雪崩能力强

概述 FSMOSMOSFET基于惠海半导体的器件设计&#xff0c;可实现低功耗RDS&#xff08;ON&#xff09;、低栅极电荷、快速切换和优异的雪崩特性。低Vth系列是专门为具有低驱动电压的同步整流系统而优化的。 特征 RDS&#xff08;ON&#xff09;和FOM低 低开关损耗 卓越的可靠…

一颗万能的PD协议芯片,能芯Type-C PD协议芯片“ECP5705”, 它是如何实现PD直流风扇应用呢?

文章目录 文章目录 前言 一、PD风扇方案介绍 二、芯片介绍 三、PD风扇-供电方式 四、能芯科技 PD 协议芯片ECP5705-应用场景 总结 前言 随着USB Type-C接口的普及和PD取电芯片的出现&#xff0c;使得小型家电和电动工具可以通过统一的USB Type-C接口进行充电&#xff0c;极大地…

【MySQL】复合查询+表的内外连接

复合查询表的内外连接 1.基本查询回顾2.多表查询3.自连接4.子查询4.1单列子查询4.2多列子查询 5.在from子句中使用子查询6.合并查询7.表的内连和外连7.1内连接7.2外连接7.2.1左外连接 7.2.2右外连接 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1…

哪个牌子的充电宝好?有必要买充电宝吗?买充电宝认准这几个牌子

在现代快节奏的生活中&#xff0c;智能手机等电子设备已经成为我们日常生活中不可或缺的一部分。然而&#xff0c;电量不足的困扰时常困扰着我们&#xff0c;特别是在外出时。面对这种情况&#xff0c;共享充电宝成为了不少人的临时解决方案&#xff0c;但其高昂的租赁费用和使…

littlefs性能分析提升

littlefs性能分析 分析的目的很简单&#xff1a;希望支持掉电安全&#xff0c;或者说具有奔溃一致性特性的文件系统&#xff0c;他的读写速度能得到提升。如果了解了瓶颈所在&#xff0c;也可触类旁通。 本次分析&#xff0c;使用了大量的对比测试&#xff1a; littlefs读&a…