【深度学习推荐系统 工程篇】三、浅析FastTransFormer看 GPU推理优化 思路

前言

在搜索/推荐场景中(一般是CTR/CVR预估)Serving的模型一般是稀疏参数占比比较大,工程落地方面会遇到两方面的困难:

  • 稀疏参数的存储/IO
  • 网络结构的优化

对于稀疏参数的存储/IO,在上一篇【深度学习推荐系统 工程篇】二、从TF-Serving看生产环境的模型推理服务 有提及,这篇是想总结下 网络结构的优化

本篇借助分析FasterTransformer框架,看Transformer在工程落地中需要做什么样的优化,然后总结一些通用的优化思路

读完这篇文章,希望读者可以:

  1. 了解FasterTransformer整体框架以及流程
  2. 了解推理过程中GPU的优化思路和方法

一、Transformer算法理论基础

关于Transformer的网络结构,网上都有了各种分析,但大多良莠不齐,随便找一个看大概率容易一头雾水;

1.1 Transformer相关资料

这里分享下找到比较优秀的资料

  • Transformer原论文:https://arxiv.org/abs/1706.03762
  • 李沐精读论文:https://www.bilibili.com/video/BV1pu411o7BE/
  • Transformer详解:http://jalammar.github.io/illustrated-transformer/
  • Harvard NLP 团队用Pytorch实现Transformer:http://nlp.seas.harvard.edu/annotated-transformer/
  • Tensor2Tensor代码:https://github.com/tensorflow/tensor2tensor/blob/master/tensor2tensor/models/transformer.py

看完这几个,基本可以对Transformer的结构有大致的了解。

1.2 理论计算复杂度

如果想要进行工程落地,最好对Transformer理论上的计算复杂度有个大概了解;

在实际推理过程中,假设输入的BatchSize为 M M M,每条的SequenceLength为 N N N

网络的hidden_dim为 D D D,Encoder个数为 e n c o d e r _ s i z e encoder\_size encoder_size,Decoder的个数为 d e c o d e r _ s i z e decoder\_size decoder_size

一次推理的计算复杂度:

O ( M N ˙ 2 D ˙ ) ∗ ( e n c o d e r _ s i z e + d e c o d e r _ s i z e ) O(M \dot N^2 \dot D) * (encoder\_size +decoder\_size) O(MN˙2D˙)encoder_size+decoder_size

PS:计算量的大头 是 Attention结构中QKV的计算

二、浅析FastTransformer框架

2.1 框架目录

本次分析FastTransformer源码是v5.0版本,项目地址:https://github.com/NVIDIA/FasterTransformer

项目框架比较清晰,将Attention结构封装成Layer,内部再实现调用高度优化的kernel函数

目录结构如下:

/src/fastertransformer: source code of FasterTransformer
|–/models: Implementation of different models, like BERT, GPT.(常用网络的实现)
|–/layers: Implementation of layer modeuls, like attention layer, ffn layer.(封装成Layer模块,如attention/ffn等结构)
|–/kernels: CUDA kernels for different models/layers and operations, like addBiasResiual.(CUDA Kernel算子实现,一般在layer中调用)
|–/tf_op: custom Tensorflow OP implementation(封装成TensorflowOp)
|–/th_op: custom PyTorch OP implementation(封装成PytorchOp)
|–/triton_backend: custom triton backend implementation()
|–/utils: Contains common cuda utils, like cublasMMWrapper, memory_utils(封装成的工具类,如cublas参数,Allocator接口,Tensor接口)

上述目录中,最重要的是layers和kernels,layer抽象了计算流程,kernel给出了高效实现;

在Transformer结构中,两个重要的layer就是AttentionLayer和FFNLayer,这里画了类图整理下层次关系:

Attention layer:
在这里插入图片描述
FFN layer:
在这里插入图片描述
整体层次比较简单,下面以Example里的Bert模型为例,看下Forward流程

2.2 Bert模型的Forward流程

相应的代码在:https://github.com/NVIDIA/FasterTransformer/blob/release/v5.0_tag/src/fastertransformer/models/bert/Bert.h
相应的文档:https://github.com/NVIDIA/FasterTransformer/blob/release/v5.0_tag/docs/bert_guide.md

