伴鱼机器学习预测服务设计篇

陈易生, ml-sys
Back

前言

在伴鱼,我们在多个在线场景使用机器学习提升用户的使用体验。例如,在伴鱼绘本中,我们根据用户的帖子浏览记录,为用户推荐他们感兴趣的帖子。

在线预测是机器学习模型发挥作用的临门一脚,重要性不言而喻。在伴鱼,我们搭建了机器学习预测服务(以下简称预测服务),统一地处理所有的预测请求。本文主要介绍预测服务的演进过程。

预测服务 V1

目前,各个算法团队都有一套组装预测服务的方式。下图 ① 到 ⑤ 代表预测请求的整个生命周期:

  1. 业务服务从特征系统获取特征,从 AB 平台获取实验分组。
  2. 业务服务等待获取结果。
  3. 业务服务将模型 ID 和特征向量发送给 ModelServer。
  4. 业务服务从 ModelServer 获取根据模型 ID 和特征向量得到的推理结果。
  5. 业务服务将模型 ID、特征向量和推理结果打成预测日志,搜集起来,用于后续构建训练数据集。

v1 architecture

其中,ModelServer 的实现有两种主流方式。其一,使用 TorchServe 或 TensorFlow Serving 这样和训练框架高度耦合的 serving 方案。其二,使用 Flask 搭建一个简单的 HTTP 服务,将模型加载至服务的内存,在收到预测请求时调用模型的预测接口进行预测。

这种方式存在几个问题:

为了系统性地解决这几个问题,预测服务 V2 提出了几个设计目的:

预测服务 V2

架构主要借鉴了 UberDoorDash:预测服务接受预测请求,根据请求的内容,进行获取特征、获取 AB 实验分组等操作,然后调用 ModelServer 进行推理,返回预测结果。与预测服务 V1 的最大区别在于,我们单独设计了一个「预测服务」,作为沟通业务服务和 ML 系统的桥梁。详情见下图。

v2 architecture

⓪ 表示在新的模型上线之前,算法工程师上传的预测配置文件会被载入预测服务,预测服务根据配置文件的内容实例化一个工作流。

① 到 ⑥ 代表预测请求的整个生命周期:

  1. 预测服务被业务服务(例如推荐引擎)调用,调用方需要提供模型名字、预测主体的 key(例如用户 ID)、上下文(context)特征。
  2. 预测服务根据模型名字,定位到该模型所对应的工作流并执行,包括调用特征系统、调用 AB 平台接口等。
  3. 预测服务调用特征系统接口获取特征向量,从 AB 平台获取实体对应的模型 ID。
  4. 预测服务根据模型 ID 和特征向量,调用 ModelServer。
  5. 预测服务从 ModelServer 获取模型的预测值。
  6. 预测服务返回预测值,并打日志。日志可用于构建训练数据集,也可以用于监控特征和预测的质量。

在这个架构下,算法工程师要上线一个模型,只需:

  1. 离线完成模型训练,将模型上传至模型仓库。
  2. 将模型部署至 ModelServer(选用 Seldon Core 作为解决方案)。
  3. 特征系统开发特征。
  4. 用 AB 平台创建实验。
  5. 将预测配置文件以 Merge Request 的形式,提交到指定的代码仓库。
  6. 由业务方的工程同学协助,对接预测服务。

不难看出,编写预测配置文件是算法工程师工作流的核心。预测配置文件以 YAML 格式定义了一个完整的模型推理工作流所涉及的全部信息。

举一个具体的例子。假设我们有一个视频推荐系统 Toy Recsys,它结合用户的网络情况(network),和用户的短期观看历史(last_5_views),给用户推荐视频。模型的基本逻辑是:网络情况好,就结合用户口味,放一些用户最可能感兴趣的长视频;网络情况差,就结合用户口味,放一些短视频。

我们称 network 和 last_5_views 是 Toy Recsys 模型的两个特征。其中,网络情况会附带在请求中(这类特征被称为 context 特征),而短期观看历史存储在特征系统中。要让预测服务知道如何获取这两个特征,不需要工程同学进行额外的编码工作,而只需由算法工程师提交如下配置文件:

model-name: toy_recsys
feature-system:
- features:
- name: network
source: context
default-value: 4G
- name: last_5_views
source: store
default-value: []

预测服务会根据算法工程师提交的预测配置文件,实例化一个获取特征的工作流,并开始处理该模型的请求。这个工作流会:

  1. 从请求中获取 user_id 和 network 参数。
  2. 使用请求中的 user_id,去调用特征系统的 RPC 接口,获取 last_5_views 的特征值。
  3. 将 user_id, network 和 last_5_views 组装成一个特征向量,发送给 ModelServer 进行推理。

值得注意的是,预测配置文件极易拓展。如果预测服务要接入 AB 平台,我们只需要支持在配置文件中填写 AB 实验的信息即可。例如:

model-name: toy_recsys
feature-system: ...
ab-experiment:
- experiment-key: TOY_RECSYS

总结

在完成预测服务的初步设计后,我们开始了预测服务的实现。我们期待在预测服务上线后,与大家分享预测服务的实现细节。


© Yik San Chan. Built with Vercel and Nextra.