摘要:从显存优化,计算优化两个方面来分析一下如何进行深度学习模型推理优化。

本文分享自华为云社区《XEngine-深度学习推理优化》,作者: ross.xw。

前言

深度学习模型的开发周期,包括训练阶段和部署阶段。训练阶段,用户需要收集训练数据,定义自己的模型结构,在CPU或者GPU硬件上进行训练,这个过程反复优化,直到训练出满意精度的模型。有了模型之后,我们需要将模型服务部署运行,我们期望服务延迟越低越好,吞吐越高越好。这里会从显存优化,计算优化两个方面来分析一下如何进行深度学习模型推理优化。

1. 显存优化

1.1 显存分布

模型推理需要占用一定量的显存空间(以GPU推理为例),其中主要包括如下4个部分:

  1. 不可控制空间
  2. 用户数据
  3. 模型参数
  4. 运行时空间
    1. op计算的激活值
    2. op计算需要的临时空间

其中“不可控制空间”指系统分配的空间,如每个进程CUDA Context所占用的显存空间,一般在100-300MB左右;“用户数据”指用户自行分配的显存空间,如模型输入输出Tensor占用的空间;“模型参数”指训练的深度学习模型的参数所占用的显存空间,我们需要将模型参数加载到显存中,才能进行计算;“运行时空间”是指模型的算子在计算的时候,需要的显存空间。

以ResNet-50模型为例,显存分配空间占比如下。我们可以看到随着Batch Size的增大,运行时空间会线性增长,运行时空间成为显存占用的瓶颈。

不同的模型显存分布也是不一样的。在NLP场景中,transformer类型的模型近几年涌现了许多超大参数量的模型,模型参数空间将成为显存的瓶颈。

接下来,会从激活优化和参数优化两个方面讲解如何进行显存空间优化,并最后扩展到多模型显存空间共享。

1.2 激活优化

激活值优化的中心思想就是显存复用。推理和训练不一样,推理计算只有forward过程,当一个op计算完后,它所占用的输入空间其实就可以被后面的op进行复用了。

1.3 参数优化

参数优化主要是为了解决超大模型的问题,如果模型太大,一个卡装不下就需要多张卡。参数空间和激活不一样,它是固定的值,提前训练好了,而激活值是临时计算出来的。这就使得我们不能用复用的方式。这些参数总要在一个地方保存。可以借鉴多级缓冲的思路,将训练好的参数可以缓存到磁盘和cpu内存中,在需要的时候提前读取上来,这样我们就不需要所有的参数都存储到显存中,将大模型单张卡加载成为可能。

为了减少数据拷贝对推理性能的影响,需要将数据预读取和计算并行起来。在GPU计算里面,我们可以通过cuda stream + event的方式将计算和拷贝并行起来,如下图所示:

1.4 多模型显存共享

除了单模型内部的激活优化和参数优化,在多并发多模型的服务场景,我们还可以进一步进行多模型显存共享。假设如下:

  • 模型:M1, M2, M3...
  • 激活空间:A1, A2, A3...
  • 参数空间:P1, P2, P3...

1.5 显存优化效果

这里选取了CV和NLP两个场景的模型,对比了一下XEngine推理引擎和其他运行时引擎的显存占用,可以看到有明显的优化。如果不考虑性能开启参数优化(ParamOpt),可以进一步的降低显存占用。

2. 计算优化

2.1 计算分析

下图取了ResNet-50模型的一个片段,并抽象到计算和访存的流水线过程。我们可以看到,每个OP计算对应一个CUDA Kernel计算,每个kernel计算会从显存(Global Memory)中读取数据,在片上CUDA Core进行计算。右图为CUDA的存储架构,也符合金字塔访存原则,即越靠近片上,访存速度越快。其中Global Memory是GPU的显存,访问速度最慢;而片上的Shared Memory次之;最快的是片上Register空间。当模型的算子OP比较多的时候,模型推理计算会反复读写显存,效率比较低,为了解决这个问题,常用的方法是图融合技术;当OP计算的速度越快,整个模型推理计算速度也会越快,因此我们需要高性能的算子实现。接下来会从这两个方面分析。

