Skip to content

vLLM + AMD GPU vGPU 部署与运维手册

GPU: AMD Radeon RX 7900 XTX (24GB VRAM, gfx1100) 节点: szb122009 (192.168.122.9) 框架: vLLM v0.6.6 + ROCm 6.3.2 + Open WebUI v0.11.0 集群: RKE2 (Kubernetes) 基础镜像: ROCm 6.3.2 + PyTorch 2.4.0 + Ubuntu 24.04 最后更新: 2026-08-18


目录


一、架构概览

用户浏览器

    ▼ https://ai.ai-ear.cn (DNS → 8.153.84.140)
┌──────────────────────────────────────────┐
│  公网服务器 (8.153.84.140)                │
│  Traefik (:443 TLS)                      │
│  dynamic.yaml → ai-open-webui router     │
│  → svc-18080 → 127.0.0.1:18080           │
└──────────────────┬───────────────────────┘
                   │ frp tunnel (remotePort 18080)

┌──────────────────────────────────────────────────────────────────┐
│  szb122009 (192.168.122.9)                                       │
│  frps (:7000) ← frpc : open-webui-18080                          │
│                                                                  │
│  hostPath 挂载:                                                  │
│  /opt/models/huggingface/  ──► /models/huggingface/ (容器内)     │
│    ├── deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B/  (1.5B, 3GB)  │
│    ├── Qwen/Qwen2.5-3B-Instruct/                   (3B,   6GB)  │
│    └── Qwen/Qwen2.5-7B-Instruct/                   (7B,  14GB)  │
│  /opt/open-webui/           ──► /app/backend/data/ (容器内)      │
│  /dev/dri, /dev/kfd         ──► GPU 设备直通                      │
│                                                                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ vLLM Pod     │  │ vLLM Pod     │  │ Open WebUI   │          │
│  │ DeepSeek-R1  │  │ Qwen2.5-3B   │  │ (Frontend)   │          │
│  │ ~3GB VRAM    │  │ ~6GB VRAM    │  │ CPU only     │          │
│  │ (replicas=0) │  │ (replicas=0) │  │ NodePort     │          │
│  └──────────────┘  └──────────────┘  │ :30080       │          │
│                                      └──────┬───────┘          │
│  ┌──────────────┐                           │                    │
│  │ vLLM Pod     │  ← 默认启动 (推荐)        │                    │
│  │ Qwen2.5-7B   │                           │                    │
│  │ ~14GB VRAM   │                           │                    │
│  │ (replicas=1) │                           │                    │
│  └──────┬───────┘                           │                    │
│         │                                   │                    │
│  ┌──────▼───────────────────────────────────▼──┐                │
│  │         AMD RX 7900 XTX 24GB (gfx1100)      │                │
│  └─────────────────────────────────────────────┘                │
└──────────────────────────────────────────────────────────────────┘

关键设计: 同一时间只启动一个 vLLM 模型 Pod,通过 deploy.sh switch 命令切换。 三个模型共享同一张 GPU,但不同时运行,避免显存不足。 默认推荐 Qwen2.5-7B (中文能力强、推理/编码/对话均衡、24GB 显存充足)。

存储方案 (hostPath)

宿主机路径容器挂载路径用途
/opt/models/huggingface//models/huggingface/HuggingFace 模型文件
/opt/open-webui//app/backend/data/Open WebUI 持久化数据 (含 SQLite DB)
/dev/dri/dev/driAMD DRI 渲染节点
/dev/kfd/dev/kfdAMD KFD 计算节点

镜像信息

镜像Harbor 地址说明
ROCm + PyTorch 基础镜像192.168.122.156:30000/rocm/pytorch:rocm6.3.2_ubuntu24.04_py3.12_pytorch_release_2.4.0~71.5 GB
vLLM 应用镜像192.168.122.156:30000/cnrancher/vllm-rocm:v0.6.6源码编译
Open WebUI192.168.122.156:30000/cnrancher/open-webui:main官方镜像转推

vLLM 启动参数一览 (Qwen2.5-7B, 默认模型)

参数当前值说明
--model/models/huggingface/Qwen/Qwen2.5-7B-Instruct模型本地路径
--served-model-nameqwen2.5-7bAPI 中暴露的模型名
--gpu-memory-utilization0.90GPU 显存利用率上限 (90%, 单模型独占)
--max-model-len16384最大上下文 token 数 (7B 可用 16K)
--dtypefloat16数据类型
--enforce-eager(flag)禁用 CUDA/HIP Graph,兼容 ROCm
--enable-auto-tool-choice(flag)支持 Open WebUI 的 tool_choice="auto"
--tool-call-parserhermesTool calling 解析器
--disable-frontend-multiprocessing(flag)绕过 ROCm IPC 序列化问题

环境变量一览

变量名说明
HSA_OVERRIDE_GFX_VERSION11.0.0RX 7900 XTX 实际是 gfx1100,需伪装以兼容 ROCm
VLLM_TARGET_DEVICErocm告知 vLLM 使用 ROCm 后端
PYTORCH_ROCM_ARCHgfx1100PyTorch ROCm 架构标识
HF_HOME/models/huggingfaceHuggingFace 缓存目录
HF_HUB_OFFLINE1离线模式,禁止下载
TRANSFORMERS_OFFLINE1Transformers 离线模式
VLLM_USE_TRITON_FLASH_ATTN0禁用 Triton Flash Attention (ROCm 不兼容)

二、部署文件清单

vllm-deploy/
├── Dockerfile              # vLLM + ROCm 镜像构建文件 (基于 ROCm 6.3.2, 源码编译)
├── build-and-push.sh       # 构建 vLLM 应用镜像并推送 (含源码编译步骤)
├── tag-and-push.sh         # 基础镜像打标签并推送到 Harbor
├── deploy.sh               # 一键部署脚本 (注册 vGPU + 部署全部服务, 默认启动 qwen7b)
├── vllm-deepseek.yaml      # DeepSeek-R1-1.5B vLLM Deployment + Service (replicas=0)
├── vllm-qwen.yaml          # Qwen2.5-3B vLLM Deployment + Service (replicas=0)
├── vllm-qwen7b.yaml        # Qwen2.5-7B vLLM Deployment + Service (replicas=1, 默认)
├── open-webui.yaml         # Open WebUI 前端 Deployment + Service
└── README.md               # 本文档 (部署与运维手册)

三、运行时补丁详解 (Runtime Patches)

vLLM v0.6.6 在 ROCm + AMD RX 7900 XTX (gfx1100) 环境下存在多个兼容性问题。 我们通过容器启动时的运行时补丁来解决,无需重新构建镜像。

Patch 0: torch._inductor.config 兼容性修复

文件: /opt/vllm/vllm/plugins/__init__.py

问题: vLLM 启动时直接访问 torch._inductor.config.compile_threads,但 ROCm 版本的 PyTorch 没有 _inductor 模块,导致 AttributeError: module 'torch' has no attribute '_inductor'

修复 (sed 命令):

bash
sed -i "s/torch._inductor.config.compile_threads = 1/\
if hasattr(torch._inductor, 'config'): torch._inductor.config.compile_threads = 1/" \
  /opt/vllm/vllm/plugins/__init__.py

原理: 添加 hasattr 保护检查,仅在 _inductor 模块存在时才设置参数。


Patch 1: all_special_tokens_extended 孤立装饰器 Bug ⭐ (最关键)

文件: /opt/vllm/vllm/transformers_utils/tokenizer.py

问题: vLLM 的 tokenizer.py 中有一个 all_special_tokens_extended 属性方法,它调用了 tokenizer_all_special_tokens_extended() 函数。在 ROCm 环境下,某些 transformers 版本的 tokenizer 对象没有这个属性,导致 AttributeError

最初的修复尝试 (有 Bug):

python
# 只注释掉了 def 行,没有处理 @property 装饰器
@property                                ← 这个装饰器变成"孤儿"
# def all_special_tokens_extended(self): ← 已注释
#     return ...                         ← 已注释
def max_token_id(self):                  ← @property 附着到了这里!
    ...

Bug 后果: @property 装饰器附着到了下一个方法 max_token_id 上,使 max_token_id 变成了一个 property 对象而不是可调用的方法。推理时报错:

TypeError: 'property' object is not callable

正确修复 (当前方案):

python
# 同时注释掉 @property 装饰器和 def 及其函数体
for each line in source:
    if 'all_special_tokens_extended' in line:
        # 检查前一行是否是 @property,如果是则也注释掉
        if new_lines[-1].strip() == '@property':
            new_lines[-1] = '# PATCHED: ' + new_lines[-1]
        new_lines.append('# PATCHED: ' + line)
        # 跳过函数体 (缩进的后续行)
        while next_line is indented body:
            new_lines.append('# PATCHED: ' + next_line)

教训: 修改 Python 装饰器相关代码时,必须同时处理装饰器和被装饰的函数,不能只注释其中一部分。


Patch 2: multiprocessing client IPC 序列化错误

文件: /opt/vllm/vllm/engine/multiprocessing/client.py

问题: vLLM 的前端多进程客户端使用 IPC (Inter-Process Communication) 传输请求输出。 在 ROCm 环境下,某些异常对象无法正确序列化/反序列化,导致 raise request_output 时出现 TypeError

修复:

python
# 原始代码:
if isinstance(request_output, BaseException):
    raise request_output

# 修复后:
if isinstance(request_output, BaseException):
    try:
        raise request_output
    except TypeError:
        raise RuntimeError(
            f"Engine error: {type(request_output).__name__}: {request_output}"
        ) from None

最终方案: 由于 --disable-frontend-multiprocessing 彻底禁用了多进程前端,此 Patch 作为额外保险保留。


Patch 3 (启动参数): --disable-frontend-multiprocessing

问题: vLLM 默认使用多进程架构 (frontend + engine worker),通过 IPC 管道通信。 ROCm 的 tensor 序列化与 CUDA 不同,IPC 管道传输 tensor 时会失败。

修复: 添加 --disable-frontend-multiprocessing 启动参数,强制 vLLM 使用单进程模式。

副作用: 前端请求处理和推理引擎在同一进程中运行,高并发时可能略有延迟, 但对于单用户/小团队场景完全可接受。


Patch 4 (启动参数): --enable-auto-tool-choice + --tool-call-parser hermes

问题: Open WebUI 默认在请求中发送 "tool_choice": "auto"。如果 vLLM 未启用 tool calling 支持,会返回 400 错误:

"auto" tool choice requires --enable-auto-tool-choice and --tool-call-parser to be set

修复: 添加 --enable-auto-tool-choice --tool-call-parser hermes。 Qwen 系列模型使用 Hermes 格式的 tool calling。


四、排查思路与操作步骤

4.1 排查时间线

阶段问题排查方法解决
1Pod CrashLoopBackOffkubectl logs 查看 vLLM 启动日志Patch 0: torch._inductor.config
2推理请求 500curl 直接调用 API + 查看 tracebackPatch 1: all_special_tokens_extended
3TypeError: 'property' object is not callable分析 Python 装饰器机制Patch 1 修正: 同时注释 @property
4IPC serialization error日志中 TypeErrorclient.pyPatch 2 + --disable-frontend-multiprocessing
5Open WebUI 400 Bad RequestOpen WebUI 日志 tool_choice 报错Patch 4: --enable-auto-tool-choice
6Open WebUI 连接 vllm-deepseek 失败检查 DB 中的 URL 配置清理 SQLite 中的残留 URL
7上下文长度超限错误提示 maximum context length is 4096增大 --max-model-len 到 8192

4.2 排查命令速查

bash
# 通用 kubectl 前缀 (在 192.168.122.37 上执行)
KUBECTL="/var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml"

# 查看 Pod 状态
$KUBECTL get pods -o wide

# 查看 vLLM 日志 (最近 50 行)
$KUBECTL logs deployment/vllm-qwen7b --tail=50

# 查看 vLLM 错误日志
$KUBECTL logs deployment/vllm-qwen7b --tail=100 | grep -i "error\|traceback\|exception"

# 查看 Open WebUI 日志
$KUBECTL logs deployment/open-webui --tail=50

# 过滤 Open WebUI 中的错误
$KUBECTL logs deployment/open-webui --tail=100 | grep -i "error\|500\|400\|TypeError"

# 实时跟踪日志
$KUBECTL logs -f deployment/vllm-qwen7b

# 进入 Pod 调试
$KUBECTL exec -it deployment/vllm-qwen7b -- bash

# 从 Open WebUI Pod 内部测试 vLLM API
$KUBECTL exec deployment/open-webui -- \
  curl -s http://vllm-qwen7b:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "qwen2.5-7b", "messages": [{"role": "user", "content": "1+1=?"}], "max_tokens": 20}'

# 检查 GPU 显存使用
$KUBECTL exec deployment/vllm-qwen7b -- \
  cat /sys/class/drm/card1/device/mem_info_vram_used

4.3 Open WebUI 数据库配置修复

场景: 切换模型后,Open WebUI 仍然尝试连接旧的 vLLM URL。

原因: Open WebUI 首次启动时将环境变量写入 SQLite 数据库,之后使用数据库配置。 kubectl set env 只更新环境变量,不更新数据库。

修复脚本 (通过 kubectl exec 在 Pod 内执行):

python
import sqlite3

conn = sqlite3.connect("/app/backend/data/webui.db")
c = conn.cursor()

# 只保留当前模型的 URL (示例: 切换到 qwen)
c.execute("UPDATE config SET value = ? WHERE key = ?",
    ('["http://vllm-qwen7b:8000/v1"]', 'openai.api_base_urls'))
c.execute("UPDATE config SET value = ? WHERE key = ?",
    ('["dummy"]', 'openai.api_keys'))
c.execute("UPDATE config SET value = ? WHERE key = ?",
    ('{"0": {"enable": true}}', 'openai.api_configs'))

conn.commit()
c.execute("SELECT key, value FROM config WHERE key LIKE 'openai%'")
for row in c.fetchall():
    print(row)
conn.close()

提示: 修复数据库后需要重启 Open WebUI: $KUBECTL rollout restart deployment/open-webui

4.4 vGPU 资源重新注册

kubelet 重启后,手动 patch 的 amd.com/gpu 资源会丢失,Pod 会因资源不足而 Pending。

bash
$KUBECTL patch node szb122009 --type=merge --subresource=status \
  -p '{"status":{"capacity":{"amd.com/gpu":"4"},"allocatable":{"amd.com/gpu":"4"}}}'

验证:

bash
$KUBECTL get node szb122009 -o jsonpath='{.status.allocatable}' | python3 -m json.tool
# 应看到 "amd.com/gpu": "4"

五、操作脚本说明

5.1 deploy.sh — 一键部署脚本

用法:

bash
# 首次部署 (默认启动 qwen7b)
./deploy.sh

# 切换到 qwen7b 模型 (推荐,日常最佳)
./deploy.sh switch qwen7b

# 切换到 qwen 模型 (轻量级)
./deploy.sh switch qwen

# 切换到 deepseek 模型 (推理)
./deploy.sh switch deepseek

执行流程:

  1. 注册 vGPU 资源 (amd.com/gpu: 4)
  2. 验证节点资源
  3. 部署 vLLM DeepSeek (replicas=0, 不启动)
  4. 部署 vLLM Qwen 3B (replicas=0, 不启动)
  5. 部署 vLLM Qwen 7B (replicas=1, 默认启动)
  6. 部署 Open WebUI
  7. 等待 Deployment 就绪

