下载与编译 llama.cpp 源码

编译这件事,说简单也简单,说折腾也折腾。我刚开始接触 llama.cpp 时就踩过不少坑,尤其是编译选项那块,选错了要么跑不动,要么跑一半崩溃。今天咱们就把它彻底理清楚。

从哪里获取源码

官方仓库在 GitHub 上,地址我就不贴了,直接搜 "ggml-org/llama.cpp" 就能找到。

git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp

注意:我建议你 clone 的时候加上 --depth=1,只拉最新版本,不然几百兆的 git 历史挺浪费带宽的。另外,别用 master 分支的最新 commit,有时候主分支正在改 bug,不稳定。我个人习惯挑一个 release 标签,比如 b3535 之类的,测试过比较稳。

编译环境准备

llama.cpp 本身是纯 C++ 17 项目,依赖不多。你需要:

  • CMake 3.22+(低版本某些选项不支持)
  • C++ 编译器:GCC 9+ 或 Clang 12+ 或 MSVC 2022
  • (可选)NVIDIA CUDA Toolkit 12+,如果你要用 GPU 加速
  • (可选)OpenBLAS,用 CPU 跑大模型时提升性能

检查一下你的环境:

g++ --version
cmake --version
# 如果要用 CUDA
nvcc --version

嗯,这里要注意:不要用系统自带的旧版 CMake,很多 Linux 发行版带的 CMake 才 3.16,会遇到找不到某些 target 的问题。我一般直接用 pip 装一个新版 pip install 'cmake>=3.22'。

编译选项详解

llama.cpp 的 CMake 选项非常多,但真正常用的就那么几个。我把它们整理成一张表,你对着选就行:

选项值示例说明
-DLLAMA_CUDA=ONON / OFF启用 CUDA 加速,NVIDIA GPU 用户必开
-DLLAMA_BLAS=ONON / OFF使用 BLAS 库优化矩阵运算,CPU 场景下推荐
-DLLAMA_AVX2=ONON / OFF针对 Intel/AMD 新 CPU 开启 AVX2 指令集,提升速度
-DLLAMA_AVX=ONON / OFF如果 CPU 不支持 AVX2,退而求其次用 AVX
-DLLAMA_FMA=ONON / OFF启用 FMA 指令,与 AVX2 配合效果更好
-DLLAMA_OPENMP=ONON / OFF多线程并行,默认就是 ON,不用改
-DCMAKE_BUILD_TYPE=ReleaseRelease / Debug发布版去掉调试信息,性能好很多
-DLLAMA_METAL=ONON / OFFmacOS 上使用 Metal 框架加速(M1/M2 用户)
-DLLAMA_VULKAN=ONON / OFF使用 Vulkan 后端(多平台通用,但生态不如 CUDA 成熟)
-DLLAMA_ACCELERATE=ONON / OFFmacOS 上使用 Apple Accelerate 框架(CPU 优化)

我的经验是:别一股脑全开。比如你用的是 Intel 10 代 CPU 没有 AVX-512,开了也没用,反而让 CMake 报错。先搞清楚你的硬件支持哪些指令集,再去对应开启。

如果你不确定 CPU 支持什么,跑一下:

grep flags /proc/cpuinfo | head -1 | tr ' ' '\n' | grep -E 'avx|fma|sse'

常用编译命令示例

我下面给出几个常用场景的命令,你直接 copy 改参数就行。

场景1:纯 CPU + 最快指令集

cmake -B build -DCMAKE_BUILD_TYPE=Release \
  -DLLAMA_AVX2=ON -DLLAMA_FMA=ON \
  -DLLAMA_OPENMP=ON
cmake --build build --config Release -j$(nproc)

场景2:NVIDIA GPU + CUDA

cmake -B build -DCMAKE_BUILD_TYPE=Release \
  -DLLAMA_CUDA=ON -DLLAMA_AVX2=ON -DLLAMA_FMA=ON
cmake --build build --config Release -j$(nproc)

场景3:macOS M1/M2 + Metal

cmake -B build -DCMAKE_BUILD_TYPE=Release \
  -DLLAMA_METAL=ON -DLLAMA_ACCELERATE=ON
cmake --build build -j$(sysctl -n hw.logicalcpu)

