本文介绍了OR算法+ML模型混合推理能力建设思路及业务背景,此场景相比常规模型推理更具特殊性和复杂性,在工程实现上面临多维挑战,因此本文分别从性能、稳定性和扩展性三个维度分析问题和解法,并以推理框架架构演进为线总结了过去两年的分期迭代实践历程和收益,其中有一些较为通用的经验,希望能够给大家带来一些帮助或启发。
-
1 背景
-
2 面临的问题
-
2.1 性能问题
-
2.2 稳定性问题
-
2.3 扩展性问题
-
3 解决思路和方案
-
4 架构演进
-
4.1 进程内调用
-
4.2 跨进程调用
-
4.3 跨节点调用
-
4 未来展望
-
5 参考资料
1 背景
调度系统主要职责是需要在合适的时间以合适的方式将合适的运单分给合适的骑手,承载着海量的调度规模。为追求更高用户体验,需要在强时间约束下完成每一轮次的调度任务,对性能极度敏感;其中计算密集的运筹学算法(Operations Research,OR)和机器学习模型(Machine Learning,ML)是主要性能热点,如OR部分计算量最大的「路径规划算法」和ML部分计算量最大的「送达时间预估深度学习模型(ETR)」计算量占比60%以上,若使用远程CPU承载此计算,集群规模将在万台以上,长尾问题明显,运维压力和资源成本难以控制。
因此,在调度系统工程架构中引入GPU硬件并通过手写CUDA算子的方式来加速这些性能热点,在模块级取得了较好的加速效果[1],与此同时在系统级出现面向GPU新硬件如何高性能、高稳定性、高扩展性地实现OR+ML混合推理的新问题。围绕这些问题,调度系统组通过近两年的创新实践,逐步沉淀出一套与调度系统算法特性匹配的推理框架。本文将介绍该推理框架的演进历程,以及后续迭代计划。
2 面临的问题
为获取更高系统性能,当前工程架构的设计理念是“数据本地化”和“计算本地化”,让计算贴近存储,因此计算密集模块将优先使用本地GPU,实际应用过程会面临以下问题。
| 2.1 性能问题
由于缺乏计算任务统一接入和全局统筹的能力,导致系统在实际应用场景会遇到分片大小差异大、卡间任务分配失衡、独立Context频繁切换等情形带来调度耗时明显增长的性能问题。
| 2.2 稳定性问题
| 2.3 扩展性问题
3 解决思路和方案
深度学习领域依托推理框架可调度计算任务实现系统性能提升、可屏蔽硬件细节实现推理与应用解耦,我们也借鉴了这一成熟解决思路。本着复用原则我们分别调研了TFServing、TorchServe、TritonServer等行业主流推理框架,其中TritonServer是英伟达近七年持续迭代并全开源的推理框架,相比TFServing、TorchServe具有支持模型范围更广泛、内嵌功能更全面、代码结构更适合二次开发等优点,并且可获得NVIDIA官方和美团内部基研团队的技术支持,最终决定引入TritonServer推理框架并进行二次开发来解决上述性能、稳定性和扩展性问题。
TritonServer推理框架主要包含Server、TritonCore、若干预开发的Backend、状态监控等功能单元,通过分析和实验发现TritonCore和TensorRT Backend复用价值高,且TritonCore提供的C-API接口易于集成,因此我们确定了以下基础方案:基于TritonCore,通过TensorRT Backend接入深度学习模型(如ETR),开发OR Backend用于接入手写版CUDA代码(如路径规划算法)。
相比常规推理应用,基于TritonCore实现OR+ML的推理能力需要在自定义Backend开发、混合推理任务全局统筹、跨语言复杂系统设计等方面进行突破。
4 架构演进
| 4.1 进程内调用
通过Java Native Interface(JNI)将TritonCore接入Java语言开发的调度业务进程,填平了跨语言鸿沟并在此基础上进行二次开发,在功能和性能上实现突破。其核心内容如下:
1)功能突破
-
开发OR Backend,接入CUDA版路径规划算法,实现从0到1的突破; -
将 TritonCore内监控模块与美团监控平台(Raptor)打通,实现推理成功率、推理延迟等12项指标可视化; -
利用Valgrind等工具定位到TritonCore存在内存泄漏等问题,并联合英伟达专家修复了这些Bug。
2)性能突破
-
改进TensorRT Backend,优化ETR模型内存使用方式,实现模型推理性能超15%的提升; -
摸索混合推理任务全局统筹策略,实现整体性能提升8%。
| 4.2 跨进程调用
在功能和性能充分验证基础上,将TritonCore调用方式从进程内改造成跨进程,实现故障隔离,将异常恢复耗时从10+分钟压缩至10秒级。本次改造围绕三方面展开。
1)通信框架升级
采用gRPC+SHM(共享内存)替代原有JNI,SHM负责重量级的数据面传输,gRPC负责轻量级的控制面通信,在保持推理性能优势同时将调用方式升级成跨进程,当出现CUDA Exception时只需重启推理服务进程即可恢复,最小化底层故障的影响半径。
2)共享内存传输体系
-
相比纯RPC的传输方式,共享内存技术可减少2次数据拷贝和4次序列化与反序列化的开销,最小化跨进程数据传输开销; -
结合推理请求分片错峰特点,将共享内存池化,最大化复用共享内存空间,在不大幅增加内存开销的情况下即可支撑6000+ QPS高并发场景。
3)自动化运维
设计哨兵模块实现秒级发现底层异常并自动重启推理进程,相比进程内调用方式需要重启调度业务进程才能恢复的方式大幅缩短故障恢复时长(10分钟级->10秒级)。
-
调度业务进程为有状态服务,重启过程依赖本地缓存数据的拉取过程,通常耗时在10+分钟; -
推理服务进程为无状态服务,重启过程常规耗时约27秒,进一步优化启动过程后耗时后仅需10~12秒。
| 4.3 跨节点调用
为满足算法复杂度和单量规模逐年增长的需求,在本地跨进程调用基础上增加跨节点调用能力,实现突破单机算力瓶颈的低时延算力扩展;核心模块包含。
1)高性能流量路由
-
基于自适应均衡算法动态分配本地/远程流量,应用Power-of-Two-Choices算法避免远程节点间负载失衡,优化后同等资源的吞吐提升18%,TP99延迟缩短了25%; -
通过哨兵监控系统实时追踪本地推理进程的健康状态,当检测到本地推理进程故障时,系统自动将本地的推理请求切换到远程集群上,保障服务的可用性。
2)低延迟主备数据传输:RDMA降低传输延迟,MRPC兜底机制保障可用性
-
应用GPUDirect RDMA技术,实现主机内存←→远端GPU显存直接透传,端到端传输时延可优化60%; -
采用MRPC作为RDMA的备用链路,当RDMA链路发生故障时,可自动降级至MRPC链路,保障服务的可用性。
4 未来展望
// 参考资料 //
---------- END ----------
>> 点击这里报名<<
我们团队负责调度系统工程架构设计、性能优化和稳定性保障等工作。欢迎感兴趣的同学联系我们交流更多细节,也欢迎大家加入我们,联系方式[email protected]。
-----
原文始发于微信公众号(美团技术团队):OR算法+ML模型混合推理框架架构演进
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论