RuntimeError: mat1 and mat2 shapes cannot be multiplied (2048×3072 and 4096×1024)

这个报错通常出现在 vLLM 中使用 Kimi K3 DSpark(或类似 draft 模型)并开启 Pipeline Parallelism(PP,PP>1)时,vLLM 在校验 speculative 配置阶段直接拒绝加载,因为该 draft 模型没有实现 SupportsPP 接口。优先排查的

快速结论:这个报错通常出现在 vLLM 中使用 Kimi K3 DSpark(或类似 draft 模型)并开启 Pipeline Parallelism(PP,PP>1)时,vLLM 在校验 speculative 配置阶段直接拒绝加载,因为该 draft 模型没有实现 SupportsPP 接口。优先排查的是:当前模型是否支持 PP、spec decode 与 PP 是否同时开启,以及在 PP 场景下 draft 是否能正确拿到 target 的嵌入和辅助隐藏状态(aux hidden states)。

适用环境:Issue 中确认的信息:vLLM(路径为 /usr/local/lib/python3.12/dist-packages/vllm),Python 3.12,Linux 容器环境(dist-packages),模型为 Kimi K3 + DSpark 投机解码。提交者用于验证的硬件为 2×RTX 3090。其他 CUDA、PyTorch、驱动版本在 Issue 中没有明确说明。

最快修复方案:暂无确认的一步修复方案。Issue 本身是 feature request,作者提交的是补丁方案和复现分析,并未给出官方合并的修复命令或版本。可优先尝试:在 DSpark/PP 支持落地前,关闭 PP(PP=1)或关闭 speculative decoding 来规避启动失败。

注意事项:作者指出,即使绕过这个显式报错(“guard”),PP 下还有至少六个串联的上游障碍;其中最关键的一点是 aux hidden states 在 PP 边界处会被静默丢弃,导致 draft 只拿到五个 tap 中的一个,且随 PP 度增大丢失比例上升。这种情况下模型可能仍能启动并生成,但输出质量会异常且难以察觉,比当前的直接拒绝更危险。因此不要仅凭“能启动”判定问题已解决。

问题场景

用户在 vLLM 中加载 Kimi K3 模型,并启用 DSpark draft 做投机解码(speculative decoding),同时开启 Pipeline Parallelism(PP,多卡流水线并行)。启动 APIServer 时,vLLM 在构建 speculative 配置、校验 draft 模型与并行配置是否兼容的过程中抛出异常,进程直接退出,模型无法提供服务。

Issue 标题为 [Feature]: Kimi K3 DSpark Pipeline Parallelism,提交者表示这个问题“主要是一个整体上 spec decode 与 pipeline 的组合还不可用,而不只是 K3 DSpark”。

报错原文

