Qwen3.8-27B 开源后,我用双 RTX 4090 跑通了:vLLM 0.27.1、128K 上下文与 MTP 实测
Qwen3.8-27B 弿ºåï¼æç¨å RTX 4090 è·éäºï¼vLLM 0.27.1ã128K ä¸ä¸æä¸ MTP 宿µ
ååæ¯è¿æ ·ç丶 2026-08-18 0 é 读10åéQwen3.8-27B 弿ºåï¼æç¨å RTX 4090 è·éäºï¼vLLM 0.27.1ã128K ä¸ä¸æä¸ MTP 宿µ
Qwen3.8-27B åå¸åï¼æç¬¬ä¸æ¶é´å¨ç°æå GPU æå¡å¨ä¸éæ°æäºä¸å¥ç¬ç«ç¯å¢ã
è¿æ¬¡æ²¡ææ²¿ç¨æ§æ¨¡åç Python ç¯å¢ï¼ä¹æ²¡æåªè®°å½ä¸æ¡âè½å¯å¨âçå½ä»¤ãæææ¨¡åä¸è½½ãCUDA çæ¬ãvLLMãsystemdãAPI é´æã128K é¿ä¸ä¸æå MTP é½å®é èµ°äºä¸éã
æç»ç»æå¦ä¸ï¼
- 宿¹ FP8 æéåç约 29GBï¼ModelScope 宿´ä»åºé¡µæ¾ç¤ºçº¦ 30.89GBã
vLLM 0.27.1ãPyTorch 2.13.0+cu130åå GPU å¼ éå¹¶è¡å¯å¨æåã- æå¡ç± systemd æç®¡ï¼å¯¹å¤æä¾å¸¦ API Key ç OpenAI å ¼å®¹æ¥å£ã
- æå¡ä¸ä¸æé 置为 128Kï¼2K/512 ç 4 å¹¶ååæµ 100 æ¬¡å ¨é¨æåã
- è¿ 128K çåå¹¶åå 4 å¹¶ååæµåå®æï¼æ²¡æè¯·æ±å¤±è´¥ã
- Prefix Cache å MTP é½åäºç¬ç«å¯¹ç §ï¼MTP æææ¾æåï¼ä½ææ¶ä¿ç为å®éªé ç½®ã
æ¬æææç¨æ·åãIP åå¯é¥é½ä½¿ç¨ <USER>ã<SERVER_IP>ã<API_KEY> å ä½ç¬¦ãæ§è¡åå¿
é¡»æ¿æ¢ä¸ºèªå·±çå¼ã
1. å çæ¨¡åï¼27B Denseãåçè§è§ä¸ 256K ä¸ä¸æ
Qwen3.8-27B-FP8 宿¹æ¨¡å页ç»åºçæ ¸å¿ä¿¡æ¯æ¯ï¼
- 模åç±»åï¼å¸¦è§è§ç¼ç å¨çå æè¯è¨æ¨¡åã
- è¯è¨æ¨¡ååæ°éï¼27B Denseã
- éè维度ï¼5120ã
- ç½ç»å±æ°ï¼64ã
- æ··åç»æï¼
16 à (3 à (Gated DeltaNet â FFN) â 1 à (Gated Attention â FFN))ã - MTPï¼ç»è¿å¤æ¥è®ç»ã
- åçä¸ä¸æï¼262,144 Tokenï¼å¯éè¿é¢å¤æ©å±é ç½®æ¯ææ´é¿ä¸ä¸æã
- FP8ï¼ç»ç²åº¦åéåï¼block size 为 128ã
- 夿¨¡æï¼åçæ¯æå¾çåè§é¢çè§£ã
å¾ 1ï¼ModelScope 宿¹æ¨¡åé¡µçæ¨¡åæ¦è§ãè¿éç 262,144 æ¯æ¨¡ååçä¸éï¼ä¸æ¯é¨ç½²åèªå¨è·å¾çæå¡é¿åº¦ã
宿¹ Benchmark åºè¯¥æä¹ç
ModelScope 模å页忶ç»åºäº Text å VL 两ç»å®æ¹ç»æã
å¾ 2ï¼ModelScope 宿¹ Text Benchmarkãæ°æ®æ¥èªå®æ¹è¯æµ Harnessã
å¾ 3ï¼ModelScope 宿¹ VL Benchmarkã
éå 个容æçè§£ç宿¹ææ ï¼
| Benchmark | Qwen3.8-27B | Qwen3.6-27B | Qwen3.7-Plus | Opus4.6 Max |
|---|---|---|---|---|
| SWE-bench Pro | 61.7 | 53.5 | 57.6 | 53.4 |
| CoWorkBench | 70.7 | 61.0 | 65.1 | 68.2 |
| LiveCodeBench v6 | 90.3 | 83.9 | 89.6 | 88.8 |
| OSWorld-Verified | 84.3 | 63.9 | 73.3 | 72.7 |
| AndroidWorld | 81.9 | 70.3 | 81.0 | 62.0 |
2. æå¡å¨ä¸è½¯ä»¶çæ¬ç©éµ
æ¬æå®é è·éççæ¬å¦ä¸ï¼
| ç»ä»¶ | 宿µçæ¬ |
|---|---|
| Linux Kernel | 7.0.0-28-generic |
| NVIDIA Driver | 595.84 |
| GPU | 2 å¼ RTX 4090ï¼å个约 48GiB |
| Python | 3.12 |
| uv | 0.12.5 |
| modelscope-hub | 0.2.0 |
| PyTorch | 2.13.0+cu130 |
| torchvision | 0.28.0+cu130 |
| torchaudio | 2.11.0+cu130 |
| Transformers | 5.15.0 |
| vLLM | 0.27.1 |
| CUDA Runtime | 13.0 |
注æï¼modelscope-hub 0.2.0 宿ä¾çå½ä»¤æ¯ ms-hubï¼æ¬æç»ä¸ä½¿ç¨è¿ä¸ª CLIã
妿å®è£
ççæ¬æ¯å¨<=0.1.8Â å¨ PyPI 䏿³¨åçå½ä»¤æ¯Â ms å modelscopeã
宿主æºåºçº¿ï¼
 # æ ¸å¯¹å
