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
"""