首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

LinkedIn 开源 GDMix:用于训练人工智能个性化模型的框架

GDMix 是什么?

考虑一个工作推荐任务,假设有两个 LinkedIn 成员 Alice 和 Annie,她们的信息非常相似。她们两个都有相同的用户特征,响应的是同一对公司。但她们的反应完全相反。如果我们使用这两个成员的数据来训练一个机器学习模型,那么模型将不会有效,因为训练样本相互矛盾。解决方案之一是根据成员的数据为每个成员训练一个单一的模型。这就是个性化的一个例子。

个性化的一种可能实现是将所有成员 ID 嵌入到一个模型中。这通常会导致一个非常大的模型,因为成员数量可能会达到数亿量级。GDMix(GeneralizedDeepMixed Model,通用深度混合模型)是 LinkedIn 为高效训练这类模型而创建的解决方案。它将一个大模型分解为全局模型(又称“固定效应模型”)和大量小模型(又称“随机效应模型”),然后分别求解。这种分而治之的方法,允许使用标准硬件对大型个性化模型进行有效的训练。GDMix 是其前身 Photon ML 的改进,它扩展并支持深度学习模型。要了解更多背景信息,请查看我们的工程博客

支持的模型

当前版本的 GDMix 支持固定效应的逻辑回归模型和 DeText 模型,然后是随机效应的逻辑回归模型。在未来,如果增加的复杂性可以通过改进行度量来证明的话,我们可能会支持随机效应的深度模型。

逻辑回归模型

作为一种基本的分类模型,逻辑回归模型因其模型简单和训练效率高,在搜索和推荐系统中得到了广泛的应用。我们的实现使用 TensorFlow 进行数据读取和梯度计算,并使用 SciPy 的 L-BFGS 求解器。这种组合利用了 TensorFlow 的多功能性和 L-BFGS 的快速收敛性。这种模式在功能上等效于 Photon-ML,但效率有所提高。我们的内部测试表明,在各种数据集上,训练速度提高到了 10%~40% 不等。

DeText 模型

DeText 是一个强调文本特征的排名框架。GDMix 原生支持 DeText 作为全局模型进行训练。用户可以指定一个固定效应模型类型为 DeText,然后提供网络规格。GDMix 会自动对其进行训练和评分,并将模型与后续的随机效应模型进行连接。目前,只允许将 DeTex 的 Pointwise 损失函数与逻辑回归随机效应模型相连接。

其他模型

GDMix 可以与任何深度学习的固定效应模型一起使用。GDMix 与其他模型之间的接口在文件 I/O 中,用户可以在 GDMix 外部训练一个模型,然后用模型对训练数据进行评分,并将评分保存到文件中,作为 GDMix 随机效应训练的输入。这使用户能够根据来自自定义固定效应模型的得分来训练随机效应模型,而 GDMix 本身并不支持这种模型。

训练效率

对于逻辑回归模型,训练效率是通过并行训练实现的。由于固定效应模型通常需要对大量的数据进行训练,因此采用了基于 TensorFlow All-Reduce 操作的同步训练。每个工作器取一部分训练数据并计算局部梯度。梯度聚集然后馈入 L-BFGS 求解器。每个随机效应模型的训练数据集通常很小,但是模型的数量(例如,所有 LinkedIn 成员的单个模型)可以达到数亿量级。这就需要一种分区和并行的训练策略,其中每个工作器负责一部分人口,所有工作器独立并同时训练分配给它们的模型。

对于 DeText 模型,无论是基于 TensorFlow 的参数服务器异步分布式训练,还是基于 Horovod 的同步分布式训练,都可以提高效率。

如何安装

GDMix 具有 Python 和 Scala 的混合实现,用于在 Spark 上训练模型和处理中间数据,GDMix 需要 Python 3.3+ 和 Apache Spark 2.0+。

作为用户

用户需要:

  • 安装 Spark 2.0+。
  • 下载用于中间数据处理的gdmix-datafat jar。
  • 安装gdmix-trainergdmix-workflowPython 包。

代码语言:javascript
复制
wget -c https://linkedin.bintray.com/maven/com/linkedin/gdmix/gdmix-data-all_2.11/0.2.0/gdmix-data-all_2.11-0.2.0.jar -O gdmix-data-all_2.11.jarpip install gdmix-trainer gdmix-workflow

