Amazon SageMaker 机器学习推理综述

e124459e770d583d3841bd7b5127d146.gif

模型推理是将机器学习模型应用到业务数据并提供对该数据的洞察,其经常在业务系统中作为一个模块提供服务,作为整个机器学习生命周期中的一个必不可少的阶段,它的重要性毋庸置疑。不同的 ML 任务和业务应用场景下对于模型推理的诉求也是不同的,Amazon SageMaker 在模型推理方面提供了众多的功能来满足不同场景下的需求。对于任何一种推理的场景,机器学习工程师都希望能尽量提升推理服务器侧的吞吐以及降低推理的整个延迟,接下来我们从工程角度讨论一下机器学习推理这个话题。

01

多维度的 ML 推理的诉求

离线推理和在线推理

简单来讲,离线推理和在线推理有如下的区别:

▌在线推理的实现复杂度要比离线推理高;

▌在线推理的金钱成本比离线推理高;

▌离线推理对延迟一般没有很严格的要求。

需要注意的是,并不是所有的业务场景都需要在线推理。

1b758e1f4049f71a1ce064b773287727.png

对于时间序列预测和传统的表格数据预测类任务,他们的大部分任务用离线推理;对于搜索,推荐系统和计算广告这三大领域,他们的大部分任务需要在线推理,有些任务可以用离线推理;而对于计算机视觉,自然语言处理,语音处理和异常检测这些领域,他们的任务是离线推理还是在线推理更多是取决于具体的业务需求。

在某些情况下,可以把在线推理降级为离线推理(来自 Netflix 推荐系统的实践),比如在线推理服务发生故障且短时间不能恢复时,可以用预先保存的离线推理的结果来作过渡。

同步推理和异步推理

简单来讲,同步推理和异步推理的语义上的区别是:发起推理请求的一方得到的响应是否是推理的结果。一般来说,异步推理会使整个数据处理流程变得复杂(进而导致架构也变得复杂),因此在决定采用异步推理之前,要想清楚同步推理是否能满足你的业务需求。

常见的使用异步推理的场景是:

▌缓解上游的业务服务器和下游的推理服务器的处理速度的严重不匹配;

▌避免推理时间太长导致对请求发起侧的长时间阻塞;

▌绕过推理服务侧对最大请求 payload size 的限制。

Amazon SageMaker 提供的异步推理功能的架构如下:

8498690c2e08e7561f0402fe2d3dd2e8.png

延迟敏感

延迟敏感指的是从终端用户侧,或者从当前处理节点,或者从推理请求发起侧来说,需要很严格的分位数延迟(很多客户不只是看平均延迟以及中位数延迟,还关心 P90/P99 的分位数延迟)。

下面给出几个对延迟比较敏感的业务/领域:

▌DSP 竞价广告场景,可接受的延迟经常是 10ms 以内。

DSP 的上游经常是 ADX 广告网络联盟,ADX 的竞价最大延迟要求是 100ms(即从 ADX 把竞价请求从自己那侧发出到收到 DSP 竞价结果的整个延迟要求在 100ms 内)。DSP 把它与 ADX 之间通信的网络往返带入的抖动也会考虑进去(比如通常情况下,DSP 与上游的 ADX 之间的网络往返延迟是 20ms,但是偶尔在网络比较差的情况下这个网络往返延迟可能会达到 60ms,抖动就是 40ms),因此 DSP 希望自己从收到竞价请求到发送完竞价结果的整个延迟控制在 10ms 内,这样即使在网络抖动比较差的情况下,也不会影响 DSP 有效参与到 ADX 的广告竞价中。

▌推荐系统场景,可接受的延迟一般是100ms~500ms。

这里的延迟一般指的是推荐服务器从接受到上游的曝光请求到把推荐结果发送回去的整个延迟。在实际的推荐系统的项目中,也经常会遇到客户对于排序任务的延迟要求是 100ms 级别,即把特征拼接好的召回结果发送出去到收到排序模型的打分结果这个过程的延迟(不包括召回结果集的特征拼接开销)。

