跳转至

vLLM 部署 Qwen3-235B-A22B-Thinking-2507 实战记录

背景

这篇文章记录如何在 OpenBayes GPU 容器中,使用 vLLM 下载、启动、测试和调优 Qwen/Qwen3-235B-A22B-Thinking-2507

本次实际部署环境:

这个模型适合复杂推理、代码、数学、长文档分析等场景。它不是普通的小模型,部署时重点不是“命令能不能跑”,而是显存、上下文长度、并发、KV Cache 之间的平衡。

官方模型卡里的关键信息如下:

  • 模型名称:Qwen/Qwen3-235B-A22B-Thinking-2507
  • 模型类型:Causal Language Model
  • 架构:Qwen3 MoE
  • 参数规模:总参数 235B,单次推理激活约 22B
  • Expert 数量:128 个 experts,每次激活 8 个
  • 原生上下文:262144 tokens
  • 模型精度:BF16
  • 模式限制:只支持 thinking mode
  • vLLM 建议版本:vllm>=0.8.5

官方参考:

资源评估

推荐硬件

这个模型虽然是 MoE,每次只激活 22B 参数,但权重本身仍然需要加载完整 235B 参数。BF16 权重体积很大,所以生产部署建议优先使用 8 卡大显存机器。

本次环境是 8 卡 RTX PRO 6000。如果是 RTX PRO 6000 Blackwell,单卡显存为 96GB,8 卡总显存约 768GB。实际进入 OpenBayes 容器后仍然要用 nvidia-smi 确认显存容量,因为历史上也有 RTX 6000 Ada 48GB 这一类相近命名的卡。

推荐规格:

场景 推荐 GPU 说明
本次 OpenBayes 部署 8 * RTX PRO 6000 按 8 卡张量并行部署
基础测试 8 * RTX PRO 6000 建议先从 64K/128K 上下文启动
生产服务 8 * RTX PRO 6000 / H100 / H200 更适合长上下文和稳定并发
262K 长上下文 8 卡 80GB+ 大显存 需要给 KV Cache 留足空间
1M 超长上下文 总显存约 1000GB 级别 官方也提示需要极高显存

如果只是想体验模型能力,不建议在本地强行裸跑。可以先用云平台、OpenBayes GPU 容器或者推理平台验证。

显存和上下文关系

vLLM 启动时最容易遇到的问题是 KV Cache 不够。上下文越长,KV Cache 占用越高。

几个经验值:

  • --max-model-len 262144 是官方原生上下文,但对显存压力很大。
  • 如果 OOM,可以先降到 131072
  • 如果只是 API 功能测试,可以先降到 3276865536
  • 不要一开始就追求 262K + 高并发,先让模型稳定起来。

环境检查

进入 GPU 容器或服务器后,先确认基础环境。

nvidia-smi
python3 --version
pip --version
df -h

建议 Python 版本使用 3.10 或 3.11。磁盘空间至少准备 600GB 以上,模型权重、缓存、临时文件都会占空间。

模型下载

ModelScope Qwen3-235B-A22B-Thinking-2507 模型文件列表

如果是在 OpenBayes 中运行,有两种常见方式:

  1. 提前把 ModelScope 模型下载好,作为 OpenBayes 数据集或输入目录挂载。
  2. 在 OpenBayes 容器中直接从 ModelScope 下载到输出目录或持久化目录。

如果模型已经作为输入挂载,路径通常类似:

/openbayes/input/input0/Qwen3-235B-A22B-Thinking-2507

如果需要在容器中下载,建议放到输出目录或持久化数据盘,例如:

/openbayes/output/models/Qwen3-235B-A22B-Thinking-2507

下面统一用变量管理路径。

export MODEL_ID="Qwen/Qwen3-235B-A22B-Thinking-2507"
export MODEL_DIR="/openbayes/output/models/Qwen3-235B-A22B-Thinking-2507"
export MODELSCOPE_CACHE="/openbayes/output/modelscope-cache"

这里为了可以省钱,大家可以先开CPU的机器把模型文件下载下来再来操作 20260609184456

