Appearance
GGML 张量库基础 — 概念
张量 (Tensor)
GGML 中的张量用 ggml_tensor 结构体表示:
c
struct ggml_tensor {
enum ggml_type type; // 数据类型 (F32, F16, Q4_0, ...)
struct ggml_backend_buffer * buffer; // 所属后端缓冲区
int64_t ne[GGML_MAX_DIMS]; // 每个维度的元素数
size_t nb[GGML_MAX_DIMS]; // 每个维度的字节步长
enum ggml_op op; // 操作类型
int32_t op_params[GGML_MAX_OP_PARAMS / sizeof(int32_t)]; // 操作参数
int32_t flags; // 标志位
struct ggml_tensor * src[GGML_MAX_SRC]; // 输入张量(图边)
void * data; // 数据指针
char name[GGML_MAX_NAME]; // 张量名
// ... 其后还有 view_src / view_offs / extra / padding 等
};注:
n_dims并非结构体成员,而是辅助函数ggml_n_dims()(按ne[]推断实际维度数);旧版的grad字段早已移除,梯度现在通过计算图的op/src[]链路传递。
关键设计:
ne[](number of elements) — 每维元素数,如[rows, cols]nb[](number of bytes) — 每维字节步长,支持非连续内存type— 支持 F32、F16、以及多种量化类型 (Q4_0, Q5_1, Q8_0 等)
数据类型
| 类型 | 比特数 | 说明 |
|---|---|---|
GGML_TYPE_F32 | 32 | 标准 float |
GGML_TYPE_F16 | 16 | 半精度 |
GGML_TYPE_BF16 | 16 | BF16(部分后端通过转换为 F16 支持,如 OpenCL) |
GGML_TYPE_Q4_0 | 4.5 | 4-bit 量化 (block) |
GGML_TYPE_Q5_1 | 6.0 | 5-bit 量化(含 min offset) |
GGML_TYPE_Q8_0 | 8.5 | 8-bit 量化 |
GGML_TYPE_Q2_0 | 2.25 | 2-bit 量化(block QK2_0=64,18 字节:1×f16 scale + 16 字节 2-bit 打包值) |
GGML_TYPE_IQ4_XS | 4.25 | 超低比特量化 |
计算图
GGML 使用计算图描述运算:
构建方式:
c
struct ggml_context * ctx = ggml_init(params);
struct ggml_tensor * x = ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 1);
ggml_set_param(ctx, x);
struct ggml_tensor * a = ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 1);
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 1);
struct ggml_tensor * x2 = ggml_mul(ctx, x, x);
struct ggml_tensor * f = ggml_add(ctx, ggml_mul(ctx, a, x2), b);自动微分
- 标记为
param的张量会自动计算梯度 ggml_set_param(ctx, tensor)将张量标记为可训练参数- 反向传播通过
ggml_build_backward_expand()自动构建梯度图
内存管理
ggml_context是一个内存池,所有张量从中分配ggml_init()创建上下文,需指定内存大小ggml_free()一次性释放所有张量
性能优化
- 量化查找表 (quant LUT) 的初始化现已并行化(多线程同时构建不同类型的 LUT),缩短启动时间
- GGML 版本已升级至 0.23.0(从 0.13.1 起经 0.14.0 → … → 0.17.0 → 0.18.0/0.18.1 → 0.19.0 → 0.20.0-0.20.2 → 0.21.0 → 0.22.0 → 0.23.0 逐级提升,通过
sync: ggml子树合并引入)
最近窗口(e9fa0781f → 9113cc188,b9840 → b11065,693 commits)GGML 0.17.0 → 0.23.0:六个小版本的跨版本升级,但
GGML_OP_COUNT(101)与GGML_TYPE_COUNT(43)均未变化——本窗口的变化在语义层:ggml_prec精度规范重写(见下)、ggml_clamp拆分为非原地 +ggml_clamp_inplace、新增ggml_rope_set_offset()(前 n_offs 维不旋转)、ggml_ssm_scan增加第 9 参K(循环态回滚快照)、新增ggml_build_forward_order();RPC 协议 4.0.3 → 6.0.0。详见 推理图、采样量化。
ggml_prec 精度规范(重写)
enum ggml_prec 从「F32/DEFAULT 二选一」扩展为一组数值等级(#26675):
c
GGML_PREC_UNDEFINED / GGML_PREC_DEFAULT = 0,
GGML_PREC_F32 = 10, // 累加必须 F32
GGML_PREC_BF16 = 15,
GGML_PREC_F16 = 20,
GGML_PREC_Q8 = 30, // 允许把 F32/BF16/F16 数据降精度到 Q8_0
GGML_PREC_Q4 = 40, // 允许降到 Q4_K / NVFP4 / MXFP4 等 4-bit配套两个通用 setter:ggml_prec_set_acc(t, prec)(累加精度,适用 MUL_MAT / MUL_MAT_ID / FLASH_ATTN_EXT)与 ggml_prec_set_src(t, prec, idx)(允许实现把 src[idx] 内部降精度,仅 MUL_MAT 系且 idx==1)。旧的 ggml_mul_mat_set_prec / ggml_flash_attn_ext_set_prec 已标记 deprecated。
COL2IM_1D 算子
GGML_OP_COL2IM_1D(ggml_col2im_1d())是 IM2COL 系列的逆运算:
IM2COL/IM2COL_3D— 将图像/特征图展开成列矩阵,便于用矩阵乘实现卷积COL2IM_1D— 把列矩阵反向聚合回 1D 特征图,用于卷积的反向梯度计算
算子在上游引入后,本窗口补齐了 CUDA 与 Vulkan 后端的实现(Metal 端的 1D im2col 路径此前已修复),使音频模型在各加速后端上都能走反向梯度。
该算子主要服务于音频模型(如 Whisper 的 1D 卷积层)在自动微分路径上的需求。
CPU 后端算子优化
x86 / ARM / Power 上的核心 kernel 也在持续打磨:
- AMX 优化 — Intel AMX 路径进一步调优矩阵乘
- Power10 / Power11 — power10 的 Q8/Q4 MMA matmul 支持 K-tail(处理非整除尾部),power11 后端按编译器支持条件启用
- SVE 修复 —
ggml_vec_dot_f32中残留的 SVE 路径修正,避免在非目标平台误用
算子定义与后端实现是两件事:一个
GGML_OP_*先在头文件声明并给出 CPU 参考,各硬件后端(CUDA/Vulkan/Metal/…)随后逐步补齐各自的 kernel。本窗口的col2im_1d(CUDA/Vulkan)与rope_back(Metal)就属此类"已有算子补后端"。
相关概念
- compute-graph — 计算图的详细设计
- quantization — 张量量化原理
- backend — 计算图在后端上的执行