▌除了搜推广领域,同声机器翻译、聊天窗口或者评论发布的实时敏感词过滤、自动驾驶中的图像语义分割等这些场景对延迟也比较敏感。

推理架构的拓扑常见有两种方式:

▌All in one process 即单体服务:

对于延迟最敏感的业务比如对接 ADX 的 DSP 竞价广告就经常使用这个拓扑(在实际的对接 ADX 的 DSP 项目中见到的也都是这样的拓扑)。

▌推理服务从整个业务逻辑中解耦出来作为单独的服务提供:

从软件设计哲学来看,这个拓扑是最佳的(因为它降低了软件复杂度,更便于推理模块的迭代更新、 autoscaling 和维护管理),除非它无法满足延迟要求。

金钱成本

金钱成本在任何时候任何企业都会考虑的,我们可以从多个视角来看如何节省金钱成本。

▌视角一:从推理的加速方法和推理服务侧的 QPS 优化方法入手(对于这两种方式,我们后面会专门讲解)

▌视角二:对于在线推理的场景,SageMaker 提供了如下几种方案来节约金钱成本(下面的三个方案今后都会有专题来介绍,这里只需要简单了解一下):

8bd0f3b1c6d2a4d8e182c56a1b5fc1fb.jpeg

模型之间的依赖

在有些比较复杂的 ML 任务中,会涉及到多个模型,比如人脸识别的任务如下面所示(图片引用自这里):

ed7cb5e9514f30010ae8ec9bbdaa89ea.png

