☰
大模型本地部署显存不够?从参数到GB的精确估算与量化选型指南
2026/10/14 6:37:39 网站建设 项目流程

大模型本地跑的瓶颈,从来不是网速,而是显存。我经常看到有人兴冲冲下载了一个“据说很强”的模型,结果一加载就报显存不足,或者在某个上下文特别长的瞬间直接崩溃。更麻烦的是,同一个模型,网上有人说 8G 能跑,有人说必须 24G,看起来矛盾,其实是因为大家默认的精度、上下文长度和并发数都不同。显存这件事是可以自己算出来的,算清楚之后,你的显卡能跑多大的模型、该选什么精度、该开多长上下文,都会有明确答案,而不是靠运气。

这篇文章我会从显存的构成讲起,给一套能直接套用的估算公式,再按 6G、8G、12G、16G、24G、48G 这些常见档位给出选型思路,最后聊聊实际运行中那些公式算不到的“隐藏开销”和排查经验。适合所有想在本机跑模型、做微调或布置本地推理服务的读者,尤其是被各种“最低配置”说法搞糊涂的朋友。

1. 显存到底被谁占满了:一张模型卡在 GPU 上的四大开销拆解

很多人以为“模型文件多大,显存就占多大”,这个说法只对了一半。模型文件是权重快照,真正运行时,显存里同时挤着权重、KV 缓存、中间激活和框架预留这四样东西,哪一样都不能少。

1.1 权重是最大的一块,但大小完全取决于精度

权重就是模型里所有“参数”本身。同一个模型,参数个数是固定的,但它在显存里占的字节数不固定,取决于每个参数用几个字节来表示:

  • fp32:每参数 4 字节,精度最高,体积也最大
  • fp16 / bf16:每参数 2 字节,大多数推理场景的主流选择
  • int8:每参数 1 字节,量化后的常见格式
  • int4:每参数 0.5 字节,最省显存,通常配合反量化逻辑读取

换算很简单:权重体积约等于参数数量乘以每参数字节数。以 7B 参数级模型为例,fp16 下就是 7 × 10^9 × 2 字节,约 14GB;int8 约 7GB;int4 约 3.5GB。第一步很多人会算,但接下来往往把另外三块开销忘得干干净净。

1.2 上下文越长,KV 缓存越大

KV 缓存,也叫注意力键值缓存,是模型生成时临时存放的历史键值对,目的是让新 token 只跟历史 token 做注意力计算,不用每步重算完整前向。代价是它随上下文长度线性增长,长对话、长文档场景下,这块经常大到和权重一个量级。

KV 大小的粗略公式是:2(Key 和 Value 两套) × 层数 × 注意力头数 × 每头维度 × 每参数字节数,再乘上当前序列长度。不同模型架构差异很大,拿一个 7B 级、32 层、32 头、每头 128 维的常见结构来套,单个 token 大约 0.5MB。看着不起眼,上下文到 8K 时就是 4GB 左右,直接顶掉半张 8G 卡。所以“模型 int4 量化完才 3.5GB,我肯定能跑长上下文”这种想法,通常会栽在 KV 上。

中间激活在推理时也有,主要是前向计算里的隐藏状态和临时张量,通常比权重小。但只要 batch size 开大、序列变长,它也会变成足够让你报错的另一刀。所以从这四块的关系已经能看出结论:显存需求不是一个“模型固定数字”,而是模型精度、上下文长度、并发批大小三者的函数。

2. 从“参数B”到“显存GB”的快速公式:fp16/bf16/int8/int4的换算逻辑

进入实操环节。先给一条能直接套用的经验公式:

推理场景的单路估算显存 ≈ 权重体积 + KV 缓存单 token 体积 × 上下文长度 × 并发数 + 余量

权重体积按前面的换算;KV 缓存则需要知道目标模型的具体结构,尤其是有没有共享 KV 头的设计。KV 单 token 字节数可用模型配置里的层数、注意力头数、头维度来算:

KV_bytes_per_token = 2 × 层数 × 注意力头数 × 头维度 × 精度字节

如果模型采用了 GQA、MQA 这类共享 KV 头设计,要用 KV 头数而不是总注意力头数,能省下不少显存。具体以模型配置文件为准,不同架构差异可能达到两到四倍。

2.1 一张精度换算表,把参数 B 直接换成显存 GB