我的下载方法:

apt install screen
screen -R download
modelscope download \
  --model Qwen/Qwen3-235B-A22B-Thinking-2507 \
  --local_dir ./

ctrl +ad # 保存并退出

过段时间就可以看到数据集下载的模型文件,在openbayes平台下载这个方法是通用的,有兴趣可以试试看。(原始模型的大小为470.21GB所以下载可能需要一段时间,推荐夜晚来做下载模型的操作,可以节约很多时间) 20260609184822

安装依赖

安装 vLLM

官方建议 vllm>=0.8.5。为了避免 Qwen3 MoE 结构不支持,建议直接安装较新的 vLLM 和 transformers。

python3 -m pip install -U pip
python3 -m pip install -U "vllm>=0.8.5" "transformers>=4.51.0" accelerate modelscope

如果 transformers 版本太低,可能会出现:

KeyError: 'qwen3_moe'

处理方式:

python3 -m pip install -U "transformers>=4.51.0"

检查 vLLM 版本

python3 - <<'PY'
import vllm
import transformers

print("vllm:", vllm.__version__)
print("transformers:", transformers.__version__)
PY

ModelScope 下载命令

方式一:ModelScope CLI 下载

本次部署使用国内 ModelScope 源下载模型。ModelScope 官方文档说明,modelscope download 支持 --local_dir,文件会直接下载到指定目录;如果下载中断,再次执行同一个命令可以继续下载。

export MODEL_ID="Qwen/Qwen3-235B-A22B-Thinking-2507"
export MODEL_DIR="/openbayes/output/models/Qwen3-235B-A22B-Thinking-2507"
export MODELSCOPE_CACHE="/openbayes/output/modelscope-cache"

mkdir -p "${MODEL_DIR}" "${MODELSCOPE_CACHE}"

modelscope download \
  --model "${MODEL_ID}" \
  --local_dir "${MODEL_DIR}" \
  --max-workers 8

下载完成后检查关键文件:

ls -lh "${MODEL_DIR}" | head
test -f "${MODEL_DIR}/config.json" && echo "config ok"
test -f "${MODEL_DIR}/tokenizer_config.json" && echo "tokenizer ok"
find "${MODEL_DIR}" -maxdepth 1 -name '*.safetensors' | wc -l

方式二:ModelScope SDK 下载

如果 CLI 下载在 Notebook 或脚本里不方便,也可以使用 SDK:

python3 - <<'PY'
import os
from modelscope import snapshot_download

model_id = "Qwen/Qwen3-235B-A22B-Thinking-2507"
model_dir = "/openbayes/output/models/Qwen3-235B-A22B-Thinking-2507"
os.environ["MODELSCOPE_CACHE"] = "/openbayes/output/modelscope-cache"

path = snapshot_download(
    model_id,
    local_dir=model_dir,
)
print("model downloaded to:", path)
PY

方式三:提前下载后挂载到 OpenBayes

如果 OpenBayes 容器内下载速度不稳定,推荐在外部环境先通过 ModelScope 下载,再作为数据集或输入目录挂载到 OpenBayes。

容器内只需要确认路径存在:

export MODEL_DIR="/openbayes/input/input0/Qwen3-235B-A22B-Thinking-2507"
ls -lh "${MODEL_DIR}"

方式四:Hugging Face 下载备用

如果环境可以访问 Hugging Face,也可以使用 Hugging Face 下载。国内环境优先使用 ModelScope。

python3 -m pip install -U huggingface_hub hf_transfer

export HF_HOME="/openbayes/output/huggingface"
export HF_HUB_ENABLE_HF_TRANSFER=1

huggingface-cli download "${MODEL_ID}" \
  --local-dir "${MODEL_DIR}" \
  --local-dir-use-symlinks False \
  --resume-download

方式五:断点续传

模型很大,下载中断很常见。ModelScope CLI 和 SDK 都支持断点续传。通常再次执行同一个下载命令即可。

如果缓存损坏,优先删除单个异常文件,不要直接清空整个模型目录。

启动服务

最小可用启动命令

