亚马逊AWS官方博客

开源 Amazon SageMaker XGBoost 算法容器介绍

Original URL:https://aws.amazon.com/cn/blogs/machine-learning/introducing-the-open-source-amazon-sagemaker-xgboost-algorithm-container/

 

XGBoost是一种流行且高效的机器学习(ML)算法,用于对表格数据集进行回归与分类的任务。它在树状结构上实现了一种被称为梯度提升的技术,能够在机器学习竞赛中带来出色表现。

自发布以来,Amazon SageMaker已经能够支持将XGBoost作为内置托管算法。关于更多详细信息,请参阅使用XGBoost与Amazon SageMaker简化机器学习流程。截至本文撰稿时,大家可以利用开源Amazon SageMaker XGBoost容器带来的高灵活性、可扩展性、可延伸性以及Managed Spot Training功能快速完成自己的模型训练任务。关于更多详细信息,请参阅Amazon SageMaker示例notebooks以及GitHub上的 sagemaker-xgboost-container,或者参考查看XGBoost算法

本文介绍了开源XGBoost算法的优势,并探讨了该算法的三个相关用例。

开源SageMaker XGBoost容器的优势

新的XGBoost容器拥有以下优势:

最新版本

开源XGBoost容器支持最新的XGBoost 1.0版本与全部改进,包括在多核实例上拥有更好的性能并改进了分布式训练的稳定性。

灵活性

在新的脚本模式下,大家现在可以自定义或者使用自己准备的训练脚本。TensorFlow、MXNet、PyTorch以及Chainer用户也可以使用这项功能,借此添加自定义的预处理或者后处理逻辑,在训练流程结束后运行其他步骤,或者充分发挥XGBoost提供的其他功能(例如交叉验证支持)。大家也可以使用无脚本算法模式(与Amazon SageMaker中内置的其他算法一样),单纯通过指定数据位置与超参数实现模型训练。

可扩展性

开源容器可以更高效地执行分布式训练,将训练任务扩展到更多实例,并减少内存不足错误的发生几率。

可延伸性

凭借着开源属性,大家可以对算法本身做出延伸、分叉或修改,在直接使用脚本模式之外更充分地满足自己的实际需求。其中包括安装其他库并更改XGBoost的基础版本。

Managed Spot Training

大家可以配合Managed Spot Training支持功能,在Amazon SageMaker XGBoost当中实现高达90%的成本节约。作为全托管选项,此功能允许大家充分利用AWS云中暂时闲置的计算容量。Amazon SageMaker将按照您的使用习惯管理竞价实例,大家无需担心容量轮替给工作负载带来的影响。最新版本XGBoost还能自动管理检查点,确保您的作业始终能够可靠完成。关于更多详细信息,请参阅Amazon SageMaker中的Managed Spot Training以及在Amazon SageMaker中使用检查点

其他输入格式

XGBoost现在提供对Parquet与Recordio-protobuf输入格式的支持。Parquet是一种用于数据分析系统的标准化、开源、自描述、列式存储格式。Recordio-protobuf则是Amazon SageMaker中适用于各类算法的一种通用型二进制数据格式,XGBoost现在也支持使用这种格式进行训练与推理。关于更多详细信息,请参阅常见的训练数据格式。此外,新容器还支持使用这些数据格式进行Pipe模式训练。关于更多详细信息,请参阅在Amazon SageMaker算法中使用Pipe输入模式

使用最新XGBoost容器作为内置算法

作为Amazon SageMaker XGBoost的用户,现在您可以在创建训练作业时指定新版本,从而轻松使用其提供的新功能与各项改进。关于XGBoost上手说明或者使用最新版本的更多详细信息,请参见GitHub repo

大家可以通过指定的框架版本(1.0-1)升级至新容器。此版本指定了上游XGBoost框架版本(1.0)以及额外的Amazon SageMaker版本(1)。如果您已经拥有基于原有0.72版本容器的XGBoost工作流,则只需完成容器升级即可享受新版本带来的各项助益。如果您选择0.90-1,则可使用容器支持的XGBoost 0.90版本。

详见以下代码:

from sagemaker.amazon.amazon_estimator import get_image_uri
container = get_image_uri(region, 'xgboost', '1.0-1')

estimator = sagemaker.estimator.Estimator(container, 
                                          role, 
                                          hyperparameters=hyperparameters,
                                          train_instance_count=1, 
                                          train_instance_type='ml.m5.2xlarge', 
                                          )

estimator.fit(training_data)

使用托管竞价实例

大家也可以在Estimator中启用train_use_spot_instances标记,借此发挥新版本对托管竞价实例的支持能力。关于更多详细信息,请参阅GitHub repo

在使用托管竞价实例进行训练时,训练作业可能随时中断,并导致作业持续时间延长。另外,如果训练作业中断,您可以使用检查点快照通过先前保存的状态快速恢复,从而节约训练时间(与成本)。您还可以使用训练作业存储快照的位置checkpoint_s3_uri,在竞价实例发生中断时进行无缝恢复。具体请参见以下代码:

estimator = sagemaker.estimator.Estimator(container, 
                                          role, 
                                          hyperparameters=hyperparameters,
                                          train_instance_count=1, 
                                          train_instance_type='ml.m5.2xlarge', 
                                          output_path=output_path, 
                                          sagemaker_session=sagemaker.Session(),
                                          train_use_spot_instances=train_use_spot_instances, 
                                          train_max_run=train_max_run, 
                                          train_max_wait=train_max_wait,
                                          checkpoint_s3_uri=checkpoint_s3_uri
                                         )
                                         
estimator.fit({'train': train_input})                                         

在作业即将结束时,大家应该看到下两行输出:

  • 训练秒数: X – 完成训练作业所耗费的具体计算时间。
  • 计费秒数: Y – 享受竞价实例折扣后的实际计费时间。

如果您启用了train_use_spot_instances,应该看到XY之最存在明显差别,这表明使用Managed Spot Training确实能够节约成本,这一点在以下代码中有所体现:

Managed Spot Training savings: (1-Y/X)*100 %

使用脚本模式

脚本模式是开源Amazon SageMaker XGBoost容器中的一项新功能。您可以使用自己训练或者托管的脚本对XGBoost训练或推理工作流进行全面自定义。以下代码示例,为在脚本模式下使用自定义训练脚本的基本演练。关于更多详细信息,请参见GitHub repo

准备入口点脚本

典型的训练脚本会从输入通道加载数据,使用超参数配置训练,执行模型训练,而后将模型保存至model_dir以供后续托管。超参数以参数形式传递至您的脚本,并可以使用argparse.ArgumentParser 实例进行检索。

从主入口点开始,我们在创建训练作业时,需要使用解析器读取传递至您Amazon SageMaker估计器的超参数。这些超参数将作为输入脚本中的参数。您还可以解析其他特定于Amazon SageMaker的环境变量,以获取关于训练环境的更多信息,例如输入数据的位置以及模型的保存位置等。具体参见以下代码:

if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    # Hyperparameters are described here
    parser.add_argument('--num_round', type=int)
    parser.add_argument('--max_depth', type=int, default=5)
    parser.add_argument('--eta', type=float, default=0.2)
    parser.add_argument('--objective', type=str, default='reg:squarederror')
    
    # Sagemaker specific arguments. Defaults are set in the environment variables.
    parser.add_argument('--train', type=str, default=os.environ['SM_CHANNEL_TRAIN'])
    parser.add_argument('--validation', type=str, default=os.environ['SM_CHANNEL_VALIDATION'])
    
    args = parser.parse_args()
    
    train_hp = {
        'max_depth': args.max_depth,
        'eta': args.eta,
        'gamma': args.gamma,
        'min_child_weight': args.min_child_weight,
        'subsample': args.subsample,
        'silent': args.silent,
        'objective': args.objective
    }
    
    dtrain = xgb.DMatrix(args.train)
    dval = xgb.DMatrix(args.validation)
    watchlist = [(dtrain, 'train'), (dval, 'validation')] if dval is not None else [(dtrain, 'train')]

    callbacks = []
    prev_checkpoint, n_iterations_prev_run = add_checkpointing(callbacks)
    # If checkpoint is found then we reduce num_boost_round by previously run number of iterations
    
    bst = xgb.train(
        params=train_hp,
        dtrain=dtrain,
        evals=watchlist,
        num_boost_round=(args.num_round - n_iterations_prev_run),
        xgb_model=prev_checkpoint,
        callbacks=callbacks
    )
    
    model_location = args.model_dir + '/xgboost-model'
    pkl.dump(bst, open(model_location, 'wb'))
    logging.info("Stored trained model at {}".format(model_location))

