1 GLIP 性能优化案例

具体请参考 GLIP 推理指导流程

1.1 消除冗余算子

开源代码中,在进行 softmax 计算之前源代码会有防溢出操作。在确保不会溢出的前提下,将开源模型代码中的这部分操作注释,可以消除一些小算子。

比如:注释如下代码,即消除了对应离线模型中的 Clip 算子。

if self.clamp_min_for_underflow:
    attn_weights_l = torch.clamp(attn_weights_l, min=-50000) # Do not increase -50000, data type half has quite limited range
if self.clamp_max_for_overflow:
    attn_weights_l = torch.clamp(attn_weights_l, max=50000) # Do not increase 50000, data type half has quite limited range

比如:通过 onnx 改图,删除 nn.MultiheadAttention 结构中的 ReduceMaxD 和 Sub 算子。

"""
      Transpose                                  
      /       \                改图               Transpose
     |     ReduceMaxD         ======>                |
      \       /                                   Softmax
         Sub                                        
          |
       Softmax
"""

为什么可以简化 ReduceMaxD + Sub 操作?softmax 有平移不变性,其本质是为了防溢出。验证代码如下:

#! python
import torch
import torch.nn.functional as F

def m1(x):
    x = x - x.max() 
    y = F.softmax(x, dim=0)
    return y

def m2(x):
    y = F.softmax(x, dim=0)
    return y

data = torch.FloatTensor([[1,0,2,0,3,0], [4,0,6,0,8,0]])
result1 = m1(data)
result2 = m2(data)

print(torch.eq(result1, result2))

1.2 新增图融合规则 TransdataTransposeTransdataBatchMatMulv2FusionPass

TransdataTransposeTransdataBatchMatMulv2FusionPass 的融合模式:将双 BatchMatMul2 节点间的 TransData、Transpose 等冗余节点删除(当 Transpose 的换轴操作与 Transdata 的换轴操作一致时才可以删除),其示意图如下所示。对于 >=8.0.RC2 的 CANN 版本,该图融合规则已添加至系统内置融合规则中,且默认开启。

/*!
 * \file transdata_transpose_transdata_batch_matmul_v2_fusion_pass.cpp
 * \brief
 *    data(fp16)        data(fp16)
 *       |                  |
 *    transdata  -->     reshape
 *       |                  |
 *    reformat          batchmatmulv2
 *       |
 *    (reshape)
 *       |
 *    transpose
 *       |
 *    (reshape)
 *       |
 *    transdata
 *       |
 *    batchmatmulv2
*/

1.3 算子性能优化

对于 >=8.0.RC2 的 CANN 版本,Gelu、Softmax 等算子通过使能 VectorCore 算子性能得到优化,并默认开启该优化项。对于 GLIP 模型而言,softmax 性能的提升收益较为明显。

如何查看是否使能 VectorCore?以SoftmaxV2为例:查看 /usr/local/Ascend/ascend-toolkit/latest/opp/built-in/op_impl/ai_core/tbe/config/ascend310p/aic-ascend310p-ops-info.json 文件,若 enableVectorCore 的 flag 为 True,表示该算子已经使能 VectorCore。

2 CLIP 性能优化案例

具体请参考 Chinise-CLIP 推理指导流程

2.1 算子高性能实现

昇腾AI处理器部分内置算子有高精度和高性能实现方式,用户可以通过 ATC 的参数配置模型编译时算子选择哪种实现方式。以 CLIP 的图像侧模型(即 ViT)为例,Sigmoid 算子采用高性能模式有较大收益。

atc --framework=5 \
--model=models/vit-b-16.img.fp16.bs${bs}.opt.onnx \
--output=models/vit-b-16.img.fp16.bs${bs} \
--input_format=NCHW \
--input_shape="image:${bs},3,224,224" \
--soc_version=Ascend${chip_name} \
--log=error \
--optypelist_for_implmode="Sigmoid" \
--op_select_implmode=high_performance \
--insert_op_conf aipp.config \
--enable_small_channel 1

2.2 使能融合算子 SwinTransformerLnQKV

融合算子 SwinTransformerLnQKV 对应融合规则 SwinTransformerLnQKVFusionPass。其融合模式如下所示:

/*!
 * \file swin_transformer_ln_qkv_fusion_pass.cc
 * \brief the pass will turn three conjuction matmul_confusionTranspose into a swin_transformer_ln_qkv
 *  *  * pattern:
 *                        LayerNorm
 *                      /     |     \
 *                   var   Reshape  mean
 *                            |
 *                        TransposeD
 *                            |
 *                         Reshape
 *                            |
 *                         Reshape          =>   swin_transformer_ln_qkv
 *                            |
 *                       BatchMatMulV2
 *                            |
 *                    ConfusionTransposeD
 *                            |
 *                         SplitVD
 *                    /       |       \
 *                Squeeze  Squeeze  Squeeze
 * 
 * 
 *                         LayerNorm
 *                      /     |     \
 *                    var     |     mean 
 *                            |
 *                       BatchMatMulV2
 *                            |             =>   vit_transformer_ln_qkv
 *                    ConfusionTransposeD
 *                            |
 *                         SplitVD
 *                    /       |       \
 *                Squeeze  Squeeze  Squeeze
 *
 */

由于不同模型的 onnx 图在结构上有细微差异,所以需要在等价的前提下通过 onnx 改图修改为能应用该融合规则的模式。以 CLIP 的图像侧模型(即 ViT)为例:

  """
                                                                                 LayerNorm
                                                                                     |
                                                                                   MatMul
                                                                                     |
                  LayerNorm                                                         Add
                      |                                                              |
                    MatMul                                                        Reshape
                      |                                                              |
                     Add                                                         Transpose
                 /    |     \                                                        |
                /     |      \                                                     Split     
               /      |       \                                                /     |     \
              /       |        \                     改图                      /      |      \
        Slice_v    Slice_q    Slice_k              =======>                  /       |       \
            |         |          |                                          /        |        \
      Reshape_v   Reshape_q   Reshape_k                              Squeeze_v   Squeeze_q   Squeeze_k
            |         |          |                                         |          \          |
    Transpose_v  Transpose_q  Transpose_k                                  |           \     Transpose_k
            |         |         /                                          |            \       /
            |       Div        /                                           |            Div    /
            |          \      /                                             \             \   /
             \         MatMul                                                \            MatMul
              \           |                                                   \             |
               \       SoftMax                                                 \          SoftMax
                \        /                                                      \          /
                  MatMul                                                           MatMul
                    |                                                                |
                 Transpose                                                        Transpose
                    |                                                                |
                  Reshape                                                          Reshape

  """

2.3 使能自定义算子 FlashAttentionTik

昇腾的 FlashAttentionTik 自定义算子通过应用加速算法,提升 attention 计算操作的性能。以 CLIP 的图像侧模型(即 ViT)为例,通过 onnx 改图,接入 FlashAttentionTik 自定义算子的示意图如下。

"""
            /         |          \                                          /        |          \
      Squeeze_v   Squeeze_q   Squeeze_k                              Squeeze_v   Squeeze_q   Squeeze_k
            |         |          |                                         |         |          |
            |         |       Transpose_k                                  |         |          |
            |         |         /                  改图                     |         |          |
            |       Div        /                 =======>                  |        Div         |
            |          \      /                                             \        |         /
             \         MatMul                                                \       |        /
              \           |                                                   FlashAttentionTik
               \       SoftMax                                                       |
                \        /                                                       Transpose
                  MatMul                                                             |
                    |                                                             Reshape
                 Transpose                                                        
                    |                                                               
                  Reshape                                                          
"""