2.2 图融合

图融合技术指将一些OP进行融合计算,由多个OP的Kernel计算转化为一个融合后OP的Kernel计算。通过这个优化,可以减少显存的反复读写,可以通过一次读取数据,在片上进行尽可能多的计算后,再将数据存储到显存中。同时也可以减少Kernel Launch的开销。融合后的算子实现可以通过手写CUDA Kernel或者调用第三方库或者CodeGen方式进行生成。

下图中左边为resnet-50模型优化前和优化后的Graph结构。CV类型的模型常用的融合手段是将线性计算和激活进行融合,如Conv + BN + Relu进行融合计算。

下图为Bert模型的图融合前后的变化。

2.3 高性能算子

  • 高性能计算库
    • Cublas/cudnn/cutlass
  • 手写CUDA Kernel
    • Cuda programming guide
    • Cuda best practice guide
  • 低精度计算
    • FP16/INT8/TensorCore (half2, dp4a, wmma)
  • CodeGen
    • TVM/XLA/MLIR…

2.4 计算优化效果

XEngine针对Bert类型模型进行优化,测试环境为NVIDIA V100,FP32计算。如下是性能对比,相对于原始框架未优化版本,在sequence length比较小的时候,有明显的性能提升。同时也和NVIDIA的SOTA解决方案FasterTransformer进行了对比,有轻微优势。

  • XEngine和Pytorch推理性能对比:

  • XEngine和FasterTransformer推理性能对比:

3. 总结

本文主要从显存优化和计算优化两个角度分析了一下模型推理常用的优化思路和技巧,并展示了一下优化的结果。希望对大家做推理工程优化有帮助。

点击关注,第一时间了解华为云新鲜技术~

XEngine:深度学习模型推理优化的更多相关文章

  1. 移动端 CPU 的深度学习模型推理性能优化——NCHW44 和 Record 原理方法详解

    用户实践系列,将收录 MegEngine 用户在框架实践过程中的心得体会文章,希望能够帮助有同样使用场景的小伙伴,更好地了解和使用 MegEngine ~ 作者:王雷 | 旷视科技 研发工程师 背景 ...

  2. CUDA上深度学习模型量化的自动化优化

    CUDA上深度学习模型量化的自动化优化 深度学习已成功应用于各种任务.在诸如自动驾驶汽车推理之类的实时场景中,模型的推理速度至关重要.网络量化是加速深度学习模型的有效方法.在量化模型中,数据和模型参数 ...

  3. CUDA上的量化深度学习模型的自动化优化

    CUDA上的量化深度学习模型的自动化优化 深度学习已成功应用于各种任务.在诸如自动驾驶汽车推理之类的实时场景中,模型的推理速度至关重要.网络量化是加速深度学习模型的有效方法.在量化模型中,数据和模型参 ...

  4. 使用函数计算三步实现深度学习 AI 推理在线服务

    目前深度学习应用广发, 其中 AI 推理的在线服务是其中一个重要的可落地的应用场景.本文将为大家介绍使用函数计算部署深度学习 AI 推理的最佳实践,  其中包括使用 FUN 工具一键部署安装第三方依赖 ...

  5. 天猫精灵业务如何使用机器学习PAI进行模型推理优化

    引言 天猫精灵(TmallGenie)是阿里巴巴人工智能实验室(Alibaba A.I.Labs)于2017年7月5日发布的AI智能语音终端设备.天猫精灵目前是全球销量第三.中国销量第一的智能音箱品牌 ...

  6. Apple的Core ML3简介——为iPhone构建深度学习模型(附代码)

    概述 Apple的Core ML 3是一个为开发人员和程序员设计的工具,帮助程序员进入人工智能生态 你可以使用Core ML 3为iPhone构建机器学习和深度学习模型 在本文中,我们将为iPhone ...

  7. 【翻译】借助 NeoCPU 在 CPU 上进行 CNN 模型推理优化

    本文翻译自 Yizhi Liu, Yao Wang, Ruofei Yu.. 的  "Optimizing CNN Model Inference on CPUs" 原文链接: h ...

  8. 用 Java 训练深度学习模型,原来可以这么简单!

    本文适合有 Java 基础的人群 作者:DJL-Keerthan&Lanking HelloGitHub 推出的<讲解开源项目> 系列.这一期是由亚马逊工程师:Keerthan V ...

  9. 基于NVIDIA GPUs的深度学习训练新优化

    基于NVIDIA GPUs的深度学习训练新优化 New Optimizations To Accelerate Deep Learning Training on NVIDIA GPUs 不同行业采用 ...

  10. AI佳作解读系列(一)——深度学习模型训练痛点及解决方法

    1 模型训练基本步骤 进入了AI领域,学习了手写字识别等几个demo后,就会发现深度学习模型训练是十分关键和有挑战性的.选定了网络结构后,深度学习训练过程基本大同小异,一般分为如下几个步骤 定义算法公 ...