在入口点脚本中,大家在使用Amazon SageMaker托管或者批处理转换时,可以选择自定义推理方式。可以定制的具体参数如下:

  • input_fn() – 如何处理输入信息
  • predict_fn() – 如何调用XGBoost模型
  • output_fn() – 如何返回响应

所有默认选项皆适用于本用例,因此大家无需额外定义。

使用Amazon SageMaker XGBoost 估计器进行训练

在训练数据与脚本准备就绪之后,Amazon SageMaker Python SDK中提供的XGBoost估计器可以在由Amazon SageMaker托管的训练基础设施之上以训练作业的形式运行我们的脚本。另外,大家还需要向估计器传递您的IAM角色、要使用的实例类型以及要传递给脚本的超参数字典。具体请参见以下代码:

from sagemaker.session import s3_input
from sagemaker.xgboost.estimator import XGBoost

xgb_script_mode_estimator = XGBoost(
    entry_point="abalone.py",
    hyperparameters=hyperparameters,
    image_name=container,
    role=role, 
    train_instance_count=1,
    train_instance_type="ml.m5.2xlarge",
    framework_version="1.0-1",
    output_path="s3://{}/{}/{}/output".format(bucket, prefix, "xgboost-script-mode"),
    train_use_spot_instances=train_use_spot_instances,
    train_max_run=train_max_run,
    train_max_wait=train_max_wait,
    checkpoint_s3_uri=checkpoint_s3_uri
)

xgb_script_mode_estimator.fit({"train": train_input})

部署自定义XGBoost模型

在模型训练完成之后,您可以使用估计器创建Amazon SageMaker端点——这是一种托管且受控的预测服务,可供您用于执行推理。详见以下代码:

predictor = xgb_script_mode_estimator.deploy(initial_instance_count=1, instance_type="ml.m5.xlarge")
test_data = xgboost.DMatrix('/path/to/data')
predictor.predict(test_data)

使用Parquet输入进行训练

现在您可以使用Amazon SageMaker支持的开源ML-IO库,通过Parquet格式的文件或直接配合流式数据对最新XGBoost算法进行训练。ML-IO是一种面向多种机器学习框架的高性能数据访问库,支持多种数据格式且在最新XGBoost容器之上默认安装到位。关于导入Parquet文件以及对其进行训练的更多详细信息,请参见GitHub repo

总结

面向Amazon SageMaker的开源XGBoost容器提供全托管使用体验与其他多种优势,可帮助您节约训练成本并进一步提升机器学习应用灵活性。

 

本篇作者

Rahul Iyer

AWS AI软件开发经理。他负责领导框架算法团队,构建并优化包括XGBoost与Scikit-learn在内的多种机器学习框架。业余时间,他喜欢探索户外、自然摄影并与家人团聚。

Rocky Zhang

AWS SageMaker高级产品经理。他开发的产品帮助客户使用机器学习技术解决现实世界中的各类业务问题。在工作之余,他的大部分休闲时间都跟足球有关——看球、踢球、指导足球战术。

Eric Kim

Amazon AI算法与平台小组工程师。他协助支持AWS SageMaker服务,并在机器学习的研究、开发与应用领域拥有丰富经验。在工作之余,他热爱音乐也喜欢小狗。

Laurence Rouesnel

Amazon AI的高级经理。他领导着致力于深度学习和机器学习研究及产品(例如SageMaker AutoPilot和Algorithms)的工程师和科学家团队。在业余时间,他是旅行,台式RPG和跑步的狂热爱好者。