Hugging Face · 官方博客

一条命令在 HF Jobs 上运行 vLLM 服务器

Run a vLLM Server on HF Jobs in One Command

二〇二六年六月二十五日 · 英文原文

Hugging Face 推出 HF Jobs 功能,允许用户通过一条命令在 Hugging Face 基础设施上启动私有、兼容 OpenAI 的 LLM 端点,无需配置服务器或 Kubernetes,按秒计费。用户可使用 `hf jobs run` 命令指定 GPU flavor(如 a10g-large)和 vLLM 镜像,暴露端口后通过 HF token 认证的 curl 或 OpenAI 客户端查询。支持扩展至更大模型(如 Qwen3.5-122B-A10B 在 h200x2 上运行),并集成 Gradio UI 聊天、SSH 调试及 Pi 编码 agent 后端。HF Jobs 适用于实验和批量生成,而生产环境建议使用 Inference Endpoints。

](https://huggingface.co/qgallouedec)

你可以通过一条命令在 Hugging Face 基础设施上启动一个私有的、兼容 OpenAI 的 LLM 端点——无需配置服务器,无需 Kubernetes,按秒计费。启动后,你可以从笔记本电脑、notebook 或任何其他地方查询它。

这是为测试、评估或批量生成快速搭建模型的最快方式。(如果你需要的是托管式、生产就绪的服务,那应该使用 Inference Endpoints——文末有关于何时选择哪个的更多说明。)

以下是完整的端到端流程。

前置条件

启动服务器

hf jobs run 相当于 HF 基础设施上的 docker run。我们使用官方的 vllm/vllm-openai 镜像,通过 --flavor 指定 GPU,并通过 --expose 暴露 vLLM 的端口:

hf jobs run --flavor a10g-large --expose 8000 --timeout 2h \
  vllm/vllm-openai:latest \
  vllm serve Qwen/Qwen3-4B --host 0.0.0.0 --port 8000

--expose 8000 将容器的端口通过 HF 的公共 jobs 代理路由出去(完整参考见 Serve Models 指南)。该命令会打印你的服务器可访问的 URL:

✓ Job started
  id: 6a381ca1953ed90bfb947332
  url: https://huggingface.co/jobs/qgallouedec/6a381ca1953ed90bfb947332
提示:暴露的端口可通过以下地址访问(需要具有 job 读取权限的 HF token):
  https://6a381ca1953ed90bfb947332--8000.hf.jobs

6a381ca1953ed90bfb947332 是你的 job ID。请记住它,后续会用到。在本文其余部分,我们将用 <job_id> 作为它的占位符。

给它几分钟时间下载权重并启动。当日志显示 Application startup complete 时,说明已就绪。

从任意位置查询

vLLM 使用 OpenAI API,每个请求只需将你的 HF token 作为 bearer token 即可。最快的方式是用 curl:

curl https://<job_id>--8000.hf.jobs/v1/chat/completions \
  -H "Authorization: Bearer $(hf auth token)" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen/Qwen3-4B",
    "messages": [{"role": "user", "content": "Hello!"}],
    "chat_template_kwargs": {"enable_thinking": false}
  }'

这会返回标准的 OpenAI 风格 JSON,其中 choices[0].message.content 包含 "Hello! How can I assist you today? 😊"

或者,在 Python 中,将 OpenAI 客户端指向暴露的 URL,并将 token 作为 API key 传入:

from huggingface_hub import get_token
from openai import OpenAI

client = OpenAI(
    base_url="https://<job_id>--8000.hf.jobs/v1",
    api_key=get_token(),
)
resp = client.chat.completions.create(
    model="Qwen/Qwen3-4B",
    messages=[{"role": "user", "content": "Hello!"}],
    extra_body={"chat_template_kwargs": {"enable_thinking": False}},
)
print(resp.choices[0].message.content)
Hello! How can I assist you today? 😊

在开始前快速检查健康状况:curl https://<job_id>--8000.hf.jobs/v1/models -H "Authorization: Bearer $(hf auth token)" 应列出该模型。

🔐 该端点是有权限限制的,而非公开的。 每个请求必须携带一个具有 job 命名空间读取权限 的 HF token。直接浏览器访问会被拒绝。实际上,jobs 代理就是你的 API 网关:访问权限仅限于你(以及你的组织)。这对于私有使用来说没问题,但请妥善对待该 URL:不要期望它是开放的而分享它,也不要把你的 token 粘贴到不可信的地方。如果你需要更细粒度或公开的访问,请在前面放置一个合适的网关。或者参考下面的 HF Jobs 还是 Inference Endpoints?

清理

Jobs 按秒计费,所以完成后请停止服务器:

hf jobs cancel <job_id>

你设置的 --timeout 是一个安全网(会自动停止),但显式取消更省钱。a10g-large 的运行费用为 $1.50/小时——运行 hf jobs hardware 查看完整价格列表,并选择适合你模型的最小 flavor。

进阶:更大的模型

同样的命令可以扩展到更大的模型——选择一个更强的 --flavor,并通过 --tensor-parallel-size 告诉 vLLM 将模型分片到多个 GPU 上。例如,在 2× H200 上运行 122B 的 Qwen3.5 mixture-of-experts 模型:

hf jobs run --flavor h200x2 --expose 8000 --timeout 2h \
  vllm/vllm-openai:latest \
  vllm serve Qwen/Qwen3.5-122B-A10B \
  --host 0.0.0.0 --port 8000 --tensor-parallel-size 2 \
  --max-model-len 32768 --max-num-seqs 256

--tensor-parallel-size 应与 flavor 中的 GPU 数量匹配(h200x2 → 2,h200x8 → 8)。运行 hf jobs hardware 查看可用选项,并为更大的模型设置更长的 --timeout,因为它们下载和加载需要更长时间。对于大模型,H200 flavor 通常性价比最高。

