> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tokios.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Tokios exposes private local models through https://api.tokios.com using an outbound-only connector tunnel.
> Use 'connector' for the local tokios-connector process.
> Use 'deployment' for the public model name in the API model field.
> Use 'upstream model id' for the model served by Ollama, llama.cpp, vLLM, LM Studio, or another local backend.
> API keys use the prefix sk-tok-. Connector tokens use the prefix ct-tok-.

# 优化 vLLM 的吞吐量和延迟

> 针对最大吞吐量或最低延迟调优 vLLM —— KV 缓存调优、前缀缓存、分块预填充、LoRA 服务、量化选项以及 V1 架构变更。

vLLM 是功能最丰富的开源 GPU 大语言模型推理运行时。它提供了大量直接影响吞吐量、延迟和显存占用的配置选项。本指南介绍最关键的调优参数以及如何根据你的工作负载进行设置。

> [!NOTE]
>
> 最后验证：2026-10-14 — vLLM v0.31.0。

> [!NOTE]
>
> **V1 是默认架构。** V1 架构现在是 vLLM v0.31.0 的默认架构。它引入了新的调度器、默认启用的分块预填充以及改进的 GPU 显存管理。如果你发现与旧版指南的行为存在差异，V1 很可能是原因。

## KV 缓存调优

KV 缓存为每个活跃序列中的每个 token 存储键值张量。它通常是模型权重之后最大的 GPU 显存消耗者，因此调优它对能同时服务的请求数量影响最大。

### 大小计算公式

vLLM 会自动计算 KV 缓存大小，但理解公式有助于你设置限制：

```
KV memory per token = 2 × num_layers × num_kv_heads × head_dim × dtype_bytes
```

系数 2 对应键和值两部分。对于一个 7B 模型，32 层、32 个 KV 头、128 头维度、`float16`：

```
2 × 32 × 32 × 128 × 2 = 524,288 bytes ≈ 0.5 MB per token
```

在 24 GB KV 缓存空间下，大约可以容纳所有序列共约 48,000 个 token。

### 使用 fp8 KV 缓存

`--kv-cache-dtype fp8` 将 KV 缓存显存占用相比默认 `float16` 减少约 50%。这直接将可缓存的 token 数量翻倍，意味着更多并发序列或更长上下文。

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --kv-cache-dtype fp8
```

> [!WARNING]
>
> FP8 KV 缓存会引入少量精度损失。对于大多数对话和代码生成工作负载，差异可以忽略不计，但如果你对特定任务进行评估，请在生产环境中启用之前验证输出质量是否达到你的阈值。

### `--max-num-seqs` 与 `--max-model-len`

这 2 个标志竞争同一个 KV 缓存池：

* `--max-model-len` 限制单个序列的上下文长度。降低它可以释放 KV 缓存以容纳更多并发序列。
* `--max-num-seqs` 限制一个批次中处理的序列数量。提高它可以增加吞吐量，但会消耗更多每序列显存。

如果你的工作负载发送短提示词（低于 2K token），降低 `--max-model-len` 并提高 `--max-num-seqs` 以最大化并发。如果你服务长上下文请求，则相反操作。

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
# Short prompts, high concurrency
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --max-model-len 4096 \
  --max-num-seqs 256

# Long context, fewer concurrent sequences
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --max-model-len 32768 \
  --max-num-seqs 32
```

## 前缀缓存

许多实际工作负载发送的请求共享公共前缀：系统提示词、RAG 检索块或多轮对话中的早期轮次。如果没有前缀缓存，vLLM 会在每次请求时重新计算该共享前缀的 KV 缓存。

`--enable-prefix-caching` 将已计算的 KV 块存储在哈希索引表中。当新请求的前缀与缓存块匹配时，vLLM 会复用已缓存的 KV 张量，而不是重新计算。

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --enable-prefix-caching
```

> [!TIP]
>
> 前缀缓存在以下场景中特别有效：
>
> * 每个请求都包含相同的系统提示词（在对话应用和编程代理中很常见）。
> * 你使用 RAG 并在每个查询前附加固定的检索块。
> * 多轮对话将早期轮次作为上下文复用。
>
> 当每个请求都有唯一前缀时，它没有任何收益。

前缀缓存在 V1 中默认启用。只有在使用 `V0` 调度器模式时才需要显式指定该标志。

## 分块预填充

预填充——处理输入提示词——是计算密集型的。一个长提示词（8K+ token）可能独占 GPU 数百毫秒，阻塞其他序列的解码步骤并导致延迟尖峰。

分块预填充将预填充拆分为较小的块，与解码步骤交替执行。GPU 处理一个提示词块，然后为其他活跃序列运行一个解码步骤，再继续下一个预填充块。这使得解码延迟保持可预测。

在 V1 中，分块预填充**默认启用**。你可以控制块大小：

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --max-num-batched-tokens 8192
```