有关实际操作示例的详细信息,请参阅《尝试 movieLens 示例》( Tryout the movieLens example)和《在 Kubernetes 上运行 GDMix 进行分布式训练》( Run GDMix on Kubernetes for distributed training)中的分布式训练部分。

作为开发人员

GDMix 的 Python 和 Scala 模块分别使用 setuptools Grtadle 来管理代码。我们建议使用 miniconda 来管理 Python dev 虚拟环境。本地构建和测试如下所示。

代码语言:javascript
复制
# Build scala module
./gradlew wrapper --gradle-version  4.5
./gradlew clean build
# Create virtural env
conda create --name gdmix python=3.7.4 -y
conda activate gdmix
pip install pytest
# Install from local gdmix-trainer dev code
cd gdmix-trainer && pip install .
# Run pytest
pytest
# Install from local gdmix-workflow dev code
cd gdmix-workflow && pip install .
# Run pytest
pytest

GDMix 使用

使用概述

GDmix 的整个训练流程如图 1 所示。数据准备步骤由用户提供,输入文件应满足下一节“输入数据”中所示的要求。固定效应捕捉全局趋势,而随机效应体现个性。针对推荐系统中大量交叉特征的复杂性,采用并行分块坐标下降法,将固定效应和随机效应看作“坐标”,在每个优化步骤中,每次只优化一个坐标,其余的坐标保持不变。通过对所有坐标进行几次迭代,我们得到了一个接近于原始问题解的解。

图 1:GDMix 概述

目前,GDMix 支持三种不同的操作模型,如下所示:

固定效应

随机效应

逻辑回归

逻辑回归

DeText 支持的深度 NLP 模型

逻辑回归

用户设计的任意模型

逻辑回归

在最后一种模式中,客户在 GDMix 之外使用自己的模型训练固定效应模型,然后将该模型的得分作为 GDMix 随机效应训练的输入。

图 2:GDMix 操作模型

图 3 显示了固定效应模型和随机效应模型训练的作业,以一个固定效应模型global和两个随机效应模型per-userper-movie为例。global模型是基于所有数据进行训练,通常需要分布式训练;而per-userper-movie的随机效应模型则是根据实体建立许多独立的小模型。为了加速随机效应模型训练的并行性,需要一个数据分区作业,按照实体 ID(如用户 ID)对记录进行分组,这可以由 Spark 高效完成。此外,还要为每个模型计算度量。

图 3:GDMix Workflow 作业

输入数据

输入数据应该按照以下结构组织,其中,固定效应和每个随机效应(per-userper-movie)都有一个子目录,其中包含featureListmetadatatrainingDatavalidationData目录。

代码语言:javascript
复制
├── fixed-effect
│   ├── featureList
│   │   └── global
│   ├── metadata
│   │   └── tensor_metadata.json
│   ├── trainingData
│   │   └── part-00000.tfrecord
│   └── validationData
│       └── part-00000.tfrecord
├── per-user
│   ├── featureList
│   │   └── per_user
│   ├── metadata
│   │   └── tensor_metadata.json
│   ├── trainingData
│   │   └── part-00000.tfrecord
│   └── validationData
│       └── part-00000.tfrecord
├── per-movie
│   ├── featureList
│   │   └── per_movie
│   ├── metadata
│   │   └── tensor_metadata.json
│   ├── trainingData
│   │   └── part-00000.tfrecord
│   └── validationData
│       └── part-00000.tfrecord

trainingDatavalidationData tfrecord 格式的预处理训练和验证数据;featureList目录包含一个列出所有特征名称的文本文件;metadata目录中有一个 json 文件,存储训练样本的数量和元数据,如名称、数据类型、形状和 IF(稀疏向量,用于对 tfrecord 数据进行反序列化 )。global模型的示例如下所示:

代码语言:javascript
复制
{
"numberOfTrainingSamples" : 179087,
"features" : [ {
"name" : "weight",
"dtype" : "float",
"shape" : [ ],
"isSparse" : false
}, {
"name" : "global",
"dtype" : "float",
"shape" : [ 50 ],
"isSparse" : true
}, {
"name" : "uid",
"dtype" : "long",
"shape" : [ ],
"isSparse" : false
} ],
"labels" : [ {
"name" : "response",
"dtype" : "int",
"shape" : [ ],
"isSparse" : false
} ]
}

GDMix 配置