精度每参数字节7B 模型权重13B 模型权重70B 模型权重
fp324约 28GB约 52GB约 280GB
fp16/bf162约 14GB约 26GB约 140GB
int81约 7GB约 13GB约 70GB
int40.5约 3.5GB约 6.5GB约 35GB

这张表能给你一个直觉:70B 级模型不是“13B 的五倍负担”,而是每次上档都要重新审视自己的卡。很多人问“40G 大显存能不能跑 70B”,答案很明确:fp16 权重 140GB,连边都摸不到;int8 也要 70GB;只有 int4 下的 35GB 才能勉强塞进 48G 左右的卡里。这就是为什么要先算账再下载,不然白花时间。

2.2 代入三个实际场景:7B、13B、70B 都别只看权重

场景一:8G 卡想跑 7B 原版 fp16。权重 14GB,直接出局。换成 int4 权重约 3.5GB,如果上下文限定在 4K,KV 按单 token 0.5MB 来算约 2GB,整机预估 3.5 + 2 + 1.5 余量 = 7GB,比较贴近但不宽裕。如果贪心把上下文拉到 8K,KV 直接变 4GB,总预估到 9GB,8G 卡必然爆。所以 8G 卡跑 7B int4,上下文 4K 以内更稳。

场景二:16G 卡想跑 13B fp16。权重 26GB,单卡放不下。换成 int8 约 13GB,4K 上下文的 KV 约 2GB,加上 1-2GB 余量,正好卡在 16G 附近,可以试但紧张。想要更长上下文,只能退到 int4 或者缩短序列。

场景三:24G 卡想跑 70B int4。权重 35GB,单卡纯 GPU 根本放不下。所以“24G 就能跑 70B”的说法背后,往往要么是走了 CPU 分载,要么是把上下文压得非常短,要么是多卡并行。单卡显存层面,这个级别的模型已经不属于“放得下”的范畴。

2.3 上下文和 batch 是两个乘数,不是两个常数

公式里的 KV 量级是随“序列长度 × 并发请求数”线性放大的。并发 4 路、上下文 8K 时,KV 开销变成单路对话的 4 倍;batch 进公式的时候也要乘进去,别只按 1 来算。

提示:所有估算值都应额外留出 10%-20% 缓冲。实际分配不是真空的,并行计算库、驱动、日志缓冲都会吃几十 MB 到几百 MB。预算贴太紧,加载那一刻就可能报错。

3. 量化不是白给的:从 FP16 到 int4 的取舍逻辑

量化是目前小显存跑大模型的现实手段,但“改成 int4”背后是有代价的。

3.1 量化到底做了什么

量化本质上是用低位宽表示权重,通过分段缩放系数尽量保住数值范围。直观理解:fp16 是每 2 字节记一个数,int4 是每 0.5 字节记一个数,体积压缩到四分之一,但低比特必然丢精度。效果怎么样,主要取决于量化算法的质量,不是简单“砍一半”就能等价。

我实测下来的体感是:int8 在很多场景几乎感知不到劣化,int4 在常用对话里也还能用,但在数学推理、复杂因果、稀有词这些地方会明显变“笨”或变“糊”。如果你的任务对输出确定性要求高,比如代码生成、结构化输出,优先选更高精度,不要一门心思冲 int4。

3.2 不同显存档位,量化的“安全水位”不同

卡显存7B 方案13B 方案70B 方案
6G不太建议,int4 短上下文勉强基本不行不行
8Gint4 短上下文可行int4 很紧张不行
12Gint4 常规长度可行 / int8 短长度int4 短长度勉强不行
16Gfp16 可行 / int8 带长上下文int8 短到中长度 / int4 更宽裕不行
24Gfp16 大上下文轻松fp16 中长上下文 / int4 余量够只 int4 且很吃紧
48G随便fp16 宽裕int4 有一定余量,int8 仍不够

这只是档位粗配,真实情况要和上下文、batch、是否微调强绑定。“能放进去”和“能用得舒服”是两回事。比如 24G 卡上跑 13B fp16,日常对话没问题,但你要一次读进去一份几万 token 的文档,KV 就会把剩余显存吃掉大半。

3.3 两个实测过的量化翻车现场

第一个翻车:为了在 8G 卡上硬上 13B int4,我把上下文设成了 16K。权重 6.5G 进去了,但 KV 直接失控,13B 级模型的 KV 单 token 比 7B 大不少,16K 上下文的 KV 能到 5-6G,剩余的一点点显存还没生成几个 token 就被耗尽。后来把上下文砍到 4K,稳定跑完。教训就是不要先定模型后定上下文,要先算总账。

