本地大模型显存预算:权重、KV缓存与运行余量

用可复现的算术框架估算本地大模型权重、KV缓存和运行时总内存需求。
本文提出一个可复现的算术框架,用于估算本地大模型部署时的总内存需求。文章指出,仅看“8B、4-bit”标签远远不够,实际内存由三部分组成:权重负载(参数量×位宽/8,但需考虑量化元数据和缩放因子)、KV缓存(公式为2×L×Hkv×D×T×C×S,强调使用KV头数而非查询头数)以及运行时开销(加载峰值、临时工作区、分配器预留等)。以Qwen3-8B为例,8192 token单序列的KV缓存约1.125 GiB,四序列则达4.5 GiB。文章还提醒注意GiB与GB的区别、Apple统一内存只能计算一次,并建议记录确切版本、实测峰值、保留余量,最终形成假设可调的预算工作表。
部署本地大模型时,看到一个“8B、4-bit”的标签,很多人会直接把它当成全部内存需求。但真正决定能否跑起来的,是权重、对话缓存和运行时开销的总和。本文用一个可复现的算术框架,帮你把这三部分算清楚。

权重负载:从参数量和位宽出发
权重的存储大小可以用一个简单公式估算:weight bytes = P × b / 8,其中 P 是标量参数数量,b 是每个参数的位数。
以一个恰好 80 亿参数的模型为例,理想化的负载如下:
- 16 bits:约 14.90 GiB
- 8 bits:约 7.45 GiB
- 4 bits:约 3.73 GiB
这里要注意 GiB(2^30 字节)和十进制 GB(10^9 字节)的区别,下载文件、内存监控和硬件规格经常混用这两种单位。
更重要的是,上述数字假设所有参数采用相同表示。真实的量化产物往往包含缩放因子、元数据,以及以更高精度保留的张量。据 Transformers 的 bitsandbytes 文档,量化线性层和其他模块是分开处理的,权重存储与计算 dtype 也是两回事。所以不要把所有“4-bit”标签当成同一种格式,必须核对具体的模型产物和运行时实现。
量化中的缩放因子与元数据
4-bit 量化并非简单地将每个参数截断为 4 位。以 bitsandbytes 的 NF4 或 GPTQ 为例,量化后的权重通常以块为单位存储,每个块附带一个缩放因子(scale)和零点(zero-point),这些元数据往往以 FP16 或 FP32 保存。此外,嵌入层、输出层和归一化层可能保持更高精度。因此实际权重文件会比理论值 P×b/8 略大,通常多出 5%-15%。
不同量化格式(GGUF、AWQ、GPTQ、bitsandbytes)的元数据开销和布局各不相同,加载时的内存峰值也可能不同。规划时应以模型仓库中实际文件大小为准,并留出加载缓冲。
KV 缓存:对话越长,增长越快
自回归生成时,Transformer 会复用已计算的键和值,这就是 KV 缓存。对于常规的全注意力解码层,未压缩缓存的估算公式是:
KV bytes = 2 × L × Hkv × D × T × C × S
其中 2 代表键和值,L 是注意力层数,Hkv 是每层的键/值头数,D 是每个键/值头的维度,T 是每条序列缓存的 token 数(含提示词和输出),C 是每个缓存元素的字节数(FP16/BF16 为 2),S 是独立存储的序列数。
关键点:要用 KV 头数,而不是查询头数。如果序列长度不同,应累加 token 数;上述乘法假设长度相等且没有共享前缀。束搜索或并发请求会引入更多独立缓存的序列。
以官方 Qwen3-8B 配置为例:36 层、8 个 KV 头、头维度 128,滑动窗口注意力关闭。在缓存 8192 token、每元素 2 字节、单序列的条件下:
2 × 36 × 8 × 128 × 8,192 × 2 × 1
= 1,207,959,552 bytes
= 1.125 GiB
同样假设下,4096 token 单序列约 0.5625 GiB,16384 token 单序列约 2.25 GiB,8192 token 四序列则达到 4.5 GiB。
这些只是张量负载估算,不代表总内存占用、速度或某台机器能否运行。其他架构和缓存实现需要调整公式:滑动窗口层可能只保留有界窗口;静态缓存会按配置上限预留,动态缓存随使用增长;缓存量化和卸载会改变内存位置和精度,并带来性能取舍。权重量化不会自动决定 KV 缓存的 dtype,要查后端支持的行为。
分组查询注意力(GQA)与 KV 头数
现代大模型(如 Qwen、Llama 3、Mistral 等)普遍采用分组查询注意力(Grouped Query Attention, GQA)而非经典的多头注意力。在 GQA 中,查询头被分成若干组,每组共享一对键/值头,因此键/值头数 Hkv 通常远小于查询头数。这就是为什么估算 KV 缓存时必须用 Hkv 而不是查询头数——如果用错,结果会严重高估。
以 Qwen3-8B 为例,它可能有 32 个查询头但只有 8 个 KV 头,意味着 KV 缓存只有传统多头注意力下的四分之一。这种设计在保持模型质量的同时显著降低了长上下文的内存压力,也是当前开源模型的主流选择。如果你的模型使用多查询注意力(MQA),则 Hkv=1,缓存会更小。
执行与加载:留给运行时的空间
规划工作表可以写成:常驻权重 + KV 缓存 + 运行时/工作负载开销。
要同时检查加载峰值和生成峰值。据 Accelerate 文档,加载过程可能产生额外的权重副本,分片加载能降低这种压力,而 CUDA 初始化本身就会占用权重之外的内存。CPU 或磁盘卸载改变了内存位置并引入传输,能装下不等于延迟可接受。
具体到你的运行时,要检查临时工作区、预填充分配、分配器预留,以及是否还有额外模型或多模态组件。没有通用的开销百分比,必须实测具体工作负载并保留余量。
在 Apple 芯片上,MLX 使用 CPU 和 GPU 共享的统一内存。这块共享容量只能算一次,要为操作系统和其他应用留出空间,不要把同一个统一内存池既算作 RAM 又算作 VRAM。
统一内存架构(Apple Silicon)
Apple M 系列芯片采用统一内存架构(Unified Memory Architecture),CPU 和 GPU 共享同一块物理内存池,不存在独立的显存。这意味着模型权重、KV 缓存、操作系统占用和其他应用内存都从同一容量中分配。因此,规划时只能将这块共享容量计算一次,不能像独立显卡那样把“系统内存”和“显存”相加。
实际可用容量通常小于标称值,因为 macOS 本身和后台应用会占用一部分。例如 32GB 统一内存的机器,实际能留给模型的可能只有 24-28GB。使用 MLX 或 llama.cpp 等框架时,应监控内存压力,并为系统保留足够空间,避免因内存交换导致性能骤降。
把估算变成可复现的检查
记录以下信息:确切的仓库、检查点修订号和量化产物;运行时版本和后端;缓存 dtype 和策略;提示词/输出 token 限制;并发序列数。
从小负载开始,分别增加上下文和并发度。用运行时支持的测量工具记录加载峰值、生成峰值、首 token 时间和生成速率,并说明内存是如何测量的——是已分配内存还是已预留内存。
这是一个提议的测量流程,本文不呈现任何实测结果,也不做“在我的笔记本上跑得很轻松”这类断言。
最后,检查确切版本的许可证。用于架构示例的官方 Qwen3-8B 仓库采用 Apache License 2.0,但不要把这个许可推广到其他 Qwen 版本、转换产物或无关模型。把适用的模型和运行时许可证与修订号、部署配置一起记录。
有用的产出是一个假设可调的预算:缩短上下文会降低常规缓存估算;降低权重精度会改变权重预算;增加独立序列会提高缓存需求。测量则告诉你估算在何处开始偏离实际运行时。
相关推荐

前端转AI Agent开发:一线架构师解析职业路径与红利
一线AI架构师解析前端转AI Agent开发的行业变化与落地路径:纯前端岗位为何消失、Agent+全栈为何成为招聘主流,以及Agent开发工程师、FDE、远程接单三条转型路线和对应学习策略。

AI Agent开发课程怎么选?五条避坑指南
机械转行开发者踩坑两年总结的AI Agent开发课程筛选清单:完整交付链路、可写进简历的项目、真实开发视角、更新频率、陪跑反馈五个维度,附具体判断方法和避坑要点。

扣子(Coze)智能体搭建入门:零代码开发AI Agent实战指南
扣子(Coze)是字节跳动推出的一站式AI应用开发平台,支持零代码拖拽搭建AI智能体。本文基于B站教程梳理扣子的核心概念、三大优势、国内版与国际版差异,以及智能体与应用的区别,帮助初学者快速入门AI Agent开发。