切换模型流程 (deploy.sh switch):

  1. 将当前模型 Pod 缩容到 0 (释放 GPU)
  2. 将目标模型 Pod 扩容到 1 (占用 GPU)
  3. 更新 Open WebUI 环境变量指向新模型

5.2 build-and-push.sh — 镜像构建脚本

用途: 从源码编译 vLLM 并构建 Docker 镜像,推送到 Harbor。

前提:

  • 基础镜像已推送到 Harbor (ROCm 6.3.2 + PyTorch 2.4.0)
  • 当前机器已安装 Docker 且能访问 Harbor
  • 网络可访问 Gitee (用于 clone vLLM 源码)

执行流程:

  1. 检查基础镜像是否存在
  2. 启动构建容器 (特权模式 + GPU 直通)
  3. 安装构建依赖 (ccache, git-lfs)
  4. 克隆 vLLM v0.6.6 源码
  5. 源码编译 vLLM (ROCm gfx1100) — 约 10-30 分钟
  6. 创建 entrypoint 脚本
  7. 验证 vLLM 安装
  8. Commit 镜像并推送到 Harbor

5.3 tag-and-push.sh — 基础镜像标签推送

用途: 将华为云镜像源的 ROCm PyTorch 基础镜像打标签并推送到 Harbor。


六、后期维护手册

6.1 日常巡检清单

检查项命令预期结果
Pod 状态$KUBECTL get pods -o wide所有 Pod 1/1 Running
vLLM 健康检查$KUBECTL exec deployment/vllm-qwen7b -- curl -s http://localhost:8000/health返回 200
vLLM API 测试$KUBECTL exec deployment/open-webui -- curl -s http://vllm-qwen7b:8000/v1/models返回模型列表
GPU 显存使用$KUBECTL exec deployment/vllm-qwen7b -- cat /sys/class/drm/card1/device/mem_info_vram_used< 22 GB
磁盘空间ssh root@192.168.122.9 'df -h /opt'使用率 < 80%
Open WebUI 日志$KUBECTL logs deployment/open-webui --tail=20 | grep -i error无严重错误
vLLM 日志$KUBECTL logs deployment/vllm-qwen7b --tail=20 | grep -i error无严重错误

6.2 模型切换操作

bash
# 切换到 Qwen2.5-7B (推荐,日常最佳)
./deploy.sh switch qwen7b

# 切换到 Qwen2.5-3B (轻量级)
./deploy.sh switch qwen

# 切换到 DeepSeek-R1 (推理模型)
./deploy.sh switch deepseek

# 注意: 切换后还需更新 Open WebUI 数据库 (如果 kubectl set env 未生效)
# 见 4.3 节 "Open WebUI 数据库配置修复"

6.3 添加新模型

步骤:

  1. 下载模型到节点 /opt/models/huggingface/ 目录
  2. 复制 vllm-qwen.yaml 为新模型创建 YAML
  3. 修改以下字段:
    • metadata.name: 新模型标识 (如 vllm-llama)
    • spec.selector.matchLabels.model: 对应标签
    • containers.command 中的 --model 路径
    • --served-model-name: API 中暴露的名称
  4. deploy.shswitch_model 函数中添加新 case
  5. kubectl apply -f 部署新模型 (replicas=0)

示例 — 添加 Llama 3:

yaml
# vllm-llama.yaml (关键字段)
metadata:
  name: vllm-llama
spec:
  replicas: 0  # 默认不启动
  selector:
    matchLabels:
      app: vllm
      model: llama
  template:
    spec:
      containers:
      - name: vllm
        command:
        - bash
        - -c
        - |
          # ... (同 qwen 的 patches) ...
          exec python3 -m vllm.entrypoints.openai.api_server \
            --model /models/huggingface/meta-llama/Llama-3-8B-Instruct \
            --served-model-name llama-3 \
            --host 0.0.0.0 --port 8000 \
            --gpu-memory-utilization 0.45 \
            --max-model-len 8192 \
            --dtype float16 \
            --enforce-eager \
            --enable-auto-tool-choice \
            --tool-call-parser hermes \
            --disable-frontend-multiprocessing