æ ¸ã驱å¨ãGPUãç£çåå
±äº«å
å
 uname -r
 nvidia-smi
 df -h /data
 df -h /dev/shm
3. ä»ç©ºç®å½å¼å§æå»ºç¬ç«ç¯å¢
æç» Qwen3.8 åç¬å»ºç«é¡¹ç®ã模åãç¼åååæµç®å½ã
3.1 å建ç®å½
 # å° <USER> æ¿æ¢ä¸ºå®é
Linux ç¨æ·å
 sudo mkdir -p /home/<USER>/projects/vllm-qwen38
 sudo mkdir -p /data/models/hf
 sudo mkdir -p /data/cache/qwen38/modelscope-hub
 sudo mkdir -p /data/cache/qwen38/huggingface
 sudo mkdir -p /data/cache/qwen38/torchinductor
 sudo mkdir -p /data/cache/qwen38/vllm
 sudo mkdir -p /data/artifacts/qwen38
 â
 sudo chown -R <USER>:<USER> /home/<USER>/projects/vllm-qwen38
 sudo chown -R <USER>:<USER> /data/models/hf
 sudo chown -R <USER>:<USER> /data/cache/qwen38
 sudo chown -R <USER>:<USER> /data/artifacts/qwen38
æç»ç®å½å ³ç³»æ¯ï¼
 /home/<USER>/projects/vllm-qwen38/      项ç®ãèæç¯å¢åå¯å¨èæ¬
 /home/<USER>/projects/vllm-qwen38/.env    模åè·¯å¾ä¸å
é¨ API Key
 /data/models/hf/Qwen3.8-27B-FP8/       模åç®å½
 /data/cache/qwen38/              ModelScopeãHFãvLLMãç¼è¯ç¼å
 /data/artifacts/qwen38/            ç¯å¢è®°å½ååæµç»æ
 /etc/systemd/system/qwen38-main.service    systemd æå¡
3.2 æ´æ° uvï¼å建 Python 3.12 ç¯å¢
 # æ´æ° uv å¹¶å建 Qwen3.8 ç¬ç«èæç¯å¢
 uv self update
 uv --version
 â
 cd /home/<USER>/projects/vllm-qwen38
 uv venv --python 3.12 --seed --managed-python .venv
 source .venv/bin/activate
 python --version
3.3 å®è£ modelscope-hub 0.2.0
 # ä¸è½½å·¥å
