昇腾社区首页
EN
注册

矩阵乘输出的量化/反量化

功能介绍

对于特定输入输出数据类型,Matmul支持将计算结果从CO1搬出到Global Memory时,对输出C矩阵元素执行数据量化或反量化操作。

  • Matmul量化场景:Matmul计算时左矩阵A、右矩阵B为half或bfloat16_t数据类型,输出C矩阵为int8_t数据类型。该场景下,C矩阵的数据从CO1搬出到Global Memory时,会执行量化操作,将最终结果量化为int8_t类型,如下图所示。
    图1 Matmul量化场景示意图
  • Matmul反量化场景:Matmul计算时左矩阵A、右矩阵B为int8_t或int4b_t数据类型,输出C矩阵为half数据类型,或者左矩阵A、右矩阵B为int8_t数据类型,输出C矩阵为int8_t数据类型。该场景下,C矩阵的数据从CO1搬出到Global Memory时,会执行反量化操作,将最终结果反量化为对应的half类型或int8_t类型,如下图所示。
    图2 Matmul反量化场景示意图
Matmul量化/反量化包含两种模式:同一系数的量化/反量化模式、向量的量化/反量化模式,开发者在算子Tiling侧调用SetDequantType接口设置量化或反量化模式,这两种模式的具体区别为:
  • 同一系数的量化/反量化模式(PER_TENSOR模式):整个C矩阵对应一个量化参数,量化参数的shape为[1]。开发者在算子Kernel侧调用接口SetQuantScalar设置量化参数。
  • 向量的量化/反量化模式(PER_CHANNEL模式):C矩阵的shape为[m, n],每个channel维度即C矩阵的每一列,对应一个量化参数,量化参数的shape为[n]。开发者在算子Kernel侧调用接口SetQuantVector设置量化参数。
表1 量化/反量化模式对应的接口配置

模式

Tiling侧接口

Kernel侧接口

同一系数的量化/反量化

SetDequantType(DequantType::SCALAR)

SetQuantScalar(gmScalar)

向量的量化/反量化

SetDequantType(DequantType::TENSOR)

SetQuantVector(gmTensor)

使用场景

需要对矩阵计算结果进行量化/反量化操作的场景,当前该场景下,Matmul输入输出矩阵支持的数据类型如下表所示。

表2 Matmul量化/反量化支持的数据类型

A矩阵

B矩阵

C矩阵

支持平台

half

half

int8_t

  • Atlas A3 训练系列产品/Atlas A3 推理系列产品
  • Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件

bfloat16_t

bfloat16_t

int8_t

  • Atlas A3 训练系列产品/Atlas A3 推理系列产品
  • Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件

int8_t

int8_t

half

  • Atlas A3 训练系列产品/Atlas A3 推理系列产品
  • Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件

int4b_t

int4b_t

half

  • Atlas A3 训练系列产品/Atlas A3 推理系列产品
  • Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件

int8_t

int8_t

int8_t

  • Atlas A3 训练系列产品/Atlas A3 推理系列产品
  • Atlas A2 训练系列产品/Atlas 800I A2 推理产品/A200I A2 Box 异构组件

约束说明

  • 在Kernel侧与Tiling侧设置的量化/反量化模式需要保持一致:
    • Kernel侧调用SetQuantScalar接口设置同一系数的量化/反量化模式,对应Tiling侧调用SetDequantType接口配置模式为DequantType::SCALAR。
    • Kernel侧调用SetQuantVector接口设置向量的量化/反量化模式,对应Tiling侧调用SetDequantType接口配置模式为DequantType::TENSOR。

调用示例

  • Tiling实现
    调用SetDequantType接口设置量化或反量化模式,其他实现内容与基础场景相同。
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo());
    matmul_tiling::MatmulApiTiling tiling(ascendcPlatform); 
    tiling.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_INT8);
    tiling.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_INT8);   
    tiling.SetCType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_INT32);   
    tiling.SetBiasType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_INT32);   
    tiling.SetShape(M, N, K);   
    tiling.SetOrgShape(M, N, K);  
    tiling.EnableBias(true);
    tiling.SetDequantType(DequantType::SCALAR);  // 设置同一系数的量化/反量化模式
    // tiling.SetDequantType(DequantType::TENSOR);  // 设置向量的量化/反量化模式
    ... // 执行其他配置
    
  • Kernel实现
    根据具体量化模式场景,调用SetQuantScalarSetQuantVector接口设置量化参数。其他实现内容与基础场景相同。
    • 同一系数的量化/反量化模式
      1
      2
      3
      4
      5
      6
      7
      8
      REGIST_MATMUL_OBJ(&pipe, GetSysWorkSpacePtr(), mm, &tiling);
      float tmp = 0.1;  // 输出gm时会乘以0.1
      uint64_t ans = static_cast<uint64_t>(*reinterpret_cast<int32_t*>(&tmp)); // 浮点值量化系数转换为uint64_t类型进行设置
      mm.SetQuantScalar(ans);
      mm.SetTensorA(gm_a);
      mm.SetTensorB(gm_b);
      mm.SetBias(gm_bias);
      mm.IterateAll(gm_c);
      
    • 向量的量化/反量化模式
      1
      2
      3
      4
      5
      6
      7
      8
      GlobalTensor gmQuant;
      ...
      REGIST_MATMUL_OBJ(&pipe, GetSysWorkSpacePtr(), mm, &tiling);
      mm.SetQuantVector(gmQuant);
      mm.SetTensorA(gm_a);
      mm.SetTensorB(gm_b);
      mm.SetBias(gm_bias);
      mm.IterateAll(gm_c);