`--max-num-batched-tokens` 设置单个调度步骤中处理的最大 token 数。较低的值减少预填充对解码延迟的影响，但增加首 token 总时间（TTFT）。较高的值提高预填充吞吐量，但可能导致偶发的解码抖动。

> [!NOTE]
>
> 如果你在旧版 vLLM 中禁用了分块预填充并正在升级到 V1，请移除 `--enable-chunked-prefill` 标志——它在 V1 中始终开启，该标志会被忽略。

## LoRA 服务

vLLM 可以在单个进程中服务多个 LoRA 适配器，而无需将它们合并到基础模型中。这让你可以运行一个基础模型并将请求路由到不同的微调变体——例如，一个编程适配器、一个摘要适配器和一个通用对话适配器——全部共享 GPU 显存中的相同基础权重。

### 启用 LoRA 服务

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
vllm serve meta-llama/Llama-3.1-8B \
  --enable-lora \
  --lora-modules \
    coder=./lora-adapter-coder \
    summarizer=./lora-adapter-summarizer
```

在 `--lora-modules` 中，每个条目将一个面向请求的名称映射到本地路径。客户端在 `model` 字段中选择适配器：

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "coder",
    "messages": [
      { "role": "user", "content": "Write a Python function that sorts a list." }
    ]
  }'
```

### 动态加载

vLLM 支持动态 LoRA 加载——你可以在运行时通过 API 添加或移除适配器，而无需重启服务器。当你有许多适配器但只有少数在任何时刻处于活跃状态时，这很有用。

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
# Load a new adapter at runtime
curl http://localhost:8000/v1/load_lora_adapter \
  -H "Content-Type: application/json" \
  -d '{
    "lora_name": "translator",
    "lora_path": "./lora-adapter-translator"
  }'
```

> [!TIP]
>
> 使用 `--max-lora-rank` 限制服务器接受的 LoRA 适配器的秩。较低秩的适配器使用更少的显存。如果你所有的适配器共享相同的秩，将其设置为该秩以避免为未使用的容量过度分配显存。

## 量化选项

量化将模型权重精度降低到 16 位以下，以少量精度换取显著的显存和速度提升。vLLM 支持多种量化格式：

| 格式 | 精度 | 硬件 | 最适合 |
| - | - | - | - |
| **AWQ** | 4-bit integer | Any GPU | 通用 4 位量化。精度保持良好。Hugging Face 上广泛提供预量化模型。 |
| **GPTQ** | 4-bit integer | Any GPU | 较旧的格式，与 AWQ 类似。新量化建议选择 AWQ——GPTQ 保留用于兼容现有模型。 |
| **FP8** | 8-bit float | Ampere+ (A100, H100, L40, RTX 4090) | 接近 FP16 的精度，显存占用减半。当 GPU 支持时是不错的选择。 |
| **NVFP4** | 4-bit float | Blackwell (B200, GB200, RTX 5090) | 最新的格式。在 Blackwell 硬件上实现最大显存节省。 |

### 使用量化模型

对于预量化模型，vLLM 从模型的 `config.json` 中自动检测格式：

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
# AWQ model — auto-detected
vllm serve TheBloke/Llama-2-7B-Chat-AWQ

# FP8 model — auto-detected on Ampere+ GPUs
vllm serve neuralmagic/Meta-Llama-3.1-8B-Instruct-FP8
```

> [!WARNING]
>
> **FP8 简写在 v0.31 中发生了变化。** FP8 量化标识符现在是 `fp8_per_tensor`。如果你在脚本或 CI 管道中显式传递 `--quantization fp8`，请更新为新的标识符。`config.json` 中包含 FP8 的模型不受影响——自动检测仍然有效。

### 在线量化

你也可以在加载过程中即时量化模型，但生产环境建议使用预量化模型：

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
vllm serve meta-llama/Llama-3.1-70B \
  --quantization awq
```

## 吞吐量与延迟

你的优化策略取决于你优先关注**吞吐量**（所有请求的总 token 每秒数）还是**延迟**（单个请求的首 token 时间和 token 间延迟）。

### 最大化吞吐量

增大批次大小以在每个 GPU 步骤中打包更多工作：

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --max-num-seqs 256 \
  --max-num-batched-tokens 16384 \
  --enable-prefix-caching \
  --kv-cache-dtype fp8
```

* `--max-num-seqs 256` 允许一个批次中最多 256 个并发序列。
* `--max-num-batched-tokens 16384` 允许每个调度步骤处理更多 token。
* `--kv-cache-dtype fp8` 释放显存以容纳更多序列。

### 最小化延迟

减小批次大小并禁用那些以延迟换吞吐量的优化：

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --max-num-seqs 16 \
  --max-num-batched-tokens 4096 \
  --enforce-eager
