GPU推理服务性能优化之路 | 得物技术

news/2024/5/4 5:00:40/文章来源:https://blog.csdn.net/SmartCodeTech/article/details/129710672

1背景

随着CV算法在业务场景中使用越来越多,给我们带来了新的挑战,需要提升Python推理服务的性能以降低生产环境成本。为此我们深入去研究Python GPU推理服务的工作原理,推理模型优化的方法。最终通过两项关键的技术: 1.Python的GPU与CPU进程分离,2.使用TensorRT对模型进行加速,使得线上大部分模型服务QPS提升5-10倍左右,大量节约了线上GPU推理服务的成本。

针对上面的两项关键技术,我们还自研了相关框架与工具进行沉淀。包括基于Python的CPU与GPU进程自动隔离的推理服务框架,以及对推理模型进行转TensorRT优化的调试工具。

此外针对不同的推理服务性能瓶颈,我们还梳理了各种实战优化技巧,比如CPU与GPU分离,TensorRT开启半精度优化,同模型混合部署,GPU数据传输与推理并行等。

下面从理论,框架与工具,实战优化技巧三个方面介绍下推理服务性能优化的方法。

2理论篇

2.1 CUDA架构

CUDA 是 NVIDIA 发明的一种并行计算平台和编程模型。它通过利用图形处理器 (GPU) 的处理能力,可大幅提升计算性能。

CUDA的架构中引入了主机端(host, cpu)和设备(device, gpu)的概念。CUDA的Kernel函数既可以运行在主机端,也可以运行在设备端。同时主机端与设备端之间可以进行数据拷贝。

CUDA Kernel函数:是数据并行处理函数(核函数),在GPU上执行时,一个Kernel对应一个Grid,基于GPU逻辑架构分发成众多thread去并行执行。
CUDA Stream流:Cuda stream是指一堆异步的cuda操作,他们按照host代码调用的顺序执行在device上。

典型的CUDA代码执行流程:
a.将数据从Host端copy到Device端。
b.在Device上执行kernel。
c.将结果从Device段copy到Host端。

以上流程也是模型在GPU推理的过程。在执行的过程中还需要绑定CUDA Stream,以流的形式执行。

2.2 传统Python推理服务瓶颈

2.2.1 传统Python推理服务架构

由于Python在神经网络训练与推理领域提供了丰富的库支持,加上Python语言自身的便利性,所以推理服务大多用Python实现。CV算法的推理引擎大多采用Python flask框架或Kserve的框架直接实现。这种框架大致调用流程如下:

以上架构是传统推理服务的常用架构。这种架构的优势是代码写起来比较通俗易懂。但是在性能上有很大的弊端,所能承载的QPS比较低。我们用了几个CV模型去压测,极限QPS也一般不会超过4。

2.2.2 瓶颈分析

由于以上架构的CPU逻辑(图片的前处理,后处理)与GPU逻辑(模型推理)在同一个线程内,所以会存在如下性能瓶颈:

  • 如果是单线程的模式,CPU逻辑与GPU逻辑相互等待,GPU Kernel函数调度不足,导致GPU使用率不高。无法充分提升QPS。这种情况下只能开启更多进程来提升QPS,但是更多进程会带来更多显存的开销。

  • 如果开启多线程模式,经过实测,这种方式也不能带来QPS的提升。主要是因为Python的GIL锁的原因,由于Python GIL锁的存在,Python的多线程实际上是伪的多线程,并不是真正的并发执行,而是多个线程通过争抢GIL锁来执行,这种情况下GPU Kernel launch线程不能得到充分的调度。在Python推理服务中,开启多线程反而会导致GPU Kernel launch线程频繁被CPU的线程打断。由于GPU kernel lanch调度不足,这种方式也无法充分利用GPU使用率。

2.2.3 解决方案

针对以上问题,我们的解决方案是把CPU逻辑与GPU逻辑分离在两个不同的进程中。CPU进程主要负责图片的前处理与后处理,GPU逻辑则主要负责执行cuda kernel 函数,即模型推理。

另外由于我们线上有大量推理服务在运行,所以我们基于Python开发了一个CPU与GPU分离的统一框架。针对原有Flask或Kserve的服务,稍作修改即可使用我们的服务。具体请参考下面的CPU与GPU分离的统一推理框架相关介绍。

针对线上的某个推理服务,使用我们的框架进行了CPU与GPU进程分离,压测得出的数据如下,可见QPS大约提升了7倍左右。

2.3 TensorRT模型加速原理

TensorRT是由英伟达公司推出的一款用于高性能深度学习模型推理的软件开发工具包,可以把经过优化后的深度学习模型构建成推理引擎部署在实际的生产环境中。TensorRT提供基于硬件级别的推理引擎性能优化。
下图为业界最常用的TensorRT优化流程,也是当前模型优化的最佳实践,即pytorch或tensorflow等模型转成onnx格式,然后onnx格式转成TensorRT进行优化。

