NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

复杂场景下的深度学习模型部署

  • 2023-08-07
    北京
  • 本文字数:3236 字

    阅读完需:约 11 分钟

复杂场景下的深度学习模型部署

背景


深度学习是一种使用神经网络的机器学习,正迅速成为解决从文本分类到推荐系统等许多不同问题的有效工具。然而,将训练好的神经网络模型部署到应用程序和服务中可能给算法从业人员带来不小的挑战。算法框架的不同、计算资源稀缺和缺乏标准实现等挑战都可能导致模型部署的失败。


作业帮的业务体量较大,需要部署大量的深度学习模型应对不同的任务。为满足实际使用,我们部署的模型服务需要具有以下特点:


  1. 高并发

  2. 低时延

  3. 模型多

  4. 更新快

  5. 业务方多


结合任务特点与实际应用场景,我们还面临以下问题:


  1. 数据预处理模块与模型版本强耦合,部署时需保持同步。

  2. 多个版本的预处理模块相互之间易冲突。

  3. 模型太多,如果全部加载至 GPU 浪费资源。


因此,本文将以上述场景作为对象,阐述三种不同的解决方案,并对比它们的性能指标。最终目标是找到一个适合作业帮任务的模型部署方案,在合理占用资源的情况下,满足不同业务方的需求。

模型部署方案

1. Gunicorn + Flask + Transformers


Transformers 是一个十分方便的自然语言处理库,它的宗旨是让最先进的 NLP 技术人人易用。通过 Transformers 可以轻松地实现模型的训练、加载和推理。此外,使用 Flask 框架部署深度学习模型是最简单快捷的方式。但是 Flask 自带的 Web 服务性能极不稳定,无法满足高并发、低延迟的需求。因此,我们通过 Gunicorn 框架提供的 WSGI 服务来部署 Flask 的接口,也就是将 Flask 代码部署在 Gunicorn 提供的 WSGI 服务上,可以显著提升服务的并发能力和稳定性。


本部署方式的整体框架如下图所示:



  1. 利用 Transformers 加载所需模型,但通过 LRU 机制控制加载在内存中的模型数量最大为 8,防止内存多大。

  2. 通过 Flask Web 框架构建模型预测服务,包括数据的预处理、模型预测和结果后处理等步骤。

  3. 最后用 Gunicorn 启动 Flask 服务,设置 worker 数量支持异步处理请求,提高并发能力。


Flask 服务的构建十分简单,具体如下图所示。实现一个模型预测函数,并将其与’predict’接口绑定即可。另外,需注意的是线上服务需要实现’ready’接口返回 200 和’ok’以执行健康检查。



采用 Gunicorn+Flask+Transformers 部署深度学习服务的初衷是,该方式与我们的训练框架较为耦合,实现起来比较简单。但在使用线上服务的实际场景中,遇到了以下问题:


  1. 在每个 worker 中,执行模型的预测会有 100+线程,导致资源的挤兑。

  2. Gunicorn 确实提高了 Flask 服务的并发能力,但在并发请求较多时,并不能解决健康检查超时的问题,使得 pod 摘流并增加预测时延。

  3. Transformers 模型推理方式的时延较长。

  4. LRU 机制的存在使得模型需要重新加载,而模型加载比较慢导致预测时延增加。


最后,这种通过这种部署方式部署至 serverless,共 6 个 pod,每个 pod 的资源是 16 核 16G 的情况下,能达到 150QPS。

2. Tornado + PyTorch


    Tornado 是使用 Python 编写的一个强大的、可扩展的 Web 服务器。它在处理严峻的网络流量时表现得足够强健,在创建和编写时又足够轻量,并能够被用在大量的应用和工具中。Tornado 在设计之初就考虑到了性能因素,支持异步非阻塞,可以接受多个用户的并发请求。本方案采用 Tornado 代替 Flask 以实现更好的异步通信。


    本部署方案直接采用PyTorch模型预测的方式代替 Transformers,避免 Transformers 内 Trainer 的冗余操作以减少预测时间。此外,将每个模型分开部署至子服务,取消模型的动态加载机制,避免模型切换造成的耗时。同时,这种方式也避免了模型过多导致的资源挤占问题。


本部署方式的整体框架如下图所示:



  1. 每个模型通过 Tornado 包装成子服务,包含数据预处理,模型预测和结果后处理。

  2. 分发服务负责接收所有请求,并根据数据类别将其分发至对应的模型预测服务进行预测。

  3. 子服务的预测结果返回至分发服务,由分发服务返回所有数据的预测结果。

  4. Tornado 部署 Web 服务同样十分便捷,同时可通过’async’和’await’关键字轻松实现异步。