第二个翻车:我把一个 70B 级模型在 24G 卡上用 int4 强行推理。短问答没问题,连续追问几轮也还能跑;一上长上下文就崩,而且每步要从内存或磁盘反复捞权重,速度慢到像死机。最后把一部分层分载到内存,关键时刻确实能顶住,代价是慢,但对“一定要在单卡上跑一次大模型”的人来说,这种慢是可以接受的。

4. 推理和微调是两笔账:优化器状态如何把显存需求翻上三倍

想微调的人常犯一个错误:拿推理公式往上怼。“7B 模型 fp16 才 14G,我 24G 卡应该能全参微调吧?”答案是不够,差得很远。训练要在推理基础上额外存三样东西:梯度、优化器状态、激活。

4.1 Adam 系优化器是显存黑洞

训练时为了让权重迭代,反向传播先要算出梯度,梯度和权重同大小,fp16 模型就多 14G;优化器如果用的是 AdamW,它为每个参数还要再存一阶动量、二阶动量,通常还会留一份 fp32 精度的权重副本来做数值稳定的更新。粗暴概括就是,权重之外至少还要按 12-16 字节每参数来算,更保守的估算会直接按 20 字节每参数。

全参数微调一个 7B 模型,按 fp16 权重加优化器状态的总代价来算,量级直奔上百 GB,这显然不是单卡消费级能承受的。24G 卡全参微调 7B,我基本会劝退。这也是现在 LoRA 类方案流行的根本原因。

4.2 LoRA 为什么能省:它只给一小块参数配“可训练副本”

LoRA 的思路不是更新全部权重,而是在注意力矩阵旁边加一排低秩的可训练小矩阵,冻结原权重,前向推理照常,训练只更新小矩阵。7B 模型可能只需要训练千分之几到百分之一的参数,优化器状态和梯度不再跟全模型挂钩,训练显存会瞬间降下来。再把基础模型量化成 int4,就是常见的 QLoRA 方案,单卡 16G 到 24G 微调 7B 类模型能成为现实,原因就在这里。

4.3 一表看清推理、全参微调、LoRA 的差距

配置7B fp16 权重需求额外显存需求单卡结论
纯推理约 14GBKV + 激活少量24G 卡轻松
全参微调权重 + 梯度 + 优化器状态激活数十 GB单卡基本别想
LoRA 微调14G 权重 + 小矩阵状态激活仍较大24G 卡比较勉强,需降批或短序列
QLoRAint4 权重约 4G + 小矩阵激活较大单卡 16G-24G 可试

注意:微调时的激活开销会随 batch size 和序列长度猛涨,且无法通过权重简单推算。就算 LoRA 把优化器状态省掉,一段长上下文也可能把显存吃到手抖。微调前务必从更短的序列、更小的 batch 起步,边跑边观察,再逐步加大。

5. 按显存档位选模型:6G 到 48G 到底怎么配

公式算明白了,接下来落地到“我的卡能跑多大模型”。下面是我常用的档位路线,不是绝对命令。实测逼近之前,永远要根据自己的任务目标做微调。

5.1 六个档位的参考配置

显存推荐档位精度 / 上下文建议适合场景
6G4B 级以下,7B 别强求int4 + 2K-4K轻量对话、小任务
8G7B 是上限int4 + 4K 以内,int8 只适合极短上下文通用对话、普通代码
12G7B 较舒服,13B 谨慎7B int8/int4 可加长;13B 仅 int4 短上下文对话、中等文档摘要
16G13B int4/int8,7B fp16 随便跑13B int4 建议 8K 内;int8 建议 4K 内复杂任务、长对话
24G13B fp16 舒服,27B-30B 级需 int4,70B 需分载13B fp16 长上下文;30B int4 短上下文;70B 靠外部分载本地推理、LoRA 微调
48G30B int8 舒服,70B int4 有戏70B 上下文化能压则压,避免 KV 爆炸单卡大模型、中规模微调

如果你心里已经有一个目标模型,做法是:查出它的参数量、层数、注意力头数、KV 头数,先算权重大小和单 token KV 体积;上下文按自己的实际需要来,短对话按 4K 到 8K 算,长文档按 16K 到 32K 认真评估。不要照搬别人的“16G 能跑”结论,因为对方可能只聊了两句话,你要的是读完整份文档。

5.2 档位之间的隐形坑