·ä¸éè¦ CUDA ç PyTorchï¼å
æ CPU å端å®è£
 UV_TORCH_BACKEND=cpu uv pip install \
  --python .venv/bin/python \
  'modelscope-hub==0.2.0'
 â
 ms-hub --version
 python -c "from importlib.metadata import version; print(version('modelscope-hub'))"
 uv pip check
4. ç¨ ModelScope 䏿¡å½ä»¤ä¸è½½å®æ´æ¨¡å
æå®æç»ç®å½å³å¯ç´æ¥ä¸è½½ï¼
 cd /home/<USER>/projects/vllm-qwen38
 source .venv/bin/activate
 â
 # ä½¿ç¨ ModelScope å½å
ç«ï¼å®æ´ä»åºç´æ¥åå
¥æç»æ¨¡åç®å½
 export MODELSCOPE_ENDPOINT=https://modelscope.cn
 export MODELSCOPE_CACHE=/data/cache/qwen38/modelscope-hub
 export MODELSCOPE_DOWNLOAD_PARALLEL_WORKERS=4
 export MODELSCOPE_DOWNLOAD_MAX_RETRIES=10
 export MODEL_DIR=/data/models/hf/Qwen3.8-27B-FP8
 â
 mkdir -p "$MODEL_DIR"
 â
 ms-hub download Qwen/Qwen3.8-27B-FP8 \
  --local-dir "$MODEL_DIR" \
  --max-workers 8
ä¸è½½ä¸æåï¼éæ°æ§è¡å䏿¡ ms-hub download å³å¯ç»ä¼ ã妿éè¦ä¸¥æ ¼å¤ç°ï¼é¢å¤å¢å --revision <MODEL_REVISION> åºå®å®æ¹ revisionã
ä¸è½½å®æåæ£æ¥é ç½®ãç´¢å¼åæéï¼
 # æ ¸å¯¹æ¨¡åé
ç½®ãæéç´¢å¼ãæéåç忻大å°
 test -s "$MODEL_DIR/config.json"
 test -s "$MODEL_DIR/model.safetensors.index.json"
 find "$MODEL_DIR" -maxdepth 1 -name '*.safetensors' -type f | sort | head
 du -sh "$MODEL_DIR"
 â
 python - "$MODEL_DIR" <<'PY'
 import json
 from pathlib import Path
 import sys
 â
 model_dir = Path(sys.argv[1])
 config = json.load(open(model_dir / "config.json"))
 text = config.get("text_config", config)
 â
 print("architectures:", config.get("architectures"))
 print("max_position_embeddings:", text.get("max_position_embeddings"))
 print("vision:", bool(config.get("vision_config")))
 print("quantization:", bool(
  text.get("quantization_config") or config.get("quantization_config")
 ))
 â
 assert "Qwen3_5ForConditionalGeneration" in config.get("architectures", [])
 assert text.get("max_position_embeddings") == 262144
 assert config.get("vision_config")
 assert text.get("quantization_config") or config.get("quantization_config")
 PY
5. å®è£ vLLM 0.27.1 ä¸ cu130 å ¼å®¹æ
è¿å¥ç¯å¢çååå¾ç®åï¼è®© vLLM å³å®å
¶éå®ç PyTorch çæ¬ï¼ä¸ååç¬å级 torchãtorchvision æ torchaudioã
 cd /home/<USER>/projects/vllm-qwen38
 source .venv/bin/activate
 â
 # ä½¿ç¨ cu130 å端å®è£
åºå®çæ¬ï¼é¿å
CUDA wheel æ··è£
 uv pip install \
  --python .venv/bin/python \
  --torch-backend=cu130 \
  'vllm==0.27.1' \
  'transformers==5.15.0' \
  'packaging>=25.0'
 â
 uv pip check
