[AI][昇腾950] 量化 (Quantization) API 与注意事项
DaVinci 950 量化 (Quantization) API 与注意事项1. 量化在 950 中的两条路径路径 A: Cube 端量化 (FIXP 硬件管线) CUBE MMAD (S32/FP32 累加) → FIXP DEQ/REQ → OUT(GM) / L1 / UB 适用: 矩阵乘法后直接量化, 零额外计算开销 路径 B: Vector 端量化 (VEC Core 软件) VEC VALU 类型转换指令 → VREG → UB → GM 适用: 非 Cube 场景, 灵活但消耗 VALU 周期2. 路径 A: FIXP 量化 (CUBE 后处理)2.1 支持的量化操作FIXP 操作转换方向模式用途REQ8S32 → S8标量 向量INT8 量化推理REQ4S32 → S4标量 向量INT4 量化推理DEQF16S32 → FP16标量INT 累加→FP16 输出QS322BF16S32 → BF16标量 向量INT 累加→BF16 输出QF32_2_B8FP32 → S8/U8标量 向量FP32 训练→INT8 部署QF32_2_S4FP32 → S4标量 向量FP32→INT4 部署QF32_2_HiF8FP32 → HiF8标量 向量FP32→HiFloat8QF32_2_E4M3FP32 → FP8 E4M3标量 向量FP32→FP8 量化QF32_2_E5M2FP32 → FP8 E5M2标量 向量FP32→FP8 量化QF32_2_BF16FP32 → BF16标量 向量FP32→BF16 精度转换QF322F16FP32 → FP16标量 向量FP32→FP16 精度转换旁路模式 (不量化):FP32 bypass: FP32 → FP32 (直通)S32 bypass: S32 → S32 (直通)2.2 FIXP 量化参数缓冲缓冲大小用途Bias1024×4B 4KB偏置加法参数RELU-pre512×4B 2KBRELU 阈值/斜率Quantization-pre512×8B 4KB量化 scale/offset 参数2.3 FIXP 量化与 RELU 的串联CUBE MMAD → L0C (S32/FP32) │ ▼ FIXP-PRE: 1. BIAS 加法 (可选) 2. DEQ 量化 (scale×data offset) 3. RELU/Clip-RELU (可选, 在 FP32 域) │ ▼ MEM_RIF: 数据重排 │ ▼ MEM_WIF: NZ2ND (NC1HWC0 → NHWC) 量化类型转换 │ ▼ OUT → GM2.4 FIXP 量化并行度路径并行度 (elem/cycle)说明L0C→OUT (S32/F32 bypass)32不量化, 直通L0C→OUT (量化后 b8/b4)64量化后每 cycle 输出 64 元素L0C→L1 (S32/F32 bypass)64直通L0C→L1 (量化后)128量化后每 cycle 输出 128 元素L0C→UB (S32 bypass)32直通L0C→UB (FP32 dual source)64双源写入 UB0UB13. 路径 B: Vector Core 量化 (VALU 类型转换)3.1 API — FP32 → 低精度 (量化)API 函数目标类型舍入模式说明Cast(dst, src, CAST_RINT, count)FP16rintFP32→FP16, 就近舍入Cast(dst, src, CAST_ROUND, count)FP16roundFP32→FP16, 四舍五入Cast(dst, src, CAST_FLOOR, count)FP16floorFP32→FP16, 向下取整Cast(dst, src, CAST_CEIL, count)FP16ceilFP32→FP16, 向上取整Cast(dst, src, CAST_RINT, count)BF16rintFP32→BF16, 就近舍入Cast(dst, src, CAST_ROUND, count)BF16roundFP32→BF16, 四舍五入3.2 API — 低精度 → FP32 (反量化)API 函数源类型说明Cast(dst, src, CAST_NONE, count)FP16→FP32精确扩展, 无舍入Cast(dst, src, CAST_NONE, count)BF16→FP32扩展到 FP32CAST_NONE表示无舍入操作, 用于精度扩展场景。3.3 API — 完整类型转换覆盖C API 函数目标类型舍入模式适用架构Float2Half(dst, src, mask)FP16rn/rd/ru/rz/rna/ro全部Float2Bfloat16(dst, src, mask)BF16rn/rd/rna/ru/rz全部Float2Int32(dst, src, mask)S32rn/rd/ru/rz/rna全部Float2E4m3(dst, src, mask)FP8 E4M3rn3510 ONLYFloat2E5m2(dst, src, mask)FP8 E5M2rn3510 ONLYFloat2Hif8(dst, src, mask)HiF8rh/rna3510 ONLYHalf2Int8(dst, src, mask)S8rn/rd/ru/rz/rna全部Half2Int4x2(dst, src, mask)S4×2 packedrn/rd/ru/rz/rna3510 ONLYHalf2Hif8(dst, src, mask)HiF8rh/rna3510 ONLYBfloat162E2m1x2(dst, src, mask)FP4 E2M1×2rn/rd/rna/ru/rz3510 ONLYBfloat162E1m2x2(dst, src, mask)FP4 E1M2×2rn/rd/rna/ru/rz3510 ONLYHalf2Float(dst, src)FP32无全部E4m32Float(dst, src)FP32无3510 ONLYE5m22Float(dst, src)FP32无3510 ONLYHif82Float(dst, src)FP32无3510 ONLY3.4 通用舍入函数API 函数等价数学适用类型Ceil(dst, src, count)⌈x⌉FP16, BF16, FP32Floor(dst, src, count)⌊x⌋FP16, BF16, FP32Round(dst, src, count)四舍五入FP16, BF16, FP32Rint(dst, src, count)就近整数FP16, BF16, FP32Trunc(dst, src, count)截断FP16, BF16, FP323.5 舍入模式详解模式枚举/缩写数学含义典型用途Round to nearest evenrn/CAST_RINT四舍五入到最近偶数训练 (无偏)Round downrd/CAST_FLOOR向负无穷取整量化范围下界截断Round upru/CAST_CEIL向正无穷取整量化范围上界截断Round toward zerorz/ —向零取整推理量化Round to nearest awayrna/CAST_ROUND四舍五入 (远离零)部署量化Round to oddro四舍五入到奇数特殊场景Round hybridrh混合舍入 (HiF8专用)HiFloat8 量化4. 量化 API 对应关系总览┌──────────────────────────────────────────────────────────────────┐ │ 量化场景 API 选择 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 场景 1: Cube 矩阵乘后直接量化 │ │ MMAD(S32/F32) → FIXP DEQ/REQ → GM │ │ 配置: FixPipeParams / FIXP 指令参数 │ │ 量化参数: 从 L1 加载 Quantization-pre (4KB) │ │ │ │ 场景 2: 向量端 FP32→FP16 量化 │ │ Cast(dst, src, CAST_ROUND, count) │ │ │ │ 场景 3: 向量端 FP32→BF16 量化 │ │ 场景 4: 向量端 FP32→FP8 量化 (3510 ONLY) │ │ 场景 5: 向量端 FP32→HiF8 量化 (3510 ONLY) │ │ 场景 6: 向量端 FP16→INT8 量化 │ │ 场景 7: 向量端 FP16→INT4 量化 (3510 ONLY, packed) │ │ 场景 8: BF16→FP4 MX 量化 (3510 ONLY) │ │ 场景 9: FP8→FP32 反量化 (3510 ONLY) │ │ 场景 10: FP16→FP32 反量化 │ │ Basic C: Cast(dst, src, CAST_NONE, count) │ │ 场景 11: MX Matmul 量化 (3510 ONLY, CUBE端) │ │ Basic C: Matmul(l0c, l0a, l0b, mx_params) │ │ 输入: FP4 E2M1/E1M2 FP8 E8M0 scale │ │ 累加: FP32 → FIXP 可进一步量化输出 │ │ │ └──────────────────────────────────────────────────────────────────┘5. 量化注意事项5.1 FIXP 量化约束#约束原因违反后果1L0C 数据不能是 denormalFIXP 内部用 FP32 域处理量化结果错误2量化参数不能是 denormal/INF/NaN参数在硬件中直接使用量化结果错误3量化后数据写入 OUT:字节对齐OUT 接口特性数据错位4量化后数据写入 L1/UB:32B 对齐L1/UB 写对齐要求硬件异常5L0C 读对齐: FP32/S3264B, FP1632BL0C bank 粒度性能损失/数据错误6L1/UB/OUT不能同时写FIXP 资源互斥指令丢弃7Quantization post type 不支持硬件限制不可用8N 方向 dummy data不删除FIXP 只删 M 方向输出含垃圾数据9量化参数只从 L1 加载FIXP 硬件设计无法加载10参数源 32B 对齐, 目的 64B 对齐MEM_RIF 接口要求硬件异常5.2 Vector Core 量化约束#约束原因解决方案1DataCopy count 必须32B 对齐硬件搬运约束FP16≥16, FP32≥8, INT8≥32, 尾部 padding2FP8/FP4 类型只在3510可用2201 无这些类型#if (__NPU_ARCH__ 3510)条件编译3FP4 是packed ×2(8bit 存 2 个 FP4)紧凑存储格式一次转换得到 2 个值, 需拆包4FP8 E8M0 只用作MX scale无尾数, 只有指数仅配合 MX Matmul 使用5反量化 (→FP32)无舍入模式精度扩展无损失Cast(dst, src, CAST_NONE, count)6INT8 量化依赖mask 控制有效元素INT8 与 FP16 位宽不同构造对应宽度的 predicate mask7量化指令消耗VALU 周期走 VALU 流水线尽量用 FIXP 路径替代8舍入模式选择影响量化精度不同舍入偏差不同训练用 rn, 推理用 rz5.3 舍入模式选择指南┌──────────────────────────────────────────────────────────────┐ │ 舍入模式决策树 │ │ │ │ 是否是训练场景? │ │ ├── 是 → rn / CAST_RINT (round to nearest even, 无偏) │ │ └── 否 (推理/部署) │ │ ├── 是否要求无偏量化? │ │ │ ├── 是 → rn / CAST_RINT │ │ │ └── 否 → 性能优先? │ │ │ ├── 是 → rz (trunc, 最快) │ │ │ └── 否 → rna / CAST_ROUND (精度好) │ │ └── HiF8 场景 → rh (hybrid, HiF8专用) │ │ │ │ 特殊场景: │ │ 量化范围上界截断 → ru / CAST_CEIL │ │ 量化范围下界截断 → rd / CAST_FLOOR │ │ 混合精度累加 → ro (round to odd, 保持精度) │ └──────────────────────────────────────────────────────────────┘5.4 量化精度陷阱陷阱现象原因修复溢出截断INT8 量化后最大值全是 127scale 太小, FP32 值远超 127/scale调大 scale 或用 saturation全零输出量化后输出全为 0scale 太大, 所有值量化后 0.5 被截断调小 scale非对称量化偏移有符号量化不对称未正确处理 zero-point用 U8 offset 做对称化预处理BF16 精度低梯度更新不收敛BF16 只有 7-bit 尾数用 FP32 累加 最后一步转 BF16FP4 精度不足量化误差 50%FP4 E2M1 只有 1-bit 尾数配合 MX scale (E8M0) 分组补偿denormal 输入量化结果不可预测denormal 在 FP32 域处理异常输入数据先 flush-to-zero混合精度链串联量化精度衰减每次量化引入舍入误差减少量化次数, 合并为一步NZ2ND 尾部垃圾N 不对齐时输出含无效数据FIXP 不删 N 方向 dummyN 按 C0 向上对齐, 或用 NZ2DN