为什么你的显卡跑大模型很慢?可能你多做了一遍 FP16 的“显存折返跑

发布时间:2026/6/21 9:38:20
为什么你的显卡跑大模型很慢?可能你多做了一遍 FP16 的“显存折返跑 一个 Q4_0 权重块只有 18 字节,里面装下 32 个权重;而 llama.cpp 的 CUDA 后端做矩阵乘法时,从头到尾没把它反量化成 fp16——它在寄存器里用一条__vsubss4((qs 0) 0x0F0F0F0F, 0x08080808)把 4-bit 当场拧成有符号 int8,直接喂给 tensor core。你可能会问:反正都要算,先解包成 fp16 再调 cuBLAS,不是更省事、更"标准"吗?问题在于——同一个 7B 模型走 cuBLAS 那条路,decode 速度会掉一截,而掉的地方根本不在算力。decode 阶段 GPU 的瓶颈是显存带宽,"先反量化"恰好要凭空多读写一整遍 N×K 的 fp16 中间矩阵。那一遍读写,就是慢的根。这篇文章我带你把 ggml-cuda 这三万七千行 CUDA 代码里最较真的几处——mmq 的寄存器解包、Flash Attention 那两个标量、CUDA Graph 的两帧 warmup——对着真实行号逐行读穿。读完你会拿到一把钥匙:拿到任何一个 GPU 后端,先问它在哪里省下了"读写显存"和"提交命令"这两笔账。一、从一张计算图到一条 switch先把地基铺平:一张计算图是怎么落到 GPU 上跑起来的?ggml 的执行模型是"计算图 + 后端"。前端把模型的前向计算编成一张ggml_cgraph——一个张量节点的拓扑序数组,每个节点带一个op(操作码)和最多GGML_MAX_SRC个输入张量。CU