ik_llama.cpp 投机解码基准测试工具 llama-spec-bench 完全指南

发布时间:2026/9/18 18:27:47

ik_llama.cpp 投机解码基准测试工具 llama-spec-bench 完全指南 ik_llama.cpp 投机解码基准测试工具 llama-spec-bench 完全指南【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cppllama-spec-bench是 ik_llama.cpp 仓库自带的直接 C 投机解码Speculative Decoding基准测试工具。它不走llama-server的 HTTP 路径而是复用llama-common的标准启动流程与投机生命周期用于对 prompt 驱动的典型任务做端到端性能与接受率acceptance评测。读完本文你将掌握该工具的输入模式、全部基准专用参数、严格 JSONL 数据集格式、Markdown/JSONL 双输出与指标定义并能结合源码理解其底层运行机制与使用注意事项。为什么需要专门的投机解码基准投机解码利用批量计算 n 个 token 比顺序计算 n 个 token 更高效这一特性先用一个快速草稿draft机制预测多个 token再由主模型在单个 batch 中统一验证草稿预测正确时即可显著加速生成。ik_llama.cpp 的投机解码生态十分丰富docs/speculative.md 列出了多种实现草稿模型draft、MTPmtp、n-gram 缓存ngram-cache、n-gram 映射ngram-simple、ngram-map-k、ngram-map-k4v、共享哈希池ngram-mod、后缀树suffix并支持两级 stage 链组合。面对如此多的实现需要一把统一的尺子来回答两个问题哪种草稿策略在什么任务上更快接受率acceptance rate与接受长度acceptance length如何llama-spec-bench正是为此而生——它在同一个进程、同一个二进制、同一组模型与采样器参数下分别跑基线无投机与投机配置输出可对比的指标。工具定位直接 C 基准而非服务器压测从源码看spec-bench.cpp 直接包含common.h、chat.h、speculative.h、llama.h并在main()中调用gpt_params_parse、llama_init_from_gpt_params、common_speculative_finalize_startup、common_speculative_run_round等公共 APIspec-bench.cpp。这意味着复用 llama-common 生命周期正常模型的加载、采样器初始化、投机 stage 的解析与启动逻辑与llama-server/llama-cli完全一致基准结论可以直接迁移到实际部署基线即对照当参数中不存在投机 stage 链时is_baseline为 true见 spec-bench.cpp工具直接退化为普通解码基准与投机配置天然可比限制明确该工具只支持直接的、非 CFG 的 decoder-only 投机运行——若启用 CFGcfg_scale 1、GQA 分组注意力异常grp_attn_n ! 1或加载 encoder-decoder 模型会直接拒绝运行spec-bench.cpp。构建与安装llama-spec-bench随 examples 一起构建在 examples/CMakeLists.txt 中通过add_subdirectory(spec-bench)引入其目标定义与链接关系见 examples/spec-bench/CMakeLists.txt链接common与llama库要求 C17。构建产物为build/bin/llama-spec-bench。一个值得注意的构建细节三个内置规范 promptcode、extract、story在CMake configure 阶段通过file(READ)configure_file嵌入到spec-bench-prompts.h中examples/spec-bench/CMakeLists.txt模板见 spec-bench-prompts.h.in因此运行时不需要访问源码树或网络同时通过CMAKE_CONFIGURE_DEPENDS声明依赖修改 prompt 文件后重新 configure 即会自动更新嵌入内容。输入模式四选一llama-spec-bench每次调用必须且只能选择一种输入模式模式参数说明内置任务集默认或--task收窄运行code、extract、story三个内置任务的全部或子集内联 prompt-p text/--prompt text运行单个自定义 promptprompt 文件-f path/--file path整个文件作为一个 prompt注意不是每行一个任务JSONL 数据集--prompts path严格格式的多 prompt 结构化负载替换内置任务集源码 spec-bench.cpp 对互斥关系做了硬性校验-p与-f不能同时出现--prompts不能与--task、-p、-f组合-p/-f也不能与--task组合违反即报错退出。内置任务的定义位于 spec-bench.cpp分别来自三个源文件codeid 为builtin-codeWrite a quick sort python algorithm, answer only the code.code.txtextractbuiltin-extract从一段 YouTube 介绍文本中提取带精确日期的事件列表extract.txtstorybuiltin-storyGive me an extended summary of the history of Bulgariastory.txt--task参数以逗号分隔、大小写不敏感内部统一string_lower归一化若包含未知任务名会在 spec-bench.cpp 报错并列出未匹配项。基本用法示例# 运行单个内联 prompt ./build/bin/llama-spec-bench -m model.gguf -n 4 -p Write a merge sort in C. # 运行单个 prompt 文件整个文件是一个 prompt ./build/bin/llama-spec-bench -m model.gguf -n 4 -f examples/spec-bench/prompts/code.txt基准专用参数详解所有参数解析集中在 spec-bench.cpp 的spec_bench_parse_args中除以下专用参数外其余参数-m、-n、--seed、--temp、--spec-type、-md/--model-draft等原样透传给gpt_params_parse处理参数默认值说明--prompts path无用严格 JSONL prompt 文件替换内置任务集仅可指定一次-p, --prompt text无运行一个内联自定义 prompt仅可指定一次-f, --file path无运行一个纯文本自定义 prompt 文件整个文件是一个 prompt不是每行一个任务--task name[,name...]全部内置任务选择内置任务子集如code,extract,story不允许空选择项--repeat n1每个任务重复运行 n 次下限 1std::max(1, ...)兜底--retry n0瞬态任务失败时最多重试 n 次下限 0std::max(0, ...)兜底--output-format md\|jsonlmd选择输出格式必须是md或jsonl否则报错--output-details关闭Markdown 模式先打印 prompt 与 response再打印详细指标表JSONL 模式输出完整细节字段--predict n/-n n256命令级生成预算作用于每个没有行内max_tokens覆盖的任务两个已废弃参数的明确指引--dataset不再支持应改用--prompts PATHspec-bench.cpp--output不是基准输出目的地请用--output-format jsonl并将 stdout 重定向到文件spec-bench.cpp。生成预算的解析优先级在 spec-bench.cpp任务自带max_tokens 0优先否则用params.n_predict两者都没有时兜底为 256。--seed未显式指定时工具会将种子固定为1234spec-bench.cpp保证可复现。JSONL 数据集格式与严格校验--prompts接受一个 JSONL 文件每行一个 JSON 对象必须包含非空的prompt字符串可选字段为id、name、category与正整数max_tokens{id:task-1,name:math,category:reasoning,prompt:Solve 12*17.,max_tokens:64}字段语义id任务唯一标识缺省时默认为该行的一-based 行号必须唯一name任务显示名缺省时等于idcategory任务分类标签缺省时等于idprompt必填非空字符串max_tokens可选正整数 0且不超过int上限用于覆盖命令行-n/--predict的预算。加载器 spec_bench_load_dataset 的校验极其严格以下情况都会抛出异常并终止运行空行包括仅空白字符的行非法 JSON非对象、解析失败出现allowed_fieldsid、name、category、prompt、max_tokens之外的未知字段缺少prompt或prompt非字符串id、name、category经 strip 后为空prompt经 strip 后为空id重复max_tokens不是正整数浮点数、负数、0、超界均被拒绝。该文件会完全替换内置任务集仅对本次调用生效。输出与指标解读默认输出 Markdown 报告到 stdout--output-format jsonl时每行输出一个 JSON 对象便于脚本与 CI 流水线消费。Markdown 报告spec_bench_print_markdownspec-bench.cpp输出内容分几块任务运行表每行一个任务/一次重复列为task、run、stage、tokens、stopeog/limit/fail、time(s)、tok/s、rounds、accepted接受数/草稿数、rate接受率百分比、a.len接受长度、pos accept按投机位置的接受率百分比序列。无投机 stage 的行显示为base详细指标表需--output-details增加prompt tok、prompt s、total s、每阶段draft s、accept s以及按位置的accepted/drafted原始计数重复汇总表--repeat 1时自动出现对每个 task × stage 分组输出tok/s、接受率、接受长度的 mean/std用于评估方差错误列表所有失败运行及其原因换行/制表符会被折叠超长截断。JSONL 输出JSONL 模式每个 attempt 输出一行最后输出一行 summary。详细模式--output-details下字段最全包括row_typeattempt或summary任务信息task_id、task_name、task_category、max_tokens、repeat_index、builtin、prompts来源builtin-default或数据集路径runtimemodel、model_alias、n_ctx、n_predict、n_batch、n_ubatch、n_threads、n_threads_batch、n_gpu_layers、flash_attn、numavariantis_baseline无投机 stage 链即为 true、spec_types各 stage 类型、stage_chainsamplerseed、temp、top_k、top_p、min_p、tfs_z、typical_p、top_n_sigma、penalty_last_n、penalty_repeat、penalty_freq、penalty_present、mirostat及其参数、n_probs、采样器序列timingprompt_s、decode_s、total_s、decode_tps、overall_tpstokensprompt、generatedspeculative汇总指标与各 stage 明细见下qualityok、error、retries_used、hit_eogprompt与output有效 prompt 文本与生成文本。compact 模式默认只保留核心字段task、run、ok、stop、generated、decode_s、decode_tps、各 stage 的drafts/draft_tokens/accepted/accept_percent/accept_length/按位置数组以及最后的 summary 行。核心指标定义源码级在 spec-bench.cpp 中明确定义acceptance_rate accepted_tokens / draft_tokens草稿 token 中被主模型接受的比例acceptance_length 1.0 accepted_tokens / num_drafts每轮投机平均接受的 token 数 1 个必然被接受的采样 token该定义在详细 JSON、compact JSON、Markdown 与重复汇总中完全一致按位置数组drafted_by_position[i]/accepted_by_position[i]中数组下标 0 对应投机位置 1即草稿序列的第 1 个 token派生数组acceptance_rate_by_position[i] accepted[i] / drafted[i]conditional_acceptance_rate[i] accepted[i] / accepted[i-1]其中下标 0 的 conditional 率为null没有前一个位置可作分母。每个 stage 的 JSON 明细还包含typestage 类型字符串来自common_speculative_type_to_str、num_drafts、accepted_drafts、draft_tokens、accepted_tokens以及t_begin_s、t_draft_s、t_accept_s三段时间对应投机解码的 begin/generation/accumulation 三个阶段。逐 stage 数据通过common_speculative_get_metrics_snapshot在任务前后的快照差值计算得出spec-bench.cpp因此多任务/多重复运行时每个任务只统计自身的增量。源码级运行机制一次 attempt 的核心流程在 spec_bench_run_attempt 中前置检查拒绝 encoder-decoder 模型解析任务预算计算有效 prompt启用 chat 模板时通过common_chat_format_single包装为单轮 user 消息见 spec-bench.cpptokenize 后校验 prompt 能放入上下文prompt_tokens n_ctx - 2状态重置common_sampler_reset采样器投机场景调用common_speculative_clear_sequence_kv非投机场景llama_kv_cache_clear并llama_reset_timingsprompt 阶段按n_batch分块llama_decode投机场景调用common_speculative_on_target_seq_batch做 prompt 预热warmupMTP 单级模式下会捕获 prompt 末尾的隐藏状态common_speculative_capture_output_hidden并跳过冗余的草稿历史传递生成阶段当剩余预算n_remain 3且投机可用时调用common_speculative_run_round执行一轮投机草稿生成 批量验证命中 EOG 即提前终止投机不可用或预算不足时退化为common_sampler_sample_legacy逐 token 采样spec-bench.cpp计时与统计分别记录prompt_sprompt 解码耗时、decode_s生成阶段耗时、total_s两者之和生成 token 数来自输出序列文本通过common_token_to_piece解码拼接。主循环对每个 task × repeat 执行 attempt--retry控制失败重试次数所有结果累加进 summaryspec-bench.cpp。进程退出码全部成功为0存在失败任务为2spec-bench.cpp方便脚本判断。使用注意事项与最佳实践原文档明确了几个容易踩坑的要点源码也印证了其必要性重复运行共享状态所有重复尝试都在同一个进程中执行因此有状态的草稿阶段——包括自适应 n-gram 阶段和 lookup 缓存——会把前面任务或重复轮次学到的状态带到后续运行。需要独立样本时务必使用--repeat 1并分开调用固定 chat 模板模式--jinja与--no-jinja会改变实际生效的 prompt见spec_bench_effective_prompt跨运行对比时必须固定否则 prompt 长度与内容的差异会污染基准结论不是 bit-identical 校验器投机验证在平局near-tie情况下可能与基线产生分歧因为批量求值会改变浮点归约顺序导致采样结果不同。因此本工具定位是性能与接受率基准不应作为输出逐字节一致性检查工具投机配置走标准参数草稿模型、--spec-type各 stage 及其键n_max、n_min、p_min、ngram_size_n、ngram_size_m、ngram_min_hits、suffix_*等的定义与用法与 docs/speculative.md 完全一致可直接参考该文档选取合适的 stage 组合再用本工具量化收益。完整示例三任务 JSONL 基准将内置三任务跑一遍、固定种子、关闭温度、每个任务生成 256 token并输出 JSONL 供后续分析./build/bin/llama-spec-bench \ -m model.gguf \ --seed 123 \ --temp 0 \ --predict 256 \ --output-format jsonl \ --task code,extract,story results.jsonl如需同时对比基线与投机配置只需在命令行追加对应的--spec-type如--spec-type ngram-mod:n_max64,n_min48,ngram_size_n24工具会在variant.spec_types与variant.is_baseline字段中记录配置配合--output-details输出同一任务在不同 stage 下的decode_tps、接受率与接受长度从而科学地评估投机解码的实际收益。【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/18 18:27:47

