# 在作业上部署模型

借助[暴露的端口](./jobs-configuration#expose-ports)，Job 可以充当临时推理服务器：在 GPU 规格上启动 vLLM，将任何兼容 OpenAI 的客户端指向该 Job 的 URL，完成后取消该 Job 即可。在 Job 运行期间按分钟计费，端点会随 Job 一起消失。

当端点只是手段而非最终产品时，这种方式非常适用：例如一次评估运行、一个数据标注会话、针对热模型迭代提示词，或一个只需运行一个下午的演示。

> [!TIP]
> 如果您需要一个更持久且不会消失的端点，请使用[Inference Endpoints](https://huggingface.co/docs/inference-endpoints)，它提供带有自动扩缩容、监控和稳定 URL 的托管基础设施。

## 启动 vLLM 服务器

`vllm/vllm-openai` 镜像已预装所有依赖。一条命令即可启动兼容 OpenAI 的服务器：

```bash
>>> hf jobs run --detach --expose 8000 --flavor a10g-small -s HF_TOKEN \
...   vllm/vllm-openai \
...   vllm serve LiquidAI/LFM2.5-8B-A1B --max-model-len 8192
✓ Job started
  id: 6a2b137a59bbdade52d4a58c
  url: https://huggingface.co/jobs/davanstrien/6a2b137a59bbdade52d4a58c
Hint: Exposed ports are reachable at (requires an HF token with read access to the job):
  https://6a2b137a59bbdade52d4a58c--8000.hf.jobs
```

`-s HF_TOKEN` 会将您的 Hugging Face token 作为密钥转发到作业中，从而对模型下载进行身份验证——这对于受限或私有模型是必需的，并且可以为其他所有模型提供更高的速率限制和更快的下载速度。

> [!NOTE]
> Jobs 会直接运行您提供的命令——它不会像 `docker run` 那样将参数传递给镜像的 entrypoint。请务必完整写出命令（例如 `vllm serve ...`，而不仅仅是 `--model ...`）。

服务器需要几分钟才能就绪（拉取镜像、下载模型、加载模型）。使用 `hf jobs logs -f <job_id>` 跟踪进度；当日志显示 `Application startup complete` 时，服务器即已就绪。

## 连接客户端

暴露的端口需要一个具有作业命名空间 `read` 访问权限的 HF token，并以 Bearer token 的形式传递。对于 OpenAI 兼容的服务器，该 token 可直接作为客户端的 API key 使用——基础 URL 为暴露的端口 URL 加上 `/v1`：

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://6a2b137a59bbdade52d4a58c--8000.hf.jobs/v1",
    api_key=os.environ["HF_TOKEN"],  # any token with read access to the job's namespace
)

response = client.chat.completions.create(
    model="LiquidAI/LFM2.5-8B-A1B",
    messages=[{"role": "user", "content": "Write a haiku about ephemeral compute."}],
)
print(response.choices[0].message.content)
```

LFM2.5 是一个推理模型，因此其响应会在最终答案之前包含位于 `<think>` 标签内的推理过程。

或者使用 `curl`：

```bash
>>> curl https://6a2b137a59bbdade52d4a58c--8000.hf.jobs/v1/chat/completions \
...   -H "Authorization: Bearer $HF_TOKEN" \
...   -H "Content-Type: application/json" \
...   -d '{"model": "LiquidAI/LFM2.5-8B-A1B", "messages": [{"role": "user", "content": "Hello!"}]}'
```

由于令牌位于 `Authorization` 请求头中，这些 URL 可在脚本、笔记本和智能体中使用——任何使用 OpenAI 兼容 API 的场景均可。它们无法直接在浏览器中打开。若要在没有 HF 令牌的情况下提供端口，请使用 `--expose-public`——参见 [暴露端口](./jobs-configuration#expose-ports)。

## 使用 llama.cpp 部署 GGUF 模型

同样的模式适用于任何支持 HTTP 的服务器。llama.cpp 的 `llama serve` 可以通过 `-hf` 标志直接从 Hub 拉取 GGUF 文件，并提供相同的 OpenAI 兼容 API。例如，要使用 Gemma 推荐的采样设置来提供 [Gemma 4 E4B](https://huggingface.co/ggml-org/gemma-4-E4B-it-GGUF) 服务：

```bash
>>> hf jobs run --detach --expose 8080 --flavor a10g-small -s HF_TOKEN \
...   ghcr.io/ggml-org/llama.cpp:server-cuda -- \
...   /app/llama serve -hf ggml-org/gemma-4-E4B-it-GGUF \
...   --host 0.0.0.0 --port 8080 -ngl 99 \
...   --temp 1.0 --top-p 0.95 --top-k 64
```

`--` 用于将任务的命令与 `hf jobs run` 自身的选项分隔开——在此处是必需的，因为否则 `llama serve` 的标志会被 CLI 本身解析。

> [!TIP]
> 你可以通过将模型仓库挂载为只读卷，并让服务器直接指向该文件，从而完全跳过模型下载：
>
> ```bash
> >>> hf jobs run --detach --expose 8080 --flavor a10g-small -s HF_TOKEN \
> ...   -v hf://ggml-org/gemma-4-E4B-it-GGUF:/model:ro \
> ...   ghcr.io/ggml-org/llama.cpp:server-cuda -- \
> ...   /app/llama serve --model /model/gemma-4-E4B-it-Q4_K_M.gguf \
> ...   --host 0.0.0.0 --port 8080 -ngl 99
> ```
>
> 由于无需下载任何内容，服务器启动速度大幅提升——模型在加载时直接从挂载的仓库中流式传输。

> [!WARNING]
> 您的服务器必须监听 `0.0.0.0`。`llama serve` 默认绑定到 `127.0.0.1`，作业代理无法访问该地址——请显式传入 `--host 0.0.0.0`。

其他任何 OpenAI 兼容服务器（SGLang、...）也适用同样的方法：在暴露的端口上启动服务器，监听 `0.0.0.0`，并使用你的 HF token 作为 API 密钥进行连接。

## 停止服务器

当您取消任务或达到其超时时间（默认为 30 分钟；对于更长的会话，请显式设置 `--timeout`）时，该任务及其计费将停止：

```bash
>>> hf jobs cancel <job_id>
```

> [!NOTE]
> 暴露端口需要 `huggingface_hub` >= 1.19.0，并且会在作业硬件费用的基础上额外计费——请参阅 [作业定价](./jobs-pricing)。

