Appearance
计算图 (Compute Graph) 是 GGML 中描述张量运算关系的数据结构,以有向无环图 (DAG) 表示,支持前向传播和自动微分。
为什么需要 compute-graph
LLM 的 forward pass 涉及数百个张量运算(矩阵乘法、归一化、激活函数等)。计算图将这些运算组织为 DAG,使得 GGML 可以:
- 自动推导运算顺序
- 优化执行计划(算子融合、内存复用)
- 支持自动微分(反向传播)
- 将运算分发到不同硬件后端
核心原理
c
// 在公共头 ggml.h 中仅为前向声明(opaque),实际定义在私有头 ggml/src/ggml-impl.h
struct ggml_cgraph {
int size; // nodes/leafs/grads/grad_accs 的最大容量
int n_nodes; // 当前节点数
int n_leafs; // 当前叶子节点数
struct ggml_tensor ** nodes; // 运算节点(数据可变)
struct ggml_tensor ** grads; // 节点对应的梯度输出
struct ggml_tensor ** grad_accs; // 梯度累加器
struct ggml_tensor ** leafs; // 常量输入张量
int32_t * use_counts;// 按 hash 槽索引的引用计数
struct ggml_hash_set visited_hash_set;
enum ggml_cgraph_eval_order order;
uint64_t uid; // 可选标识,匹配非零值用于识别同一图
};注:旧版本使用固定大小数组 nodes[GGML_MAX_NODES],现版本已改为动态指针,且不存在 GGML_MAX_NODES 常量。
工作流程:
- 构建 — 用户通过
ggml_mul_mat(),ggml_add()等创建张量运算 - 收集 —
ggml_build_forward_expand()将目标张量的所有依赖加入图 - 执行 —
ggml_graph_compute()按拓扑序遍历并计算每个节点 - 微分 —
ggml_build_backward_expand()自动构建梯度计算图
在源码中的实现
ggml/include/ggml.h—ggml_cgraph结构和图操作 APIggml/src/ggml.c— 图构建和执行实现ggml/src/ggml-backend.cpp— 后端执行计算图src/llama-model.cpp— 为 Transformer 层构建计算图