ik_llama.cpp 性能基准测试指南:llama-bench 参数详解、实战用法与源码原理 ik_llama.cpp 性能基准测试指南llama-bench 参数详解、实战用法与源码原理【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cppllama-bench 是 ik_llama.cpp 仓库内置的性能测试工具用于在给定硬件CPU/GPU与模型配置下测量大模型推理的关键指标——Prompt 处理pp与文本生成tg的吞吐量。本文以 examples/llama-bench/README.md 为骨架结合 llama-bench.cpp 源码完整讲解全部命令行参数、四种测试类型、四种输出格式与批量组合测试逻辑并深入剖析其计时与吞吐计算原理帮助你在选购硬件、对比量化方案、调优部署参数时获得可复现、可归档的基准数据。llama-bench 是什么定位与适用场景llama-bench 是专门为 llama.cpp 系推理引擎设计的性能测试工具Performance testing tool for llama.cpp。它不做真实对话生成而是通过随机 token驱动推理管线分别测量两种核心负载Prompt processingpp以给定 batch 大小批量处理一段 prompt衡量预填充prefill阶段的吞吐单位是每秒处理多少 tokenText generationtg逐 token 自回归生成一段文本衡量解码decode阶段的速度同样以 t/s 计。这两个指标分别对应真实业务中的首 token 延迟敏感的长上下文处理与流式输出吞吐是评估模型、量化格式、硬件组合最常用的量化基准。在 ik_llama.cpp 这类以量化与性能优化为卖点的 fork 中llama-bench 也是验证新量化类型如 IQx_KS 系列与后端优化效果的标准工具。构建 llama-benchllama-bench 位于 examples/llama-bench/其构建通过 examples/CMakeLists.txt 中的add_subdirectory(llama-bench)纳入顶层工程。按照标准流程配置并编译即可cmake -B build -DCMAKE_BUILD_TYPERelease cmake --build build --target llama-bench -j编译产物llama-bench会出现在build/bin/下。其 CMakeLists.txt 显示它链接common与llama两个库因此会自动继承构建时启用的后端能力CUDA/Vulkan/Metal/SYCL/CANN 等。提示源码在非 Release 构建下会打印warning: asserts enabled, performance may be affected/debug build, performance may be affectedllama-bench.cpp基准测试请务必使用 Release 优化构建否则测得的 t/s 会失真。命令行语法与全部参数运行./llama-bench -h可查看完整帮助。以下为完整参数表括号内为默认值均来自 cmd_params_defaults 与print_usageusage: ./llama-bench [options] options: -h, --help -m, --model filename (default: models/7B/ggml-model-q4_0.gguf) -p, --n-prompt n (default: 512) -n, --n-gen n (default: 128) -pg pp,tg (default: 512,128) -b, --batch-size n (default: 2048) -ub, --ubatch-size n (default: 512) -ctk, --cache-type-k t (default: f16) -ctv, --cache-type-v t (default: f16) -t, --threads n (default: 16) -ngl, --n-gpu-layers n (default: 99) -sm, --split-mode none|layer|row (default: layer) -mg, --main-gpu i (default: 0) -nkvo, --no-kv-offload 0|1 (default: 0) -fa, --flash-attn 0|1 (default: 0) -mmp, --mmap 0|1 (default: 1) --numa distribute|isolate|numactl (default: disabled) -embd, --embeddings 0|1 (default: 0) -ts, --tensor-split ts0/ts1/.. (default: 0) -r, --repetitions n (default: 5) -o, --output csv|json|md|sql (default: md) -v, --verbose (default: 0) Multiple values can be given for each parameter by separating them with , or by specifying the parameter multiple times.各参数的核心作用如下参数作用-m指定 GGUF 模型文件路径可重复指定以依次测试多个模型-pPrompt 长度token 数控制 pp 测试的输入规模-n生成 token 数控制 tg 测试的生成长度-pg先处理指定长度 prompt、再生成指定长度 token 的组合测试-bbatch size即单次 decode 调用一次性送入的 token 数pp 吞吐的关键变量-ubmicro-batch sizeubatch控制计算图内部子批次切分-ctk/-ctvKV cache 中 K/V 张量的数据类型支持f16、bf16、q8_0、q4_0、q4_1、q5_0、q5_1、iq4_nl、q6_0、q8_KV见源码ggml_type_from_namellama-bench.cpp-t线程数默认取机器逻辑核心数源码为cpu_get_num_math()-ngl卸载到 GPU 的层数是 CPU/GPU 混合部署的核心旋钮-sm多 GPU 拆分模式注意当前仓库源码实际支持none|layer|graphllama-bench.cpp-mg主 GPU 编号-nkvo是否不把 KV cache 卸载到 GPU-fa是否启用 Flash Attention-mmp是否用 mmap 映射模型文件--numaNUMA 策略distribute/isolate/numactl多路 CPU 服务器必测项-embd是否以 embedding 模式加载模型只输出向量、不做生成-ts多 GPU 下 tensor 拆分比例用/分隔如-ts 0.5/0.5-r每个测试的重复次数结果取平均并计算标准差-o输出格式csv/json/md/sql-v详细日志默认关闭此时会以空回调静默 llama 日志llama-bench.cpp注意README 中-sm写作row但当前仓库源码的split_mode_str与参数解析实际接受graph以源码为准。四种测试类型与多值组合机制llama-bench 定义了四种测试类型源码枚举test_kind_typellama-bench.cpppp仅测 prompt 处理由-p触发n_prompt 0tg仅测 token 生成由-n触发n_gen 0pg先 pp 后 tg 的联合测试由-pg pp,tg触发报告标签为pp512tg128形式gp先处理给定长度 prompt不计时再测生成——用于模拟长上下文预热后的生成报告标签为tg128pp512形式由-gp pp,tg触发这是源码中比 README 更完整的额外类型。默认情况下给定-p 512 -n 128会同时生成一个 pp512 测试和一个 tg128 测试。组合机制除-r、-o、-v外所有参数都支持多值——用逗号分隔-n 16,32或重复指定-n 16 -n 32。测试实例生成器get_cmd_params_instancesllama-bench.cpp会对所有参数的取值做笛卡尔积每个 pp 与 tg 测试都会与其它参数的所有组合各跑一遍。同时该函数对循环顺序做了专门编排源码注释 this ordering minimizes the number of times that each model needs to be reloaded让相同模型参数的测试尽量连续配合主循环中的equal_mparams判断llama-bench.cpp复用已加载的模型避免每个组合都重新加载模型、显著缩短批量测试总时长。每个测试按-r指定的次数重复默认 5 次结果以平均 t/s 与标准差呈现JSON 输出还会给出每次重复的原始样本。实战示例四类典型基准场景1. 对比不同模型的文本生成速度$ ./llama-bench -m models/7B/ggml-model-q4_0.gguf -m models/13B/ggml-model-q4_0.gguf -p 0 -n 128,256,512modelsizeparamsbackendngltestt/sllama 7B mostly Q4_03.56 GiB6.74 BCUDA99tg 128132.19 ± 0.55llama 7B mostly Q4_03.56 GiB6.74 BCUDA99tg 256129.37 ± 0.54llama 7B mostly Q4_03.56 GiB6.74 BCUDA99tg 512123.83 ± 0.25llama 13B mostly Q4_06.86 GiB13.02 BCUDA99tg 12882.17 ± 0.31llama 13B mostly Q4_06.86 GiB13.02 BCUDA99tg 25680.74 ± 0.23llama 13B mostly Q4_06.86 GiB13.02 BCUDA99tg 51278.08 ± 0.07-p 0表示跳过 prompt 处理只测纯生成-n 128,256,512顺带观察生成长度对吞吐的影响可见生成长度越长、平均吞吐略降这与 KV cache 占用和内存带宽有关。2. 不同 batch size 下的 Prompt 处理吞吐$ ./llama-bench -n 0 -p 1024 -b 128,256,512,1024modelsizeparamsbackendngln_batchtestt/sllama 7B mostly Q4_03.56 GiB6.74 BCUDA99128pp 10241436.51 ± 3.66llama 7B mostly Q4_03.56 GiB6.74 BCUDA99256pp 10241932.43 ± 23.48llama 7B mostly Q4_03.56 GiB6.74 BCUDA99512pp 10242254.45 ± 15.59llama 7B mostly Q4_03.56 GiB6.74 BCUDA991024pp 10242498.61 ± 13.58-n 0跳过生成。这张表清晰展示了 batch size 对 prefill 吞吐的放大效应128→1024 吞吐近乎翻倍是调优-b参数的直接依据。3. 不同线程数下的 CPU 性能曲线$ ./llama-bench -n 0 -n 16 -p 64 -t 1,2,4,8,16,32modelsizeparamsbackendthreadstestt/sllama 7B mostly Q4_03.56 GiB6.74 BCPU1pp 646.17 ± 0.07llama 7B mostly Q4_03.56 GiB6.74 BCPU1tg 164.05 ± 0.02llama 7B mostly Q4_03.56 GiB6.74 BCPU2pp 6412.31 ± 0.13llama 7B mostly Q4_03.56 GiB6.74 BCPU2tg 167.80 ± 0.07llama 7B mostly Q4_03.56 GiB6.74 BCPU4pp 6423.18 ± 0.06llama 7B mostly Q4_03.56 GiB6.74 BCPU4tg 1612.22 ± 0.07llama 7B mostly Q4_03.56 GiB6.74 BCPU8pp 6432.29 ± 1.21llama 7B mostly Q4_03.56 GiB6.74 BCPU8tg 1616.71 ± 0.66llama 7B mostly Q4_03.56 GiB6.74 BCPU16pp 6433.52 ± 0.03llama 7B mostly Q4_03.56 GiB6.74 BCPU16tg 1615.32 ± 0.05llama 7B mostly Q4_03.56 GiB6.74 BCPU32pp 6459.00 ± 1.11llama 7B mostly Q4_03.56 GiB6.74 BCPU32tg 1616.41 ± 0.79pp 与 tg 两条曲线随线程数的表现明显不同pp 随线程数持续增长矩阵乘法并行度高tg 则在 8~16 线程后趋于饱和甚至回落自回归解码是内存带宽受限的串行过程。这解释了为何生成场景线程开得过多反而无益。4. 不同 GPU 卸载层数下的混合部署曲线$ ./llama-bench -ngl 10,20,30,31,32,33,34,35modelsizeparamsbackendngltestt/sllama 7B mostly Q4_03.56 GiB6.74 BCUDA10pp 512373.36 ± 2.25llama 7B mostly Q4_03.56 GiB6.74 BCUDA10tg 12813.45 ± 0.93llama 7B mostly Q4_03.56 GiB6.74 BCUDA20pp 512472.65 ± 1.25llama 7B mostly Q4_03.56 GiB6.74 BCUDA20tg 12821.36 ± 1.94llama 7B mostly Q4_03.56 GiB6.74 BCUDA30pp 512631.87 ± 11.25llama 7B mostly Q4_03.56 GiB6.74 BCUDA30tg 12840.04 ± 1.82llama 7B mostly Q4_03.56 GiB6.74 BCUDA31pp 512657.89 ± 5.08llama 7B mostly Q4_03.56 GiB6.74 BCUDA31tg 12848.19 ± 0.81llama 7B mostly Q4_03.56 GiB6.74 BCUDA32pp 512688.26 ± 3.29llama 7B mostly Q4_03.56 GiB6.74 BCUDA32tg 12854.78 ± 0.65llama 7B mostly Q4_03.56 GiB6.74 BCUDA33pp 512704.27 ± 2.24llama 7B mostly Q4_03.56 GiB6.74 BCUDA33tg 12860.62 ± 1.76llama 7B mostly Q4_03.56 GiB6.74 BCUDA34pp 512881.34 ± 5.40llama 7B mostly Q4_03.56 GiB6.74 BCUDA34tg 12871.76 ± 0.23llama 7B mostly Q4_03.56 GiB6.74 BCUDA35pp 5122400.01 ± 7.72llama 7B mostly Q4_03.56 GiB6.74 BCUDA35tg 128131.66 ± 0.49注意 35 层全量卸载处 pp 与 tg 的吞吐出现跳变式提升此前每层卸载带来的收益是线性的而全量卸载消除了 CPU↔GPU 间的同步与调度开销。这是用-ngl决定该把多少层放 GPU时的经典决策数据。输出格式从控制台表格到可归档数据库默认输出为 Markdown-o md其余三种格式通过-o切换CSV$ ./llama-bench -o csvbuild_commit,build_number,cuda,metal,gpu_blas,blas,cpu_info,gpu_info,model_filename,model_type,model_size,model_n_params,n_batch,n_threads,f16_kv,n_gpu_layers,main_gpu,mul_mat_q,tensor_split,n_prompt,n_gen,test_time,avg_ns,stddev_ns,avg_ts,stddev_ts 3469684,1275,1,0,0,1,1,13th Gen Intel(R) Core(TM) i9-13900K,NVIDIA GeForce RTX 3090 Ti,models/7B/ggml-model-q4_0.gguf,llama 7B mostly Q4_0,3825065984,6738415616,512,16,1,99,0,1,0.00,512,0,2023-09-23T12:09:01Z,212155977,732372,2413.341687,8.305961 3469684,1275,1,0,0,1,1,13th Gen Intel(R) Core(TM) i9-13900K,NVIDIA GeForce RTX 3090 Ti,models/7B/ggml-model-q4_0.gguf,llama 7B mostly Q4_0,3825065984,6738415616,512,16,1,99,0,1,0.00,0,128,2023-09-23T12:09:02Z,969320879,2728399,132.052051,0.371342CSV 首行为字段表头数据行中的字符串字段统一用双引号包裹源码csv_printer::escape_csv会转义内部引号便于导入 Excel 或 pandas 做多轮对比。JSON$ ./llama-bench -o json[ { build_commit: 3469684, build_number: 1275, cuda: true, metal: false, gpu_blas: true, blas: true, cpu_info: 13th Gen Intel(R) Core(TM) i9-13900K, gpu_info: NVIDIA GeForce RTX 3090 Ti, model_filename: models/7B/ggml-model-q4_0.gguf, model_type: llama 7B mostly Q4_0, model_size: 3825065984, model_n_params: 6738415616, n_batch: 512, n_threads: 16, f16_kv: true, n_gpu_layers: 99, main_gpu: 0, mul_mat_q: true, tensor_split: 0.00, n_prompt: 512, n_gen: 0, test_time: 2023-09-23T12:09:57Z, avg_ns: 212365953, stddev_ns: 985423, avg_ts: 2410.974041, stddev_ts: 11.163766, samples_ns: [ 213837238, 211635853, 212328053, 211329715, 212698907 ], samples_ts: [ 2394.34, 2419.25, 2411.36, 2422.75, 2407.16 ] }, { build_commit: 3469684, build_number: 1275, cuda: true, metal: false, gpu_blas: true, blas: true, cpu_info: 13th Gen Intel(R) Core(TM) i9-13900K, gpu_info: NVIDIA GeForce RTX 3090 Ti, model_filename: models/7B/ggml-model-q4_0.gguf, model_type: llama 7B mostly Q4_0, model_size: 3825065984, model_n_params: 6738415616, n_batch: 512, n_threads: 16, f16_kv: true, n_gpu_layers: 99, main_gpu: 0, mul_mat_q: true, tensor_split: 0.00, n_prompt: 0, n_gen: 128, test_time: 2023-09-23T12:09:59Z, avg_ns: 977425219, stddev_ns: 9268593, avg_ts: 130.965708, stddev_ts: 1.238924, samples_ns: [ 984472709, 974901233, 989474741, 970729355, 967548060 ], samples_ts: [ 130.019, 131.295, 129.362, 131.86, 132.293 ] } ]JSON 格式是信息最全的除聚合值avg_ns/stddev_ns/avg_ts/stddev_ts外还通过samples_ns/samples_ts数组给出每次重复的原始耗时与吞吐样本源码json_printer::print_testllama-bench.cpp适合做分布分析。SQL$ ./llama-bench -o sqlCREATE TABLE IF NOT EXISTS test ( build_commit TEXT, build_number INTEGER, cuda INTEGER, metal INTEGER, gpu_blas INTEGER, blas INTEGER, cpu_info TEXT, gpu_info TEXT, model_filename TEXT, model_type TEXT, model_size INTEGER, model_n_params INTEGER, n_batch INTEGER, n_threads INTEGER, f16_kv INTEGER, n_gpu_layers INTEGER, main_gpu INTEGER, mul_mat_q INTEGER, tensor_split TEXT, n_prompt INTEGER, n_gen INTEGER, test_time TEXT, avg_ns INTEGER, stddev_ns INTEGER, avg_ts REAL, stddev_ts REAL ); INSERT INTO test (build_commit, build_number, cuda, metal, gpu_blas, blas, cpu_info, gpu_info, model_filename, model_type, model_size, model_n_params, n_batch, n_threads, f16_kv, n_gpu_layers, main_gpu, mul_mat_q, tensor_split, n_prompt, n_gen, test_time, avg_ns, stddev_ns, avg_ts, stddev_ts) VALUES (3469684, 1275, 1, 0, 0, 1, 1, 13th Gen Intel(R) Core(TM) i9-13900K, NVIDIA GeForce RTX 3090 Ti, models/7B/ggml-model-q4_0.gguf, llama 7B mostly Q4_0, 3825065984, 6738415616, 512, 16, 1, 99, 0, 1, 0.00, 512, 0, 2023-09-23T12:10:30Z, 212693772, 743623, 2407.240204, 8.409634);SQL 输出专为导入 SQLite 设计文档明确说明 SQL output is suitable for importing into a SQLite database可直接管道给sqlite3$ ./llama-bench -o sql | sqlite3 benchmarks.db这样就能把历次测试累积到同一张test表中用 SQL 直接查询不同 commit、不同量化、不同硬件的吞吐演化。字段类型映射见源码sql_printer::get_sql_field_typellama-bench.cpp。源码原理llama-bench 如何测量吞吐环境信息自动采集每次测试结果会带上构建与硬件元信息llama-bench.cppbuild_commit取自LLAMA_COMMIT、build_number取自LLAMA_BUILD_NUMBERcuda/vulkan/metal/sycl/gpu_blas/blas由ggml_cpu_has_*系列接口在运行时探测CPU 型号在 Linux 上解析/proc/cpuinfo、在 Windows 上读注册表ProcessorNameStringget_cpu_infollama-bench.cppGPU 信息通过 CUDA/SYCL/CANN 后端接口枚举get_gpu_info。这些字段让历史结果天然可追溯、可复现。计时与吞吐计算主流程位于main()llama-bench.cpp解析参数 → 初始化后端与 NUMA → 创建输出 printer对每个测试实例在相同模型参数时复用已加载模型equal_mparams比较 n_gpu_layers、split_mode、tensor_split 等否则llama_model_load_from_file重新加载每个实例先用llama_init_from_model创建上下文清空 KV cache 后先跑一轮 warmup各 1 个 tokenparams.warmup默认开启规避冷启动与缓存加载对首次测量的污染正式测量循环-r次清空 KV cache →get_time_ns()记录起点 →test_prompt/test_gen→ 记录耗时纳秒存入samples_ns。test_prompt以 batch 为单位用std::rand() % n_vocab生成随机 token 填充输入并反复llama_decodellama-bench.cpptest_gen则每轮 decode 一个 tokenllama-bench.cpp。计时器get_time_ns基于std::chrono::high_resolution_clockllama-bench.cpp。吞吐换算在test::get_ts()llama-bench.cppt/s 1e9 * n_tokens / t_ns其中n_tokens为n_prompt n_gengp 类型不计入预热的 prompt 长度。平均值与标准差由模板函数avg/stdev计算llama-bench.cppMarkdown 表格中的t/s列按%.2f ± %.2f渲染。Markdown 表格的动态列Markdown printer 的列并非固定会根据本次运行是否改动某参数动态决定是否展示该列llama-bench.cpp。例如只有显式改动了 batch size 或线程数时才出现n_batch/threads列CPU 后端恒显示线程列GPU 后端恒显示ngl列。因此不同场景的输出表格结构可能不同但始终包含 model、size、params、backend、test、t/s 六列保证可读性。ik_llama.cpp 扩展参数覆盖 fork 特色优化开关相比上游当前仓库的 llama-bench 增加了大量用于验证 fork 特有优化的开关参数在基准测试时可用它们逐一开关、量化每项优化的收益-fa/--flash-attn、-mla/--mla-use 0|1|2、-amb/--attention-max-batch注意力相关Flash Attention、MLA 使用模式-rtr/--run-time-repack运行期张量重打包-mqkv/--merge-qkv、-muge/--merge-up-gate-experts、-fmoe/--fused-moe、-ger/--grouped-expert-routing、-no-fug/--no-fused-up-gate、-no-ooae/--no-offload-only-active-expertsMoE 模型的计算融合与专家路由优化-ser/--smart-expert-reduction i,f智能专家裁剪min_experts, thresh_experts-gr/--graph-reuse、-sas/--scheduler-async计算图复用与异步调度-thp/--transparent-huge-pages、--defer-expertsLinux only内存与加载策略-cuda/--cuda-params、-ot/--override-tensor、--n-cpu-moe nCUDA 参数透传与张量放置覆盖如把指定 MoE 层专家权重强制放 CPU--fit/--fit-margin、--max-gpu显存自适应放置-rcache/--rope-cacheRoPE 缓存-tgb/--threads-gen-batch n1,n2分别为 pp 与 tg 阶段指定不同线程数内部以std::pairint,int存储-oe/--output-err把结果额外输出到 stderr可同时用两种格式如 stdout 出 md、stderr 出 json-w/--warmup 0|1开关预热轮。这些参数与-ot一起使 llama-bench 不仅能测默认配置的性能还能系统性地为 MoE 量化、专家卸载、计算融合等优化做 A/B 验证。配套脚本量化对比与历史回归仓库还提供了两个与 llama-bench 配套的脚本可将单次基准扩展为规模化对比scripts/run-all-perf.sh对同一模型的多种量化格式依次跑 benchmark默认量化列表为f16 q8_0 q6_k q5_k q5_1 q5_0 q4_k q4_1 q4_0 q3_k q2_k默认参数为-ngl 999 -n 64 -p 512用法./scripts/run-all-perf.sh model [qnt] [args]结果输出到../tmp/results-model/。适合做量化格式 × 吞吐全景对比。scripts/compare-llama-bench.py基于 git 历史对比不同 commit 的基准结果用于回归检测——某次优化提交是否让 pp/tg 变慢可以脚本化地自动发现。使用注意事项SYCL 后端的已知问题文档明确提示使用 SYCL 后端时某些情况下会出现挂起hang需要设置--mmp 0关闭 mmap 规避。务必使用 Release 构建调试构建与开启断言会显著拉低 t/s测出的数据不具备参考意义。关闭 verbose 以获得干净输出非-v模式会用空回调静默 llama 日志llama-bench.cpp保证 stdout 只有结果表格方便管道处理。-p 0与-n 0的语义置 0 表示跳过该类型的测试可用于只测 pp 或只测 tg。多值参数会做笛卡尔积谨慎组合取值数量-t 1,2,4,8 -n 16,32 -p 64,128会产生 16 组测试每组重复-r次总耗时可能很长。若需理解其它通用选项如--numa与上下文参数的详细行为可参阅 examples/main/README.md 中对 main 例子的说明。综合来看llama-bench 兼具单次快速测量与规模化回归对比两种用法日常调参用-r 5 -o md快速看趋势量化选型用 run-all-perf.sh 批量扫描长期跟踪用-o sql把每次结果沉淀进 SQLite 数据库再结合 compare-llama-bench.py 做提交级回归分析——这套工作流正是围绕 llama-bench 构建可复现性能基准的完整闭环。【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考