éååå¼ºå¶æè¨ï¼
 python - <<'PY'
 from importlib.metadata import version
 â
 expected = {
   "vllm": "0.27.1",
   "torch": "2.13.0",
   "torchvision": "0.28.0",
   "torchaudio": "2.11.0",
   "transformers": "5.15.0",
 }
 â
 for package, wanted in expected.items():
  actual = version(package)
  print(f"{package}: {actual}")
  assert actual == wanted, f"{package}: expected {wanted}, got {actual}"
 PY
 â
 python - <<'PY'
 import torch
 import vllm
 import vllm._C_stable_libtorch as vllm_native
 from vllm.platforms import current_platform
 â
 print("vLLM:", vllm.__version__)
 print("PyTorch:", torch.__version__)
 print("CUDA Runtime:", torch.version.cuda)
 print("GPU count:", torch.cuda.device_count())
 print("vLLM platform:", current_platform.device_type)
 print("native extension:", vllm_native.__file__)
 â
 assert vllm.__version__ == "0.27.1"
 assert torch.version.cuda == "13.0"
 assert torch.cuda.is_available()
 assert torch.cuda.device_count() == 2
 assert current_platform.is_cuda()
 PY
vLLM 0.27.1 å·²ç»ä½¿ç¨ _C_stable_libtorchãè䏿¯ä»¥åçç import vllm._C å¯è½ç´æ¥æ¥æ¨¡åä¸åå¨ï¼ä¸è½æ®æ¤å¤æ CUDA å®è£
失败ã
6. æç»å¯å¨é ç½®ï¼128KãTP=2ãå¾çåè§é¢ <æªå¯ç¨ Prefix Cache è· MTP>
6.1 .env ä¸ API Key
å çæå¯é¥ï¼
 openssl rand -hex 32
ç¶åå¨é¡¹ç®ç®å½å建 .envï¼
 cd /home/<USER>/projects/vllm-qwen38
 install -m 600 /dev/null .env
 â
 cat > .env <<'EOF'
 MODEL_DIR=/data/models/hf/Qwen3.8-27B-FP8
 VLLM_INTERNAL_API_KEY=<API_KEY>
 CUDA_VISIBLE_DEVICES=0,1
 HF_HOME=/data/cache/qwen38/huggingface
 HF_HUB_CACHE=/data/cache/qwen38/huggingface/hub
 TORCHINDUCTOR_CACHE_DIR=/data/cache/qwen38/torchinductor
 VLLM_CACHE_ROOT=/data/cache/qwen38/vllm
 PYTHONUNBUFFERED=1
 EOF
 â
 chmod 600 .env
 grep -qxF '.env' .gitignore 2>/dev/null || echo '.env' >> .gitignore
VLLM_INTERNAL_API_KEY æ¯é¨ç½²ä¾§ç§æåéãå¯å¨èæ¬ä¼æå®æ å°ä¸º vLLM è¯å«ç VLLM_API_KEYï¼ç¶å忶坼åºç§æåéãè¿æ ·æ¢ä¸ä¼æ Key æ¾è¿å½ä»¤è¡ï¼ä¹ä¸ä¼è§¦å vLLM 对æªç¥ VLLM_* ç¯å¢åéçæ£æ¥ã
6.2 宿´å¯å¨èæ¬
æä»¶è·¯å¾ï¼
 /home/<USER>/projects/vllm-qwen38/start-qwen38-main.sh
宿´å 容ï¼
 #!/usr/bin/env bash
 set -euo pipefail
 â
 PROJECT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
 ENV_FILE="$PROJECT_DIR/.env"
 export PATH="$PROJECT_DIR/.venv/bin:$PATH"
 â
 if [[ ! -r "$ENV_FILE" ]]; then
  echo "Missing or unreadable environment file: $ENV_FILE" >&2
  exit 1
 fi
 â
 set -a
 source "$ENV_FILE"
 set +a
 â
 : "${MODEL_DIR:?MODEL_DIR is required}"
 : "${VLLM_INTERNAL_API_KEY:?VLLM_INTERNAL_API_KEY is required}"
 export VLLM_API_KEY="$VLLM_INTERNAL_API_KEY"
 unset VLLM_INTERNAL_API_KEY
 â
 cd "$PROJECT_DIR"
 â
 exec "$PROJECT_DIR/.venv/bin/vllm" serve "$MODEL_DIR" \
  --host 0.0.0.0 \
  --port 9999 \
  --served-model-name qwen3.8-27b-fp8 qwen-27b-prod \
  --tensor-parallel-size 2 \
  --max-model-len 131072 \
  --gpu-memory-utilization 0.90 \
  --max-num-seqs 4 \
  --max-num-batched-tokens 8192 \
  --enable-chunked-prefill \
  --kv-cache-dtype fp8 \
  --reasoning-parser qwen3 \
  --enable-auto-tool-choice \
  --tool-call-parser qwen3_coder \
  --mm-encoder-tp-mode data \
  --mm-processor-cache-type shm \
  --limit-mm-per-prompt '{"image":10,"video":{"count":1,"num_frames":32}}' \
  --media-io-kwargs '{"video":{"num_frames":32}}' \
  --disable-custom-all-reduce
