ERNIE-5.5-Flash-Base 部署实操:两条官方引擎路径与一份参数不可移植清单

举报
Daniel777 发表于 2026/11/10 14:41:11 2026/11/10
【摘要】 百度在 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 仍有提交。本文只处理一件事:把这两条路...

百度在 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 仍有提交。本文只处理一件事:把这两条路径跑起来,并逐项标清哪些参数不能从一个栈抄到另一个栈。

三条结论先行。

  1. 安装形态不通用。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 教程装」会失败。
  2. 参数命名空间不通用。同一个功能在两栈里既有异名(分辨率解析器 ernie5 / ernie55),也有同名异值(ECHO 两步推理在 vLLM 写 2、在 SGLang 写 3),还有大量单边独有参数。抄错多数不会报参数错误,而是「服务起来了、结果不对」。
  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 权重

顺序按「先分安装形态,再分参数命名空间,最后分权重形态」安排。前三行解决的是「起不来」,中间几行是「起来了但跑不长」,后半是「结果不对」;和第二节的四段流程一一对应。


十二、未披露清单

以下项目在两份官方文档中均未给出明确口径,部署前不要按默认值假设:

  1. 插件在 vllm 0.33.0 上的兼容性;插件 pyproject.toml 只锁 0.32.0。
  2. PyPI 主线 sglang 0.5.23 是否包含 ERNIE 5.5 全部运行时改动,与 dev-ernie-55-flash 镜像的能力边界差异。
  3. 80 GB 卡在 SGLang 侧的长上下文上限;vLLM 侧明确为 262,144。
  4. BF16 多节点组合(B200 8 卡、GB200 双 tray、H100 双节点)的实测验证结果,cookbook 已注明「按内存预算推算、未验证」。
  5. 1M prefill 所需临时激活内存的具体数值,官方只写「tens of GB」。
  6. SGLang 侧是否同样忽略 generation_config.json 的 do_sample;vLLM 侧明确忽略。
  7. SGLang 侧 completions 请求的 BOS / mask token 处理方式。
  8. FP4 权重与 ERNIE-5.5-Flash(Chat / reasoning / tool-call / DSpark)的发布时间。
  9. 国产加速器、非 NVIDIA 设备的支持范围;两份文档列出的硬件全为 NVIDIA。
  10. 权重下载体积之外的磁盘临时空间、加载耗时、多节点权重分发方式。
  11. vLLM 侧 PD 分离是否同样存在 n > 1 挂起问题;SGLang 侧有明确警告。
  12. 两份文档对 --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 分离」描述的是能力上界,真正决定能不能跑起来的是同一份文档后面那几行配置约束;把它们抄进一张表,比多列十个功能更有价值。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。