GDmix 配置是一个 json 文件,指定了 GDMix 训练相关参数,如输入数据路径、输出路径、固定效应 / 随机效应模型的模型参数、计算资源(仅限分布式)等。有关 GDmix 配置的更多详细信息,请参见gdmix_config.md 文件。

试用 movieLens 示例

在本节中,我们将介绍如何使用 GDmix 和 movieLens 数据来训练固定效应模型globe和两个随机效应模型per-userper-movie。在脚本 download_process_movieLens_data.py 中准备了每种模型的功能。per-user使用特征年龄、性别和职业,per-movie使用特征类型和上映日期,globe使用所有这五个特征。

在容器中运行 GDMix

尝试 movieLens 示例的最简单方法是在预构建的 Docker 容器中运行它:

代码语言:javascript
复制
docker run --name gdmix -it linkedin/gdmix bash
  • 针对global``per-userper-movie的训练逻辑回归模型(有关详细信息,请参阅《训练逻辑回归模型》( Train logsitic regression models)一节):

代码语言:javascript
复制
python -m gdmixworkflow.main --config_path lr-single-node-movieLens.config --jar_path gdmix-data-all_2.11.jar
  • global训练一个深度和广度的神经网络模型,为per-userper-movie训练两个逻辑回归模型(详见《训练神经网络和逻辑回归模型》( Train neural network model plus logsitic regression models)一节):

代码语言:javascript
复制
python -m gdmixworkflow.main --config_path detext-single-node-movieLens.config --jar_path gdmix-data-all_2.11.jar

直接运行 GDMix

要直接运行 GDMix,用户需要遵循上面《作为用户》(As user)一节中的说明进行操作,我们将详细说明下面的步骤。因为我们还不支持 PySpark,因此需要安装 Spark。下面我们介绍如何在 CentOS/RHEL 7.x 上安装 Spark 2.4.6,在其他系统上的安全也可以类似地完成。