6G 和 8G 档最常踩的坑是忽视“连续聊天轮次”。一轮对话的上下文是连续累积的,聊到第三、第四轮就把 KV 撑大了;本地聊天助手一开始很流畅,聊久了开始卡或报错,本质就是 KV 线性增长撞墙。12G 档要注意别同时开多个推理服务,每个进程会独立缓存一份权重,两个 7B int4 进程加起来照样超过 10G。

24G 档的口号是“本地跑大模型”最响亮,但一定要分清是推理还是微调。推理 70B int4 可以凑合,微调 13B 全参几乎不可能,LoRA 反而是现实选择。48G 档虽然算单体大卡了,也要检查 CPU 内存和带宽是否成为瓶颈,模型分载时经常是“读到哪、算到哪”,内存喂太慢 GPU 就空转。

5.3 显存不够的另一条路:分载和多卡

如果算下来就差一点,有三条常见方案:把部分层分载到系统内存,换取这个级别模型的可运行性;用多卡张量并行,比如两张 24G 卡跑 70B int4 会舒服很多;或者反过来压需求,降低量化等级或缩短上下文。三条路都可走,但要在“能跑”和“体验”里做取舍。分载让每个 token 慢到让人怀疑人生,多卡有同步开销,缩上下文可能丢信息,没有完美答案。

6. 实际运行中那些“算外”的显存开销与排查经验

公式算完,不代表运行就顺利。实测中总有一堆“算外”开销,这里挑我遇到最多的三块讲。

6.1 框架缓存和系统预留:监控工具的数字不能直接解读

打开显卡监控工具,你会看到自己的进程显示的显存占用,比“权重 + KV”的估算值高出一截,而且不会即时回落。原因是主流深度学习框架倾向于向驱动申请大块显存池,分配在前、回收在后,进程退出前这块池子可能一直占着。所以用监控工具判断“模型到底占多大”是不准的,要看进程自己报的那一项,或者从框架内部的显存统计接口查实际分配量。

另一块是并行计算运行时的上下文和各种底层库的初始化开销,几百 MB 起步。这跟模型没关系,但会占掉你可用显存里的“零头”。前面估算时要求留 10%-20% 缓冲,对应的就是这件事。

6.2 一次 OOM 的完整排查链路,按这个顺序来

我实际遇过一次看似“模型明明能放下却报显存不足”的情况。排查过程大概是:

  1. 先用公式算:7B int4 权重 3.5G,上下文 8K 时估 KV 约 4G,卡是 8G,加缓冲已经到 7.5G 附近。第一反应是“就差一点”,于是把上下文降到 4K,但还是报错。
  2. 查框架内部的显存分配接口,发现峰值分配早就超过了估算。把模型配置拉出来重新算,发现它的 KV 头配置比通用例子多,单 token 不是 0.5MB 而是 0.75MB,8K 上下文的实际 KV 成本比预估高了一半。
  3. 确认框架预留:分布式缓存、临时分配池这些默认打开的预留机制吃了一部分,设置释放后回到公式附近,问题解决。
  4. 最后验证:改完配置连续跑多轮长对话,再用进程内的峰值统计接口记录整条曲线,确认估算对得上。

任何一次大模型 OOM 都应该走类似链路:先核对参数配置,再验上下文和 batch,再看框架预留,最后动量化或换模型。不要一上来就“换个 int4”或“换个小模型”,那样只是把问题表面压掉,换个场景还会再爆。

6.3 验证算得对不对的三个指标

我建议日常关注三个指标:加载阶段的显存峰值、跑单轮对话时的峰值分配、跑到长上下文时的峰值分配。三个值分别反映不同开销:加载只反映权重搬运,单轮对话反映权重加 KV 的日常量,长上下文直接检验 KV 是否成为瓶颈。

当你把这些值记录下来,会发现一个规律:如果长上下文运行时的峰值显著超过“权重 + 估算 KV × 长度”,那多半是激活或框架池在作祟,不是模型本身的问题。我现在的习惯是,每次下载新模型前,先用公式把边界算出来,跑一次就做一次三个指标对照。时间久了,显存规划会准得惊人,连“该不该换卡”这种问题都能用数据回答,而不是靠心情。

最后分享一个小技巧:在你准备冲一个大模型之前,先拿它的量化版跑一遍,把上下文故意调到你真实使用的最大长度,来回多聊几轮。如果这一关能稳定过,那我恭喜你,这台卡在相当长一段时间内都不用换了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询