python 在AWS Sagemaker中训练scikit学习模型时无法创建model.tar.gz文件

5n0oy7gb  于 2022-12-17  发布在  Python
关注(0)|答案(3)|浏览(165)

我想在AWS Sagemaker中为scikit logistic回归创建一个端点。我有一个train.py文件,其中包含scikit Sagemaker的训练代码。

import subprocess as sb
import pandas as pd
import numpy as np
import pickle,json
import sys

def install(package):
    sb.call([sys.executable, "-m", "pip", "install", package])

install('s3fs')

import argparse
import os

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

    # hyperparameters sent by the client are passed as command-line arguments to the script.
    parser.add_argument('--solver', type=str, default='liblinear')

    # Data, model, and output directories
    parser.add_argument('--output_data_dir', type=str, default=os.environ.get('SM_OUTPUT_DIR'))
    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'))

    args, _ = parser.parse_known_args()

    # ... load from args.train and args.test, train a model, write model to args.model_dir.

    input_files = [ os.path.join(args.train, file) for file in os.listdir(args.train) ]
    if len(input_files) == 0:
        raise ValueError(('There are no files in {}.\n' +
                          'This usually indicates that the channel ({}) was incorrectly specified,\n' +
                          'the data specification in S3 was incorrectly specified or the role specified\n' +
                          'does not have permission to access the data.').format(args.train, "train"))

    raw_data = [ pd.read_csv(file, header=None, engine="python") for file in input_files ]

    df = pd.concat(raw_data)

    y = df.iloc[:,0]
    X = df.iloc[:,1:]


    solver = args.solver
    from sklearn.linear_model import LogisticRegression
    lr = LogisticRegression(solver=solver).fit(X, y)
from sklearn.externals import joblib
def model_fn(model_dir):
    lr = joblib.dump(lr, "model.joblib")
    return lr

在我的sagemaker笔记本中,我运行了以下代码

import os
import boto3
import re
import copy
import time
from time import gmtime, strftime
from sagemaker import get_execution_role
import sagemaker

role = get_execution_role()

region = boto3.Session().region_name

bucket=<bucket> # Replace with your s3 bucket name
prefix = <prefix>

output_path = 's3://{}/{}/{}'.format(bucket, prefix,'output_data_dir')
train_data = 's3://{}/{}/{}'.format(bucket, prefix, 'train')
train_channel = sagemaker.session.s3_input(train_data, content_type='text/csv')

from sagemaker.sklearn.estimator import SKLearn
sklearn = SKLearn(
    entry_point='train.py',
    train_instance_type="ml.m4.xlarge",
    role=role,output_path = output_path,
    sagemaker_session=sagemaker.Session(),
    hyperparameters={'solver':'liblinear'})

我在这里试我的模型

sklearn.fit({'train': train_channel})

现在,为了创建端点,

from sagemaker.predictor import csv_serializer
predictor = sklearn.deploy(1, 'ml.m4.xlarge')

尝试创建终结点时,它正在引发

ClientError: An error occurred (ValidationException) when calling the CreateModel operation: Could not find model data at s3://<bucket>/<prefix>/output_data_dir/sagemaker-scikit-learn-x-y-z-000/output/model.tar.gz.

我检查了我的S3 bucket。在我的output_data_dir中有sagemaker-scikit-learn-x-y-z-000目录,其中有debug-output\training_job_end.ts文件。在我的<prefix>文件夹之外创建了一个额外的目录,名称为sagemaker-scikit-learn-x-y-z-000,其中有source\sourcedir.tar.gz文件。通常每当我用sagemaker内置算法训练我的模型时,output_data_dir\sagemaker-scikit-learn-x-y-z-000\output\model.tar.gz类型的文件被创建。有人能告诉我我的scikit模型被存储在哪里,如何在没有手动操作的情况下将source\sourcedir.tar.gz推入我的前缀代码,以及如何查看sourcedir.tar.gz的内容吗?
编辑:我详细阐述了关于prefix的问题。每当我运行sklearn.fit()时,在我的S3存储桶中创建了两个名称相同的文件sagemaker-scikit-learn-x-y-z-000。一个在我的<bucket>/<prefix>/output_data_dir/sagemaker-scikit-learn-x-y-z-000/debug-output/training_job_end.ts中创建,另一个在<bucket>/sagemaker-scikit-learn-x-y-z-000/source/sourcedir.tar.gz中创建。为什么第二个文件没有像第一个那样在我的<prefix>中创建?sourcedir.tar.gz文件中包含什么?

mwyxok5s

mwyxok5s1#

我不确定你的模型是否真的被存储了,如果你在S3中找不到它的话,当你在你的入口点脚本中定义一个调用joblib.dump的函数时,我在main的末尾调用了这个函数,例如:

# persist model
path = os.path.join(args.model_dir, "model.joblib")
joblib.dump(myestimator, path)
print('model persisted at ' + path)

然后可以在..\output\model.tar.gz中找到该文件,就像在其他情况下一样。为了仔细检查所创建的文件,您可能希望在培训方案中找到一个print语句。

qv7cva1a

qv7cva1a2#

您必须将模型转储为训练代码的最后一步。当前您在错误的位置执行此操作,因为model_fn的目标是加载模型用于推理,而不是用于训练。
1.培训后添加转储:

lr = LogisticRegression(solver=solver).fit(X, y)
lr = joblib.dump(lr, args.model_dir)

1.更改model_fn()以加载模型而不是转储模型。
查看更多here

fgw7neuy

fgw7neuy3#

这篇文章很好地解释了这一点:https://towardsdatascience.com/deploying-a-pre-trained-sklearn-model-on-amazon-sagemaker-826a2b5ac0b6
简而言之,tar.gz是通过tar-gz-ing model.joblib二进制文件创建的,该文件最初是由joblib. dump创建的。

#Build tar file with model data + inference code
bashCommand = "tar -cvpzf model.tar.gz model.joblib inference.py"
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()

inference.py可能是可选的。

相关问题