开发者
资源
[object Object][object Object][object Object]undefined
[object Object]
  • 接口功能:在Swish门控线性单元激活函数后添加DynamicMxQuant操作,实现x的SwigluMxQuant计算。

  • swigluMode为0时的计算公式:

    swigluOuti=Swiglu(xi)=Swish(Ai)BiswigluOut_i = Swiglu(x_i)=Swish(A_i)*B_i y,mxscale=DynamicMxQuant(swigluOuti)y, mxscale = DynamicMxQuant(swigluOut_i)

    其中,A[object Object]i[object Object]表示x[object Object]i[object Object]的前半部分,B[object Object]i[object Object]表示x[object Object]i[object Object]的后半部分。

  • swigluMode为1时的计算公式:

    x_glu=x_glu.clamp(min=None,max=clampLimit)x\_glu = x\_glu.clamp(min=None, max=clampLimit) x_linear=x_linear.clamp(min=clampLimit,max=clampLimit)x\_linear = x\_linear.clamp(min=-clampLimit, max=clampLimit) out_glu=x_glusigmoid(gluAlphax_glu)out\_glu = x\_glu * sigmoid(gluAlpha * x\_glu) swigluOuti=out_glu(x_linear+gluBias)swigluOut_i = out\_glu * (x\_linear + gluBias) y,mxscale=DynamicMxQuant(swigluOuti)y, mxscale = DynamicMxQuant(swigluOut_i)

    其中,x_glu表示x[object Object]i[object Object]的偶数索引部分,x_linear表示x[object Object]i[object Object]的奇数索引部分。

  • 场景1,当scaleAlg为0时,DynamicMxQuant计算逻辑:

    • 将输入x在axis维度上按k = blocksize = 32个数分组,一组k个数 {{Vi}i=1k}\{\{V_i\}_{i=1}^{k}\} 动态量化为 {mxscale1,{Pi}i=1k}\{mxscale1, \{P_i\}_{i=1}^{k}\}, k = blocksize
    shared_exp=floor(log2(maxi(Vi)))emaxmxscale=2shared_expPi=cast_to_dst_type(Vi/mxscale,round_mode), i from 1 to blocksizeshared\_exp = floor(log_2(max_i(|V_i|))) - emax \\ mxscale = 2^{shared\_exp}\\ P_i = cast\_to\_dst\_type(V_i/mxscale, round\_mode), \space i\space from\space 1\space to\space blocksize\\
    • ​量化后的 PiP_{i} 按对应的 ViV_{i} 的位置组成输出yOut,mxscale按对应的axis维度上的分组组成输出mxscaleOut。

    • emax: 对应数据类型的最大正则数的指数位。

      [object Object]undefined
  • 场景2,当scaleAlg为1时,只涉及FP8类型,DynamicMxQuant计算逻辑:

    • 将长向量按块分,每块长度为k,对每块单独计算一个块缩放因子Sfp32bS_{fp32}^b,再把块内所有元素用同一个Sfp32bS_{fp32}^b映射到目标低精度类型FP8。如果最后一块不足k个元素,把缺失值视为0,按照完整块处理。
    • 找到该块中数值的最大绝对值:Amax(Dfp32b)=max({di}i=1k)Amax(D_{fp32}^b)=max(\{|d_{i}|\}_{i=1}^{k})
    • 将FP32映射到目标数据类型FP8可表示的范围内,其中Amax(DType)Amax(DType)是目标精度能表示的最大值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<254Mfixpb>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}
    • 计算块缩放因子:Sue8m0b=2EintbS_{ue8m0}^b=2^{E_{int}^b}
    • 计算块转换因子:Rfp32b=1fp32(Sue8m0b)R_{fp32}^b=\frac{1}{fp32(S_{ue8m0}^b)}
    • 应用到量化的最终步骤,对于每个块内元素,di=DType(dfp32iRfp32n)d^i = DType(d_{fp32}^i \cdot R_{fp32}^n),最终输出的量化结果是(Sb,[di]i=1k)\left(S^b, [d^i]_{i=1}^k\right),其中SbS^b代表块的缩放因子,这里指Sue8m0bS_{ue8m0}^b[di]i=1k[d^i]_{i=1}^k代表块内量化后的数据
[object Object]

每个算子分为,必须先调用“aclnnSwigluMxQuantGetWorkspaceSize”接口获取计算所需workspace大小以及包含了算子计算流程的执行器,再调用“aclnnSwigluMxQuant”接口执行计算。

[object Object]
[object Object]
[object Object]
  • 参数说明:

    [object Object]
  • 返回值:

    aclnnStatus:返回状态码,具体参见

    第一段接口会完成入参校验,出现以下场景时报错:

    [object Object]
[object Object]
  • 参数说明:

    [object Object]
  • 返回值:

    aclnnStatus:返回状态码,具体参见

[object Object]
  • 确定性计算:

    • aclnnSwigluMxQuant默认确定性实现。
  • 输入x对应activateDim的维度需要是2的倍数,且x的维数必须大于1维。

  • 当输出yOut的数据类型为FLOAT4_E2M1、FLOAT4_E1M2时,yOut的最后一维需要是2的倍数,x的最后一维需要是4的倍数。

  • groupIndexOptional所有元素之和不能大于输入x除尾轴之外的剩余轴的乘积,groupIndexOptional的每个元素需要大于0。

  • 输出yOut和mxscaleOut超出groupIndexOptional所有元素之和的部分未进行清理,该部分内存为垃圾数据。

[object Object]

示例代码如下,仅供参考,具体编译和执行过程请参考

[object Object]