6.4 Open WebUI 升级

bash
# 拉取新版本
docker pull ghcr.io/open-webui/open-webui:main
docker tag ghcr.io/open-webui/open-webui:main 192.168.122.156:30000/cnrancher/open-webui:main
echo 'xxx' | docker login 192.168.122.156:30000 -u admin --password-stdin
docker push 192.168.122.156:30000/cnrancher/open-webui:main

# 在 K8s 集群节点重新部署
$KUBECTL rollout restart deployment/open-webui
$KUBECTL rollout status deployment/open-webui --timeout=120s

注意: Open WebUI 数据持久化在 /opt/open-webui/,升级不会丢失配置和聊天记录。

6.5 vLLM 版本升级

bash
# 1. 修改 build-and-push.sh 中的 IMAGE_TAG 为新版本
# 2. 执行构建 (约 30 分钟)
bash build-and-push.sh

# 3. 更新 YAML 文件中的 image tag
# vllm-qwen.yaml / vllm-deepseek.yaml:
#   image: 192.168.122.156:30000/cnrancher/vllm-rocm:v0.7.0  ← 新版本

# 4. 重新部署
./deploy.sh

注意: 新版本可能需要调整运行时补丁。升级前建议先在测试环境验证。

6.6 备份与恢复

bash
# 备份 Open WebUI 数据
tar czf open-webui-backup-$(date +%Y%m%d).tar.gz -C /opt open-webui/

# 备份 YAML 配置
cp -r /root/vllm-deploy /root/vllm-deploy-backup-$(date +%Y%m%d)

# 恢复 Open WebUI 数据
tar xzf open-webui-backup-YYYYMMDD.tar.gz -C /opt/
$KUBECTL rollout restart deployment/open-webui

6.7 常见问题处理

问题症状解决方案
Pod Pendingamd.com/gpu 资源不足重新注册 vGPU 资源 (见 4.4)
Pod CrashLoopBackOff启动失败反复重启查看日志,检查补丁是否正确应用
Open WebUI 无法连接 vLLM连接超时/拒绝检查 DB 中的 URL 配置 (见 4.3)
推理结果异常乱码/重复/截断检查 --max-model-len--max-tokens 参数
GPU 显存溢出OOM Killed降低 --gpu-memory-utilization--max-model-len
响应缓慢首 token 延迟 > 5s见性能调优章节

七、性能调优手册

7.1 GPU 显存分配

当前配置 (Qwen2.5-7B, 默认模型):

  • --gpu-memory-utilization 0.90 → 使用 90% × 24GB = 21.6 GB
  • 模型权重: ~14 GB (Qwen2.5-7B FP16)
  • KV Cache: ~7.6 GB (剩余空间,支持 16K 上下文)

调整建议:

场景gpu-memory-utilization效果
单模型独占 GPU (当前)0.90最大 KV Cache,支持长上下文/高并发
单模型 + 留余量0.75平衡性能和稳定性
保守配置0.45低显存占用,适合测试

修改方法: 编辑 YAML 中的 --gpu-memory-utilization 参数,然后 kubectl apply -f 并重启。

7.2 批处理与并发

bash
# 增大最大并行请求数 (默认 256)
--max-num-seqs 64

# 增大批处理大小 (默认自动)
--max-num-batched-seqs 128

# 启用连续批处理 (默认已启用)
--enable-chunked-prefill

7.3 推理加速选项

bash
# 启用 Prefix Caching (相同前缀的请求共享 KV Cache)
--enable-prefix-caching

# 调整调度策略 (优化首 token 延迟)
--scheduling-policy fcfs  # 默认 FCFS; 可选: priority

