ERNIE-5.5-Flash-Base 部署实操:两条官方引擎路径与一份参数不可移植清单
百度在 2026-11-05 放出 ERNIE-5.5-Flash-Base 权重,SGLang 与 vLLM 各给了一条官方部署路径。到 11-10,两条路径的一手文档都已可查:sgl-project/sglang 主干有 ERNIE-5.5-Flash 的 cookbook 与命令生成器,baidu/vLLM-ERNIE 在 11-10 05:10 仍有提交。本文只处理一件事:把这两条路径跑起来,并逐项标清哪些参数不能从一个栈抄到另一个栈。
三条结论先行。
- 安装形态不通用。vLLM 路径必须额外装一个 git 插件,且插件的
pyproject.toml把vllm硬锁在0.32.0;SGLang 路径给的是专用预构建镜像lmsysorg/sglang:dev-ernie-55-flash,或--prerelease=allow的 pip 安装。PyPI 上vllm最新为0.33.0、vllm-ernie查询返回 404,这两点决定了「照着通用 vLLM 教程装」会失败。 - 参数命名空间不通用。同一个功能在两栈里既有异名(分辨率解析器
ernie5/ernie55),也有同名异值(ECHO 两步推理在 vLLM 写2、在 SGLang 写3),还有大量单边独有参数。抄错多数不会报参数错误,而是「服务起来了、结果不对」。 - 能力声明不等于默认配置。两份文档都写支持 1,048,576 token 上下文,但 vLLM README 明确 80 GB 卡跑不到 1M、最多 262,144,SGLang cookbook 要求把并发降到个位数并调低 CUDA graph 批量。直接照「1M」二字填参数只会 OOM。
全文命令与数字依据官方仓库、官方博客、官方 cookbook 与 PyPI 结构化数据整理,未在对应 GPU 环境实测;需要落地的步骤都标了验证方法,建议先在小规模环境测通再上生产。
一、材料清单与时间线
| 材料 | 位置 | 时间 | 用途 |
|---|---|---|---|
| ERNIE 5.5 Flash Base 发布博客 | ernie.baidu.com/release/ernie-5-5-flash-base/ |
2026-11-05 | 模型形态、权重、许可、BOS 要求 |
baidu/vLLM-ERNIE README + pyproject.toml |
GitHub 仓库 main 分支 | 首次提交 2026-10-30,最新 2026-11-10 05:10(#8) | vLLM 路径全部命令、并行矩阵、排错 |
插件源码 __init__.py / models/ernie5_5/__init__.py / config.py |
同仓库 src/vllm_ernie/ |
同上 | 注册机制、架构名、配置默认值 |
SGLang cookbook ERNIE-5.5-Flash.mdx |
sgl-project/sglang 的 docs/cookbook/autoregressive/Baidu/ |
主干当前版本 | SGLang 路径、硬件矩阵、进阶用法 |
命令生成器 ernie-5.5-flash.jsx |
同仓库 docs/src/snippets/configs/baidu/ |
主干当前版本 | 每个硬件格子的完整启动参数 |
PyPI JSON:vllm / sglang / vllm-ernie |
pypi.org/pypi/<pkg>/json |
2026-11-10 查询 | 版本锁与发布时间核实 |
| 魔乐社区模型卡 | modelers.cn/models/PaddlePaddle/ERNIE-5.5-Flash-Base |
— | 容器启动方式与 curl 示例【交叉】 |
【官方】模型发布日为 11-05,插件仓库在模型发布前(10-30)就已开始提交,11-04 补了 attention TP、11-03 补了 128×128 block FP8 checkpoint、11-10 补了 DSpark bundled load 与 Python chat template。【交叉】两份部署文档都把「ERNIE-5.5-Flash(Chat)」标为 Coming soon,当前可下载的只有 Base 权重。本文讨论的全部是 Base 权重,涉及 reasoning / tool-call / DSpark 的配置只作对照,不能用于当前权重。
一个容易踩空的前提:模型许可与工具许可不是一回事。官方博客写模型权重采用 ERNIE 5.5 Flash Base Model License Agreement v1.0;vllm-ernie 插件仓库与 SGLang 是 Apache-2.0。cookbook 里「released under the Apache-2.0 license」描述的是模型架构说明段落,不等于权重许可。商用部署要先读模型许可原文。【官方】
二、两条路径总览
| 维度 | vLLM + 官方插件 | SGLang 预构建镜像 |
|---|---|---|
| 安装 | uv pip install vllm==0.32.0 + git+https://github.com/baidu/vLLM-ERNIE.git |
docker pull lmsysorg/sglang:dev-ernie-55-flash,或 uv pip install --prerelease=allow sglang |
| 版本约束 | 插件 pyproject.toml 硬锁 vllm==0.32.0;requires-python >=3.10 |
无显式版本锁,靠镜像 tag;PyPI 主线 0.5.23,requires-python >=3.11 |
| 启动命令 | vllm serve baidu/ERNIE-5.5-Flash-Base ... |
sglang serve --model-path baidu/ERNIE-5.5-Flash-Base ... |
| 默认端口 | 8000 | 30000 |
| 并行主推 | --data-parallel-size N --enable-expert-parallel |
--tp N,高吞吐再加 --attn-dp-size N |
| KV cache dtype | --kv-cache-dtype fp8(auto 为 BF16) |
默认 fp8_e4m3,另一合法值 bfloat16 |
| 上下文参数 | --max-model-len |
--context-length |
| 分辨率解析器 | --reasoning-parser ernie5 --tool-call-parser ernie5 |
--reasoning-parser ernie55 --tool-call-parser ernie55 |
| 请求端点 | /v1/completions |
/v1/completions |
| 硬件范围 | README 明写 NVIDIA GPUs only | 命令生成器只列 B300 / GB300 / B200 / GB200 / H100 |
| Base 权重支持 | 已支持 | 已支持 |

两条路径的权重完全一致:FP8 版 baidu/ERNIE-5.5-Flash-Base,BF16 版 baidu/ERNIE-5.5-Flash-Base-BF16。vLLM README 另给了 VLLM_USE_MODELSCOPE=True 从魔搭下载,仓库名在两边相同。【官方】两边都只服务 Base 的 completions,Chat 版权重未发布。
三、第一关:装得上——显存矩阵与验证状态
官方给出的权重体积是 FP8 约 280 GB、BF16 约 560 GB。两份文档的 GPU 数量表一致,SGLang 补了具体型号与验证状态。
| 单卡显存 | 对应型号【官方】 | FP8 最少卡数 | BF16 最少卡数 | 验证状态【官方】 |
|---|---|---|---|---|
| 288 GB | B300 / GB300 | 2 | 4 | 单节点 FP8 已验证;B300 的 BF16 已验证 |
| 192 GB | B200 / GB200 | 4 | 8(GB200 为 2 trays × 4) | 单节点 FP8 已验证;其余 BF16 为预算推算 |
| 80 GB | H100 | 8 | 2 节点 × 8 | 单节点 FP8 已验证 |
【官方】SGLang cookbook 原话:单节点 FP8 配方在 B300、GB300、B200、GB200、H100 上验证过,BF16 只有 B300 验证过,其他 BF16 配方「follow from the same memory budget and are not yet verified」。这一句必须和表格一起读——表格里有若干格是按内存预算推出来的,不是实测结论。vLLM README 只给容量表,没有逐格验证说明。【未披露】
【推算】把权重体积除以卡数:FP8 280 ÷ 2 = 140 GB/卡,BF16 560 ÷ 4 = 140 GB/卡,两行落在同一个每卡权重预算上;80 GB 卡跑 FP8 需要 8 张(640 GB 总量)才能同时容纳 280 GB 权重、KV cache 与激活。假设是权重均匀切分、忽略并行副本与临时缓冲;实际可用余量还要扣掉 KV cache 和 prefill 激活,所以官方才要求 80 GB 卡把 --gpu-memory-utilization 提到 0.93。该换算只用于理解表格结构,不能当部署规格引用。
显存不足时的官方处理顺序:先换精度(FP8),再降上下文长度,最后才加卡。vLLM README 给了一个「BF16 硬挤单节点 4 卡」的降级配方,代价是 KV cache 空间很小:
# vLLM:BF16 单节点 4 卡(官方标注 KV cache 余量很小)
--gpu-memory-utilization 0.95 \
--max-model-len 65536 \
--max-num-seqs 16 \
--max-num-batched-tokens 8192 \
--max-cudagraph-capture-size 512
【官方】这一组参数是「能起来但跑不长」的典型:上下文从 131072 砍到 65536,并发从默认降到 16。把这四个值抄到 FP8 8 卡配置上不会报错,只会白白限制吞吐。
四、第二关 A:起得来——vLLM 插件路径
4.1 完整启动命令
以下为官方 README 的 4 卡 FP8 配方,原样保留参数:
uv venv --python 3.12
source .venv/bin/activate
uv pip install vllm==0.32.0
uv pip install git+https://github.com/baidu/vLLM-ERNIE.git
export VLLM_ENGINE_READY_TIMEOUT_S=3600
vllm serve baidu/ERNIE-5.5-Flash-Base \
--host 0.0.0.0 \
--port 8000 \
--data-parallel-size 4 \
--enable-expert-parallel \
--moe-backend humming \
--kv-cache-dtype fp8 \
--max-model-len 131072 \
--speculative-config '{"method":"mtp","num_speculative_tokens":2}'
参数落点:
| 参数 | 作用【官方】 | 边界 |
|---|---|---|
--data-parallel-size 4 --enable-expert-parallel |
attention 走数据并行、MoE 专家并行 | README 称这样 KV cache 最多、吞吐最高 |
--tensor-parallel-size 2/4/8 |
attention 张量并行,低并发降延迟 | 必须整除 8;单 KV head 在每个 rank 复制,KV cache 更少 |
--moe-backend humming |
支持 SiTU + FP8 权重 | 仅 Blackwell;Hopper 必须去掉,保留 vLLM 默认 MoE kernel |
--kv-cache-dtype fp8 |
KV cache 以 FP8 存 | auto 保持 BF16 |
--speculative-config |
打开 ECHO(走 MTP 路径) | num_speculative_tokens 可取 1 / 2 / 3;去掉该项即关闭 draft |
VLLM_ENGINE_READY_TIMEOUT_S=3600 |
放宽引擎就绪超时 | 官方每条命令都设,权重加载耗时长 |
【官方】命令默认绑 0.0.0.0 且无认证,README 明确要求加 --api-key <key> 或改绑 127.0.0.1。生产环境不要把这条命令原样暴露到不受信任网络。
4.2 插件为什么必须装、装了为什么可能没生效
pyproject.toml 里的注册入口:
[project]
name = "vllm-ernie"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = ["vllm==0.32.0"]
[project.entry-points."vllm.general_plugins"]
ernie = "vllm_ernie:register"
register() 在每个 vLLM 进程里执行,最终把三个架构名注册进 ModelRegistry,并打补丁:
# src/vllm_ernie/models/ernie5_5/__init__.py(节选)
ARCHITECTURES = {
"Ernie5_5_MoeForCausalLM": "Ernie5_5ForCausalLM",
"Ernie5_5MoeMTPModel": "Ernie5_5MTP",
"Ernie5_5_MoeDSparkDraftModel": "Ernie5_5DSparkForCausalLM",
}
def register() -> None:
from vllm import ModelRegistry
for arch, cls_name in ARCHITECTURES.items():
if arch not in ModelRegistry.get_supported_archs():
ModelRegistry.register_model(arch, f"{_MODEL_MODULE}:{cls_name}")
from .patches import apply_patches
apply_patches()
由此得到四个高频失败点,全部可用只读命令核实:
| 失败点 | 证据 | 症状 |
|---|---|---|
| 未装插件 | PyPI vllm-ernie 返回 404,只能 git+ 安装 |
启动报 Model architectures ['Ernie5_5_MoeForCausalLM'] are not supported |
| 版本不对 | 插件锁 vllm==0.32.0;PyPI vllm 最新 0.33.0(0.32.0 上传于 2026-10-18) |
装了最新 vLLM 后插件行为未在文档中说明【未披露】 |
| 插件被环境变量禁用 | README:VLLM_PLUGINS="" 禁用全部,设了值就必须含 ernie |
与「未装插件」同一条报错 |
| Python 版本三处口径 | 插件 >=3.10;vLLM 0.32.0 的 wheel 元数据 <3.15,>=3.11;README 命令用 3.12 |
低于 3.11 时 vLLM 装不上 |
【交叉】PyPI 结构化数据与仓库 README 一致指向「必须显式锁 0.32.0」。pip install vllm 不带版本会拿到 0.33.0,而插件依赖声明不允许该版本共存——这是「照通用教程装」最常见的断点。
只读核验(不启动服务、不下载权重):
# check_vllm_ernie.py:只读探测,依据官方接口整理,未在目标机器实测
import importlib.metadata as md
import os
print("python vllm version :", md.version("vllm"))
try:
print("plugin dist version:", md.version("vllm-ernie"))
except md.PackageNotFoundError:
print("plugin dist version: NOT INSTALLED (git+ install needed)")
eps = md.entry_points(group="vllm.general_plugins")
print("general_plugins :", [e.name for e in eps])
print("VLLM_PLUGINS env :", repr(os.environ.get("VLLM_PLUGINS", "<unset>")))
from vllm import ModelRegistry
for arch in ("Ernie5_5_MoeForCausalLM", "Ernie5_5MoeMTPModel"):
print(f"{arch:32s}:", arch in ModelRegistry.get_supported_archs())
这段脚本读的是本地安装状态与注册表,不触发模型加载,也不需要 GPU。把它放在 vllm serve 之前跑一次,可以把「插件没装」和「插件被禁用」两类问题在启动前分开。
五、第二关 B:起得来——SGLang 镜像路径
5.1 安装与容器启动
# 方式 A:官方预构建镜像
docker pull lmsysorg/sglang:dev-ernie-55-flash
# 方式 B:pip 主线(cookbook 原文)
pip install --upgrade pip
pip install uv
uv pip install --prerelease=allow sglang
【交叉】魔乐模型卡给出的容器启动方式包含 --gpus all --network host --ipc host 与 HF cache 挂载:
docker run -d -it --name ernie55 \
--gpus all \
--network host \
--ipc host \
-v ~/.cache/huggingface:/root/.cache/huggingface \
lmsysorg/sglang:dev-ernie-55-flash
【推断】存在专用 dev-ernie-55-flash 镜像、而 pip 安装只写 --prerelease=allow sglang,说明 ERNIE 5.5 的运行时改动可能尚未全部进入 PyPI 主线包;PyPI 查询到的主线版本是 0.5.23。两种安装方式不要混着配参数,尤其是把镜像里才有的后端行为写进 pip 环境的启动命令。官方文档未明示两者能力边界,此处标【推断】并建议以实际 --help 输出为准。
5.2 启动命令
命令生成器给 4 卡 FP8 高吞吐配方如下(低延迟配方把 --attn-dp-size 换成 ECHO 的四个投机解码参数):
sglang serve \
--model-path baidu/ERNIE-5.5-Flash-Base \
--tp 4 \
--attn-dp-size 4 \
--context-length 131072 \
--max-running-requests 256 \
--host 0.0.0.0 \
--port 30000
# 低延迟配方(命令生成器 flags,ECHO 两步)
--speculative-algorithm EAGLE \
--speculative-num-steps 2 \
--speculative-eagle-topk 1 \
--speculative-num-draft-tokens 3
【官方】cookbook 明确模型会自动设置 ernie55 attention backend、--page-size 256、--swa-full-tokens-ratio 0.1,并把 --kv-cache-dtype 默认设为 fp8_e4m3;该参数只有 fp8_e4m3 和 bfloat16 两个合法值。这三项不需要手写,手写成 vLLM 的 fp8 反而是非法值。
并行约束有两条硬限制:
| 约束 | 官方口径 | 违反后果 |
|---|---|---|
| attention TP 相关参数必须整除 8 | tp / attn-dp-size / attn-cp-size 对应输出组数 8 |
配置不成立 |
DeepEP 需 --ep 4 及以上 |
--ep 2 时每 rank 256 个专家,超出 DeepEP 单 rank 上限 |
启动或运行期异常 |
【官方】--attn-dp-size 等于 --tp 时 attention TP 为 1,用于高吞吐;低延迟配方用普通 TP。BF16 在 H100 上是例外:--tp 16 --attn-dp-size 2,让 attention TP 保持 8。这组数字不能与 vLLM 的 --data-parallel-size 混用——两者名字接近,切分对象不同。
六、参数不可移植清单
这是两条路径最容易出错的地方。把官方两边文档并排后,冲突分三类。
6.1 异名同义
| 功能 | vLLM | SGLang | 抄错后的表现 |
|---|---|---|---|
| 启动入口 | vllm serve <repo> |
sglang serve --model-path <repo> |
参数无法解析 |
| 端口 | --port 8000 |
--port 30000 |
请求打空 |
| 上下文长度 | --max-model-len 131072 |
--context-length 131072 |
未知参数 |
| 并发上限 | --max-num-seqs |
--max-running-requests |
未知参数 |
| 分辨率解析器 | --reasoning-parser ernie5 |
--reasoning-parser ernie55 |
解析器找不到 |
| 工具调用解析器 | --tool-call-parser ernie5 |
--tool-call-parser ernie55 |
解析器找不到 |
| 投机解码开关 | --speculative-config '{"method":"mtp",...}' |
--speculative-algorithm EAGLE |
未知参数 |
| KV 分层缓存 | --kv-transfer-config SimpleCPUOffloadConnector |
--enable-hierarchical-cache --hicache-ratio 2 |
未知参数 |
| PD 分离路由 | MooncakeConnector + vllm-router==0.1.16 |
cookbook 的 PD Disagg(Mooncake) | 组件不通用 |
【官方】解析器名 ernie5 与 ernie55 的差异是文档可核验的事实,且两者都只对 Coming soon 的 ERNIE-5.5-Flash 生效;Base 权重没有 chat / reasoning / tool-call 训练,cookbook 明确写 --reasoning-parser 与 --tool-call-parser 对 Base 不适用。当前把这两个参数加到 Base 服务上属于无效配置。
6.2 同名异值
| 概念 | vLLM 写法 | SGLang 写法 | 差异来源 |
|---|---|---|---|
| ECHO 两步推理 | "num_speculative_tokens":2 |
--speculative-num-steps 2 --speculative-num-draft-tokens 3 |
SGLang 的 draft tokens = steps + 1(默认 1、1、2) |
| KV cache 量化 | --kv-cache-dtype fp8 |
--kv-cache-dtype fp8_e4m3 |
同一概念不同枚举值 |
| 精度「auto / BF16」 | auto 保持 BF16 |
另一合法值 bfloat16 |
枚举名不同 |
| 1M 上下文降并发 | 降 --max-num-seqs + --gpu-memory-utilization 0.85 |
降 --max-running-requests 至个位数 + --cuda-graph-max-bs-decode |
两套显存控制维度 |
最关键的是第一行。想跑「两步 ECHO」,vLLM 写 2,SGLang 的 draft tokens 要写 3。把 2 从 vLLM 命令抄到 SGLang 的 --speculative-num-draft-tokens,服务照常启动,只是 draft 长度少一个 token,表现为加速比与预期不符而非报错。cookbook 给出 GSM8K batch size 1、greedy 下的平均接受长度 1.93 / 2.28 / 2.36(1/2/3 步),并说明 2 步已拿走大部分收益;这是官方给出的测量条件,不是本文实测。【官方】
6.3 单边独有
| 参数 | 只存在于 | 约束 |
|---|---|---|
--moe-backend humming |
vLLM | 仅 Blackwell + FP8 + SiTU;Hopper 必须删除 |
--enable-expert-parallel / --data-parallel-size |
vLLM | 与 SGLang 的 --tp 不是同一组语义 |
--attn-dp-size / --attn-cp-size / --page-size |
SGLang | attention 并行与分页大小 |
--hicache-ratio |
SGLang | 只支持 ratio,不支持 --hicache-size |
--enable-dp-lm-head |
SGLang | DSpark 在 attention DP 下缺它启不来;无 attention DP 时被忽略 |
VLLM_PLUGINS / VLLM_USE_MODELSCOPE |
vLLM | 插件开关与下载源 |
--moe-a2a-backend deepep |
SGLang | 需 --ep >= 4;PP 下要设为 none |

一个最小错抄示例与修正:
# 错误:把 vLLM 的参数名与取值拼进 sglang serve
sglang serve --model-path baidu/ERNIE-5.5-Flash-Base \
--max-model-len 131072 \
--kv-cache-dtype fp8 \
--reasoning-parser ernie5
# 修正:全部换成 SGLang 命名空间,且 Base 不加解析器
sglang serve --model-path baidu/ERNIE-5.5-Flash-Base \
--context-length 131072 \
--kv-cache-dtype fp8_e4m3 \
--tp 4 --attn-dp-size 4 \
--max-running-requests 256 \
--port 30000
七、第三关:答得对——请求层的六个坑
Base 模型只有续写能力,两边都走 /v1/completions,不是 /v1/chat/completions。
# vLLM 侧(端口 8000),官方 README 示例
curl http://127.0.0.1:8000/v1/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "baidu/ERNIE-5.5-Flash-Base",
"prompt": "Question: What is 15% of 240?\nAnswer:",
"max_tokens": 64,
"temperature": 0,
"stop": ["\n"]
}'
# SGLang 侧(端口 30000),cookbook 示例
from openai import OpenAI
client = OpenAI(base_url="http://localhost:30000/v1", api_key="EMPTY")
resp = client.completions.create(
model="baidu/ERNIE-5.5-Flash-Base",
prompt="Question: What is 15% of 240?\nAnswer:",
max_tokens=64,
temperature=0,
stop=["\n"],
)
print(resp.choices[0].text)
【官方】两份文档都给出该示例的输出为 36(前导空格)。这是文档示例,不是本文实测结果。
| 坑 | 官方口径 | 正确做法 |
|---|---|---|
| 用 chat 端点 | Base 无 chat 训练,cookbook 明写 chat / reasoning / tool-call 不适用 | 只用 /v1/completions,few-shot 示例写在 prompt 里 |
| 输出有随机性 | generation_config.json 设 do_sample=false, temperature=1.0, top_p=0.95;vLLM 只应用后两项、忽略 do_sample |
显式传 "temperature": 0 |
model 字段写错 |
vLLM PD 分离下不匹配会在流中间失败,而不是返回 404 | 严格等于服务名;BF16 用 baidu/ERNIE-5.5-Flash-Base-BF16 |
| 手动加特殊 token | vLLM README:tokenizer 自动在 completions prompt 前加 `< | ERNIE_MASK |
| BOS 处理 | 官方博客:模型要求输入开头有 BOS,Transformers 用法保持 add_special_tokens=True |
走推理服务时由 tokenizer 处理;SGLang 侧未单独说明【未披露】 |
| 未设 stop | few-shot 会一路续写 | 用 stop: ["\n"] 截到一条答案末尾 |
第二行值得单独看:「配置文件写了 greedy」不等于「服务按 greedy 跑」。vLLM 明确不读 do_sample,cookbook 也同样要求请求里传 temperature=0。把生成配置当服务默认行为,是部署完最容易出现、又最难从日志发现的结果偏差。
八、第四关:跑得长——三档上下文
| 档位 | vLLM 配置【官方】 | SGLang 配置【官方】 |
|---|---|---|
| 128K(训练长度) | --max-model-len 131072,两侧默认配方都用这个值 |
--context-length 131072 |
| 262,144 | 80 GB 卡上限:--data-parallel-size 8 --gpu-memory-utilization 0.93 |
文档未单列 80 GB 卡的上下文上限【未披露】 |
| 1,048,576 | --max-model-len 1048576 --gpu-memory-utilization 0.85,并降 --max-num-seqs;需 184 GiB 级 GPU,80 GB 卡跑不到 |
--context-length 1048576,--max-running-requests 降到个位数(2×B300),并降 --cuda-graph-max-bs-decode |
【官方】两份文档对 1M 的解释一致:1M prefill 需要额外数十 GB 临时激活内存,每个 rank 的 KV pool 必须能装下完整的 1M 请求。因此「模型支持 1M」是能力声明,「命令里填 1048576」还需要同时改显存占比与并发。魔乐模型卡写的「Both servers accept a context length of up to 1,048,576 tokens」与 cookbook / README 并不矛盾,只是省略了配套约束;读部署文档时要把这两层分开。【交叉】

长共享前缀另有两套不可互换的卸载方案:
# vLLM:SimpleCPUOffloadConnector,官方示例为每 rank 128 GiB
--kv-transfer-config '{"kv_connector":"SimpleCPUOffloadConnector","kv_role":"kv_both","kv_connector_extra_config":{"cpu_bytes_to_use_per_rank":137438953472}}'
# SGLang:HiCache 主机层,只支持 ratio
--enable-hierarchical-cache --hicache-ratio 2
【官方】vLLM 的固定值 137438953472 即 128 GiB,且按 DP rank 单独钉住。【推算】4 个 rank 时为 512 GiB 主机内存,前提是每个 rank 都预留满额且主机内存充足;官方提醒 rank 数 × 该值必须能装进主机 RAM。SGLang 的 --hicache-ratio 2 是 GPU KV pool 的两倍,属于相对量;两者单位与维度都不同,不能按数字大小比较。
九、进阶配置:投机解码与 PD 分离
9.1 ECHO / DSpark
| 项 | vLLM | SGLang |
|---|---|---|
| ECHO 开启 | --speculative-config '{"method":"mtp","num_speculative_tokens":2}' |
--speculative-algorithm EAGLE --speculative-num-steps 2 --speculative-eagle-topk 1 --speculative-num-draft-tokens 3 |
| 步数范围 | 1 / 2 / 3 均可 | 1 / 2 / 3 步,draft tokens 固定为步数 + 1 |
| 采样约束 | 未提 topk 约束 | 只支持 chain draft,必须 --speculative-eagle-topk 1 |
| DSpark | {"method":"dspark","draft_sample_method":"probabilistic"}(默认 greedy 被显式覆盖;不写 num_speculative_tokens,长度来自 checkpoint block size) |
--speculative-algorithm DSPARK --enable-dp-lm-head(attention DP 下缺该 flag 启不来) |
| 适用权重 | DSpark 仅 ERNIE-5.5-Flash(Coming soon) | 同左;Base 权重不带 DSpark draft |
【官方】ECHO 是主干最后一层兼任 draft,vLLM 通过 MTP 路径运行,SGLang 通过 EAGLE/NEXTN 路径运行。两条路径描述的是同一个 checkpoint 里的同一层,但配置语法完全不同。
9.2 PD 分离
vLLM 侧给的是可直接执行的完整拓扑:一个 P 节点、一个 D 节点,各 4 卡 DP4 + EP4,KV 经 RDMA 用 MooncakeConnector 搬运,前面挂 vllm-router==0.1.16。
uv pip install mooncake-transfer-engine-cuda13 # P 与 D 都装
uv pip install vllm-router==0.1.16 # 路由节点
export P_IP=10.0.0.1
export D_IP=10.0.0.2
export IB_DEVICES=mlx5_0,mlx5_1,mlx5_4,mlx5_5
export VLLM_ENGINE_READY_TIMEOUT_S=3600
export VLLM_HTTP_TIMEOUT_KEEP_ALIVE=1800
export VLLM_MOONCAKE_ABORT_REQUEST_TIMEOUT=600
# P 节点(D 节点改为 D_IP 与 kv_consumer)
VLLM_HOST_IP=${P_IP} vllm serve baidu/ERNIE-5.5-Flash-Base \
--host ${P_IP} --port 8000 \
--data-parallel-size 4 --enable-expert-parallel \
--moe-backend humming --kv-cache-dtype fp8 \
--max-model-len 131072 --gpu-memory-utilization 0.85 \
--max-num-seqs 128 \
--kv-transfer-config '{"kv_connector":"MooncakeConnector","kv_role":"kv_producer","kv_connector_extra_config":{"device_name":"'${IB_DEVICES}'"}}'
vllm-router \
--host 0.0.0.0 --port 8080 \
--policy round_robin --vllm-pd-disaggregation \
--kv-connector mooncake \
--prefill http://${P_IP}:8000 8998 \
--decode http://${D_IP}:8000 \
--intra-node-data-parallel-size 4
【官方】P 节点在 8998 端口提供 Mooncake bootstrap;投机解码开启时 P 与 D 必须传相同的 --speculative-config;IB_DEVICES 只列 InfiniBand HCA,用 ibdev2netdev 查。SGLang 侧的 PD 用 cookbook 的 PD Disagg 卡片(同样是 Mooncake),但额外给了一条警告:PD 分离下单请求 n > 1 并行采样会挂起,因为多个子请求共用一个 bootstrap room,须发 n = 1 的请求。该限制只见于 SGLang 文档,vLLM 侧未提【未披露】。
十、只读环境探测脚本
部署前把环境状态一次打全。脚本不启动服务、不下载权重、不写文件,只读取本地安装信息并可选探测已运行的服务端点。
#!/usr/bin/env python3
# preflight_ernie.py —— 只读预检,依据官方文档整理,未在目标机器实测
import importlib.metadata as md
import json
import os
import socket
import urllib.request
TARGETS = [("vllm", 8000), ("sglang", 30000)]
MODEL = "baidu/ERNIE-5.5-Flash-Base"
def ver(name):
try:
return md.version(name)
except md.PackageNotFoundError:
return "NOT INSTALLED"
def port_open(port, host="127.0.0.1"):
s = socket.socket()
s.settimeout(0.4)
try:
s.connect((host, port))
return True
except OSError:
return False
finally:
s.close()
def get(url):
try:
with urllib.request.urlopen(url, timeout=2) as r:
return r.status, r.read(2000).decode("utf-8", "replace")
except Exception as e:
return None, f"{type(e).__name__}: {e}"
print("== 本地安装 ==")
for pkg in ("vllm", "vllm-ernie", "sglang"):
print(f" {pkg:12s} {ver(pkg)}")
for key in ("VLLM_PLUGINS", "VLLM_USE_MODELSCOPE", "VLLM_ENGINE_READY_TIMEOUT_S"):
print(f" {key:30s} {os.environ.get(key, '<unset>')}")
try:
print(" general_plugins:", [e.name for e in md.entry_points(group="vllm.general_plugins")])
except Exception as e:
print(" general_plugins: query failed", e)
print("== 服务端点(仅探测,不发送生成请求)==")
for name, port in TARGETS:
if not port_open(port):
print(f" {name:8s} :{port} 未监听,跳过")
continue
code, body = get(f"http://127.0.0.1:{port}/v1/models")
print(f" {name:8s} :{port} /v1/models -> {code} {body[:200]}")
print("== 请求模板(供人工核对,不自动发送)==")
print(json.dumps({
"endpoint": "/v1/completions",
"model": MODEL,
"prompt": "Question: What is 15% of 240?\nAnswer:",
"max_tokens": 64,
"temperature": 0,
"stop": ["\n"],
}, ensure_ascii=False, indent=2))
脚本刻意不调用 /v1/completions:官方示例里的 temperature: 0 请求会触发一次真实生成,放进预检就不是只读了。要验生成结果,用第七节的 curl 单独跑一次。
【推断】entry_points(group=...) 在 Python 3.10+ 可用;低于该版本时需改用 entry_points().get(...) 形式。插件自身声明 >=3.10,而 vLLM 0.32.0 的 wheel 要求 >=3.11,实际以 3.12 最贴近 README 命令。
十一、排查清单
| 症状 | 优先检查 | 定位动作 | 改动点 |
|---|---|---|---|
Model architectures ['Ernie5_5_MoeForCausalLM'] are not supported |
插件未装 / 被禁用 | 跑 check_vllm_ernie.py 看 entry points 与注册表 |
装 git+...;或让 VLLM_PLUGINS 含 ernie |
| 装完 vLLM 后插件报依赖冲突 | 版本 | pip show vllm 是否为 0.32.0 |
显式 vllm==0.32.0 |
pip install vllm-ernie 找不到包 |
分发渠道 | PyPI 查询为 404 | 改 git+ 安装 |
| Python 3.10 环境装不上 vLLM | wheel 元数据 | 查 Requires-Python: >=3.11,<3.15 |
用 3.12 |
| 启动即 OOM / KV cache 极小 | 精度与卡数 | 对照第三节矩阵 | FP8 优先;降 --max-model-len;再加卡 |
| Hopper 上 MoE 报错 | --moe-backend humming |
查 GPU 架构 | 删除该参数,保留默认 kernel |
| 填 1048576 后起不来 | 显存与并发 | 查 --gpu-memory-utilization / --max-running-requests |
vLLM 降到 0.85 并降并发;SGLang 并发降到个位数 |
| 请求 404 或流中途断开 | model 字段 |
对比 /v1/models 返回名 |
改成服务名;BF16 换 -BF16 后缀 |
| 同一 prompt 每次结果不同 | 采样参数 | 查请求体 | 显式 "temperature": 0 |
| 输出开头多出 mask token | prompt 拼接 | 检查是否手写 `< | ERNIE_MASK |
| 加了 reasoning parser 没效果 | 权重形态 | 确认是 Base 还是 Flash | Base 上移除解析器参数 |
| SGLang 上 DeepEP 异常 | --ep 值 |
查是否小于 4 | 提到 4 以上;PP 下设 --moe-a2a-backend none |
| PD 分离下请求挂起 | 并行采样 | 查请求 n |
改成 n = 1 |
| DSpark 在 attention DP 下启不来 | --enable-dp-lm-head |
查启动参数 | 补上;且确认用的是 Flash 权重 |
顺序按「先分安装形态,再分参数命名空间,最后分权重形态」安排。前三行解决的是「起不来」,中间几行是「起来了但跑不长」,后半是「结果不对」;和第二节的四段流程一一对应。
十二、未披露清单
以下项目在两份官方文档中均未给出明确口径,部署前不要按默认值假设:
- 插件在
vllm 0.33.0上的兼容性;插件pyproject.toml只锁 0.32.0。 - PyPI 主线
sglang 0.5.23是否包含 ERNIE 5.5 全部运行时改动,与dev-ernie-55-flash镜像的能力边界差异。 - 80 GB 卡在 SGLang 侧的长上下文上限;vLLM 侧明确为 262,144。
- BF16 多节点组合(B200 8 卡、GB200 双 tray、H100 双节点)的实测验证结果,cookbook 已注明「按内存预算推算、未验证」。
- 1M prefill 所需临时激活内存的具体数值,官方只写「tens of GB」。
- SGLang 侧是否同样忽略
generation_config.json的do_sample;vLLM 侧明确忽略。 - SGLang 侧 completions 请求的 BOS / mask token 处理方式。
- FP4 权重与
ERNIE-5.5-Flash(Chat / reasoning / tool-call / DSpark)的发布时间。 - 国产加速器、非 NVIDIA 设备的支持范围;两份文档列出的硬件全为 NVIDIA。
- 权重下载体积之外的磁盘临时空间、加载耗时、多节点权重分发方式。
- vLLM 侧 PD 分离是否同样存在
n > 1挂起问题;SGLang 侧有明确警告。 - 两份文档对
--api-key与鉴权网关的推荐组合;vLLM README 只提示「加 key 或绑 loopback」。
【未披露】不等于「不支持」。以上条目应以对应版本的 --help、release notes 或实测结果补齐,不能从命名推断。
十三、可复用判据
把这套核对方式迁移到其他模型的双栈部署,保留四条:
| 判据 | 动作 | 本篇对应证据 |
|---|---|---|
| 先分安装形态 | 查依赖声明、PyPI 是否存在该包、是否有专用镜像 | vllm==0.32.0 硬锁、vllm-ernie 404、专用 dev 镜像 |
| 再分参数命名空间 | 把两栈同功能参数并排,找异名 / 同名异值 / 单边独有 | ernie5 vs ernie55;ECHO 2 步写 2 与 3 |
| 能力声明与默认配置分开 | 凡出现「支持 X」,去找配套要改的显存、并发、批量参数 | 1M 上下文需 0.85 显存占比与个位数并发 |
| 预检只读 | 环境探测脚本不触发生成、不写文件,第一次业务请求不当探针 | 第十节脚本 |
第三条最容易被忽略。厂商文档里的「支持 1M」「支持投机解码」「支持 PD 分离」描述的是能力上界,真正决定能不能跑起来的是同一份文档后面那几行配置约束;把它们抄进一张表,比多列十个功能更有价值。
- 点赞
- 收藏
- 关注作者
评论(0)