代码语言:javascript
复制
yum  install -y java-1.8.0-openjdk
export JAVA_HOME=/etc/alternatives/jre
spark_version=2.4.6
spark_pkg=spark-${spark_version}-bin-hadoop2.7
wget https://downloads.apache.org/spark/spark-${spark_version}/${spark_pkg}.tgz
mkdir /opt/spark
tar -xf ${spark_pkg}.tgz && \
mv ${spark_pkg}/jars /opt/spark && \
mv ${spark_pkg}/bin /opt/spark && \
mv ${spark_pkg}/sbin /opt/spark && \
mv ${spark_pkg}/kubernetes/dockerfiles/spark/entrypoint.sh /opt/ && \
mv ${spark_pkg}/examples /opt/spark && \
mv ${spark_pkg}/kubernetes/tests /opt/spark && \
mv ${spark_pkg}/data /opt/spark && \
chmod +x /opt/*.sh && \
rm -rf spark-*
export SPARK_HOME=/opt/spark
export PATH=/opt/spark/bin:$PATH
export SPARK_CLASSPATH=$SPARK_CLASSPATH:/opt/spark/jars/

下载并运行提供的脚本 download_process_movieLens_data.py 来下载 movieLens 数据并对其进行预处理,--dest_path参数可以用来将结果保存到其他路径,默认为当前路径下的movieLens目录:

代码语言:javascript
复制
wget https://raw.githubusercontent.com/linkedin/gdmix/master/scripts/download_process_movieLens_data.py
pip install pandas
python download_process_movieLens_data.py

下载用于 Spark 处理中间数据的gdmix-datafat jar:

代码语言:javascript
复制
wget -c https://linkedin.bintray.com/maven/com/linkedin/gdmix/gdmix-data-all_2.11/0.2.0/gdmix-data-all_2.11-0.2.0.jar -O gdmix-data-all_2.11.jar

安装 Python 包gdmix-trainergdmix-workflow

代码语言:javascript
复制
pip install gdmix-trainer gdmix-workflow

训练逻辑回归模型

为演示目的提供了一个 GDMix 配置 lr-single-node-movieLens.config ,下载它并使用以下命令开始 GDMix 训练:

代码语言:javascript
复制
wget https://raw.githubusercontent.com/linkedin/gdmix/master/gdmix-workflow/examples/movielens-100k/lr-single-node-movieLens.config
python -m gdmixworkflow.main --config_path lr-single-node-movieLens.config --jar_path gdmix-data-all_2.11.jar

在一台装有 16 块 Intel Xeon CPU 2.10GHz 的计算机上,完成训练需要 2 分钟。如果训练成功,结果目录(来自 GDMix 配置中的output_dir字段)将在训练结束时显示:

代码语言:javascript
复制
GDMix training is finished, results are saved to lr-training.

结果目录lr-training具有以下结构。固定效应模型和随机效应模型根据 GDMix 配置保存在子目录globalper-userper-movie中。在每个子目录中,metricmodel目录将度量保存在验证数据集和训练的模型上,其余的是用于回放或调试的中间数据。

代码语言:javascript
复制
|-- global
|   |-- metric
|   |   `-- evalSummary.json
|   |-- models
|   |   `-- global_model.avro
|   |-- train_scores
|   |   `-- part-00000.avro
|   `-- validation_scores
|       `-- part-00000.avro
|-- per-movie
|   |-- metric
|   |   `-- evalSummary.json
|   |-- models
|   |   `-- part-00000.avro
|   |-- partition
|   |   |-- metadata
|   |   |   `-- tensor_metadata.json
|   |   |-- partitionList.txt
|   |   |-- trainingData
|   |   |   ...
|   |   `-- validationData
|   |       ...
|   |-- train_scores
|   |   `-- partitionId=0
|   |       `-- part-00000-active.avro
|   `-- validation_scores
|       `-- partitionId=0
|           `-- part-00000.avro
`-- per-user
|-- metric
|   `-- evalSummary.json
|-- models
|   `-- part-00000.avro
|-- partition
|   |-- metadata
|   |   `-- tensor_metadata.json
|   |-- partitionList.txt
|   |-- trainingData
|   |   ...
|   `-- validationData
|       ...
|-- train_scores
|   `-- partitionId=0
|       `-- part-00000-active.avro
`-- validation_scores
`-- partitionId=0
`-- part-00000.avro

下面表格总结了每个模型的度量。正如我们所看到的,与单独使用global固定效应模型相比,为per-userper-movie添加随机效应模型可以显著提高 AUC。

global

LR

0.6237

per-user

LR

0.7058

per-movie

LR

0.7599

训练神经网络模型和逻辑回归模型

作为比较,我们将训练一个由 DeText 支持的固定效应global神经网络模型,并保持随机效应模型不变。我们增加了电影片名作为global模型的一个附加特征,而神经网络是有广度和深度的,即电影片名是“深度的”,其余特征是“广度的”。

我们使用 detext-single-node-movieLens.config GDMix 配置来进行训练:

代码语言:javascript
复制
wget https://raw.githubusercontent.com/linkedin/gdmix/master/gdmix-workflow/examples/movielens-100k/detext-single-node-movieLens.config
python -m gdmixworkflow.main --config_path detext-single-node-movieLens.config --jar_path gdmix-data-all_2.11.jar

在一台装有 16 块 Intel Xeon CPU 2.10GHz 的计算机上,完成训练需要 3 分钟。下面的表格显示了每种模型的 AUC。具有广度和深度的固定效应global模型的性能远远优于逻辑回归模型(0.7090 vs 0.6237),整体 AUC 也有所提高(0.7680 vs 0.7599)。我们仍然可以从per-user的随机效果模型中看到显著的改进,但与per-movie的模型相比并没有太多的改进。在生产环境中,我们可以部署深度和广度的global和逻辑回归per-user模型,以简化模型的部署。

模型

类型

AUC

global

DeText

0.7090

per-user

LR

0.7665

per-movie

LR

0.7680

请注意,由于 download_process_movieLens_data.py 中的随机训练 / 验证数据分区,用户可能会得到略微不同的结果。

在 Kubernetes 上进行分布式训练

GDMix 的分布式训练是基于 Kubernetes 的。它利用 Kubernetes 作业调度服务 Kubeflow Spark-on-k8s-operator 在分布式运行 TensorFlow 和 Spark 作业。它还是用 Kubeflow Pipeline 来编排作业。在这种情况下,需要集中存储训练数据和模型。用户可以使用 Kubernetes-HDFS NFS 作为集中存储。有关分布式训练的更多信息,请参阅 gdMix-workflow 的自述文件。下图显示了 Kubeflow Pipeline UI 中的 GDMix movieLens 示例的快照。

图 4:在 Kubeflow Pipeline 进行 GDMix 分布式训练

原文链接:

https://github.com/linkedin/gdmix

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/SBbuxz4ygsfYg9fKd56R
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券