先用适合 OpenBayes 8 卡 RTX PRO 6000 的保守参数启动,目标是跑通 OpenAI-compatible API。

export MODEL_DIR="/openbayes/output/models/Qwen3-235B-A22B-Thinking-2507"

vllm serve "${MODEL_DIR}" \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name Qwen3-235B-A22B-Thinking-2507 \
  --tensor-parallel-size 8 \
  --max-model-len 131072 \
  --dtype bfloat16 \
  --gpu-memory-utilization 0.85 \
  --max-num-seqs 1 \
  --enable-reasoning \
  --reasoning-parser deepseek_r1

说明:

  • --tensor-parallel-size 8:使用 8 张 GPU 做张量并行。
  • --max-model-len 131072:先用 128K 上下文启动,更适合第一次在 OpenBayes 上验证。
  • --dtype bfloat16:匹配模型 BF16 权重。
  • --gpu-memory-utilization 0.85:不要一开始打满显存,给系统和碎片留空间。
  • --max-num-seqs 1:第一次启动先保证单请求稳定。
  • --enable-reasoning:启用 reasoning 输出。
  • --reasoning-parser deepseek_r1:官方模型卡给出的 vLLM 部署参数。
  • --served-model-name:给 API 暴露一个稳定模型名,避免客户端使用本地绝对路径。

OpenBayes 路径示例

如果模型已经作为 OpenBayes 输入目录挂载:

export MODEL_DIR="/openbayes/input/input0/Qwen3-235B-A22B-Thinking-2507"

vllm serve "${MODEL_DIR}" \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name Qwen3-235B-A22B-Thinking-2507 \
  --tensor-parallel-size 8 \
  --max-model-len 131072 \
  --dtype bfloat16 \
  --gpu-memory-utilization 0.85 \
  --enable-reasoning \
  --reasoning-parser deepseek_r1

这里先用 131072,比 262K 更容易启动成功。等验证稳定后再逐步升到 262K。

如果确认 8 张 RTX PRO 6000 都是 96GB 显存,并且 128K 稳定,可以再尝试 262K:

export MODEL_DIR="/openbayes/output/models/Qwen3-235B-A22B-Thinking-2507"

vllm serve "${MODEL_DIR}" \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name Qwen3-235B-A22B-Thinking-2507 \
  --tensor-parallel-size 8 \
  --max-model-len 262144 \
  --dtype bfloat16 \
  --gpu-memory-utilization 0.85 \
  --max-num-seqs 1 \
  --max-num-batched-tokens 65536 \
  --enable-chunked-prefill \
  --enable-reasoning \
  --reasoning-parser deepseek_r1

API 测试

健康检查

curl http://127.0.0.1:8000/v1/models

正常会返回模型列表,里面应该能看到:

Qwen3-235B-A22B-Thinking-2507

Chat Completions 测试

curl http://127.0.0.1:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen3-235B-A22B-Thinking-2507",
    "messages": [
      {
        "role": "user",
        "content": "请用三句话解释 Kubernetes 中 Pod、Deployment、Service 的关系。"
      }
    ],
    "temperature": 0.6,
    "top_p": 0.95,
    "max_tokens": 2048
  }'

Qwen3 Thinking 模型会产生 reasoning 内容。vLLM 文档说明 reasoning 模型会在响应中返回额外的 reasoning 字段,最终答案在 content 字段中。

Python 客户端测试

python3 - <<'PY'
from openai import OpenAI

client = OpenAI(
    api_key="EMPTY",
    base_url="http://127.0.0.1:8000/v1",
)

resp = client.chat.completions.create(
    model="Qwen3-235B-A22B-Thinking-2507",
    messages=[
        {
            "role": "user",
            "content": "9.11 和 9.8 哪个更大?请给出最终答案。",
        }
    ],
    temperature=0.6,
    top_p=0.95,
    max_tokens=2048,
)

msg = resp.choices[0].message
print("reasoning:")
print(getattr(msg, "reasoning", None))
print("content:")
print(msg.content)
PY

启动参数说明

核心参数

