pyasc 量化算子开发指南:深入解析 asc.language.basic.set_deq_scale 接口

📅 发布时间:2026/9/19 12:52:32
pyasc 量化算子开发指南:深入解析 asc.language.basic.set_deq_scale 接口
pyasc 量化算子开发指南深入解析 asc.language.basic.set_deq_scale 接口【免费下载链接】pyasc本项目为Python用户提供算子编程接口支持在昇腾AI处理器上加速计算接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyascasc.language.basic.set_deq_scale是 CANN pyascPython 版 Ascend C 算子编程接口中用于设置DEQSCALE 寄存器、为反量化Dequantization计算提供 scale / offset / sign_mode 等量化参数的底层基础接口。本指南以其官方 API 文档为主体结合仓库内 Python 实现vec_vconv.py、types.py与单元测试test_common_api.py完整讲解三种重载形式的参数语义、与cast/cast_deq的配合方式、向量量化VecDeq的 16 组参数机制及源码级实现原理。读完本文你将能够在昇腾 AI 处理器的算子内核中正确配置 DEQSCALE 寄存器实现 int16/int32 输入的量化与精度转换。一、接口定位DEQSCALE 寄存器与量化流程在昇腾向量单元中从高精度数据类型如 int16、int32向低精度数据类型如 int8、uint8、half转换时通常需要先进行量化Quantization。量化参数 scale缩放因子、offset偏移、sign_mode符号模式需要写入向量单元的 DEQSCALE 寄存器供后续的 Cast / CastDeq 指令读取。set_deq_scale的职责正是设置 DEQSCALE 寄存器的值。它不是独立完成数值转换的算子而是与 cast_deq 等接口成对使用先调用set_deq_scale配置量化参数再调用cast/cast_deq执行量化与精度转换。从仓库的接口文档实现看其官方描述为设置DEQSCALE寄存器的值。对应的三个 Ascend C 函数原型见 utils.py 中的 docstring 定义为__aicore__ inline void SetDeqScale(half scale) __aicore__ inline void SetDeqScale(float scale, int16_t offset, bool signMode) template typename T __aicore__ inline void SetDeqScale(const LocalTensorT vdeq, const VdeqInfo vdeqInfo)pyasc 提供了与这三个 C 原型一一对应的 Python 重载统一通过asc.set_deq_scale(...)调用。二、三种重载形式与完整参数说明asc.language.basic.set_deq_scale共支持三种重载分别对应标量 scale、标量 scaleoffsetsign_mode、向量化 16 组量化参数三种使用场景。2.1 set_deq_scale(scale: float) → None对应 C 的SetDeqScale(half scale)仅设置一个 scale 量化参数。适用于 int32 → half 的量化路径此时计算公式为dst[i] src[i] * scale无需 offset 与符号模式。scalehalfscale 量化参数half 类型。在 pyasc 源码中该重载的 float 入参会被转换为 half 类型后再构建 IR 指令见 vec_vconv.pydispatcher.register(scaleRuntimeFloat) def _(scale: RuntimeFloat): builder.create_asc_SetDeqScaleOp(_mat(scale, KnownTypes.half).to_ir())2.2 set_deq_scale(scale: float, offset: int, sign_mode: bool) → None对应 C 的SetDeqScale(float scale, int16_t offset, bool signMode)一次性设置 scale、offset、sign_mode 三个参数。适用于 int16 → int8/uint8 的量化路径计算公式为dst[i] (src[i] * scale) offset。scalefloatscale 量化参数float 类型。offsetoffset 量化参数int16_t 类型只有前 9 位有效。sign_modebool 类型表示量化结果是否带符号。源码中的 IR 构建见 vec_vconv.py会将 Python 类型显式转换为昇腾 IR 所需的精度scale 转为 float32、offset 转为 int16、sign_mode 转为 bitdispatcher.register(scaleRuntimeFloat, offsetRuntimeInt, sign_modeRuntimeBool) def _(scale: RuntimeFloat, offset: RuntimeInt, sign_mode: RuntimeBool): builder.create_asc_SetDeqScaleOp( _mat(scale, KnownTypes.float32).to_ir(), _mat(offset, KnownTypes.int16).to_ir(), _mat(sign_mode, KnownTypes.bit).to_ir())2.3 set_deq_scale(vdeq: LocalTensor, vdeq_info: VdeqInfo) → None对应 C 模板版本SetDeqScale(const LocalTensorT vdeq, const VdeqInfo vdeqInfo)即向量量化VecDeq模式将 16 组量化参数以 128 字节张量的形式放到统一缓冲区UB中供cast_deq以循环方式逐组使用。vdeq输入量化 tensor大小为128Byte。类型为 LocalTensor支持的 TPosition 为VECIN / VECCALC / VECOUT。LocalTensor 的起始地址需要32 字节对齐。vdeq_info存储量化 tensor 信息的数据结构结构体内包含量化 tensor 中的16 组量化参数每组含 scale、offset、sign_mode。源码中的 IR 构建走独立指令SetDeqScaleL4Op见 vec_vconv.pydispatcher.register(vdeqLocalTensor, vdeq_infoVdeqInfo) def _(vdeq: LocalTensor, vdeq_info: VdeqInfo): builder.create_asc_SetDeqScaleL4Op(vdeq.to_ir(), vdeq_info.to_ir())2.4 VdeqInfo16 组量化参数的数据结构VdeqInfo是向量量化模式下的核心数据结构定义于 types.py。其构造签名如下VdeqInfo( scale: List[float], # 16 个 scale 值 offset: List[int], # 16 个 offset 值 sign_mode: List[bool], # 16 个符号模式 ) - None源码对长度有强校验三个字段必须恰好各含 16 个元素否则直接抛出ValueErrorVdeqInfo expects exactly 16 elements per field。内部实现将三个 Python 列表分别构建为 float32、int16、bit 类型的常量数组再通过create_asc_ConstructOp组装成VdeqInfo结构体scale_array array(KnownTypes.float32, scale) offset_array array(KnownTypes.int16, offset) sign_mode_array array(KnownTypes.bit, [1 if x else 0 for x in sign_mode]) self.handle builder.create_asc_ConstructOp( builder.get_asc_VdeqInfoType(), [scale_array.to_ir(), offset_array.to_ir(), sign_mode_array.to_ir()], builder.get_type_array_attr([...]), )参数速查表参数类型说明注意事项scalefloat重载 1 转 half重载 2 转 float32量化缩放因子重载 1 对应 Chalf原型offsetint内部转 int16量化偏移只有前 9 位有效sign_modebool内部转 bit量化结果是否带符号决定输出为有符号/无符号vdeqLocalTensor128Byte 量化 tensor起始地址需 32 字节对齐TPosition 仅限 VECIN/VECCALC/VECOUTvdeq_infoVdeqInfo16 组量化参数scale/offset/sign_mode 三列表各须恰好 16 个元素三、与 cast / cast_deq 的配合使用完整可运行示例set_deq_scale本身不产生数值运算必须配合cast或cast_deq使用。官方文档给出了三种典型调用组合同见 utils.py 的示例定义。3.1 Cast仅设置 scale# Cast scale 1.0 asc.set_deq_scale(scale) asc.cast(cast_dst_local, cast_dsrc_local, asc.RoundMode.CAST_NONE, src_size)该场景下 DEQSCALE 寄存器只配置 scale配合cast完成精度转换。3.2 CastDeq标量量化模式# CastDeq scale 1.0 offset 0 sign_mode True asc.set_deq_scale(scale, offset, sign_mode) asc.cast_deq(dst_local, src_local, countsrc_size, is_vec_deqFalse, half_blockFalse)这是 int16 → int8/uint8 的标量量化路径。cast_deq的is_vec_deqFalse表示不启用向量量化直接使用set_deq_scale设置的 scale、offset、sign_mode计算公式为dst[i] (src[i] * scale) offset3.3 CastDeq向量量化模式 / CastVdeq# CastVdeq vdeq_local asc.LocalTensor(dtypeasc.uint64, posasc.TPosition.VECIN, addr0, tile_size16) vdeq_scale [1.0] * 16 vdeq_offset [0] * 16 vdeq_sign_mode [False] * 16 vdeq_info asc.VdeqInfo(vdeq_scale, vdeq_offset, vdeq_sign_mode) asc.set_deq_scale(vdeq_local, vdeq_info) asc.cast_deq(dst_local, src_local, countsrc_size, is_vec_deqTrue, half_blockFalse)这是向量量化VecDeq路径set_deq_scale传入 LocalTensor 后cast_deq必须设置is_vec_deqTrue。此时 DEQSCALE 寄存器从 UB 上 128 字节的量化 tensor 中读取 16 组参数scale[0]-scale[15]、offset[0]-offset[15]、sign_mode[0]-sign_mode[15]以循环的方式逐元素参与量化计算公式为dst[i] (src[i] * scale[j]) offset[j], 0 j 15即第 i 个元素使用第i % 16组参数。3.4 cast_deq 中的量化规则与约束从 cast_deq 的官方 docstring 可以进一步确认set_deq_scale的量化语义输入 int16_t→ 输出 int8_t/uint8_t使用前必须调用set_deq_scale设置 scale、offset、sign_modehalf_block参数指示输出元素存放在上半还是下半 Block。输入 int32_t→ 输出 half使用前必须调用set_deq_scale设置 scale公式为dst[i] src[i] * scale。关键约束is_vec_deq控制是否选择向量量化模式当set_deq_scale传入 Tensor 时is_vec_deq必须为 true。四、源码级实现重载分发与 IR 构建链路4.1 基于 OverloadDispatcher 的重载分发set_deq_scale的实际实现位于 vec_vconv.py。它先声明三个overload签名再通过OverloadDispatcher按参数类型自动路由到对应的 IR 构建逻辑require_jit set_common_docstring(api_nameset_deq_scale) def set_deq_scale(*args, **kwargs) - None: builder global_builder.get_ir_builder() dispatcher OverloadDispatcher(set_deq_scale) # 三个 register 分别对应三种重载 dispatcher(*args, **kwargs)从源码结构可以推断pyasc 将 Python 侧的调用统一收集为 ascAscend IR指令交由后端编译为昇腾算子二进制。require_jit装饰器表明该接口只能在 JIT 编译的内核上下文中调用。4.2 三种重载对应的底层指令Python 重载底层 IR 指令类型转换set_deq_scale(scale)create_asc_SetDeqScaleOpfloat → halfset_deq_scale(scale, offset, sign_mode)create_asc_SetDeqScaleOpfloat → float32int → int16bool → bitset_deq_scale(vdeq, vdeq_info)create_asc_SetDeqScaleL4Op直接使用 LocalTensor 与 VdeqInfo前两种重载最终写入同一指令SetDeqScaleOp区别仅在参数精度第三种独立为SetDeqScaleL4Op体现向量量化模式下 128 字节 tensor 读取的特殊硬件通路。4.3 单元测试验证仓库的单元测试 test_common_api.py 覆盖了全部三种重载的调用路径def test_set_deq_scale(mock_launcher_run): def kernel_set_deq_scale() - None: asc.set_deq_scale(1.0) asc.set_deq_scale(1.0, 5, False) vdeq_scale [1.0] * 16 vdeq_offset [0] * 16 vdeq_sign_mode [False] * 16 vdeq_local asc.LocalTensor(dtypeasc.uint64, posasc.TPosition.VECIN, addr0, tile_size16) vdeq_info asc.VdeqInfo(vdeq_scale, vdeq_offset, vdeq_sign_mode) asc.set_deq_scale(vdeq_local, vdeq_info) kernel_set_deq_scale[1]()该测试在mock_launcher_run环境下以 JIT 内核方式执行验证了标量双参、标量三参、向量化三种调用均可正常编译通过可作为开发者编写自定义算子的参考范式。五、使用建议与注意事项成对使用set_deq_scale必须与cast/cast_deq配合单独调用无法完成量化转换cast_deq使用前必须先调用set_deq_scale完成 DEQSCALE 寄存器配置。两种量化模式的选择数据通道中存在规律变化的量化参数如逐 16 元素循环时选用向量量化模式传入 LocalTensor VdeqInfo否则使用标量模式传入 scale 或 scaleoffsetsign_mode避免不必要的 UB 开销。向量量化约束vdeq张量大小为 128Byte、起始地址需 32 字节对齐、TPosition 仅限 VECIN/VECCALC/VECOUTVdeqInfo三个列表必须恰好各 16 个元素否则运行时报ValueError。offset 精度offset 为 int16_t 类型但只有前 9 位有效设置超出范围的偏移值会被硬件截断请按实际量化位宽规划。数据类型匹配int16 输入走(src * scale) offset公式int32 输入走src * scale公式且 int32 场景只需设置 scale请根据输入类型选择正确的重载形式。六、延伸阅读配套转换接口cast_deq 接口文档、cast 接口文档Python 侧实现vec_vconv.pyset_deq_scale 分发逻辑、types.pyVdeqInfo 结构体定义docstring 定义utils.pyset_deq_scale 与 cast_deq 的官方说明单元测试test_common_api.py相关量化算子示例cast_deq 文档 与 cast 文档 中的调用组合【免费下载链接】pyasc本项目为Python用户提供算子编程接口支持在昇腾AI处理器上加速计算接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考