文章目录
业界的主流模型方法
预存推荐结果或Embedding结果
- 最简单直接的模型服务方法就是在离线环境下生成对每个用户的推荐结果,然后将结果预存到以Redis为代表的线上数据库中,这样线上环境直接取出预存数据推荐给用户。
- 优点:无需模型线上推断过程,线下训练平台与线上服务平台完全解耦。可以选择线下任何机器学习工具进行模型训练;线上过程没有复杂的计算,推荐结果延迟性低。
- 缺点:需要存储User、Item应用场景组合推荐结果,用户物品规模量上来之后,会出现组合爆炸的情况,线上数据库无法支持大量的数据存储;无法引入线上类场景特征,推荐系统灵活性及效果受限。
- 如何减少模型存储所需的空间:通过存储Embedding的方式来替代直接存储推荐结果,先离线训练好Embedding,再在线上通过相似度运算得到最终的推荐结果。预存Embedding的方法是业界经常采用的模型服务手段。
预训练Embedding+轻量级线上模型
- 用复杂深度学习网络离线训练生成Embedding,存入内存数据库,再在线上实现逻辑回归或浅层神经网络等轻量级模型来拟合优化目标。
- 阿里的推荐模型 MIMN(Multi-channel user Interest Memory Network,多通道用户兴趣记忆网络)神经网络才是真正在线上服务的部分。架构图如下:
- S(1)-S(m) 和 M(1)-M(m)就是在离线生成的Embedding向量,在MIMN模型中,它们被称为多通道用户兴趣向量,这些Embedding向量就是连接离线模型和线上模型部分的接口。线上部分从Redis之类的模型数据库中拿到这些离线生成Embedding向量,然后跟其他特征Embedding向量组合在一起,扔给一个标准的多层神经网络进行预估,这就是一个典型的“预训练Embedding+轻量级线上模型”的服务方式。
- 优点:具备灵活的线上推断效率,是主流模型服务解决方案。
- 缺点:不是End2End解决方案,实现复杂度高。
利用PMML转换和部署模型
- PMML的全称是“预测模型标记语言”(Predictive Model Markup Language, PMML),它是一种通用的以XML的形式表示不同模型结构参数的标记语言。在模型上线的过程中,PMML经常作为中间媒介连接离线训练平台和线上预测平台。Spark模型利用PMML的上线过程如下图:
- JPMML作为序列化和解析PMML文件的library,JPMML项目分为Spark和Java Server两部分。Spark部分的library完成Spark MLlib模型的序列化,生成PMML文件,并且把它保存到线上服务器能够触达的数据库或文件系统中,而Java Server部分则完成PMML模型的解析,生成预估模型,完成了与业务逻辑的整合。JPMML在Java Server部分只进行推断,不考虑模型训练、分布式部署等一系列问题,因此library比较轻,能够高效地完成推断过程。
- 优点:可支持End2End的模型训练。
- 缺点:语言表示能力有限,不能够完全支持复杂复杂模型的训练。
TensorFlow Serving
- TensorFlow Serving工作流程也是经历了模型存储、模型载入还原以及提供服务的过程。在具体细节上,TensorFlow在离线把模型序列化,存储到文件系统,TensorFlow Serving把模型文件载入到模型服务器,还原模型推断过程,对外以HTTP接口或gRPC接口的方式提供模型服务。
- 在Sparrow Recsys项目中,我们会在离线使用TensorFlow的Keras完成模型构建和训练,再利用TensorFlow Serving载入模型,用Docker作为服务容器,然后在Jetty推荐服务器中发出HTTP请求到TensorFlow Serving,获得模型推断结果,最后推荐服务器利用这一结果完成推荐排序。如下图所示:
- 优点:End2End解决方案,支持绝大多数TensorFlow模型。
- 缺点:只支持TensorFlow模型,线上服务效率较低,需要大量优化
搭建TensorFlow Serving模型服务
安装Docker
- Linux(CentOS系统)安装请参考以下脚本
#1、安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
#2、加载docker源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#3、安装docker
yum install -y docker-ce
#4、关闭防火墙及增强安全性功能
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i '/^SELINUX/s#enforcing#disabled#' /etc/selinux/config
#5、阿里云镜像加速,打码的地方自己去阿里云上面找一下
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://#######.mirror.aliyuncs.com"]
}
EOF
- Windows安装请参考官方链接。
建立TensorFlow Serving服务
- Docker命令拉取TensorFlow Serving的镜像
docker pull tensorflow/serving
- 再从TenSorflow的官方GitHub地址下载TensorFlow Serving相关的测试模型文件
# 把tensorflow/serving的测试代码clone到本地,这里建议使用git bash工具。
git clone https://github.com/tensorflow/serving
# 指定测试数据的地址,我把git下来的地址放进了e盘
TESTDATA="e:/serving/tensorflow_serving/servables/tensorflow/testdata"
- Docker启动TensorFlow Serving的模型服务容器,并载入我们刚才下载的测试模型文件half_plus_two:
# 启动TensorFlow Serving容器,在8501端口运行模型服务API
docker run -t --rm -p 8501:8501 \
-v "$TESTDATA/saved_model_half_plus_two_cpu:/models/half_plus_two" \
-e MODEL_NAME=half_plus_two \
tensorflow/serving &
请求TensorFlow Serving获得预估结果
# 请求模型服务API
curl -d '{"instances": [1.0, 2.0, 5.0]}' \
-X POST http://localhost:8501/v1/models/half_plus_two:predict
- 得到结果如下: