无法使用自定义算法运行训练

问题描述 投票:0回答:1

我正在尝试使用 Sagemaker 的训练作业和 Sagemaker Python SDK 来运行训练,训练脚本依赖于一些自定义库。根据我的理解,由于自定义脚本,我需要使用已注册到 ECR(弹性容器注册表)的 docker 容器生成自定义映像。下面的环境是 Sagemaker Studio 代码编辑器。

我得到的错误是

Failed to parse hyperparameter
。请参阅下文了解我的设置以及我尝试过的解决方案。

目录

working directory
    —Dockerfile
    —train.py
    —requirements.txt 

Dockerfile

# Use python image as base
FROM python:3.10

# Install system dependencies
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        libpq-dev \
        gcc \
    && rm -rf /var/lib/apt/lists/*

# Set working directory in container
COPY code /opt/program
WORKDIR /code

# Install Python dependencies
COPY requirements.txt /code/
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install sagemaker-training

# Copies the training code inside the container
COPY train.py /opt/ml/code/train.py

# Defines train.py as script entrypoint
ENV SAGEMAKER_PROGRAM train.py

# Set environment variables
ENV PYTHONUNBUFFERED=TRUE
ENV PYTHONDONTWRITEBYTECODE=TRUE
ENV PATH="/opt/program:${PATH}"

需求.txt

simpletransformers==0.70.0
pandas==2.1.1
numpy==1.26.0
torch==2.2.1
sklearn-deap==0.3.0
sklearn-genetic-opt==0.10.1
boto3==1.33.3
sagemaker

火车.py

import argparse
import os
import logging
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, f1_score
from simpletransformers.classification import ClassificationModel
import torch

from sagemaker_pytorch_estimator.pytorch_estimator import PyTorchModel
from sagemaker_containers.data_instances.data_buffer import BufferDataset, BufferedShuffledDataset

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())

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

    parser.add_argument("--batch_size", type=int, default=32)
    parser.add_argument("--test_size", type=float, default=0.2)
    parser.add_argument("--target_column", type=str, default="annotation")
    parser.add_argument("--vertical", type=str, default="some_category")
    parser.add_argument("--model_dir", type=str, default=os.environ.get("SM_MODEL_DIR"))
    parser.add_argument("--train", type=str, default=os.environ.get("SM_CHANNEL_TRAIN"))
    parser.add_argument("--val", type=str, default=os.environ.get("SM_CHANNEL_VAL"))
    parser.add_argument("--test", type=str, default=os.environ.get("SM_CHANNEL_TEST"))

    args, _ = parser.parse_known_args()

    model_data = None
    role = None
    entry_point = None

    ....(script continues)

启动脚本:

import sagemaker
from sagemaker.session import TrainingInput
from sagemaker.estimator import Estimator

vertical = 'some_category'
s3_bucket = 'some_bucker'
prefix = 'classification'
instance_type = 'ml.m4.xlarge' 
print("Instance Type: {}".format(instance_type))

region = sagemaker.Session().boto_region_name
print("AWS Region: {}".format(region))

role = sagemaker.get_execution_role()
print("RoleArn: {}".format(role))

s3_output_location='s3://{}/{}/{}'.format(s3_bucket, prefix, 'classifier')
container = '############.###.###.##-####-#.amazonaws.com/some-name/ml-training:latest'
print("Image Container: {}".format(container))

estimator = Estimator(
    image_uri=container,
    role=role,
    instance_count=1,
    instance_type=instance_type,
    volume_size=10,
    output_path=s3_output_location,
    sagemaker_session=sagemaker.Session()
)

estimator.set_hyperparameters(vertical=vertical,
                              s3_bucket=s3_bucket,
                              target_column='annotation',
                              test_size=0.2)

estimator.fit()

错误

Failed to parse hyperparameter 

我尝试过的解决方案:

  1. 对于 sagemaker-training 库来说似乎是一个
     开放问题 
    。唯一的建议是将超参数包装在一些用户建议的函数周围,但这似乎不是当前有效的解决方案(出现此错误:
    TypeError: Estimator.set_hyperparameters() takes 1 positional argument but 2 were given
  2. 这里有一些建议,但我不知道如何将它们应用到我的情况。
  3. 这篇SO post声称
    argparse
    与Sagemaker不兼容(所有官方aws sagemaker文档都使用
    argparse
    )。我不清楚他们建议的解决方案。
amazon-web-services machine-learning containers amazon-sagemaker amz-sagemaker-distributed-training
1个回答
1
投票

这里有几个话题需要讨论。首先,您不需要创建一个容器只是为了包含额外的依赖项。

通过估算器使用额外的依赖项

您可以通过提供

source_dir
并在引用的源目录中包含requirements.txt 文件来向估算器添加依赖项。

来自 Estimator API 文档

源目录 除条目外具有任何其他训练源代码依赖项的目录的绝对、相对或 S3 URI 路径 点文件。如果 source_dir 是 S3 URI,则它必须指向 tar.gz 文件。训练时会保留此目录中的结构 亚马逊 SageMaker。

包含

source_dir
的最直接方法是将其本地放在笔记本旁边。

|----- example-notebook.ipynb
|----- src
        |----- train.py
        |----- requirements.txt

然后,您可以将估算器配置为使用具有以下配置的源目录:

estimator = Estimator(
    [...]
    entry_point="train.py",
    source_dir="src",
    [...]
)

如果指定了

source_dir
,则
entry_point
必须指向位于
source_dir
根目录的文件。训练作业将自动安装所提供的依赖项
requirements.txt

由于您使用的是 Scikit-Learn,因此您还可以使用 SKLearn Estimator,它已经捆绑了多个依赖项,并与通用 Estimator 相比提供了简化的界面。

修复超参数解析

如果您想按原样使用代码,那么您可以按如下方式调整代码:

import json

# JSON encode hyperparameters
def json_encode_hyperparameters(hyperparameters):
    return {str(k): json.dumps(v) for (k, v) in hyperparameters.items()}


hyperparameters = json_encode_hyperparameters({
    "vertical": vertical,
    "s3_bucket": s3_bucket,
    "target_column": target_column, 
    "test_size": 0.2
})

estimator = Estimator(
    image_uri=container,
    role=role,
    instance_count=1,
    instance_type=instance_type,
    volume_size=10,
    output_path=s3_output_location,
    sagemaker_session=sagemaker.Session(),
    hyperparameters=hyperparameters
)

set_hyperparameters
期望输入为
kwargs
,而
hyperparameters
属性接受不同格式的输入。因此,您不能将 JSON 编码的字典与
set_hyperparameters
一起使用;相反,请将其与
hyperparameters
属性一起使用。

© www.soinside.com 2019 - 2024. All rights reserved.