它涉及到如下的步骤(下面的#A、#B、#C三个步骤会涉及到三个模型):

A.先用人脸检测算法来检测是否有人脸并定位人脸;

B. 接着进行人脸对齐(一般使用人脸关键点检测来实现,把人脸转换为标准脸);

C. 接着对标准脸进行人脸特征向量提取;

D. 最后把人脸特征向量与资料库中保存的可信的人脸特征向量进行相似度对比,找到相似度分数最高且超过阈值的对应的那个人。

模型之间的依赖关系的强弱可以细分为:

▌模型之间直接前后强依赖

上游模型推理后的输出就是下游模型推理需要的输入(对于这种情况,SageMaker inference pipeline 是一个不错的选择)。比如 OCR 的二阶段 pipeline 实现方式:文字检测(找到文字 bbox 并抠图)——>文字识别(把抠图中的文字找出并输出为字符串)。

处理链路上模型之间有先后的处理顺序

对于这样的情况,有两种思路:

A.模型推理单独放在 SageMaker 中,其他的逻辑放在 SageMaker 外面;

B.所有的逻辑都放入 SageMaker 中,用 inference pipeline 实现。

理论上可以把复杂的处理过程切分为多个小的阶段,根据下一个阶段需要的输入来构造当前阶段的输出。在这样的方式下,就可以使用 SageMaker 的 inference pipeline。但是不建议这样做(尤其是使用 SageMaker Endpoint 做线上推理的时候),因为 inference pipeline 的本质上还是希望这个 pipeline 中的每个组件都是模型推理部分或者模型的特征工程处理/数据预处理/数据后处理。因此对于这样的情况,建议还是使用方案 #A,也就是用一个上游的组件/服务来处理/编排这些逻辑,把涉及到模型推理相关的放在 SageMaker 里面。

模型之间是层次依赖关系

模型之间是层次的关系。比如对于图片的层次分类,有一种方案就是作为 pipeline 来建模:第一个层级用单个模型来预测图片属于哪个一级类别;第二个层级是多个模型,每个一级类别用一个模型,预测图片属于哪个二级类别;依次类推直到第 N 个层级(用层次分类建模而没有选择把所有最细类别单独一个 flatten 模型建模,原因是用层次建模的话,模型学习起来的难度要相对低一些,但是会有误差传递问题)。

针对这种情况,如果是线上推理,可选择的方案是:

A. Inference pipeline 方案:第一个容器放第一层级的单模型,第二个容器放第二个层级的多个模型,以此类推。

对于 CPU 推理实例,建议要让推理实例的内存足够大,可以容纳所有这些模型。

对于 GPU 推理实例,如果 GPU 实例只有1个 GPU 卡,那么 GPU 将是独占的,请求在 GPU 上处理时变成串行的(这里指的是不用 vGPU 或者 Nvidia MPS 或者手动 CUDA 高并发编程的情况);如果想并发的处理多个 inference pipeline 请求,且每个容器中的所有模型需要的总的显存小于单个 GPU 卡的显存,并且容器数量小于单机 GPU 卡的数量,可以使用多卡的机器并且给每个容器绑定上不同的 GPU 卡。

拓扑参考如下:

89e9cde37672f4b362c36f584025ddb3.png

B. Multi-model Endpoint(MME)方案:第一个层级的单模型放在 SageMaker Endpoint,第二个层级的多模型放在 MME,第三个层级的多模型放在另一个 MME,以此类推;或者把这些不同层级的所有模型都放在一个 MME 里面。

拓扑参考如下:

9ff245445be52120187e677585ebc123.png

或者:

86ef4640aacf3a6e7919fd6a7f77822f.png

C. All in one process:把所有不同层级模型放在一个进程中,自己写逻辑来做推理。

对于模型之间是层次依赖关系这样的场景,如果是延迟不敏感的业务并且推理实例的内存或者 GPU 显存够用,建议使用上面提到的 inference pipeline 方案;如果延迟不敏感但是推理实例的内存或者 GPU 显存不够用,那么可以考虑上面提到的 MME 方案。如果是离线推理,inference pipeline 和 All in one process 的方案都可以选择(细节同上),更建议使用 inference pipeline。

02

推理服务器侧的 QPS 优化

只要是服务器侧,一定会关心吞吐量,推理服务器侧也不例外。而 QPS 是吞吐量的一个重要指标(吞吐量的另一个重要指标是并发数),也是我们这里主要讨论的指标。单位时间内可处理完的请求数就越多,那么单个请求处理折算后的金钱成本就越低。

dfe99df1b658a0d2dda423b46af9fb36.jpeg

03

模型推理的加速

模型推理的加速本身是一个优化问题,我们需要找到影响速度的 bottleneck,我们需要知道对于一个业务系统做推理优化涉及到的每个影响因素。我们通过对一个请求的整个处理过程的拆分提取出如下的这些重要的影响因素(从 high level 到 low level):

架构拓扑

▌服务之间的网络延迟

▌服务本身的处理效率

▌通信 API 的效率

▌序列化与反序列化的效率

▌模型本身的优化

▌推理设备的选择

▌推理框架本身的优化

我们来对每个影响因素进行详细解读。

架构拓扑

架构的不同拓扑决定了一个请求的处理路径的长度。一般来说,请求的处理链路越长,延迟也会越高。因此这里需要权衡,是选择使用微服务的设计思路还是需要追求最低的延迟。大部分场景下,我们都是建议在延迟可以接受的情况下用微服务这样的设计。

场景举例:

▌DSP 竞价广告业务, 几乎都是 all in one process 的方式。

DSP 竞价广告的工作性质决定了它对整个端到端延迟(一般要求 10ms 内)要求非常严格。

▌其他大部分场景, 模型推理服务可以考虑从业务服务器逻辑中单独剥离出来。

比如使用 SageMaker Endpoint for built-in TFServing 做推荐系统的排序模型的线上推理的话,一个建议的架构拓扑是:

Recommender server(召回逻辑可以在 Recommender server 中实现,也可以单独剥离出去作为一个服务)—> SageMaker Endpoint —> Nginx —> guincorn (optional) —>TFS

服务之间的网络延迟

网络延迟也是经常需要考虑的点,尤其是请求发起端和推理服务端不在一个区域或者是两个不同的云服务提供商的情况。如果请求发起端和推理服务端都在同一个 Amazon 的区域, 那么他们之间的网络往返延迟是 10ms 以内。因此,整个业务系统的每个组件的置放以及这个置放导致的网络延迟是否在可接受的范围,甚至网络加速方案都需要考虑进来。

▌比如有的客户由于种种原因就会有业务系统的上游组件在云厂商 A,下游组件在云厂商 B。这个时候两个云厂商之间的通信要走公网,那这个延迟就是不可控的,这个时候用 Amazon Direct Connect 专线是一个可选的加速方案。

服务本身的处理效率

在整个请求的处理过程中会涉及到除了模型推理服务外的其他服务,不管是什么性质的服务,服务本身的处理以及代码编写是否高效都是非常重要的。另外,对于推理服务来说,它是一个计算密集型的任务,因此把一些复杂的预处理的逻辑放在它的上游客户端更好(有点像瘦服务端的意思)。

▌如果还在模型实验阶段,并且对数据预处理逻辑的改动比较频繁,这个时候为了尽量不让上游客户端感知,把复杂的预处理逻辑放在推理服务端侧做过渡也可以接受,但是当模型稳定以后,也就是模型持续在线上稳定运行且不需要修改预处理逻辑以后,可以考虑把这个预处理逻辑放在上游客户端。

真实的例子:

  • 比如 Redis 可以作为 online feature store 来提供特征的获取, 那么 Redis 集群的性能以及 Redis 客户端的使用方式就很重要。之前遇到过一个场景,要获取500个 itemid 的特征, 相比使用 Redis 客户端发出了500个请求,更好的方式是使用 Redis 的 pipeline 功能在一个请求中发送多个命令。

  • 比如想拆分一个 payload 很大的请求为多个小的请求,使用 goroutine 同时发送多个请求给推理服务侧。为了更好的并行,这里设置 goroutine 可使用的 CPU 数量为当前机器的总的 CPU 数量或者物理 core 的数量是一个更好的选择。

  • 比如被频繁调用的某个函数中会使用循环体来对一个变量进行相对复杂的操作,而该变量本质上是一个常量(比如 feature 字典的初始化或者 Vocabulary 字典的加载)。那最好的处理方式是把这个循环体提取到函数外面,且把该变量作为一个全局变量执行一次初始化。

  • 比如发送一个 JPEG 图片到模型推理侧进行 JPEG 解码并推理,比在发送侧对 JPEG 图片解码后再发送给模型推理侧进行推理更好(JPEG 解码后的 payload 要远大于 JPEG 图片本身的 payload,从而带来更多的网络发送延迟和接受延迟)。

通信 API 的效率

不同的通信 API 的效率有很大的差别。对于推理服务的两种常见的 API 是 gRPC API 和 REST API,这两种 API 的简单对比如下:

gRPC 基于 HTTP 2,REST API 基于1;

▌gPRC 默认使用 Protocol buffers 来序列化负载数据,REST API 主要依赖 JSON 或者 XML 来收发数据。

▌相对于 REST API 代码的简单易用,使用 gPRC 的代码要复杂一些,可读性差一些。

是不是任何情况下,gRPC 的性能都比 REST 要高?

▌通过实际项目发现,当请求的 payload 比较小(比如 200KB), REST API 通常会快一点;当请求的 payload 比较大(比如 4MB),gRPC API 会比 REST API 快很多。

序列化与反序列化的效率

数据在进行网络传输时,需要在发送侧把内存中的对象序列化为适合在网络上传输的字节流,对应在服务侧需要把从网络上接受到的字节流反序列化为内存中的对象以方便程序操作。不同的序列化和反序列化的方法的效率也不一样:比如对 Ndarray 做 JSON 序列化与反序列化比对 Ndarray 做 String 序列化和反序列化的性能差。

模型本身的优化

这里从模型层面入手考虑如何能降低纯粹的模型推理时间,有下面三种思路可以尝试:

c4d1d23777c3baa8bb12a5fb1aac3f74.jpeg

除了模型压缩方法中可以做量化,常见的模型编译工具比如 TensorRT 和 TVM 也会做模型参数的精度量化。从上面的表中可以看出,模型编译和模型压缩追求的都是加速模型推理,尽管使用方法非常不同。相对于模型编译,模型压缩使用起来要更复杂。有些情况下,两者可以结合使用,比如先把大模型用知识蒸馏变成小模型,然后在使用 TVM/TensorRT 进一步优化。在 SageMaker 中,通过使用 SageMaker Neo 功能可以简单的通过设置参数就可以对某些模型比如图像分类模型和 XGBoost 模型针对目标硬件上做编译,而不需要关心具体细节。

一般来说,如果模型运行在 server 侧,并且在纯的模型推理时延可以接受的情况下,模型压缩或者模型编译用的不多,但是如果模型运行在端侧(资源受限)的话,模型压缩或者模型编译几乎是一定需要的。

推理设备的选择

用作模型推理的设备有很多种,在亚马逊云科技上的可选的设备有 CPU、自研机器学习推理专用芯片 Inferentia、EIA(EIA 支持直接附加到 SageMaker Endpoint 的 CPU 实例上),而不同的设备还有很多不同的细分类型。

在进行推理设备选择的时候,我们应该综合考虑速度和价格成本:

不同特点/业务的模型在不同的设备上的性价比不一样。

▌推理实例的带宽越大,同样 payload 大小的请求和响应的收发耗时就越小(SageMaker Endpiont 的 cloudwatch 指标 overhead latency 包括了这个耗时)。

▌训练时使用 GPU,推理时完全可以使用 CPU(只要纯推理延迟能满足要求)。

▌如果整个推理链路性能的瓶颈或者说 latency 的 main part 并不是纯推理时间,那么一般可以考虑用 CPU 做推理,这样性价比更高。

▌模型的推理本身是计算消耗型的,因此如果选择 CPU 实例的话,需要选择计算优化型的而不是内存优化型的(发现经常有客户选用 M5/M4 系列而不是 C5 系列,他们的推理速度差别挺大的)

推理框架本身的优化

推理框架本身能提供的一些优化也是非常重要的,这里的优化指的是框架本身的实现的高效性以及提供的一些可以配置的优化选项。当前业界比较成熟的推理框架是比如 Triton、Tensorflow Serving(简称 TFS)等。当使用 GPU 实例做推理时,可以优先尝试 Triton on SageMaker;还可以尝试先用 TensorRT 对模型做编译,然后用 Triton on SageMaker 做 serving。

举例:对于 TFS,如果在 CPU 实例上进行推理,可以通过设置如下的参数来加速(这些相关的参数或者环境变量如何设置,之后会详细介绍)。

  • TFS inter op 和 intra op 的并行度设置

  • MKL-DNN 的相关设置比如线程池数量,以及线程与 CPU 的 bind 策略

04

总结

本篇文章从相对宏观的角度来介绍了在 SageMaker 中的机器学习推理,相信大家已经对 SageMaker 在推理场景提供的能力有了大致的了解,也对 SageMaker 上进行推理优化有了一定的的认识。接下来我会用另一个文章来介绍一个具体的场景,即 SageMaker 模型部署服务中的内置 TF Serving 模型推理优化。

本篇作者

08f08f821708a45aa4c2a4fa81a7a083.jpeg

梁宇辉

亚马逊云科技机器学习产品技术专家,负责基于亚马逊云科技的机器学习方案的咨询与设计,专注于机器学习的推广与应用,深度参与了很多真实客户的机器学习项目的构建以及优化。对于深度学习模型分布式训练,推荐系统和计算广告等领域具有丰富经验。

57cd846b3c11d19a8f736c62581015b1.gif

da82a412e6b032f735a0a8ba4b4ac562.gif

听说,点完下面4个按钮

就不会碰到bug了!

15209e75a3d028dc27e559c704453ce1.gif

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值