è½çåæ£æ¥ Shell è¯æ³ï¼
 cd /home/<USER>/projects/vllm-qwen38
 chmod 750 start-qwen38-main.sh
 bash -n start-qwen38-main.sh
6.3 è¿äºåæ°è§£å³ä»ä¹é®é¢
| åæ° | å½åå¼ | å«ä¹ |
|---|---|---|
--tensor-parallel-size | 2 | æéå计ç®åå°ä¸¤å¼ GPUï¼å®ä¸æ¯å¹¶åæ°ã |
--max-model-len | 131072 | æå¡è¾å ¥ä¸è¾åºæ»é¿åº¦ä¸é 128Kã |
--gpu-memory-utilization | 0.90 | æ¯ä¸ª Worker çç®æ æ¾åå ç¨æ¯ä¾ï¼ä»ä¿ç约 10% ä½éã |
--max-num-seqs | 4 | è°åº¦å¨åæ¶å¤ççæ´»è·åºåä¸éï¼ä¸æ¯ HTTP è¿æ¥ä¸éã |
--max-num-batched-tokens | 8192 | åè½®è°åº¦ Token é¢ç®ã |
--enable-chunked-prefill | å¼å¯ | é¿ Prompt ååé¢å¡«å ï¼é¿å å个é¿è¯·æ±é¿æç¬å è°åº¦å¨ã |
--kv-cache-dtype | fp8 | KV Cache ä½¿ç¨ FP8ï¼éä½é¿ä¸ä¸æç¼åæ¾åï¼ä¸çåäºæé FP8ã |
--reasoning-parser | qwen3 | æ reasoning ä¸æç» content å离ã |
--enable-auto-tool-choice | å¼å¯ | å
许 tool_choice=autoã |
--tool-call-parser | qwen3_coder | è§£æ OpenAI å
¼å®¹ tool_callsï¼Agent ä¸çº¿åä»éä¸é¡¹éªè¯ã |
--mm-encoder-tp-mode | data | 夿¨¡æç¼ç å¨ææ°æ®ç»´åº¦ä½¿ç¨ TP Workerã |
--mm-processor-cache-type | shm | å¤è¿ç¨éè¿å ±äº«å åå¤ç¨åªä½é¢å¤çç»æã |
--limit-mm-per-prompt | 10 å¾ã1 è§é¢ã32 帧 | æå¡ä¾§è®¸å¯ä¸éï¼ä¸ä»£è¡¨å·²ç»å®ææéç¨³å®æ§éªè¯ã |
--disable-custom-all-reduce | å¼å¯ | ä¸ä¾èµå½ååå¡ P2Pï¼èªå®ä¹ all-reduce åéå° NCCLã |
æé FP8 ç±æ¨¡å config.json èªå¨è¯å«ï¼æä»¥æ²¡ææå·¥æ·»å --quantization fp8ã
å¾çæå¤ 10 å¼ æ¯è¿å¥æå¡çé¨ç½²éé¢ï¼ä¸æ¯ Qwen 宿¹å®£ç§°çåºå®ç¡¬ä¸éãè§é¢éå¶ä¸ºæ¯è¯·æ± 1 个ãæå¤ 32 帧ï¼ä¹æ¯ä¸ºäºæ§å¶ä¸ä¸æåæ¾åå³°å¼ã
7. systemd æç®¡ä¸å¯å¨
å建 /etc/systemd/system/qwen38-main.serviceï¼
 [Unit]
 Description=Qwen3.8 27B FP8 vLLM Service
 Wants=network-online.target
 After=network-online.target
 â
 [Service]
 Type=simple
 User=<USER>
 Group=<USER>
 WorkingDirectory=/home/<USER>/projects/vllm-qwen38
 ExecStart=/home/<USER>/projects/vllm-qwen38/start-qwen38-main.sh
 Restart=on-failure
 RestartSec=10
 TimeoutStartSec=900
 TimeoutStopSec=120
 KillMode=mixed
 LimitNOFILE=1048576
 TasksMax=infinity
 â
 [Install]
 WantedBy=multi-user.target
