491 lines
13 KiB
Markdown
491 lines
13 KiB
Markdown
# 自定义 vLLM 容器
|
||
|
||
这是一个基于 Fedora 的 Docker/Podman 容器,专为在 AMD Radeon R9700 (gfx1201) GPU 上运行 vLLM 而设计。
|
||
|
||
## 特性
|
||
|
||
- 基于 Fedora 43
|
||
- 使用最新的 TheRock ROCm 7.x SDK
|
||
- 包含 PyTorch 预发布版本(ROCm 支持)
|
||
- 内置 Flash-Attention(ROCm 版本)
|
||
- 支持多种大型语言模型
|
||
- 基于配置文件的启动方式
|
||
- 仅支持本地模型(无网络下载功能)
|
||
- 多模型配置支持
|
||
- **提供标准的 OpenAI API 服务**
|
||
- **智能部署(自动检测 Git 更新)**
|
||
|
||
## 快速开始
|
||
|
||
### 1. 构建并运行(推荐)
|
||
|
||
```bash
|
||
# 赋予脚本执行权限
|
||
chmod +x build_and_run.sh
|
||
|
||
# 一键构建并运行
|
||
./build_and_run.sh
|
||
```
|
||
|
||
### 2. 手动构建和运行
|
||
|
||
```bash
|
||
# 构建镜像
|
||
docker build -t custom-vllm-r9700:latest .
|
||
|
||
# 运行容器
|
||
docker run -it --device /dev/dri --device /dev/kfd \
|
||
--group-add video --group-add render --security-opt seccomp=unconfined \
|
||
-v /opt/models:/models \
|
||
-v /opt/model_config.yaml:/etc/vllm/model_config.yaml \
|
||
-e LOCAL_MODEL_DIR=/models \
|
||
custom-vllm-r9700:latest
|
||
```
|
||
|
||
## 构建容器
|
||
|
||
在项目目录中运行:
|
||
|
||
```bash
|
||
docker build -t custom-vllm-r9700:latest .
|
||
```
|
||
|
||
## 使用方法
|
||
|
||
### 使用 Docker/Podman
|
||
|
||
```bash
|
||
docker run -it --device /dev/dri --device /dev/kfd \
|
||
--group-add video --group-add render --security-opt seccomp=unconfined \
|
||
-v /opt/models:/models \
|
||
-v /opt/model_config.yaml:/etc/vllm/model_config.yaml \
|
||
-e LOCAL_MODEL_DIR=/models \
|
||
custom-vllm-r9700:latest
|
||
```
|
||
|
||
### 使用 Toolbx(Fedora)
|
||
|
||
```bash
|
||
toolbox create vllm-custom \
|
||
--image custom-vllm-r9700:latest \
|
||
-- --device /dev/dri --device /dev/kfd \
|
||
--group-add video --group-add render --security-opt seccomp=unconfined
|
||
|
||
toolbox enter vllm-custom
|
||
```
|
||
|
||
### 使用 Distrobox(Ubuntu)
|
||
|
||
```bash
|
||
distrobox create -n vllm-custom \
|
||
--image custom-vllm-r9700:latest \
|
||
--additional-flags "--device /dev/kfd --device /dev/dri --group-add video --group-add render --security-opt seccomp=unconfined"
|
||
|
||
distrobox enter vllm-custom
|
||
```
|
||
|
||
## 配置文件
|
||
|
||
容器使用 YAML 格式的配置文件来设置 vLLM 服务器参数。配置文件需要挂载到 `/etc/vllm/model_config.yaml`。项目根目录中提供了配置文件示例 `model_config.yaml.example`,您可以参考它来创建自己的配置文件。
|
||
|
||
### 配置文件示例
|
||
|
||
```yaml
|
||
# model_config.yaml - 多模型配置示例
|
||
# 默认启动的模型
|
||
default: "deepseek_r1_distill_qwen_32b_awq"
|
||
|
||
# 模型配置
|
||
models:
|
||
deepseek_r1_distill_qwen_14b:
|
||
path: "/models/DeepSeek-R1-Distill-Qwen-14B"
|
||
name: "DeepSeek-R1-Distill-Qwen-14B"
|
||
max_model_len: 8192
|
||
gpu_memory_utilization: 0.9
|
||
port: 2001
|
||
dtype: "float16"
|
||
quantization: "awq"
|
||
tensor_parallel_size: 1
|
||
enforce_eager: true
|
||
api_key: "sk-14b-20240101-abcdef123456"
|
||
|
||
deepseek_r1_distill_qwen_32b_awq:
|
||
path: "/models/DeepSeek-R1-Distill-Qwen-32B-AWQ"
|
||
name: "DeepSeek-R1-Distill-Qwen-32B-AWQ"
|
||
|
||
# 模型性能参数
|
||
max_model_len: 32768
|
||
gpu_memory_utilization: 0.95
|
||
enforce_eager: true
|
||
max_num_seqs: 2
|
||
max_num_batched_tokens: 1024
|
||
block_size: 16
|
||
tensor_parallel_size: 1
|
||
swap_space: 0
|
||
|
||
# 新增:采样参数默认值
|
||
sampling_defaults:
|
||
temperature: 0.6
|
||
max_tokens: 4096
|
||
top_p: 0.9
|
||
frequency_penalty: 0.0
|
||
presence_penalty: 0.0
|
||
stop:
|
||
- "用户:"
|
||
- "助手:"
|
||
- "###"
|
||
- "问题:"
|
||
- "回答:"
|
||
|
||
# 其他配置
|
||
dtype: "auto"
|
||
quantization: "awq"
|
||
port: 2001
|
||
api_key: "sk-32b-20240101-ghijk789012"
|
||
|
||
glm_4_7_flash_awq:
|
||
path: "/models/GLM-4.7-Flash-AWQ"
|
||
name: "GLM-4.7-Flash-AWQ"
|
||
|
||
# 模型性能参数
|
||
max_model_len: 32768
|
||
gpu_memory_utilization: 0.9
|
||
enforce_eager: false
|
||
max_num_seqs: 2
|
||
max_num_batched_tokens: 1024
|
||
block_size: 16
|
||
tensor_parallel_size: 1
|
||
swap_space: 0
|
||
|
||
# 新增:采样参数默认值
|
||
sampling_defaults:
|
||
temperature: 0.6
|
||
max_tokens: 4096
|
||
top_p: 0.9
|
||
frequency_penalty: 0.0
|
||
presence_penalty: 0.0
|
||
stop:
|
||
- "用户:"
|
||
- "助手:"
|
||
- "###"
|
||
- "问题:"
|
||
- "回答:"
|
||
|
||
# 其他配置
|
||
dtype: "auto"
|
||
quantization: "awq"
|
||
port: 2001
|
||
api_key: "sk-32b-20240101-ghijk789012"
|
||
|
||
qwen3_vl_32b_instruct_awq:
|
||
path: "/models/Qwen3-VL-32B-Instruct-AWQ"
|
||
name: "Qwen3-VL-32B-Instruct-AWQ"
|
||
max_model_len: 32768
|
||
gpu_memory_utilization: 0.7
|
||
port: 2001
|
||
dtype: "auto"
|
||
quantization: "awq"
|
||
tensor_parallel_size: 1
|
||
enforce_eager: true
|
||
api_key: "sk-glm-20240101-lmnop345678"
|
||
|
||
# 服务器通用设置
|
||
server:
|
||
host: "0.0.0.0"
|
||
log_level: "info"
|
||
# 全局管理员密钥(拥有所有模型的访问权限)
|
||
admin_key: "sk-admin-20240101-xyz789"
|
||
# 允许的请求头名称(支持多个,按顺序检查)
|
||
api_key_headers: ["Authorization", "X-API-Key", "api-key"]
|
||
# 是否允许通过查询参数传递密钥
|
||
allow_query_param: true
|
||
# 查询参数名称
|
||
api_key_param: "api_key"
|
||
```
|
||
|
||
### 配置参数说明
|
||
|
||
- `default`:默认启动的模型名称
|
||
- `models`:模型配置列表
|
||
- 每个模型包含:
|
||
- `path`:模型路径(相对于 LOCAL_MODEL_DIR)
|
||
- `name`:模型名称
|
||
- `max_model_len`:最大模型上下文长度
|
||
- `gpu_memory_utilization`:GPU 内存利用率
|
||
- `port`:服务器端口
|
||
- `dtype`:数据类型
|
||
- `quantization`:量化方式
|
||
- `tensor_parallel_size`:张量并行度
|
||
- `enforce_eager`:是否强制使用 eager 模式
|
||
- `max_num_seqs`:最大并发请求数
|
||
- `max_num_batched_tokens`:最大批量 tokens 数
|
||
- `block_size`:块大小
|
||
- `swap_space`:交换空间大小
|
||
- `sampling_defaults`:采样参数默认值
|
||
- `api_key`:API 密钥(用于 OpenAI 兼容模式)
|
||
- `server`:服务器通用设置
|
||
- `host`:服务器主机地址
|
||
- `log_level`:日志级别
|
||
- `admin_key`:全局管理员密钥
|
||
- `api_key_headers`:允许的请求头名称
|
||
- `allow_query_param`:是否允许通过查询参数传递密钥
|
||
- `api_key_param`:查询参数名称
|
||
|
||
## 环境变量
|
||
|
||
- `LOCAL_MODEL_DIR`:本地模型目录路径(必须设置,默认:/models)
|
||
- `VLLM_CONFIG_FILE`:配置文件路径(默认:/etc/vllm/model_config.yaml)
|
||
|
||
## 启动 vLLM 服务器
|
||
|
||
### 使用智能部署脚本(推荐)
|
||
|
||
项目提供了 `build_and_run.sh` 脚本,具有智能检测和自动部署功能:
|
||
|
||
**智能部署逻辑:**
|
||
|
||
1. **检测 Git 代码更新**:
|
||
- 自动拉取远程仓库最新代码
|
||
- 比较本地和远程代码版本
|
||
- 检测本地未提交的更改
|
||
|
||
2. **智能构建决策**:
|
||
- ✅ 代码有更新 → 重新构建镜像
|
||
- ✅ 本地有更改 → 重新构建镜像
|
||
- ✅ 镜像不存在 → 构建镜像
|
||
- ⏭️ 代码无更新且镜像存在 → 跳过构建,直接部署
|
||
|
||
3. **自动部署**:
|
||
- 停止并删除旧容器
|
||
- 使用新镜像(或现有镜像)启动新容器
|
||
|
||
```bash
|
||
# 赋予执行权限
|
||
chmod +x build_and_run.sh
|
||
|
||
# 智能部署(自动检测 Git 更新)
|
||
./build_and_run.sh
|
||
|
||
# 强制重新构建(忽略 Git 状态)
|
||
./build_and_run.sh -f
|
||
|
||
# 仅停止并删除容器
|
||
./build_and_run.sh -s
|
||
|
||
# 指定端口运行
|
||
./build_and_run.sh -p 8080
|
||
|
||
# 指定配置文件和模型目录
|
||
./build_and_run.sh -c /opt/model_config.yaml -m /opt/models
|
||
|
||
# 交互式运行(前台运行)
|
||
./build_and_run.sh -i
|
||
|
||
# 指定 Git 分支
|
||
./build_and_run.sh -b master
|
||
```
|
||
|
||
**脚本选项:**
|
||
|
||
- `-f, --force`:强制重新构建镜像(忽略 Git 状态)
|
||
- `-s, --stop`:仅停止并删除容器
|
||
- `-d, --detach`:后台运行容器(默认)
|
||
- `-i, --interactive`:交互式运行容器
|
||
- `-c, --config FILE`:指定配置文件路径
|
||
- `-m, --models DIR`:指定模型目录路径
|
||
- `-p, --port PORT`:指定服务端口
|
||
- `-b, --branch NAME`:指定 Git 分支(默认:main)
|
||
- `-h, --help`:显示帮助信息
|
||
|
||
**使用场景:**
|
||
|
||
- **首次部署**:直接运行 `./build_and_run.sh`,自动构建并部署
|
||
- **日常更新**:运行 `./build_and_run.sh`,自动检测代码更新并重新部署
|
||
- **快速重启**:代码无更新时,跳过构建,直接重启容器
|
||
- **强制更新**:使用 `-f` 参数强制重新构建
|
||
|
||
### 手动部署
|
||
|
||
```bash
|
||
# 1. 构建镜像
|
||
docker build -t custom-vllm-r9700:latest .
|
||
|
||
# 2. 运行容器
|
||
docker run -it --device /dev/dri --device /dev/kfd \
|
||
--group-add video --group-add render --security-opt seccomp=unconfined \
|
||
-v /opt/models:/models \
|
||
-v /opt/model_config.yaml:/etc/vllm/model_config.yaml \
|
||
-e LOCAL_MODEL_DIR=/models \
|
||
custom-vllm-r9700:latest
|
||
```
|
||
|
||
### 容器内运行
|
||
|
||
进入容器后,可以使用以下命令启动 vLLM 服务器:
|
||
|
||
```bash
|
||
# 使用默认模型启动
|
||
start-vllm
|
||
|
||
# 或指定模型名称启动
|
||
start-vllm deepseek_r1_distill_qwen_14b
|
||
|
||
# 或直接指定模型路径
|
||
vllm serve /models/model-name --tensor-parallel-size 2 --max-model-len 128000
|
||
```
|
||
|
||
## 测试 API(OpenAI 兼容)
|
||
|
||
vLLM 提供与 OpenAI API 完全兼容的服务接口。
|
||
|
||
### 1. 使用 curl 测试
|
||
|
||
```bash
|
||
# 聊天补全接口
|
||
curl -X POST http://localhost:8000/v1/chat/completions \
|
||
-H "Content-Type: application/json" \
|
||
-H "Authorization: Bearer sk-32b-20240101-ghijk789012" \
|
||
-d '{
|
||
"model": "deepseek_r1_distill_qwen_32b_awq",
|
||
"messages": [
|
||
{"role": "user", "content": "你好,请介绍一下你自己"}
|
||
],
|
||
"temperature": 0.6,
|
||
"max_tokens": 4096,
|
||
"top_p": 0.9
|
||
}'
|
||
|
||
# 文本补全接口
|
||
curl -X POST http://localhost:8000/v1/completions \
|
||
-H "Content-Type: application/json" \
|
||
-H "Authorization: Bearer sk-32b-20240101-ghijk789012" \
|
||
-d '{
|
||
"model": "deepseek_r1_distill_qwen_32b_awq",
|
||
"prompt": "Once upon a time",
|
||
"max_tokens": 100
|
||
}'
|
||
|
||
# 列出可用模型
|
||
curl http://localhost:8000/v1/models \
|
||
-H "Authorization: Bearer sk-32b-20240101-ghijk789012"
|
||
```
|
||
|
||
### 2. 使用 Python OpenAI SDK
|
||
|
||
```python
|
||
from openai import OpenAI
|
||
|
||
# 初始化客户端
|
||
client = OpenAI(
|
||
base_url="http://localhost:8000/v1",
|
||
api_key="sk-32b-20240101-ghijk789012"
|
||
)
|
||
|
||
# 聊天补全
|
||
response = client.chat.completions.create(
|
||
model="deepseek_r1_distill_qwen_32b_awq",
|
||
messages=[
|
||
{"role": "user", "content": "你好,请介绍一下你自己"}
|
||
],
|
||
temperature=0.6,
|
||
max_tokens=4096
|
||
)
|
||
|
||
print(response.choices[0].message.content)
|
||
|
||
# 文本补全
|
||
response = client.completions.create(
|
||
model="deepseek_r1_distill_qwen_32b_awq",
|
||
prompt="Once upon a time",
|
||
max_tokens=100
|
||
)
|
||
|
||
print(response.choices[0].text)
|
||
```
|
||
|
||
### 3. 使用其他 OpenAI 兼容工具
|
||
|
||
由于提供标准的 OpenAI API,您可以使用任何支持 OpenAI 的工具和库,例如:
|
||
|
||
- LangChain
|
||
- LlamaIndex
|
||
- AutoGen
|
||
- FastChat
|
||
- 等等
|
||
|
||
只需将 `base_url` 设置为 `http://localhost:8000/v1`,并使用配置的 API 密钥即可。
|
||
|
||
## 本地模型目录结构
|
||
|
||
确保本地模型目录包含以下文件之一:
|
||
- `config.json`
|
||
- `pytorch_model.bin`
|
||
- `model.safetensors`
|
||
|
||
正确的目录结构示例:
|
||
|
||
```
|
||
/opt/models/
|
||
├── deepseek_r1_distill_qwen_14b/
|
||
│ ├── config.json
|
||
│ └── model.safetensors
|
||
├── deepseek_r1_distill_qwen_32b_awq/
|
||
│ ├── config.json
|
||
│ └── pytorch_model.bin
|
||
├── glm_4_7_flash_awq/
|
||
│ ├── config.json
|
||
│ └── model.safetensors
|
||
└── qwen3_vl_32b_instruct_awq/
|
||
├── config.json
|
||
└── pytorch_model.bin
|
||
```
|
||
|
||
## 注意事项
|
||
|
||
- 确保您的 AMD Radeon R9700 GPU 驱动已正确安装
|
||
- 容器需要访问 GPU 设备,因此运行时需要添加 `--device /dev/dri --device /dev/kfd` 参数
|
||
- 首次启动时,vLLM 会编译计算图,可能需要较长时间
|
||
- 如果遇到内存不足的问题,可以调整 `gpu_memory_utilization` 参数
|
||
- API 密钥在配置文件的每个模型中单独配置,用于 OpenAI 兼容模式的认证
|
||
|
||
## OpenAI API 兼容性
|
||
|
||
本容器提供的服务完全兼容 OpenAI API 标准,包括:
|
||
|
||
- **聊天补全**:`/v1/chat/completions`
|
||
- **文本补全**:`/v1/completions`
|
||
- **模型列表**:`/v1/models`
|
||
- **嵌入**:`/v1/embeddings`(如支持)
|
||
|
||
所有端点都支持标准的 OpenAI 请求格式和参数,您可以无缝切换使用。
|
||
|
||
## 项目文件说明
|
||
|
||
- `Dockerfile` - Docker 镜像构建文件
|
||
- `README.md` - 项目说明文档
|
||
- `model_config.yaml.example` - 配置文件示例(包含所有模型配置参数)
|
||
- `build_and_run.sh` - 智能部署脚本(自动检测 Git 更新)
|
||
- `scripts/` - 脚本目录
|
||
- `start_vllm.py` - vLLM 启动脚本
|
||
- `01-rocm-envs.sh` - ROCm 环境配置
|
||
- `99-toolbox-banner.sh` - Toolbox 横幅
|
||
- `zz-venv-last.sh` - 虚拟环境配置
|
||
|
||
## 部署说明
|
||
|
||
### Docker 运行命令
|
||
|
||
```bash
|
||
docker run -it --device /dev/dri --device /dev/kfd \
|
||
--group-add video --group-add render --security-opt seccomp=unconfined \
|
||
-v /opt/models:/models \
|
||
-v /opt/model_config.yaml:/etc/vllm/model_config.yaml \
|
||
-e LOCAL_MODEL_DIR=/models \
|
||
custom-vllm-r9700:latest
|
||
```
|
||
|
||
**挂载说明:**
|
||
- `/opt/models` - 本地模型目录,挂载到容器的 `/models`
|
||
- `/opt/model_config.yaml` - 本地配置文件,挂载到容器的 `/etc/vllm/model_config.yaml`
|
||
- `LOCAL_MODEL_DIR=/models` - 指定模型目录环境变量
|