写点什么

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

  • 2020-10-23
  • 本文字数:6347 字

    阅读完需:约 21 分钟

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 包。


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 模块分别使用setuptoolsGrtadle来管理代码。我们建议使用miniconda来管理 Python dev 虚拟环境。本地构建和测试如下所示。


# Build scala module./gradlew wrapper --gradle-version  4.5./gradlew clean build# Create virtural envconda create --name gdmix python=3.7.4 -yconda activate gdmixpip install pytest# Install from local gdmix-trainer dev codecd gdmix-trainer && pip install .# Run pytestpytest# Install from local gdmix-workflow dev codecd gdmix-workflow && pip install .# Run pytestpytest
复制代码

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目录。


├── 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
复制代码


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


{"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 容器中运行它:


docker run --name gdmix -it linkedin/gdmix bash
复制代码


  • 针对global``per-userper-movie的训练逻辑回归模型(有关详细信息,请参阅《训练逻辑回归模型》(Train logsitic regression models)一节):


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)一节):


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,在其他系统上的安全也可以类似地完成。


yum  install -y java-1.8.0-openjdkexport JAVA_HOME=/etc/alternatives/jrespark_version=2.4.6spark_pkg=spark-${spark_version}-bin-hadoop2.7wget https://downloads.apache.org/spark/spark-${spark_version}/${spark_pkg}.tgzmkdir /opt/sparktar -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/sparkexport PATH=/opt/spark/bin:$PATHexport SPARK_CLASSPATH=$SPARK_CLASSPATH:/opt/spark/jars/
复制代码


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


wget https://raw.githubusercontent.com/linkedin/gdmix/master/scripts/download_process_movieLens_data.pypip install pandaspython download_process_movieLens_data.py
复制代码


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


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


pip install gdmix-trainer gdmix-workflow
复制代码

训练逻辑回归模型

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


wget https://raw.githubusercontent.com/linkedin/gdmix/master/gdmix-workflow/examples/movielens-100k/lr-single-node-movieLens.configpython -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字段)将在训练结束时显示:


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


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


|-- 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。


globalLR0.6237
per-userLR0.7058
per-movieLR0.7599

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

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


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


wget https://raw.githubusercontent.com/linkedin/gdmix/master/gdmix-workflow/examples/movielens-100k/detext-single-node-movieLens.configpython -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
globalDeText0.7090
per-userLR0.7665
per-movieLR0.7680


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

在 Kubernetes 上进行分布式训练

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



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


原文链接:


https://github.com/linkedin/gdmix


2020-10-23 17:401947
用户头像
赵钰莹 极客邦科技 总编辑

发布了 883 篇内容, 共 647.9 次阅读, 收获喜欢 2680 次。

关注

评论

发布
暂无评论
发现更多内容

一篇通俗易懂的Android视图系统设计与实现,精通android网络开发pdf

android 程序员 移动开发

一种清晰, 便于扩展android项目架构方案,kotlin编程

android 程序员 移动开发

不愧是阿里技术官,Android Framework的精髓全写在这本“限量笔记

android 程序员 移动开发

中年危机并不可怕,可怕的是你没有做好自己的规划,斗鱼Android开发二面被刷

android 程序员 移动开发

为了KPI,对APK进行极限优化!,大厂Android研发岗面试复盘

android 程序员 移动开发

一线互联网技术总监的忠告:我们精通那么多技术为何还是做不好一个项目?

android 程序员 移动开发

不知道这些你就OUT了,2019年最常见又实用的Android开发面试题

android 程序员 移动开发

专科培训班出生,四年换四次工作被朋友嘲笑面霸!最终拿下字节跳动Offer年薪57w

android 程序员 移动开发

一篇文章,全面总结2020最新整理-Android-大厂高频面试知识点

android 程序员 移动开发

一篇看懂Android与Flutter之间的通信,最新Android开发面试解答

android 程序员 移动开发

不是吧!做了3年Android还没看过OkHttp源码?好吧,kotlin开源

android 程序员 移动开发

一文读懂深克隆与浅克隆的关系

Tom弹架构

Java 架构 设计模式

专科毕业,我是如何拿到字节跳动、网易双offer的,白嫖党最爱

android 程序员 移动开发

业余时间如何开发一个App?出于好奇心QiShare带你体验一下 _ 创作者训练营第二期

android 程序员 移动开发

一篇文章让你彻底了解三次握手和四次挥手,轻松拿下offer

android 程序员 移动开发

三年开发经验,跳槽腾讯音乐,三面斩获Offer,Android入门教程

android 程序员 移动开发

下次一定会成,Android面试血泪教训(九场面试的经验与得失

android 程序员 移动开发

Microchip发布2.3版TimeProvider® 4100主时钟授时和同步系统

hadoop源码编译参考

Clarke

一行代码解决安卓重复点击,稳进大厂

android 程序员 移动开发

三年Android开发却只有一年工作经验,是怎么收到offer的?

android 程序员 移动开发

不愧是阿里技术官,Android-Framework的精髓全写在这本“限量笔记

android 程序员 移动开发

一起来看看 Android 官推 kotlin-first 的图片加载库(1)

android 程序员 移动开发

专科 二本程序员的“黄金五年”该如何规划,kotlin协程和线程的区别

android 程序员 移动开发

专科渣校,呕心沥血在家3个月“拿下”330页PDF,终于拿下阿里OFFer

android 程序员 移动开发

一线大厂大型APP性能优化系列-自定义启动器(三),2020-2021阿里巴巴安卓面试真题解析

android 程序员 移动开发

一键登录已成大势所趋,Android端操作指南来啦!,handler机制的原理面试

android 程序员 移动开发

与面试官的一次促膝长谈:人家也是第一次当面试官,你们答不上来我也特别尴尬

android 程序员 移动开发

《穷爸爸富爸爸》

石云升

投资理财 11月日更

两年 Android 经验面经(有赞等公司),请查收

android 程序员 移动开发

中年程序员崩溃大哭:混不上管理层,加不动班,flutter游戏背包

android 程序员 移动开发

LinkedIn 开源 GDMix:用于训练人工智能个性化模型的框架_AI&大模型_LinkedIn_InfoQ精选文章