Misc. bug: DSpark drafter inheriting main model’s context size

用户运行 llama-server ,为带有 DSpark draft 头的 Bonsai-27B 模型( --spec-type draft-dspark )进行投机解码,并将主模型上下文设置为 32768( -c 32768 ),同时将 draft 模型完全卸载到 GPU( -ngld 99 )

Misc. bug: DSpark drafter inheriting main model's context size

Misc. bug: DSpark drafter inheriting main model’s context size

快速结论:该报错发生在使用 --spec-type draft-dspark 进行投机解码时,draft 模型的上下文批处理大小(n_batch)被强制提升至主模型的 -c 设定值(如 32768),导致在显存有限的 GPU(如 16GB)上因 cudaMalloc out of memory 而崩溃。优先排查并限定 draft 模型的 n_batch 上限。

问题场景

用户运行 llama-server,为带有 DSpark draft 头的 Bonsai-27B 模型(--spec-type draft-dspark)进行投机解码,并将主模型上下文设置为 32768(-c 32768),同时将 draft 模型完全卸载到 GPU(-ngld 99)。在显存为 16GB 的移动端 RTX 3080 Ti 上启动时,立即崩溃。

报错原文

0.02.287.240 I srv    load_model: draft-dspark: raising draft ctx n_batch 1024 -> 32772 (full-context staging + block)
0.02.290.271 E ggml_backend_cuda_buffer_type_alloc_buffer: allocating 5888.53 MiB on device 0: cudaMalloc failed: out of memory
0.02.290.275 E ggml_gallocr_reserve_n_impl: failed to allocate CUDA0 buffer of size 6174568960
0.02.290.276 E graph_reserve: failed to allocate compute buffers
0.02.290.470 E llama_init_from_model: failed to initialize the context: failed to allocate compute pp buffers

原因分析

可能原因:DSpark draft 模型在首次解码(prompt ingest)时,其内部上下文的大小(n_batch/n_ubatch)被强制与主模型的 -c 参数同步。日志中 raising draft ctx n_batch 1024 -> 32772 表明,draft 模型的批处理大小从初始值被拉升到与主模型上下文一致的大小(32768 + 额外 block 大小)。这导致 draft 模型的计算缓冲区(compute buffer)被放大到约 5.9 GB,在显存总量为 16GB、且已加载主模型参数的 GPU 上无法分配。评论指出,draft 模型的上下文行(context rows)仅为 K/V 缓存,无需执行查询(query),因此该缓冲区不必随 n_ctx 线性增长。

Note: 此 Issue 来自 llama.cpp 主线仓库,但 DSpark 支持目前仅在 PrismML 的定制分支中实现。有关该分支的具体问题,建议在 PrismML-Eng/llama.cpp 仓库中跟踪。

环境排查

  • 确认 GPU 显存大小:RTX 3080 Ti Laptop 为 16GB。
  • 确认主模型上下文大小:-c 32768
  • 确认主模型与 draft 模型的层级卸载设置:-ngl 99 -ngld 99
  • 确认模型类型:Bonsai-27B(Q2_0)+ DSpark drafter(Q4_1)。
  • 确认 llama.cpp 版本:version 9591(62061f910),构建于 Linux x86_64。
  • 检查是否使用了非主线分支:--spec-type draft-dsparkBONSAI_SPECULATIVE=1 环境变量。

解决步骤

  1. 可优先尝试:在加载命令中手动限定 draft 模型的 n_batch/n_ubatch,防止其扩容至全上下文大小。例如,在命令行中添加 --spec-draft-batch 1024(如果支持),或通过运行时参数限制。
  2. 核心修复思路(需修改源码或等待补丁):限制 draft 模型的 n_batch/n_ubatch 为一个固定上限(如 8192)。这样,计算缓冲区大小将受控,而 KV 缓存可独立管理更大上下文。该补丁原理是:
    • 使用 f16 KV 缓存可全速维持 32k 上下文。
    • 使用 Q4 KV 缓存可维持 128k 上下文(约 70 tok/s)。
    • 当 prompt 长度超过限定 batch 时,回退到自回归解码(auto-regressive),无性能错误,仅减速。
  3. 临时绕过:将 draft 模型卸载到 CPU(--spec-draft-device none),但代价是性能从 65+ T/S 大幅降至 ~15 T/S,且伴有 PCIe 传输瓶颈。
  4. 确认你使用的是 PrismML 定制分支,并在其仓库中反馈问题:PrismML-Eng/llama.cpp #74

验证方法

启动后,查看日志确认不再出现 raising draft ctx n_batch ... 日志,且无 cudaMalloc failed: out of memory 错误。运行正常推理,观察投机解码是否生效(GPU 利用率正常,token 生成速度较高)。

参考来源

ggml-org/llama.cpp #25714

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

celebrityanime
celebrityanime
文章: 13722

发表回复

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