其中TensorRT所做的工作主要在两个时期,一个是网络构建期,另外一个是模型运行期。

a.网络构建期
i.模型解析与建立,加载onnx网络模型。
ii.计算图优化,包括横向算子融合,或纵向算子融合等。
iii.节点消除,去除无用的节点。
iv.多精度支持,支持FP32/FP16/int8等精度。
v.基于特定硬件的相关优化。

b.模型运行期
i.序列化,加载RensorRT模型文件。
ii.提供运行时的环境,包括对象生命周期管理,内存显存管理等。

以下是我们基于 VisualTransformer模型进行的TensorRT优化前后的性能评测报告:

3框架与工具篇

这一篇章,主要介绍我们自己推出的框架与工具。其中框架为CPU与GPU分离的Python统一推理框架,工具则为Onnx转TensorRT的半自动化调试工具。相关框架与工具我们在线上大量推理服务推进使用中。

其中CPU与GPU分离的Python统一推理框架解决了普通Python推理服务无法自动隔离CPU与GPU的问题,用户只需要继承并实现框架提供的前处理,推理,后处理相关接口,底层逻辑即可自动把CPU与GPU进行进程级别隔离。

其中TensorRT半自动化调试工具,主要定位并解决模型转TensorRT的过程中遇到的各种精度丢失问题。底层基于TensorRT的相关接口与工具进行封装开发。简化TensorRT的优化参数。

3.1 CPU与GPU分离的统一推理框架

新架构设计方案如下:

方案设计的思路是GPU逻辑与CPU逻辑分离到两个进程,其中CPU进程主要负责CPU相关的业务逻辑,GPU进程主负责GPU相关推理逻辑。同时拉起一个Proxy进程做路由转发。

(1)Proxy进程
Proxy进程是系统门面,对外提供调用接口,主要负责路由分发与健康检查。当Proxy进程收到请求后,会轮询调用CPU进程,分发请求给CPU进程。

(2)CPU进程
CPU进程主要负责推理服务中的CPU相关逻辑,包括前处理与后处理。前处理一般为图片解码,图片转换。后处理一般为推理结果判定等逻辑。
CPU进程在前处理结束后,会调用GPU进程进行推理,然后继续进行后处理相关逻辑。CPU进程与GPU进程通过共享内存或网络进行通信。共享内存可以减少图片的网络传输。

(3)GPU进程
GPU进程主要负责运行GPU推理相关的逻辑,它启动的时候会加载很多模型到显存,然后收到CPU进程的推理请求后,直接触发kernel lanuch调用模型进行推理。

该方案对算法同学提供了一个Model类接口,算法同学不需要关心后面的调用逻辑,只需要填充其中的前处理,后处理的业务逻辑,既可快速上线模型服务,自动拉起这些进程。

该方案把CPU逻辑(图片解码,图片后处理等)与GPU逻辑(模型推理)分离到两个不同的进程中。可以解决Python GIL锁带来的GPU Kernel launch调度问题。

3.2 TensorRT调试工具

TensorRT虽然不是完全开源的,但是官方给出了一些接口与工具,基于这些接口与工具我们可以对模型优化流程进行分析与干预。基于TensorRT官方提供的接口与工具,我们自己研发了一套工具。用户可以使用我们的工具把模型转成TensorRT格式,如果在模型转换的过程中出现精度丢失等问题,也可以使用该工具进行问题定位与解决。

自研工具主要在两个阶段为用户提供帮助,一个阶段是问题定位,另一个阶段是模型转换。具体描述如下:

3.2.1 问题定位

问题定位阶段主要是为了解决模型转TensorRT开启FP16模式时出现的精度丢失问题。一般分类模型,对精度的要求不是极致的情况下,尽量开启FP16,FP16模式下,NVIDIA对于FP16有专门的Tensor Cores可以进行矩阵运算,相比FP32来说吞吐量提升一倍以上。
比如在转TensorRT时,开启FP16出现了精度丢失问题,自研工具在问题定位阶段的大致工作流程如下:

主要工作流程为:
(1)设定模型转换精度要求后,标记所有算子为输出,然后对比所有算子的输出精度。
(2)找到最早的不符合精度要求的算子,对该算子进行如下几种方式干预。

  • 标记该算子为FP32。
  • 标记其父类算子为FP32。
  • 更改该算子的优化策略(具体参考TensorRT的tactic)

循环通过以上两个步骤,最终找到符合目标精度要求的模型参数。这些参数比如,需要额外开启FP32的那些算子等。然后相关参数会输出到配置文件中,如下:

3.2.2 模型转换

模型转换阶段则直接使用上面问题定位阶段得到的参数,调用TensorRT相关接口与工具进行转换。
此外,我们在模型转换阶段,针对TensorRT原有参数与API过于复杂的问题也做了一些封装,提供了更为简洁的接口,比如工具可以自动解析ONNX,判断模型的输入与输出shape,不需要用户再提供相关shape信息了。

4优化技巧实战篇

在实际应用中,我们期望用户能够对一个推理模型开启CPU与GPU分离的同时,也开启TensorRT优化。这样往往可以得到QPS两次优化的叠加效果。比如我们针对线下某个分类模型进行优化,使用的是CPU与GPU分离,TensorRT优化,并开启FP16半精度,最终得到了10倍的QPS提升。

以下是我们在模型优化过程中的一些实战技巧,梳理一下,分享给大家。

(1)分类模型,CPU与GPU分离,TensorRT优化,并开启FP16,得到10倍QPS提升
某个线上基于Resnet的分类模型,对精度损失可以接受误差在0.001(误差定义:median,atol,rtol)范围内。因此我们对该推理服务进行了三项性能优化:
a.使用我们提供的GPU与CPU分离的统一框架进行改造。
b.对模型转ONNX后,转TensorRT。
c.开启FP16模式,并使用自研工具定位到中间出现精度损失的算子,把这些算子标记为FP32.

经过以上优化,最终得到了10倍QPS的提升(与原来Pytorch直接推理比较),成本上得到比较大的缩减。

(2)检测模型,CPU与GPU分离,TensorRT模型优化,QPS提升4-5倍左右。
某个线上基于Yolo的检查模型,由于对精度要求比较高,所以没有办法开启FP16,我们直接在FP32的模式下进行了TensorRT优化,并使用统一框架进行GPU与CPU分离,最终得到QPS 4-5倍的提升。

(3)同模型重复部署,充分利用GPU算力资源
在实际的场景中,往往GPU的算力是充足的,而GPU显存是不够的。经过TensorRT优化后,模型运行时需要的显存大小一般会降低到原来的1/3到1/2。

为了充分利用GPU算力,框架进一步优化,支持可以把GPU进程在一个容器内复制多份,这种架构即保证了CPU可以提供充足的请求给GPU,也保证了GPU算力充分利用。优化后的架构如下图:

5总结

采用以上两个推理模型的加速技巧,即CPU与GPU进程隔离,TensorRT模型加速。我们对线上的大量的GPU推理服务进行了优化,也节省了比较多的GPU服务器成本。
其中CPU与GPU进程隔离主要是针对Python推理服务的优化,因为在C++的推理服务中,不存在Python GIL锁,也就不存在Python Kernel launch线程的调度问题。目前业界开源的Python推理服务框架中,还没有提供类似的优化功能,所以我们后续有考虑把Python统一推理服务框架进行开源,希望能为社区做一点贡献。
此外TensorRT的模型优化,我们参考了大量NIVIDIA的官网文档,在上层做了封装,后续会进一步深入研究。

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

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

相关文章

最佳实践| 探索 Authing 企业级云原生权限治理平台

在现代企业中,数据已经成为最重要的资产之一。 有数据显示,全球大约有一半的组织在过去的一年中经历了至少一次成功的网络攻击事件,其中,39% 的攻击事件是由内部人员造成的。为了保护企业的数据和信息资产,许多政府和…

Linux应用开发之文件与IO流

与大多数操作系统一样,Linux为程序运行提供了大量的服务,包括打开文件、读文件、启动一个新程序、分配存储区以及获得当前时间等,这些服务被称为系统调用接口(system call interface)。另外,glibc库还提供了…

移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例 1: 输入:head [1,2,6,3,4,5,6], val 6 输出:[1,2,3,4,5] 示例 2: 输入&#xff…

使用IDEA把项目上传到gitee仓库