Bert模型主要包括 AttentionLayer和FFNLayer,可通过参数配置具体实现:

// Attention Layer
enum class AttentionType
{UNFUSED_MHA,UNFUSED_PADDED_MHA,FUSED_MHA,FUSED_PADDED_MHA
};
// FFN Layer
enum ActivationType
{Gelu,Relu
};

Bert模型的一次Forward流程:

在这里插入图片描述

2.3 Forward流程中的优化思路

2.3.1 流程优化(Remove Padding)

在这个文档中 https://github.com/NVIDIA/FasterTransformer/blob/release/v5.0_tag/docs/bert_guide.md 给出了去除Padding的流程图,

一个Batch中,对于没有达到MaxSeqLen的输入,一般会进行padding,补齐到MaxSeqLen,但显而易见会引入不必要的计算;

Effective-transformer 引入segment offset数组来去除Padding;FasterTransformer把这个优化集成到了项目中

2.3.2 OpFusion

OpFusion是网络结构优化中常见的手段,主要是以下几点目标:

  • 减少 Kernel Launch 次数以及开销
  • 在CPU/GPU异构架构中,如果部分算子仅有CPU实现的话会造成频繁的H2D/D2H,用GPU实现相应的cpu算子逻辑,可以避免HostMem,DeviceMem互相拷贝
  • 即使相邻的两个Op均有GPU实现,融合成一个算子,也可以减少计算结果显存读写的开销(否则需要先写回GlobalMemory,再从GlobalMemory读

回到FastTransformer,它将琐碎的操作尽可能的合并成一个Kernel;

PS:Tensorflow框架的一个特点是算子比较琐碎,一个操作经常由多个基础算子组成,因此针对Tensorflow的模型,OpFusion几乎是上线推理前必做的优化手段

2.3.3 优化Gemm

这里主要有几点:

  • 对QKV计算,调用Gemm或者BatchedGemm
  • FP16/FP32分别调用不同的gemm api接口(fp32 use cublas as default,fp16 use cublasLt as default)
  • AutoTunning

这里想分享2点:

一个是NV的线性计算库

看代码的时候发现用到Blas库比较多,除了基础的cublas接口,还有cuBlasLT,cuBlasXT等等,特意查了下资料:

  1. cuBlas/cuBlasLT简单的介绍和区别:https://developer.nvidia.com/blog/new-cublas-12-0-features-and-matrix-multiplication-performance-on-nvidia-hopper-gpus/
  2. cuBLas的官方API:https://docs.nvidia.com/cuda/cublas/index.html

二是针对Gemm/Kernel函数的AutoTunning思路

背景:由于GPU架构的复杂性,没有一组通用的参数,可以让某一操作 在所有数据规模/硬件 上达到最优的性能

在这种限制下,一种可能的做法 是将可调的参数独立出来组成参数空间(如 O ( b a t c h _ s i z e , m , n , k , d a t a _ t y p e ) O(batch\_size, m, n, k, data\_type) O(batch_size,m,n,k,data_type) 这几个参数够成了参数空间),在上线前,针对线上的真实请求,遍历参数空间中的性能指标,挑出最优的一组 写到 config文件里 使用

适用的场景不仅包括Gemm,也可以对Kernel函数的BlockSize, ThreadSize进行调整

2.3.4 低精度优化

  • 使用half2类型,进行向量化读取操作,在相同的指令周期内处理更多数据(类似于CPU上的AVX指令集操作),提升吞吐
  • FP16发挥硬件TensorCore的能力,加速计算

关于half2,额外找了些资料:

half2提升数据读取:https://developer.nvidia.com/blog/cuda-pro-tip-increase-performance-with-vectorized-memory-access/
关于half2与half的区别:https://forums.developer.nvidia.com/t/half2-vs-half-datatype/219492/3

另外关于低精度还想再分享一点,就是能降存储

最近比较火的大模型动辄上百亿参数,很难进行进行单机加载(近期发布的BaiChuan-13B,模型大小约30GB),

如果想在显存较小的显卡上加载,只能尝试低精度的方式(FP16或量化)降低数据存储(不过会影响网络精度,需要客观评估带来的业务影响)

2.3.5 高效的Kernel函数实现

项目中Kernel函数上都实现的很高效,如Reduce操作,都可以当做CUDA编程例子来学,

主要的点:

  • shared_memory 加速读取
  • __ldg缓存的使用
  • #pragma unroll
  • half2/INT8 低精度实现

三、GPU 推理优化思路

3.1 GPU推理存在的问题

谈问题之前,我们首先设想一个能充分发挥GPU算力的完美推理框架,它应该是这样

  • 几乎没有Kernel lanuch开销(NVProf中Kernel之间没有空隙),最好所有的操作都能在一个Kernel中完成
  • 接近全部的时间都用在 计算 上,达到硬件算力指标

但实际情况中,:

  1. Kernel Lanuch开销总是存在
  2. 永远会有访存的开销(尤其GPU中的GlobalMemory / SharedMemory 访问差了一个数量级,使得访存可能成为计算的瓶颈)

这些问题是GPU硬件架构 客观决定的,所以我们的优化工作只能是尽力缓解,然后去逼近理论计算的上限

3.2 可能的优化思路

针对上面提到的问题,我们可以总结下可能优化思路(在2.3中已经提到):

  • 流程优化
  • OpFusion
  • Gemm优化
  • 低精度优化
  • 高效的Kernel实现

基本上涵盖了可能的思路

3.3 “No silver bullet”(没有银弹)

另外对于模型的优化,笔者想借助软件工程的一句经典名言来发表下自己的想法:“No sliver bullet”,

即优化框架的通用性 和 极致性能很难兼得,没有一种框架可以对 现在所有的网络结构以及未来可能出现的结构 提供极致的优化

优化 的 过程永远是 螺旋式的迭代前进,即

  1. 新的网络结构(算法)
  2. Perf分析热点,进行可能优化,抽出通用的部分作为框架(工程)
  3. 新的网络结构(算法)
  4. Perf分析热点,进行可能优化,抽出通用的部分作为框架(工程)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/86937.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电子信息工程专业课复习知识点总结:(五)通信原理

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 第一章通信系统概述——通信系统的构成、各部分性质、性能指标1.通信系统的组成?2.通信系统的分类?3.调制、解调是什么?有什么用…

详解MySQL存储引擎

前言: 📕作者简介:热爱编程的小七,致力于C、Java、Python等多编程语言,热爱编程和长板的运动少年! 📘相关专栏Java基础语法,JavaEE初阶,数据库,数据结构和算法系列等,大家有兴趣的可以看一看。 😇😇😇有兴趣的话关注博主一起学习,一起进步吧! 一、MySQL存…

【CNN-FPGA开源项目解析】卷积层01--floatMult16模块

文章目录 (基础)半精度浮点数的表示和乘运算16位半精度浮点数浮点数的乘运算 floatMult16完整代码floatMult16代码逐步解析符号位sign判断指数exponent计算尾数fraction计算尾数fraction的标准化和舍位整合为最后的16位浮点数结果[sign,exponent,fraction] 其他变量宽度表alway…

Aspose转pdf乱码问题

一、问题描述 ​ 在centos服务器使用aspose.word转换word文件为pdf的时候显示中文乱码(如图),但是在win服务器上使用可以正常转换 二、问题原因 由于linux服务器缺少对应的字库导致文件转换出现乱码的 三、解决方式 1.将window中字体(c:\windows\fonts)放到linux…

leetcode刷题 二维数组 八方向

题目描述 输入:board [[0,1,0],[0,0,1],[1,1,1],[0,0,0]] 输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]] 题目分析:就是以二维数组某个元素为中心,寻找周围八个方向的元素,按照题目要求修改二维数组元素返回; 拷贝一份二…

