AWS 上的分布式 XGBoost YARN

这是关于如何在 AWS EC2 集群上设置和运行分布式 XGBoost 的分步教程。分布式 XGBoost 运行在各种平台上,如 MPI, SGE 和 Hadoop YARN 。 在本教程中,我们使用 YARN 作为示例,因为这是分布式计算广泛使用的解决方案。

准备条件

我们需要获得一个 AWS key-pair(密钥对) 来访问 AWS 服务。我们假设我们正在使用一个 mykey 的 key(键)和相应的权限文件 mypem.pem

我们还需要 AWS credentials,其中包括 ACCESS_KEY_IDSECRET_ACCESS_KEY

最后,我们需要一个 S3 bucket(桶)来托管数据和模型, s3://mybucket/

设置 Hadoop YARN 集群

本节将介绍如何从头开始部署 Hadoop YARN 集群。 如果你已经有一个部署好的 Hadoop YARN 集群,那么你可以直接跳过这一步。 我们将使用 yarn-ec2 来启动集群。

我们可以先使用下面的命令来 clone yarn-ec2 脚本

  1. git clone https://github.com/tqchen/yarn-ec2

要使用该脚本,我们必须将环境变量 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 设置正确。这可以通过在 ~/.bashrc 中添加以下两行来完成(用正确的替换字符串)

  1. export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
  2. export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

现在我们可以从 EC2 启动集群的 master 了

  1. ./yarn-ec2 -k mykey -i mypem.pem launch xgboost

等待几分钟,直到 master 启动完成。

master 机器启动之后,可以使用以下命令查询 master 机器的公共 DNS 。

  1. ./yarn-ec2 -k mykey -i mypem.pem get-master xgboost

它会显示 master 机器的公共 DNS 就像下面这样 ec2-xx-xx-xx.us-west-2.compute.amazonaws.com 现在我们可以打开浏览器,输入(用 master DNS 替换 DNS)

  1. ec2-xx-xx-xx.us-west-2.compute.amazonaws.com:8088

这将显示 YARN 集群的 job tracker 。需要注意的是,在 master 完成引导和启动 job tracker 之前我们可能需要等待几分钟。

在 master 机器启动后,我们可以自由添加更多的 slave 机器到集群中。 以下的命令将 m3.xlarge 实例添加到集群中了。

  1. ./yarn-ec2 -k mykey -i mypem.pem -t m3.xlarge -s 2 addslave xgboost

我们也可以选择添加两个 spot 实例

  1. ./yarn-ec2 -k mykey -i mypem.pem -t m3.xlarge -s 2 addspot xgboost

slave 机器将启动,引导并向 master 报告。 你可以单击 job tracker 上的 Nodes 链接来检查 slave 机器是否已连接。 或者只需输入以下 URL(将 DNS 替换为 master DNS)

  1. ec2-xx-xx-xx.us-west-2.compute.amazonaws.com:8088/cluster/nodes

我们需要注意的一件事情是,并不是 job tracker 中的所有的链接都会起作用。 这是由于它们中的许多使用 AWS 的私有 IP,只能由 EC2 访问。 我们可以使用 ssh 代理来访问这些包。 现在我们已经建立了一个 master 和两个 slaves 的集群。我们准备好运行这个实验。

使用 S3 构建 XGBoost

我们可以通过以下命令登录到 master 服务器上。

  1. ./yarn-ec2 -k mykey -i mypem.pem login xgboost

我们将使用 S3 来托管数据和结果模型,因此在集群关闭后数据不会丢失。 要做到这一点,我们需要构建 S3 支持的 xgboost 。我们唯一需要做的就是设置 USE_S3 变量为 true 。这可以通过以下的命令来实现。

  1. git clone --recursive https://github.com/dmlc/xgboost
  2. cd xgboost
  3. cp make/config.mk config.mk
  4. echo "USE_S3=1" >> config.mk
  5. make -j4

现在我们已经构建了 S3 支持的 XGBoost 。如果您打算在 HDFS 上存储数据,您也可以启用 HDFS 支持,只需要打开 USE_HDFS 就可以了。

XGBoost 也依赖环境变量来访问 S3,所以你需要在 ~/.bashrc 中添加以下两行(用正确的字符串替换)在 master 机器上也是如此。

  1. export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
  2. export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  3. export BUCKET=mybucket

在 S3 上托管数据