å 载并å¯å¨ï¼
 # éæ°å è½½ unitï¼è®¾ç½®å¼æºèªå¯å¹¶è·è¸ªå¯å¨æ¥å¿
 sudo systemctl daemon-reload
 sudo systemctl enable --now qwen38-main
 sudo systemctl status qwen38-main --no-pager
 journalctl -u qwen38-main -f
å¯å¨æåè³å°è¦çå°ï¼
 Application startup complete
 Starting vLLM server on http://0.0.0.0:9999
8. API éªæ¶ï¼é´æã模ååè¡¨åææ¬è¯·æ±
8.1 å¥åº·ä¸é´æ
 cd /home/<USER>/projects/vllm-qwen38
 set -a
 source .env
 set +a
 â
 curl -i http://127.0.0.1:9999/health \
  -H "Authorization: Bearer $VLLM_INTERNAL_API_KEY"
 â
 curl http://127.0.0.1:9999/v1/models \
  -H "Authorization: Bearer $VLLM_INTERNAL_API_KEY"
 â
 # ä¸å¸¦ Key çæ¨¡å请æ±åºè¿å 401
 curl -i http://127.0.0.1:9999/v1/models
模åå表åºå å«ä¸¤ä¸ª served nameï¼
 qwen3.8-27b-fp8
 qwen-27b-prod
8.2 ææ¬è¯·æ±
 curl http://127.0.0.1:9999/v1/chat/completions \
  -H "Authorization: Bearer $VLLM_INTERNAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
   "model": "qwen3.8-27b-fp8",
   "messages": [
   {"role": "user", "content": "请åªåå¤ï¼Qwen3.8 æå¡æ£å¸¸ã"}
  ],
   "max_tokens": 64,
   "temperature": 0.7,
   "top_p": 0.8,
   "top_k": 20,
   "presence_penalty": 1.5,
   "chat_template_kwargs": {
    "enable_thinking": false
  }
 }'
8.3 å¾çåè§é¢è¯·æ±
æ¿çµèçClaudeCodeæä»¶å»æµè¯äºå¾çä¸ä¸
9. 2K åºçº¿ä¸è¿ 128K åæµ
为äºè§å¯çº¯æå¡æ§è½ï¼æçåæµç»ä¸å ³é thinkingãè¿æ ·è¾åºé¿åº¦æ´å¯æ§ï¼ä¹æ´éåæ¯è¾ Prefix Cache ä¸ MTPã
9.1 2K è¾å ¥ã512 è¾åºã4 å¹¶å
 cd /home/<USER>/projects/vllm-qwen38
 source .venv/bin/activate
 â
 export HF_HUB_OFFLINE=1
 export TRANSFORMERS_OFFLINE=1
 set -a
 source .env
 set +a
 â
 vllm bench serve \
  --backend openai-chat \
  --base-url http://127.0.0.1:9999 \
  --endpoint /v1/chat/completions \
  --model /data/models/hf/Qwen3.8-27B-FP8 \
  --tokenizer /data/models/hf/Qwen3.8-27B-FP8 \
  --served-model-name qwen3.8-27b-fp8 \
  --dataset-name random \
  --random-input-len 2048 \
  --random-output-len 512 \
  --num-prompts 100 \
  --request-rate 4 \
  --max-concurrency 4 \
  --header "Authorization=Bearer $VLLM_INTERNAL_API_KEY" \
  --extra-body '{"chat_template_kwargs":{"enable_thinking":false}}' \
  --save-result \
  --result-dir /data/artifacts/qwen38
