AI实践哪家强?来 AICon, 解锁技术前沿,探寻产业新机! 了解详情
写点什么

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

  • 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 中需要一些特殊的配置。另外,数据预处理和模型版本强耦合的问题仍未得到合理的解决方案,目前的处理方式仍有版本对不齐的风险。本文未对这些问题进行深入研究,留待后续探讨。

2023-08-07 15:074132

评论

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

最好用的办公套件Microsoft Office 2024 for mac中文版

晨光熹微

YashanDB数据库分页查询优化实用教程

数据库砖家

YashanDB数据库功能与应用场景全面介绍

数据库砖家

YashanDB数据库基础架构部署最佳方案分享

数据库砖家

YashanDB数据库基础知识:初学者必看指南

数据库砖家

YashanDB数据库事务隔离级别及实际应用方案

数据库砖家

Yate for mac 音乐标签管理工具

晨光熹微

Mac电子邮件客户端Mimestream

晨光熹微

YashanDB数据库使用过程中遇到的挑战及解决办法

数据库砖家

(网页CAD插件)WEB CAD二开焊接符号

WEB CAD SDK

全球 DaaS 市场研究报告上线,聚焦数据服务化趋势与行业演进路径

tapdata

DaaS市场研究报告 数据即服务报告 数据服务行业解决方案 什么是数据即服务 数据服务化趋势

将两台 Mac 显示器设置为单个屏幕

柠檬与橘子

打破交互困局:科大讯飞这样出手

脑极体

AI

YashanDB数据库分布式事务设计与应用实践

数据库砖家

YashanDB数据库企业应用部署实例分析

数据库砖家

YashanDB数据库全方位性能优化及实战经验分享

数据库砖家

4年磨砺,今朝开源!清源SCA开源版重磅登场!

安势信息

开源 安势信息 清源SCA开源版

Mac上软件闪退(意外退出)的解决方法

柠檬与橘子

强大的文件查找器Find Any File for mac

晨光熹微

YashanDB数据库升级注意事项及版本兼容性分析

数据库砖家

Trae - 非科班在建模比赛中的 AI 编程手|AI编程社知识库精选

火山引擎开发者社区

Trae AI 编程

YashanDB数据库分布式事务实现与挑战解析

数据库砖家

Mac上好用的文件提取工具File Juicer

晨光熹微

玩转 MCP 第二弹|一文教你用 Trae 实现网页自动化测试

火山引擎开发者社区

MCP Trae

菜单栏上面的文件管理器File Cabinet Pro for mac

晨光熹微

应用深度清理卸载工具App Cleaner & Uninstaller Pro中文版

晨光熹微

YashanDB数据库分布式架构设计实战指南

数据库砖家

YashanDB数据库事务处理与数据一致性保障

数据库砖家

YashanDB数据库事务管理详解,保证数据一致性

数据库砖家

Mac超强全能视频播放器Infuse Pro中文版

晨光熹微

Pandabuy崛起,系统搭建秘诀在这!

tbapi

淘宝代购系统 Pandabuy 反向海淘系统 pandabuy系统

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