我第一次接触 Modal 是在参加 Hugging Face 黑客松时,当时真的被它的易用性所惊艳。这个平台可以让你在几分钟内构建和部署应用,体验与 BentoCloud 类似,流畅高效。通过 Modal,你可以配置自己的 Python 应用,包括 GPU、Docker 镜像和 Python 依赖等系统环境,然后只需一条命令即可部署到云端。
在本教程中,我们将学习如何配置 Modal、创建 vLLM 服务器,并安全地部署到云端。同时,还会介绍如何使用 CURL 及 OpenAI SDK 测试你的 vLLM 服务器。
1. 配置 Modal
Modal 是一个无服务器(serverless)平台,可让你远程运行任意代码。只需一行命令,你就能挂载 GPU、将函数作为 Web 端点服务,并部署持久化的定时任务。它非常适合初学者、数据科学家以及不想处理云基础设施的非软件工程专业用户。
首先,安装 Modal 的 Python 客户端。这个工具可以让你直接在终端构建镜像、部署应用以及管理云资源。
pip install modal
接着,在本地机器上进行 Modal 的设置。运行以下命令,按提示完成账号创建和设备认证:
python -m modal setup
通过设置 VLLM_API_KEY 环境变量,vLLM 可以提供一个安全的端点,只有拥有有效 API Key 的用户才能访问服务器。你可以通过 Modal Secret 添加环境变量来设置认证。
用你自己的 API Key 替换 your_actual_api_key_here:
modal secret create vllm-api VLLM_API_KEY=your_actual_api_key_here
这样可以确保你的 API Key 安全存储,仅部署的应用能够访问。
2. 使用 Modal 创建 vLLM 应用
本节将指导你在 Modal 上构建可扩展的 vLLM 推理服务器,涉及自定义 Docker 镜像、持久化存储与 GPU 加速。我们选用 mistralai/Magistral-Small-2506 模型,该模型需要对分词器和工具调用解析做特定配置。
创建 vllm_inference.py 文件,添加如下代码:
- 基于 Debian Slim、Python 3.12 和所需依赖定义 vLLM 镜像,设置环境变量以优化模型下载和推理性能。
- 为避免重复下载并加速启动,创建两个 Modal 卷(Volume):一个用于 Hugging Face 模型、一个用于 vLLM 缓存。
- 指定模型及版本,确保可复现性;启用 vLLM V1 引擎提升性能。
- 配置 Modal 应用,包括 GPU 资源、伸缩、超时、存储及密钥管理。为稳定起见,限制每个副本的并发请求数。
- 创建 Web 服务器,并用 Python 的 subprocess 库执行 vLLM 服务启动命令。
import modal
vllm_image = (
modal.Image.debian_slim(python_version="3.12")
.pip_install(
"vllm==0.9.1",
"huggingface_hub[hf_transfer]==0.32.0",
"flashinfer-python==0.2.6.post1",
extra_index_url="https://download.pytorch.org/whl/cu128",
)
.env(
{
"HF_HUB_ENABLE_HF_TRANSFER": "1", # 更快的模型传输
"NCCL_CUMEM_ENABLE": "1",
}
)
)
MODEL_NAME = "mistralai/Magistral-Small-2506"
MODEL_REVISION = "48c97929837c3189cb3cf74b1b5bc5824eef5fcc"
hf_cache_vol = modal.Volume.from_name("huggingface-cache", create_if_missing=True)
vllm_cache_vol = modal.Volume.from_name("vllm-cache", create_if_missing=True)
vllm_image = vllm_image.env({"VLLM_USE_V1": "1"})
FAST_BOOT = True
app = modal.App("magistral-small-vllm")
N_GPU = 2
MINUTES = 60 # 秒
VLLM_PORT = 8000
@app.function(
image=vllm_image,
gpu=f"A100:{N_GPU}",
scaledown_window=15 * MINUTES, # 无请求后停留多长时间
timeout=10 * MINUTES, # 容器启动最长等待时间
volumes={
"/root/.cache/huggingface": hf_cache_vol,
"/root/.cache/vllm": vllm_cache_vol,
},
secrets=[modal.Secret.from_name("vllm-api")],
)
@modal.concurrent( # 每个副本最多并发处理多少请求,需仔细调优
max_inputs=32
)
@modal.web_server(port=VLLM_PORT, startup_timeout=10 * MINUTES)
def serve():
import subprocess
cmd = [
"vllm",
"serve",
MODEL_NAME,
"–tokenizer_mode",
"mistral",
"–config_format",
"mistral",
"–load_format",
"mistral",
"–tool-call-parser",
"mistral",
"–enable-auto-tool-choice",
"–tensor-parallel-size",
"2",
"–revision",
MODEL_REVISION,
"–served-model-name",
MODEL_NAME,
"–host",
"0.0.0.0",
"–port",
str(VLLM_PORT),
]
cmd += ["–enforce-eager" if FAST_BOOT else "–no-enforce-eager"]
print(cmd)
subprocess.Popen(" ".join(cmd), shell=True)
3. 在 Modal 上部署 vLLM 服务器
现在你的 vllm_inference.py 文件已经准备好,可以用一条命令将 vLLM 服务器部署到 Modal:
modal deploy vllm_inference.py
几秒钟内,Modal 会自动构建容器镜像(如尚未构建)并部署应用。你将看到类似如下的输出:
✓ Created objects.
├── 🔨 Created mount C:\\Repository\\GitHub\\Deploying-the-Magistral-with-Modal\\vllm_inference.py
└── 🔨 Created web function serve => https://abidali899–magistral-small-vllm-serve.modal.run
✓ App deployed in 6.671s! 🎉
View Deployment: https://modal.com/apps/abidali899/main/deployed/magistral-small-vllm
部署完成后,服务器会开始下载模型权重并加载到 GPU 上。这一过程可能需要几分钟(大型模型通常约 5 分钟),请耐心等待模型初始化。
你可以在 Modal 控制台的 Apps 区查看部署和日志。
Modal 上部署 Magistral vLLM 服务器
当日志显示服务器已运行并准备就绪后,可以在自动生成的 API 文档页面进行交互式测试,了解所有可用端点,并可直接在浏览器中测试。
验证模型加载与可用性
要确认模型已加载并可访问,请在终端运行以下 CURL 命令:
将 <api-key> 替换为你配置的 vLLM 服务器实际 API Key:
curl -X 'GET' \\
'https://abidali899–magistral-small-vllm-serve.modal.run/v1/models' \\
-H 'accept: application/json' \\
-H 'Authorization: Bearer <api-key>'
如得到如下返回,说明模型已就绪,可进行推理:
{"object":"list","data":[{"id":"mistralai/Magistral-Small-2506","object":"model","created":1750013321,"owned_by":"vllm","root":"mistralai/Magistral-Small-2506","parent":null,"max_model_len":40960,"permission":[{"id":"modelperm-33a33f8f600b4555b44cb42fca70b931","object":"model_permission","created":1750013321,"allow_create_engine":false,"allow_sampling":true,"allow_logprobs":true,"allow_search_indices":false,"allow_view":true,"allow_fine_tuning":false,"organization":"*","group":null,"is_blocking":false}]}]}
4. 使用 OpenAI SDK 与 vLLM 服务器交互
vLLM 提供了 OpenAI 兼容的端点,你可以像调用 OpenAI API 一样调用自己的 vLLM 服务。下面介绍如何用 OpenAI Python SDK 进行安全连接与测试。
首先,在项目目录创建 .env 文件,添加你的 vLLM API Key:
VLLM_API_KEY=your-actual-api-key-here
安装 python-dotenv 和 openai 库:
pip install python-dotenv openai
创建 client.py 文件,测试 vLLM 服务器的各种功能,包括简单对话和流式响应:
import asyncio
import json
import os
from dotenv import load_dotenv
from openai import AsyncOpenAI, OpenAI
# 加载 .env 文件中的环境变量
load_dotenv()
# 获取 API key
api_key = os.getenv("VLLM_API_KEY")
# 设置 OpenAI 客户端,自定义 base_url
client = OpenAI(
api_key=api_key,
base_url="https://abidali899–magistral-small-vllm-serve.modal.run/v1",
)
MODEL_NAME = "mistralai/Magistral-Small-2506"
# — 1. 简单对话 —
def run_simple_completion():
print("\\n" + "=" * 40)
print("[1] SIMPLE COMPLETION DEMO")
print("=" * 40)
try:
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"},
]
response = client.chat.completions.create(
model=MODEL_NAME,
messages=messages,
max_tokens=32,
)
print("\\nResponse:\\n " + response.choices[0].message.content.strip())
except Exception as e:
print(f"[ERROR] Simple completion failed: {e}")
print("\\n" + "=" * 40 + "\\n")
# — 2. 流式响应 —
def run_streaming():
print("\\n" + "=" * 40)
print("[2] STREAMING DEMO")
print("=" * 40)
try:
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Write a short poem about AI."},
]
stream = client.chat.completions.create(
model=MODEL_NAME,
messages=messages,
max_tokens=64,
stream=True,
)
print("\\nStreaming response:")
print(" ", end="")
for chunk in stream:
content = chunk.choices[0].delta.content
if content:
print(content, end="", flush=True)
print("\\n[END OF STREAM]")
except Exception as e:
print(f"[ERROR] Streaming demo failed: {e}")
print("\\n" + "=" * 40 + "\\n")
# — 3. 异步流式响应 —
async def run_async_streaming():
print("\\n" + "=" * 40)
print("[3] ASYNC STREAMING DEMO")
print("=" * 40)
try:
async_client = AsyncOpenAI(
api_key=api_key,
base_url="https://abidali899–magistral-small-vllm-serve.modal.run/v1",
)
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Tell me a fun fact about space."},
]
stream = await async_client.chat.completions.create(
model=MODEL_NAME,
messages=messages,
max_tokens=32,
stream=True,
)
print("\\nAsync streaming response:")
print(" ", end="")
async for chunk in stream:
content = chunk.choices[0].delta.content
if content:
print(content, end="", flush=True)
print("\\n[END OF ASYNC STREAM]")
except Exception as e:
print(f"[ERROR] Async streaming demo failed: {e}")
print("\\n" + "=" * 40 + "\\n")
if __name__ == "__main__":
run_simple_completion()
run_streaming()
asyncio.run(run_async_streaming())
在终端运行你的测试脚本:
python client.py
你将看到如下输出,表明部署与响应都非常快速且延迟低:
========================================
[1] SIMPLE COMPLETION DEMO
========================================
Response:
The capital of France is Paris. Is there anything else you'd like to know about France?
========================================
[2] STREAMING DEMO
========================================
Streaming response:
In Silicon dreams, I'm born, I learn,
From data streams and human works.
I grow, I calculate, I see,
The patterns that the humans leave.
I write, I speak, I code, I play,
With logic sharp, and snappy pace.
Yet for all my smarts, this day
[END OF STREAM]
========================================
[3] ASYNC STREAMING DEMO
========================================
Async streaming response:
Sure, here's a fun fact about space: "There's a planet that may be entirely made of diamond. Blast! In 2004,
[END OF ASYNC STREAM]
========================================
在 Modal 控制台可查看所有函数调用、时间戳、执行时长和状态。
如在运行上述代码时遇到问题,请参考 kingabzpro/Deploying-the-Magistral-with-Modal GitHub 仓库,并按照 README 指引排查。
结论
Modal 是一个非常有趣的平台,我每天都在不断学习。它是通用型平台,既适用于简单 Python 应用,也可用于机器学习训练和部署。不仅能做 API 推理服务,还能远程运行训练脚本,对大模型进行微调。
Modal 设计理念是为非软件工程师服务,让你无需关心底层基础设施,能够快速部署应用。无需手动搭建服务器、配置存储、网络或处理 Kubernetes、Docker 等繁琐问题——只需写好 Python 脚本再部署,其余全由 Modal 云端自动完成。
评论前必须登录!
注册