--max-model-len 32768 --max-num-seqs 256 标志特定于该模型:Qwen3.5-122B 是一种混合 Mamba/attention 架构,默认上下文为 256K token,这会导致 vLLM 的默认 batch 设置内存不足。限制上下文长度和并发序列数量可以使其保持在 GPU 内存范围内。如果模型因内存不足或 cache-block 错误而无法启动,首先尝试调低这两个参数。其他所有内容(暴露的 URL、OpenAI 客户端、token 认证)保持不变。

进阶:在 UI 中聊天

更喜欢聊天窗口而不是 curl?几行 Gradio 代码即可指向同一个端点。在 vllm serve 命令中添加 --reasoning-parser deepseek_r1,这样 Qwen3 的思考过程会作为单独字段返回(非必需,但很有帮助),然后在本地运行以下代码(你只需要 job ID):

import gradio as gr
from gradio import ChatMessage
from huggingface_hub import get_token
from openai import OpenAI

client = OpenAI(base_url="https://<job_id>--8000.hf.jobs/v1", api_key=get_token())

def chat(message, history):
    messages = [{"role": m["role"], "content": m["content"]} for m in history if not m.get("metadata")]
    messages.append({"role": "user", "content": message})
    stream = client.chat.completions.create(model="Qwen/Qwen3-4B", messages=messages, stream=True)

    thinking, answer = "", ""
    for chunk in stream:
        delta = chunk.choices[0].delta
        thinking += delta.model_extra.get("reasoning", "")
        answer += delta.content or ""
        out = []
        if thinking.strip():
            status = "done" if answer.strip() else "pending"
            out.append(ChatMessage(role="assistant", content=thinking, metadata={"title": "💭 Thinking", "status": status}))
        if answer.strip():
            out.append(ChatMessage(role="assistant", content=answer))
        yield out

gr.ChatInterface(chat).launch()

运行它,打开 http://127.0.0.1:7860,然后聊天——思考过程会流式显示到可折叠面板中,答案在下方。

视频 5

进阶:SSH 进入运行中的服务器

需要调试启动失败、查看 GPU 内存或交互式地查看日志?你可以直接打开一个 shell 进入正在运行的 job。使用 --ssh 启动,并确保你的公钥已在 huggingface.co/settings/keys 注册:

hf jobs run --flavor a10g-large --expose 8000 --timeout 2h --ssh \
  vllm/vllm-openai:latest \
  vllm serve Qwen/Qwen3-4B --host 0.0.0.0 --port 8000

然后使用 job ID 连接:

hf jobs ssh <job_id>

你现在位于容器内部,可以运行 nvidia-smi、检查进程或直接操作模型——这比从外部读取日志更容易进行调试和监控。SSH 支持需要 huggingface_hub >= 1.20.0

进阶:将其用作 Pi 的编码 agent 后端

同一个端点可以作为终端编码 agent 的后端。Pi 是一个与提供商无关的 agent 框架。将其指向 job,你就可以获得一个运行在自己托管模型上的 Read/Write/Edit/Bash agent。

需要先设置一件事:agent 通过 tool call 驱动模型,而 vLLM 只有在服务器以启用 tool calling 的方式启动时才会接受这些调用。因此,使用 --enable-auto-tool-choice 和与模型系列匹配的 --tool-call-parser(Qwen3 使用 hermes)重新启动。Agent 也受益于更强的模型,所以这里适合引入更大的模型:

hf jobs run --flavor h200x2 --expose 8000 --timeout 2h \
  vllm/vllm-openai:latest \
  vllm serve Qwen/Qwen3.5-122B-A10B \
  --host 0.0.0.0 --port 8000 --tensor-parallel-size 2 \
  --max-model-len 32768 --max-num-seqs 256 \
  --reasoning-parser deepseek_r1 \
  --enable-auto-tool-choice --tool-call-parser hermes

然后将该 job 作为自定义 provider 添加到 ~/.pi/agent/models.json

{
  "providers": {
    "hf-jobs": {
      "baseUrl": "https://<job_id>--8000.hf.jobs/v1",
      "api": "openai-completions",
      "apiKey": "!hf auth token",
      "models": [
        { "id": "Qwen/Qwen3.5-122B-A10B" }
      ]
    }
  }
}

然后启动 agent 指向它:

pi

你刚才用几条命令启动的模型,现在正在驱动终端中的交互式编码 agent。

视频 6

HF Jobs 还是 Inference Endpoints?

HF Jobs 并不是在 Hugging Face 上提供模型的唯一方式。Inference Endpoints 是我们针对相同任务提供的托管产品,选择哪个取决于你的需求。

当你需要最大的灵活性和控制力时,选择 HF Jobs:它只是 HF 基础设施上的 docker run,因此你可以选择镜像、精确的 vllm serve 标志和硬件,按秒付费,直到 job 运行结束。这使得它非常适合实验、一次性评估、批量生成,或在决定投入之前试用模型。

当你需要更接近生产就绪的东西时,选择 Inference Endpoints。它们提供了长期运行服务所需的运维便利:更细粒度的访问控制(端点可以是公开的、受保护的或私有的),以及 scale-to-zero,这样在非活动期间你不会被计费。如果你要搭建一个持久端点而不是运行一个 job,那才是合适的工具。

延伸阅读

本文专注于 vLLM,但相同的暴露端口模式适用于任何兼容 OpenAI 的服务器。要使用 llama.cpp 提供 GGUFs 或运行 SGLang,请参阅 Serve Models on Jobs 指南,其中详细介绍了这些后端。

译自 Hugging Face · 官方博客 · 录于 二〇二六年六月二十五日