Skip to content

计算图 (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 常量。

工作流程:

  1. 构建 — 用户通过 ggml_mul_mat(), ggml_add() 等创建张量运算
  2. 收集ggml_build_forward_expand() 将目标张量的所有依赖加入图
  3. 执行ggml_graph_compute() 按拓扑序遍历并计算每个节点
  4. 微分ggml_build_backward_expand() 自动构建梯度计算图

在源码中的实现

  • ggml/include/ggml.hggml_cgraph 结构和图操作 API
  • ggml/src/ggml.c — 图构建和执行实现
  • ggml/src/ggml-backend.cpp — 后端执行计算图
  • src/llama-model.cpp — 为 Transformer 层构建计算图

相关概念

  • ggml — 计算图所在的张量库
  • tensor — 计算图中的节点
  • backend — 计算图的执行后端