0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

爱奇艺深度学习平台对TF Serving毛刺问题的优化

Tensorflowers 来源:TensorFlow 作者:爱奇艺技术产品团 2020-12-17 16:48 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在点击率 CTR(Click Through Rate)预估算法的推荐场景中使用 TensorFlow Serving 热更新较大模型时会出现短暂的延时毛刺,导致业务侧超时,降低算法效果,为了解决这个问题,爱奇艺深度学习平台团队经过多个阶段的优化实践,最后对 TF Serving 和 TensorFlow 的源码进行深入优化,将模型热更新时的毛刺现象解决,本文将分享 TensorFlow Serving 的优化细节,希望对大家有帮助。

背景介绍

TensorFlow Serving是谷歌开源的用来部署机器学习模型的高性能推理系统。它主要具备如下特点:

同时支持 gRPC 和 HTTP 接口

支持多模型,多版本

支持模型热更新和版本切换

TensorFlow Serving
https://github.com/tensorflow/serving

爱奇艺深度学习平台上大量的 CTR 推荐类业务使用 TensorFlow Serving 来部署线上推理服务。

CTR 类业务对线上服务的可持续性要求很高,如果模型升级时要中断服务是不可接受的,因此 TF Serving 的模型热更新功能对这样的业务场景提供了很大的帮助,可以避免重启容器来做模型升级。

但是,随着业务对模型更新实时性的要求越来越高,我们发现,模型热更新时出现的短暂客户端请求超时现象(称之为毛刺现象)变成进一步提升实时性的一个比较大的障碍。

模型更新时的毛刺现象

先来看一下,

什么是模型更新时的毛刺现象?

