| Files | Last commit | Last update |
|---|---|---|
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago |
ClaGateQuant
产品支持情况
| 产品 | 是否支持 |
|---|---|
| Ascend 950PR&950DT系列产品 | √ |
| Atlas A3系列产品 | × |
| Atlas A2系列产品 | × |
| Atlas 200I/500 A2推理产品 | × |
| Atlas推理系列产品 | × |
| Atlas训练系列产品 | × |
功能说明
-
算子功能:融合算子,实现CLA(Cross-Layer Attention)两路head-wise gate加权合并与动态块量化。先对Global/CLA分支与Local/SWA分支的Attention输出分别施加Sigmoid门控并加权合并,再将合并结果reshape为
[T, K](K = N*D)进行基于块的动态量化,输出低精度的FP8/FP4张量和对应的E8M0缩放因子。在dst_type为FLOAT8_E4M3FN、FLOAT8_E5M2时,根据scale_alg的取值来指定计算scale的不同算法。量化模式由dual_axis_flag控制:单轴模式(dual_axis_flag=false,默认)仅在K方向([1,32]block,row-wise)输出一套量化数据,col_data/col_scale为空输出;双轴模式(dual_axis_flag=true)还会在T方向([32,1]block,col-wise)输出col-wise量化数据。 -
计算公式:
阶段1:CLA gate融合
逐token、逐head做两路Sigmoid门控加权,其中σ(x)=11+e−x\sigma(x) = \dfrac{1}{1 + e^{-x}}为Sigmoid函数:
sg=σ(zg),sl=σ(zl)s_g = \sigma(z_g), \qquad s_l = \sigma(z_l)
merged[t,n,d]=sg[t,n]⋅Og[t,n,d]+sl[t,n]⋅Ol[t,n,d]merged[t, n, d] = s_g[t, n] \cdot O_g[t, n, d] + s_l[t, n] \cdot O_l[t, n, d]
量化前逻辑矩阵:
X=reshape(merged,[T,K]),K=N×DX = \operatorname{reshape}(merged, [T, K]), \qquad K = N \times D
阶段2:双轴动态块量化
-
场景1,当
scale_alg为0时,即OCP Microscaling Formats (Mx) Specification实现:-
Row-wise量化(K方向):将X在K维度上按32个数一组量化,一组32个数{{Vi}i=132}\{\{V_i\}_{i=1}^{32}\}量化为{row_scale,{Pi}i=132}\{row\_scale, \{P_i\}_{i=1}^{32}\}
shared_exp=floor(log2(maxi(∣Vi∣)))−emaxshared\_exp = floor(log_2(max_i(|V_i|))) - emax
row_scale=2shared_exprow\_scale = 2^{shared\_exp}
Pi=cast_to_dst_type(Vi/row_scale,round_mode), i from 1 to 32P_i = cast\_to\_dst\_type(V_i/row\_scale, round\_mode), \space i\space from\space 1\space to\space 32
-
Col-wise量化(T方向,仅
dual_axis_flag=true):将X在T维度上按32个数一组量化,一组32个数{{Vj}j=132}\{\{V_j\}_{j=1}^{32}\}量化为{col_scale,{Pj}j=132}\{col\_scale, \{P_j\}_{j=1}^{32}\}shared_exp=floor(log2(maxj(∣Vj∣)))−emaxshared\_exp = floor(log_2(max_j(|V_j|))) - emax
col_scale=2shared_expcol\_scale = 2^{shared\_exp}
Pj=cast_to_dst_type(Vj/col_scale,round_mode), j from 1 to 32P_j = cast\_to\_dst\_type(V_j/col\_scale, round\_mode), \space j\space from\space 1\space to\space 32
-
Row-wise量化后的PiP_i按对应的ViV_i的位置组成输出
row_data,row_scalerow\_scale按对应的K维度上的分组组成输出row_scale(每两个相邻分组的scale组成一对,存于最后一维,shape为[T, ceil(N*D/64), 2],尾组不足两个时偶数pad填充0)。Col-wise量化后的PjP_j按对应的VjV_j的位置组成输出col_data,col_scalecol\_scale按对应的T维度上的分组组成输出col_scale(shape为[ceil(T/64), N*D, 2],同样偶数pad填充0)。 -
emax: 对应数据类型的最大正则数的指数位。
DataType emax FLOAT4_E2M1 2 FLOAT4_E1M2 0 FLOAT8_E4M3FN 8 FLOAT8_E5M2 15
-
-
场景2,当
scale_alg为1时,只涉及FP8类型(向上取整算法):- Row-wise量化(K方向):将X在K维度上按32个数一组量化,每组长度为32,对每组单独计算一个块缩放因子Sfp32bS_{fp32}^b,再把组内所有元素用同一个Sfp32bS_{fp32}^b映射到目标低精度类型FP8。如果最后一组不足32个元素,把缺失值视为0,按照完整组处理。
-
找到该组中数值的最大绝对值:
Amax(Dfp32b)=max({∣di∣}i=132)Amax(D_{fp32}^b)=max(\{|d_{i}|\}_{i=1}^{32})
-
将FP32映射到目标数据类型FP8可表示的范围内,其中Amax(DType)Amax(DType)是目标精度能表示的最大值(FLOAT8_E4M3FN为448,FLOAT8_E5M2为57344):
Sfp32b=Amax(Dfp32b)Amax(DType)S_{fp32}^b = \frac{Amax(D_{fp32}^b)}{Amax(DType)}
-
将块缩放因子Sfp32bS_{fp32}^b转换为FP8格式下可表示的缩放值Sue8m0bS_{ue8m0}^b:从Sfp32bS_{fp32}^b中提取无偏指数EintbE_{int}^b和尾数MfixpbM_{fixp}^b,为保证量化时不溢出,对指数向上取整,且在FP8可表示的范围内:
Eintb={Eintb+1,如果Sfp32b为正规数,且Eintb<254且Mfixpb>0Eintb+1,如果Sfp32b为非正规数,且Mfixpb>0.5Eintb,否则E_{int}^b = \begin{cases} E_{int}^b + 1, & \text{如果} S_{fp32}^b \text{为正规数,且} E_{int}^b < 254 \text{且} M_{fixp}^b > 0 \\ E_{int}^b + 1, & \text{如果} S_{fp32}^b \text{为非正规数,且} M_{fixp}^b > 0.5 \\ E_{int}^b, & \text{否则} \end{cases}
-
计算块缩放因子:row_scale=Sue8m0b=2Eintbrow\_scale=S_{ue8m0}^b=2^{E_{int}^b}
-
计算块转换因子:Rfp32b=1fp32(Sue8m0b)R_{fp32}^b=\dfrac{1}{fp32(S_{ue8m0}^b)}
-
应用到量化的最终步骤,对于每个组内元素,Pi=cast_to_dst_type(dfp32i⋅Rfp32b)P_i = cast\_to\_dst\_type(d_{fp32}^i \cdot R_{fp32}^b),最终Row-wise输出的量化结果是(row_scale,[Pi]i=132)\left(row\_scale, [P_i]_{i=1}^{32}\right)。
-
- Col-wise量化(T方向,仅
dual_axis_flag=true):将X在T维度上按32个数一组量化,采用与Row-wise相同的向上取整算法,对每组独立计算块缩放因子并量化,得到col_scalecol\_scale与{Pj}j=132\{P_j\}_{j=1}^{32},最终Col-wise输出的量化结果是(col_scale,[Pj]j=132)\left(col\_scale, [P_j]_{j=1}^{32}\right)。
- Row-wise量化(K方向):将X在K维度上按32个数一组量化,每组长度为32,对每组单独计算一个块缩放因子Sfp32bS_{fp32}^b,再把组内所有元素用同一个Sfp32bS_{fp32}^b映射到目标低精度类型FP8。如果最后一组不足32个元素,把缺失值视为0,按照完整组处理。
-
参数说明
| 参数名 | 输入/输出/属性 | 描述 | 数据类型 | 数据格式 | shape |
|---|---|---|---|---|---|
| global_attn | 输入 | Global/CLA分支Attention输出O_g |
BFLOAT16、FLOAT16 | ND (TND) | [T, N, D] |
| local_attn | 输入 | Local/SWA分支Attention输出O_l,shape与global_attn一致 |
BFLOAT16、FLOAT16 | ND (TND) | [T, N, D] |
| global_gate_logits | 输入 | Global gate的Sigmoid前值z_g |
BFLOAT16、FLOAT16 | ND | [T, N] |
| local_gate_logits | 输入 | Local gate的Sigmoid前值z_l |
BFLOAT16、FLOAT16 | ND | [T, N] |
| row_data | 输出 | Row-wise量化数据P_i |
FLOAT8_E5M2、FLOAT8_E4M3FN、FLOAT4_E2M1、FLOAT4_E1M2 | ND | [T, N*D] |
| row_scale | 输出 | Row-wise每个[1,32]分组的E8M0缩放因子(两两一组存最后一维,偶数pad补0) |
FLOAT8_E8M0 | ND | [T, ceil(N*D/64), 2] |
| col_data | 输出 | Col-wise量化数据P_j;dual_axis_flag=false时为空输出 |
FLOAT8_E5M2、FLOAT8_E4M3FN、FLOAT4_E2M1、FLOAT4_E1M2 | ND | [T, N*D] |
| col_scale | 输出 | Col-wise每个[32,1]分组的E8M0缩放因子(偶数pad补0);dual_axis_flag=false时为空输出 |
FLOAT8_E8M0 | ND | [ceil(T/64), N*D, 2] |
| dst_type | 可选属性 | 目标量化类型:底层属性35=FLOAT8_E5M2、36=FLOAT8_E4M3FN、40=FLOAT4_E2M1、41=FLOAT4_E1M2,默认36;PTA接口按ScalarType int枚举注册:23=torch.float8_e5m2、24=torch.float8_e4m3fn、296=torch_npu.float4_e2m1fn_x2、297=torch_npu.float4_e1m2fn_x2,None等价24=torch.float8_e4m3fn | INT64 | - | - |
| round_mode | 可选属性 | 舍入模式:FP8仅支持"rint";FP4支持"rint"/"floor"/"round"。默认"rint" |
STRING | - | - |
| scale_alg | 可选属性 | scale计算方法:1=cuBLAS,0=OCP;FP4仅支持0。默认1 | INT64 | - | - |
| input_attn_layout | 可选属性 | 输入global_attn/local_attn的排布格式,当前仅支持"TND"。默认"TND" |
STRING | - | - |
| dual_axis_flag | 可选属性 | 量化模式:true=双轴量化(同时输出row/col两套结果);false=单轴量化(仅输出row-wise,col_data/col_scale为空输出)。默认false | BOOL | - | - |
说明:算子属性注册顺序为
dst_type、round_mode、scale_alg、input_attn_layout、dual_axis_flag,与tiling、aclnn实现保持一致;算子与PTA侧dual_axis_flag默认均为False,dst_type为可选ScalarType int枚举,传None时按24=torch.float8_e4m3fn处理。
约束说明
global_attn/local_attn必须为3维张量且shape一致,为[T, N, D];N ∈ [1,128],D ∈ {128, 256}。global_gate_logits/local_gate_logits必须为2维张量[T, N],数据类型与global_attn/local_attn一致。- 当
dst_type为FP4(底层40/41,PTA侧为296/297)时,K = N*D必须可被4整除,且scale_alg必须为0。 - FP8输出类型仅支持
"rint"舍入模式。 dual_axis_flag=false时,col_data/col_scale为空输出(内部空形状[0]),接口不访问该输出。
调用说明
| 调用方式 | 调用样例 | 说明 |
|---|---|---|
| aclnn调用 | test_aclnn_cla_gate_quant | 通过aclnnClaGateQuant 接口方式调用ClaGateQuant算子。 |
| 图模式 | cla_gate_quant_proto.h | 通过ClaGateQuant 算子IR原型构图方式调用ClaGateQuant算子。 |
| PyTorch API | cla_gate_quant.py | 通过cla_gate_quant Torch Extension接口调用ClaGateQuant算子(支持单算子模式与TorchAir图模式)。 |