本文按逻辑分层结构的方法分析 llama.cpp。
重点是把 API / Runtime / Kernel / Backend / Model Loader / Tool 这些模块分开,注意不要把目录名、可执行文件、库、设备代码混在一起。分析以模块为主,目录只作参考。
llama.cpp项目一直处于高度活跃状态,主线仓库目录会持续重构,例如examples/和tools/、src/llama.cpp和拆分后的llama-*.cpp等。
1. 逻辑分层结构
可以把 llama.cpp 理解成如下所示的逻辑分层结构:
1┌──────────────────────────────────────────────────────────────┐
2│ Application / Tools │ [Tool]
3│ │
4│ cli / main │
5│ server │
6│ quantize │
7│ perplexity │
8│ bench │
9│ embedding │
10│ gguf-split │
11│ imatrix │
12│ Python / Rust / Go / Node bindings │
13│ convert_hf_to_gguf.py / gguf-py │
14└───────────────────────────────┬──────────────────────────────┘
15 │ C API
16 ▼
17┌──────────────────────────────────────────────────────────────┐
18│ Public API │ [API]
19│ │
20│ include/llama.h │
21│ llama_model_load_from_file() │
22│ llama_init_from_model() │
23│ llama_decode() │
24│ llama_get_logits() │
25│ llama_sampler_*() │
26│ llama_backend_init() │
27└───────────────────────────────┬──────────────────────────────┘
28 │ implemented by
29 ▼
30┌──────────────────────────────────────────────────────────────┐
31│ libllama Runtime │ [Runtime]
32│ │
33│ ┌────────────────────────────┐ │
34│ │ Model Loader / GGUF Loader │ │ [Model Loader]
35│ │ │ │
36│ │ GGUF metadata parsing │ │
37│ │ tensor name mapping │ │
38│ │ mmap / split files │ │
39│ │ weight placement │ │
40│ │ CPU/GPU offload │ │
41│ └────────────────────────────┘ │
42│ │
43│ ┌────────────────────────────┐ │
44│ │ Model Object │ │ [Runtime]
45│ │ │ │
46│ │ llama_model │ │
47│ │ hparams │ │
48│ │ architecture registry │ │
49│ │ vocab / tokenizer │ │
50│ │ chat template │ │
51│ │ adapters / LoRA │ │
52│ └────────────────────────────┘ │
53│ │
54│ ┌────────────────────────────┐ │
55│ │ Context Object │ │ [Runtime]
56│ │ │ │
57│ │ llama_context │ │
58│ │ llama_batch │ │
59│ │ KV cache │ │
60│ │ decode loop │ │
61│ │ sampling / grammar │ │
62│ │ logits / embeddings │ │
63│ └────────────────────────────┘ │
64└───────────────────────────────┬──────────────────────────────┘
65 │ build ggml_cgraph
66 ▼
67┌──────────────────────────────────────────────────────────────┐
68│ Inference Engine / Graph Builder │ [Runtime / Engine]
69│ │
70│ embedding lookup │
71│ attention graph │
72│ MLA / GQA / MQA │
73│ MoE graph │
74│ RoPE │
75│ norm / softmax │
76│ output projection │
77│ KV cache update graph │
78└───────────────────────────────┬──────────────────────────────┘
79 │ ggml_cgraph
80 ▼
81┌──────────────────────────────────────────────────────────────┐
82│ Graph Scheduler + Graph Allocator │ [Scheduler / Runtime]
83│ │
84│ ggml_backend_sched │
85│ ggml_gallocr │
86│ │
87│ decide which op runs on which backend │
88│ insert copies between CPU/GPU │
89│ plan intermediate tensor memory │
90│ handle fallback │
91└───────────────────────────────┬──────────────────────────────┘
92 │
93 ▼
94┌──────────────────────────────────────────────────────────────┐
95│ GGML Tensor IR │ [Tensor IR]
96│ │
97│ ggml_tensor │
98│ ggml_cgraph │
99│ ggml_op │
100│ f16 / f32 / bf16 │
101│ q4_0 / q4_1 / q5_k / q6_k / iq formats │
102│ GGML_OP_MUL_MAT │
103│ GGML_OP_ROPE │
104│ GGML_OP_NORM │
105│ GGML_OP_SOFT_MAX │
106│ GGML_OP_CPY │
107└───────────────────────────────┬──────────────────────────────┘
108 │ ggml_backend interface
109 ▼
110┌──────────────────────────────────────────────────────────────┐
111│ Backend Implementations │ [Backend]
112│ │
113│ CPU │
114│ CUDA │
115│ Metal │
116│ Vulkan │
117│ SYCL │
118│ HIP / ROCm │
119│ BLAS │
120│ RPC │
121│ CANN / MUSA / Kompute / other vendor backends │
122└───────────────────────────────┬──────────────────────────────┘
123 │ launch device code
124 ▼
125┌──────────────────────────────────────────────────────────────┐
126│ Kernels / Device Code │ [Kernel]
127│ │
128│ CPU SIMD kernels: AVX2 / AVX512 / NEON / SVE / AMX │
129│ CUDA kernels: .cu │
130│ Metal shaders: .metal │
131│ Vulkan compute shaders: SPIR-V │
132│ SYCL kernels │
133│ HIP kernels │
134│ cuBLAS / oneMKL / vendor libs │
135└───────────────────────────────┬──────────────────────────────┘
136 │
137 ▼
138┌──────────────────────────────────────────────────────────────┐
139│ Hardware │
140│ │
141│ x86 CPU │
142│ ARM CPU │
143│ NVIDIA GPU │
144│ AMD GPU │
145│ Apple GPU │
146│ Intel GPU │
147│ other accelerators │
148└──────────────────────────────────────────────────────────────┘
2. 分层关系
用一句话概括分层之间的关系:
Tool 调用 API,API 背后是 libllama Runtime,Runtime 构建 GGML 图,Graph Scheduler 决定图在哪里执行,Backend 调用 Kernel,Kernel 跑在硬件上。
下图是对上面逻辑分层结构图各层之间关系的简短概括,便于看的更加清楚:
1Tool
2 └─ Public C API
3 └─ libllama Runtime
4 ├─ Model Loader
5 ├─ Model / Context / KV Cache
6 ├─ Tokenizer / Vocab
7 ├─ Sampling / Grammar
8 └─ Inference Graph Builder
9 └─ GGML Graph Scheduler
10 └─ GGML Tensor IR
11 └─ Backend
12 └─ Kernel
13 └─ Hardware
该图清晰地勾勒出 llama.cpp 引擎自顶向下的分层架构与完整执行链路。整体设计遵循了高内聚、低耦合的工程原则,将上层应用逻辑、中层计算调度与底层硬件执行进行了明确的边界划分。
在最上层,各类上层应用或工具(Tool)通过调用标准化的公共 C 语言接口(Public C API)与底层引擎进行交互。这种设计不仅屏蔽了底层 C++ 实现的复杂性,还确保了跨编程语言(如 Python、Rust、Go 等)和跨平台调用的稳定性与兼容性。
C API 之下是核心的 libllama 运行时(Runtime),它是整个推理框架的调度中枢,负责管理模型的生命周期与推理状态。运行时内部划分为多个协同工作的核心模块:
- Model Loader 负责将磁盘上的模型权重文件(如 GGUF 格式)解析并加载到内存中;
- Model / Context / KV Cache 模块用于维护模型实例、推理上下文,并管理用于加速自回归注意力计算的键值缓存(KV Cache);
- Tokenizer / Vocab 模块处理自然语言文本与离散词元之间的高效双向转换;
- Sampling / Grammar 模块则不仅提供温度、Top-p、Top-k 等常规解码策略,还引入了基于语法的约束采样(Grammar),以确保模型的输出严格符合特定的数据结构或格式要求(如 JSON Schema)。
当输入数据和上下文准备就绪后,系统进入计算图的构建与调度阶段。Inference Graph Builder 会根据当前模型的架构(如 Transformer)和输入序列,动态构建出前向传播的计算图。构建完成的计算图随即交由 GGML Graph Scheduler 进行处理。调度器负责计算图的拓扑排序、内存分配优化(如内存池的复用机制以减少显存/内存碎片)以及计算任务的合理拆分,从而在宏观层面最大化计算资源的利用率。
在架构的最底层,是具体的张量计算与硬件执行链路。GGML Tensor IR 定义了一套张量中间表示,将计算图中的逻辑节点抽象为标准的张量操作(如矩阵乘法、层归一化、激活函数等)。这些中间表示随后被路由到具体的计算后端(Backend),例如针对 NVIDIA GPU 的 CUDA、针对 Apple Silicon 的 Metal、针对 AMD GPU 的 ROCm,或是基于 AVX/NEON 指令集的通用 CPU 后端。后端将这些抽象的 IR 操作映射并编译为高度优化的底层计算核函数(Kernel)。最终,这些 Kernel 被下发到物理硬件(Hardware)上执行,完成实际的浮点或量化矩阵运算,并将推理结果逐层向上传递,直至返回给最上层的 Tool。
整体而言,这一自顶向下的分层架构实现了业务逻辑、图优化调度与底层硬件加速的深度解耦。它不仅使得推理框架能够灵活适配各种异构硬件,也为大语言模型的高效、稳定推理提供了坚实的工程基础。
3. 模块角色分类
深入模块和源代码文件,对照前面介绍的逻辑分层结构,,逐一理清以下问题:
哪些是 API?
哪些是 Runtime?
哪些是 Kernel?
哪些是 Backend?
哪些是 Model Loader?
哪些是 Tool?
3.1 API
角色定义
API 是对外暴露的稳定接口边界。
对于 llama.cpp,最核心的 API 是:
1include/llama.h
它是一个 C API,方便被 C/C++、Python、Rust、Go、Node.js 等语言绑定调用。
典型内容
1llama_backend_init()
2llama_model_load_from_file()
3llama_new_context_with_model()
4llama_decode()
5llama_get_logits()
6llama_get_embeddings()
7llama_sampler_init_*()
8llama_sampler_sample()
9llama_kv_self_clear()
10llama_kv_self_seq_rm()
11llama_kv_self_seq_cp()
12llama_lora_adapter_init()
13llama_model_quantize()
它是什么
- 是 libllama 暴露给应用层的接口。
- 是 C ABI 边界。
- 是上层工具、server、binding 依赖的入口。
它不是什么
- 不是 HTTP API。
- 不是
llama-server的 OpenAI-compatible API。 - 不是内部实现细节。
- 不是 CUDA kernel。
- 不是模型加载器本身。
常见误判
llama-server 提供的:
1/v1/chat/completions
2/v1/completions
3/v1/embeddings
这是 Application-level API,属于 Tool/Application 层,不属于 libllama 的核心 C API。
3.2 运行时模块(Runtime)
角色定义
运行时是 libllama 的核心运行时实现。它负责:
- 管理模型对象;
- 管理上下文对象;
- 管理 KV cache;
- 处理 token batch;
- 构建前向计算图;
- 调用 GGML 执行;
- 返回 logits / embeddings;
- 管理 sampler、grammar、LoRA、adapter 等。
典型位置
常见于:
1src/llama*.cpp
2src/llama*.h
例如逻辑上包括:
1llama-model.cpp / llama-model.h
2llama-context.cpp / llama-context.h
3llama-kv-cache.cpp / llama-kv-cache.h
4llama-graph.cpp / llama-graph.h
5llama-sampling.cpp / llama-sampling.h
6llama-grammar.cpp / llama-grammar.h
7llama-vocab.cpp / llama-vocab.h
8llama-adapter.cpp / llama-adapter.h
9llama-arch.cpp / llama-arch.h
10llama-chat.cpp / llama-chat.h
11llama-hparams.cpp / llama-hparams.h
不同版本文件名可能变化,但逻辑模块基本稳定。
运行时包含的主要子模块
1. 模型对象(Model Object)
llama_model 负责表示一个已经加载好的模型,包括:
- 模型结构;
- hparams;
- 权重张量;
- vocab;
- tokenizer;
- chat template;
- adapter;
- 架构类型,例如 LLaMA、Qwen、Gemma、Mistral、Phi、StableLM 等。
2. 上下文对象(Context Object)
llama_context 负责一次推理会话,包括:
- KV cache;
- 当前 batch;
- 计算图;
- logits 输出;
- embedding 输出;
- sampling 状态;
- grammar 状态;
- sequence 管理。
3. KV Cache 对象
llama_kv_cache 负责缓存 attention 的 key/value,包括:
- KV cache 分配;
- sequence 删除;
- sequence 复制;
- defrag;
- cache clear;
- slot 管理的基础能力。
注意:
高级 continuous batching、请求队列、slot 调度通常在
llama-server或应用层实现,不属于 libllama 核心运行时。
4. Tokenizer / Vocab 相关对象
负责:
- token id 和文本互转;
- BPE;
- SentencePiece;
- special tokens;
- chat template 中涉及的 token 处理。
5. Sampling / Grammar
负责:
- temperature;
- top-k;
- top-p;
- min-p;
- repetition penalty;
- frequency/presence penalty;
- grammar 约束;
- JSON schema 约束;
- sampler chain。
6. Adapter / LoRA
负责:
- LoRA 加载;
- adapter 权重;
- 在计算图中应用 adapter。
3.3 模型加载模块(Model Loader)
角色定义
模型加载模块负责把磁盘上的模型文件加载成 模型加载模块运行时模块可用的模型对象。
在 llama.cpp 中,模型文件主要是GGUF。
典型位置
逻辑上包括:
1src/llama-model-loader.cpp
2src/llama-model-loader.h
3ggml/src/gguf.c
4ggml/src/gguf.cpp
5ggml/include/gguf.h
以及模型架构映射相关文件:
1src/llama-arch.cpp
2src/llama-hparams.cpp
3src/llama-vocab.cpp
它负责什么
- 打开 GGUF 文件;
- 读取 metadata;
- 读取 tensor 元信息;
- 读取架构名称;
- 读取 hparams;
- 读取 vocab;
- 读取 tokenizer 信息;
- 将 GGUF tensor 名字映射到内部模型结构;
- 决定权重放在 CPU 还是 GPU;
- 支持 mmap;
- 支持 split GGUF;
- 支持量化权重直接加载;
- 创建
llama_model。
它不负责什么
llama_decode();- sampling;
- KV cache 更新;
- HTTP server;
- CUDA kernel;
- graph scheduling;
- 生成 token。
重要边界
1GGUF 是文件格式。
2GGUF parser 是模型加载器的一部分。
3Model Loader 是 Runtime 的前置阶段。
不要把下面三者混在一起:
1GGUF file format
2GGUF parser
3LLM inference runtime
3.4 推理引擎/计算图构建模块(Inference Engine / Graph Builder)
角色定义
推理引擎负责把 LLM 的前向传播描述成 GGML 计算图。它不直接做矩阵乘法,而是构建类似:
1ggml_mul_mat()
2ggml_rope()
3ggml_norm()
4ggml_softmax()
5ggml_cpy()
6ggml_get_rows()
这样的 GGML op,然后组成:
1ggml_cgraph
典型职责
- embedding lookup;
- attention;
- GQA / MQA / MLA;
- MoE;
- RoPE;
- RMSNorm / LayerNorm;
- FFN;
- output projection;
- logits;
- embeddings;
- KV cache 写入;
- batch 拆分;
- sequence 处理。
它和运行时模块的关系
严格说,推理引擎是运行时的一部分。但如果画架构图,可以单独抽出来:
1libllama Runtime
2 │
3 ▼
4Inference Engine / Graph Builder
因为它的职责很明确:
把 LLM 模型结构转换成 GGML 计算图。
它不是什么
- 不是 Graph Scheduler;
- 不是 Backend;
- 不是 Kernel;
- 不是模型加载器;
- 不是 Tool。
3.5 计算图调度模块(Graph Scheduler)
角色定义
计算图调度模块负责决定 GGML 计算图中的节点在哪里执行。在 llama.cpp / GGML 中,核心是:
1ggml_backend_sched
相关文件通常包括:
1ggml/src/ggml-backend.cpp
2ggml/include/ggml-backend.h
3ggml/src/ggml-alloc.c
4ggml/include/ggml-alloc.h
它负责什么
- 接收一个
ggml_cgraph; - 判断每个 op 能否在某个 backend 上执行;
- 根据 buffer type、设备内存、offload 策略选择 backend;
- 在不同 backend 之间插入 copy;
- 分配中间 tensor;
- 复用内存;
- 执行 graph plan;
- 处理 fallback 到 CPU。
例子
假设计算图里有:
1embedding -> attention -> ffn -> output
Scheduler 可能决定:
1embedding : CPU
2attention : CUDA
3ffn : CUDA
4output : CPU
然后在 CPU 和 CUDA 之间插入:
1GGML_OP_CPY
或者通过 backend copy 机制传输 tensor。
它和 Backend 的区别
1Scheduler 决定谁来做。
2Backend 负责实际做。
它和 llama-server 请求调度的区别
这是最容易混淆的地方之一。
llama.cpp 里有两种“调度”:
| 类型 | 所在层 | 调度对象 |
|---|---|---|
| Graph Scheduler | GGML Runtime | 计算图中的 op |
| Request Scheduler | llama-server / Application | HTTP 请求、slot、batch、用户会话 |
所以:
llama-server里的 continuous batching、slot 管理、请求队列,不是 GGML Graph Scheduler。
3.6 GGML Tensor IR
角色定义
GGML Tensor 是底层张量表示和计算图 IR。它描述:
- tensor shape;
- tensor dtype;
- tensor layout;
- op 类型;
- op 输入输出;
- 量化格式;
- 计算图结构。
典型位置
1ggml/include/ggml.h
2ggml/src/ggml.c
3ggml/src/ggml-quants.c
4ggml/src/ggml-quants.h
它负责什么
ggml_tensorggml_cgraphggml_opggml_typeggml_backend_bufferggml_build_forwardggml_mul_matggml_ropeggml_normggml_soft_maxggml_cpy
以及量化类型:
1GGML_TYPE_F16
2GGML_TYPE_F32
3GGML_TYPE_Q4_0
4GGML_TYPE_Q4_1
5GGML_TYPE_Q5_0
6GGML_TYPE_Q5_1
7GGML_TYPE_Q8_0
8GGML_TYPE_Q2_K
9GGML_TYPE_Q3_K
10GGML_TYPE_Q4_K
11GGML_TYPE_Q5_K
12GGML_TYPE_Q6_K
13GGML_TYPE_IQ4_XS
14...
它和 Kernel 的区别
GGML Tensor IR 只描述:
1要做什么计算
Kernel 负责:
1具体怎么在 CPU/GPU 上算
例如:
1GGML_OP_MUL_MAT
是 IR 层的 op。
而:
1CUDA quantized matmul kernel
2Metal matmul shader
3CPU AVX2 q4_0 dot product kernel
是 Kernel 层。
3.7 Backend
角色定义
Backend 是 GGML 的执行后端抽象。
它实现统一接口,让 GGML 可以把图交给不同设备执行。
典型接口
1ggml_backend
2ggml_backend_buffer
3ggml_backend_buffer_type
4ggml_backend_event
5ggml_backend_graph_compute
6ggml_backend_supports_op
典型位置
1ggml/include/ggml-backend.h
2ggml/src/ggml-backend.cpp
以及各后端目录:
1ggml/src/ggml-cpu/
2ggml/src/ggml-cuda/
3ggml/src/ggml-metal/
4ggml/src/ggml-vulkan/
5ggml/src/ggml-sycl/
6ggml/src/ggml-hip/ # 或由 CUDA/HIP 兼容路径实现
7ggml/src/ggml-blas/
8ggml/src/ggml-rpc/
9ggml/src/ggml-cann/
10ggml/src/ggml-musa/
11ggml/src/ggml-kompute/
不同版本目录可能略有变化。
Backend 负责什么
- 创建设备 buffer;
- 管理设备内存;
- 上传/下载 tensor;
- 执行 graph;
- 管理 event / stream;
- 判断某个 op 是否支持;
- 调用具体 kernel;
- 处理同步;
- 提供设备能力给 scheduler。
Backend 和 Kernel 的区别
这是另一个非常容易混淆的地方。
1Backend 是执行后端的管理层。
2Kernel 是具体设备计算代码。
例如 CUDA backend 包括:
1CUDA backend 管理层
2 - buffer 管理
3 - stream 管理
4 - event 管理
5 - graph_compute 入口
6 - op dispatch
7
8CUDA kernels
9 - matmul kernel
10 - rope kernel
11 - norm kernel
12 - softmax kernel
13 - quantization kernel
所以:
ggml-cuda目录整体不能简单叫 Kernel。
它同时包含 Backend 和 Kernel。
3.8 Kernel
角色定义
Kernel 是真正执行数学计算的代码。
它通常位于 backend 目录内部。
CPU Kernel
例如:
1AVX2
2AVX512
3FMA
4NEON
5SVE
6AMX
7RISC-V Vector
负责:
- quantized matmul;
- dot product;
- rope;
- norm;
- softmax;
- copy;
- dequantize;
- quantize。
CUDA Kernel
例如:
1.cu 文件
2__global__ functions
3cuBLAS / vendor libraries
负责:
- FP16 matmul;
- Q4_K matmul;
- Q6_K matmul;
- flash attention;
- rope;
- norm;
- softmax;
- copy。
Metal Kernel
例如:
1.metal shaders
2metallib
3Metal compute pipeline
Vulkan Kernel
例如:
1Vulkan compute shaders
2SPIR-V
3descriptor sets
4pipeline layout
SYCL Kernel
例如:
1SYCL kernels
2oneAPI DPC++
3Intel GPU / CPU execution
HIP Kernel
例如:
1ROCm HIP kernels
2AMD GPU execution
Kernel 不负责什么
Kernel 通常不负责:
- 模型加载;
- tokenization;
- sampling;
- HTTP;
- KV cache 语义;
- graph scheduling;
- backend buffer lifecycle。
Kernel 只关心:
1输入 tensor
2输出 tensor
3shape
4dtype
5stride
6计算逻辑
3.9 Tool
角色定义
Tool 是可执行程序、脚本、示例、测试、转换工具、语言绑定等。
它们使用 libllama API,但不属于核心推理库本身。
典型 Tool
1llama-cli / main
2llama-server
3llama-quantize
4llama-perplexity
5llama-bench
6llama-embedding
7llama-gguf-split
8llama-imatrix
9llama-export-lora
10llama-batched
11llama-speculative
以及:
1common/
2examples/
3tools/
4tests/
5scripts/
6convert_hf_to_gguf.py
7gguf-py/
8bindings/
Tool 负责什么
Tool 通常负责:
- 命令行参数;
- prompt 输入;
- 交互式聊天;
- HTTP server;
- OpenAI-compatible API;
- 并发请求;
- slot 管理;
- benchmark;
- perplexity 评测;
- 模型量化命令行;
- GGUF 分割;
- imatrix 生成;
- 模型转换;
- 测试;
- 语言绑定。
Tool 不是什么
Tool 不是:
- libllama 核心 Runtime;
- GGML Backend;
- Kernel;
- Graph Scheduler;
- 模型加载器本身。
特别注意:common/
很多版本里有common/,它通常提供:
- 参数解析;
- 采样参数封装;
- chat template 辅助;
- 日志;
- CLI 工具公共代码。
它属于 Tool-side helper,不是 libllama 的核心 API。
4. 模块清单
一个更详细的模块清单。
| 模块 | 所属层 | 角色 | 说明 |
|---|---|---|---|
| Application / Tools | Tool | Tool | CLI、server、bench、quantize 等 |
| Language Bindings | Tool / Wrapper | Tool | Python、Rust、Go、Node 等 |
| Public C API | API | API | include/llama.h |
| Common Helper | Tool Helper | Tool | 参数、采样封装、CLI 公共逻辑 |
| Model Loader | libllama Runtime | Model Loader | 加载 GGUF |
| GGUF Parser | Model Loader | Model Loader | 解析 GGUF 文件 |
| Architecture Registry | Runtime | Runtime | 模型架构映射 |
| Model Object | Runtime | Runtime | llama_model |
| Context Object | Runtime | Runtime | llama_context |
| KV Cache | Runtime | Runtime | attention cache |
| Tokenizer / Vocab | Runtime | Runtime | token 编解码 |
| Sampling | Runtime | Runtime | sampler chain |
| Grammar | Runtime | Runtime | GBNF / JSON schema 约束 |
| Chat Template | Runtime / Tool Helper | Runtime 或 Tool | 模板应用 |
| LoRA / Adapter | Runtime | Runtime | adapter 加载与应用 |
| Inference Graph Builder | Runtime / Engine | Engine | 构建 GGML 图 |
| GGML Tensor IR | GGML Core | Tensor IR | tensor/op/graph 表示 |
| Quant Formats | GGML Core | Tensor IR / Kernel 支持 | Q4_K、Q6_K 等 |
| Graph Allocator | GGML Runtime | Scheduler / Allocator | 中间 tensor 内存规划 |
| Graph Scheduler | GGML Runtime | Scheduler | 决定 op 在哪个 backend 执行 |
| Backend Interface | GGML Runtime | Backend | ggml_backend 抽象 |
| CPU Backend | Backend | Backend | CPU 执行后端 |
| CUDA Backend | Backend | Backend | NVIDIA GPU 后端 |
| Metal Backend | Backend | Backend | Apple GPU 后端 |
| Vulkan Backend | Backend | Backend | Vulkan GPU 后端 |
| SYCL Backend | Backend | Backend | Intel oneAPI 后端 |
| HIP Backend | Backend | Backend | AMD ROCm 后端 |
| BLAS Backend | Backend | Backend | BLAS 加速 |
| RPC Backend | Backend | Backend | 远程执行 |
| Vendor Backends | Backend | Backend | CANN、MUSA、Kompute 等 |
| CPU Kernels | Kernel | Kernel | SIMD/AVX/NEON 等 |
| CUDA Kernels | Kernel | Kernel | .cu |
| Metal Shaders | Kernel | Kernel | .metal |
| Vulkan Shaders | Kernel | Kernel | SPIR-V compute shaders |
| SYCL Kernels | Kernel | Kernel | SYCL/DPC++ |
| HIP Kernels | Kernel | Kernel | ROCm HIP |
| Model Conversion Scripts | Tool | Tool | HF 转 GGUF 等 |
| Quantization Tool | Tool | Tool | llama-quantize |
| Benchmark Tool | Tool | Tool | llama-bench |
| Perplexity Tool | Tool | Tool | llama-perplexity |
| Server Tool | Tool | Tool | llama-server |
| Tests | Dev Tool | Tool | 单元测试、集成测试 |
5. 主要执行流程
下面用一次完整推理说明各模块如何协作。
5.1 加载模型
1Tool
2 │
3 │ llama_model_load_from_file()
4 ▼
5API
6 │
7 ▼
8Model Loader
9 │
10 ├─ 打开 GGUF
11 ├─ 读取 metadata
12 ├─ 读取 tensor info
13 ├─ 读取 vocab
14 ├─ 读取 hparams
15 ├─ 映射 tensor name
16 ├─ 决定 CPU/GPU placement
17 └─ 创建 llama_model
这里的关键是:
1Model Loader 只负责把模型变成 llama_model。
2它不负责 decode。
5.2 创建上下文
1Tool
2 │
3 │ llama_new_context_with_model()
4 ▼
5API
6 │
7 ▼
8Runtime
9 │
10 ├─ 创建 llama_context
11 ├─ 初始化 KV cache
12 ├─ 初始化 sampler 相关状态
13 └─ 准备 compute graph 所需资源
5.3 tokenize prompt
1Tool
2 │
3 │ llama_tokenize()
4 ▼
5API
6 │
7 ▼
8Runtime / Tokenizer
9 │
10 └─ text -> token ids
5.4 decode batch
1Tool
2 │
3 │ llama_decode(batch)
4 ▼
5API
6 │
7 ▼
8Runtime
9 │
10 ├─ 检查 batch
11 ├─ 准备输入 tensor
12 ├─ 构建 ggml_cgraph
13 └─ 交给 GGML scheduler
5.5 Graph Scheduler 调度
1Inference Engine
2 │
3 │ ggml_cgraph
4 ▼
5Graph Scheduler
6 │
7 ├─ 分析 op
8 ├─ 判断 backend 支持情况
9 ├─ 分配中间 tensor
10 ├─ 插入 copy
11 └─ 生成执行计划
5.6 Backend 执行
1Scheduler
2 │
3 ▼
4Backend
5 │
6 ├─ CPU backend
7 ├─ CUDA backend
8 ├─ Metal backend
9 ├─ Vulkan backend
10 └─ ...
5.7 Kernel 计算
1Backend
2 │
3 ▼
4Kernel
5 │
6 ├─ matmul
7 ├─ rope
8 ├─ norm
9 ├─ softmax
10 ├─ attention
11 └─ copy
5.8 返回 logits
1Kernel
2 │
3 ▼
4Backend
5 │
6 ▼
7GGML Runtime
8 │
9 ▼
10libllama Runtime
11 │
12 ├─ 更新 KV cache
13 ├─ 输出 logits / embeddings
14 └─ 返回给 API
5.9 Tool 采样下一个 token
1Tool
2 │
3 │ llama_sampler_sample()
4 ▼
5API
6 │
7 ▼
8Runtime Sampling
9 │
10 └─ 选择 next token
然后循环:
1decode -> logits -> sample -> decode -> logits -> sample
6. 各层之间的依赖关系
正确的依赖方向应该是:
1Tool
2 ↓
3API
4 ↓
5Runtime
6 ↓
7GGML Scheduler
8 ↓
9GGML Tensor IR
10 ↓
11Backend
12 ↓
13Kernel
14 ↓
15Hardware
下层不应该依赖上层。
例如:
1CUDA kernel 不应该知道 HTTP 请求。
2Backend 不应该知道 prompt。
3GGML scheduler 不应该知道 token 含义。
4Model loader 不应该知道 sampling 策略。
5Tool 不应该直接实现 matmul kernel。
7. 如何快速判断一个文件属于哪一层?
可以用下面几个规则。
7.1 是否是 API?
看它是否在公共头文件中暴露:
1include/llama.h
如果是:
1LLAMA_API ...
那它属于 API 边界。
但注意:
1API 的声明在 include/llama.h
2API 的实现通常在 src/llama*.cpp
所以:
1llama.h 是 API
2llama.cpp 是 Runtime 实现
7.2 是否是 Runtime?
如果它处理:
llama_modelllama_contextllama_batch- KV cache
- sampler
- grammar
- tokenizer
- logits
- decode 流程
那它属于 Runtime。
典型目录:
1src/
7.3 是否是 Model Loader?
如果它处理:
- GGUF 文件;
- tensor 元信息;
- 模型权重加载;
- mmap;
- split file;
- tensor name mapping;
- hparams 读取;
- vocab 读取;
- 权重 offload 到 GPU buffer;
那它属于 Model Loader。
典型文件:
1src/llama-model-loader.*
2ggml/src/gguf.*
7.4 是否是 Inference Engine?
如果它负责:
- 构建 attention graph;
- 构建 FFN graph;
- 构建 embedding graph;
- 构建 output graph;
- 生成
ggml_cgraph;
那它属于 Inference Engine / Graph Builder。
典型逻辑文件:
1src/llama-graph.*
2src/llama-context.*
7.5 是否是 Graph Scheduler?
如果它处理:
ggml_backend_schedggml_gallocr- backend 选择;
- op fallback;
- tensor copy;
- graph memory plan;
那它属于 Graph Scheduler / GGML Runtime。
典型文件:
1ggml/src/ggml-backend.cpp
2ggml/src/ggml-alloc.c
7.6 是否是 Backend?
如果它实现:
1ggml_backend
2ggml_backend_buffer
3ggml_backend_buffer_type
4graph_compute
5supports_op
那它属于 Backend。
典型目录:
1ggml/src/ggml-cpu/
2ggml/src/ggml-cuda/
3ggml/src/ggml-metal/
4ggml/src/ggml-vulkan/
5ggml/src/ggml-sycl/
6ggml/src/ggml-hip/
7ggml/src/ggml-rpc/
7.7 是否是 Kernel?
如果它是:
- CUDA
__global__ - Metal shader
- Vulkan compute shader
- SYCL kernel
- CPU SIMD inner loop
- quantized dot product
- matmul microkernel
那它属于 Kernel。
典型形式:
1.cu
2.metal
3.comp / SPIR-V
4SYCL kernel lambda
5CPU SIMD intrinsic loops
7.8 是否是 Tool?
如果它有:
1int main()
或者它是:
- CLI;
- server;
- benchmark;
- Python 转换脚本;
- binding;
- test;
那它属于 Tool / Application。
典型目录:
1examples/
2tools/
3common/
4tests/
5scripts/
6bindings/
8. 最容易混淆的边界
8.1 llama-server 不是 libllama 核心 API
llama-server 是 Tool。
它可能提供:
1HTTP API
2OpenAI-compatible API
3WebSocket
4Web UI
5slot management
6request queue
7continuous batching
这些都属于 Application 层。
真正的 libllama API 是:
1include/llama.h
8.2 common/ 不是核心 API
common/ 通常是工具辅助库。
它可能包含:
1参数解析
2采样参数默认值
3chat template helper
4log helper
5CLI utils
它是 Tool-side helper。
不能把它和:
1include/llama.h
混为一谈。
8.3 llama-quantize 是 Tool,不是量化 Kernel
llama-quantize 是可执行工具。
它调用 API 或 GGML 量化函数。
真正的量化相关模块分成三层:
1Tool:
2 llama-quantize
3
4GGML Tensor IR:
5 Q4_K / Q6_K / IQ4_XS 等格式定义
6
7Kernel:
8 CPU/CUDA/Metal 上的 quantize/dequantize/matmul 实现
8.4 ggml-cuda 不只是 Kernel
ggml-cuda 目录通常包含:
1CUDA backend 管理层
2CUDA kernels
3buffer 管理
4stream/event 管理
5op dispatch
所以要拆开看:
1ggml-cuda backend -> Backend
2.cu kernels -> Kernel
8.5 GGUF 不是 Runtime
GGUF 是模型文件格式。
读取 GGUF 的是 Model Loader。
Runtime 使用已经加载好的模型对象。
1GGUF file : 数据
2GGUF parser : Model Loader
3llama_model : Runtime 对象
4llama_decode : Runtime 行为
8.6 Graph Scheduler 不是请求调度器
1Graph Scheduler:
2 调度 ggml op 到 CPU/GPU/Metal/Vulkan...
3
4Request Scheduler:
5 调度用户请求、slot、conversation、batch
前者在 GGML。
后者通常在:
1llama-server
2application layer
8.7 llama_decode() 是 API,但执行路径跨越很多层
1llama_decode()
本身是 API。
但它内部会经过:
1Runtime
2 -> Graph Builder
3 -> GGML Scheduler
4 -> Backend
5 -> Kernel
6 -> Hardware
所以不能说:
1llama_decode() 只是 Runtime
更准确地说:
1llama_decode() 是 API 入口,
2其实现涉及 Runtime / Engine / Scheduler / Backend / Kernel。
9. 推荐架构图:带角色标注
可以画成下面这样:
1┌──────────────────────────────────────────────┐
2│ Applications / Tools │ Tool
3│ │
4│ llama-cli │
5│ llama-server │
6│ llama-quantize │
7│ llama-bench │
8│ bindings │
9└──────────────────┬───────────────────────────┘
10 │
11 │ C API
12 ▼
13┌──────────────────────────────────────────────┐
14│ Public API │ API
15│ │
16│ include/llama.h │
17└──────────────────┬───────────────────────────┘
18 │
19 ▼
20┌──────────────────────────────────────────────┐
21│ libllama Runtime │ Runtime
22│ │
23│ Model Loader │ Model Loader
24│ Model Object │
25│ Context Object │
26│ KV Cache │
27│ Tokenizer / Vocab │
28│ Sampling / Grammar │
29│ LoRA / Adapter │
30└──────────────────┬───────────────────────────┘
31 │
32 ▼
33┌──────────────────────────────────────────────┐
34│ Inference Engine / Graph Builder │ Engine
35│ │
36│ build ggml_cgraph │
37└──────────────────┬───────────────────────────┘
38 │
39 ▼
40┌──────────────────────────────────────────────┐
41│ Graph Scheduler + Allocator │ Scheduler
42│ │
43│ ggml_backend_sched │
44│ ggml_gallocr │
45└──────────────────┬───────────────────────────┘
46 │
47 ▼
48┌──────────────────────────────────────────────┐
49│ GGML Tensor IR │ Tensor IR
50│ │
51│ ggml_tensor │
52│ ggml_cgraph │
53│ ggml_op │
54│ quant types │
55└──────────────────┬───────────────────────────┘
56 │
57 ▼
58┌──────────────────────────────────────────────┐
59│ Backend │ Backend
60│ │
61│ CPU │
62│ CUDA │
63│ Metal │
64│ Vulkan │
65│ SYCL │
66│ HIP │
67│ BLAS │
68│ RPC │
69└──────────────────┬───────────────────────────┘
70 │
71 ▼
72┌──────────────────────────────────────────────┐
73│ Kernels │ Kernel
74│ │
75│ SIMD / AVX / NEON │
76│ CUDA kernels │
77│ Metal shaders │
78│ Vulkan compute shaders │
79│ SYCL kernels │
80│ HIP kernels │
81└──────────────────┬───────────────────────────┘
82 │
83 ▼
84┌──────────────────────────────────────────────┐
85│ Hardware │
86└──────────────────────────────────────────────┘
10. 如果要做架构扩展,应该改哪层?
这个可以帮助判断模块边界。
10.1 新增一个 CLI 功能
应该改:
1Tool
例如:
1llama-cli
2llama-server
3llama-bench
不应该改:
1Kernel
2Backend
3GGML Scheduler
除非需要新的底层能力。
10.2 新增一个模型架构
通常改:
1Model Loader
2Runtime
3Inference Engine / Graph Builder
例如:
- 新增 GGUF tensor name mapping;
- 新增 hparams 解析;
- 新增 graph 构建逻辑;
- 新增 tokenizer 特殊处理;
- 新增 chat template。
一般不需要改:
1Backend
2Kernel
除非模型使用了新的 op 或新的计算模式。
10.3 新增一个 GPU 后端
应该改:
1Backend
2Kernel
例如新增:
1ggml-newbackend
需要实现:
- buffer;
- buffer type;
- event;
- graph compute;
- supports_op;
- device kernels。
通常不需要改:
1llama.h
2llama Runtime
3Model Loader
除非新后端需要特殊模型加载策略。
10.4 新增一个量化格式
需要改:
1GGML Tensor IR
2Kernel
3Quantization Tool
包括:
- 新
ggml_type - block size
- quantize/dequantize
- CPU/CUDA/Metal/Vulkan matmul kernel
llama-quantize支持
可能需要改:
1Model Loader
如果 GGUF metadata 或 tensor 存储方式有影响。
10.5 新增 sampling 策略
通常改:
1Runtime Sampling
2API
3Tool
例如:
- 新 sampler;
- 新参数;
- 新 sampler chain 节点;
- CLI 参数;
- server 参数。
不需要改:
1Backend
2Kernel
3Graph Scheduler
11. 最终总结
可以把 llama.cpp 的架构压缩成一句话:
1llama.cpp = C API + LLM Runtime + GGUF Model Loader + GGML Graph Engine + Multi-backend Scheduler + Device Kernels + CLI Tools
更严格地分:
1API
2 include/llama.h
3
4Runtime
5 src/llama*
6 model / context / kv cache / sampling / grammar / tokenizer
7
8Model Loader
9 GGUF parser
10 llama-model-loader
11 tensor mapping
12 weight placement
13
14Inference Engine
15 graph builder
16 llama_decode 内部前向图构建
17
18Graph Scheduler
19 ggml_backend_sched
20 ggml_gallocr
21
22GGML Tensor IR
23 ggml_tensor
24 ggml_cgraph
25 ggml_op
26 quant types
27
28Backend
29 CPU / CUDA / Metal / Vulkan / SYCL / HIP / BLAS / RPC / vendor backends
30
31Kernel
32 SIMD / .cu / .metal / SPIR-V / SYCL / HIP device code
33
34Tool
35 llama-cli / llama-server / llama-quantize / llama-bench / bindings / scripts / tests
最关键的边界是:
1API 是接口。
2Runtime 是推理运行时。
3Model Loader 是模型加载。
4Engine 是图构建。
5Scheduler 是执行调度。
6Backend 是设备执行抽象。
7Kernel 是设备数学实现。
8Tool 是上层应用。
参考链接