ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

llama.cpp 测试调试实战指南:用 debug-test.sh 快速定位并 GDB 调试单个 ctest 用例

llama.cpp 测试调试实战指南:用 debug-test.sh 快速定位并 GDB 调试单个 ctest 用例 llama.cpp 测试调试实战指南用 debug-test.sh 快速定位并 GDB 调试单个 ctest 用例【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp在 llama.cpp 这样的 C 项目中测试套件覆盖分词器、采样、量化、KV Cache 状态恢复等大量模块全量跑一遍ctest反馈周期很长。本文基于官方开发文档 调试测试技巧讲解如何使用仓库内置的 scripts/debug-test.sh 脚本按正则快速筛选、执行或进入 GDB 调试单个测试用例并拆解脚本背后的 ctest 工作机制、tests/CMakeLists.txt 中的用例注册方式帮助你在改动源码后以最短反馈闭环定位问题。快速上手debug-test.sh 的用法仓库scripts目录下提供了 debug-test.sh 脚本它接受一个测试名正则REGEX和一个可选的测试编号test number一条命令即可完成“重建 Debug 构建目录 → 编译 → 定位用例 → 执行或进入调试器”的全流程。命令形式为debug-test.sh [OPTION]... test_regex test_number支持的选项可通过debug-test.sh -h查看完整帮助源码见 print_full_help选项说明-h, --help显示帮助信息并退出-g以 GDB 模式运行编译完成后自动进入gdb --args 测试命令会话test_regex必填用于筛选测试用例的正则表达式test_number可选直接指定要运行的测试编号跳过交互式选择示例一列出并交互式选择测试./scripts/debug-test.sh test-tokenizer脚本会编译后输出一个可交互的测试列表从中选择一个测试即可随后脚本会在调试环境中构建并运行它。示例二只执行测试获得 PASS / FAIL 结果./scripts/debug-test.sh test-tokenizer不带测试编号时脚本会先列出所有匹配的测试供选择执行结束后会打印TEST PASS绿色或TEST FAIL红色以及完整的测试命令便于复现。示例三进入 GDB 调试./scripts/debug-test.sh -g test-tokenizer # 进入调试器后chevrons 提示符下可以设置断点例如 b main示例四已知编号直接运行最快闭环./scripts/debug-test.sh test 23当你已经通过ctest -N之类的方式知道测试编号时直接传编号可以省去交互选择步骤。脚本内部实现剖析五个步骤文档“How does the script work?”一节将脚本拆解为五个可独立复用的步骤。下面对照 scripts/debug-test.sh 源码逐步说明每一步都可以在没有脚本的情况下手动执行。前置检查依赖与参数解析脚本开头会强制检查ctest和cmake是否存在见 check_dependency缺失时直接报错退出随后通过getopts解析-g选项并把第一个位置参数作为test_regex必填、第二个作为test_number可选。步骤 1重置并准备构建目录从仓库根目录出发脚本固定使用build-ci-debug作为构建上下文目录每次运行都会先删除再重建保证构建状态干净rm -rf build-ci-debug mkdir build-ci-debug cd build-ci-debug对应源码中build_dirbuild-ci-debug常量与 重置逻辑。脚本还通过git rev-parse --show-toplevel确认当前处于 Git 仓库内并pushd回到仓库根目录操作因此你可以在任意子目录调用它。步骤 2Debug 模式配置与编译文档给出的“合理默认”配置命令为cmake -DCMAKE_BUILD_TYPEDebug -DLLAMA_CUDA1 -DLLAMA_FATAL_WARNINGSON .. make -j各参数含义-DCMAKE_BUILD_TYPEDebugDebug 构建保留完整调试符号且不优化是断点调试的前提-DLLAMA_CUDA1文档示例中开启 CUDA 后端。需要注意当前脚本实际写入的是 cmake -B ./build-ci-debug -DCMAKE_BUILD_TYPEDebug -DGGML_CUDA1即使用GGML_CUDA选项——从 根 CMakeLists.txt 的结构看LLAMA_CUDA属于已废弃选项会被映射并提示使用GGML_CUDA-DLLAMA_FATAL_WARNINGSON将警告视为错误对应 根 CMakeLists.txt 中的LLAMA_FATAL_WARNINGS选项默认 OFF适合在调试编译期问题时更严格地暴露隐患。文档明确说明这些参数“可按需调整”例如在无 CUDA 环境的机器上可去掉 GPU 后端选项。步骤 3用 ctest 正则收集匹配的测试ctest -R test-tokenizer -V -N三个关键参数-R test-tokenizer正则筛选匹配所有名为test-tokenizer*的用例-Nshow-only 模式只展示测试命令、不执行输出的命令正是喂给 GDB 的素材-VVerbose 模式输出完整命令行与参数。脚本内部用ctest -R ${test_suite} -V -N | grep -E Test #[0-9]*提取Test #N行作为测试名列表见 收集逻辑。典型输出节选... 1: Test command: ~/llama.cpp/build-ci-debug/bin/test-tokenizer-0 ~/llama.cpp/tests/../models/ggml-vocab-llama-spm.gguf 1: Working Directory: . Labels: main Test #1: test-tokenizer-0-llama-spm ... 4: Test command: ~/llama.cpp/build-ci-debug/bin/test-tokenizer-0 ~/llama.cpp/tests/../models/ggml-vocab-falcon.gguf 4: Working Directory: . Labels: main Test #4: test-tokenizer-0-falcon ...可以看到多个 ctest 用例共享同一个测试二进制test-tokenizer-0区别只在于传入的 GGUF 词表模型文件不同——这正源于仓库的测试注册方式后文展开。步骤 4从输出中识别测试命令的关键信息以上面的 1 号测试为例两条关键信息测试二进制~/llama.cpp/build-ci-debug/bin/test-tokenizer-0测试用 GGUF 模型~/llama.cpp/tests/../models/ggml-vocab-llama-spm.gguf即 models/ggml-vocab-llama-spm.gguf.inp 词表对应的资源脚本通过二次解析ctest -V -N输出中的Test command行按换行分隔见 提取测试参数拿到每个编号对应的完整命令再用你输入的test_number下标取出单条命令。步骤 5执行测试或进入 GDB不带-g时脚本直接eval该命令并根据退出码打印 PASS/FAIL见 结果输出带-g时执行gdb --args ${Test Binary} ${Test GGUF Model}实际示例gdb --args ~/llama.cpp/build-ci-debug/bin/test-tokenizer-0 ~/llama.cpp/tests/../models/ggml-vocab-llama-spm.gguf进入 GDB 后即可用b main、run、bt等常规命令调试。测试编号与用例来源tests/CMakeLists.txt 的注册机制理解“测试编号”从哪里来能让正则筛选和编号直跑更准确。llama.cpp 的测试由 tests/CMakeLists.txt 中的三个 CMake 函数统一注册llama_build(source)只编译测试可执行文件llama_test(target ...)为已有二进制注册 ctest 用例支持NAME用例名、LABEL默认main、ARGS传给二进制的参数、WORKING_DIRECTORYllama_build_and_test(source)编译并注册同名用例。以分词器测试为例tests/CMakeLists.txt 先编译一次test-tokenizer-0然后为 14 种词表 GGUF 各注册一个用例llama_build(test-tokenizer-0.cpp) llama_test(test-tokenizer-0 NAME test-tokenizer-0-llama-spm ARGS ${PROJECT_SOURCE_DIR}/models/ggml-vocab-llama-spm.gguf) llama_test(test-tokenizer-0 NAME test-tokenizer-0-falcon ARGS ${PROJECT_SOURCE_DIR}/models/ggml-vocab-falcon.gguf) # ... 以及 bert-bge、command-r、deepseek-llm、gemma-4、gpt-2、llama-bpe、mpt 等这正是ctest -R test-tokenizer -V -N输出中“同一二进制、不同模型参数”的原因。用例的NAME属性决定了 ctest 里显示的测试名与-R正则匹配结果ARGS属性决定了Test command行的参数部分。此外tests目录下的 CMake 还定义了若干带依赖关系的用例例如test-generate-models通过FIXTURES_SETUP generate-models生成虚拟模型test-recurrent-state-rollback、test-save-load-state等通过FIXTURES_REQUIRED generate-models声明依赖见 tests/CMakeLists.txt。需要留意的是ctest -N输出的编号顺序依赖 fixture 展开后的注册顺序因此脚本按“当前构建中 ctest 输出的顺序”给编号跨构建配置时编号可能变化——建议每次以脚本打印的Test# N: 测试名列表为准。用例的判定与退出码以 tests/test-tokenizer-0.cpp 为例它加载指定 GGUF 词表模型对一组内置的“文本 → 期望 token 序列”逐条执行分词对比若某条不一致会打印expected tokens与got tokens的逐 token 对照含common_token_to_piece还原的字符最后输出Tests passed/failed并以退出码 0通过或 3失败结束见 判定与退出。脚本正是以退出码是否为 0 来判定TEST PASS/TEST FAIL所以手动在 GDB 中run后观察同一退出码也能得到一致结论。实践建议把反馈闭环压到最短先执行、后调试默认模式不带-g快速拿到 PASS/FAIL确认稳定复现失败后再加-g进入 GDB避免在无问题时承受调试器的交互成本。正则可以很宽脚本对-R参数不做引号保护源码test这类宽正则能一次列出全部用例配合编号列表选择而test-tokenizer这类前缀正则能聚焦单一模块。手动复现五步当你只想调试、不想触发脚本的全量重编译例如已有 Debug 构建时可以跳过步骤 1/2直接按“步骤 3 收集 → 步骤 4 识别 → 步骤 5 执行”三步手动操作ctest -R regex -V -Ngdb --args command。警惕编号漂移test_number对应的是本次构建中 ctest 的输出顺序若你修改了 tests/CMakeLists.txt 中的用例注册编号可能随之变化交互式选择更稳妥。参考文件调试测试技巧文档本文主体来源含五步法原始说明scripts/debug-test.sh调试脚本实现依赖检查、ctest 解析、GDB 启动、结果判定tests/CMakeLists.txtllama_build/llama_test/llama_build_and_test注册函数与全部用例定义tests/test-tokenizer-0.cpp分词器测试实现展示用例如何输出期望/实际 token 对比及退出码CMakeLists.txtLLAMA_FATAL_WARNINGS选项与GGML_CUDA/ 废弃LLAMA_CUDA选项映射【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表