1

概括

我通过 Azure 机器学习服务 SDK 在 Azure 容器实例上部署了一个 PyTorch 模型。该模型采用(大)图像以标准 numpy 格式进行分类。

看来,我在服务器端达到了 HTTP 请求大小限制。对模型的请求对大小在 8-9mb 范围内的 PNG 图像成功,对 15mb+ 大小的图像失败。具体来说,它因 413 Request Entity Too Large 而失败。

我假设,作为部署过程的一部分,限制是在正在构建的 Docker 映像中的 Nginx 中设置的。我的问题:鉴于问题是由于 HTTP 请求大小限制,有没有办法在 azureml API 中增加这个限制?

部署过程

部署过程按预期成功。

from azureml.core import Workspace
from azureml.core.model import InferenceConfig, Model
from azureml.core.webservice import AciWebservice, Webservice
from azureml.exceptions import WebserviceException
from pathlib import Path

PATH = Path('/data/home/azureuser/my_project')

ws = Workspace.from_config()
model = ws.models['my_pytorch_model']

inference_config = InferenceConfig(source_directory=PATH/'src',
                                   runtime='python',
                                   entry_script='deployment/scoring/scoring.py',
                                   conda_file='deployment/environment/env.yml')

deployment_config = AciWebservice.deploy_configuration(cpu_cores=2, memory_gb=4)
aci_service_name = 'azure-model'

try:
    service = Webservice(ws, name=aci_service_name)
    if service:
        service.delete()
except WebserviceException as e:
    print()

service = Model.deploy(ws, aci_service_name, [model], inference_config, deployment_config)

service.wait_for_deployment(True)
print(service.state)

通过测试requests

使用请求的简单测试:

import os
import json
import numpy as np
import requests
from PIL import Image as PilImage

test_data = np.array(PilImage.open(PATH/'src/deployment/test/test_image.png')).tolist()
test_sample = json.dumps({'raw_data': 
    test_data
})
test_sample_encoded = bytes(test_sample, encoding='utf8')

headers = {
    'Content-Type': 'application/json'
}

response = requests.post(
    service.scoring_uri,
    data=test_sample_encoded,
    headers=headers,
    verify=True,
    timeout=10
)

requests对于较大的文件会产生以下错误:

ConnectionError: ('Connection aborted.', BrokenPipeError(32, 'Broken pipe'))

我猜这是请求中的一个已知错误,当​​在数据上传完成之前从服务器关闭连接时。

通过测试pycurl

使用 curl 包装器,我得到了更可解释的响应。

import pycurl
from io import BytesIO

c = pycurl.Curl()
b = BytesIO()

c.setopt(c.URL, service.scoring_uri)
c.setopt(c.POST, True)
c.setopt(c.HTTPHEADER,['Content-Type: application/json'])
c.setopt(pycurl.WRITEFUNCTION, b.write)
c.setopt(c.POSTFIELDS, test_sample)
c.setopt(c.VERBOSE, True)
c.perform()

out = b.getvalue()

b.close()
c.close()

print(out)

对于大文件,这会产生以下错误:

<html>
    <head>
        <title>
            413 Request Entity Too Large
        </title>
    </head>
    <body bgcolor="white">
        <center>
            <h1>
                413 Request Entity Too Large
            </h1>
        </center>
        <hr>
        <center>
                nginx/1.10.3 (Ubuntu)
        </center>
    </body>
</html>

让我相信这是 Nginx 配置中的一个问题。具体来说,我猜 client_max_body_size 设置为 10mb。

问题总结

鉴于我确实遇到了 Nginx 配置的问题,我可以以某种方式更改它吗?如果不使用 Azure 机器学习服务 SDK,那么可能通过覆盖/etc/nginx/nginx.conf文件?

4

2 回答 2

0

在构建的镜像中,nginx 配置中的 client_max_body_size 设置为 100m。不支持更改 nginx 配置。

于 2019-10-02T17:41:45.490 回答
-1

为了对大数据进行评分,您可能需要研究不同的架构。在 HTTP 请求正文中传递大量原始数据并不是最有效的方式。

例如,您可以构建评分管道。例如,请参阅此笔记本:管道样式转移

或者,如果您想使用 ACI Web 服务,您可以将图像暂存到 blob 存储,然后通过引用 blob 位置来传递图像。

于 2019-10-02T14:59:59.173 回答