随机推荐

  1. C#/.NET/.NET Core优秀项目和框架2023年10月简报

    前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(公众号每周至少推荐两个优秀的项目和框架当然节假日除外),公众号推文有项目和框架的介绍.功能特点以及部分截图等(打不开或 ...

  2. [C++]P3384 轻重链剖分(树链剖分)

    [C++]树链剖分 预备知识 树的基础知识 关于这个本文有介绍 邻接表存图 线段树基础 会区间加法和区间结合就可以了P3372 建议阅读这篇Blog 最近公共祖先LCA 虽然用不到这个思想 但是有类似 ...

  3. SQL改写案例3(递归查询开窗案例)

    没错,又是京华的开发老哥,这次找我问个SQL实现逻辑的案例. 我博客的案例基本都是他给我的,真的是又要帮他优化SQL还要教他实现SQL逻辑. 开发老哥写的SQL: SELECT ROW_NUMBER( ...

  4. Java Springbool敏感词过工具类滤

    Java Springbool敏感词过工具类滤 1. 功能描述利用前缀树这种数据结构,设计并开发出敏感词过滤工具. 2. 构建敏感词表resource/sensitive-words.txt 3. 敏 ...

  5. 由后缀表达式题目:stoi atoi 函数新发现

    洛谷上的题:有些·表示一个操作结束~假装没看到 1 #include<iostream> 2 #include<stack> 3 #include<string> ...

  6. Android Gson 混淆问题

    开发过程中遇到一个奇怪的问题. 有一个接口,debug 版本接收到云侧下发的字符串后可以通过 gson 将其转换为相应 bean 类,而 release 版本拿到的 bean 总是缺少一个关键的字段, ...

  7. C#Winform使用NPOI获取word中的数据

    公众号「DotNet学习交流」,分享学习DotNet的点滴. 需求 想要获取word里面的内容,如下图所示: 有一张表和一段文本,并将它们存入数据库或者Excel. 步骤 添加NPOI的库,如下图所示 ...

  8. FastJson、Jackson、Gson进行Java对象转换Json

    - Java对象转换Json的细节处理前言Java对象在转json的时候,如果对象里面有属性值为null的话,那么在json序列化的时候要不要序列出来呢?对比以下json转换方式一.fastJson1 ...

  9. StackGres 数据库平台工程,使用 Citus + Patroni 创建生产级高可用分布式 PostgreSQL 分片集群

    系列 StackGres, 可私有部署的云原生数据库平台工程 StackGres 数据库平台工程功能介绍与快速上手 StackGres 1.6 数据库平台工程集群配置管理(K8S Pods/Postg ...

  10. [USACO2007OPENS] Fliptile S

    题目描述 FJ 知道,智商高的奶牛产奶量也大,所以他为奶牛们准备了一个翻动瓦片的益智游戏. 在一个 \(M \times N\) 的方阵上(\(1 \leq M,N \leq 15\)),每个格子都有 ...