| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
engram修复aiv数小于rank数切换channel导致sq溢出 Co-authored-by: wuchenhao<wuchenhao6@huawei.com> # message auto-generated for no-merge-commit merge: !14556 merge master into master engram修复aiv数小于rank数切换channel导致sq溢出 Created-by: wuchenhao123 Commit-by: wuchenhao Merged-by: cann-robot Description: ## 描述 修复了在 aiv 核数小于卡数时,单个aiv切换channel时多个channel共享一个sq队列计数器导致溢出,新增数组分别记录 ## 关联的Issue https://gitcode.com/cann/ops-transformer/issues/6728 ## 测试 本地测试 ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [X] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: - [ ] ================================================================================ Code Review: PR #14556 修复切换channel导致sq溢出 ================================================================================ PR 链接 : https://gitcode.com/cann/ops-transformer/pull/14556 源分支 : wuchenhao123/ops-transformer_backward:master (82c55ed80) 目标分支 : cann/ops-transformer:master (5d7509970) 变更文件 : mc2/engram_fetch/op_kernel/arch35/engram_fetch_arch35.h (+22 / -20) 审查方式 : 基于 GitCode API 获取的完整 patch,结合本地同 SHA 提交 (82c55ed80) 读取全文件上下文,并核对了 engram_fetch_utils.h 中的常量与 GetCoreAssignment 实现。 审查日期 : 2026-10-26 ================================================================================ 一、变更概述 -------------------------------------------------------------------------------- 该 PR 修复 EngramFetchArch35 kernel 中跨 channel 切换时 SQ(Send Queue)在途 读计数丢失导致的 SQ 溢出问题: 1. 删除单一标量计数器 sqReadCount_ 及其"channel 切换即清零"的逻辑 (activeChannelHandle_ 成员一并删除)。 2. 新增 UB 缓冲区 rankReadCntBuf_,以 rankReadIdx 为索引维护 "每 (core, channel) 一个"的在途读计数,跨 channel 切换、跨 batch 持久保持, 仅在 mid-stream Drain 后清零。 3. PrepareRead 内的 ++sqReadCount_ 移除,计数增量改由唯一调用方 RemoteFetchRank 通过 rankReadCnt(rankReadIdx) 维护。 4. 将 GetBlockNum() 提升为成员 totalBlocks_,在 Init 中缓存一次, 替换 ScatterByRank / Process / FetchByRank 中的 4 处重复调用。 5. usedUb 预算中计入了新增的 rankReadCntBufSize。 二、根因确认(修复动机成立) -------------------------------------------------------------------------------- 旧代码 bug 场景(真实存在): - HCOMM_SQ_MAX_PENDING = 32767(engram_fetch_utils.h:45),为每 channel 硬件 SQ 的在途上限。 - 旧逻辑在 activeChannelHandle_ 变化时无条件执行 sqReadCount_ = 0, 但被切走的 channel 上仍有未 Drain 的在途读。 - 触发条件:totalBlocks_ < numRanks_(核数少于 rank 数),单核通过 ownerRank += totalBlocks_ 轮询 ≥2 个远端 rank(每 rank 独立 channel), 且 token 数超过一个 batch(indicesBatchSize_)或单 rank 在途读跨 batch 累积。 此时每次切换 channel / 进入下一 batch 都把计数清零,实际在途读数被低估, 累计 ≥ 32767 后硬件 SQ 溢出。 - 注:totalBlocks_ >= numRanks_ 时每远程核只绑一个 channel, 旧代码不会误清零,故旧 bug 仅存在于 tb < numRanks 且单核服务 ≥2 个 远端 rank 的配置。修复后两种模式均正确。 结论:这是一个真实的 bug,修复方向正确。 三、修复正确性核验(逐项通过) -------------------------------------------------------------------------------- 1. 索引边界安全性:PROVEN SAFE - tb >= numRanks:rankReadIdx 恒为 0,slots = 1。 - tb < numRanks:ownerRank = aivId_ + k*totalBlocks_,且 aivId_ < tb (GetBlockIdx 保证),故 ownerRank / totalBlocks_ = k。 k_max = floor((numRanks_-1-aivId_)/tb) <= ceil(numRanks_/tb) - 1 = rankReadCntSlots - 1,恒在界内,不会越界。 2. slot ↔ channel 一一对应:CORRECT - tb >= numRanks:GetCoreAssignment 对固定 aivId_ 结果确定, 每 remote 核只访问一个 channel(assignedRank/idxInRankGroup 不变), 单 slot 即该 channel 的计数。 - tb < numRanks:slot k 对应 channel(aivId_+k*tb, 0),各核负责的 rank 按 residue 划分、互不重叠,跨核无共享计数需求(计数器本就在各核私有 UB 中)。 3. 计数语义与旧代码一致(无切换场景): - needDrain 在下发前判断 (cnt + 1 >= 32767),即第 32767 个读触发 FlushPreparedReads + Drain 后清零,SQ 峰值恰好为上限,与旧逻辑等价。 - isLast(CQE 标记)读不清零、不 Drain,计数跨 batch 保留——这正是 修复点,使非活跃 channel 的在途读被持续追踪。 4. 计数迁移完整性:VERIFIED - PrepareRead 在新旧代码中均仅有 RemoteFetchRank 两个调用点, 无其它调用方依赖被删除的 sqReadCount_ 自增。 - hcomm_ 的读请求仅经 PrepareRead 下发,全部被计数覆盖。 5. 同步正确性:CORRECT - Init 中 Duplicate(PIPE_V) 后紧跟 SyncFunc<HardEvent::V_S> 再做标量 读写,方向正确;此后对该缓冲区只有标量访问(标量↔标量无需同步), 其它向量操作不触碰该 buffer,无 hazard。 6. UB 预算:UPDATED - rankReadCntBufSize 已计入 usedUb(engram_fetch_arch35.h:238), 缓冲区 ≤ Ceil(slots*4, 32)*32,slots 最大约 1024(tb=1 时),约 4KB, 开销可忽略。 7. totalBlocks_ 缓存:SAFE - GetBlockNum() 在 kernel 生命周期内不变,Init 缓存一次安全; 旧文件 4 处调用点全部替换,无残留(新文件仅剩 Init 中 1 处)。 8. Batch 完整性(未被破坏): - 每个 RemoteFetchRank 末尾 preparedReadCount_ > 0 即 BatchCommit, activeBatchHandle_ 不会跨 channel 复用(前提是 MakeBatchHandle 仅在 preparedReadCount_==0 时重绑,现有代码满足,属既有逻辑)。 四、发现的问题与建议 -------------------------------------------------------------------------------- 【信息】1. numRanks_ == 1 时缓冲区空转 位置:Init(engram_fetch_arch35.h:227-232) numRanks_==1 走 LocalFetchRange 路径,rankReadCntBuf_ 永不使用,但仍会 InitBuffer + Duplicate + 同步一次。开销极小(32B + 一条向量指令), 可不改;仅提示。 【信息】2. slots 计数略宽松(无影响) tb < numRanks 时 slots = ceil(numRanks_/tb),对不均匀尾部(如 numRanks=5, tb=4,core3 只用 slot 0)会多分配少量 slot。仅浪费几十字节, 无正确性影响,可不改。 五、总体结论 -------------------------------------------------------------------------------- 修复方案正确、完整: - 单一标量计数在 channel 切换时清零的缺陷被"每 (core, channel) 槽位计数" 取代,索引在两种核分配模式下均可证明不越界,slot 与 channel 一一对应。 - 计数迁移无遗漏调用点,UB 预算、同步、batch 复用约束均未被破坏。 - 未发现新引入的 bug 或行为回归。 ================================================================================ See merge request: cann/ops-transformer!14556 | 20 小时前 | |
engram算子性能优化 Co-authored-by: liuyibin<liuyibin5@huawei.com> # message auto-generated for no-merge-commit merge: !12642 merge sort into master engram算子性能优化 Created-by: liuyibin Commit-by: liuyibin Merged-by: cann-robot Description: ## 描述 engram算子性能优化 1.训练正向,先对输入的indices进行升序排列,优化后续h2d拷贝性能。 2.训练反向,unsort阶段scalar优化。 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。例如:关联Issue #000--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: See merge request: cann/ops-transformer!12642 | 1 个月前 | |
engram推理 减少sf热点判断 && 优化分核和buffer深度 Co-authored-by: wuchenhao<wuchenhao6@huawei.com> # message auto-generated for no-merge-commit merge: !12459 merge engram-fetch-wait-local-copy-rebase into master engram推理 减少sf热点判断 && 优化分核和buffer深度 Created-by: wuchenhao123 Commit-by: wuchenhao Merged-by: cann-robot Description: ## 描述 engram推理优化 1.优化核函数分核,提高n buffer深度 2.sf的热点判断改为模板参数 ## 关联的Issue https://gitcode.com/cann/ops-transformer/issues/5569 ## 测试 本地测试 ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [X] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: - [ ] 代码检视报告 项目名称:ops-transformer_backward PR !12459 (engram-fetch-wait-local-copy-rebase) 检视模块:engram_fetch 推理分核优化 + SF 模板化 + buffer 调优(7个文件) 检视人:Turing Team 检视日期:2026-09-21 PR 分支:engram-fetch-wait-local-copy-rebase,3 commits(047ae5a54 / 75e67d854 / ce88522db) 检视范围 mc2/engram_fetch/op_kernel/engram_fetch_utils.h Kernel/公共 cpp-secure.md, cpp-general.md mc2/engram_fetch/op_kernel/arch35/engram_fetch_arch35.h Kernel cpp-secure.md, ascendc-api.md mc2/engram_fetch/op_kernel/arch35/engram_fetch_wait_arch35.h Kernel cpp-secure.md mc2/engram_fetch/op_kernel/arch35/engram_fetch.cpp Kernel cpp-secure.md mc2/engram_fetch/op_kernel/engram_fetch_tiling_key.h Kernel - mc2/engram_fetch/op_host/op_tiling/arch35/engram_fetch_tiling.cpp Tiling cpp-secure.md, cpp-general.md mc2/common/torch_extension/elastic_buffer.py Host(Python) python-secure.md 检视概览 统计项 数值 发现问题总数 2 个确认 + 4 个存疑 严重级(CRITICAL) 0 个 中等级(MEDIUM) 1 个(问题2,极端形态) 轻微级(LOW) 1 个(问题1,极端形态) 核心结论:分核逻辑(GetCoreAssignment 重写)除零/越界/溢出推导全部闭合,fetch/wait 两侧通道覆盖配对正确;SF 模板化口径差在当前 host 成对派生合同下无风险。1 个 uint32 窄化防御缺口(极端形态不可达)+ 1 个模板口径差需按建议补防御;4 个存疑项供自主判断。 ================================================================================ 问题详情及修改建议 -------------------------------------------------------------------------------- 问题ID:ISSUE-001 | 严重级别:LOW(极端形态防御缺口)|检查项 MCR-02 假设检验过程 代码段:EngramFetchArch35::Init() 中 tileBytes_ 计算 假设:H0: 该代码段是安全的 证据序号 证据类型 规范ID 证据描述 分值增量 累计自信值 1 规范违反 2.1/2.2 int64 hiddenBytes_ 直接 static_cast<uint32_t> 窄化, +40% 40% >UINT32_MAX 回绕;Ceil(x,32)*32 在 x 接近 UINT32_MAX 时 uint32 乘法回绕 2 上下文防御缺失 2.1 tiling 侧仅校验 hiddenBytes <= INT64_MAX,无 UINT32_MAX 校验 +30% 70% 3 数据流追踪 2.1 hiddenBytes = hiddenDim * bytesPerElem,仅 INT64_MAX 约束 +25% 95% 结论:自信值 95% > 60%,推翻 H0。但触发需单行 hiddenBytes_ >= 4GB(现实 hidden 在 MB 量级,框架/显存不可能支撑),判定为极端形态防御缺口,LOW。 关联规范:cpp-secure.md 2.1 有符号整数运算不溢出 / 2.2 无符号整数运算不回绕;红线3 代码路径:mc2/engram_fetch/op_kernel/arch35/engram_fetch_arch35.h:174 问题类型:整型窄化回绕(极端形态) 问题代码: tileBytes_ = AscendC::Ceil(static_cast<uint32_t>(hiddenBytes_), UB_ALIGN) * UB_ALIGN; 影响:回绕到 0 时 relay 缓冲零容量、LocalCopySlice 每轮 thisLen=0 死循环; 回绕到小值时缓冲容量低估。正常业务形态不受影响。 修改建议 修改前(kernel 侧): tileBytes_ = AscendC::Ceil(static_cast<uint32_t>(hiddenBytes_), UB_ALIGN) * UB_ALIGN; 修改后(推荐在 tiling 侧补校验,engram_fetch_tiling.cpp 的 hiddenBytes 计算处): OP_TILING_CHECK(tilingData.hiddenBytes > static_cast<int64_t>(UINT32_MAX), OP_LOGE(nodeName, "hiddenBytes exceeds uint32 range: %ld", tilingData.hiddenBytes), return ge::GRAPH_FAILED); 修改说明:一行 tiling 校验早失败,覆盖回绕域;kernel 代码不动。与 MC2 专项检视 意见 MCR-02 一致。 -------------------------------------------------------------------------------- 问题ID:ISSUE-002 | 严重级别:MEDIUM(口径差疑点,当前合同下无风险)|检查项 MCR-03 假设检验过程 代码段:SetTilingKey() 的 hasSf 计算 + Process<HasSf> 模板选择 假设:H0: 模板选择与运行时状态一致 证据序号 证据类型 规范ID 证据描述 分值增量 累计自信值 1 规范违反 4.1 原运行时判断(numSfPacks>0 且双 GM 指针非空)被 tiling +40% 40% 描述符存在性近似替代,OPTIONAL 输入缺席形态依赖框架合同 2 上下文防御缺失 4.1 HAS_SF 模板下 kernel 不再保留 GM 指针判空兜底 +30% 70% 结论:自信值 70% > 60%,推翻 H0(形式上)。但证据有效性校验:host 侧 (elastic_buffer.py/C++)sf_table 与 fetched_sf 由同一 sf 对象成对派生,无 SF 时 传 1-D 空 tensor(torch.empty(0),非 nullptr),GetDimNum()==2 判别稳定; 唯一"2D且dim1>0但零数据"入口是 numTokens==0,kernel 早退。当前合同下不可达, 降级为 MEDIUM 存疑确认项。 关联规范:cpp-secure.md 4.1 外部输入合法性校验 代码路径:mc2/engram_fetch/op_host/op_tiling/arch35/engram_fetch_tiling.cpp:576-580 问题代码: bool hasSf = sfTableDesc != nullptr && sfTableShape != nullptr && fetchedSfDesc != nullptr && fetchedSfShape != nullptr && fetchedSfShape->GetStorageShape().GetDimNum() == DIM_TWO && fetchedSfShape->GetStorageShape().GetDim(1) > 0; 影响:若未来调用方破坏"成对同现同缺"合同(2D shape 但 GM 空),HAS_SF 模板下 GatherSf 解引用空 GM → 核 fault;NO_SF 模板下 fetchedSf 不被搬运。 修改建议 1. aclnn 包装层加成对性校验(elastic_buffer.cpp 的 EngramFetch/EngramFetchTrain): TORCH_CHECK(sfTable.sizes().size() == fetchedSf.sizes().size(), "sfTable and fetchedSf must be provided as a pair"); 2. 补三类形态端到端回归:有SF / 无SF(1-D空tensor) / 空shape 3. 回复 reviewer:当前 host 成对派生合同 + 1-D 空 tensor 判别,判定逻辑无需修改 ================================================================================ 存疑项(供自主判断) -------------------------------------------------------------------------------- 存疑-1 | fp8 无 SF 组合被禁用的兼容性 代码路径:mc2/common/torch_extension/elastic_buffer.py:799-809 问题代码: if sf is not None: ... storage dtype must be float8_e4m3fn/float8_e5m2 when sf is provided ... else: ... storage dtype must be bfloat16/float16/float32 when sf is not provided ... 描述:本次改动将 dtype 集合按有无 sf 分叉,语义上合理(SF 仅配 FP8 量化), 但为破坏性变更:存量调用方若使用 fp8 storage 不带 sf(kernel 本身支持纯字节 拷贝),升级后会被拦截。需业务确认是否存在该用法;若存在需放开 else 分支 包含 fp8 类型。 -------------------------------------------------------------------------------- 存疑-2 | fetch/wait blockDim 一致性是 drain 通道覆盖的隐含约束 代码路径:engram_fetch_arch35.h / engram_fetch_wait_arch35.h 的 GetCoreAssignment 调用 描述:fetch 侧用通道 [0, usedChannelPerRank),wait 侧 drain 同集合;两侧 usedChannelPerRank = (totalBlocks-1)/(numRanks-1) 依赖各自 GetBlockNum()。 当前两侧 tiling 均 SetBlockDim(GetCoreNumAiv()) → 一致成立。若未来任一侧 blockDim 调整导致不等 → wait 漏 drain 通道 → URMA 读永不完成 → drain 超时。 建议:在两侧 tiling 或文档中固化"fetch/wait blockDim 必须一致"的约束注释。 -------------------------------------------------------------------------------- 存疑-3 | GatherSf 的 UB->GM DataCopyPad 参数结构体(既有代码,非本PR引入) 代码路径:engram_fetch_arch35.h:487-488 问题代码: AscendC::DataCopyExtParams sfCopyOut{1U, sfBytes, 0U, 0U, 0U}; AscendC::DataCopyPad(sfDstGm, sfTmp, sfCopyOut); 描述:UB->GM 方向按 ascendc-api.md API-10 应使用 DataCopyParams(blockLen 字节), 同文件 LocalCopySlice(510行) 用 DataCopyParams{1, u16(thisLen), 0, 0}。GatherSf 用 DataCopyExtParams(5字段)传 UB->GM 方向。该代码为既有实现(非本PR引入), 编译可过说明重载存在,但与 API-10 推荐形态不一致,且与同文件正确用法不统一。 曾疑似与 SF 推理 drain 超时相关(已回退修复,原因待查)。建议查阅 ascendc-docs 确认 UB->GM 的 ExtParams 重载语义后统一写法。 -------------------------------------------------------------------------------- 存疑-4 | GetCoreAssignment 函数自身无 totalBlocks>=numRanks 前提守卫 代码路径:engram_fetch_utils.h:73-92 问题代码: uint32_t usedChannelPerRank = (totalBlocks - 1U) / (numRanks - 1U); 描述:当 totalBlocks < numRanks 时商为 0,后续 aivId / usedChannelPerRank 除零。 当前 3 个调用点(ScatterByRank/FetchByRank/wait Process)均有 totalBlocks >= numRanks_ 守卫,按 cpp-secure.md 2.3 Kernel 侧排除规则 (__aicore__ 函数参数由调用者保证)判 PASS。但函数语义新增了隐含前提 (旧实现任意输入安全),建议加 ascendc_assert(totalBlocks >= numRanks) 自文档化。 ================================================================================ 合规项确认 检查项 规范 结果 说明 除零保护 红线1 PASS GetCoreAssignment: numRanks<=1 早退 + 商>=1 推导; 调用点 totalBlocks>=numRanks 守卫 数组越界 红线2 PASS hcommHandle[assignedRank*CPR+idxInRank]: idxInRank<usedChannel<=CPR, assignedRank<numRanks 溢出/回绕 红线3 ISSUE-001(极端形态)+ 问题1 指针判空 红线4 PASS sfTableDesc/Shape/FetchedSfDesc/Shape 全判空 变量初始化 红线5 PASS tileBytes_{TILE_BYTES_INFER_MAX} 类内初始化 资源匹配 红线6 PASS AllocTensor/FreeTensor、MakeBatchHandle/Commit 配对 UB 容量预算 API-3 PASS usedUb 含 tileBytes*6;indicesBatch 按 21B/索引 预留 6 个 scatter 缓冲,数学自洽 uint16_t 截断 1.1 PASS mte3 blockLen u16(thisLen<=24KB)、u16(sfBytes<=2KB) 均 <65535 switch/LOG API 11.x PASS OP_LOGD %lu/%d 与实参类型匹配 TQueBind 深度 API-6 PASS RELAY_BUFFER_NUM_INFER=6 配对使用,144KB 预算安全 模板组合 - PASS 2 mode x 2 hasSf = 4 变体,tiling_key 声明/选择一致 fallback 分支配对 - PASS ScatterByRank/FetchByRank/wait fallback 的 ownerRank 步进与 rankOffsets 读写配对一致 报告生成时间:2026-09-21 报告状态:已完成检视;2 个问题 + 4 个存疑项待处理决策 See merge request: cann/ops-transformer!12459 | 1 个月前 | |
feat(engram): support full-vocab local inference Co-authored-by: henry_21st<qianlong3@huawei.com> # message auto-generated for no-merge-commit merge: !13996 merge pr13457-master-convergence into master feat(engram): support full-vocab local inference Created-by: henry_21st Commit-by: henry_21st Merged-by: cann-robot Description: ## 1. Backgroud(背景信息) EngramFetch 当前仅支持 Sliced 模式。假设用户的全局 vocab 为 1024 行,在 4P 标卡上运行时,每张卡只持有 256 行的 host 内存映射;均匀索引分布下约 75% 的请求需要访问远端 rank 的 host 映射,路径为本卡 PCIe、远端 host、远端 PCIe,再返回本卡。该路径延迟高、有效带宽低,并且在部分无卡间直连能力的标卡部署上不可用。 本方案针对“vocab 不适合常驻 device HBM,但完整 host vocab 可以被多个进程共享”的推理场景,增加 full-vocab local 模式:每个 rank 将同一份完整 host vocab 映射到本 rank 当前 NPU,fetch 只做本卡 gather,不再引入 Engram 层的跨卡通信。 ## 2. 方案设计 ### 2.1 对外接口 #### 2.1.1 Python API python buffer = ElasticBuffer( group=None, # full-vocab local inference *, num_cpu_bytes=0, # zero_copy=False 时可自动推导 with_grad=False, # group=None 必须为 False ) buffer.engram_write(storage, sf=None, *, zero_copy=False) result = buffer.engram_fetch(indices) fetched = result() group=None 是 local full-vocab 推理的唯一入口。多 rank 部署时,每个 rank 各自创建一个 ElasticBuffer(group=None);这些 Buffer 可以引用同一份 host mmap/SharedMemory,但设备侧注册、device pointer、生命周期和 fetch kernel 都属于各自 NPU。local 模式没有跨卡通信。 核心语义: | 参数/模式 | 语义 | | --- | --- | | group=None | full-vocab local 推理;固定 rank_size=1,不初始化 HCCL,不支持训练、MoE dispatch/combine 和 barrier()。 | | group 非 None | 保持现有 Sliced/training 语义;Sliced 推理仍按 rank 分片,需要跨卡通信。 | | zero_copy=False | 推理默认行为。engram_write 将 storage 拷贝到本 Buffer 内部 host pinned window;group=None 且未显式指定容量时,按 storage.nbytes() 向上 2MB 对齐。 | | zero_copy=True | 原地注册调用方 CPU storage。注册或映射失败直接报错,不隐式回退到拷贝模式。 | | with_grad=True | 训练模式;必须提供非空 pinned storage,等价直接映射,不接受 zero_copy=False。 | zero_copy 是 keyword-only 参数。推理侧的有效默认值为 False;训练侧的有效默认值为 True。两种模式的内存契约如下: | | zero_copy=False | zero_copy=True | | --- | --- | --- | | host 数据份数 | 每个 Buffer 一份内部 pinned window | 调用方一份;多个 rank 可共享同一物理页 | | engram_write 行为 | 一次拷贝 | 只注册,不拷贝 | | external storage 生命周期 | write 完成后可释放 | 必须保持地址和大小不变,直至所有 fetch 完成且 destroy() 成功 | | 就地更新 | 后续 fetch 不可见,需要重新 engram_write | 后续 fetch 可见;可见点由 stream 顺序和应用层同步决定 | | 换源张量 | 允许重新 write | 拒绝同 Buffer 内改变零拷贝模式和外部地址/大小 | | 注册失败 | 不涉及原地注册 | 硬报错,不回退 | 索引与输出契约: - indices 必须是 1D NPU int32 tensor,值为全局行号。 - 负数或越界索引是调用方错误,输出行为未定义;fetched 使用 at::empty 创建,不承诺 invalid 输出为 0。 - local 模式 num_entries_per_rank = storage.size(0);Sliced 模式每 rank 写入分片行数,全局条目数为 storage.size(0) * world_size。 - FP8 输出不反量化;fetched 与 storage dtype 一致,fetched_sf 与 sf_table dtype 一致。 See merge request: cann/ops-transformer!13996 | 7 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 20 小时前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 7 天前 |