参数 建议值 作用
--tensor-parallel-size 8 使用多少张 GPU 切分模型
--max-model-len 131072 / 262144 最大上下文长度
--gpu-memory-utilization 0.800.90 vLLM 可使用的显存比例
--dtype bfloat16 模型计算精度
--max-num-seqs 116 同时处理的序列数
--max-num-batched-tokens 32768131072 prefill 批处理 token 上限
--enable-reasoning 开启 让 API 输出 reasoning 字段
--reasoning-parser deepseek_r1 按官方建议解析 thinking 输出

推荐启动组合

1. 稳定优先

适合第一次启动、排查 OOM、模型功能验证。

vllm serve "${MODEL_DIR}" \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name Qwen3-235B-A22B-Thinking-2507 \
  --tensor-parallel-size 8 \
  --max-model-len 65536 \
  --dtype bfloat16 \
  --gpu-memory-utilization 0.80 \
  --max-num-seqs 1 \
  --enable-reasoning \
  --reasoning-parser deepseek_r1

2. 长上下文优先

适合文档分析、长日志分析、代码仓库分析。

vllm serve "${MODEL_DIR}" \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name Qwen3-235B-A22B-Thinking-2507 \
  --tensor-parallel-size 8 \
  --max-model-len 262144 \
  --dtype bfloat16 \
  --gpu-memory-utilization 0.85 \
  --max-num-seqs 1 \
  --max-num-batched-tokens 65536 \
  --enable-chunked-prefill \
  --enable-reasoning \
  --reasoning-parser deepseek_r1

3. 吞吐优先

适合短 prompt、多请求服务。不要和 262K 长上下文同时拉满。

vllm serve "${MODEL_DIR}" \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name Qwen3-235B-A22B-Thinking-2507 \
  --tensor-parallel-size 8 \
  --max-model-len 32768 \
  --dtype bfloat16 \
  --gpu-memory-utilization 0.90 \
  --max-num-seqs 8 \
  --max-num-batched-tokens 32768 \
  --enable-reasoning \
  --reasoning-parser deepseek_r1

调优思路

1. OOM 调优顺序

如果启动时报 OOM,不要先怀疑模型文件。优先按下面顺序降配置:

  1. 降低 --max-model-len,例如 262144 -> 131072 -> 65536 -> 32768
  2. 降低 --max-num-seqs,先设置为 1
  3. 降低 --max-num-batched-tokens,例如 131072 -> 65536 -> 32768
  4. 降低 --gpu-memory-utilization0.80
  5. 确认 --tensor-parallel-size 是否等于实际可用 GPU 数量。

常见错误:

The model's max seq len is larger than the maximum number of tokens that can be stored in KV cache

处理方式:

--max-model-len 131072
--max-num-seqs 1
--gpu-memory-utilization 0.85

2. 长上下文调优

长上下文的瓶颈通常不是权重,而是 prefill 和 KV Cache。

建议:

  • 文档分析类任务使用 --enable-chunked-prefill
  • --max-num-batched-tokens 不要无限增大,先从 65536 开始。
  • 长上下文场景优先保证单请求稳定,不要追求高并发。
  • 如果业务请求多数小于 32K,不要把服务默认配置成 262K,显存利用率会很差。

3. 并发调优

并发能力主要由 max_model_lenmax_num_seqs、KV Cache 显存共同决定。

建议做两套服务:

服务类型 max_model_len max_num_seqs 用途
short-context 32768 8 到 32 日常问答、短 prompt
long-context 131072 或 262144 1 到 2 长文档、复杂推理

这样比一个服务同时承担所有请求更稳定。

4. Thinking 输出调优

这个模型只支持 thinking mode。官方说明默认 chat template 会自动包含 <think>,所以输出里只有 </think> 而没有显式 <think> 开始标签是正常现象。

如果客户端只需要最终答案,可以在应用层只展示 content 字段,不展示 reasoning 字段。

如果需要限制思考长度,可以结合 vLLM reasoning 参数和请求侧 max_tokens 做控制。实际生产中建议先限制 max_tokens,避免一次请求长时间占满 GPU。