场景4:不指定任何优化,纯兼容性

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release -j$(nproc)
小提示:编译时间挺长的,尤其第一次。我建议你开 -j$(nproc) 利用全部核心。另外,-B build 会把所有编译产物放在 build 目录里,清理时直接 rm -rf build 就行,干净利落。

编译完成后的产物

编译成功后,可执行文件都在 build/bin/ 下。最关键的有:

  • server — 我们这门课的主角,用来启动 API 服务
  • main — 命令行交互,测试模型好不好用
  • quantize — 模型量化工具,后面会用到
  • llama-perplexity — 评测模型困惑度

你可以先跑一下 ./build/bin/main -h 看看是否正常输出帮助信息。如果出现 "cannot open shared object file" 之类的错误,说明动态库路径没配好,后面会讲解决方案。

注意:如果你开启了 CUDA 支持,运行时需要把 CUDA 的 lib 路径加进 LD_LIBRARY_PATH 里,否则会报 "libcudart.so not found"。我一般在 ~/.bashrc 里写一行:
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
然后 source ~/.bashrc 刷新。

常见问题与避坑指南

1. CMake 报错找不到 ggml.h 或链接失败

这通常是因为 submodule 没拉全。llama.cpp 依赖 ggml 子模块,clone 时用 --recurse-submodules 或者手动:

git submodule update --init --recursive

我自己有一次忘记这步,折腾了半天才发现 submodule 里空空如也。

2. 编译时出现 "fatal error: cblas.h: No such file or directory"

开启了 BLAS 但没装 OpenBLAS 开发包。Ubuntu 下装:

sudo apt install libopenblas-dev

macOS 用 Homebrew:brew install openblas。

3. CUDA 版本不兼容

llama.cpp 对 CUDA 版本有要求,太老的(比如 11.0)可能编译不过。我曾经在服务器上踩过 CUDA 11.4 的坑,编译通过了,但推理时 float16 会出 NaN。解决方案:升级到 CUDA 12.x 或者用官方推荐的版本。查看文档里的 README.md 有兼容性列表。

4. 编译过程中内存不足(OOM)

llama.cpp 本身不大,但大模型源代码里的某些翻译单元(比如 llama.cpp 本身)在开启全部优化后,编译器内存占用会很高。我遇到过老服务器只有 4GB 内存,直接 OOM。解决办法:减少并行数,比如 -j2,或者关掉一些指令集优化。

5. macOS 上 Metal 编译失败

如果你用 M1/M2,确保 Xcode Command Line Tools 已更新。有时候需要指定 SDK 路径:

export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)

6. Windows 上 MSVC 编译乱码

llama.cpp 的源码是 UTF-8,但 MSVC 默认用本地编码。解决办法:在 CMake 命令行里加 -DCMAKE_CXX_FLAGS="/utf-8"。

一个实际案例:我有一次帮朋友编译,他用了 CentOS 7,GCC 4.8 默认编译器。llama.cpp 要求 C++ 17,直接报错。最后装了 devtoolset-9(GCC 9)才搞定。所以 第一件事就是检查编译器版本。

编译流程总览

下面这张图帮你梳理了从下载到运行服务器的完整流程,以及编译选项的决策路径。你编译前过一遍,心里就有数了。

llama.cpp 编译流程与选项决策 git clone 源码 检查编译器 & CMake 探测 CPU/GPU 信息 有 GPU ? CUDA/Metal/Vulkan CPU 指令集选择 (AVX2/AVX/FMA) cmake -B build [选项] cmake --build build ./build/bin/server

编译后验证

编译完别急着配 API,先做个最基本验证:

# 看看版本号
./build/bin/server --version

# 测试是否能加载一个最小的模型(比如 7B Q4_K_M)
# 先下载一个模型,比如:
# 然后运行:
./build/bin/main -m models/llama-7b-q4_k_m.gguf -p "Hello" -n 10

如果能看到输出的 token,恭喜你,编译成功了。

关于模型下载:后续课程会专门讲。现在验证的话,你可以从 Hugging Face 上随便拖一个 .gguf 文件下来,比如 TheBloke 的 Llama-2-7B-GGUF。但注意:别用太大模型验证,8GB 显存跑 7B 量化版刚刚好。

好了,编译这块就这些。遇到具体问题不要慌,先看看 CMake 日志的最后几行,错误原因通常都写得很明白。我见过不少同学急着找教程,其实错误信息里已经告诉你怎么修了。