9.2 è¿ 128K åå¹¶å
è¾å ¥ä½¿ç¨ 126,976 Tokenï¼è¾åºä½¿ç¨ 2,048 Tokenï¼æ»è®¡ 129,024ï¼ä¸ºè天模æ¿ä¿ç约 2,048 Token ä½éã
 cd /home/<USER>/projects/vllm-qwen38
 source .venv/bin/activate
 â
 export HF_HUB_OFFLINE=1
 export TRANSFORMERS_OFFLINE=1
 set -a
 source .env
 set +a
 â
 vllm bench serve \
  --backend openai-chat \
  --base-url http://127.0.0.1:9999 \
  --endpoint /v1/chat/completions \
  --model /data/models/hf/Qwen3.8-27B-FP8 \
  --tokenizer /data/models/hf/Qwen3.8-27B-FP8 \
  --served-model-name qwen3.8-27b-fp8 \
  --dataset-name random \
  --random-input-len 126976 \
  --random-output-len 2048 \
  --num-prompts 1 \
  --request-rate 1 \
  --max-concurrency 1 \
  --ignore-eos \
  --header "Authorization=Bearer $VLLM_INTERNAL_API_KEY" \
  --extra-body '{"chat_template_kwargs":{"enable_thinking":false}}' \
  --save-result \
  --result-dir /data/artifacts/qwen38 \
  --result-filename qwen38-near-128k-single.json
9.3 è¿ 128K åå¹¶å
åªæåå¹¶åéè¿ååè¿è¡ï¼
 cd /home/<USER>/projects/vllm-qwen38
 source .venv/bin/activate
 â
 export HF_HUB_OFFLINE=1
 export TRANSFORMERS_OFFLINE=1
 set -a
 source .env
 set +a
 â
 vllm bench serve \
  --backend openai-chat \
  --base-url http://127.0.0.1:9999 \
  --endpoint /v1/chat/completions \
  --model /data/models/hf/Qwen3.8-27B-FP8 \
  --tokenizer /data/models/hf/Qwen3.8-27B-FP8 \
  --served-model-name qwen3.8-27b-fp8 \
  --dataset-name random \
  --random-input-len 126976 \
  --random-output-len 2048 \
  --num-prompts 4 \
  --request-rate inf \
  --max-concurrency 4 \
  --ignore-eos \
  --header "Authorization=Bearer $VLLM_INTERNAL_API_KEY" \
  --extra-body '{"chat_template_kwargs":{"enable_thinking":false}}' \
  --save-result \
  --result-dir /data/artifacts/qwen38 \
  --result-filename qwen38-near-128k-concurrency4.json
9.4 宿µæ±æ»
| åºæ¯ | æå/失败 | Output tok/s | Mean TTFT | Mean TPOT |
|---|---|---|---|---|
| 2K/512ï¼4 å¹¶ååºçº¿ | 100/0 | 133.06 | 1080.70 ms | 27.95 ms |
| 126976/2048ï¼åå¹¶å | 1/0 | 18.55 | 42252.54 ms | 32.80 ms |
| 126976/2048ï¼4 å¹¶å | 4/0 | 34.29 | 105883.49 ms | 64.61 ms |
é¿ä¸ä¸æç»æå¾ç´è§ï¼4 个请æ±é½è½å®æï¼ä½ TTFT å TPOT 齿¾èä¸åã
è¿ 128K åå¹¶åæé´ï¼ä¸¤å¼ GPU åè¾¾å° 100% å©ç¨çï¼æ¾å约为 43.2/48.0GiB å 42.9/48.0GiBã
10. Prefix Cache ä¸ MTPï¼å嫿µè¯ï¼åèèç»å
10.1 Prefix Cache
å¨ç¨³å®èæ¬ä¸å¢å ï¼
  --enable-prefix-caching \
ç¶åéå¯å¹¶æ ¸å¯¹æ¥å¿ï¼
 sudo systemctl restart qwen38-main
 journalctl -u qwen38-main -b --no-pager | \
  grep -Ei 'prefix|cache|Application startup complete'
ç¸å 2K/512 éæºæ°æ®çç»ææ¯ï¼
| é ç½® | æå/失败 | Output tok/s | Mean TTFT | Mean TPOT |
|---|---|---|---|---|
| æ Prefix Cache | 100/0 | 133.06 | 1080.70 ms | 27.95 ms |
| å¼å¯ Prefix Cache | 100/0 | 132.74 | 1087.93 ms | 28.01 ms |
è¿å¹¶ä¸ä»£è¡¨ Prefix Cache æ æãrandom æ°æ®éå 乿²¡æéå¤é¿åç¼ï¼èªç¶æ æ³ä½ç°ç¼åå½ä¸æ¶çã
10.2 Prefix Cache + MTP=1/2/3 ç»åå®éª
ä¸è½® MTP 宿ºæªå¾å¯¹åºçæ¯ Prefix Cache ä¿æå¼å¯ æ¶çç»åå®éªï¼è䏿¯åç¬ MTPãå æ¤ï¼ä¸é¢çæ§è½å·®å¼ä¸è½å ¨é¨å½å äº MTPã
å¯å¨èæ¬åæ¶å¢å 两è¡ï¼
  --enable-prefix-caching \
  --speculative-config '{"method":"mtp","num_speculative_tokens":2}' \
