批量转换作业导致数据文件> 100MB的“ InternalServerError”

时间:2019-05-29 05:43:40

标签: python tensorflow amazon-sagemaker

我正在使用Sagemaker来对时间序列执行二进制分类,每个样本都是一个形状为[24,11](24h,11个特征)的numpy数组。我在脚本模式下使用了一个张量流模型,我的脚本与我用作参考的脚本非常相似: https://github.com/awslabs/amazon-sagemaker-examples/blob/master/sagemaker-python-sdk/tensorflow_script_mode_training_and_serving/mnist.py

该培训取得了成功,因此我能够部署一个用于批量转换的模型。当我仅输入几个样本(例如[10,24,11])时,变换作业就可以正常工作,但是当我输入更多样本进行预测(例如,[30000、24、11]时,它会返回InternalServerError ],其大小> 100MB)。

这是错误:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-0c46f7563389> in <module>()
     32 
     33 # Then wait until transform job is completed
---> 34 tf_transformer.wait()

~/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/sagemaker/transformer.py in wait(self)
    133     def wait(self):
    134         self._ensure_last_transform_job()
--> 135         self.latest_transform_job.wait()
    136 
    137     def _ensure_last_transform_job(self):

~/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/sagemaker/transformer.py in wait(self)
    207 
    208     def wait(self):
--> 209         self.sagemaker_session.wait_for_transform_job(self.job_name)
    210 
    211     @staticmethod

~/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/sagemaker/session.py in wait_for_transform_job(self, job, poll)
    893         """
    894         desc = _wait_until(lambda: _transform_job_status(self.sagemaker_client, job), poll)
--> 895         self._check_job_status(job, desc, 'TransformJobStatus')
    896         return desc
    897 

~/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/sagemaker/session.py in _check_job_status(self, job, desc, status_key_name)
    915             reason = desc.get('FailureReason', '(No reason provided)')
    916             job_type = status_key_name.replace('JobStatus', ' job')
--> 917             raise ValueError('Error for {} {}: {} Reason: {}'.format(job_type, job, status, reason))
    918 
    919     def wait_for_endpoint(self, endpoint, poll=5):

ValueError: Error for Transform job Tensorflow-batch-transform-2019-05-29-02-56-00-477: Failed Reason: InternalServerError: We encountered an internal error.  Please try again.

在部署模型时,我尝试同时使用SingleRecord和MultiRecord参数,但结果相同,因此我决定保留MultiRecord。我的变压器看起来像这样:

transformer = tf_estimator.transformer(
    instance_count=1, 
    instance_type='ml.m4.xlarge',
    max_payload = 100,
    assemble_with = 'Line',
    strategy='MultiRecord'
)

起初,我使用json文件作为转换作业的输入,它引发了错误:

Too much data for max payload size

因此,接下来我尝试了jsonlines格式(据我所知,不支持.npy格式),以为jsonlines可能会被Line分割,从而避免了大小错误,但这就是我得到{{1} }。这是相关的代码:

InternalServerError

名为test_x_list的列表的形状为[30000,24,11],它对应于30000个样本,所以我想返回30000个预测。

我怀疑我的jsonlines文件没有被Line分割,并且当然太大,无法批量处理,这会引发错误,但是我不明白为什么它无法正确分割。我使用的是默认的output_fn和input_fn(我没有在脚本中重写这些函数)。

任何对我可能做错事的见解将不胜感激。

1 个答案:

答案 0 :(得分:0)

我认为这是此AWS论坛帖子的重复:https://forums.aws.amazon.com/thread.jspa?threadID=303810&tstart=0

无论如何,出于完整性考虑,我也会在这里回答。

问题在于,将数据集转换为jsonlines时,您未正确序列化数据集:

test_x_list = test_x.tolist()
...
with jsonlines.open(file_path, 'w') as writer:
    writer.write(test_x_list)   

上面的操作是创建一个非常大的单行,其中包含您的完整数据集,对于单次推理调用而言,它太大了,无法使用。

我建议您更改代码以使每一行成为单个样本,以便可以对单个样本而不是整个数据集进行推断:

test_x_list = test_x.tolist()
...
with jsonlines.open(file_path, 'w') as writer:
    for sample in test_x_list:
        writer.write(sample)

如果一次采样太慢,您还可以使用max_concurrent_transformsstrategymax_payload参数来批处理数据并同时运行如果您的算法可以并行运行,则转换-当然,您也可以将数据拆分为多个文件,并使用多个节点运行转换。有关这些参数的作用的更多详细信息,请参见https://sagemaker.readthedocs.io/en/latest/transformer.htmlhttps://docs.aws.amazon.com/sagemaker/latest/dg/API_CreateTransformJob.html