尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

CANN PTO-ISA 标量量化指令 SET_QUANT_SCALAR 完全指南:pre-quantization scale 的寄存器编码与 TPUSH 流水线实战

发布时间:2026/9/19 5:39:38

资讯中心
01
ARTICLE

CANN PTO-ISA 标量量化指令 SET_QUANT_SCALAR 完全指南:pre-quantization scale 的寄存器编码与 TPUSH 流水线实战

CANN PTO-ISA 标量量化指令 SET_QUANT_SCALAR 完全指南:pre-quantization scale 的寄存器编码与 TPUSH 流水线实战
CANN PTO-ISA 标量量化指令 SET_QUANT_SCALAR 完全指南pre-quantization scale 的寄存器编码与 TPUSH 流水线实战【免费下载链接】pto-isaParallel Tile Operation (PTO) is a virtual instruction set architecture designed by Ascend CANN, focusing on tile-level operations. This repository offers high-performance, cross-platform tile operations across Ascend platforms.项目地址: https://gitcode.com/cann/pto-isa导读本文聚焦 Ascend CANN Parallel Tile OperationPTO虚拟指令集中台手动指令SET_QUANT_SCALAR系统讲解它如何在 NPU 上为后续TPUSH指令设置标量预量化缩放因子pre-quantization scale以及该 FP32 标量如何编码进硬件量化配置寄存器含 8 位输出类型的符号位编码到第 46 位的细节。结合仓库中的 CPU 模拟实现、A5/A2A3 NPU 后端实现与tpushpop_fixpipe测试用例你将掌握SET_QUANT_SCALAR的 C intrinsic 调用方式、模板约束、跨平台实现差异以及它与TPUSH/TPOP组合完成矩阵乘 → 量化存储 → 反量化取回全链路量化的实战写法。指令概览标量预量化参数的入口指令定位在 PTO 指令体系中SET_QUANT_SCALAR属于手动 / 资源绑定类指令其作用是设置标量量化参数pre-quantization scale供后续TPUSH操作消费。与兄弟指令SET_QUANT_VECTOR从 Scaling 类型 Tile 的地址解析出量化参数并写入硬件 FPC 寄存器不同SET_QUANT_SCALAR直接接收一个 FP32 标量由硬件把它编码到量化配置寄存器中——这意味着它非常适合逐 Tile、逐调用动态指定缩放因子的场景而无需预先构造并维护一张 Scaling Tile。该指令在文档体系中的索引位置docs/isa/SET_QUANT_SCALAR_zh.md指令参考正文本文主体docs/PTOISA_zh.md指令族总览表中的条目说明docs/isa/README_zh.mdISA 文档索引中对标量/向量量化指令的一行式说明。与量化流水线的关联该指令本身不搬运数据它的价值体现在配置先行、消费在后的流水线关系上SET_QUANT_SCALAR必须在消费此配置的TPUSH指令之前调用。TPUSH负责将矩阵单元CubeAcc 区的计算结果按 Fixpipe 配置布局转换 量化模式推入 Fixpipe 流水线而TPUSH执行时读取的正是此前由SET_QUANT_SCALAR写入的量化配置。从 tpushpop_fixpipe 测试用例 可以看到标准的调用次序wait_flag(PIPE_M, PIPE_FIX, EVENT_ID0); // 等待矩阵乘完成、Fixpipe 就绪 SET_QUANT_SCALAROutT(2.0f); // ① 先写量化配置缩放因子 2.0 TPUSHMatPipe, AccTile, FixpipeConfig(pipe, accTile); // ② 再推入 Fixpipe set_flag(PIPE_FIX, PIPE_M, EVENT_ID1);测试中同时使用set_flag/wait_flag显式管理PIPE_M → PIPE_FIX的事件依赖保证SET_QUANT_SCALAR与TPUSH处于同一流水级且先后有序。C 内建接口与模板签名接口声明SET_QUANT_SCALAR的公开 C intrinsic 声明位于 include/pto/common/pto_instr.hpptemplate typename OutType, typename... WaitEvents PTO_INST RecordEvent SET_QUANT_SCALAR(float preQuantScalar, WaitEvents... events);要点拆解组成说明OutType模板参数量化输出类型决定符号位编码行为见下文位编码小节preQuantScalarFP32 标量即预量化缩放因子events...可变参数WaitEvents先调用detail::PtoWaitEvents(events...)建立依赖再执行指令主体返回值PTO_INST RecordEvent与 PTO 事件/流水线模型对接头文件路径公共包含头pto/pto-inst.hpp即 include/pto/pto-inst.hpp内部声明所在pto/common/pto_instr.hpp即 include/pto/common/pto_instr.hpp。也就是说Kernel 源码中只需#include pto/pto-inst.hpp即可使用该 intrinsic无需直接包含内部实现头文件。指令分派机制从声明看公共模板只做两件事先detail::PtoWaitEvents(events...)同步事件再把模板参数转发给平台相关的实现SET_QUANT_SCALAR_IMPLOutType(preQuantScalar)。真正落地到不同硬件的是_IMPL后缀的内部函数它们分别定义于include/pto/cpu/SetQuantScalar.hppCPU 模拟后端include/pto/npu/a5/SetQuantScalar.hppA5 NPUinclude/pto/npu/a2a3/SetQuantScalar.hppA2A3 NPU。这种公共模板声明 平台_IMPL特化的架构与 PTO 其他指令如TSTORE、TMOV、TINSERT保持一致同一份 Kernel 源码通过编译期宏选择即可跨平台运行。模板约束与使用前提官方文档 docs/isa/SET_QUANT_SCALAR_zh.md 明确列出以下约束OutType必须是受支持的量化输出类型如int8_t、uint8_t、int16_t、bfloat16_t、half。该类型应与TPUSH的 Fixpipe 配置、以及最终存储的 Global 侧OutT保持一致测试用例中OutT作为TPOP输出与SET_QUANT_SCALAROutT的模板参数同步出现。preQuantScalar是一个 FP32 标量用于指定预量化缩放因子语义上对应量化公式quantized round(value * scale)中的scale。调用次序必须在消费此配置的TPUSH指令之前调用且建议在PIPE_M → PIPE_FIX事件同步之后、TPUSH之前执行见前文测试代码。实现定义行为标量值编码到硬件寄存器的具体方式属于实现定义行为——本文下一节将基于仓库源码给出可验证的编码细节。此外从实现可以推断当OutType为 8 位类型sizeof(OutType) 1时符号位会被写入配置值的第 46 位该分支由std::is_same_vOutType, int8_t决定是否置 1详见下文符号位编码。从源码看寄存器编码FP32 位模式与第 46 位符号位SET_QUANT_SCALAR的实现定义行为并非黑盒——三个后端的_IMPL函数给出了完全一致的编码逻辑。A5 / A2A3 NPU 后端include/pto/npu/a5/SetQuantScalar.hpp 与 include/pto/npu/a2a3/SetQuantScalar.hpp 的实现逐字一致template typename OutType PTO_INTERNAL void SET_QUANT_SCALAR_IMPL(float preQuantScalar) { uint64_t quantConfig static_castuint64_t(*reinterpret_castint32_t*(preQuantScalar)); if constexpr (sizeof(OutType) 1) { constexpr bool sign (std::is_same_vOutType, int8_t) ? true : false; quantConfig (quantConfig ~(static_castuint64_t(1) 46)) | (static_castuint64_t(sign) 46); } set_quant_pre(quantConfig); }编码流程分三步位模式搬运将 FP32 标量按int32_t重新解释reinterpret_castint32_t*再零扩展为uint64_t。也就是说量化配置寄存器的高 32 位不是用零填充的普通 64 位整数转换而是完整保留了 FP32 的 IEEE-754 位模式符号位、指数、尾数随后统一交给底层硬件原语set_quant_pre(quantConfig)。8 位类型符号位编码仅当sizeof(OutType) 1即int8_t或uint8_t时进入分支。用sign (OutType 为 int8_t)得到符号标志然后通过先清位再写位的位运算把第 46 位写成该标志quantConfig ~(1ULL 46)清除第 46 位| (sign 46)按需置 1。这正对应文档所述对于 8 位输出类型符号位会自动编码到配置值的第 46 位。因此int8_t时第 46 位为 1、uint8_t时第 46 位为 0量化硬件据此区分有符号/无符号 8 位定点语义。写入硬件最终调用set_quant_pre(quantConfig)把配置送入硬件量化预置寄存器。CPU 模拟后端include/pto/cpu/SetQuantScalar.hpp 提供逐位一致的软件模拟差异只在写入目标它不再调用set_quant_pre而是把编码结果拷贝到 CPU 模拟的内存模型寄存器区uint64_t quantConfig static_castuint64_t(std::bit_castuint32_t(preQuantScalar)); // ... 相同的 sizeof(OutType) 1 分支 ... uint8_t* reg_base reinterpret_castuint8_t*(NPUMemoryModel::Instance().GetREGBase()); uint8_t* scalarReg reg_base QUANT_SCALAR_REG_OFFSET * sizeof(uint64_t); std::copy(quantSrc, quantSrc sizeof(quantConfig), scalarReg);QUANT_SCALAR_REG_OFFSET定义于 include/pto/common/cpu_stub.hpp值为0即量化标量寄存器位于寄存器基址GetREGBase()起的第 0 个uint64_t槽位与之配套的读取原语是GET_QUANT_SCALAR_IMPL()见 include/pto/cpu/GetQuantScalar.hpp从同一槽位把配置读回供 CPU 模拟验证。这意味着 CPU 后端与 NPU 后端共享同一份编码语义FP32 位模式 第 46 位符号位保证了 CPU 模拟结果与 NPU 实机行为的一致性——这也是该指令能被 tests/cpu/st 用例无硬件验证的直接原因。符号位编码的语义小结OutTypesizeof第 46 位含义int8_t11有符号 8 位定点uint8_t10无符号 8 位定点int16_t、bfloat16_t、half等1不修改保持 FP32 位模式原样最小可运行示例AICORE Kernel 中的调用写法以下示例直接取自 docs/isa/SET_QUANT_SCALAR_zh.md 的示例小节是官方给出的最小化用法可在 AICORE Kernel 内编译运行#include pto/pto-inst.hpp using namespace pto; template typename T AICORE void example_set_quant_scalar() { float preQuantScale 0.5f; SET_QUANT_SCALARint8_t(preQuantScale); }将preQuantScale设为 0.5f 表示先乘 0.5 再量化即 pre-quantization 缩放SET_QUANT_SCALARint8_t显式指定输出为int8_t因此编译器会在编译期展开sizeof(OutType) 1分支把第 46 位置 1若要使用无符号 8 位输出把模板参数改为SET_QUANT_SCALARuint8_t即可第 46 位保持 0。实战与 TPUSH/TPOP 组合的完整量化数据通路单个指令示例不足以体现它的价值。仓库中的 tpushpop_fixpipe 测试用例同一用例在 tests/npu/a5/src/st/testcase/tpushpop_fixpipe 与 tests/npu/a2a3/src/st/testcase/tpushpop_fixpipe 下均有对应版本展示了SET_QUANT_SCALAR在矩阵乘 → Fixpipe 量化推送 → 反量化取回完整数据通路中的真实位置。数据通路全景TLOAD(GlobalA/B) ──► TMATMUL(accTile) ──► SET_QUANT_SCALAROutT(scale) ──► TPUSH(accTile) │ TPOP(vecTile) ◄─── Fixpipe 量化/布局转换 ◄──┘矩阵乘TLOAD装载 Global 侧输入TMATMUL(accTile, aTile, bTile)在PIPE_M上完成矩阵乘结果进入 Acc 区 Tile配置量化在PIPE_M → PIPE_FIX事件同步之后调用SET_QUANT_SCALAROutT(2.0f)写入 2.0 的缩放配置该用例OutT为 8 位定点类型故同时写入符号位推送 FixpipeTPUSHMatPipe, AccTile, FixpipeConfig(pipe, accTile)按FixpipeParamsLayoutMode_t::NZ2ND, QuantMode_t::F322F16配置完成 NZ→ND 布局转换与 FP32→FP16 量化反量化取回TPOP从 Fixpipe 取回VecTile输出到 Global。测试用例的关键片段tpushpop_fixpipe_kernel.cppwait_flag(PIPE_FIX, PIPE_M, EVENT_ID1); TMATMUL(accTile, aTile, bTile); set_flag(PIPE_M, PIPE_MTE1, EVENT_ID1); set_flag(PIPE_M, PIPE_FIX, EVENT_ID0); wait_flag(PIPE_M, PIPE_FIX, EVENT_ID0); SET_QUANT_SCALAROutT(2.0f); TPUSHMatPipe, AccTile, FixpipeConfig(pipe, accTile);事件同步的正确姿势从上述用例可以看出SET_QUANT_SCALAR本身不参与显式事件同步它紧随wait_flag(PIPE_M, PIPE_FIX, EVENT_ID0)之后执行依赖关系由前后两条指令保证wait_flag(PIPE_M, PIPE_FIX, EVENT_ID0)确保矩阵乘PIPE_M已完成且 FixpipePIPE_FIX空闲此时写量化配置不会与TMATMUL竞争TPUSH在同一流水级消费配置二者之间无需额外 flag。这也印证了文档约束该指令必须在消费此配置的TPUSH指令之前调用的工程含义配置写入与消费之间由指令序和流水级天然保证开发者不应把SET_QUANT_SCALAR挪到TPUSH之后否则TPUSH读到的是旧配置或未定义值。与其他量化参数写入点的对比从源码检索可以发现set_quant_pre不仅在SET_QUANT_SCALAR_IMPL中被调用还出现在TStore、TMov、TInsert、TExtract等指令实现中如 include/pto/npu/a5/TStore.hpp、include/pto/npu/a5/TMov.hpp、include/pto/npu/a2a3/TExtract.hpp 等。可以推断这些指令的重载形式内部也会写预量化参数SET_QUANT_SCALAR是把显式设置量化配置从数据移动指令中解耦出来的独立入口——当你需要先配置、后推入即TPUSH场景时使用它而TSTORE/TMOV等指令带preQuantScalar参数的重载则是边搬运边量化的捷径。量化模式的配套选择TPUSH的模板配置决定了量化发生的方式。测试用例使用FixpipeParamsLayoutMode_t::NZ2ND, QuantMode_t::F322F16见 tpushpop_fixpipe_kernel.cpp即 FP32 累加结果量化为 FP16 并伴随 NZ→ND 布局转换。SET_QUANT_SCALAR提供的scale就是叠加在这条量化链路上的标量预缩放。实际工程中OutT、Fixpipe 的QuantMode_t与存储侧 Global 类型三者应保持语义一致如int8_t输出 8 位量化模式 int8_tGlobal 缓冲。汇编形态说明关于汇编形态docs/isa/SET_QUANT_SCALAR_zh.md 明确说明当前公开的汇编参考尚未为SET_QUANT_SCALAR定义稳定的 PTO-AS 写法。因此设置量化配置时请一律使用 C intrinsic 形式即本文介绍的SET_QUANT_SCALAROutType(scalar)不要依赖任何未公开的汇编助记符编写 Kernel这与兄弟指令SET_QUANT_VECTOR的现状一致——其文档docs/isa/SET_QUANT_VECTOR_zh.md同样声明尚未定义稳定的 PTO-AS 写法。从代码结构看CPU/NPU 后端以PTO_INTERNAL函数形式提供_IMPL属于编译器内联展开的实现细节不承诺稳定的汇编级接口这也是官方选择仅公开 C intrinsic的原因。与 SET_QUANT_VECTOR 的对比选型维度SET_QUANT_SCALARSET_QUANT_VECTOR输入FP32 标量preQuantScalarScaling 类型 TileFpTileData::Loc TileType::Scaling编码方式标量位模式写入量化配置寄存器含第 46 位符号位将 Scaling Tile 地址转换为量化参数地址格式写入硬件 FPC 寄存器适用场景单一缩放因子、逐调用动态指定、无需维护 Scaling Tile一组/逐元素缩放因子、需要 Tile 承载的向量化量化参数约束要点必须在消费的TPUSH之前调用必须在消费的TPUSH之前调用仅支持 Scaling 类型 Tile 输入参考实现include/pto/cpu/SetQuantScalar.hppinclude/pto/cpu/SetQuantVector.hpp选型建议若每个 Tile 使用同一个预量化缩放因子如 per-tensor scale优先SET_QUANT_SCALAR代码更简洁若需要 per-channel/per-block 的向量化缩放使用SET_QUANT_VECTOR并构造TileTileType::Scaling, ...输入。跨平台一致性验证该指令的跨平台正确性由两条证据链支撑实现一致性A5include/pto/npu/a5/SetQuantScalar.hpp、A2A3include/pto/npu/a2a3/SetQuantScalar.hpp与 CPU 模拟include/pto/cpu/SetQuantScalar.hpp三份_IMPL的编码逻辑完全一致FP32 位模式搬运 sizeof1时的第 46 位符号位仅写入目标不同硬件寄存器 vs. CPU 内存模型寄存器用例覆盖tpushpop_fixpipe测试用例在 tests/cpu/st/testcase/tpushpop_fixpipe/tpushpop_fixpipe_kernel.cpp、tests/npu/a5/src/st/testcase/tpushpop_fixpipe/tpushpop_fixpipe_kernel.cpp 与 tests/npu/a2a3/src/st/testcase/tpushpop_fixpipe/tpushpop_fixpipe_kernel.cpp 中同步维护同一份 Kernel 在 CPU 模拟与 NPU 实机上执行相同的SET_QUANT_SCALAR → TPUSH → TPOP通路。这也符合 PTO 的设计哲学开发者只需编写一次 Kernel通过编译目标切换即可在 CPU 模拟环境完成功能验证、在 NPU 上获得实机性能。使用注意事项与最佳实践综合文档约束与源码实现给出如下工程建议类型一致性SET_QUANT_SCALAROutT的OutT应与TPUSH的量化输出类型、以及后续TPOP/存储的 Global 类型保持同一语义避免符号位编码与实际定点格式错配。调用次序严格化始终在消费该配置的TPUSH之前调用若使用事件同步应在PIPE_M → PIPE_FIX依赖建立之后执行参见 tpushpop_fixpipe 用例。缩放因子语义preQuantScalar是 FP32 位模式原样进入寄存器的因此传入值应为标准 IEEE-754 单精度浮点如0.5f、2.0f不要传入未转换的整数否则位模式语义将不符合预期。8 位输出的符号语义当OutType为int8_t时第 46 位自动置 1、uint8_t时保持 0开发者无需也不应手动操作该位该行为由编译期if constexpr分支保证。汇编接口现状目前只使用 C intrinsic 形式勿依赖未稳定的 PTO-AS 助记符。验证途径功能正确性可先在 CPU 模拟后端验证NPUMemoryModel寄存器区的第 0 槽位可被 GET_QUANT_SCALAR 读回核对再迁移到 A5/A2A3 NPU 实机。参考资料指令参考docs/isa/SET_QUANT_SCALAR_zh.md正文docs/isa/SET_QUANT_SCALAR.md英文版指令族总览docs/PTOISA_zh.md、docs/isa/README_zh.md公共接口include/pto/common/pto_instr.hpp平台实现CPU include/pto/cpu/SetQuantScalar.hpp、A5 include/pto/npu/a5/SetQuantScalar.hpp、A2A3 include/pto/npu/a2a3/SetQuantScalar.hpp配套读回原语include/pto/cpu/GetQuantScalar.hpp测试用例tests/cpu/st/testcase/tpushpop_fixpipe/tpushpop_fixpipe_kernel.cpp、tests/npu/a5/src/st/testcase/tpushpop_fixpipe/tpushpop_fixpipe_kernel.cpp、tests/npu/a2a3/src/st/testcase/tpushpop_fixpipe/tpushpop_fixpipe_kernel.cpp兄弟指令docs/isa/SET_QUANT_VECTOR_zh.md【免费下载链接】pto-isaParallel Tile Operation (PTO) is a virtual instruction set architecture designed by Ascend CANN, focusing on tile-level operations. This repository offers high-performance, cross-platform tile operations across Ascend platforms.项目地址: https://gitcode.com/cann/pto-isa创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。