发布于: Oct 30, 2022

深度学习模型部署是一个比较复杂的过程,因为你需要像搭积木一样的来去搭建一个多层的网络,每层的网络又有不同的目的,比如距离输入侧较近的层要承担很多类似特征工程的工作。但是对于我们现在要使用的 XGBoost 这个传统的 ML 算法来说,这个模型可以理解成就是算法本身,是一个开箱即用的东西。我们只要打开箱子直接用就行了,怎么用呢?我们要做的就是按照要求,设置输入数据的格式,然后给算法配置参数就可以了。上面我们对 XGBoost 的输入格式做过说明,下面我们先按照格式要求把数据准备好:

# 对于training set 把label数据挪到第一列,去掉表头保存到当前目录
X_train_xgb= pd.concat([y_train,X_train], axis=1)
X_train_xgb.to_csv('./X_train.csv',header=False,index=False)
# 对于validation set 同样的把label数据挪到第一列,去掉表头保存到当前目录
X_valid_xgb= pd.concat([y_valid,X_valid], axis=1)
X_valid_xgb.to_csv('./X_valid.csv',header=False,index=False)
# 把准备的数据输入放到S3的工作目录里
train_data_location = 's3://{}/{}/{}'.format(bucket, prefix, 'train')
validation_data_location = 's3://{}/{}/{}'.format(bucket, prefix, 'validation')
sm_session.upload_data('./X_train.csv',bucket,prefix)
sm_session.upload_data('./X_valid.csv',bucket,prefix)

数据准备好了,下一步就是配置各种参数然后训练。这里是使用了 Amazon SageMaker Python SDK 来完成训练的,这个 SDK 里的 Estimator 这个概念值得说明一下,Estimator SDK 中对任何训练的一种抽象。在 Amazon SageMaker 中你可以使用三类算法来完成训练任务,包括:

  • Amazon SageMaker 自带算法,比如这里用的 XGBoost,还有比如 Object2Vec
  • 公开的一些第三方 ML Framework,比如 TensorFlow MXNet
  • 自带算法

但是不管你使用哪一种算法来训练,在 SDK 中都是通过 estimator.fit 的调用来完成训练。不同之处在于超参的设置,输入数据的格式等等。

# 我们使用SageMaker内置的XGBoost来训练,首先要获取这个算法的containerfrom sagemaker.amazon.amazon_estimator import get_image_uri
container = get_image_uri(region, 'xgboost', repo_version='0.90-2')
# 设置算法超参
hyperparameters = {
        "max_depth":"5",
        "eta":"0.5",
        "early_stopping_rounds":"5",
        "eval_metric":"mae",
        "num_round":"20"}
# 训练使用哪种EC2实例来完成
instance_type = 'ml.m5.2xlarge'
# 模型输出目录
output_path = 's3://{}/{}/output'.format(bucket, prefix)
# 训练输入数据的类型
content_type = "csv"
# 设置训练任务的名字
job_name = 'xgb-housing-' + time.strftime("%Y-%m-%d-%H-%M-%S", time.gmtime())print("Training job", job_name)
# 借助 Managed Spot Training 功能,大幅降低训练成本
train_use_spot_instances = True
train_max_run = 3600
train_max_wait = 7200 if train_use_spot_instances else None
checkpoint_s3_uri = ('s3://{}/{}/checkpoints/{}'.format(bucket, prefix, job_name) 
                     if train_use_spot_instances else None)
# 在SageMaker里的使用任何算法来训练都要先生成一个 estimator 对象
estimator = sagemaker.estimator.Estimator(container,
                                          role,
                                          hyperparameters=hyperparameters,
                                          train_instance_count=1,
                                          train_instance_type=instance_type,
                                          train_volume_size=5,  # 5 GB
                                          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
                                          );# 设置训练数据的 data channel
train_data_location = 's3://{}/{}/{}'.format(bucket, prefix, 'X_train.csv')
validation_data_location = 's3://{}/{}/{}'.format(bucket, prefix, 'X_valid.csv')
train_channel = sagemaker.session.s3_input(train_data_location, content_type='text/csv')
valid_channel = sagemaker.session.s3_input(validation_data_location, content_type='text/csv')
data_channels = {'train': train_channel, 'validation': valid_channel}
# 调用 fit 来训练
estimator.fit(inputs=data_channels, job_name=job_name, logs=True)

评估模型的第一步是要先确立评估的标准——evaluation metric,在这里我们使用 XGBoost 解决回归问题,选择 mae 来作为评估标准,在上面我们调用 fit 启动训练任务的时候,已经通过 hyperparameters 设置了这个评估标准。在训练过程中,我们就可以一直看到这个评估指标的输出情况:

可以看到,经过 20 轮的训练,maetraining set 上是 7241.31,在 validation set 上是 20050.7。我们在一开始的机器学习的生命周期中就已经提到过,训练评估调参是个迭代循环的过程(如下图所示)。

该不断循环过程的目的是得到一个最佳的超参配比,使得评估指标在 validation set 上的效果最优。这里的评估指标就是 mae,数值越小越优。然而,不同算法有不同的超参可以选择,数量很多, 而且对于一个新的问题,如何设置超参通常是一个要依赖实践经验的事情,如果没有很好的经验可以参考,这通常会是一个费时耗力的事情。Amazon SageMaker 提供了一个很方便的功能可以帮我们来实现自动化的调参,找到最佳的超参配比来使得指标最优。在 console 中找到“Hyperparameter tuning jobs”然后点击“Create hyperparameter tuning jobs”开始创建自动化调参任务。

