| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
KvRmsNormRopeCache算子编码问题和文档整改 Co-authored-by: xulin<xulin91@huawei.com> Co-authored-by: Thaurissan<chenfangjia2@huawei.com> # message auto-generated for no-merge-commit merge: !8091 merge imprvKvRnrc into master KvRmsNormRopeCache算子编码问题和文档整改 Created-by: Thaurissan Commit-by: Thaurissan;xulin Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> 在编码质量检查和用例维护中,发现现有KvRmsNormRopeCache算子的kernel实现: 存在一些隐式场景约束,未在说明文档中加以公开说明,这将造成易用性问题。 存在残留的开发遗留脚手架,不利于可读性和开源质量。 部分通路存在显著的冗余变量和重复代码,不利于算子质量和可维护性。 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。例如:关联Issue #000--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> [#3493](https://gitcode.com/cann/ops-transformer/issues/3493) ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> 1. 更新README.md 2. 更新aclnnKvRmsNormRopeCache.md 3. 更新aclnnKvRmsNormRopeCacheV2.md ## 类型标签 <!-- [x] 表示选中 --> - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [x] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [x] ❓ 其他,请描述:编码问题整改 See merge request: cann/ops-transformer!8091 | 17 天前 | |
fix(KvRmsNormRopeCache): 修复 recompute 模板 dv 单块场景 Σx² 未计算 Co-authored-by: qianzehong<qianzehong@huawei.com> # message auto-generated for no-merge-commit merge: !8518 merge kv_bugfix into master fix(KvRmsNormRopeCache): 修复 recompute 模板 dv 单块场景 Σx² 未计算 Created-by: qianzehong Commit-by: qianzehong Merged-by: cann-robot Description: ## 描述 修复 KvRmsNormRopeCache regbase recompute 模板在 **dv 单块场景下 Σx² 完全未计算**的问题。 ### 问题 host tiling(kv_rms_norm_rope_cache_regbase_recompute_tiling.cpp:357)中: cpp int64_t basicBlockLoop = FindNearestPower2(ubFactorDvLoopCountCeil); 而 FindNearestPower2(value) 对 value <= 1 返回 0。因此当 dv <= ubFactor(dv 一个 UB 块即可载入,ubFactorDvLoopCountCeil == 1)时 basicBlockLoop == 0,kernel 侧 ReduceSumBasicComputeVF 的二分折叠循环一次都不进入,导致: 1. **Σx² 根本没有计算**:循环体内的 DataCopyPad / CastPowVF / ReduceSum / UpdateCache 全部未执行,cacheBuffer 从未被写入。 2. **totalSumLocal 未初始化**:它是默认构造的 LocalTensor<float>,GetPhyAddr() 返回 0。后续 CalculateVOutVF 等把它当 xSumPtr 读取,等于把 UB 0 地址的残留数据当作平方和。 UB 0 地址是合法地址,**不会崩溃,只会静默算错** —— 该行的 rmsnorm 缩放系数为脏数据。 Init() 中已有 if (basicBlockLoop == 0) { resultCacheID_ = 0; } 的特判,说明该分支被预期到,但计算路径未做处理。 ### 触发条件 recompute 模板在 full_load 模板 tiling 失败(ubFactor <= 0)时被选中。full_load 的 UB 分母(inUbSize / outUbSize / inCosSinUbSize)在 dk > dv 时几乎完全由 dk 主导,dv 仅贡献 rmsNormWspSize。因此 **dk 超大 + dv 小**时会落入 recompute,且 dv <= ubFactor: - bf16、非量化:取 dk=32768, dv=512 即命中 ubFactorDvLoopCountCeil == 1(已上板复现,见下)。 - dv == ubFactor 恰好整除(floor=1, tail=0, ceil=1)同样命中。 ### 修复 ReduceSumBasicComputeVF 增加 basicBlockLoop == 0 的单块归约分支:按 dv 的实际长度搬运一块、取平方、ReduceSum 后写入 cache[0]。 未复用主循环的原因:主循环主块的 DataCopyPad 搬运长度恒为 ubFactor(xDataCopyParams.blockLen = this->ubFactor * sizeof(T_KV)),单块场景下 floor(dv/ubFactor) == 0,会越界读 GM ubFactor - dv 个元素;同时 basicBlockIdx(0) == mainFoldCount(0) && ubFactorDvTail > 0 成立,尾块折叠分支会去搬 dv 之外的数据折叠进来。因此单开一条路径,而不是把 FindNearestPower2(1) 改成返回 1。 本 PR 为**纯新增 23 行**,basicBlockLoop > 0 的原有路径未改动任何一行。 ### 附带修复:910B geir example 的 index 未初始化(阻塞本 PR 流水线) 本 PR 的 910B 流水线失败与上述 recompute 改动无关(910B 走 DS 模板 tilingKey 3000,不实例化 arch35 的 tilingKey 20000),根因是 master 上既有的 example 数据构造缺陷,随本 PR 一并修复。 examples/test_geir_kv_rms_norm_rope_cache.cpp 的 GenOnesData 把字节数 data_len 当元素数 分配 int32_t 数组,再只写 size 个 int32(4 * size 字节),但 Tensor 按 data_len 字节 交给 GE。dtype 不宽于 4 字节时覆盖得住;index 是 DT_INT64、shape [181],需要 1448 字节而 只清零了前 724 字节,于是 index[0..89] 为 0,**index[90..180] 是未初始化堆内存**。 该用例 cache_mode=Norm、cache 的 seq 维为 1,合法 index 只有 0。kernel 侧 kv_rms_norm_rope_cache_b16_b1sd.h 只校验 offset >= 0,没有 offset < cacheLength 上界, 于是脏 index 为正数时 DataCopyPad 写到越界 gmOffset,触发 SMMU fault / aivec error; 为负数时被跳过,那 91 行 cache 不写入、静默算错。 因 GEInitialize() 已大量 malloc/free,该 5792 字节分配拿不到零页,故为**稳定失败而非偶发**; 两次 910B 上板日志(chipId 4 与 6)均为越界写,blockDim=37、fault kernel te_kvrmsnormropecache__kernel0,与 bns=181 的 DS 模板切分一致。 修复:按 data_len 字节分配并零初始化。**未启用 value 形参**(其自始未被使用,调用方传 2): 该用例 cache 的 seq 维为 1,填入 2 会使 index 恒越界。 建议后续单独加固 b16_b1sd.h 的 index 上界校验(改动产品代码、影响 910B 全场景,不在本 PR 范围)。 ## 关联的Issue #3691 ## 测试 **上板实测环境**:Ascend950(Ascend950PR_9589),CANN 9.1.0。以 bash build.sh --pkg --soc=ascend950 --ops=kv_rms_norm_rope_cache 构建自定义算子包并安装为 vendor,通过 TTK(python3 -m ttk kernel -b=release)执行。 **用例**:kv=[1,1,2,33280](dv=512, dk=32768)、gamma=[512]、cos/sin=[1,1,2,32768]、bf16、cache_mode=Norm、is_output_kv=true、epsilon=1e-5、固定 --seed 42。 该算子无内置 golden,故 dump 输入输出后用 numpy 按 c_kv = x / sqrt(mean(x^2) + eps) * gamma 独立校验第 4 个输出 c_kv(bf16 容差 rtol=atol=4e-3)。修复前/修复后两版包除本 PR 所改的那一个文件外完全相同(修复前那份已 cmp 确认与 upstream/master 逐字节一致)。 | | 修复前(master) | 修复后(本 PR) | |---|---|---| | c_kv[0, :4] | [316., 211., -184., 62.5] | [1.3828, 0.9219, -0.8047, 0.2734] | | numpy golden [0, :4] | [1.3858, 0.9232, -0.8066, 0.2734] | 同左 | | max_abs_diff | 314.62 | 0.0039 | | max_rel_diff | 229.36 | 0.0038 | | 不匹配元素 | **1024 / 1024** | **0 / 1024** | | 结论 | FAIL(全部输出为脏数据) | PASS | 修复前 c_kv 整体被放大约 228 倍,与「把 UB 0 地址的残留值当作 Σx² 代入 1/sqrt(Σx²/dv + eps)」的预期一致;修复后全部元素落在 bf16 精度标准内。 未做二级冒烟/算子泛化,本次仅覆盖触发该缺陷的单块路径;其余路径(basicBlockLoop > 0)代码逐字节未改动。 ## 文档更新 无。 ## 类型标签 <!-- [x] 表示选中 --> - [x] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: See merge request: cann/ops-transformer!8518 | 11 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 17 天前 | ||
| 11 天前 |