Expedia Group借助模型库加速推理管道

2023年10月19日 由 alex 发表 207 0

在Expedia Group ™,我们通常将机器学习模型部署为不同的服务,由其他服务和应用程序远程调用以检索 AI 预测。这种设置非常有用,因为它将机器学习生命周期与公司中运行的其他软件完全解耦,为机器学习科学团队在生产中部署和试验其模型提供了更大的灵活性。


但在某些情况下,进行远程调用来调用机器学习模型的额外成本并不是轻易能够承受的。例如,我们的一些系统每秒可能处理数百万笔交易。在具有如此高吞吐量的工作流程中引入人工智能预测可能需要在昂贵的硬件上扩展模型服务器的数百个新实例。另一个例子是可以处理大量数据以提供更高准确性的模型,但由于网络数据传输引起的延迟,客户端服务被迫限制其推理请求的大小。


为了适应此类用例,Expedia Group ML Platform团队推出了一项新的创新功能,可最大限度地减少在生产工作流程中引入机器学习模型的延迟:模型库。


什么是模型库?


除了将机器学习模型部署为服务之外,ML Platform 还可以将这些模型作为库进行分发,这些库可以轻松附加到 Expedia Group 运行的任何服务。这是如何运作的?


与大多数大型企业一样,基于 JVM 的语言(Java、Kotlin、Scala...)经常用于开发 Expedia Group 运行的应用程序。因此,ML Platform 团队在内部开发并分发了一个 Java 框架,专门用于在生产系统中执行机器学习推理工作流程。


训练模型后,其生成的工件将捆绑到一个存档中,并发布到我们的模型存储库中。开发人员可以使用推理框架从存储库下载这些档案,将其模型嵌入到应用程序流程中,然后运行推理,只需几行代码即可获得预测。很快,开发人员还可以在编译时将特定版本的模型库附加到他们的应用程序中。


这里的关键是模型推理是在本地发生的,与运行服务的 JVM 位于同一进程中。


1


JVM 上的模型推理


Java 如何运行模型推理?大多数机器学习运行时已经提供了 Java API 来调用其本机库进行推理,与 Python API 或模型服务器(例如 TensorFlow Serving)使用的库相同。


从 Java 进程调用本机库的成本不仅可以忽略不计,而且还利用了从 JVM 调用它的所有优点。例如,Java 支持良好的多线程,因此很容易实现模型推理并发,而使用 Python 则很难实现,因为它有GIL。没有什么可以阻止机器学习科学家继续用 Python 构建和训练他们的模型,只要它们以与语言无关的格式保存,许多流行的机器学习运行时就是这种情况。


如上图所示,我们的推理框架遵循模块化架构,其中通过自动注册应用程序类路径中存在的所有模块来提供计算能力。该平台支持的每个机器学习运行时都作为一个独特的模块进行分发,包装了其 Java 绑定和本机库。开发人员只需包含对框架的依赖项并选择所需的运行时模块即可开始将机器学习模型嵌入到其应用程序中并在本地生成预测。


技术挑战


以下部分说明了使用模型库启用本地推理时遇到的一些挑战,以及我们如何解决这些挑战。


大型或计算密集型模型


通过让应用程序开发人员仅选择他们需要的机器学习运行时模块,我们可以防止通过包含通常非常大的不必要的本机库来增加应用程序的大小。例如,TensorFlow JAR 约为 100Mb。


但众所周知,机器学习模型的大小也可以在相对较小到极大之间变化,通常取决于其参数数量。不仅需要下载模型库并将其存储在磁盘上,而且其模型也应该适合内存。此外,运行推理可能会占用大量 CPU(或 GPU),具体取决于模型的复杂性。因此,主机应用程序需要分配和扩展足够的资源以适应其计划运行的模型。


应用程序还可能加载多个模型,无论是生成不同类型的预测还是对模型的多个变体进行在线评估。同样,需要事先考虑这一点,并相应地调整资源。


在不支持 Java 的运行时上训练的模型


虽然只有少数机器学习运行时不在其本机库之上提供 Java API(例如 scikit-learn、LightGBM 等),但可能需要为使用其中之一训练的模型构建一个库。在这种情况下,你应该将模型工件转换为与 Java 兼容的另一种可移植格式。


ONNX 是一个不错的选择,因为 Python 中不仅已经有很多实用程序库可以负责将模型转换为它(例如onnxmltools),而且它也被认为是模型最快的机器学习运行时之一推理(我们观察到一些模型只需将其转换为 ONNX 即可运行速度提高 6 倍)。


需要注意的是,ONNX 模型返回的结果与其原始版本之间可能会出现一些差异。这可能是因为 ONNX 中的大多数计算都使用 32 位浮点,而原始运行时使用的是更高的精度。这些差异对于预测的整体准确性通常是不明显的,但你仍然可能需要在投入生产之前运行一些额外的验证。


用Python编写的数据预处理/后处理代码


通常,输入数据在输入模型之前需要进行处理,并且预测在返回给用户之前可能还需要进行额外的调整。机器学习科学家倾向于编写一些任意的 Python 代码,而不是改变已经训练好的模型。这使得模型的执行与 Python 高度耦合,而 Python 的性能本质上低于 Java 或 C++ 等其他语言。


一种解决方案是将 Python 代码转换为 Java 并将其作为库分发。然后,你可以在训练过程中使用 Python 到 Java 的桥(如JPype )从 Python 调用 Java 代码,并在主机应用程序中导入相同的代码以进行推理。这种方法的一个缺点是机器学习科学家现在需要编写和维护 Java 代码,这是一种他们可能不熟悉的语言。此外,即使 Java 例程非常快,它们也缺乏对向量化操作的方便支持。


更好的解决方案是使用机器学习运行时重写此逻辑,该运行时可以生成用于本机处理数据的模型。例如,可以使用TensorFlow NumPy API将 NumPy 代码转换为 TensorFlow 模型。这是否意味着你需要执行最多三个模型才能获得预测(即预处理、训练模型和后处理)?你也许可以将所有这些模型合并为一个模型,具体取决于你选择的运行时。例如,Keras 允许你将多个 TensorFlow 模型合并为一个。ONNX 还公开了有趣的组合功能。然后可以将生成的工件嵌入本机并执行,从而提供最佳性能。


2


结论


将模型嵌入到更贴近客户的应用程序中可以显着改善用户体验,同时最大限度地发挥在工作流程中添加机器学习的优势。但它也有其挑战,在选择这种方法之前需要仔细考虑。建议仅当高性能和低延迟对于解锁用例至关重要时才使用模型库,而使用标准模型服务器部署无法实现或成本太高。


文章来源:https://medium.com/expedia-group-tech/speeding-up-inference-pipelines-with-model-libraries-at-expedia-group-6b345b532898
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
热门职位
Maluuba
20000~40000/月
Cisco
25000~30000/月 深圳市
PilotAILabs
30000~60000/年 深圳市
写评论取消
回复取消