Задание пакетного преобразования приводит к ошибке «InternalServerError» с файлом данных > 100 МБ

Я использую Sagemaker для выполнения бинарной классификации временных рядов, каждая выборка представляет собой пустой массив формы [24,11] (24h, 11features). Я использовал модель тензорного потока в режиме сценария, мой сценарий очень похож на тот, который я использовал в качестве эталона: https://github.com/awslabs/amazon-sagemaker-examples/blob/master/sagemaker-python-sdk/tensorflow_script_mode_training_and_serving/mnist.py

Обучение показало успех, и я смог развернуть модель для пакетного преобразования. Задание преобразования работает нормально, когда я ввожу всего несколько выборок (скажем, [10,24,11]), но возвращает InternalServerError, когда я ввожу больше выборок для предсказания (например, [30000, 24, 11], размер которых >100 МБ).

Вот ошибка:

---------------------------------------------------------------------------
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 можно разделить по строке и, таким образом, избежать ошибки размера, но именно здесь я получил InternalServerError. Вот соответствующий код:

#Convert test_x to jsonlines and save
test_x_list = test_x.tolist()
file_path ='data_cnn_test/test_x.jsonl'
file_name='test_x.jsonl'

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

input_key = 'batch_transform_tf/input/{}'.format(file_name)
output_key = 'batch_transform_tf/output'
test_input_location = 's3://{}/{}'.format(bucket, input_key)
test_output_location = 's3://{}/{}'.format(bucket, output_key)

s3.upload_file(file_path, bucket, input_key)

# Initialize the transformer object
tf_transformer = sagemaker.transformer.Transformer(
    base_transform_job_name='Tensorflow-batch-transform',
    model_name='sagemaker-tensorflow-scriptmode-2019-05-29-02-46-36-162',
    instance_count=1,
    instance_type='ml.c4.2xlarge',
    output_path=test_output_location,
    assemble_with = 'Line'
    )

# Start the transform job
tf_transformer.transform(test_input_location, content_type='application/jsonlines', split_type='Line')

Список с именем test_x_list имеет форму [30000, 24, 11], что соответствует 30000 выборкам, поэтому я хотел бы вернуть 30000 прогнозов.

Я подозреваю, что мой файл jsonlines не разбивается Line и, конечно, слишком велик для обработки в одном пакете, что вызывает ошибку, но я не понимаю, почему он не разбивается правильно. Я использую output_fn и input_fn по умолчанию (я не переписывал эти функции в своем сценарии).

Буду очень признателен за любое понимание того, что я могу делать неправильно.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
1 517
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я предполагаю, что это дубликат сообщения на форуме 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_transforms, strategy и max_payload, чтобы иметь возможность пакетировать данные, а также запускать параллельные преобразования, если ваш алгоритм может работать параллельно — также, конечно, вы может разбить данные на несколько файлов и выполнять преобразования более чем с одним узлом. Дополнительные сведения о том, что делают эти параметры, см. в https://sagemaker.readthedocs.io/en/latest/transformer.html и https://docs.aws.amazon.com/sagemaker/latest/dg/API_CreateTransformJob.html.

Другие вопросы по теме