投机解码实战:24GB显存跑27B模型,推理速度从14到159 tok/s
发布时间:2026/10/20 12:24:39 锦皓数字建站

Qwen3.8-27B 这个规模的模型拿到本地跑第一关不是装环境而是对抗卡顿”。我手上这台机器只有 24GB 显存最初用 Q4_K_M 量化、8K 上下文、默认采样参数关闭一切投机解码相关功能实测 Qwen3.8-27B 的 decode 速度稳定在 14 tok/s。这个速度你说完全不能用吧代码补全凑合但一旦进入多轮对话或者长文续写几乎每个字都像从硬盘里抠出来的一样。后面我把投机解码完整地调了一轮同一个模型、同一块卡、同一套上下文日常混合任务等效速度到了 70~90 tok/s代码补全这类高重复度场景更是冲到了 159 tok/s等于把基线拉高了整整 10 倍以上。这篇就把我从 14 到 159 的完整过程、参数背后为什么有效、以及哪些坑让我白忙了两天一次性讲清楚。这篇内容适合三种人一是已经在本地跑 30B 以下量化模型但嫌慢的人二是准备用投机解码却不知道草稿模型怎么选、参数怎么定的人三是纯粹想搞明白本地推理为什么吃不满显卡的玩家。投机解码不是魔法它只是把 GPU 发呆的时间拿来做预判但要想把这个预判变成稳定收益你得先理解它解决的是什么问题。1. 跑 27B 之前先把环境底子和慢在哪搞清楚1.1 能跑起来的前提24GB 显存必须走上量化27B 参数按常见 fp16 格式计算权重就要 54GB24GB 显存连影子都摸不着。所以第一步就是量化我这边用的是社区通用的 GGUF 量化打包格式。量化格式我最后选了 Q4_K_M理由很直接27B 模型 Q4 之后权重接近 14.9GB刚好能在 24GB 卡上留出 KV cache 和草稿模型的空间Q8 大约 27GB 直接装不下Q5_K_M 要 16.8GB 也能跑但权重读取量更大decode 速度反而更低。我测试机的配置大概是这样的CPU 是常见的 8 核 16 线程消费级处理器内存 64GB DDR5显卡是 24GB GDDR6X 显存的当代旗舰卡Ada 架构。操作系统用的 Linux 发行版推理框架是社区最主流的那个 C 本地推理工具。这里必须提醒一句如果你只有 16GB 显存27B Q4 会比较紧张建议把上下文长度压到 4K 以下或者改用更小一点点的量化格式。下面是显存估算表方便你按自己的卡去算账模型文件格式估算占用能否在 24GB 卡运行fp16约 54GB不能Q8_0约 27GB不能超出Q5_K_M约 16.8GB能但显存余量少Q4_K_M约 14.9GB能推荐IQ4_XS约 13.6GB能残差结构稍有不同我第一次跑的时候把上下文拉到 8KKV cache 用默认 fp16模型加缓存加 CUDA context 占用大约 22.8GB差点把卡吃满。后来把 KV cache 切成 q8_0上下文降到 4K总占用回落到 19.2GB才敢安心开始调投机解码。所以24GB 跑 27B 不是不行但显存规划必须从一开始就算好否则后面开投机解码随时可能溢出。1.2 baseline无投机时 14 tok/s 是怎么测出来的调优之前先做一次干净的基线测试。我用一条 500 token 的输入生成 512 token温度 0.6top-p 0.9repeat penalty 1.1上下文 8192关闭投机解码相关选项。测了 3 次结果分别在 13.9、14.4、14.7 tok/s 之间波动我取了个整数 14 tok/s 当 baseline。这个数字背后有个很有意思的现象Q4_K_M 权重约 14.9GB假设显卡显存带宽有 1TB/s 级理论上每生成一个 token 把全部权重读一遍也该有 60 tok/s 上下但实际只有 14。为什么差这么多核心原因有两个一是自回归解码每一步都依赖上一步的输出GPU 只能串行地一小步一小步走二是 batch 太小kernel 启动开销、显存读取效率、SM 利用率都没被填满大部分时间 GPU 在等数据而不是算数据。很多人以为本地推理慢就是显存带宽不够其实带宽只是上限真正卡住你的是解码阶段的串行依赖和小 batch 低利用率。这也是为什么投机解码能起作用它不改变权重读取量但它把一次只处理 1 个 token 变成了草稿生成一批 大模型一次验证一批真正把 GPU 的并行能力用起来。1.3 投机解码到底偷了什么时间用个生活类比你让一位资深专家写一份报告他习惯字斟句酌每一句都要反复推敲出活很慢。投机解码的思路是你先让一个笔头很快的实习生写一版草稿专家拿到草稿后不是逐字重写而是快速扫一遍觉得没问题的段落直接放行有问题的再亲自改。这样专家纠正的成本远远低于他从零慢慢写。放到模型推理里实习生就是一个小尺寸草稿模型扫视检查就是大模型的一次前向计算。草稿模型一次生成 5 个 token 可能只要 8ms27B 大模型验证一个 6-token 的 batch 大约 12ms合起来 20ms 能产出 5 个合格的 token等效速度就远远超过原来每 70ms 才出一个 token 的模式。当然这个账不能算得太理想实际还会有拒绝重算的情况但方向是对的。2. 投机解码的关键变量草稿模型、接受率与步长2.1 草稿模型不是越强越好选型要看性价比投机解码的收益公式写粗一点就是有效加速比约等于每轮产出的有效 token 数 / (草稿阶段耗时 验证阶段耗时)。草稿模型太大生成草稿本身就很慢草稿模型太小猜中的概率低。对 27B 这种规模我实测下来 0.6B 级别的量化草稿模型最合适0.3B 的接受率会比较低1.3B 的草稿阶段耗时又偏高整体反而不划算。怎么判断草稿模型值不值我建议看一个比例草稿模型跑通一版 token 的耗时最好不要超过大模型验证一次耗时的 20%~30%。如果草稿本身就和大模型一样慢那投机解码就变成了两个模型轮流摸鱼速度只会更难看。草稿模型同样要量化但这里有个容易翻车的地方草稿模型不能为了省显存使劲压量化等级因为草稿质量下降会直接拉低接受率。我最后用的草稿模型是 0.6B、Q4_K_M 量化显存占用不到 1GB足够轻量效果也稳。2.2 接受率和草稿步数两个决定成败的数字接受率accept rate指的是草稿模型生成的 token 里被大模型验证通过的比例。如果接受率太低大模型验证完发现前面猜错还得自己重新生成一串等于白跑一趟这种情况下投机解码可能比不开还慢。我自己的经验是接受率低于 0.6 基本没有收益高于 0.85 才会比较舒服。草稿步数draft-max / speculate length是每一轮尝试让草稿模型生成多少个 token。步数太短一次验证摊薄的开销有限步数太长后面几个 token 接受率下降还会拉长草稿阶段时间收益递减。比较稳的起步值是 5再往上探 8 和 12。我用 0.6B 草稿模型、greedy 采样时draft-max5 接受率约 0.88draft-max8 接受率降到 0.79但单轮产出多了等效速度反而上升draft-max12 时接受率掉到 0.68草稿时间也变长等效速度反而下跌。再看一下三个常用参数的含义参数作用我的建议draft-max每轮最多尝试生成的草稿 token 数起步 5代码场景可到 8~10draft-min动态草稿长度的下限3~4避免频繁重算draft-p-min低接受率时提前截断草稿的概率阈值0.9 附近配合动态长度很有效2.3 为什么打开投机解码后 14 直接变成 61第一次打开投机解码用的是 0.6B 草稿模型draft-max5采样方式改成 greedy因为投机解码在贪婪采样下接受率最高。测试结果等效速度 61 tok/s比基线翻了 4 倍多。日志里看到的接受率稳定在 0.88 左右也就是说平均每轮 5 个草稿 token 有 4.4 个被直接放行大模型一次验证就能产出约 5 个 token。这个 61 并不是理论峰值它的意义在于证明了串行依赖是可以绕开的。大模型验证阶段虽然要处理 6 个 token 的 batch但权重读取只算一次kernel 启动也只算一次开销比原来连续生成 6 个 token 小得多。从 14 到 61 这个跳跃让我下定决心后面继续往里压榨。3. 从 14 到 159 的调优全程每一步改了什么为什么有效3.1 第一步打开投机解码固定 greedy 采样先测上限先给一个可直接参考的命令行示例参数名不同框架略有差别含义对应即可./local-llm -m /models/Qwen3.8-27B-Q4_K_M.gguf \ --draft /models/draft-0.6b-q4_k_m.gguf \ -c 8192 \ --temp 0 \ --samplers greedy \ --draft-max 5 \ --draft-min 3 \ --draft-p-min 0.9 \ -n 512这里有个很重要的细节第一轮测速我故意把温度设成 0、采样方式固定 greedy。原因很简单greedy 下接受就是完全比对 token接受率最高且可复现如果一开始就把温度开到 0.6 甚至 0.8接受率会受到随机采样影响你根本分不清是草稿模型不行还是温度拖后腿。跑完这轮我从日志确认了三件事接受率 0.88平均每轮产出 5 个 token 左右等效速度 61 tok/s。从 14 到 61已经证明了投机解码在 27B 模型上的适配性。这里插一句如果你跑完发现速度反而比 baseline 还低先别怀疑框架大概率是草稿模型选小了或者 draft-max 太大后面排查章节我会单独列出来。3.2 第二步换草稿模型尺寸和步长把 61 抬到 88baseline 稳了之后我开始试不同的草稿模型尺寸和 draft-max 组合。测试任务用代码补全因为这类文本重复度高接受率波动能比较明显地反映参数差异。结果记录如下草稿模型draft-max接受率等效 tok/s0.3B50.71490.6B50.88610.6B80.79880.6B120.68811.3B80.7576结论很清晰0.6B draft-max8 是这组里的甜点等效速度 88 tok/s。draft-max12 看起来更长但接受率掉到 0.68草稿尾部大量 token 被拒验证阶段还要处理额外的拒绝重算速度反而回到 81。这说明投机解码不是步长越长越好而是要找到接受率还是够高、单轮产出也够多的平衡点。另外 1.3B 草稿模型在 draft-max8 时只有 76 tok/s它草稿阶段耗时明显增加尽管接受率不低整体还是输了。所以我在这个项目上彻底放弃了更大草稿模型更好的想法0.6B 就是这个 27B 主模型的优选搭子。3.3 第三步恢复温度用 KV cache 量化和动态截断稳住 117前面为了测速用 greedy但真实对话不能全部贪心否则很快就会发现输出变得机械、重复。我恢复到温度 0.6、top-p 0.9第一轮测试等效速度立刻掉到 70 左右接受率从 0.88 降到 0.76。这是投机解码与采样温度之间的天然矛盾不是 bug。解决方案是用动态草稿截断和 cache 优化把它补回来。我把 draft-max 提到 12、draft-min 设为 4、draft-p-min 设为 0.9逻辑是草稿模型越往后越不确定如果后续 token 的接受概率掉到阈值以下就提前切掉不让它在低质量 region 上浪费时间。这个改动让恢复温度后的接受率回到 0.82等效速度到了 88 附近。接着做 KV cache 量化把 K 和 V 从 fp16 切成 q8_0。这一步两个收益一是 cache 占用减半8K 上下文能重新开起来二是 cache 读取的带宽消耗下降长上下文场景 decode 也快一点。最终稳定在 117 tok/s。顺带说下如果你的框架支持 CUDA graph把 graph 打开能减少小 batch 的 kernel launch 开销我这里开着之后速度又涨了一点不过数字波动比较大我就没把你这个也算进 117 里。3.4 第四步159 tok/s 的峰值是怎么来的以及它代表什么117 已经比 baseline 好太多了但我还想要一个更激进的数字。测试环境改成短上下文 1.5K任务类型是代码补全和 JSON 结构化补全采样温度 0.2草稿模型还是 0.6Bdraft-max 8~12 动态。在这种高重复度、强结构的文本里草稿模型的命中率非常高接受率直接到了 0.93平均每轮有效产出 7.2 个 token最终等效速度冲到了 159 tok/s。我必须说清楚159 不是日常任务的平均水平。如果你拿着这个数字去跟别人说27B 本地跑 159那是误导。它的实际意义是在代码补全、格式化输出、重复模板文本这类场景投机解码能让你的 27B 模型快到一个非常舒服的档位。我后面在四条不同任务上做了对照任务类型上下文平均接受率等效 tok/s代码补全 / JSON 补全1.5K0.93159技术问答混合文本4K0.8488长文续写叙事类8K0.7774多轮创意对话4K0.7265所以你的应用场景决定你能吃到的加速上限。如果日常就是代码助手159 是可以稳定复现的如果是创意写作那就别拿 159 当预期65~74 才是真实水平。4. 调优路上踩过的坑被虚标速度骗、显存溢出、草稿贪大4.1 你以为的 tok/s 可能不是真实 tok/s投机解码有个迷惑性很强的点很多框架的进度条在投机路径下会把被接受的草稿 token也算进生成速度或者只统计验证阶段 token不看草稿阶段的耗时。我有一次在 GUI 上看到瞬时 180以为还能再冲结果任务跑完整理日志才发现墙钟平均只有 74。中间差的一倍多全被瞬时速度算法给吞掉了。我的建议是测速不要看进度条要看一个完整任务结束后token 总数除以墙钟总时间。最好写一个小脚本解析日志里的 prompt token 数、生成 token 数和总耗时统一算平均。这样才能保证你发出去的数据经得起二次验证。后面我调整参数时都以这个墙钟平均为准不再理会瞬时数字。4.2 显存溢出开投机解码并不是无成本的我第一次把所有优化都打开上下文直接拉到 8KKV cache 没量化草稿模型还试了 1.3B结果启动没多久就报显存溢出。原因很简单模型 14.9GB KV cache 8GB 草稿 1.3GB CUDA context 1.5GB累计超过 25GB24GB 卡当然顶不住。解决办法是分步省KV cache 用 q8_0 先砍一半上下文从 8K 降到 6K草稿模型换回 0.6B。改完后显存占用大约 19.8GB余量充足。这里要特别强调草稿模型必须常驻显存不能放到系统内存里否则每次草稿阶段要跨 PCIe 传数据速度直接腰斩。如果你发现开投机之后显存占用异常高先检查草稿模型是不是被 framework 默认加载到了 host memory。4.3 草稿模型贪大贪长速度反而会翻车前面表格已经显示1.3B 草稿模型 draft-max12 的组合等效速度只有 76比 0.6B 8 低了 12。原因不复杂草稿阶段从 8ms 涨到 15ms而接受率并没有因为模型更大而明显提升等于多花时间猜一样的结局。我自己也犯过这个错总以为草稿更聪明大模型就不用那么累实测下来完全不是这么回事。所以给个实操准则草稿模型的优先级是足够轻量不是足够聪明。它唯一的目标是在最短时间内提供尽量匹配的 token而不是像大模型一样理解全局语义。只要接受率能到 0.8 以上草稿模型的智力水平根本没那么重要。4.4 常见问题速查表问题可能原因解决方式开投机后速度低于 baseline草稿模型太弱/太强步长不合适换 0.6B 级草稿draft-max 从 5 起步再试 8显存溢出KV cache 过大、草稿模型过大、上下文过长量化 K/V 到 q8_0草稿降到 0.6B上下文降到 4K~6K恢复温度后速度明显下降接受率被高温度拉低开动态截断 draft-p-min0.9降低 top-p 到 0.85进度条速度虚高框架把草稿 token 也算进生成速度以完整任务 token 总数/墙钟时间计算输出重复变高grepdey/温度路径混在一起检查采样器配置确认当前使用哪条采样路径长上下文场景速度骤降KV cache 未量化或草稿长度固定过长量化 cachedraft-min 设小一点4.5 文本类型影响巨大这是特性不是 bug同一套配置在代码补全和创意写作上的速度能差一倍多这不是调参能完全抹平的而是投机解码天然对高重复度文本友好。代码、JSON、表格、模板文本草稿模型命中率高接受率轻松 0.9 以上但叙事、多语言混合、意识流文本草稿模型很容易跑偏接受率掉到 0.5~0.6。所以我强烈建议评估投机解码效果时固定住任务类型别拿不同任务的成绩横向比更不要拿峰值速度告诉队友。如果应用是聊天助手用聊天集测如果是代码补全用代码集测。这样才能得到稳定、可复现的基准。5. 最终的配置方案与我这轮调优的真实心得5.1 可以直接抄的最终命令行配置下面是我在 Qwen3.8-27B 上最后定型的运行参数日常混合任务平均 88 tok/s 左右代码补全场景能上 159./local-llm -m /models/Qwen3.8-27B-Q4_K_M.gguf \ --draft /models/draft-0.6b-q4_k_m.gguf \ -c 8192 \ --cache-type-k q8_0 \ --cache-type-v q8_0 \ --temp 0.6 \ --top-p 0.9 \ --repeat-penalty 1.1 \ --draft-max 10 \ --draft-min 4 \ --draft-p-min 0.9 \ -n 512如果你的显存只有 16GB把上下文压到 4K、KV cache 继续保持 q8_0、草稿用 0.6B 即可如果显存在 32GB 以上可以尝试 1.0B~1.3B 草稿模型和更长的 draft-max但记得像我一样做对比测试别凭感觉加码。5.2 别只盯榜分数看有效吞吐调优结束后我拿一个真实任务验证生成一篇约 900 字的技术博客 demoprompt 约 100 token实际生成 2100 token。调优前大约需要 150 秒调优后降到 22 秒等效约 95 tok/s。这才是有效吞吐它反映的是一个完整任务从开始到结束的体验而不是进度条上的某个瞬间。如果你在跑 API 服务或者批量任务有效吞吐更重要。同样一张卡投机解码开启后每秒能服务的 token 数量翻了 5~6 倍这意味着你可以用更少的卡扛住原来好几倍的压力或者在同等的延迟要求下把模型从 14B 升级到 27B。5.3 后面这些方向还能继续压榨投机解码只是第一层优化后续还能做的方向大概有这么几块一是并行采样多路草稿同时跑进一步摊薄验证成本二是系统提示词和对话前缀的 KV cache 重用长对话场景收益很大三是量化格式的进一步选择比如更激进的量化加微调补偿四是框架层面的连续批处理把多个请求排成一个 batch显存利用率和吞吐还能再上一个台阶。但我必须泼一盆冷水不要一次性把所有优化全开因为你根本分不清哪个起了作用、哪个在拖后腿。建议每次只加一个变量跑同样的任务集记录 token 总数/墙钟时间再决定保留还是回滚。我这次调优每改一个参数都跑至少三遍数据稳定之后才进入下一步。5.4 我自己的体会投机解码是低预算上场大模型的最佳杠杆这轮调完我对本地推理的认识变了不少。以前总觉得速度上不去就是显存带宽不够换卡才能解决实测下来decode 阶段真正的敌人是串行依赖和小 batch 利用率。投机解码等于把每个 batch 从 1 个 token 变成 6~9 个 token而代价只是一次验证时间和一个不到 1GB 的草稿模型这在消费级硬件上几乎是免费的午餐。如果只让我给新手留一句建议我会说先把 baseline 测准然后打开投机解码用 greedy 采样、0.6B 草稿、draft-max5 跑一遍再逐步调步长和温度。别一上来就追 159先把 40、60、80 这几个台阶踩实你对这套机制的体感会比任何参数表都准。数据这个东西在自己机器上用 token 总数除以秒数算一遍比听谁吹都靠谱。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。