Amazon SageMaker:使用 multipart/form-data 文件调用终端节点
Amazon SageMaker: Invoke endpoint with file as multipart/form-data
在 Amazon SageMaker 上为我的模型设置端点后,我尝试使用 POST 请求调用它,该请求包含一个键为 image
且内容类型为 [=14] 的文件=].
我的 AWS CLI 命令是这样的:
aws sagemaker-runtime invoke-endpoint --endpoint-name <endpoint-name> --body image=@/local/file/path/dummy.jpg --content-type multipart/form-data output.json --region us-east-1
这应该相当于:
curl -X POST -F "image=@/local/file/path/dummy.jpg" http://<endpoint>
在 运行 aws
命令后,文件没有通过请求传输,我的模型正在接收没有任何文件的请求。
谁能告诉我 aws
命令的正确格式应该是什么才能实现此目的?
第一个问题是您正在为 CURL 请求使用 'http'。几乎所有 AWS 服务都严格使用 'https' 作为其协议,包括 SageMaker。 https://docs.aws.amazon.com/general/latest/gr/rande.html。不过我会假设这是一个错字。
您可以通过将“--debug”参数传递给您的调用来检查 AWS CLI 的详细输出。我用我最喜欢的 duck.jpg 图片重新 运行 做了一个类似的实验:
aws --debug sagemaker-runtime invoke-endpoint --endpoint-name MyEndpoint --body image=@/duck.jpg --content-type multipart/form-data >(cat)
查看输出,我看到:
2018-08-10 08:42:20,870 - MainThread - botocore.endpoint - DEBUG - Making request for OperationModel(name=InvokeEndpoint) (verify_ssl=True) with params: {'body': 'image=@/duck.jpg', 'url': u'https://sagemaker.us-west-2.amazonaws.com/endpoints/MyEndpoint/invocations', 'headers': {u'Content-Type': 'multipart/form-data', 'User-Agent': 'aws-cli/1.15.14 Python/2.7.10 Darwin/16.7.0 botocore/1.10.14'}, 'context': {'auth_type': None, 'client_region': 'us-west-2', 'has_streaming_input': True, 'client_config': <botocore.config.Config object at 0x109a58ed0>}, 'query_string': {}, 'url_path': u'/endpoints/MyEndpoint/invocations', 'method': u'POST'}
看起来 AWS CLI 使用的是字符串文字“@/duck.jpg”,而不是文件内容。
再次尝试使用 curl 和“--verbose”标志:
curl --verbose -X POST -F "image=@/duck.jpg" https://sagemaker.us-west-2.amazonaws.com/endpoints/MyEndpoint/invocations
我看到以下内容:
Content-Length: 63097
好多了。 '@' 运算符是 CURL 特定的功能。 AWS CLI 确实有一种传递文件的方法:
--body fileb:///duck.jpg
还有一个 'file' 用于非二进制文件,例如 JSON。不幸的是你不能有前缀。也就是说,你不能说:
--body image=fileb:///duck.jpg
您可以使用如下命令将字符串 'image=' 添加到您的文件中。 (如果你的图像真的很大,你可能需要更聪明;这真的很低效。)
echo -e "image=$(cat /duck.jpg)" > duck_with_prefix
您的最终命令将是:
aws sagemaker-runtime invoke-endpoint --endpoint-name MyEndpoint --body fileb:///duck_with_prefix --content-type multipart/form-data >(cat)
另一个注意事项:由于 AWS 身份验证签名要求,将原始 curl 与 AWS 服务一起使用非常困难 - https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html
可以做到,但使用 AWS CLI 或 Postman 等现有工具可能会提高工作效率 - https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-use-postman-to-call-api.html
在 Amazon SageMaker 上为我的模型设置端点后,我尝试使用 POST 请求调用它,该请求包含一个键为 image
且内容类型为 [=14] 的文件=].
我的 AWS CLI 命令是这样的:
aws sagemaker-runtime invoke-endpoint --endpoint-name <endpoint-name> --body image=@/local/file/path/dummy.jpg --content-type multipart/form-data output.json --region us-east-1
这应该相当于:
curl -X POST -F "image=@/local/file/path/dummy.jpg" http://<endpoint>
在 运行 aws
命令后,文件没有通过请求传输,我的模型正在接收没有任何文件的请求。
谁能告诉我 aws
命令的正确格式应该是什么才能实现此目的?
第一个问题是您正在为 CURL 请求使用 'http'。几乎所有 AWS 服务都严格使用 'https' 作为其协议,包括 SageMaker。 https://docs.aws.amazon.com/general/latest/gr/rande.html。不过我会假设这是一个错字。
您可以通过将“--debug”参数传递给您的调用来检查 AWS CLI 的详细输出。我用我最喜欢的 duck.jpg 图片重新 运行 做了一个类似的实验:
aws --debug sagemaker-runtime invoke-endpoint --endpoint-name MyEndpoint --body image=@/duck.jpg --content-type multipart/form-data >(cat)
查看输出,我看到:
2018-08-10 08:42:20,870 - MainThread - botocore.endpoint - DEBUG - Making request for OperationModel(name=InvokeEndpoint) (verify_ssl=True) with params: {'body': 'image=@/duck.jpg', 'url': u'https://sagemaker.us-west-2.amazonaws.com/endpoints/MyEndpoint/invocations', 'headers': {u'Content-Type': 'multipart/form-data', 'User-Agent': 'aws-cli/1.15.14 Python/2.7.10 Darwin/16.7.0 botocore/1.10.14'}, 'context': {'auth_type': None, 'client_region': 'us-west-2', 'has_streaming_input': True, 'client_config': <botocore.config.Config object at 0x109a58ed0>}, 'query_string': {}, 'url_path': u'/endpoints/MyEndpoint/invocations', 'method': u'POST'}
看起来 AWS CLI 使用的是字符串文字“@/duck.jpg”,而不是文件内容。
再次尝试使用 curl 和“--verbose”标志:
curl --verbose -X POST -F "image=@/duck.jpg" https://sagemaker.us-west-2.amazonaws.com/endpoints/MyEndpoint/invocations
我看到以下内容:
Content-Length: 63097
好多了。 '@' 运算符是 CURL 特定的功能。 AWS CLI 确实有一种传递文件的方法:
--body fileb:///duck.jpg
还有一个 'file' 用于非二进制文件,例如 JSON。不幸的是你不能有前缀。也就是说,你不能说:
--body image=fileb:///duck.jpg
您可以使用如下命令将字符串 'image=' 添加到您的文件中。 (如果你的图像真的很大,你可能需要更聪明;这真的很低效。)
echo -e "image=$(cat /duck.jpg)" > duck_with_prefix
您的最终命令将是:
aws sagemaker-runtime invoke-endpoint --endpoint-name MyEndpoint --body fileb:///duck_with_prefix --content-type multipart/form-data >(cat)
另一个注意事项:由于 AWS 身份验证签名要求,将原始 curl 与 AWS 服务一起使用非常困难 - https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html
可以做到,但使用 AWS CLI 或 Postman 等现有工具可能会提高工作效率 - https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-use-postman-to-call-api.html