下面这张图是我们在 TF Serving 代码中增加了 Bvar(https://github.com/apache/incubator-brpc/blob/master/docs/cn/bvar.md) 来查看内部请求的延迟情况。图中是延迟的分位比,延迟分位值分别为 [p80, p90, p99, p999],单位是微秒。

745748d6-357a-11eb-a64d-12bb97331649.png

从图中可以看到,在模型更新前后,p999的延迟都在 30ms以下。但是,在模型更新的瞬间,p999延迟突然抖动到 120ms+,持续了大概 10 秒时间,这就是毛刺现象,反应到客户端就是会产生请求超时失败。

为了完全解决这个问题,爱奇艺深度学习平台经过多个阶段的深入优化,最后将模型更新时的毛刺现象解决。

TF Serving 的模型更新过程

工欲善其事必先利其器,我们先来看看 TF Serving 内部的模型更新过程。

如上图,Source会启动一个线程来不断查看模型文件,然后将发现的新模型构建相应的 Servable 数据结构放到 Aspired Versions 的队列中去。

DynamicManager也会启动一个线程,来不断查看 Aspired Versions队列是否有需要处理的请求,根据配置的 Version Policy 来执行模型更新策略,最后通过 SessionBundle来执行模型的加载和卸载。

Version Policy 默认为 AvailabilityPreservingPolicy,该 policy 的特点是当有新的模型加入时,会保证至少有一个可服务的模型版本,当新版本加载完成后,再卸载旧版本,这样可以最大程度的保证模型的可服务性。

举例子来讲,如果只支持一个模型版本,当前版本是 2,如果有新的版本 3 加入,那么会先加载版本 3,然后再卸载版本 2。

接下来,详细看一下 TF Serving 的模型加载过程,主要分成以下几个步骤:

创建一个 DirectSession

将模型的 Graph 加载到 Session 中

执行 Graph 中的 Restore Op 来将变量从模型中读取到内存

执行 Graph 中的 Init Op 做相关的模型初始化

如果配置了 Warmup,执行 Warmup 操作,通过定义好的样本来预热模型

TensorFlow 的模型执行有个非常显著的特点是 lazy initialization,也就是如果没有 Warmup,当 TF Serving 加载完模型,其实只是加载了 Graph 和变量,Graph 中的 OP 其实并没有做初始化,只有当客户端第一次发请求过来时,才会开始初始化 OP。

问题的初步优化

从上面的分析来看,可以看到初步的解决方案,那就是做模型的 Warmup,具体方案如下:

配置模型 Warmup,在模型目录中增加 tf_serving_warmup_requests 文件

使用独立线程来做模型的加载和卸载操作,配置 num_unload_threads和 num_load_threads

模型如何做 Warmup 详细请参考 TF 的文档 SavedModel Warmup。

https://tensorflow.google.cn/tfx/serving/saved_model_warmup

第二项优化主要是参考美团的文章基于 TensorFlow Serving 的深度学习在线预估。

https://tech.meituan.com/2018/10/11/tfserving-improve.html

我们来对比一下优化前后的区别:

7526301a-357a-11eb-a64d-12bb97331649.png

可以看到,使用上面的优化,抖动的延迟减少了几个数量级,效果很明显。

问题的进一步优化

虽然上面的优化将模型更新时的毛刺降低到只有 120ms+,但是这个仍然会对客户端的请求产生超时现象,如果模型更新的频率不高,比如一天更新一次,那么基本上是可以接受的。

但是,如果业务对模型更新的实时性到一个小时以内,甚至更高,那么就必须进一步解决毛刺问题。我们不得不继续思考,剩下的这个毛刺是由于什么原因产生的?

TF Serving 是一个计算密集型的服务,对可能产生影响的因素,我们做了如下猜测:

计算原因:是不是新模型的初始化,包括 Warmup 的计算,影响了推理请求?

内存原因:是不是模型更新过程中的内存分配或释放产生锁而导致的?

或者两者都有?

计算原因分析

先来分析一下计算方面的原因,如果模型加载会影响到推理请求,那么能不能将模型的加载也用独立的线程来做?

经过调研 TF Serving 的源码,我们发现了这样的参数,原来 TF 已经考虑到这样的因素。

// If set, session run calls use a separate threadpool for restore and init // ops as part of loading the session-bundle. The value of this field should // correspond to the index of the tensorflow::ThreadPoolOptionProto defined as // part of session_config.session_inter_op_thread_pool. google.protobuf.Int32Value session_run_load_threadpool_index = 4;

通过配置 session_inter_op_thread_pool并设置 session_run_load_threadpool_index可以将模型的初始化放在独立的线程。

修改配置后,并做了相关验证,如下图。

757b8cae-357a-11eb-a64d-12bb97331649.png

验证的结论很遗憾,使用独立的线程来处理模型初始化并不能缓解毛刺问题。

从而,进一步分析了 TF Serving 的线程机制,发现计算部分主要集中在 TF 的 Inter 和 Intra Op 线程,在模型初始化线程独立出来后,原来的推理请求基本不会被影响到。

另外,经过分析还发现,TF 在执行 Restore Op 的时候会创建额外的线程池来恢复大的变量,于是尝试将 Restore 时的线程池去掉,发现仍然没有效果。

内存原因分析

先来看一下 TF 内存的分配机制,TF 的 GPU 显存是通过 BFC (best-fit with coalescing) 算法来分配的,CPU 内存分配是直接调用底层 glibc ptmalloc2 的 memory allocation。

目前平台上 CTR 类业务基本都是 CPU 推理,因此内存的分配和释放都是通过 glibc ptmalloc2 来管理的。

经过调研了解到,Linux glibc 的内存管理也是经过优化的,原来的实现是 dlmalloc,对多线程的支持并不好,现在的 ptmalloc2 是优化后支持了多线程。

如果要深入到 ptmalloc2 优化内存管理就比较麻烦,不过调研发现已经有了开源的优化方案,那就是谷歌的 Tcmalloc和 Facebook 的 Jemalloc。

Tcmalloc
http://goog-perftools.sourceforge.net/doc/tcmalloc.html)

Jemalloc
http://jemalloc.net/

Ptmalloc,Tcmalloc 和 Jemalloc 的优缺点网上有很多分析的文章,都指出 Tcmalloc 和 Jemalloc 在多线程环境下有比较好的性能,大体从原理上来讲是区分大小内存块的分配,各个线程有自己内存分配区域,减少锁竞争。

对比试验了三个内存分配器,实验结果如下图:

759f37ee-357a-11eb-a64d-12bb97331649.png

75f04a12-357a-11eb-a64d-12bb97331649.jpg

从实验结果来看,Tcmalloc 和 Jemalloc 对毛刺都有比较好的缓解,但是 Tcmalloc 会增加正常情况下的 p999 延迟;而反观 Jemalloc 的毛刺 p999 降到了 50ms 以下,正常情况下的 p999 比 Ptmalloc也有所优化。

看起来 Jemalloc 是一个相对比较理想的方案,不过在进一步的试验中发现,如果同时更新两个版本,Jemalloc 的 p999 毛刺会达到近 60ms,并且更新后会有一个比较长的延迟抖动期,会持续近一分钟时间,如下图:

7630b0ac-357a-11eb-a64d-12bb97331649.jpg

优化到这一步,如果对这样的延迟变化不敏感的话,基本就可以用 Jemalloc 来做为方案上线了,但对这样的效果仍觉得不是非常理想,因此进行了更深入的优化。

问题的最终深入优化

上面内存方案的优化效果提供了一个很好的启示和方向,毛刺的根本原因应该在内存的分配和释放竞争上,所以来进一步分析 TF 的内存分配。

TF 内存分配和释放的使用场景主要分成两个部分:

一部分是模型 Restore 时变量本身 Tensor 的分配,这个是在加载模型时分配的,内存的释放是在模型被卸载的时候

一部分是 RPC 请求时网络前向计算时的中间输出Tensor 内存分配,在请求处理结束后就被释放

模型更新时,新模型加载时的 Restore OP 有大量的内存被分配,旧模型被卸载时的有很多对象被析构,大量内存被释放。

而这个过程中,RPC 请求没有中断,这个时候两者的内存分配和释放会产生冲突和竞争关系。

因此设计了内存分配隔离方案:

将模型本身参数的内存分配和 RPC 请求过程中的内存分配隔离开来,让它们的分配和释放在不同的内存空间。

768b8496-357a-11eb-a64d-12bb97331649.jpg

结合模型的更新,线上模型一个容器里面最多就两个版本的模型文件,给每个模型版本各自分配了独立的内存池,用来做 AB 切换。

在代码的编写上,TF 刚好有一个现成的 BFC 内存分配器,利用 BFC 做模型参数的内存分配器,RPC 请求的内存分配仍然使用 glibc ptmalloc2 来统一分配,因此最后的设计是这样:

代码改动主要在 TF 的源码,主要是对 ProcessState,ThreadPoolDevice和 Allocator做了一些改动。

最后来看一下试验效果:

771935d4-357a-11eb-a64d-12bb97331649.png

从图中,可以看到模型更新后,延迟抖动很少,大约在 2ms,在实际的线上测试高峰期大概有 5ms 的抖动,满足业务需求。

总结

本文介绍了爱奇艺深度学习平台对 TF Serving 毛刺问题的优化,主要归纳如下:

配置模型 Warmup 文件来初预热模型

使用 Jemalloc 做内存分配优化

TF 模型参数分配和 RPC 请求内存分配分离

经过实践,每个方法都有进一步的优化,最后基本解决了模型热更新过程中的毛刺问题。

— 参考文献 —

1. TF ServingAarchtecture

https://github.com/tensorflow/serving/blob/master/tensorflow_serving/g3doc/architecture.md

2. BVar

https://github.com/apache/incubator-brpc/blob/master/docs/cn/bvar.md

3. TF WarmUp

https://tensorflow.google.cn/tfx/serving/saved_model_warmup

4. 美团基于 TensorFlow Serving 的深度学习在线预估

https://tech.meituan.com/2018/10/11/tfserving-improve.html

5. Google Tcmalloc

http://goog-perftools.sourceforge.net/doc/tcmalloc.html

6. Facebook Jemalloc: http://jemalloc.net/

责任编辑:xj

原文标题:社区分享 | TensorFlow Serving 模型更新毛刺的完全优化实践

文章出处:【微信公众号:TensorFlow】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 毛刺
    +关注

    关注

    0

    文章

    30

    浏览量

    16035
  • 深度学习
    +关注

    关注

    73

    文章

    5608

    浏览量

    124635
  • tensorflow
    +关注

    关注

    13

    文章

    336

    浏览量

    62374

原文标题:社区分享 | TensorFlow Serving 模型更新毛刺的完全优化实践

文章出处:【微信号:tensorflowers,微信公众号:Tensorflowers】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    开放平台OpenClaw接入

    配置接入OpenClaw服务器 a. 在服务器中执行以下命令接入小插件。 openclaw plugins install @ynhcj/xiaoyi@latest b. 在OpenClaw服务器
    发表于 04-08 14:33

    调用回收平台商品详情 API 接口指南

    ​  回收作为知名的二手电子产品回收与交易平台,其提供的 API 接口是开发者接入其服务的重要桥梁。本文将聚焦于 获取商品详情 的 API 接口,介绍其基本用法、关键参数、响应数据结构以及使用时
    的头像 发表于 03-30 17:13 509次阅读
    调用<b class='flag-5'>爱</b>回收<b class='flag-5'>平台</b>商品详情 API 接口指南

    2026年低代码平台市场综合评测:国内10大低代码平台深度解析

    至24周。本文结合Gartner、中国信通院等权威机构数据,全面解析低代码市场现状,并深度测评国内10大主流低代码平台,为企业选型提供精准参考。 一、2026年低代码平台市场综合数据 1.全球
    发表于 03-30 16:02

    Onsemi FQT1N80TF - WS N - 通道MOSFET深度解析

    Onsemi FQT1N80TF - WS N - 通道MOSFET深度解析 引言 在电子设计领域,MOSFET作为关键元件,广泛应用于各种电路中。Onsemi的FQT1N80TF - WS N
    的头像 发表于 03-30 14:40 278次阅读

    Onsemi FQT1N80TF-WS N沟道MOSFET深度解析

    Onsemi FQT1N80TF-WS N沟道MOSFET深度解析 在电子设计领域,MOSFET作为关键元件,广泛应用于各类电路之中,其性能的优劣直接影响着整个系统的运行效率与稳定性。今天,我们就来
    的头像 发表于 03-29 15:45 449次阅读

    开放平台平台功能

    平台的高效编排方式。开发者可通过该模式基于鸿蒙Agent通信协议快速、便捷地将成熟的第三方智能体对接至小开放平台,实现分发与调用,提升平台的场景覆盖能力。该模式适用于同时具备鸿蒙端应
    发表于 01-30 15:24

    开放平台快速创建鸿蒙智能体

    1.登录小开放平台,进入小智能体平台页面,点击立即体验,进入创建页面。 2.点击左上角【+创建智能体】按钮,即可进入智能体创建流程。 3.击【+创建】后,会进入到标准创建页面,在这
    发表于 01-19 11:00

    穿孔机顶头检测仪 机器视觉深度学习

    ,能适用恶劣工况,在粉尘、高温、氧化皮等恶劣环境中均可正常工作。 测量原理 利用顶头与周围的物质(水、空气、导盘等)红外辐射能量的差异,用热成像相机拍摄出清晰的图片,再通过深度学习短时间内深度
    发表于 12-22 14:33

    DAC8560:16位超低毛刺电压输出数模转换器的深度剖析

      在电子设计领域,数模转换器(DAC)是连接数字世界和模拟世界的关键桥梁。今天,我们将深入探讨TI公司的DAC8560,这是一款16位、超低毛刺、电压输出的数模转换器,具有诸多出色的特性,适用于
    的头像 发表于 11-28 13:44 787次阅读
    DAC8560:16位超低<b class='flag-5'>毛刺</b>电压输出数模转换器的<b class='flag-5'>深度</b>剖析

    企查平台企业详情数据 API 接口使用指南

    ​  引言 企查作为国内知名的企业信息查询平台,汇聚了海量的企业工商信息、经营数据等。对于开发者或数据分析师而言,若能通过其开放的 API 接口获取这些结构化数据,将极大地提升工作效率和应用开发
    的头像 发表于 11-20 14:48 1540次阅读
    <b class='flag-5'>爱</b>企查<b class='flag-5'>平台</b>企业详情数据 API 接口使用指南

    HarmonyOS 6正式发布,超能小一用就爱!

    景终端设备上带来真人感对话、小看世界、小帮接、AI修图、小慧记等行业领先的AI智慧体验,深受消费者喜爱。升级到HarmonyOS 6后,小再进阶超级助理,支持更多华为终端设备,
    的头像 发表于 10-22 17:43 1715次阅读

    锂离子电池毛刺控制的要求及检测

    锂离子电池在完成装配封口前最怕金属粉尘、杂质、水分和毛刺。极片毛刺会引起的内部短路,因此涉及到锂电池的安全问题,是锂电池制造过程中非常关键的管控项目。毛刺的控制也一直是业内人士关注的焦点。美能光子湾
    的头像 发表于 08-05 17:54 1889次阅读
    锂离子电池<b class='flag-5'>毛刺</b>控制的要求及检测

    奥拓电子亮相CITS 2025影视拍摄技术创新与趋势论坛

    近日,由奥拓电子和中广国际联合主办的CITS 2025“第二届影视拍摄技术创新与趋势论坛”在北京希尔顿酒店举行,共有来自中影、图仕、北京电影学院等单位的150余位影视拍摄领域
    的头像 发表于 07-30 09:07 1106次阅读

    铝铸件去毛刺加工,用SycoTec浮动去毛刺主轴

    在现代制造业中,铝铸件因其质量轻、强度高、耐腐蚀性好等性能,被广泛应用于航空航天、汽车制造、电子设备等众多领域。然而,铝铸件在生产过程中,不可避免地会产生毛刺。这些毛刺不仅影响铝铸件的外观质量,还可
    的头像 发表于 07-16 09:40 566次阅读
    铝铸件去<b class='flag-5'>毛刺</b>加工,用SycoTec浮动去<b class='flag-5'>毛刺</b>主轴

    存储示波器的存储深度对信号分析有什么影响?

    信号(如电源毛刺、EMI干扰) 需求:高采样率(≥5倍信号频率) + 大存储深度(≥10Mpts分段存储)。 优化:启用外部触发或增加分段存储段数。 2. 使用高级存储功能 分段存储
    发表于 05-27 14:39