llama.cpp学习整理

学习材料:https://github.com/ggml-org/llama.cpp/tree/master/docs

一、基本概念

GGML

全称Georgi Gerganov’s Machine Learning,由Georgi Gerganov开发的纯C语言编写的机器学习张量计算库,专为LLM推理场景设计。它是整个llama.cpp生态的底层计算层。

GGML计算图整个推理流程:

  • 构建阶段:通过一系列算子调用(ggml_mul_matggml_add等等)构建DAG,每个节点都是Tensor运算
  • 规划阶段:ggml_graph_plan对DAG进行拓扑排序,确定执行顺序,和每个节点的运行参数
  • 执行阶段:ggml_graph_compute按拓扑顺序逐个节点执行ggml_compute_forward,完成数学计算

二、GGUF

gguf全称GPT-Generated Unified Format,为LLM设计的单文件二进制格式,将一切信息打包进一个.gguf文件中,包括:

  • 量化后的模型权重
  • 分词器词表和配置
  • 模型架构参数
  • 量化方式、上下文长度等元数据
  • 提示词模版(Chat Template,Jinja格式)

量化

常用的量化格式有Q4_KQ4_0Q4_1Q4_K_M等等。_0_1的区别在于是否带最小值偏移:Q4_0只存储一个scale,Q4_1额外存储一个min。_K对应K-Quants,目前成为主流量化方式。

K-Quants将模型权重矩阵进行分层分块量化,通过_S(small)、_M(medium)、_L(large)控制混合精度(例如Q4_K_M中attention和feed-forward的部分张量会提升到Q6_K,块本身的布局不变)。它将权重分割成超级块(比如包含256个值),有一个Scale和Min;每个超级块再分割成子块,每个子块都拥有独立的Scale和Min。

Q4_K举例(Q4_K_M的块布局与之相同),它整体分块如下:

超级块(Super Block)= 256 个权重
├── 子块 0(32 个权重)
├── 子块 1(32 个权重)
├── ...
└── 子块 7(32 个权重)

在内存中的布局如下:

字段 类型 大小 说明
d ggml_half(FP16) 2 字节 超级块级别的缩放因子(scale of scales)
dmin ggml_half(FP16) 2 字节 超级块级别的最小值缩放因子
scales uint8_t[12] 12 字节 8 个子块各自的 scale 和 min(各占 6-bit,打包存储)
qs uint8_t[128] 128 字节 256 个权重的 4-bit 量化值

总计144字节,即144×8/256=4.5 bit/权重。

反量化公式:w ≈ q × (scale × d) - (min × dmin)

三、整体架构图

四、运行方式

# 下载qwen3.5(需要git-lfs,未安装的话先执行 git lfs install)
git clone https://huggingface.co/ggml-org/Qwen3.5-0.8B-GGUF

# 编译
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
cmake -B build # cpu编译,如果需要GPU,加上-DGGML_CUDA=ON
cmake --build build --config Release -j$(nproc)

# 运行
./build/bin/llama-server --list-devices # 列出设备列表
./build/bin/llama-server -m ../Qwen3.5-0.8B-GGUF/Qwen3.5-0.8B-Q4_0.gguf --host 0.0.0.0 --port 8080

# 也可以不手动下载,用-hf让llama-server自动下载模型:
# ./build/bin/llama-server -hf ggml-org/Qwen3.5-0.8B-GGUF:Q4_0 --host 0.0.0.0 --port 8080

# 在网页中打开http://127.0.0.1:8080/

评论