2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)     speculative_config = self.create_speculative_config(
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)   File "/usr/local/lib/python3.12/dist-packages/vllm/engine/arg_utils.py", line 1785, in create_speculative_config
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)     return SpeculativeConfig(**self.speculative_config)
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)   File "/usr/local/lib/python3.12/dist-packages/pydantic/_internal/_dataclasses.py", line 121, in __init__
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)     s.__pydantic_validator__.validate_python(ArgsKwargs(args, kwargs), self_instance=s)
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)   File "/usr/local/lib/python3.12/dist-packages/vllm/config/speculative.py", line 1277, in _verify_args
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)     self.draft_model_config.verify_with_parallel_config(
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)   File "/usr/local/lib/python3.12/dist-packages/vllm/config/model.py", line 1262, in verify_with_parallel_config
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960)     raise NotImplementedError(
2026-07-28 06:23:24 [ERROR]   (APIServer pid=551960) NotImplementedError: Pipeline parallelism is not supported for this model. Supported models implement the `SupportsPP` interface.

原因分析

最直接的原因:vLLM 的 SpeculativeConfig._verify_args 会调用 draft model config 的 verify_with_parallel_config,检查该 draft 模型是否声明支持 Pipeline Parallelism。Kimi K3 DSpark 的 draft 模型没有实现 SupportsPP 接口,因此在 PP>1 时被显式拒绝加载。

根据提交者在评论中的分析,这个报错其实“挡在”两个独立问题前面:

  • 问题 A(守卫直接暴露的问题):draft 通过对象引用直接复用 target 的模块——load_dspark_modeldraft_inner.embed_tokens 指向 target_embed(位于 PP rank 0),把 draft_model.lm_head 指向 target_lm_head(位于最后一个 PP rank)。而 draft checkpoint 本身不包含这两个权重(checkpoint_skip_substrs = ("confidence_head", "embed_tokens", "lm_head"))。PP 下没有任何一个 rank 同时拥有这两者,这种“接线”无法满足,于是被守卫拦下。
  • 问题 B(更危险、且静默):K3 的 DSpark draft 并非独立模型,它消费从 target 的 target_layer_ids(发布 checkpoint 中为 [7, 31, 47, 63, 87])上“抽取”出来的辅助隐藏状态(aux hidden states),经 combine_hidden_states 投影后生成每层的 latent cache。但在 KimiK3Model.forward 中,各 rank 只在自己的层范围内计算这些 tap,然后返回:
if not get_pp_group().is_last_rank:
    return IntermediateTensors(
        {"hidden_states": hidden_states, "residual": residual}
    )

aux_hidden_states 并不在这个 payload 里,因此每个中间 rank 都会静默丢弃自己刚算出的 tap,只有最后一个 rank 的 tap 能存活。后果是:如果只修 A,DSpark 能初始化、能生成,但 draft 实际只基于五个 tap 中的一个做条件——比现在“诚实地拒绝”更糟。而且丢失比例随 PP 度上升,PP=2 时在 K3 的层切分下五个 tap 层中已有四个落在错误的一侧。

需要强调:这些分析来自提交者的补丁讨论,属于 Issue 内明确给出的解释,但相关修复尚未确认被上游合并。

环境排查

  • 确认 vLLM 版本与安装路径(Issue 中为 /usr/local/lib/python3.12/dist-packages/vllm,对应 Python 3.12)。
  • 确认当前是否设置了 PP>1(pipeline parallel size)。
  • 确认是否同时开启了 speculative decoding / DSpark draft 配置。
  • 确认 draft model config 是否实现了 SupportsPP 接口(Kimi K3 DSpark 在 Issue 时点未实现)。
  • 确认 Kimi K3 的 target_layer_ids 与 checkpoint 期望是否一致(发布 checkpoint 中为 [7, 31, 47, 63, 87]hidden_size 为 7168,draft 约 9.5 GB:7.12 GB 权重 + 2.35 GB 嵌入,提交者按此估算)。
  • Issue 中未提供 CUDA、PyTorch、驱动、显卡型号(除提交者使用的 2×RTX 3090)等信息,需要自行核对时以本地环境为准。

解决步骤

  1. 先确认自己是否真的必须用 PP。如果只是单机多卡显存不足、并不需要流水线并行,可优先尝试把 PP 关掉(PP=1),或暂时关闭 speculative decoding,先让服务起来。
  2. 如果必须用 PP + DSpark,需要等待或采用上游对 SupportsPP 的支持。Issue 中提交者给出的补丁方向是:
    • 解决问题 B:把 aux hidden states 一并放进 IntermediateTensors 传递。具体为——非首 rank 在拉取 hidden_states/residual 的同时拉取 aux_hidden_state_{i};非末 rank 转发“上游带来的 + 自己新算的”;末 rank 组装“带来的 + 自己的”,由于上游 rank 一定持有更低的层索引,拼接后天然保持层顺序。make_empty_intermediate_tensors 为上游产生的每个 tap 分配一个槽位,本地用 sum(1 for L in aux_hidden_state_layers if L < self.start_layer) 计算,避免为对齐 payload shape 增加额外通信。代价为每个被携带的 tap 约 hidden_size × 2 B = 14 KB/token(7168,bf16),尾段在原有 28 KB 之外再携带 70 KB/token。
    • 解决问题 A:把 draft 放到最后一个 rank(它本来就持有 lm_head,且层切分会有意让最后一段层数更少),并在加载时一次性把 rank 0 的 embed_tokens 广播过去,而不是重新读 checkpoint。发布版 draft 在该卡上约占 9.5 GB。
    • 提交者还提到一个更省的变体(留待后续):context_proj 是对拼接结果的线性变换,因此 W · concat(x₀…x₅) = Σ Wᵢ · xᵢ,每个 rank 可以只对自己的切片做投影并累加一个部分和,使 payload 大小与 tap 数量无关。但这需要 draft 权重按 rank 分片,所以没有作为第一版方案。
  3. 如果只是想临时规避而不是修复,退回 PP=1 或关闭 spec decode,是 Issue 中唯一有依据的规避路径。

验证方法

提交者特别指出:能启动并不能作为证据,因为问题 B 是静默失败的。他建议的验证门槛是“数值比对”——对 combine_hidden_states(所有 tap 汇聚的唯一入口)加插桩,要求同一 prompt 在 PP=2 下的指纹与 PP=1 下完全相等,并使用位置加权校验和,这样“tap 顺序被打乱”也能与“正确”区分开。之后再检查输出一致性和非零的 acceptance counter。

测试配置方面,由于发布版 draft 期望 hidden_size 7168 且 tap 在 7–87 层,提交者使用了一个缩放后的小型合成 K3 切片对应的 K3DSparkModel 配置,并对每一层都设 tap,让 tap 尽可能跨越最多的 PP 边界。他在跟进中给出的验证环境为:2×RTX 3090、vLLM main 6c95a641e、PP=2、小型合成 K3 切片配匹配的迷你 DSpark draft。

同时提交者指出,实际排查中“不是一个守卫,而是六个上游障碍串联,每一个只有在前一个被移除后才可见”,因此验证时应逐个确认修复后暴露出的下一层问题,而不是看到服务启动就收工。

参考来源

vllm-project/vllm #50098

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 23916

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注