采用 Tornado+PyTorch 的方案部署模型的原因是,组里同事有 Tornado 的踩坑经验,方便实现性能上的优化(如异步)。此外,本方式仍与训练框架有联系,从训练到部署的链路仍比较完整。然而在上线测试后,发现本部署方式仍有以下问题:


  1. PyTorch 预测时启动大量线程的问题仍未解决。

  2. 模型多的情况下,需要申请大量模块并部署,管理太繁杂。

  3. 没有动态 Batching 功能,无法更好地发挥机器性能。

3. 单模型性能测试


为更方便地进行性能测试,我们采用单个模型进行性能的测试。通过不同部署方式在单模型上的性能进行对比,以挑选最优的部署方案。本节中,我们采用了 ONNX 和 TorchScript 两种模型格式,并分别用 Tornado 和 Triton Inference Server 进行部署。


ONNX (Open Neural Network Exchange)是一种针对机器学习所设计的开放式文件格式,用于存储训练好的模型。它使得不同的人工智能框架可以采用相同格式存储模型数据并交互。对于我们的场景,其优势在于可以控制线程数防止资源挤占。


Triton 是英伟达等公司推出的开源推理框架,为用户提供在深度学习模型部署的解决方案。其主要职责和服务紧密相关,服务中常见的需求需要它做处理。比如 Batching,Sequence,Pipeline 和模型仓库的管理等

我们将各个服务部署在 Docker 中,限定 CPU 核数为 16 来模拟线上模块的资源。通过 Locust 工具进行压测,具体结果如下表所示:


部署方式

QPS

时延中位数 (ms)

95%分位时延 (ms)

CPU利用率

Tornado + ONNX

100

300

500

1300%

Tornado + TorchScript

60

1600

1800

1600%

Triton + ONNX

100

340

530

1300%

Triton + TorchScript

100

50

150

800%

集成预处理的Triton + TorchScript

25

200

300

1600%


在不考虑预处理的情况下,Triton + TorchScript 的部署方式是最优的。Triton 的动态 Batching 功能极大地提升了并行预测的功能。但是在我们的场景中,数据预处理与模型预测强耦合。于是,尝试利用 Python Backend 将预处理部分同样集成在 Triton 中,实现完整的模型预测服务。但在实际测试过程中,发现集成预处理的 Triton 服务效果并不理想,怀疑是预处理的串行使得模型预测时无法进行动态 Batching。因此,我们最终决定将部署方式确定为 Tornado Web 服务和 Triton Inference Server。


本节对 ONNX 的处理比较粗糙,可能并没有发挥其优势。但 Triton + TorchScript 的方式已经满足业务需求,并没有对 ONNX 的实验进行深究。

4. Tornado + Triton


本节介绍最终确定的模型部署方式:Tornado + Triton。通过将不同版本的预处理模块打包成不同的 Python 模块解决版本冲突问题。另外,针对业务方多且需求不一致的问题,我们通过写多个接口的方式解决。比如,’/category_predict’支持单条预测,’/category_predict_nlp’支持批量预测。于是,本部署方式如下图所示:



其中,Tornado Web 服务接收应用方的请求,对数据进行预处理,然后异步调用 Triton 进行模型预测,最后对预测结果进行后处理并返回结果。


    本节中通过题型预测任务对新的部署方式进行测试,将对应的 21 个模型部署至限定 16 核的 Triton Inference Server。产生随机数据模拟线上请求并用 Locust 工具进行压测,具体结果如下:


部署方式

QPS

时延中位数 (ms)

95%分位时延 (ms)

CPU利用率

Web服务+Triton

100

270

600

800%


通过结果可以发现,将数据预处理和结果后处理集成在 Web 服务中并通过 Triton 进行模型部署的方案在我们复杂的业务场景下是最优的。这种方式不仅通过动态 Batching 的方式增加并发降低时延,并且方便了模型的管理与更新。其唯一的缺陷是无法解决预处理模块和模型版本强耦合的问题,在部署时需保持同步,且时间点最好是在服务低谷期。

总结与展望


本文涉及的场景比较复杂,主要有以下几个问题:


  1. 模型多,不同任务的模型总数接近 100 个,且更新频率随业务节奏变更。

  2. 易冲突,数据预处理和模型版本强耦合,且不同版本预处理模块易冲突。

  3. 性能要求高,任务面向用户,在部署至 CPU 环境下要求高并发和低时延。


