你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
Azure 机器学习推理 HTTP 服务器是一个 Python 包,它以 HTTP 终结点的形式公开评分函数,并将 Flask 服务器代码和依赖项包装到单一包中。 推理服务器包含在 预生成的 Docker 映像 中,用于在 Azure 机器学习中部署模型时使用的推理。 单独使用包时,可以在本地部署模型进行生产。 还可以在本地开发环境中轻松验证评分(入口)脚本。 如果评分脚本出现问题,推理服务器将返回错误和错误的位置。
还可以使用推理服务器在持续集成和部署管道中创建验证入口。 例如,可以使用候选脚本启动推理服务器,并针对本地终结点运行测试套件。
本文支持想要使用推理服务器在本地调试的开发人员。 本文介绍如何将推理服务器与联机终结点配合使用。
先决条件
- Python 3.8 或更高版本
- 蟒蛇
推理服务器在基于 Windows 和 Linux 的作系统上运行。
了解联机终结点的本地调试选项
通过在部署到云之前在本地调试终结点,可以提前捕获代码和配置中的错误。 若要在本地调试终结点,可以使用多个选项,包括:
- Azure 机器学习推理 HTTP 服务器。
- 本地终结点。
下表概述了每个选项针对各种调试方案提供的支持:
场景 | 推理服务器 | 本地终结点 |
---|---|---|
更新本地 Python 环境,而无需重新生成 Docker 映像 | 是 | 否 |
更新评分脚本 | 是 | 是 |
更新部署配置(部署、环境、代码、模型) | 否 | 是 |
集成 Microsoft Visual Studio Code (VS Code) 调试器 | 是 | 是 |
本文介绍如何使用推理服务器。
在本地运行推理服务器时,可以专注于调试评分脚本,而不必担心部署容器配置。
在本地调试评分脚本
若要在本地调试评分脚本,可以使用多个选项测试推理服务器行为:
- 使用虚拟评分脚本。
- 使用 VS Code 通过 azureml-inference-server-http 包进行调试。
- 从 示例存储库运行实际的评分脚本、模型文件和环境文件。
以下部分提供有关每个选项的信息。
使用虚拟评分脚本测试推理服务器行为
创建名为server_quickstart的目录以保存文件:
mkdir server_quickstart cd server_quickstart
若要避免包冲突,请创建虚拟环境,例如
myenv
,并激活它:python -m virtualenv myenv
注意
在 Linux 上,运行
source myenv/bin/activate
命令来激活虚拟环境。测试推理服务器后,可以运行
deactivate
命令来停用 Python 虚拟环境。从 Python 包索引 (PyPI) 源安装
azureml-inference-server-http
包:python -m pip install azureml-inference-server-http
创建入口脚本。 以下示例创建一个基本条目脚本并将其保存到名为 score.py 的文件:
echo -e 'import time\ndef init(): \n\ttime.sleep(1) \n\ndef run(input_data): \n\treturn {"message":"Hello, World!"}' > score.py
azmlinfsrv
使用命令启动推理服务器,并将 score.py 文件设置为条目脚本:azmlinfsrv --entry_script score.py
注意
推理服务器托管在 0.0.0.0 上,这意味着它会侦听托管计算机的所有 IP 地址。
使用
curl
实用工具将评分请求发送到推理服务器:curl -p 127.0.0.1:5001/score
推理服务器发布以下响应:
{"message": "Hello, World!"}
完成测试后,选择 Ctrl+C 以停止推理服务器。
可以修改 score.py 评分脚本文件。 然后,你可以使用 azmlinfsrv --entry_script score.py
命令再次运行推理服务器,以测试更改。
与 VS Code 集成
在 VS Code 中,可以使用 Python 扩展 通过 azureml-inference-server-http 包进行调试。 VS Code 提供两种调试模式: 启动和附加。
在使用任一模式之前,请运行以下命令安装 azureml-inference-server-http
包:
python -m pip install azureml-inference-server-http
注意
为了避免包冲突,请在虚拟环境中安装推理服务器。 可以使用命令 pip install virtualenv
为配置启用虚拟环境。
启动模式
对于启动模式,请执行以下步骤来设置 VS Code launch.json 配置文件,并在 VS Code 中启动推理服务器:
启动 VS Code 并打开包含 score.py 脚本的文件夹。
对于 VS Code 中的该工作区,请将以下配置添加到 launch.json 文件:
{ "version": "0.2.0", "configurations": [ { "name": "Debug score.py", "type": "debugpy", "request": "launch", "module": "azureml_inference_server_http.amlserver", "args": [ "--entry_script", "score.py" ] } ] }
通过选择 “运行>开始调试 ”或选择 F5,在 VS Code 中启动调试会话。
附加模式
对于附加模式,请执行以下步骤,将 VS Code 与 Python 扩展一起使用以附加到推理服务器进程:
注意
对于 Linux,请先运行 gdb
命令安装 sudo apt-get install -y gdb
包。
启动 VS Code 并打开包含 score.py 脚本的文件夹。
对于 VS Code 中的该工作区,请将以下配置添加到 launch.json 文件:
{ "version": "0.2.0", "configurations": [ { "name": "Python: Attach using Process ID", "type": "debugpy", "request": "attach", "processId": "${command:pickProcess}", "justMyCode": true } ] }
在命令窗口中,通过运行
azmlinfsrv --entry_script score.py
命令启动推理服务器。执行以下步骤,在 VS Code 中启动调试会话:
对于启动和附加模式,可以设置 断点 并逐步调试脚本。
使用端到端示例
以下过程使用 Azure 机器学习示例存储库中的 示例文件 在本地运行推理服务器。 示例文件包括评分脚本、模型文件和环境文件。 有关如何使用这些示例文件的更多示例,请参阅使用联机终结点部署机器学习模型并对其进行评分。
克隆示例存储库并转到包含相关示例文件的文件夹:
git clone --depth 1 https://github.com/Azure/azureml-examples cd azureml-examples/cli/endpoints/online/model-1/
使用 conda 创建和激活虚拟环境:
在此示例中,
azureml-inference-server-http
包已自动安装。 该包作为azureml-defaults
包的依赖库被列在 conda.yaml 文件中。# Create the environment from the YAML file. conda env create --name model-env -f ./environment/conda.yaml # Activate the new environment. conda activate model-env
查看评分脚本、onlinescoring/score.py:
import os import logging import json import numpy import joblib def init(): """ This function is called when the container is initialized/started, typically after create/update of the deployment. You can write the logic here to perform init operations like caching the model in memory """ global model # AZUREML_MODEL_DIR is an environment variable created during deployment. # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION) # Please provide your model's folder name if there is one model_path = os.path.join( os.getenv("AZUREML_MODEL_DIR"), "model/sklearn_regression_model.pkl" ) # deserialize the model file back into a sklearn model model = joblib.load(model_path) logging.info("Init complete") def run(raw_data): """ This function is called for every invocation of the endpoint to perform the actual scoring/prediction. In the example we extract the data from the json input and call the scikit-learn model's predict() method and return the result back """ logging.info("model 1: request received") data = json.loads(raw_data)["data"] data = numpy.array(data) result = model.predict(data) logging.info("Request processed") return result.tolist()
通过指定评分脚本和模型文件夹的路径来运行推理服务器。
在部署期间,将
AZUREML_MODEL_DIR
定义变量以存储模型文件夹的路径。 在参数中model_dir
指定该值。 评分脚本运行时,它会从AZUREML_MODEL_DIR
变量中检索值。在这种情况下,请使用当前目录作为
./
model_dir
值,因为评分脚本将子目录指定为model/sklearn_regression_model.pkl
。azmlinfsrv --entry_script ./onlinescoring/score.py --model_dir ./
当推理服务器启动并成功调用评分脚本时,将打开示例 启动日志 。 否则,日志会显示错误消息。
执行以下步骤,使用示例数据测试评分脚本:
打开另一个命令窗口,转到运行该
azmlinfsrv
命令的同一工作目录。使用以下
curl
实用工具将示例请求发送到推理服务器并接收评分结果:curl --request POST "127.0.0.1:5001/score" --header "Content-Type:application/json" --data @sample-request.json
如果评分脚本没有问题,该脚本将返回评分结果。 如果出现问题,可以更新评分脚本,然后再次启动推理服务器以测试更新的脚本。
查看推理服务器路由
默认情况下,推理服务器会在端口 5001 上侦听以下路由:
名称 | 路由 |
---|---|
运行情况探测 | 127.0.0.1:5001/ |
分数 | 127.0.0.1:5001/score |
OpenAPI (swagger) | 127.0.0.1:5001/swagger.json |
查看推理服务器参数
推理服务器接受以下参数:
参数 | 必须 | 默认 | 说明 |
---|---|---|---|
entry_script |
真 实 | 空值 | 标识评分脚本的相对路径或绝对路径 |
model_dir |
假 | 空值 | 标识保存用于推理的模型的目录的相对路径或绝对路径 |
port |
假 | 5001 | 指定推理服务器的服务端口 |
worker_count |
假 | 1 | 提供用于处理并发请求的工作线程数量 |
appinsights_instrumentation_key |
假 | 空值 | 提供要在其中发布日志的 Application Insights 实例的检测密钥。 |
access_control_allow_origins |
假 | 空值 | 为指定的源启用跨域资源共享(CORS),多个源之间用逗号(,)分隔,例如 microsoft.com, bing.com |
探索推理服务器请求处理
以下步骤演示推理服务器 azmlinfsrv
如何处理传入请求:
Python CLI 包装器位于推理服务器的网络堆栈周围,用于启动推理服务器。
客户端将请求发送到推理服务器。
推理服务器通过 Web 服务器网关接口 (WSGI) 服务器发送请求,该服务器将请求调度到以下 Flask 辅助角色应用程序之一:
Flask 辅助角色应用处理请求,这包括加载入口脚本和所有依赖项。
入口脚本接收请求。 入口脚本对加载的模型进行推理调用,并返回响应。
浏览推理服务器日志
可通过两种方法获取推理服务器测试的日志数据:
azureml-inference-server-http
在本地运行包并查看日志输出。- 使用联机终结点并查看容器日志。 推理服务器的日志名为“Azure 机器学习推理 HTTP 服务器 <版本>”。
注意
自版本 0.8.0 以来,日志记录格式已更改。 如果日志使用的样式与预期不同,请将 azureml-inference-server-http
包更新到最新版本。
查看启动日志
推理服务器启动时,日志会显示以下初始服务器设置:
Azure ML Inferencing HTTP server <version>
Server Settings
---------------
Entry Script Name: <entry-script>
Model Directory: <model-directory>
Config File: <configuration-file>
Worker Count: <worker-count>
Worker Timeout (seconds): None
Server Port: <port>
Health Port: <port>
Application Insights Enabled: false
Application Insights Key: <Application-Insights-instrumentation-key>
Inferencing HTTP server version: azmlinfsrv/<version>
CORS for the specified origins: <access-control-allow-origins>
Create dedicated endpoint for health: <health-check-endpoint>
Server Routes
---------------
Liveness Probe: GET 127.0.0.1:<port>/
Score: POST 127.0.0.1:<port>/score
<logs>
例如,通过 执行端到端示例 步骤来运行推理服务器时,日志包含以下信息:
Azure ML Inferencing HTTP server v1.2.2
Server Settings
---------------
Entry Script Name: /home/user-name/azureml-examples/cli/endpoints/online/model-1/onlinescoring/score.py
Model Directory: ./
Config File: None
Worker Count: 1
Worker Timeout (seconds): None
Server Port: 5001
Health Port: 5001
Application Insights Enabled: false
Application Insights Key: None
Inferencing HTTP server version: azmlinfsrv/1.2.2
CORS for the specified origins: None
Create dedicated endpoint for health: None
Server Routes
---------------
Liveness Probe: GET 127.0.0.1:5001/
Score: POST 127.0.0.1:5001/score
2022-12-24 07:37:53,318 I [32726] gunicorn.error - Starting gunicorn 20.1.0
2022-12-24 07:37:53,319 I [32726] gunicorn.error - Listening at: http://0.0.0.0:5001 (32726)
2022-12-24 07:37:53,319 I [32726] gunicorn.error - Using worker: sync
2022-12-24 07:37:53,322 I [32756] gunicorn.error - Booting worker with pid: 32756
Initializing logger
2022-12-24 07:37:53,779 I [32756] azmlinfsrv - Starting up app insights client
2022-12-24 07:37:54,518 I [32756] azmlinfsrv.user_script - Found user script at /home/user-name/azureml-examples/cli/endpoints/online/model-1/onlinescoring/score.py
2022-12-24 07:37:54,518 I [32756] azmlinfsrv.user_script - run() is not decorated. Server will invoke it with the input in JSON string.
2022-12-24 07:37:54,518 I [32756] azmlinfsrv.user_script - Invoking user's init function
2022-12-24 07:37:55,974 I [32756] azmlinfsrv.user_script - Users's init has completed successfully
2022-12-24 07:37:55,976 I [32756] azmlinfsrv.swagger - Swaggers are prepared for the following versions: [2, 3, 3.1].
2022-12-24 07:37:55,976 I [32756] azmlinfsrv - Scoring timeout is set to 3600000
2022-12-24 07:37:55,976 I [32756] azmlinfsrv - Worker with pid 32756 ready for serving traffic
了解日志数据格式
推理服务器中的所有日志(启动器脚本除外)以以下格式显示数据:
<UTC-time> <level> [<process-ID>] <logger-name> - <message>
每个条目由以下组件组成:
<UTC-time>
:输入条目进入日志的时间<level>
:条目 的日志记录级别 的第一个字符,例如E
ERROR、I
INFO 等<process-ID>
:与条目关联的进程的 ID<logger-name>
:与日志条目关联的资源的名称<message>
:日志消息的内容
Python 中有六个级别的日志记录。 每个级别都有一个根据其严重性分配的数值:
日志记录级别 | 数值 |
---|---|
严重 | 50 |
错误 | 40 |
警告 | 30 |
信息 | 20 |
调试 | 10 |
未设置 | 0 |
排查推理服务器问题
以下部分提供了推理服务器的基本故障排除提示。 若要对联机终结点进行故障排除,请参阅 联机终结点部署和评分疑难解答。
检查已安装的包
按照以下步骤解决已安装的包的问题:
收集有关为 Python 环境安装的包和版本的信息。
在环境文件中,检查指定的 Python 包的版本
azureml-inference-server-http
。 在 Azure 机器学习推理 HTTP 服务器 启动日志中,检查显示的推理服务器的版本。 确认两个版本匹配。在某些情况下,pip 依赖项解析程序会安装意外的包版本。 可能需要运行
pip
来更正已安装的包和版本。如果在环境中指定 Flask 或其依赖项,请删除这些项。
- 依赖包包括
flask
、jinja2
、itsdangerous
、werkzeug
、markupsafe
和click
。 - 包
flask
在推理服务器包中列为依赖项。 最佳方法是允许推理服务器安装flask
包。 - 当推理服务器配置为支持新版本的 Flask 时,推理服务器会在可用时自动接收包更新。
- 依赖包包括
检查推理服务器版本
azureml-inference-server-http
服务器包会发布到 PyPI。 PyPI 页列出了更改日志和包的所有版本。
如果使用早期包版本,请将配置更新到最新版本。 下表汇总了稳定版本、常见问题和建议的调整:
包版本 | 说明 | 问题 | 解决方案 |
---|---|---|---|
0.4.x | 捆绑在 20220601 或更早日期的训练图像以及包 azureml-defaults 版本 0.1.34 到 1.43 中的内容。 最新稳定版本为 0.4.13。 |
对于低于 0.4.11 的服务器版本,可能会遇到 Flask 依赖项问题,例如 can't import name Markup from jinja2 。 |
如果可能,请升级到版本 0.4.13 或 1.4.x(最新版本)。 |
0.6.x | 已预装在 20220516 及更早发布的推理映像中。 最新稳定版本为 0.6.1。 |
空值 | 空值 |
0.7.x | 支持 Flask 2。 最新稳定版本为 0.7.7。 | 空值 | 空值 |
0.8.x | 使用更新后的日志格式。 结束对 Python 3.6 的支持。 | 空值 | 空值 |
1.0.x | 结束对 Python 3.7 的支持。 | 空值 | 空值 |
1.1.x | 迁移到 pydantic 2.0。 |
空值 | 空值 |
1.2.x | 添加了对 Python 3.11 的支持。 将 gunicorn 更新到版本 22.0.0。 更新 werkzeug 至 3.0.3 版本及更高版本。 |
空值 | 空值 |
1.3.x | 添加了对 Python 3.12 的支持。 将certifi 升级到版本 2024.7.4。 将 flask-cors 升级到版本 5.0.0。 升级 gunicorn 和 pydantic 包。 |
空值 | 空值 |
1.4.x | 将 waitress 升级到版本 3.0.1。 结束对 Python 3.8 的支持。 删除阻止 Flask 2.0 升级中断请求对象代码的兼容性层。 |
如果依赖于兼容性层,则请求对象代码可能不起作用。 | 将分数脚本迁移到 Flask 2。 |
检查包依赖项
azureml-inference-server-http
服务器包的最相关依赖包包括:
flask
opencensus-ext-azure
inference-schema
如果在 Python 环境中指定 azureml-defaults
包,则 azureml-inference-server-http
包是依赖包。 依赖项已自动安装。
提示
如果使用适用于 Python 的 Azure 机器学习 SDK v1,并且未在 Python 环境中显式指定 azureml-defaults
包,则 SDK 可能会自动添加该包。 但是,包版本相对于 SDK 版本被锁定。 例如,如果 SDK 版本为 1.38.0,则 azureml-defaults==1.38.0
条目将添加到环境的 pip 要求中。
推理服务器启动期间出现类型错误
在推理服务器启动期间可能会遇到以下 TypeError
:
TypeError: register() takes 3 positional arguments but 4 were given
File "/var/azureml-server/aml_blueprint.py", line 251, in register
super(AMLBlueprint, self).register(app, options, first_registration)
TypeError: register() takes 3 positional arguments but 4 were given
如果在 Python 环境中安装了 Flask 2,但 azureml-inference-server-http
包版本不支持 Flask 2,则会出现此错误。 0.7.0 包及更高版本中提供了 azureml-inference-server-http
对 Flask 2 的支持,以及 azureml-defaults
1.44 包及更高版本。
如果你未在 Azure 机器学习 Docker 映像中使用 Flask 2 包,请使用最新版本的
azureml-inference-server-http
或azureml-defaults
包。如果在 Azure 机器学习 Docker 映像中使用 Flask 2 包,请确认映像生成版本为
July 2022
或更高版本。可以在容器日志中找到映像版本。 例如,请参阅以下日志语句:
2022-08-22T17:05:02,147738763+00:00 | gunicorn/run | AzureML Container Runtime Information 2022-08-22T17:05:02,161963207+00:00 | gunicorn/run | ############################################### 2022-08-22T17:05:02,168970479+00:00 | gunicorn/run | 2022-08-22T17:05:02,174364834+00:00 | gunicorn/run | 2022-08-22T17:05:02,187280665+00:00 | gunicorn/run | AzureML image information: openmpi4.1.0-ubuntu20.04, Materialization Build:20220708.v2 2022-08-22T17:05:02,188930082+00:00 | gunicorn/run | 2022-08-22T17:05:02,190557998+00:00 | gunicorn/run |
映像生成日期显示在
Materialization Build
表示法后面。 在前面的示例中,映像版本为20220708
2022 年 7 月 8 日。 在此示例中,该映像与 Flask 2 兼容。如果在容器日志中未看到类似的消息,则表明该映像已过期,应进行更新。 如果使用计算统一设备体系结构(CUDA)映像,但找不到较新的映像,请检查 AzureML 容器 存储库以查看映像是否已弃用。 可以查找已弃用映像的指定替换项。
如果将推理服务器与联机终结点配合使用,还可以在 Azure 机器学习工作室中找到日志。 在终结点的页面上,选择“ 日志 ”选项卡。
如果使用 SDK v1 进行部署,并且未在部署配置中显式指定映像,推理服务器会应用 openmpi4.1.0-ubuntu20.04
包,其版本与本地 SDK 工具集匹配。 但是,已安装的版本可能不是映像的最新可用版本。
对于 SDK 版本 1.43,推理服务器默认安装 openmpi4.1.0-ubuntu20.04:20220616
包版本,但此包版本与 SDK 1.43 不兼容。 请确保使用最新 SDK 进行部署。
如果无法更新映像,可以通过在环境文件中固定 azureml-defaults==1.43
或 azureml-inference-server-http~=0.4.13
条目来暂时避免此问题。 这些条目指示推理服务器使用 flask 1.0.x
安装较旧版本。
推理服务器启动期间 ImportError 或 ModuleNotFoundError
在推理服务器启动期间,可能会遇到特定模块(例如 ImportError
、ModuleNotFoundError
、opencensus
或 jinja2
)上的 markupsafe
或 click
。 以下示例显示了此错误消息:
ImportError: cannot import name 'Markup' from 'jinja2'
使用版本 0.4.10 或更早版本的推理服务器时,如果没有将 Flask 依赖项固定到兼容版本,就会发生导入和模块错误。 若要防止此问题,请安装更高版本的推理服务器。