Closed
flash_attn DN不合轴模板 s2BaseSize 切换为 256 #7137
jiang-liruiAdd on 8 days agoClosed at 8 days ago
8 days ago Modify description of issue
jiang-lirui
8 days ago Comments:
8 days ago Comments:
/assign @jiang-lirui


8 days ago Assign jiang-lirui as responsible person
周云飞
8 days ago Comments:
8 days ago Comments:
问题说明
统一 S2=256 属于性能取舍,现有数据支持整体收益,但不能说明所有场景都更快。按报告,Ascend950PR 上 223 条语料平均加速比为 1.0700;mask=3、KV 长度约 256 的单块场景总耗时加速比为 0.957。因此,不设 maxSeqlenKv 门控意味着接受这部分回退。单块缺少跨块重叠的解释仍需结合流水实现验证。
处理建议
可以考虑以 template 2 专用 config 10–13 承载该策略,保持 host、AICPU 和 kernel 的 S2、槽数及同步编号一致,并保留 D=72 的真实 originalDV,避免影响输出拷贝。是否全档切换,建议结合单块回退的可接受程度决定;单块拆分可作为独立优化评估,同时关注尾块精度和 UB 容量约束。


8 days ago Close issue
8 days ago Added label: resolved
flash_attn DN不合轴模板 s2BaseSize 切换为 256
flash_attn_s2base256(mastere5969b59d+ 单提交2d2de8ca5,7 文件 +182/−67)223 条语料平均加速 1.0700、总耗时 1.1131,D=64 最高 1.1298;唯一回归桶是
「mask=3 且 S2≈256」的单块场景(21 条,总耗时 0.957)。
1. 为什么要从 128 切到 256
template 2 的路由是
vHeadDim<=128 && maskMode∈{0,3} && maxSeqlenQ>=256,也就是 Q 至少 256 行。此时 KV 方向若仍按 128 切块:
放大到 256 后,S2 迭代数减半、分数槽按 2 个配置、D=64 还能额外开 bmm2 独立槽,流水重叠明显变好。
2. 方案总览
CalcFaKernelConfigArch35::CalcBaseSize:FA_Template_DN_Unmerged→sInner=256;UpdateTilingKeyConfig按真实 D 映射 10–13*_dn_unmerged的 cube/vec block 用ConfigValue的 count 常量推导 UB 槽数与同步 id(不再用dBaseSize>128?2:4之类的硬编码),并支持 MM2 独立槽s2BaseSize直接取CalcConfig的sInner,删除原来的二次覆盖Route_Q256_*_DnUnmerged两条期望 tilingKey 同步到 config 11(D=128 档)3. 档位表(config 10–13)
ConfigParams字段:s1 / s2 / d / dv / originalDV / ubMm1ResBufcnt / ubMm2ResBufcnt / ubVec1ResBufcnt / ubMaskBufcnt / l1PBufcnt / l1QBufcnt / l1KvBufcnt。要点:
originalDV保留真实 V 宽度(D=72 为 72),供输出拷贝选 ROW_PAD;D=72 不再复用 D=128 的 originalDV;ubMask=0:不合轴 DN 用解析式 mask,不拷 mask 表;ubMm2=1只在 D=64 开(2 个分数槽 + 1 个 bmm2 槽装得下),其余档 bmm2 复用分数槽;ConfigValueArch92同步补 10–13 占位(arch92 不下发,仅为共享 SEL 实例化)。4. 各层实现
4.1 host 与 AICPU
// arch35/flash_attn_kernel_config_arch35.h } else if (config.templateId == FA_Template_DN_Unmerged) { config.sOuter = 64; config.sInner = 256; // 全档统一 }// arch35/flash_attn_tiling.cpp: UpdateTilingKeyConfig if (kernelConfig_.templateId == FA_Template_DN_Unmerged) { if (qkHeadDim == 64) config = 10; else if (qkHeadDim == 72) config = 13; // originalDV=72 else if (qkHeadDim == 128) config = 11; else if (qkHeadDim == 192 && vHeadDim==128) config = 12; return; }AICPU 侧不需要特判:
mBaseSize_/s2BaseSize_来自CalcConfig,template 2 自然拿到sInner=256。4.2 kernel(cube/vec block)
flash_attn_block_cube_dn_unmerged.h:UB_MM1_RES_BUFCNT = FA_T::UB_MM1_RES_BUFCNT、UB_MM2_RES_BUFCNT = FA_T::UB_MM2_RES_BUFCNT、MM_RES_SEPARATE_BMM2 = (UB_MM2 != 0);CROSSCORE_L1P_0 = CROSSCORE_MM_0 + UB_MM_RES_FLAGCNT(同类 buffer 的 id 连续),InitBuffers 的 UB 大小按 count 累加;跨核 wait/set 按
UB_MM_RES_FLAGCNT > 2/3分级。flash_attn_block_vec_dn_unmerged.h:CC_L1P_0 = CC_MM_0 + UB_MM_RES_FLAGCNT;UB_VEC1_RES_BUFCNT = FA_T::UB_VEC1_RES_BUFCNT(MTE3(P→L1) 暂存桶深度,S2=256 时为 2);vec2 / vec1Res / LSE 的核内同步 id 按"同类连续"推导。
ConfigValue的 count 表达,block 代码不再出现档位特判。4.3 tiling key
flash_attn_template_tiling_key.h中 template 2 的ConfigSEL 由0..9改为10, 11, 12, 13;template 0/1 仍用 0..9(8/9 为 D=72 档)。因此 template 2 的 kernel 实例数由 10 档降为 4 档
(× 4 layout × 2 mask = 32 个 key)。
5. 收益(223 条语料,S2=256 vs S2=128 基线)
口径:同一台 Ascend950PR,hot、5 次取 min;
perf/analysis/speedup_T1_s256_vs_T0_s128.csv。6. 已知回归与风险
原因:整个 KV 恰好是一个 256 块,S2 放大后没有第二个块与之重叠,反而损失了原来
"128 块 × 2" 的跨块流水。可选补救:单块时把 s2 循环拆成两段(未做)。
10_mfu_report.md)显示D=72 组 MFU 中位 47%、最高 56%,提升空间在窄模板而非 S2 策略。
DN_MASK_*一类的 S2 微调策略在参考分支
perf/dn-plus-noncoaxis里出现过(causal 用 208/224),本分支未启用。(本分支已修 2 条 UT)。
7. 验证清单(本分支实测)
_vf_p_layout30/32、_vf_tail_edge20/21、_s224_prec10/10、functional 5/5(与重构前 s2 分支逐条一致;2 条 bf16 为既有长尾)run_T2_split_refactor:平均 0.9988(即重编号/重构未改变行为)transformer_op_host_ut374/374 通过(含 Route_Q256 两条)复现:
perf/README.md的run_perf_raw.py+perf/analysis/ab_min.py;UT 用bash build.sh -u --ophost_test --noexec --ops=flash_attn -j16 --soc=ascend950后运行build/tests/ut/framework_normal/op_host/transformer_op_host_ut(需BUILD_PATH=<build 目录>)。8. 后续可选项
perf/dn-plus-noncoaxis,见09_vec2_dn_feasibility.md;修订记录
223 条收益数据(1.0700/1.1131)、回归桶与风险、验证清单及后续可选项;历史推导引用 02/06 号文档。