ElementUI实现登录注册+axios全局配置+CORS跨域

一、搭建项目 1.1 安装 Element-UI 先确保是否安装了vue-cli脚手架工具 !!! 安装vue脚手架可以看看我的上一篇博客 构建好项目后通过npm安装element-ui cd 项目根路径 #进入新建项目的根目录 npm install element-ui -S #安装…

AUTOSAR 面试知识回顾

如果答不上来,就讲当时做了什么 1. Ethernet基础: 硬件接口: ECU到PHY: data 是MII总线, 寄存器控制是SMI总线【MDCMDIO两根线, half duplex】PHY输出(100BASE-T1): MDI总线,2 wire 【T1: twisted 1 pair …

C#__简单使用TCP/UDP发送消息

Socket(套接字、插口) TCP和UCP的区别: 1、基于连接和无连接 2、对系统资源的要求(TCP较多,UCP少) 3、UDP程序结构简单 4、流模式和数据报模式 5、TCP保证数据正确性和数据先后顺…

关于地址存放的例题

unsigned int a 0x1234; unsigned char b *(unsigned char*)&a; 上面代码大端存储和小端存储的值分别是多少? 大端存储的是把高位地址存放在低位地址处,低位存放到高位。小端是高位存放在高位,低位在低位。因为a是整型,所…