使用IDEA把项目上传到gitee仓库在gitee上建立一个仓库第一步(新建仓库)第二步(点击创建)第三步(复制仓库地址)创建工程第一步(选择工程所在文件夹)第二步(文件加入git&am…

qq怎么安装不了(QQ怎么都安装不上重装也不行,是哪里出了问题?)

qq怎么安装不了(QQ怎么都安装不上重装也不行,是哪里出了问题?) 一、发现问题 今天有朋友说他电脑怎么都装不上QQ,总是弹出“安装包可能被非法改动导致安装失败,请从官网下载最新安装包重新安装”,操作系统是XP&#…

[数据结构高频面试题]用两个栈实现队列详解

文章目录 一、栈实现队列的特点分析 1、1 具体分析 1、2 整体概括 二、用栈模拟队列代码的实现 2、1 手撕 栈 代码 2、1、1 stack.h 2、1、2 stack.c 2、2 用栈实现队列代码 🙋‍♂️ 作者:Ggggggtm 🙋‍♂️ 👀 专栏:…

Flink- 物理分区、Sink输出

物理分区 随机分区(shuffle) 轮询分区(Round-Robin) 重缩放分区(rescale) 广播(broadcast) 全局分区(global) 自定义分区(Custom) …

Studio One6中文语言版DAW数字音频音乐创作软件

Studio One6是一款非常实用的数字音乐创作软件,专门用于创作现代化音乐,软件具有简洁的界面和强大的功能,能够很好地辅助用户创作音乐。顾名思义就是“一个工作室”的意思,它所倡导的制作理念是直接在一个制作软件里完成音乐制作的…

Android 解包payload.bin文件,获取system.img

解析payload.bin获取.img文件 payload.bin payload.bin是Android OTA镜像打包文件,将包括system.img、boot.img和lk.img等在内的Android系统进行,打包为一个payload.bin文件。 在系统OTA过程中,系统会自动解压安装。 前期准备 需要安装py…

学习Java日志框架之——搞懂日志门面(JCL+SLF4J)

文章目录一、什么是日志门面1、门面模式(外观模式)2、日志门面二、了解JCL1、JCL组件结构2、JCL案例(1)JCL默认实现(2)导入log4j测试原有程序三、SLF4J简介四、SLF4J基本使用1、入门案例2、动态打印信息3、…

一次内存泄露排查

前因: 因为测试 长时间压测导致 接口反应越来越慢,甚至 导致服务器 崩溃 排查过程 1、top 查看是 哪个进程 占用 内存过高 2、根据 进程 id 去查找 具体是哪个 程序的问题 ps -ef| grep 41356 可以看到 具体的 容器位置 排查该进程 对象存活 状态…

23年PMP考试会使用第七版教材吗?

大家都知道了,今年的考纲是改版了的,为啥要改版呢,因为《PMBOK指南》更新到第七版了,考纲自然也要更新,据PMI的市场调查,近年来,项目管理行业新趋势在第六版和旧考纲中未收纳,为了确…

三、数据链路层

(一)纠错与检错1、奇偶校验码(再研究下,原理知道,具体过程无法重现)分为奇校验和偶校验,奇偶校验位在首部或尾部,奇偶校验满信息位奇偶校验位(1)原理&#xf…

Redis 数据结构

这里写目录标题Redis 数据结构一、String类型String数据类型的使用场景key 的设置约定二、Hash数据类型string存储对象(json)与hash存储对象的区别三、list 类型四、set 类型set数据交并差操作set 类型数据操作的注意事项六、sorted_set 类型Redis 数据结…

算法----火柴拼正方形

题目 你将得到一个整数数组 matchsticks ,其中 matchsticks[i] 是第 i 个火柴棒的长度。你要用 所有的火柴棍 拼成一个正方形。你 不能折断 任何一根火柴棒,但你可以把它们连在一起,而且每根火柴棒必须 使用一次 。 如果你能使这个正方形&a…

Junit单元测试框架

1)Junit是一个开源的JAVA语言的单元测试框架,也是JAVA方向使用最广泛的单元测试框架,使用JAVA开发者都应该学习junit框架,并且掌握单元测试的编写 2)selenium和Junit都可以被导入到maven项目里面 3)先进行创建maven项目,导入相关依…

linux 全局环境变量删除后 还有 仍然存在

linux 全局环境变量删除后 还有 仍然存在1、编辑 /etc/profile2、设置REDISCLI_AUTH后,redis-cli 进去redis后不需要再次认证2、删除全局环境后 source后 仍然存在3、unset释放全局环境变量4、总结1、编辑 /etc/profile 设置redis环境变量 在末尾加入一行 export R…

家电企业数字工厂系统解决方案

国内小型家电生产商的中小企业普遍使用传统的手工作业模式,依靠大量的人力,线下管理各种数据,如:纸质文档、excel制作等,信息化程度非常低,严重限制着企业生产效率的提升和生产规模的扩大。对传统制造企业来…

基于WEB的网上购物系统的设计与实现(附:源码 论文 sql文件)

摘 要 随着计算机网络技术的飞速发展和人们生活节奏的不断加快,电子商务技术已经逐渐融入了人们的日常生活当中,网上商城作为电子商务最普遍的一种形式,已被大众逐渐接受。因此开发一个网上商城系统,适合当今形势,更加…

AWS白皮书 – 成本优化

本文讲解AWS良好架构框架(AWS Well-Architected Framework)里其中五大支柱之一:成本优化(Cost Optimization)。 一套成本优化型系统应充分利用全部资源、以最低价格来实现业务成果,同时充分满足你的功能需…