# vLLM

适用于 CLORE.AI GPU 上生产工作负载的高吞吐量 LLM 推理服务器。

{% hint style="success" %}
所有示例都可以在通过以下方式租用的 GPU 服务器上运行 [CLORE.AI 市场](https://clore.ai/marketplace).
{% endhint %}

{% hint style="info" %}
**当前版本：v0.7.x** — 本指南涵盖 vLLM v0.7.3+。新功能包括对 DeepSeek-R1 的支持、带自动工具选择的结构化输出、多 LoRA 服务，以及更好的内存效率。
{% endhint %}

## 服务器要求

| 参数   | 最低       | 推荐     |
| ---- | -------- | ------ |
| 内存   | **16GB** | 32GB+  |
| 显存   | 16GB（7B） | 24GB+  |
| 网络   | 500Mbps  | 1Gbps+ |
| 启动时间 | 5-15 分钟  | -      |

{% hint style="info" %}
需要匹配的 GPU？ [RTX 4090（24GB）](https://clore.ai/rent-4090.html?utm_source=docs\&utm_medium=guide\&utm_campaign=vllm) 足以轻松处理 7B–13B；对于 70B+ 模型， [H100（80GB）](https://clore.ai/rent-h100.html?utm_source=docs\&utm_medium=guide\&utm_campaign=vllm) 是最稳妥的选择。
{% endhint %}

{% hint style="danger" %}
**重要：** vLLM 需要较大的 RAM 和 VRAM。低于 16GB RAM 的服务器甚至无法运行 7B 模型。
{% endhint %}

{% hint style="warning" %}
**启动时间：** 首次启动会从 HuggingFace 下载模型（视模型大小和网络速度而定，需 5-15 分钟）。此期间出现 HTTP 502 属于正常现象。
{% endhint %}

## 为什么选择 vLLM？

* **最高吞吐量** - PagedAttention 带来 24 倍更高的吞吐量
* **可直接用于生产** - 开箱即用的 OpenAI 兼容 API
* **持续批处理** - 高效的多用户服务
* **流式输出** - 实时生成 token
* **多 GPU** - 面向大模型的张量并行
* **多 LoRA** - 可同时提供多个微调适配器（v0.7+）
* **结构化输出** - JSON Schema 约束和工具调用（v0.7+）

## 在 CLORE.AI 上快速部署

**Docker 镜像：**

```
vllm/vllm-openai:v0.7.3
```

**端口：**

```
22/tcp
8000/http
```

**命令：**

```bash
vllm serve mistralai/Mistral-7B-Instruct-v0.2 --host 0.0.0.0 --port 8000
```

### 验证是否正常工作

部署后，找到你的 `http_pub` URL，在 **我的订单**:

```bash
# 检查健康状态（首次运行可能需要 5-15 分钟）
curl https://your-http-pub.clorecloud.net/health

# 列出模型（仅在模型加载后可用）
curl https://your-http-pub.clorecloud.net/v1/models
```

{% hint style="warning" %}
如果超过 15 分钟仍然返回 HTTP 502，请检查：

1. 服务器是否有 16GB+ RAM
2. 服务器是否有足够的 VRAM 供该模型使用
3. 是否已为受限模型设置 HuggingFace token
   {% endhint %}

## 访问你的服务

在 CLORE.AI 上部署后，可通过以下方式访问 vLLM： `http_pub` URL：

```bash
# 聊天补全
curl https://your-http-pub.clorecloud.net/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "messages": [{"role": "user", "content": "你好！"}]
  }'
```

{% hint style="info" %}
所有 `localhost:8000` 下面的示例在通过 SSH 连接时可用。对于外部访问，请替换为你的 `https://your-http-pub.clorecloud.net/` URL。
{% endhint %}

## 安装

### 使用 Docker（推荐）

```bash
docker run -d --gpus all \
    -p 8000:8000 \
    --ipc=host \
    vllm/vllm-openai:v0.7.3 \
    --model mistralai/Mistral-7B-Instruct-v0.2 \
    --host 0.0.0.0
```

### 使用 pip

```bash
pip install vllm==0.7.3

# 运行服务器
python -m vllm.entrypoints.openai.api_server \
    --model mistralai/Mistral-7B-Instruct-v0.2
```

## 支持的模型

| 模型                            | 参数量      | 所需 VRAM         | 所需 RAM |
| ----------------------------- | -------- | --------------- | ------ |
| Mistral 7B                    | 7B       | 14GB            | 16GB+  |
| Llama 3.1 8B                  | 8B       | 16GB            | 16GB+  |
| Llama 3.1 70B                 | 70B      | 140GB（或 2x80GB） | 64GB+  |
| Mixtral 8x7B                  | 47B      | 90GB            | 32GB+  |
| Qwen2.5 7B                    | 7B       | 14GB            | 16GB+  |
| Qwen2.5 72B                   | 72B      | 145GB           | 64GB+  |
| DeepSeek-V3                   | 236B MoE | 多 GPU           | 128GB+ |
| DeepSeek-R1-Distill-Qwen-7B   | 7B       | 14GB            | 16GB+  |
| DeepSeek-R1-Distill-Qwen-32B  | 32B      | 64GB            | 32GB+  |
| DeepSeek-R1-Distill-Llama-70B | 70B      | 140GB           | 64GB+  |
| Phi-4                         | 14B      | 28GB            | 32GB+  |
| Gemma 2 9B                    | 9B       | 18GB            | 16GB+  |
| CodeLlama 34B                 | 34B      | 68GB            | 32GB+  |

## 服务器选项

### 基础服务器

```bash
vllm serve mistralai/Mistral-7B-Instruct-v0.2 \
    --host 0.0.0.0 \
    --port 8000
```

### 生产服务器

```bash
vllm serve mistralai/Mistral-7B-Instruct-v0.2 \
    --host 0.0.0.0 \
    --port 8000 \
    --tensor-parallel-size 1 \
    --max-model-len 8192 \
    --gpu-memory-utilization 0.9 \
    --max-num-seqs 256 \
    --enable-prefix-caching
```

### 使用量化（更低 VRAM）

```bash
# AWQ 量化模型（使用更少 VRAM）
vllm serve TheBloke/Mistral-7B-Instruct-v0.2-AWQ \
    --host 0.0.0.0 \
    --quantization awq
```

### 结构化输出和工具调用（v0.7+）

启用自动工具选择和结构化 JSON 输出：

```bash
vllm serve mistralai/Mistral-7B-Instruct-v0.2 \
    --host 0.0.0.0 \
    --enable-auto-tool-choice \
    --tool-call-parser mistral
```

在 Python 中使用：

```python
from openai import OpenAI
import json

client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取某个城市的当前天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名称"},
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
                },
                "required": ["city"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[{"role": "user", "content": "巴黎的天气如何？"}],
    tools=tools,
    tool_choice="auto"
)

# 解析工具调用
tool_call = response.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
print(f"Tool: {tool_call.function.name}, Args: {args}")
```

通过 response format 输出结构化 JSON：

```python
response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[{"role": "user", "content": "提取：John Smith，30 岁，软件工程师"}],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                    "occupation": {"type": "string"}
                },
                "required": ["name", "age", "occupation"]
            }
        }
    }
)
print(response.choices[0].message.content)
```

### 多 LoRA 服务（v0.7+）

同时使用多个 LoRA 适配器为一个基础模型提供服务：

```bash
vllm serve meta-llama/Meta-Llama-3.1-8B-Instruct \
    --host 0.0.0.0 \
    --enable-lora \
    --lora-modules \
        sql-adapter=path/to/sql-lora \
        code-adapter=path/to/code-lora \
        chat-adapter=path/to/chat-lora \
    --max-lora-rank 64
```

按模型名称查询特定的 LoRA 适配器：

```python
# 使用 SQL 适配器
response = client.chat.completions.create(
    model="sql-adapter",
    messages=[{"role": "user", "content": "编写一个 SQL 查询以找出前 10 位客户"}]
)

# 使用代码适配器
response = client.chat.completions.create(
    model="code-adapter",
    messages=[{"role": "user", "content": "编写一个 Python 函数来排序列表"}]
)
```

## DeepSeek-R1 支持（v0.7+）

vLLM v0.7+ 原生支持 DeepSeek-R1 蒸馏模型。这些推理模型会生成 `<think>` 标签，展示它们的推理过程。

### DeepSeek-R1-Distill-Qwen-7B（单 GPU）

```bash
vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-7B \
    --host 0.0.0.0 \
    --port 8000 \
    --max-model-len 16384
```

### DeepSeek-R1-Distill-Qwen-32B（双 GPU）

```bash
vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-32B \
    --host 0.0.0.0 \
    --port 8000 \
    --tensor-parallel-size 2 \
    --max-model-len 32768 \
    --gpu-memory-utilization 0.90
```

### DeepSeek-R1-Distill-Llama-70B（四 GPU）

```bash
vllm serve deepseek-ai/DeepSeek-R1-Distill-Llama-70B \
    --host 0.0.0.0 \
    --port 8000 \
    --tensor-parallel-size 4 \
    --max-model-len 32768
```

### 查询 DeepSeek-R1

```python
from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")

response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
    messages=[
        {
            "role": "user",
            "content": "解答：如果一列火车在 1.5 小时内行驶 120 公里，它的速度是多少 m/s？"
        }
    ],
    max_tokens=2048,
    temperature=0.6
)

content = response.choices[0].message.content
# 响应包含 <think>...</think> 推理块，后面跟着答案
print(content)
```

解析 think 标签：

```python
import re

def parse_deepseek_r1_response(content: str) -> dict:
    """从 DeepSeek-R1 响应中提取思考过程和答案。"""
    think_match = re.search(r'<think>(.*?)</think>', content, re.DOTALL)
    thinking = think_match.group(1).strip() if think_match else ""
    answer = re.sub(r'<think>.*?</think>', '', content, flags=re.DOTALL).strip()
    return {"thinking": thinking, "answer": answer}

result = parse_deepseek_r1_response(content)
print("Thinking:", result["thinking"][:200], "...")
print("Answer:", result["answer"])
```

## API 用法

### 聊天补全（OpenAI 兼容）

```python
from openai import OpenAI

# 对于外部访问，请使用你的 http_pub URL：
client = OpenAI(
    base_url="https://your-http-pub.clorecloud.net/v1",
    api_key="not-needed"
)

# 或通过 SSH 隧道：
# client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")

response = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[
        {"role": "user", "content": "解释量子计算"}
    ],
    max_tokens=500,
    temperature=0.7
)

print(response.choices[0].message.content)
```

### 流式输出

```python
stream = client.chat.completions.create(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    messages=[{"role": "user", "content": "写一首诗"}],
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")
```

### cURL

```bash
curl https://your-http-pub.clorecloud.net/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "messages": [{"role": "user", "content": "你好！"}],
    "max_tokens": 100
  }'
```

### 文本补全

```bash
curl https://your-http-pub.clorecloud.net/v1/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "prompt": "法国的首都是",
    "max_tokens": 50
  }'
```

## 完整 API 参考

vLLM 提供 OpenAI 兼容端点，以及额外的实用端点。

### 标准端点

| 端点                     | 方法   | 说明          |
| ---------------------- | ---- | ----------- |
| `/v1/models`           | GET  | 列出可用模型      |
| `/v1/chat/completions` | POST | 聊天补全        |
| `/v1/completions`      | POST | 文本补全        |
| `/health`              | GET  | 健康检查（可能返回空） |

### 附加端点

| 端点            | 方法   | 说明            |
| ------------- | ---- | ------------- |
| `/tokenize`   | POST | 将文本分词         |
| `/detokenize` | POST | 将 token 转换为文本 |
| `/version`    | GET  | 获取 vLLM 版本    |
| `/docs`       | GET  | Swagger UI 文档 |
| `/metrics`    | GET  | Prometheus 指标 |

#### 文本分词

在发送请求前用于统计 token 数量：

```bash
curl https://your-http-pub.clorecloud.net/tokenize \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "prompt": "Hello world"
  }'
```

响应：

```json
{"count": 2, "max_model_len": 32768, "tokens": [9707, 1879]}
```

#### 反分词

将 token ID 转回文本：

```bash
curl https://your-http-pub.clorecloud.net/detokenize \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistralai/Mistral-7B-Instruct-v0.2",
    "tokens": [9707, 1879]
  }'
```

响应：

```json
{"prompt": "Hello world"}
```

#### 获取版本

```bash
curl https://your-http-pub.clorecloud.net/version
```

响应：

```json
{"version": "0.7.3"}
```

#### Swagger 文档

在浏览器中打开以查看交互式 API 文档：

```
https://your-http-pub.clorecloud.net/docs
```

#### Prometheus 指标

用于监控：

```bash
curl https://your-http-pub.clorecloud.net/metrics
```

{% hint style="info" %}
**推理模型：** DeepSeek-R1 及类似模型包含 `<think>` 响应中的标签，用于在最终答案之前展示模型的推理过程。
{% endhint %}

## 基准测试

### 吞吐量（每用户 tokens/秒）

| 模型                | RTX 3090 | RTX 4090 | A100 40GB | A100 80GB |
| ----------------- | -------- | -------- | --------- | --------- |
| Mistral 7B        | 100      | 170      | 210       | 230       |
| Llama 3.1 8B      | 95       | 150      | 200       | 220       |
| Llama 3.1 8B（AWQ） | 130      | 190      | 260       | 280       |
| Mixtral 8x7B      | -        | 45       | 70        | 85        |
| Llama 3.1 70B     | -        | -        | 25（2x）    | 45（2x）    |
| DeepSeek-R1 7B    | 90       | 145      | 190       | 210       |
| DeepSeek-R1 32B   | -        | -        | 40        | 70（2x）    |

*基准测试更新于 2026 年 1 月。*

### 上下文长度与 VRAM

| 模型       | 4K 上下文 | 8K 上下文 | 16K 上下文 | 32K 上下文 |
| -------- | ------ | ------ | ------- | ------- |
| 8B FP16  | 18GB   | 22GB   | 30GB    | 46GB    |
| 8B AWQ   | 8GB    | 10GB   | 14GB    | 22GB    |
| 70B FP16 | 145GB  | 160GB  | 190GB   | 250GB   |
| 70B AWQ  | 42GB   | 50GB   | 66GB    | 98GB    |

## Hugging Face 身份验证

适用于受限模型（Llama 等）：

```bash
# 在命令中设置 token
vllm serve meta-llama/Meta-Llama-3.1-8B-Instruct \
    --host 0.0.0.0 \
    --env HUGGING_FACE_HUB_TOKEN=hf_xxxxx
```

或者设置为环境变量：

```bash
export HUGGING_FACE_HUB_TOKEN=hf_xxxxx
```

## GPU 要求

| 模型   | 最低 VRAM | 最低 RAM   | 推荐                 |
| ---- | ------- | -------- | ------------------ |
| 7-8B | 16GB    | **16GB** | 24GB VRAM，32GB RAM |
| 13B  | 26GB    | 32GB     | 40GB VRAM          |
| 34B  | 70GB    | 32GB     | 80GB VRAM          |
| 70B  | 140GB   | 64GB     | 2x80GB             |

## 成本估算

CLORE.AI 市场的典型费率：

| GPU      | 显存   | 价格/天       | 最适合       |
| -------- | ---- | ---------- | --------- |
| RTX 3090 | 24GB | $0.30–1.00 | 7-8B 模型   |
| RTX 4090 | 24GB | $0.50–2.00 | 7-13B，速度快 |
| A100     | 40GB | $1.50–3.00 | 13-34B 模型 |
| A100     | 80GB | $2.00–4.00 | 34-70B 模型 |

*价格为美元/天。费率因提供商而异——请查看* [*CLORE.AI 市场*](https://clore.ai/marketplace) *以获取当前费率。*

## 故障排除

### 长时间 HTTP 502

1. **检查 RAM：** 服务器必须有 16GB+ RAM
2. **检查 VRAM：** 必须能装下该模型
3. **模型下载：** 首次运行会从 HuggingFace 下载（5-15 分钟）
4. **HF Token：** 受限模型需要身份验证

### 内存不足

```bash
# 减少内存使用
--gpu-memory-utilization 0.8
--max-model-len 4096
--max-num-seqs 64

# 或使用量化
--quantization awq
```

### 模型下载失败

```bash
# 检查 HF 令牌
echo $HUGGING_FACE_HUB_TOKEN

# 预先下载模型
huggingface-cli download mistralai/Mistral-7B-Instruct-v0.2
```

## vLLM 与其他方案对比

| 特性       | vLLM     | llama.cpp | Ollama |
| -------- | -------- | --------- | ------ |
| 吞吐量      | 最佳       | 良好        | 良好     |
| VRAM 使用量 | 高        | 低         | 中等     |
| 易用性      | 中等       | 中等        | 容易     |
| 启动时间     | 5-15 分钟  | 1-2 分钟    | 30 秒   |
| 多 GPU    | 原生       | 有限        | 有限     |
| 工具调用     | 是（v0.7+） | 有限        | 有限     |
| 多 LoRA   | 是（v0.7+） | 否         | 否      |

**在以下情况下使用 vLLM：**

* 吞吐量优先
* 为多个用户提供服务
* 有足够的 VRAM 和 RAM
* 生产环境部署
* 需要工具调用 / 结构化输出

**在以下情况下使用 Ollama：**

* 需要快速设置
* 单个用户
* 可用资源较少

## 后续步骤

* [Ollama](/guides/guides_v2-zh/yu-yan-mo-xing/ollama.md) - 更简单的替代方案，启动更快
* [DeepSeek-R1](/guides/guides_v2-zh/yu-yan-mo-xing/deepseek-r1.md) - 推理模型指南
* [DeepSeek-V3](/guides/guides_v2-zh/yu-yan-mo-xing/deepseek-v3.md) - 最佳通用模型
* [Qwen2.5](/guides/guides_v2-zh/yu-yan-mo-xing/qwen25.md) - 多语言模型
* [Llama.cpp](/guides/guides_v2-zh/yu-yan-mo-xing/llamacpp-server.md) - 更低 VRAM 选项


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-zh/yu-yan-mo-xing/vllm.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