GraphQL基础知识与Spring for GraphQL使用教程

文章目录 1、数据类型1.1、标量类型1.2. 高级数据类型 基本操作2、Spring for GraphQL实例2.1、项目目录2.2、数据库表2.3、GraphQL的schema.graphql2.4、Java代码 3、运行效果3.1、添加用户3.2、添加日志3.3、查询所有日志3.4、查询指定用户日志3.5、数据订阅 4、总结 GraphQL…

C 语言简单入门

C 语言发展历史|标准 1972年,丹尼斯里奇(Dennis Ritch)和肯汤普逊(Ken Tompson)在贝尔实验室开发 UNIX 操作系统时基于 B 语言设计出 C 语言。 1987年,布莱恩柯林汉(Brian Kernighan&#xff…

数据库基础理论

什么是数据库? 数据:描述事物的符号记录,可以是数字、文字、图形、图像、声音、语言等,数据有多种形式,他们都是可以经过数字化后存入计算机。 数据库:存储数据的仓库,是长期存放在计算机内、…

世界前沿技术发展报告2023《世界信息技术发展报告》(三)量子信息技术

(三)量子信息技术 1. 概述2. 量子计算2.1 阿里巴巴达摩院成功研制两比特量子芯片,单比特操控精度超99.97%2.2 加拿大Xanadu公司开发出可编程光量子计算机2.3 美国英伟达公司为经典-量子混合计算推出开发架构2.4 日本国家自然科学研究所开发出…

SpringBoot实战

ISBN: 978-7-115-43314-5 作者:【美】Craig Walls 译者:丁雪丰 页数:209页 阅读时间:2022-12-27 推荐指数:★★★☆☆ 阅读本书还是要有一定的基础的,如果想要入门级还是不行, 建议入门级可以看…

python+nodejs+php+springboot+vue 法律知识分享科普系统平台

在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 要想实现法律知…

数字图像基础,数字图像处理中的基础内容(数字图像处理概念 P2)

文章目录 人类视觉系统构造数字图像生成采样和量化像素之间的基本关系 人类视觉系统构造 锥状体:明亮的视野杆状体:微光或暗视野图像成像原理:类似照相机亮度适应现象:人的视觉不能同时在一个范围内工作同时对比现象:…

el-select的某一项选中后显示id

环境: vue3element-plus 今天在使用elementui的下拉组件的时候发现有一个选项在选中后显示的是id.找了会没看到问题,后来想到会不会是没有设置key的原因(之前看到说vue3可以不用设置key),果然加上key就可以了

变量、因子、缺失值、类型转换、剔除多余变量、随机抽样、用R使用SQL、trim、na.rm=TRUE、数据标准化应用

变量:名义型、有序型、连续型变量 名义型:普通事件类型,如糖尿病I型和糖尿病II型。 有序型:有顺序的事件类型,如一年级、二年级和三年级。 连续型:表示有顺序的数量,如年龄。 因子:…

基于Python+Django的热门旅游景点数据分析系统的设计与实现(源码+lw+部署文档+讲解等)

前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻…

C++项目:仿muduo库实现高性能高并发服务器

文章目录 一、实现目标二、前置知识(一)HTTP服务器1.概念 (二)Reactor模型:1.概念2.分类(1)单Reactor单线程:单I/O多路复用业务处理。(2)单Reactor多线程&…