7.4 量化模型 (减少显存占用)

量化方式显存节省精度损失适用场景
FP16 (当前)基准精度优先
INT8 (W8A8)~50%极小平衡方案
INT4 (GPTQ/AWQ)~75%较小显存紧张
GGUF Q4_K_M~75%较小llama.cpp 专用

使用量化模型示例:

bash
# 下载 GPTQ-Int4 版本的 Qwen 后修改:
--model /models/huggingface/Qwen/Qwen2.5-3B-Instruct-GPTQ-Int4 \
--quantization gptq

7.5 监控与诊断

bash
# 查看 vLLM 内置指标 (通过日志)
$KUBECTL logs deployment/vllm-qwen7b | grep "metrics.py"
# 输出示例:
# Avg prompt throughput: 12.5 tokens/s
# Avg generation throughput: 35.2 tokens/s
# Running: 1 reqs, GPU KV cache usage: 5.2%

# 查看 GPU 实时状态 (需要 rocm-smi)
$KUBECTL exec deployment/vllm-qwen7b -- rocm-smi

# 查看 GPU 显存详细使用
$KUBECTL exec deployment/vllm-qwen7b -- \
  cat /sys/class/drm/card1/device/mem_info_vram_used

# 性能基准测试 (测量响应时间)
$KUBECTL exec deployment/open-webui -- curl -s -w "\nTime: %{time_total}s\n" \
  http://vllm-qwen7b:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"qwen2.5-7b","messages":[{"role":"user","content":"写一篇500字的文章"}],"max_tokens":512}'

7.6 性能基准参考 (AMD RX 7900 XTX)

模型首 token 延迟生成速度 (tokens/s)显存占用
Qwen2.5-7B (FP16, 默认)~1-2s~20-35~14 GB
Qwen2.5-3B (FP16)~0.5-1s~30-50~6 GB
DeepSeek-R1-1.5B (FP16)~0.3-0.5s~40-60~3 GB

八、上下文长度配置手册

8.1 核心概念

  • Context Length: 模型能处理的最大 token 数 (输入 + 输出)
  • Prompt Tokens: 用户输入 + 系统提示 + 历史对话占用的 token
  • Completion Tokens: 模型生成的 token
  • KV Cache: 存储中间计算结果,随上下文长度线性增长

8.2 当前配置

bash
--max-model-len 16384   # 当前值: 支持 16K token 上下文 (Qwen2.5-7B)

显存占用估算 (Qwen2.5-7B):

模型权重:        ~14 GB (固定)
KV Cache (16K):  ~7 GB (线性增长)
─────────────────────────
总计:            ~21 GB (gpu-memory-utilization=0.90 → 上限 21.6 GB)

8.3 不同上下文长度的显存需求 (Qwen2.5-7B)

max-model-lenKV Cache 大小总显存需求gpu-memory-utilization 建议
4096~2 GB~16 GB0.70
8192~4 GB~18 GB0.80
16384 (当前)~7 GB~21 GB0.90
32768~14 GB~28 GB超出显存,不可行

8.4 调整上下文长度

减小到 8K (节省显存,适合简单对话):

bash
# 修改 YAML 中的启动参数
--max-model-len 8192 \
--gpu-memory-utilization 0.80 \

当前配置: 16K (默认,日常使用最佳平衡):

bash
--max-model-len 16384 \
--gpu-memory-utilization 0.90 \

⚠️ 警告: 7B 模型在 24GB GPU 上不支持 32K 上下文 (需 ~28GB)。 如遇到 OOM Killed,降低 --gpu-memory-utilization--max-model-len

8.5 Open WebUI 端上下文设置

Open WebUI 默认使用模型的完整上下文长度。如需限制:

  1. 在 Open WebUI 管理界面中:

    • Settings → Models → 选择模型
    • 调整 "Context Length" 滑块
  2. 或通过 API 限制:

