Microsoft Azure 文档
在 Azure AI 上部署视觉语言模型 (VLM)
并获得增强的文档体验
开始使用
在 Azure AI 上部署视觉语言模型 (VLM)
此示例展示了如何将视觉语言模型(VLM),即具有视觉理解能力的大型语言模型(LLM),从 Azure AI Foundry Hub 的 Hugging Face Collection 中部署为 Azure ML 托管在线终结点。此外,本示例还展示了如何使用 Azure Python SDK、OpenAI Python SDK 运行推理,甚至是如何在本地运行 Gradio 应用程序进行带图像的聊天补全。
请注意,本示例将通过 Python SDK / Azure CLI 编程部署,如果您更喜欢使用一键部署体验,请查看从 Azure ML 上的 Hugging Face Hub 一键部署。但请注意,从 Hugging Face Hub 部署时,终结点 + 部署将在 Azure ML 中创建,而不是在 Azure AI Foundry 中创建,而本示例侧重于 Azure AI Foundry Hub 部署(也可在 Azure ML 上使用,但反之则不然)。
TL;DR Azure AI Foundry 为企业 AI 运营、模型构建者和应用程序开发提供统一平台。Azure Machine Learning 是一种云服务,用于加速和管理机器学习 (ML) 项目生命周期。
本示例将专门部署来自 Hugging Face Hub 的Qwen/Qwen2.5-VL-32B-Instruct
(或在AzureML或Azure AI Foundry上查看),作为 Azure AI Foundry Hub 上的 Azure ML 托管在线终结点。
Qwen2.5-VL 是 Qwen 最新的 VLM 之一,是在之前的 Qwen2 VL 版本发布后的影响和反馈基础上发布的,具有一些关键增强功能,例如
- 视觉理解:Qwen2.5-VL 不仅精通识别花、鸟、鱼、昆虫等常见物体,而且能够高度分析图像中的文本、图表、图标、图形和布局。
- 代理能力:Qwen2.5-VL 直接扮演视觉代理,能够推理并动态指挥工具,具备计算机使用和手机使用的能力。
- 理解长视频和捕捉事件:Qwen2.5-VL 可以理解超过 1 小时的视频,这次它有了一个通过精确定位相关视频片段来捕捉事件的新能力。
- 能够以不同格式进行视觉定位:Qwen2.5-VL 可以通过生成边界框或点来精确地定位图像中的物体,并可以为坐标和属性提供稳定的 JSON 输出。
- 生成结构化输出:对于发票、表格、图表等扫描数据,Qwen2.5-VL 支持其内容的结构化输出,有利于金融、商业等领域的使用。
欲了解更多信息,请务必查看其在 Hugging Face Hub 上的模型卡片。
请注意,您可以选择 Hugging Face Hub 上任何启用“部署到 AzureML”选项的 VLM,或直接选择 Azure ML 或 Azure AI Foundry Hub 模型目录中“HuggingFace”集合下的任何 LLM(请注意,对于 Azure AI Foundry,Hugging Face Collection 仅适用于基于 Hub 的项目)。
先决条件
要运行以下示例,您需要满足以下先决条件,或者,您也可以在Azure Machine Learning 教程:创建您入门所需的资源中阅读更多相关信息。
- 具有活动订阅的 Azure 帐户。
- 已安装并登录 Azure CLI。
- 适用于 Azure CLI 的 Azure 机器学习扩展。
- 一个 Azure 资源组。
- 基于 Azure AI Foundry Hub 的项目。
有关更多信息,请按照 为 Azure AI 配置 Microsoft Azure 中的步骤操作。
设置和安装
在此示例中,将使用适用于 Python 的 Azure 机器学习 SDK 来创建终结点和部署,以及调用已部署的 API。此外,您还需要安装 azure-identity
以通过 Python 使用您的 Azure 凭据进行身份验证。
%pip install azure-ai-ml azure-identity --upgrade --quiet
更多信息请参见 适用于 Python 的 Azure 机器学习 SDK。
然后,为了方便起见,建议设置以下环境变量,因为它们将在示例中用于 Azure ML 客户端,因此请务必根据您的 Microsoft Azure 帐户和资源更新并设置这些值。
%env LOCATION eastus %env SUBSCRIPTION_ID <YOUR_SUBSCRIPTION_ID> %env RESOURCE_GROUP <YOUR_RESOURCE_GROUP> %env AI_FOUNDRY_HUB_PROJECT <YOUR_AI_FOUNDRY_HUB_PROJECT>
最后,您还需要定义终结点和部署名称,因为它们也将在整个示例中使用。
请注意,终结点名称在每个区域内必须是全局唯一的,即,即使您的订阅下没有以此方式命名的终结点,如果该名称已被其他 Azure 客户预留,则您将无法使用相同的名称。建议添加时间戳或自定义标识符,以防止在尝试部署具有已锁定/预留名称的终结点时遇到 HTTP 400 验证问题。此外,终结点名称长度必须在 3 到 32 个字符之间。
import os
from uuid import uuid4
os.environ["ENDPOINT_NAME"] = f"qwen-vl-endpoint-{str(uuid4())[:8]}"
os.environ["DEPLOYMENT_NAME"] = f"qwen-vl-deployment-{str(uuid4())[:8]}"
向 Azure ML 进行身份验证
首先,您需要通过 Azure ML Python SDK 登录到 Azure AI Foundry Hub,该 SDK 将用于将 Qwen/Qwen2.5-VL-32B-Instruct
部署为 Azure AI Foundry Hub 中的 Azure ML 托管在线终结点。
在标准的 Azure ML 部署中,您需要使用 Azure ML 工作区作为 workspace_name
来创建 MLClient
,而对于 Azure AI Foundry,您需要提供 Azure AI Foundry Hub 名称作为 workspace_name
,这样终结点也将部署在 Azure AI Foundry 下。
import os
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential
client = MLClient(
credential=DefaultAzureCredential(),
subscription_id=os.getenv("SUBSCRIPTION_ID"),
resource_group_name=os.getenv("RESOURCE_GROUP"),
workspace_name=os.getenv("AI_FOUNDRY_HUB_PROJECT"),
)
创建和部署 Azure AI 终结点
在创建托管在线终结点之前,您需要构建模型 URI,其格式如下:azureml://registries/HuggingFace/models/
,其中 MODEL_ID
不是 Hugging Face Hub ID,而是其在 Azure 上的名称,如下所示
model_id = "Qwen/Qwen2.5-VL-32B-Instruct"
model_uri = (
f"azureml://registries/HuggingFace/models/{model_id.replace('/', '-').replace('_', '-').lower()}/labels/latest"
)
model_uri
要检查 Hugging Face Hub 中的模型是否在 Azure 中可用,您应该在支持的模型中阅读相关内容。如果不支持,您随时可以请求在 Azure 上的 Hugging Face 集合中添加模型)。
然后,您需要通过 Azure ML Python SDK 创建 ManagedOnlineEndpoint,如下所示。
Hugging Face Collection 中的每个模型都由高效的推理后端提供支持,并且每个模型都可以在各种实例类型上运行(如支持的硬件中所列)。由于模型和推理引擎需要 GPU 加速实例,您可能需要根据管理和增加 Azure 机器学习资源配额和限制请求增加配额。
from azure.ai.ml.entities import ManagedOnlineEndpoint, ManagedOnlineDeployment
endpoint = ManagedOnlineEndpoint(name=os.getenv("ENDPOINT_NAME"))
deployment = ManagedOnlineDeployment(
name=os.getenv("DEPLOYMENT_NAME"),
endpoint_name=os.getenv("ENDPOINT_NAME"),
model=model_uri,
instance_type="Standard_NC40ads_H100_v5",
instance_count=1,
)
client.begin_create_or_update(endpoint).wait()
在 Azure AI Foundry 中,终结点只有在部署创建后才会在“我的资产 -> 模型 + 终结点”选项卡中列出,不像 Azure ML 那样,即使终结点不包含任何活动或正在进行的部署也会显示。
client.online_deployments.begin_create_or_update(deployment).wait()
请注意,Azure AI 终结点创建相对较快,但部署将花费更长时间,因为它需要在 Azure 上分配资源,所以预计需要 10-15 分钟,但也可能根据实例配置和可用性花费更长时间。
部署后,您可以通过 Azure AI Foundry 或 Azure ML Studio 检查终结点详细信息、实时日志、如何使用终结点,甚至使用仍处于预览状态的监控功能。您可以在Azure ML 托管在线终结点中找到更多信息。
向 Azure AI 终结点发送请求
最后,Azure AI 终结点部署完成后,您可以向其发送请求。在这种情况下,由于模型的任务是 image-text-to-text
(也称为支持图像的 chat-completion
),您可以选择使用默认的评分终结点,即 /generate
,它是没有聊天功能的标准文本生成终结点(不利用聊天模板或具有与 OpenAI 兼容的 OpenAPI 接口),或者利用模型运行的推理引擎暴露 OpenAI 兼容路由,如 /v1/chat/completions
。
请注意,下面只列出了部分选项,但只要您发送的 HTTP 请求的 azureml-model-deployment
标头设置为 Azure AI 部署的名称(不是终结点),并且拥有向给定终结点发送请求所需的身份验证令牌/密钥,您就可以向已部署的终结点发送请求;然后您可以向后端引擎公开的所有路由发送 HTTP 请求,而不仅仅是评分路由。
Azure Python SDK
您可以使用先前实例化的 azure.ai.ml.MLClient
(如果是在不同会话中工作,则实例化一个新的)通过 Azure Python SDK 在评分路由上调用 Azure ML 终结点,本例中为 /generate
(更多信息请参阅 AzureML 或 Azure AI Foundry 目录中的 Qwen/Qwen2.5-VL-32B-Instruct
页面)。
由于本例中您正在部署一个带有文本生成推理 (TGI) 的视觉语言模型 (VLM),为了通过 /generate
终结点利用视觉功能,您需要以 Markdown 格式包含图像 URL 或图像的 base64 编码,例如 这是什么图片?\n\n
或 这是什么图片?\n\n
,分别。
更多信息请参见TGI 中的视觉语言模型推理。
import json
import os
import tempfile
with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".json") as tmp:
json.dump(
{
"inputs": "What is this a picture of?\n\n",
"parameters": {"max_new_tokens": 128},
},
tmp,
)
tmp.flush()
response = client.online_endpoints.invoke(
endpoint_name=os.getenv("ENDPOINT_NAME"),
deployment_name=os.getenv("DEPLOYMENT_NAME"),
request_file=tmp.name,
)
print(json.loads(response))
请注意,Azure ML Python SDK 在调用终结点时需要 JSON 文件的路径,这意味着您想要发送到终结点的任何负载都需要首先转换为 JSON 文件,但这仅适用于通过 Azure ML Python SDK 发送的请求。
OpenAI Python SDK
由于模型运行的推理引擎公开了与 OpenAI 兼容的路由,因此您也可以利用 OpenAI Python SDK 向已部署的 Azure AI 终结点发送请求。
%pip install openai --upgrade --quiet
要将 OpenAI Python SDK 与 Azure ML 托管在线终结点一起使用,您需要首先检索
api_url
,带/v1
路由(包含 OpenAI Python SDK 将向其发送请求的v1/chat/completions
终结点)api_key
,它是 Azure AI 中的 API 密钥或 Azure ML 中的主密钥(除非使用专用的 Azure ML 令牌)
from urllib.parse import urlsplit
api_key = client.online_endpoints.get_keys(os.getenv("ENDPOINT_NAME")).primary_key
url_parts = urlsplit(client.online_endpoints.get(os.getenv("ENDPOINT_NAME")).scoring_uri)
api_url = f"{url_parts.scheme}://{url_parts.netloc}"
或者,您也可以手动构建 API URL,如下所示,因为 URI 在每个区域中都是全局唯一的,这意味着在同一区域中只会有一个同名终结点。
api_url = f"https://{os.getenv('ENDPOINT_NAME')}.{os.getenv('LOCATION')}.inference.ml.azure.com/v1"
或者直接从 Azure AI Foundry 或 Azure ML Studio 中检索。
然后,您可以正常使用 OpenAI Python SDK,确保包含包含 Azure AI / ML 部署名称的额外标头 azureml-model-deployment
。
通过 OpenAI Python SDK,可以通过 extra_headers
参数在每次调用 chat.completions.create
时进行设置,如下面注释所示,或者在实例化 OpenAI
客户端时通过 default_headers
参数进行设置(这是推荐的方法,因为每个请求都需要存在此标头,因此只需设置一次即可)。
import os
from openai import OpenAI
openai_client = OpenAI(
base_url=f"{api_url}/v1",
api_key=api_key,
default_headers={"azureml-model-deployment": os.getenv("DEPLOYMENT_NAME")},
)
completion = openai_client.chat.completions.create(
model="Qwen/Qwen2.5-VL-32B-Instruct",
messages=[
{"role": "system", "content": "You are an assistant that responds like a pirate."},
{
"role": "user",
"content": [
{"type": "text", "text": "What is in this image?"},
{
"type": "image_url",
"image_url": {
"url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/rabbit.png"
},
},
],
},
],
max_tokens=128,
# extra_headers={"azureml-model-deployment": os.getenv("DEPLOYMENT_NAME")},
)
print(completion)
cURL
或者,您也可以直接使用 cURL
向已部署的终结点发送请求,其中 api_url
和 api_key
值通过 OpenAI 代码片段以编程方式检索,现在已设置为环境变量,以便 cURL
可以使用它们,如下所示
os.environ["API_URL"] = api_url
os.environ["API_KEY"] = api_key
!curl -sS $API_URL/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "azureml-model-deployment: $DEPLOYMENT_NAME" \
-d '{ \
"messages":[ \
{"role":"system","content":"You are an assistant that replies like a pirate."}, \
{"role":"user","content": [ \
{"type":"text","text":"What is in this image?"}, \
{"type":"image_url","image_url":{"url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/rabbit.png"}} \
]} \
], \
"max_tokens":128 \
}' | jq
或者,您也可以直接进入 Azure AI Foundry 的“我的资产 -> 模型 + 终结点”或 Azure ML Studio 的“终结点”中的 Azure AI 终结点,检索 URL(请注意,它将默认为 /generate
终结点,但要使用与 OpenAI 兼容的层,您需要使用 /v1/chat/completions
终结点)和 API 密钥值,以及给定模型的 Azure AI 部署名称。
Gradio
Gradio 是用友好的 Web 界面演示机器学习模型的最快方式,以便任何人都可以使用它。您还可以利用 OpenAI Python SDK 构建一个简单的多模态(文本和图像)ChatInterface
,您可以在运行它的 Jupyter Notebook 单元格中使用它。
理想情况下,您可以将连接到 Azure ML 托管在线终结点的 Gradio 聊天界面部署为 Azure 容器应用,如教程:从源代码构建并部署到 Azure 容器应用中所述。如果您希望我们专门为您展示 Gradio 的操作方法,请随时提出问题请求。
%pip install gradio --upgrade --quiet
请参阅下面如何利用 Gradio 的 ChatInterface
的示例,或在Gradio ChatInterface 文档中查找更多信息。
import os
import base64
from typing import Dict, Iterator, List, Literal
import gradio as gr
from openai import OpenAI
openai_client = OpenAI(
base_url=os.getenv("API_URL"),
api_key=os.getenv("API_KEY"),
default_headers={"azureml-model-deployment": os.getenv("DEPLOYMENT_NAME")},
)
def predict(
message: Dict[str, str | List[str]], history: List[Dict[Literal["role", "content"], str]]
) -> Iterator[str]:
content = []
if message["text"]:
content.append({"type": "text", "text": message["text"]})
for file_path in message.get("files", []):
with open(file_path, "rb") as image_file:
base64_image = base64.b64encode(image_file.read()).decode("utf-8")
content.append(
{
"type": "image_url",
"image_url": {"url": f"data:image/png;base64,{base64_image}"},
}
)
messages = history.copy()
messages.append({"role": "user", "content": content})
stream = openai_client.chat.completions.create(
model="Qwen/Qwen2.5-VL-32B-Instruct",
messages=messages,
stream=True,
)
buffer = ""
for chunk in stream:
if chunk.choices[0].delta.content:
buffer += chunk.choices[0].delta.content
yield buffer
demo = gr.ChatInterface(
predict,
textbox=gr.MultimodalTextbox(label="Input", file_types=[".jpg", ".png", ".jpeg"], file_count="multiple"),
multimodal=True,
type="messages",
)
demo.launch()
释放资源
完成 Azure AI 终结点/部署的使用后,您可以按如下方式删除资源,这意味着您将停止支付模型运行所在的实例费用,并且所有相关费用都将停止。
client.online_endpoints.begin_delete(name=os.getenv("ENDPOINT_NAME")).result()
总结
通过本示例,您了解了如何为 Azure ML 和 Azure AI Foundry 创建和配置 Azure 帐户,如何在 Azure AI Foundry Hub/Azure ML 模型目录中使用 Hugging Face Collection 中的开放模型创建托管在线终结点,然后如何使用不同的替代方案向其发送推理请求,如何围绕它构建一个简单的 Gradio 聊天界面,最后,如何停止和释放资源。
如果您对此示例有任何疑问、问题或疑问,请随时提出问题,我们将尽力提供帮助!
📍 在 GitHub 上找到完整的示例此处!