æ 2 å嫿¹æ 1ã2ã3ï¼æ¯è½®é½é坿å¡ã确认 MTP é
置已å è½½ï¼åè¿è¡å®å
¨ç¸åç 2K/512 åæµã
æ¥å¿æ£æ¥ï¼
 sudo systemctl restart qwen38-main
 journalctl -u qwen38-main -b --no-pager | \
  grep -Ei 'speculative|mtp|num_speculative_tokens|Application startup complete'
å®éªç»æï¼
| é ç½® | æå/失败 | Output tok/s | Mean TTFT | Mean TPOT | æ¥åç |
|---|---|---|---|---|---|
| æ®éè§£ç åºçº¿ | 100/0 | 133.06 | 1080.70 ms | 27.95 ms | ä¸éç¨ |
| Prefix + MTP=1 | 100/0 | 145.91 | 177.61 ms | 27.05 ms | æ¬è½®æªè®°å½ |
| Prefix + MTP=2 | 100/0 | 184.94 | 598.32 ms | 20.17 ms | 65.73% |
| Prefix + MTP=3 | 100/0 | 194.79 | 637.98 ms | 19.05 ms | 52.62% |
Prefix + MTP=1
Prefix + MTP=2
Prefix + MTP=3
è¿ç»æ°æ®ç²ç¥è¯´æ speculative decoding å¨å½åç¯å¢ä¸ç¡®å®è¿è¡è¿ï¼ä¹è¯´æ num_speculative_tokens 䏿¯è¶å¤§æ¥åçå°±è¶é«ã
11. éå°çå 个é®é¢
| ç°è±¡ | åå | å¤ç |
|---|---|---|
No such file or directory: 'ninja' | FlashInfer JIT éè¦ ninjaï¼systemd PATH 䏿¾ä¸å° | å®è£
ninja-buildï¼å¹¶ä¿çèæ¬ä¸ç .venv/bin PATH |
Using default W8A8 Block FP8 kernel config | 没æå¹é å½å GPU ä¸ç©éµå½¢ç¶çé¢è°ä¼é ç½® | è¿æ¯æ§è½è¦åï¼ä¸æ¯å¯å¨å¤±è´¥ |
ç¼ºå° ninja æ¶å¯æ§è¡ï¼
 sudo apt update
 sudo apt install -y ninja-build
 â
 which ninja
 ninja --version
 sudo systemctl restart qwen38-main
12. æç»ç»è®º
Qwen3.8-27B-FP8 å¨è¿å¥å GPU ç¯å¢ä¸å·²ç»å®æäºä»ä¸è½½å° APIãä» 2K å°è¿ 128Kã仿®éè§£ç å° MTP ç宿´é¨ç½²é¾è·¯ã
ææç»ä¿ççç产åºçº¿æ¯ï¼
- vLLM 0.27.1 ä¸ cu130 åºå®çæ¬ç¯å¢ã
- TP=2ã128Kã4 æ´»è·åºåãFP8 KV CacheãChunked Prefillã
- systemd æç®¡ãAPI Key é´æåç¨³å® served aliasã
- é»è®¤ä¸å¯ç¨ MTPã
- å¼å¯ Prefix Cache éå¤åç¼ä¸å¡ã
æå¼å¾ä¿ççç»éªå¹¶ä¸æ¯æä¸ªååæ°åï¼èæ¯æç¨³å®åºçº¿åå®éªåæ°åå¼ãåªè¦ç®å½ãç¯å¢ãèæ¬ãæå¡ååæµç»æé½è½ç¬ç«åéï¼åç»å级 vLLMãæ©å¤§ä¸ä¸ææç»§ç»è° MTPï¼å°±ä¸ä¼æå·²ç»å¯ç¨çæå¡ä¸èµ·ç ´åã
Aitishiku.com