STM32调试迁移VS Code:GDB+OpenOCD+AI辅助实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 21:38:04

StarRocks DAYOFYEAR 函数详解:获取日期在一年中的第几天

StarRocks DAYOFYEAR 函数详解:获取日期在一年中的第几天 【免费下载链接】starrocks The worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks prov…

2026/9/18 21:33:04

Module `0x2::TestViz` <a id=“0x2_TestViz“></a>

Module 0x2::TestViz 【免费下载链接】aptos-core Aptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience. 项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core 标题使用反引号包…

2026/9/18 14:13:01

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/18 0:01:09

Google Colab 实战:运行模型、数据加载与报错排查

1. 为什么我劝你先搞懂 Colab 的运行模型1.1 Colab 到底是什么,跟本地跑代码差在哪Google Colab 简单说就是一台跑在浏览器里的 Linux 虚拟机,你打开一个 Notebook,背后就连上了一台带 GPU 的远程机器。你在单元格里敲的每一行 Python&#x…

2026/9/18 0:01:09

C语言数据类型与表达式详解

1. C语言数据与数据类型概述在C语言编程中,数据是程序处理的核心对象。理解数据的分类和特性是掌握C语言的基础。C语言中的数据主要分为四大类:常量、变量、表达式和函数。这些数据类型构成了C语言程序的基本元素,每种类型都有其独特的特性和…

2026/9/18 0:01:09

SQL时间字段指定时间段查询:区间语义、索引与时区避坑

上周排查一个线上问题&#xff0c;用户反馈"昨天的订单一条都没查到"&#xff0c;但数据库里明明躺着两千多条。最后定位下来&#xff0c;不是数据丢了&#xff0c;也不是接口挂了&#xff0c;而是那个查询条件把时间段写成了> 2024-05-20 00:00:00 AND < 2024…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行&#xff0c;Type-C接口算是典型的“看着简单&#xff0c;做起来全坑”的东西。光引脚就24个&#xff0c;高低速信号、电源、控制线全部塞在一个小小的连接器里&#xff0c;如果PCB布局不做规划&#xff0c;打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码