使用 AWS SageMaker Python SDK 批量转换稀疏矩阵

iva*_*ler 5 python sparse-matrix amazon-web-services scikit-learn amazon-sagemaker

我已使用 AWS SageMaker 成功训练了 Scikit-Learn LSVC 模型。
我想在一个相对较大的数据集上进行批量预测(又名批量变换),该数据集是一个形状为 252772 x 185128 的 scipy 稀疏矩阵。(特征数量很高,因为存在词袋的单热编码和 ngrams 特征)。

我之所以挣扎是因为:

  • 数据的大小

  • 数据的格式

我做了几个实验来检查发生了什么:

1. 对样本稀疏矩阵数据进行本地预测

它的工作原理
是在 SageMaker 笔记本上本地反序列化模型工件并根据稀疏矩阵的样本进行预测。
这只是为了检查模型是否可以对此类数据进行预测。

2. 对样本 csv 数据进行批量转换

它有效
在 SageMaker 上启动批量转换作业并请求以密集 csv 格式转换小样本:它有效,但显然无法扩展。
代码是:

sklearn_model = SKLearnModel(
    model_data=model_artifact_location_on_s3,
    entry_point='my_script.py',
    role=role,
    sagemaker_session=sagemaker_session)

transformer = sklearn_model.transformer(
   instance_count=1, 
   instance_type='ml.m4.xlarge', 
   max_payload=100)

transformer.transform(
   data=batch_data, 
   content_type='text/csv',
   split_type=None)   

print('Waiting for transform job: ' + transformer.latest_transform_job.job_name)
transformer.wait()

Run Code Online (Sandbox Code Playgroud)

在哪里:

  • 'my_script.py' 实现了一个简单的model_fn反序列化模型工件:
def model_fn(model_dir):
    clf = joblib.load(os.path.join(model_dir, "model.joblib"))
    return clf
Run Code Online (Sandbox Code Playgroud)
  • batch_data是 csv 文件的 s3 路径。

3. 样本密集 numpy 数据集的批量转换。


准备了一个数据样本并将其以 Numpy.npy格式保存到 s3 。根据此文档,SageMaker Scikit-learn 模型服务器可以反序列化 NPY 格式的数据(以及 JSON 和 CSV 数据)。
与之前的实验(2)唯一的区别是content_type='application/x-npy'中的参数transformer.transform(...)

该解决方案无法扩展,我们想传递一个 Scipy 稀疏矩阵:

4. 大稀疏矩阵的批量变换。


这是SageMaker Python SDK 不支持开箱即用的稀疏矩阵格式的问题。
按照此:

我曾经write_spmatrix_to_sparse_tensor在 s3 上将数据写入 protobuf 格式。我使用的函数是:

def write_protobuf(X_sparse, bucket, prefix, obj):
    """Write sparse matrix to protobuf format at location bucket/prefix/obj."""
    buf = io.BytesIO()
    write_spmatrix_to_sparse_tensor(file=buf, array=X_sparse, labels=None)
    buf.seek(0)
    key = '{}/{}'.format(prefix, obj)
    boto3.resource('s3').Bucket(bucket).Object(key).upload_fileobj(buf)
    return 's3://{}/{}'.format(bucket, key)
Run Code Online (Sandbox Code Playgroud)

那么用于启动批量转换作业的代码是:

sklearn_model = SKLearnModel(
    model_data=model_artifact_location_on_s3,
    entry_point='my_script.py',
    role=role,
    sagemaker_session=sagemaker_session)

transformer = sklearn_model.transformer(
   instance_count=1, 
   instance_type='ml.m4.xlarge', 
   max_payload=100)

transformer.transform(
   data=batch_data, 
   content_type='application/x-recordio-protobuf',
   split_type='RecordIO')   

print('Waiting for transform job: ' + transformer.latest_transform_job.job_name)
transformer.wait()
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

sagemaker_containers._errors.ClientError: Content type application/x-recordio-protobuf is not supported by this framework.
Run Code Online (Sandbox Code Playgroud)

问题:
(Transformer 参考文档:https://sagemaker.readthedocs.io/en/stable/transformer.html

  • 如果content_type='application/x-recordio-protobuf'不允许,我应该使用什么?
  • split_type='RecordIO'在这种情况下设置是否正确 ?
  • 我应该在脚本中提供一个input_fn函数来反序列化数据吗?
  • 还有其他更好的方法来解决这个问题吗?