请求示例:

curl http://127.0.0.1:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen3-235B-A22B-Thinking-2507",
    "messages": [
      {
        "role": "user",
        "content": "请分析一次 Kubernetes 集群 CoreDNS 延迟升高的排查路径。"
      }
    ],
    "temperature": 0.6,
    "top_p": 0.95,
    "max_tokens": 4096
  }'

1M 上下文实验

官方提供了 1M token 上下文的实验方案,但这个不是普通部署配置。官方提示处理 1M token 需要约 1000GB 总 GPU 显存,生产使用前必须单独压测。

替换 1M 配置

export MODEL_DIR="/openbayes/output/models/Qwen3-235B-A22B-Thinking-2507"

cp "${MODEL_DIR}/config.json" "${MODEL_DIR}/config.json.bak"
cp "${MODEL_DIR}/config_1m.json" "${MODEL_DIR}/config.json"

1M vLLM 启动示例

VLLM_ATTENTION_BACKEND=DUAL_CHUNK_FLASH_ATTN VLLM_USE_V1=0 \
vllm serve "${MODEL_DIR}" \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name Qwen3-235B-A22B-Thinking-2507 \
  --tensor-parallel-size 8 \
  --max-model-len 1010000 \
  --enable-chunked-prefill \
  --max-num-batched-tokens 131072 \
  --enforce-eager \
  --max-num-seqs 1 \
  --gpu-memory-utilization 0.85 \
  --enable-reasoning \
  --reasoning-parser deepseek_r1

参数说明:

  • VLLM_ATTENTION_BACKEND=DUAL_CHUNK_FLASH_ATTN:启用长上下文注意力后端。
  • VLLM_USE_V1=0:配合该后端使用。
  • --enforce-eager:关闭 CUDA graph capture,避免和该长上下文后端冲突。
  • --max-num-seqs 1:1M 上下文场景基本只能先保证单请求。

如果只是日常部署,不建议直接使用 1M 配置。

systemd 管理示例

本次主要运行在 OpenBayes 容器中,不需要 systemd。如果后续迁移到裸机长期运行,可以参考下面的 systemd 配置。

[Unit]
Description=vLLM Qwen3 Thinking Server
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/data
Environment=MODEL_DIR=/data/models/Qwen3-235B-A22B-Thinking-2507
ExecStart=/usr/local/bin/vllm serve ${MODEL_DIR} \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name Qwen3-235B-A22B-Thinking-2507 \
  --tensor-parallel-size 8 \
  --max-model-len 131072 \
  --dtype bfloat16 \
  --gpu-memory-utilization 0.85 \
  --max-num-seqs 1 \
  --enable-reasoning \
  --reasoning-parser deepseek_r1
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

启动:

systemctl daemon-reload
systemctl enable --now vllm-qwen3-thinking.service
systemctl status vllm-qwen3-thinking.service

Kubernetes 部署示例

本次部署平台是 OpenBayes,不需要自己写 Kubernetes Deployment。如果后续要把这个服务迁移到自建 Kubernetes,需要注意:

  • GPU 节点必须安装 NVIDIA Driver、Container Toolkit、GPU Operator 或 device plugin。
  • Pod 需要申请 8 张 GPU。
  • 模型目录建议使用 PVC、hostPath 或对象存储预热到本地盘。
  • readinessProbe 不能太激进,大模型启动可能需要很久。