在这个例子中,我们将把 xgboost 中的示例数据集复制到 S3 bucket(存储桶)中作为输入。 在正常使用情况下,数据集通常是从 existing distributed processing pipeline (现有的分布式处理 pipeline)创建的。 我们可以使用 s3cmd 将数据复制到 mybucket(用真实的 bucket 名称替换 ${BUCKET}) 。

  1. cd xgboost
  2. s3cmd put demo/data/agaricus.txt.train s3://${BUCKET}/xgb-demo/train/
  3. s3cmd put demo/data/agaricus.txt.test s3://${BUCKET}/xgb-demo/test/

提交作业

现在一切准备就绪,我们可以将 xgboost 分布式作业提交到 YARN 集群了。 我们将使用 dmlc-submit 脚本来提交作业。

现在我们可以在 distributed training folder(分布式训练文件夹)(用真实的 bucket 名称替换 ${BUCKET}) 中运行以下脚本。

  1. cd xgboost/demo/distributed-training
  2. # Use dmlc-submit to submit the job.
  3. ../../dmlc-core/tracker/dmlc-submit --cluster=yarn --num-workers=2 --worker-cores=2\
  4. ../../xgboost mushroom.aws.conf nthread=2\
  5. data=s3://${BUCKET}/xgb-demo/train\
  6. eval[test]=s3://${BUCKET}/xgb-demo/test\
  7. model_dir=s3://${BUCKET}/xgb-demo/model

所有配置如 datamodel_dir 也可以直接写入配置文件。 请注意,我们只指定文件的文件夹路径,而不是文件名。 XGBoost 将读取该文件夹下的所有文件作为训练和评估数据。

在这个命令中,我们使用了 2 个 workers,每个 worker 使用两个正在运行的线程。 XGBoost 可以从每个 worker 使用多个 cores 中受益。 工作 cores 的常见的选择范围从 4 到 8 。 训练好的模型将被保存到指定的模型文件夹中。您可以浏览模型文件夹。

  1. s3cmd ls s3://${BUCKET}/xgb-demo/model/

以下是分布式训练的输出示例。

  1. 16/02/26 05:41:59 INFO dmlc.Client: jobname=DMLC[nworker=2]:xgboost,username=ubuntu
  2. 16/02/26 05:41:59 INFO dmlc.Client: Submitting application application_1456461717456_0015
  3. 16/02/26 05:41:59 INFO impl.YarnClientImpl: Submitted application application_1456461717456_0015
  4. 2016-02-26 05:42:05,230 INFO @tracker All of 2 nodes getting started
  5. 2016-02-26 05:42:14,027 INFO [05:42:14] [0] test-error:0.016139 train-error:0.014433
  6. 2016-02-26 05:42:14,186 INFO [05:42:14] [1] test-error:0.000000 train-error:0.001228
  7. 2016-02-26 05:42:14,947 INFO @tracker All nodes finishes job
  8. 2016-02-26 05:42:14,948 INFO @tracker 9.71754479408 secs between node start and job finish
  9. Application application_1456461717456_0015 finished with state FINISHED at 1456465335961

分析模型

模型训练后,我们可以分析学习的模型,并将其用于未来的预测任务。 XGBoost 是一个可移植的框架,所有平台的模型都是 exchangable(可交换) 。 这意味着我们可以在 python/R/Julia 中加载训练好的模型,并利用这些语言中的 data science pipelines (数据科学 pipeline)来做模型分析和预测。

例如,你可以使用 这个 ipython notebook 来绘制 feature importance (特征重要性)和可视化的学习模型。

故障排除

遇到问题的时候,最好的方法可能是使用以下命令获取容器的 stdout 和 stderr 的日志,以检查导致问题的原因。

  1. yarn logs -applicationId yourAppId

未来发展方向

在本教程中,您已经学会了在 YARN 上使用分布式 XGBoost 。 XGBoost 是用于渐变增强的可移植和可伸缩框架。 您可以在 资源页面 中查看更多的示例和资源。

该项目的目标是为所有平台提供最佳的可扩展机器学习解决方案。 API 被设计为可移植的,相同的代码也可以在其他平台上运行,例如 MPI 和 SGE 。 XGBoost 正在积极发展,我们正在开发更多令人兴奋的功能,如分布式 xgboost python/R 包。查看 路线图 来了解更多的细节并且欢迎你为这个项目你做出贡献。