ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ik_llama.cpp 上下文扫描基准:llama-sweep-bench 使用指南与实现解析

ik_llama.cpp 上下文扫描基准:llama-sweep-bench 使用指南与实现解析 ik_llama.cpp 上下文扫描基准llama-sweep-bench 使用指南与实现解析【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cppllama-sweep-bench 是 ik_llama.cpp 仓库中新增的基准测试工具它沿整个上下文长度逐窗口扫描分别测量每个 ubatch 窗口下的提示处理PP与 Token 生成TG性能用于可视化性能随上下文长度的变化曲线。本文将以仓库中该功能的 README、源码与配套绘图脚本为主体完整讲解其设计动机、构建方式、命令行用法、指标含义、JSONL 输出与绘图流程并结合 sweep-bench.cpp 源码剖析其底层实现原理帮助你用它对不同量化、不同后端、不同 fork 的推理性能做横向对比。背景为什么需要一个按窗口扫描的基准工具该工具由贡献者saood06在 PR #225 Examples: Add new sweep-bench benchmark 中引入2025-02-23 创建2025-04-26 更新移植自上游 llama.cpp 的一个提交。PR 描述明确指出它是应 #223 中关于性能测试的讨论需求而加入的“一个很好的基准工具”。在 sweep-bench/README.md 中工具的目的被概括为通过在整个上下文大小上做扫描sweep在每个 ubatch 大小的窗口内收集性能指标来基准测试 ik_llama.cpp 的提示处理与 Token 生成性能。整个过程只使用单一 Token 序列。其核心价值在于不把指标在整个上下文上做平均——传统基准通常只报一个总吞吐量掩盖了上下文变长后性能衰减的细节而 sweep-bench 逐个窗口测量可以直观看出提示处理速度t/s如何随已填充的 KV cache 长度增长而下降Token 生成速度如何随上下文长度变化例如 CUDA 图、flash attention 等优化在不同上下文长度下的表现差异每个测量窗口还输出当前 KV cache 大小便于对齐曲线横轴。项目维护者 ikawrakow 在评审中批准了该 PR并评价“这会非常有用”社区成员 ubergarm 在评论中也表示“已经成为 llama-sweep-bench 的忠实用户”并提到自己在个人 fork 中使用它跨 fork 对比性能例如比较 GLM-4 的新性能表现。这说明该工具从诞生起就被实际用于跨 fork、跨量化的性能对比。扫描基准的核心流程按照 README 的描述基准对上下文中的每个 ubatch 大小窗口依次执行如下步骤生成ubatch/4个 Token只生成窗口的一部分以节省时间测量生成性能从 KV cache 中移除刚生成的 Token准备一批ubatch大小的随机 Token处理准备好的批测量提示处理性能。对应地外层循环见 sweep-bench.cpp按n_kv从 0 递增到n_kv_max步长为n_ubatch。每一轮先测生成TG再测提示处理PP。测量使用ggml_time_us()打点计时并对每次重复取平均t_pp (t_pp_end - t_pp_start) / 1e6 / nrept_tg (t_tg_end - t_tg_start) / 1e6 / nrep速度分别按pp / t_pp与tg / t_tg计算。其中 PP每窗口提示 Token 数取params.n_ubatchTG每窗口生成 Token 数在未显式指定-n时取n_ubatch / 4——这一点与 README 中“generate ubatch/4 tokens”的说明完全对应源码中tg params.n_predict 0 ? params.n_predict : params.n_ubatch / 4见 sweep-bench.cpp。构建与安装该工具作为独立 example 集成在 CMake 构建体系中顶层 examples 通过add_subdirectory(sweep-bench)引入见 examples/CMakeLists.txt子目录的 CMakeLists.txt 定义目标llama-sweep-bench链接common与llama库并要求 C17。因此在正常的 CMake 配置后编译即可得到可执行文件llama-sweep-bench。例如使用项目标准的 CMake 流程构建生成到build目录之后在build/bin/下即可找到该二进制。构建产物也会通过install(TARGETS ${TARGET} RUNTIME)安装到系统路径。命令行用法与参数README 给出的最简用法以 Meta-Llama-3.2-3B-Instruct Q8_0 模型为例./llama-sweep-bench -c 8704 -ub 512 -m models/Meta-Llama-3.2-3B-Instruct-Q8_0.gguf其中-c指定上下文长度即扫描范围n_kv_max-ub指定物理批大小同时作为每窗口的 PP Token 数-m指定 GGUF 模型路径。工具在print_usage见 sweep-bench.cpp中列出其专属选项同时在 common/common.cpp 中完成参数解析参数说明默认值-c, --ctx-size N上下文长度即扫描的最大 KV cache 大小n_kv_max512-b, --batch-size N提示处理的逻辑批大小需 ≥32 才能使用 BLAS2048-ub, --ubatch-size N提示处理的物理批大小需 ≥32 才能使用 BLAS同时决定每窗口 PP Token 数512-m, --modelGGUF 模型路径--n, --predict N每窗口生成 Token 数不指定时自动取n_ubatch / 4n_ubatch / 4-nrep, --n-repetitions N每个上下文窗口的重复测量次数用于绘制误差棒1--sweep-stride N每 N 个扫描行才测量一次用于快速采样长上下文1--sweep-memory报告 RSS 高水位HWM与采样到的 VRAM 增量关闭-wb, --warmup-batch正式测量前先运行一个热身批关闭--output-format FORMAT输出格式md表格默认或jsonlmd需要说明的是--sweep-stride与--sweep-memory仅在sweep_bench模式下生效见 common.cpp 中的params.sweep_bench 条件-nrep、-wb/--warmup-batch、--output-format为通用参数解析逻辑common.cpp、common.cpp。--output-format接受jsonl与md两种取值分别对应sweep_bench_output_jsonl的开关。这些默认值均可在 common/common.h 中核对n_batch 2048、n_ubatch 512、nrep 1、sweep_stride 1、sweep_memory false。除上述专属参数外它还继承gpt_params的全部通用选项因此你可以叠加使用-t线程数、-tb批线程数、-nglGPU 层数、-faflash attention、-ctk/-ctvKV cache 量化类型如q8_KV、q8_0等。PR 描述中作者给出的演示命令就是一个典型组合./llama-sweep-bench -c 2048 -ub 512 -m WizardLM-2-8x22B-IQ4_K_R4.gguf \ -ctk q8_KV -ctv q8_0 -fa --output-format jsonl即上下文 2048、ubatch 512、对 KV cache 使用q8_KV/q8_0量化、启用 flash attention并以 JSONL 输出随后用sweep-bench-plot.py绘图对比。输出指标与示例结果README 中定义了每个指标的准确含义指标含义PP每个 ubatch 窗口的提示 Token 数n_ubatchTG每个 ubatch 窗口生成的 Token 数默认 n_ubatch / 4N_KV当前 KV cache 大小T_PP提示处理时间即首 Token 时间S_PP提示处理速度(B*PP)/T_PP或PP/T_PPt/sT_TG生成整批 Token 的时间S_TG文本生成速度(B*TG)/T_TGt/sREADME 给出的 Markdown 表格示例-c 8704 -ub 512PP512、TG128PPTGN_KVT_PP sS_PP t/sT_TG sS_TG t/s51212801.100465.512.31155.385121285121.183432.971.89567.5551212810241.305392.382.07161.8151212815361.279400.422.16459.1451212820481.571325.962.28056.1451212825601.431357.872.41852.9451212830721.515337.932.56649.8851212835841.588322.342.72247.0351212840961.675305.702.86444.6951212846081.769289.502.99942.6851212851201.845277.483.10241.2651212856321.893270.463.21939.7651212861441.953262.203.34838.2351212866562.018253.713.47436.8451212871682.078246.343.58935.6651212876802.140239.223.71734.4351212881922.196233.153.85433.21从这张表可以清晰读出提示处理速度从上下文为空时的约 465 t/s 单调下降到 8K 时的约 233 t/s生成速度也从 55 t/s 左右缓慢衰减到 33 t/s 左右。这正是该工具“可视化性能随上下文长度变化”的直观呈现——而传统基准只给出一个平均数字无法暴露这种衰减曲线。开启--sweep-memory后表格还会追加RSS HWM与VRAM delta两列分别由get_rss_hwm_mib()基于getrusage读取ru_maxrss见 sweep-bench.cpp和sweep_vram_tracker基于ggml_backend_cuda_get_device_memory计算 CUDA 显存增量见 sweep-bench.cpp提供可用于观察不同上下文长度下内存/显存的高水位增长。非 CUDA 构建或 Windows 平台上对应值为n/a。JSONL 输出与绘图脚本JSONL 输出传入--output-format jsonl后每行输出一条 JSON 记录。README 中的示例-c 8704 -b 2048 -ub 51232 线程如下{n_kv_max: 8704, n_batch: 2048, n_ubatch: 512, flash_attn: 0, n_gpu_layers: -1, n_threads: 32, n_threads_batch: 32, pp: 512, tg: 128, n_kv: 0, t_pp: 1.093814, speed_pp: 468.086884, t_tg: 1.780312, speed_tg: 71.897514 } {n_kv_max: 8704, n_batch: 2048, n_ubatch: 512, flash_attn: 0, n_gpu_layers: -1, n_threads: 32, n_threads_batch: 32, pp: 512, tg: 128, n_kv: 512, t_pp: 1.169302, speed_pp: 437.868073, t_tg: 1.897474, speed_tg: 67.458099 } {n_kv_max: 8704, n_batch: 2048, n_ubatch: 512, flash_attn: 0, n_gpu_layers: -1, n_threads: 32, n_threads_batch: 32, pp: 512, tg: 128, n_kv: 1024, t_pp: 1.183700, speed_pp: 432.542053, t_tg: 2.059179, speed_tg: 62.160694 } {n_kv_max: 8704, n_batch: 2048, n_ubatch: 512, flash_attn: 0, n_gpu_layers: -1, n_threads: 32, n_threads_batch: 32, pp: 512, tg: 128, n_kv: 1536, t_pp: 1.428625, speed_pp: 358.386566, t_tg: 2.160639, speed_tg: 59.241734 } {n_kv_max: 8704, n_batch: 2048, n_ubatch: 512, flash_attn: 0, n_gpu_layers: -1, n_threads: 32, n_threads_batch: 32, pp: 512, tg: 128, n_kv: 2048, t_pp: 1.360647, speed_pp: 376.291595, t_tg: 2.274003, speed_tg: 56.288403 }每条记录包含完整的测量环境信息n_kv_max、n_batch、n_ubatch、flash_attn、n_gpu_layers、n_threads、n_threads_batch以及该窗口的pp、tg、n_kv、t_pp、speed_pp、t_tg、speed_tg。开启--sweep-memory时还会追加rss_hwm_mib与vram_delta_mib字段不可用时为null见 sweep-bench.cpp。JSONL 格式非常适合程序化处理、脚本汇总与绘图。绘图脚本 sweep-bench-plot.py仓库提供了配套脚本 sweep-bench-plot.py基于 pandas matplotlib 实现。它的用法是python3 sweep-bench-plot.py result_1.md result_2.md ... # 或 python3 sweep-bench-plot.py result_1.jsonl result_2.jsonl ...脚本能力要点与 README 和 PR 演示一致可同时传入多个结果文件nargs自动以文件名为每条曲线的 label当前实现优先按 Markdown 表格解析pd.read_csv按|分隔同时保留了读取 JSONL 的注释代码段两种格式都可被 pandas 处理按label与n_kv分组计算speed_pp与speed_tg的均值与标准差单样本标准差以 0 填充因此配合-nrep多次重复测量可画出带误差棒的曲线生成两张图并保存到当前目录performance_comparison_pp.png横轴 Context Length纵轴 Prompt Processing Rate圆形标记与performance_comparison_tg.png横轴 n_kv纵轴 Token Generation Rate方形标记横轴刻度超过 16 个时自动隔点采样保持可读性。PR 作者正是“运行llama-sweep-bench后直接拿输出跑sweep-bench-plot.py”得到对比图的——这也是推荐的完整工作流先用 JSONL/MD 收集多组数据再一次性绘图对比。源码级实现解析深入 sweep-bench.cpp 可以进一步理解几个关键设计1. 批量解码辅助函数。decode_helper把一次可能很大的llama_batch按n_batch切片后逐段调用llama_decode并在每段后调用llama_synchronize确保异步后端如 CUDA真正完成计算避免计时失真sweep-bench.cpp。2. 随机 Token 构造。提示处理批与生成批都不依赖真实文本而是用std::rand() % n_vocab生成随机 Tokenpp_helper见 sweep-bench.cpp保证每个窗口的负载一致且可复现只测“纯计算”性能。3. KV cache 的推进与回卷。每轮生成完成后用llama_kv_cache_seq_rm移除超出当前n_kv的 Token随后再重新填充一个 ubatch 大小的随机批从而精确控制每个窗口的起始 KV 长度。代码中还保留了对支持 checkpoint 恢复的模型common_speculative_needs_checkpoint例如需要状态保存的推测解码/DSV 场景的分支处理使用llama_state_seq_get_data/llama_state_seq_set_data保存并在测量后恢复序列状态sweep-bench.cpp。4. 热身。-wb/--warmup-batch对应params.batch_warmup在正式测量前先解码一个 BOS Token 批与一个 ubatch 大小的随机批让 GPU 驱动、缓存与 CUDA graph 等完成初始化避免把冷启动开销计入计时sweep-bench.cpp。5. 精简日志。--minilog模式通过llama_selective_log_callback过滤掉模型加载时的元数据 dump、层大小、llm_load_tensors:等冗长输出sweep-bench.cpp让基准输出更干净、更适合脚本解析。6. 计时与循环。主循环从n_kv 0到n_kv_max以n_ubatch为步长推进--sweep-stride用于跳过中间窗口只做测量未测量窗口仍执行相同计算以保持状态流一致见 sweep-bench.cpp结束时调用llama_print_timings汇总整体统计。典型应用场景综合 PR 描述、README 与社区反馈该工具最典型的用途包括量化方案对比同一模型的不同 GGUF 量化如 README 演示用的Q8_0、PR 演示用的IQ4_K_R4在同一上下文扫描下对比 PP/TG 曲线判断哪种量化在长上下文下更划算KV cache 量化与注意力优化验证通过-ctk/-ctv与-fa组合量化对比 flash attention 开启/关闭、KV cache 量化前后在不同上下文长度下的性能差异跨 fork / 跨构建对比如社区成员所述用同一套命令在不同 fork、不同后端CPU 线程数、GPU offload 层数等上跑出可比曲线直接叠图观察差异内存/显存增长观测配合--sweep-memory观察长上下文下 RSS 与 VRAM 的高水位变化为部署容量规划提供依据。需要注意的适用前提基准使用随机 Token 与单一序列测的是纯计算吞吐而非真实应用负载n_batch/n_ubatch需 ≥32 才能启用 BLAS 加速路径结果受线程数、GPU offload 层数、是否启用 flash attention 等参数影响做对比时应保持除被测变量外的其他参数一致。小结llama-sweep-bench 通过“逐 ubatch 窗口扫描整个上下文”的方式把提示处理与 Token 生成性能随上下文长度的变化曲线完整呈现出来弥补了传统平均指标的信息损失。它既是一个即用型的命令行基准工具-c/-ub/-nrep/--sweep-stride/--sweep-memory/--output-format等参数开箱即用又通过 sweep-bench-plot.py 提供一键绘图能力而 sweep-bench.cpp 源码则展示了批量解码、KV cache 回卷、checkpoint 恢复、内存跟踪等完整的基准工程实现值得作为自研基准工具的参考范本。相关参考文件功能文档与示例examples/sweep-bench/README.md基准实现examples/sweep-bench/sweep-bench.cpp绘图脚本examples/sweep-bench/sweep-bench-plot.py构建配置examples/sweep-bench/CMakeLists.txt、examples/CMakeLists.txt参数定义与解析common/common.h、common/common.cpp引入该工具的 PR 记录github-data/pull_requests/225 - Examples _ Add new sweep-bench benchmark.md【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表