```

* `--max-num-seqs 16` 保持较小的批次，使每个请求更快获得 GPU 时间。
* `--enforce-eager` 禁用 CUDA graph。CUDA graph 捕获并重放固定的计算图，这提高了吞吐量但会在每个新批次形状的首次运行时增加延迟。在调试或每毫秒 TTFT 都很重要时使用 `--enforce-eager`。

> [!TIP]
>
> 对于用户等待响应的交互式应用，目标 TTFT 低于 500ms。从 `--max-num-seqs 32` 和 `--max-num-batched-tokens 4096` 开始，然后根据负载下实测的 TTFT 进行调整。

## V1 架构变更

V1 是 vLLM v0.31.0 中的默认调度器。如果你之前使用过 vLLM，以下是变化内容：

**新的调度器。** V1 调度器用统一的显存管理器取代了 V0 块管理器，该管理器在单次遍历中处理 KV 缓存、前缀缓存和分块预填充。这减少了调度开销并消除了 V0 可能导致 GPU 显存碎片的多种边界情况。

**分块预填充成为默认。** 预填充和解码自动交替执行。你不再需要 `--enable-chunked-prefill`——它始终开启。

**更好的显存管理。** V1 以更细的粒度跟踪 GPU 显存，减少填充和对齐造成的浪费空间。在相同硬件上，预计可用 KV 缓存多出 5-15%，与 V0 相比。

**CUDA graph 改进。** V1 在更广泛的批次形状范围内更积极地捕获 CUDA graph，无需手动调优即可提高吞吐量。

> [!NOTE]
>
> 如果你遇到 V1 的回退问题，可以通过在启动服务器之前设置环境变量 `VLLM_USE_V1=0` 回退到 V0。请将问题报告给 vLLM 团队——V0 不会收到新功能。

### v0.31 新增：持久权重缓存和快照

vLLM v0.31 引入了 2 个新的 CLI 命令：

* **`vllm preload`** 启动一个持久权重缓存守护进程，在服务器重启之间将模型权重保留在 GPU 显存中。服务器不再在每次重启时从磁盘加载数 GB 的模型，而是连接到守护进程并复用已缓存的权重。这将冷启动时间从数分钟缩短到数秒。

* **`vllm snapshot create`** 捕获当前服务器状态（已加载的模型、适配器、配置），**`vllm snapshot restore`** 即时恢复它。适用于在错误配置更改后回滚或在机器之间复制已知良好的设置。

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
# Start the weight-cache daemon
vllm preload meta-llama/Llama-3.1-8B-Instruct

# Create a snapshot of the current state
vllm snapshot create my-production-config

# Restore it on another machine
vllm snapshot restore my-production-config
```

### v0.31 中的破坏性变更

* **`--trust-request-mm-kwargs`** 现在是客户端通过请求体发送多模态输入（图像、音频）时必需的。没有此标志，vLLM 会出于安全原因拒绝多模态 kwargs。如果你的应用在 API 请求中发送图像或其他媒体，请添加此标志。

* **`--grpc`** 在 HTTP 服务器旁边启用 gRPC 服务。如果你使用 gRPC 客户端，请使用此标志启动 vLLM 以暴露 gRPC 端点。

## 示例配置

### 高吞吐批处理

对于总 token 每秒数比单个请求延迟更重要的离线批处理工作负载：

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --tensor-parallel-size 4 \
  --kv-cache-dtype fp8 \
  --enable-prefix-caching \
  --max-num-seqs 512 \
  --max-num-batched-tokens 32768 \
  --max-model-len 8192
```

此配置在 4 GPU 设置上最大化并发。等效 4 位的 KV 缓存和较高的批次限制以更长每请求延迟为代价推高吞吐量。

### 低延迟交互式服务

对于用户等待响应且 TTFT 应低于 500ms 的对话应用：

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --kv-cache-dtype fp8 \
  --enable-prefix-caching \
  --max-num-seqs 32 \
  --max-num-batched-tokens 4096 \
  --max-model-len 8192
```

较小的批次大小和适中的 token 限制保持 GPU 的响应能力。前缀缓存加速重复的系统提示词而不会增加延迟。

### 多适配器 LoRA 服务

对于从一个基础模型服务多个微调变体：

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
vllm serve meta-llama/Llama-3.1-8B \
  --enable-lora \
  --lora-modules \
    coder=./adapters/coder \
    reviewer=./adapters/reviewer \
    summarizer=./adapters/summarizer \
  --max-lora-rank 64 \
  --kv-cache-dtype fp8 \
  --enable-prefix-caching \
  --max-num-seqs 128
```

客户端通过 `model` 字段中的名称选择适配器。全部 3 个适配器共享相同的基础模型权重，因此 GPU 显存占用接近单独服务基础模型——每个 LoRA 适配器仅增加几 MB。

> [!NOTE]
>
> 更改 vLLM 配置后，请重新注册你的 Tokios 部署，以便连接器获取新的上游端点。请参阅[注册模型](/zh/setup/register-model.md)。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.