示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: qwen3-thinking-vllm
  labels:
    app.kubernetes.io/name: qwen3-thinking-vllm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: qwen3-thinking-vllm
  template:
    metadata:
      labels:
        app.kubernetes.io/name: qwen3-thinking-vllm
    spec:
      containers:
        - name: vllm
          image: vllm/vllm-openai:latest
          imagePullPolicy: IfNotPresent
          command:
            - vllm
            - serve
            - /models/Qwen3-235B-A22B-Thinking-2507
          args:
            - --host
            - "0.0.0.0"
            - --port
            - "8000"
            - --served-model-name
            - Qwen3-235B-A22B-Thinking-2507
            - --tensor-parallel-size
            - "8"
            - --max-model-len
            - "131072"
            - --dtype
            - bfloat16
            - --gpu-memory-utilization
            - "0.85"
            - --max-num-seqs
            - "1"
            - --enable-reasoning
            - --reasoning-parser
            - deepseek_r1
          ports:
            - containerPort: 8000
              name: http
          resources:
            requests:
              cpu: "16"
              memory: 128Gi
              nvidia.com/gpu: "8"
            limits:
              cpu: "32"
              memory: 256Gi
              nvidia.com/gpu: "8"
          readinessProbe:
            httpGet:
              path: /v1/models
              port: 8000
            initialDelaySeconds: 300
            periodSeconds: 30
            timeoutSeconds: 10
            failureThreshold: 20
          livenessProbe:
            httpGet:
              path: /v1/models
              port: 8000
            initialDelaySeconds: 600
            periodSeconds: 60
            timeoutSeconds: 10
            failureThreshold: 10
          volumeMounts:
            - name: model
              mountPath: /models/Qwen3-235B-A22B-Thinking-2507
              readOnly: true
      volumes:
        - name: model
          hostPath:
            path: /data/models/Qwen3-235B-A22B-Thinking-2507
            type: Directory

常见问题

1. KeyError: qwen3_moe

原因:transformers 版本过低。

处理:

python3 -m pip install -U "transformers>=4.51.0"

2. CUDA out of memory

处理顺序:

--max-model-len 65536
--max-num-seqs 1
--gpu-memory-utilization 0.80
--max-num-batched-tokens 32768

如果仍然不行,检查是否有其他进程占用 GPU:

nvidia-smi

3. API 返回模型名不是客户端传的名字

启动时加:

--served-model-name Qwen3-235B-A22B-Thinking-2507

客户端请求统一使用:

"model": "Qwen3-235B-A22B-Thinking-2507"

4. 输出里没有 <think> 开始标签

这是正常现象。官方说明该模型默认 chat template 会自动包含 <think>,输出中只有 </think> 不代表错误。

5. 长上下文请求非常慢

这是正常现象。长上下文会让 prefill 阶段非常重。

优化方向:

  • 开启 --enable-chunked-prefill
  • 降低 --max-num-batched-tokens
  • 将短请求和长请求拆成两个服务。
  • 在业务层限制用户输入长度。

运维建议

生产环境建议至少做这些限制:

  • API 网关层限制请求体大小。
  • 限制单请求 max_tokens
  • 根据业务拆分 short-context 和 long-context 服务。
  • 监控 GPU 显存、GPU 利用率、请求延迟、队列长度。
  • 模型目录只读挂载,避免运行时误删。
  • 升级 vLLM 前先保留旧镜像,灰度验证 thinking 输出格式。

Prometheus 监控可直接抓 vLLM 指标端点,常见关注项:

  • 请求总数
  • 首 token 延迟
  • 输出 token 速率
  • GPU KV Cache 使用率
  • running / waiting 请求数

总结

Qwen3-235B-A22B-Thinking-2507 的部署核心是显存规划。推荐路径是:

  1. 先通过 ModelScope 国内源下载模型并确认文件完整。
  2. 使用 vllm>=0.8.5 和较新的 transformers
  3. 先用 --max-model-len 65536131072 跑通。
  4. 稳定后再提高到 262144
  5. 短请求和长上下文请求拆分部署。
  6. 1M 上下文只作为专项实验,不作为默认生产配置。

对于 OpenBayes + 8 卡 RTX PRO 6000 场景,最推荐的起步命令是:

export MODEL_DIR="/openbayes/output/models/Qwen3-235B-A22B-Thinking-2507"

vllm serve "${MODEL_DIR}" \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name Qwen3-235B-A22B-Thinking-2507 \
  --tensor-parallel-size 8 \
  --max-model-len 131072 \
  --dtype bfloat16 \
  --gpu-memory-utilization 0.85 \
  --max-num-seqs 1 \
  --enable-reasoning \
  --reasoning-parser deepseek_r1
回到页面顶部