bash
# 在请求中指定 max_tokens
curl http://vllm-qwen7b:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen2.5-7b",
    "messages": [...],
    "max_tokens": 1024
  }'

8.6 长对话处理策略

当对话历史超过上下文长度时:

策略说明实现方式
截断历史只保留最近 N 轮对话Open WebUI 自动处理
摘要压缩将旧对话摘要后保留Open WebUI Memory 功能
增大上下文提高 --max-model-len修改 YAML 并重启
新建对话清空历史重新开始用户手动操作

8.7 上下文长度错误排查

错误信息:

This model's maximum context length is 4096 tokens.
However, you requested 5806 tokens in the messages.
Please reduce the length of the messages.

解决步骤:

  1. 检查当前 --max-model-len 值:
    bash
    $KUBECTL logs deployment/vllm-qwen7b | grep "max_model_len"
  2. 增大 --max-model-len (编辑 YAML → kubectl apply -f)
  3. 同时调整 --gpu-memory-utilization 以匹配显存需求
  4. 重启 Pod 使配置生效

九、已知限制与后续优化

9.1 当前限制

限制原因影响缓解措施
单模型独占 GPU显存不足无法同时运行多个模型deploy.sh switch 手动切换
vGPU 手动注册HAMi 不支持 AMDkubelet 重启后需重新注册考虑 AMD Device Plugin
HIP Graph 不可用gfx1100 不稳定无法使用 CUDA Graph 加速使用 --enforce-eager
Triton Flash Attn 不可用ROCm 不兼容注意力计算较慢可接受的性能损失
多进程 IPC 不可用ROCm 序列化问题单进程运行--disable-frontend-multiprocessing
RAG embedding 下载失败容器无外网RAG 功能不可用预下载 embedding 模型到本地

9.2 后续优化路线图

  1. 部署 AMD GPU Device Plugin — 实现 amd.com/gpu 资源自动注册
  2. 模型量化 (GPTQ-Int4) — 减少 ~75% 显存占用,可能允许同时运行多模型
  3. vLLM 版本升级 — v0.7.x+ 可能修复 ROCm 兼容性问题,支持 HIP Graph
  4. 持久化存储 — 使用 Longhorn/NFS PVC 替代 hostPath
  5. 负载均衡 — 部署多个 vLLM 实例 + Ingress Controller
  6. 监控告警 — 集成 Prometheus + Grafana
  7. RAG 功能 — 预下载 embedding 模型到本地

附录 A: 公网暴露配置

组件文件说明
DNS阿里云 DNSai.ai-ear.cn A → 8.153.84.140
frpc/etc/frp/frpc.tomlopen-webui-18080 隧道 (localIP=192.168.122.9, localPort=30080)
Traefik/etc/traefik/dynamic.yamlai-open-webui 路由 + TLS
证书/etc/pki/nginx/ai.ai-ear.cn.crt自签名证书 (365天)
K8s Serviceopen-webui.yamlNodePort 30080

附录 B: 快速恢复命令

bash
# 通用 kubectl 前缀 (在 192.168.122.37 上执行)
KUBECTL="/var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml"

# 一键重新部署
cd /root/vllm-deploy && bash deploy.sh

# 注册 vGPU (kubelet 重启后)
$KUBECTL patch node szb122009 --type=merge --subresource=status \
  -p '{"status":{"capacity":{"amd.com/gpu":"4"},"allocatable":{"amd.com/gpu":"4"}}}'

# 重启所有服务
$KUBECTL rollout restart deployment/vllm-qwen7b
$KUBECTL rollout restart deployment/open-webui

# 切换到 Qwen2.5-7B (默认)
cd /root/vllm-deploy && bash deploy.sh switch qwen7b

# 测试 API
$KUBECTL exec deployment/open-webui -- \
  curl -s http://vllm-qwen7b:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"qwen2.5-7b","messages":[{"role":"user","content":"你好"}],"max_tokens":50}'