<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Speculative Decoding on 火炬树</title>
        <link>https://torchtree.com/tags/speculative-decoding/</link>
        <description>Recent content in Speculative Decoding on 火炬树</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <copyright>TorchTree Co., Ltd.</copyright>
        <lastBuildDate>Sat, 07 Nov 2026 11:37:03 +0800</lastBuildDate><atom:link href="https://torchtree.com/tags/speculative-decoding/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>DSpark 如何加速 Spark-X2.6：从逐词生成到批量验证</title>
        <link>https://torchtree.com/post/dspark-speculative-decoding-spark-x2-6/</link>
        <pubDate>Fri, 06 Nov 2026 23:45:27 +0800</pubDate>
        
        <guid>https://torchtree.com/post/dspark-speculative-decoding-spark-x2-6/</guid>
        <description>&lt;p&gt;本地运行语言模型时，模型往往需要逐个生成 Token。回答越长，用户等待的时间也越长。推测解码（Speculative Decoding）提供了另一种生成路径：先用成本较低的草稿模型预测一段内容，再让目标模型一次验证这一段，从而减少目标模型串行运行的次数。&lt;/p&gt;
&lt;p&gt;本文以 SparkLLM 发布的 &lt;strong&gt;Spark-X2.6-4B 和配套 DSpark 草稿模型&lt;/strong&gt;为例，解释验证过程和性能数据的含义，帮助已经了解语言模型基本用法的读者判断是否值得在本地尝试。文中的速度数据来自项目方模型卡，并非独立复测；资料核查于 2026 年 11 月 7 日。&lt;/p&gt;
&lt;h2 id=&#34;从逐个生成到一次验证多个候选&#34;&gt;从逐个生成到一次验证多个候选
&lt;/h2&gt;&lt;p&gt;语言模型将文本拆成 Token，可以把它理解为模型处理的文本片段。普通自回归生成先根据已有上下文预测下一个 Token，把结果加入上下文，再预测下一个。由于后一步依赖前一步的结果，这些生成步骤需要串行进行。&lt;/p&gt;
&lt;p&gt;推测解码将工作分给两个模型：&lt;strong&gt;目标模型&lt;/strong&gt;负责最终的生成规则，&lt;strong&gt;草稿模型&lt;/strong&gt;提前提出一串候选。目标模型可以针对这串已知候选，在一次前向计算中得到各位置的验证结果。验证仍要按顺序决定哪些候选可保留，但不必为每个候选单独运行一次目标模型。&lt;/p&gt;
&lt;p&gt;假设草稿给出四个候选 &lt;code&gt;A B C D&lt;/code&gt;。在贪心解码的示例中，目标模型同意前两个位置，在第三个位置选择 &lt;code&gt;X&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;草稿候选： A  B  C  D
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;验证结果： ✓  ✓  ✗
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;本轮输出： A  B  X
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;C&lt;/code&gt; 被拒绝后，&lt;code&gt;D&lt;/code&gt; 依赖的前文已经改变，因此也要丢弃；下一轮从 &lt;code&gt;A B X&lt;/code&gt; 继续。如果所有候选都被接受，目标模型还可根据完整候选前缀给出一个额外 Token。实际生成也可能提前遇到结束符或输出长度上限。&lt;/p&gt;
&lt;p&gt;上述例子只描述贪心路径。对随机采样，验证不是简单比较两个模型各自抽到的 Token：标准推测采样通过接受概率和拒绝后的修正分布，保留目标模型的采样分布。&lt;strong&gt;分布一致不意味着同一个随机种子必然产生逐字相同的回答&lt;/strong&gt;；具体保证也取决于推理引擎的采样实现和配置。&lt;a class=&#34;link&#34; href=&#34;https://proceedings.mlr.press/v202/leviathan23a.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;推测解码论文&lt;/a&gt;给出了这种方法的理论说明。&lt;/p&gt;
&lt;h2 id=&#34;dspark-在这条路径中做什么&#34;&gt;DSpark 在这条路径中做什么
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://huggingface.co/XHToken/Spark-X2.6-4B-GGUF&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Spark-X2.6-4B-GGUF&lt;/a&gt; 是目标模型；&lt;a class=&#34;link&#34; href=&#34;https://huggingface.co/XHToken/Spark-X2.6-4B-DSpark-GGUF&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Spark-X2.6-4B-DSpark-GGUF&lt;/a&gt; 是专门配套它的草稿模型。后者提供候选，不能替代目标模型独立完成这条推理路径。&lt;/p&gt;
&lt;p&gt;模型卡列出的草稿模型有 624M 参数、5 层滑动窗口注意力，窗口大小为 512，权重采用 BF16；目标模型可使用 BF16 或量化后的 GGUF 权重。它利用目标模型第 2、10、18、25、33 层的隐藏状态，也就是目标模型处理中间得到的表示，辅助生成候选。草稿模型每次前向最多提出 7 个 Token，再交由目标模型验证。&lt;/p&gt;
&lt;p&gt;滑动窗口限制了该注意力层直接关注的位置范围；完整推理的资源消耗还包括目标模型、缓存和其他操作，不能据此断言整体成本与上下文长度无关。草稿模型也要占用内存并执行计算，因此增加它并不自动带来加速。&lt;/p&gt;
&lt;h2 id=&#34;接受长度不是速度倍数&#34;&gt;接受长度不是速度倍数
&lt;/h2&gt;&lt;p&gt;项目方以最多 7 个草稿 Token、最多输出 4096 个 Token 测量平均接受长度。&lt;strong&gt;这里的接受长度包含目标模型额外提供的一个 Token&lt;/strong&gt;，所以最大值是 8；例如平均值为 4，并不表示每轮平均接受了 4 个草稿 Token。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;测试设置&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;六个数据集上的平均接受长度&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;目标温度 1，High thinking，草稿概率采样&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;4.02&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;目标温度 1，Low thinking，草稿概率采样&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;4.07&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;目标温度 1，关闭 thinking，草稿概率采样&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;4.50&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;目标温度 0，High thinking，草稿贪心解码&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;4.55&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这四列同时改变了思考模式、目标温度或草稿采样方式，不能据此单独归因于其中某个设置。在第一列中，MATH500 为 4.59，Arena-Hard-v2 为 3.22，说明这组测试的不同任务上，草稿能被利用的长度不同。&lt;/p&gt;
&lt;p&gt;每轮推进的 Token 越多，越有机会摊薄目标模型的调用成本；但一轮还要支付草稿生成和目标验证的时间。一个便于判断的近似关系是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;加速比 ≈ 平均每轮输出 Token 数 × 普通解码每 Token 耗时 ÷ 推测解码每轮耗时。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因此，即使平均每轮推进约 4 个 Token，也不能推导出 4 倍加速。如果草稿经常很早被拒绝，或草稿与验证的额外开销较大，收益会缩小，甚至可能变慢。&lt;/p&gt;
&lt;h2 id=&#34;项目方实测看清比较条件&#34;&gt;项目方实测：看清比较条件
&lt;/h2&gt;&lt;p&gt;下表是模型卡中六个数据集的平均生成吞吐量，单位为 Token/秒。RTX 4090 使用 llama.cpp，M5 Pro 使用 MLX；两种设备同时采用不同推理引擎，不能把差异单独归因于硬件。量化格式也不同。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;设备、引擎与目标模型精度&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;普通解码&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;使用 DSpark&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;平均加速比&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;RTX 4090 · llama.cpp · BF16&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;95&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;203&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;2.14×&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;RTX 4090 · llama.cpp · Q4_K_M&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;226&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;447&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;1.98×&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;M5 Pro · MLX · BF16&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;31&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;77&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;2.50×&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;M5 Pro · MLX · INT4&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;71&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;115&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;1.62×&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这是四组配置各自的平均加速比，不是所有任务都处于 1.62–2.50 倍之间。例如 M5 Pro 的 BF16 测试中，MATH500 为 2.94 倍；M5 Pro 的 INT4 测试中，Arena-Hard-v2 为 1.30 倍。表中吞吐量和倍数经过取整，直接相除可能略有差异。&lt;/p&gt;
&lt;p&gt;这些数据反映生成阶段的吞吐量，不等于首 Token 延迟或完整请求的端到端加速。提示词处理、输出长度、并发负载、采样参数、显存和实现版本都可能改变实际效果。主模型量化后，普通解码本身也更快；草稿开销能否继续换来足够收益，需要在目标设备上测量。&lt;/p&gt;
&lt;h2 id=&#34;在自己的工作负载上判断&#34;&gt;在自己的工作负载上判断
&lt;/h2&gt;&lt;p&gt;如果设备有空间同时容纳目标模型、BF16 草稿权重和运行时缓存，并且应用经常生成较长文本，可以尝试对比。对于输出很短、提示词处理占主要时间或设备内存紧张的场景，先测量完整请求延迟与内存占用，再决定是否启用。&lt;/p&gt;
&lt;p&gt;比较时保持目标模型及其量化版本、提示词、输出长度、采样和思考模式、上下文长度以及并发数一致，分别运行开启和关闭 DSpark 的请求。记录预热后的生成 Token/秒、首 Token 延迟、端到端耗时和峰值内存；多次运行并覆盖自己的典型任务。推测解码改变随机数的使用方式，采样结果可能不同，比较时应控制工作负载而不是要求文本完全相同。&lt;/p&gt;
&lt;p&gt;截至核查日，模型卡给出的 GGUF 示例使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/XHToken/llama.cpp&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;XHToken/llama.cpp&lt;/a&gt; 的 &lt;code&gt;master&lt;/code&gt; 分支，面向 Linux、Bash 和 NVIDIA GPU，并注明上游集成仍在进行。模型卡列出的 M5 Pro 数字来自 MLX，不能直接套用上述 CUDA 命令。安装步骤和支持状态会变化，实际部署前应查看模型卡中的版本与说明；普通运行只需要目标模型，启用该草稿路径则还需要对应的 DSpark 权重和支持它的运行时。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;来源&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huggingface.co/XHToken/Spark-X2.6-4B-DSpark-GGUF&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Spark-X2.6-4B-DSpark-GGUF 模型卡&lt;/a&gt;（SparkLLM，未注明发布日期；2026-11-07 核查）&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huggingface.co/XHToken/Spark-X2.6-4B-GGUF&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Spark-X2.6-4B-GGUF 模型卡&lt;/a&gt;（SparkLLM，未注明发布日期；2026-11-07 核查）&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://dev.to/sparkllm/spark-x26-4b-dspark-is-here-more-than-2x-average-bf16-inference-speed-3b1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Spark-X2.6-4B DSpark Is Here&lt;/a&gt;（SparkLLM，2026-10-31）&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://proceedings.mlr.press/v202/leviathan23a.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Fast Inference from Transformers via Speculative Decoding&lt;/a&gt;（Leviathan 等，2023）&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