因此,本文从实际应用场景触发,设计并尝试了多种部署方式,对比其在线上使用过程中的表现。经过几次实验后,找到了一种适用于我们复杂场景的深度学习模型部署方式,在不依赖 GPU 资源的情况下满足业务方的需求,并为后续的模型部署提供了一种可行的部署方案。


然而,由于业务节奏,本文在实验过程中仍忽略了一些问题。比如,ONNX 格式的模型部署在 Triton 中的性能为何不如部署在 Tornado Web 服务中,或许是 ONNX 在 Triton 中需要一些特殊的配置。另外,数据预处理和模型版本强耦合的问题仍未得到合理的解决方案,目前的处理方式仍有版本对不齐的风险。本文未对这些问题进行深入研究,留待后续探讨。

公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2023-08-07 15:072897

评论

发布
暂无评论
发现更多内容

你想学Python爬虫?看看这篇关于开发者工具神器的博客吧

梦想橡皮擦

5月月更

聊武侠、讲段子,为了帮小白入门Spring Boot,这书有多拼!

博文视点Broadview

大数据课程培训到离职转行这个过程你知道经历了什么吗

@零度

大数据开发

AI简报-FIX你的模型

AIWeker

人工智能 深度学习 5月月更 AI简报

【二级等保】二级等保怎么做?价格怎么样?贵吗?

行云管家

运维 网络安全 堡垒机 运维审计

什么?JDK8的ConcurrentHashMap 有 Bug

skow

Java 后端 并发

【LeetCode】调整数组顺序使奇数位于偶数前面Java题解

Albert

LeetCode 5月月更

关于加密通道规范,你真正用的是TLS,而非SSL

华为云开发者联盟

TLS 加密 ssl 加密通道 CA系统

小程序转APP,小团队也能实现数字化生态闭环

Speedoooo

APP开发 跨端开发 小程序容器 小程序转app 跨端运行

2022年中国消费金融数字化发展分析

易观分析

消费金融

深入解读SQL的聚集函数

华为云开发者联盟

sql GaussDB(DWS) 聚集操作 主键列

昆仑分布式数据库Sequence功能及其实现机制

KunlunBase昆仑数据库

国产数据库

文档管理:企业进步的重要因素

小炮

文档管理

Wallys-QCN9074 /802.11ax/4x4 MU-MIMO /6GHz wifi6E

wallys-wifi6

Wallys-Waterproof Enclosure Metal Outdoor

wallys-wifi6

IPQ4019 802.11ac

实例讲解FusionInsight MRS RTD 实时决策引擎在医保行业应用

华为云开发者联盟

数据湖 风控 医保 FusionInsight RTD 实时决策

web前端培训创建 NPX 工具

@零度

web前端开发

数据库系统最佳实践系列 --- 使用 prepared statement

KunlunBase昆仑数据库

国产数据库

MySQL-8.0 Group Replication 研究与改造汇总

KunlunBase昆仑数据库

国产数据库 MySQL 数据库

leetcode 451. Sort Characters By Frequency 根据字符出现频率排序

okokabcd

LeetCode 排序

数据库堡垒机品牌有哪些?买哪家划算?咨询电话多少?

行云管家

网络安全 信息安全 数据安全 堡垒机

EMQX+阿里云Tablestore多场景一站式IoT数据解决方案正式发布

EMQ映云科技

阿里云 物联网 一站式平台 emqx 5月月更

KunlunBase 查询优化(一)

KunlunBase昆仑数据库

MySQL 数据库 国产数据库

昆仑数据库可定制的数据分片方案

KunlunBase昆仑数据库

国产数据库

手把手教你搭个Frida + Sekiro Rpc框架

奋飞安全

三分钟让你了解 vue 中的父子通讯

CRMEB

java培训学习后找不到工作的原因你占了几条

@零度

JAVA开发

官宣|秒云与极狐(GitLab)达成战略合作,打造云原生DevOps一体化解决方案

MIAOYUN

DevOps 运维 云原生

KunlunBase 查询优化(二)Project 和 Filter 下推

KunlunBase昆仑数据库

国产数据库

KunlunBase 查询优化(三)排序下推

KunlunBase昆仑数据库

国产数据库

昆仑分布式数据库系统简介 之 SQL 标准兼容性和日常维护工作

KunlunBase昆仑数据库

国产数据库

复杂场景下的深度学习模型部署_机器学习/深度学习_作业帮技术团队_InfoQ精选文章