第一步:新建一个名字叫 xgb-housing-tuning 的调参 job

第二步:tuning job 内部需要先有一个 training job,然后通过不断优化超参,来使得 training job 的评估指标最优。这一步就是创建这个 training job,设置名字叫 xgb-housing-training-job 的训练 job,然后在后续的界面中按照图示设置如何自动调参。

可以设置跟 notebook 相同的 role。设置算法的时候选择 Amazon SageMaker 内置的 XGBoost 算法。

objective metric 就是评估指标,我们这里还是选择 mae。在 Hyperparameter configuration 这里,Amazon SageMaker 会自动的把 XGBoost 相关的超参列出来供我们进行调整,可以针对相关的超参选择取值,以及取值范围。这里我们主要设置了eta 的取值范围和 max_depth

在设置输入数据的时候要设置两个 channel,分别对应 training set validation set。默认有一个名叫 trainchannel,另外一个 channel 则需要自己添加,这里注意自己添加的这个 channel 的名字一定要叫 validation,如果用其他的名字会报错。其他需要设置的包括 Input modeContent typeS3 location,按照图示设置就可以了。

在设置 training job 最后一个界面可以勾选使用 spot training,这样可以利用 spot instance 大大节省调参的成本。

第三步,设置最大同时训练任务数(3 次)和总共训练多少次(9 次)

完成以上 hyperparameter tuning job 的创建后,就可以看到调参的运行情况,这里我们可以看到已经有 3 个训练任务在同时运行了。

完成后我们可以看到所有 9 个训练任务的结果,其中 mae 最小值是 16320.2998046875,查看这个训练任务的详情我们就可以得到最佳的超参配比了。

从上面的最优训练结果进入训练结果界面的,在界面的上半部分我们可以到这次的训练,SageMaker 使用 spot training 的方式,实际帮我们节省了 73% 的开销。

在同一个界面的下部可以看到每个超参的取值是多少:

通过上面的不断训练评估调参,如果我们最终得到了一个比较满意的超参配比。这个超参配比就是我们上面调参的最终目的,然后就可以训练得到最终的模型,训练最终模型的时候要先把 training setvalidation set 的数据合并到一起,这样做是为了使样本数量最齐全,从而得到最好的训练效果。简言之,要想得到最好的模型,我们需要最全的观察数据 + 最好的超参配比。完成最后这一步的方法跟上一节训练的方法完全一样,最终也可以看到一个 training job 界面,类似上图,在这个界面点击“Create Model”就可以把训练结果制作成一个可部署的模型了。建好后,就可以向下图一样在左边的菜单里的 inference->Models 下面看到创建好的模型了。

由此可见,我们为了得到一个真正由于生产环境的模型,可能需要在 training 这个阶段做非常多次的训练,得到非常多的 training job,其中可能只有一个有幸被选中作为最终的、能够被部署的模型。

点击上面任何一个模型后选择“Create endpoint”就可以进入模型的部署界面了。

Create and configure endpoint 这个部署界面,我们除了可以设置一个 endpoint name 以外,还可以通过设置 endpoint configuration 来对不同的模型设置不同的 weight 来做负载均衡,从而实现 A/B testing 的功能,如下图:

在完成以上 endpoint 的部署后,进入完成部署的 endpoint 可以看到刚才 endpoint 里面包含的多个模型,可以单独对任何一个模型,设置权重、调整 instance 数量、设置弹性伸缩。

点击“Configure auto scaling”后就可以通过设置“Maximum instance count”“Target value”来完成这个弹性伸缩的设置:

现在我们要使用上图中的部署好的 endpoint 来做推理。跟上面在训练的时候提到的 Estimator 类似,Amazon SageMaker Python SDK 也对推理调用有统一的抽象,这个名字是 Predictors,任何的推理调用都要首先创建一个 RealTimePredictor,然后调用它的 predict 方法,如下:

from sagemaker.predictor import csv_serializer
# 创建 predictor
xgb_predictor=sagemaker.predictor.RealTimePredictor(
    "xgb-housing", // 这个名字就是上图中蓝色方框中endpoint的name
    sagemaker_session=sm_session,
    serializer=csv_serializer,
    content_type='text/csv')
# 调用predictor的predict方法做推理
xgb_predictor.predict(X_valid.values[0]).decode('utf-8')

注意这里举例调用 predict 方法时,是使用的 Xvalid 的第一行,这个不同于存放在 Xvalid.csv 文件的中的数据(这个数据是 Xvalidxgb),Xvalid 这个 pandas dataframe 中的数据是不包含 label 列的,而 Xvalid.csv 文件的第一列是 label 列。

在本文中,我们以房价评估为例,使用 Amazon SageMaker 的内置的 XGBoost 算法,展示了 Amazon SageMakerML 的整个生命周期中的各项功能。Amazon SageMaker 提供了一连贯的功能,帮助数据科学家高效的、低成本实现端到端,从模型构建到生成环境部署的各种工作。这些功能包括全托管 Jupyter notebook 用来构建模型,后续的自动调参、模型构建、部署、负载均衡、弹性伸缩直达生产环境。其中当数据科学家临时需要 GPU 的时候,可以通过简单的界面操作就可以更换 notebook GPU 实例,在自动训练和自动调参的过程中可以使用 spot training 大大节省训练成本。

这一系列的功能,大大降低了企业使用 ML 所需要的资金门槛和人才门槛,是当今企业通过 ML 来提升竞争力的强有力的平台。

相关文章