经常有朋友上来就丢一张截图问我:我这显卡能跑多大的模型?说实话,这个问题看起来简单,但直接回答很容易翻车。光说显存多少、型号多高级不够,真正决定答案是几个变量凑在一起算出来的——模型参数量、加载精度、上下文长度、量化方案、还有你实际能用的显存到底有多少。这篇文章就把"显存计算"这条线彻底捋清楚,从公式到手算到实测,给你一套能直接复用的模型选择方法。
不管你是想在本机跑个开源小模型做实验,还是打算部署一个能长期对话的助手,只要把显存这笔账算明白,就不会再出现"下了一个模型然后一直爆显存"的情况。内容偏实操,适合刚接触本地模型部署、或者已经在跑但经常遇到CUDA out of memory的读者,认真看完这篇,至少能少踩一半的坑。
1. 先算清显存里究竟要塞多少东西
1.1 权重、KV Cache、激活值:显存开销的三座大山
估算显存的第一步,是把"模型要占的地方"拆成三块:模型权重、KV Cache、激活值。
模型权重最好理解,就是神经网络那一堆参数本身存下来需要多少字节。比如一个70亿参数的模型,如果每个参数用2字节保存,那光权重就是14GB,这部分在你加载模型的那一刻就固定占掉了,不管你生成一个token还是生成一万个token,它都在那里。
KV Cache是很多人容易忽略的地方。Transformer架构在做推理时,每一轮生成都要用到之前所有token的Key和Value向量,这些向量不能重复计算,所以需要缓存下来。它随着上下文长度线性增长,你让模型读一篇长文档、或者进行多轮对话,上下文越长KV Cache越大。最离谱的情况是,一个量化后只有4GB的模型,上下文拉到32K之后KV Cache可能比模型权重还大。
激活值则是前向计算过程中产生的中间变量,平时对话场景里它占的空间不算大,但如果你用很大的batch size同时跑很多条请求,或者上下文特别长,激活值也会变成不能忽视的一块。推理框架里常说的"flash attention可以省显存",省的主要就是这部分。
这三块加起来,才是模型真正占用的显存总量。很多人只看模型文件大小就下单,下载回来加载完直接OOM,本质上是只算了权重、没算另外两项。
1.2 可用显存要先扣掉两笔隐形成本
显存标称和实际可用之间,永远隔着一道墙。第一道墙是系统层面已经占用的显存——你开着浏览器、桌面环境、其他图形应用,它们都在吃显存。第二道墙是CUDA context本身要占掉的显存,通常几百MB到1GB不等,具体看驱动和框架版本。所以一张标称8GB的卡,实际能留给模型的空间经常只有7GB甚至更少。
这时候就要养成一个习惯:不要看任务管理器里的显存数字,那是"你觉得你在用的部分",很多时候不准。正确做法是用显卡驱动自带的监控工具查看当前已用显存和剩余显存,比如nvidia-smi这类命令行工具,把其他程序关掉之后再去计算可用空间。
我之前遇到过一个很典型的例子,有位朋友说自己的卡标称16GB,怎么加载一个8GB的模型都报显存不足。我让他看了一眼显卡监控,结果发现他后台挂着桌面合成器、一个浏览器外加一个视频渲染进程,三样东西吃掉了接近6GB,实际能用的只剩10GB不到。所以显存计算的第一步永远是"先看实际可用"。
2. 显存计算的核心公式:从参数量到GB
2.1 精度系数表:FP16、INT8、INT4各占多少字节
模型权重占用的字节数,完全取决于保存精度。这里给一个非常实用的对照关系,直接按"参数量乘以系数"来估算就行:
| 精度 | 每个参数占用字节数 | 7B模型权重近似占用 | 13B模型权重近似占用 |
|---|---|---|---|
| FP32 | 4字节 | 28GB | 52GB |
| FP16/BF16 | 2字节 | 14GB | 26GB |
| INT8 | 1字节 | 7GB | 13GB |
| INT4 | 0.5~0.65字节 | 3.5~4.5GB | 6.5~8.5GB |
FP32在今天基本不会有人拿来做推理了,训练或者追求极致精度才用。日常跑模型最常见的是FP16和量化精度。INT4之所以不是一个整数,是因为现在的量化实现通常不是每个参数单独量化,而是一组参数共享一个缩放系数,这部分额外开销加进去,实际占用会比理论值略高。
这里给一个估算法则:FP16下,模型权重的GB数约等于参数量的两倍;INT8约等于参数量本身;INT4大约等于参数量的60%。7B模型对应下来就是14GB、7GB、4GB出头。这个估算对大多数开源模型都适用,误差在1GB以内。
2.2 一个7B模型的完整计算过程(含KV Cache)
纸上谈兵没意思,直接算一遍。假设某7B模型,层数32、注意力维度是4096,用FP16加载,推理上下文长度设定为4096。权重已经算过了,14GB,实际加载时框架自身还有一点结构开销,保守算14.5GB。
再算KV Cache。标准的多头注意力架构里,每一层每个token的KV Cache大小是2组向量乘以维度4096再乘以2字节,也就是16KB。32层下来,每个token约512KB。4096个token就是2GB。所以模型加载后,光是上下文吃到4096,KV Cache就要2GB。
激活值先按1GB估算。那总占用就是权重14.5GB加KV Cache 2GB加激活值1GB,约17.5GB。反过来看,17.5GB这个数字说明:一张16GB显存的卡跑FP16精度的7B模型长上下文非常勉强,而24GB的卡就很从容。
如果你用的是支持GQA(分组查询注意力)的模型,KV Cache还能再砍掉一大截。GQA相当于让多个查询头共享一组KV,KV Cache直接除以分组比例,模型推理长文本时省下的显存相当可观。这也是为什么同样参数量、不同架构的模型,实际跑起来需要的显存可能差好几个GB。模型选择时如果以显存为主要约束,架构优势不能忽略。
3. 模型选择的实操思路:先定显存再定精度
3.1 不同显存档位的模型选择建议(附对照表)
把计算公式反过来用,就能根据你的显卡倒推适合的模型规模。基于个人实测经验,给出各档显存的参考方案:
| 显存档位 | FP16稳妥范围 | INT8稳妥范围 | INT4稳妥范围 | 实操建议 |
|---|---|---|---|---|
| 8GB | 3B以内 | 7B临界 | 7B舒适,13B勉强 | 优先7B量化,上下文控制在4K以内 |
| 12GB | 5~6B | 7B舒适,13B临界 | 13B舒适 | 7B任意精度随便跑,13B建议量化+短上下文 |
| 16GB | 7B,上下文别太长 | 13B舒适 | 30B级别尝试 | 日常主力档位,7B可开长上下文 |
| 24GB | 7~9B | 13~20B | 30B级别舒适 | 量化后甚至可以摸70B的门槛,但只能短上下文 |
| 48GB | 20B级别 | 30B级别 | 70B级别短上下文 | 服务器/专业卡配置,预算有限时优先量化 |
这个表格遵循的底层逻辑很简单:显存预算是"权重 + KV Cache + 激活值"的总和,而KV Cache上限取决于你能接受的上下文长度。如果你只需要短对话,那KV Cache开销很小,可以大胆上更高参数量;如果你打算做长文档分析,那就得主动降低模型规模,不然上下文还没拉长显存就爆了。
自己动手算的时候,按这个流程走:先查模型参数量和架构(层数、维度、是否GQA,这些在模型文档里都有),然后确定你的精度偏好,算出权重;再看你打算开多少上下文长度,算出KV Cache;最后留1GB左右的缓冲给激活值和框架开销。加起来小于可用显存,就行。
3.2 量化级别怎么选:别一上来就无脑INT4
量化是显存紧张时的救星,但也得讲究分寸。常见的量化格式里,INT4能省最多显存,代价是精度损失更明显;INT8精度损失很小,但节省有限;中间还有Q5、Q6这种折中方案。
实际使用感受是:如果显存余量允许,优先考虑INT8或者高质量的五比特量化;只有当显存确实吃紧、不上INT4就跑不起来的时候,才选择INT4。因为量化对模型能力的影响并不是均匀分布的——普通闲聊可能感觉不出来,但涉及数学计算、代码生成、逻辑推理这类对数值精度敏感的任务,INT4造成的降智是很明显的。
同样的模型,在24GB卡上用INT8跑一个13B模型的体验,通常比用INT4去够一个30B级别模型更舒服。量化省下的显存换来了更大的参数量,但丢了单模型本身的精度上限,这个交换是不是划算,取决于你的具体任务。如果任务本身对精度要求不高,比如文本分类、信息抽取,那大参数量的INT4模型反而是个合理选择。
在对比模型文件时还有个坑:不同量化格式的文件名看起来差不多,实际占用和效果差异很大。同级别的量化,不同实现方式可能差几个GB,建议下载前先查清楚这份量化文件的具体参数,而不是看文件名带个"4"就觉得是4比特、就按4比特算显存。
4. 实测现场:同一模型在多张卡上的真实表现
4.1 测试环境与显存观测方法
纸上算十遍不如实测一次。我搭了一套相对标准的测试流程:用同一个开源7B对话模型、同一份测试对话脚本,分别在8GB、12GB、16GB、24GB四张不同显存容量的显卡上跑。模型分别用FP16、INT8、INT4三种精度加载,每种精度依次设置1K、4K、8K三段上下文长度,记录显存占用、能否成功推理、以及生成速度。
观测显存靠的是显卡监控命令行工具,实时刷新看显存曲线。有一点很重要:监控要在推理过程中持续观察,而不是只看加载完成后的静态占用。因为生成第一批token时激活值会有一个峰值,很多人加载没问题、一开始生成就OOM,就是吃了这个峰值的亏。测完一次要清一下显存缓存再测下一组,不然上一次推理的残留占用会污染下一次的读数。
脚本方面用的是常见的大模型推理框架,加上Pipeline式的提问。为了排除其他干扰,所有测试都关掉图形界面和后台任务,并在每次测试前重启推理进程,保证显存从干净状态开始。
4.2 各档显存实测数据与结论
直接上结果。8GB卡上,FP16加载7B模型在"加载"这一步就失败了,OOM。换成INT8之后勉强加载成功,但上下文推到4K就开始报错,缩回1K才能稳定推理。换到INT4后,4K上下文也能正常跑,只是生成速度明显变慢,每秒不到10个token,属于能用但谈不上舒服。
12GB卡的表现有意思:FP16加载7B模型能成功,但上下文一旦超过2K,生成速度骤降,偶尔还会卡住。INT8下7B模型就很稳了,4K上下文还能维持流畅生成。INT4下不但7B模型随便跑,换成13B模型也能正常推理,只是速度和上下文长度需要取舍。
16GB和24GB卡基本算"用起来没焦虑"的档位。16GB卡跑FP16的7B模型毫无压力,上下文拉到8K也很稳;INT4下换成30B级别的模型,生成速度慢但能跑完整对话。24GB卡更宽裕,INT4模式下70B级别模型短上下文也能启动,生成速度差不多是"等得起"的水平。
整个测试下来最重要的结论是:显存大小决定了"能不能跑",而精度选择和上下文规划决定了"跑得爽不爽"。大多数显存焦虑其实是上下文焦虑——把上下文调短一截,很多问题当场消失。
5. 常见问题与排查技巧实录
5.1 "显存不够用"时的三个处理方向
显存不够,别急着换显卡,按优先级试三个方向。
第一个是降低精度。FP16换INT8通常能省一半显存,INT4又能再省一半。这个操作对推理效果的影响在可接受范围内,但前提是选对量化级别,别为了省显存把所有任务都压到INT4。
第二个是缩短上下文长度。很多人习惯把上下文直接拉满,但绝大多数任务根本用不到那么长。算一笔账:7B模型在8GB卡上,1K上下文的KV Cache只有0.5GB左右,8K就到了4GB——上下文从1K拉长到8K,相当于凭空多吃了3.5GB显存。如果你只是做短对话,把上下文设成2K立刻就能多出很大空间。
第三个是开启CPU offload,把一部分层放到系统内存里。这个方法能撑起超显存容量的模型,代价是速度断崖式下降,因为内存带宽和显存带宽差着数量级。我的建议是:offload只适合偶尔跑一跑、不追求速度的场景,长期用还是得回到前两个方向。
5.2 "显存明明够,但总提示OOM"的问题排查
这类问题最常见的原因有三个。
第一个是显存碎片化。加载模型、生成token、释放缓存反复几次之后,显存里会出现大量碎片,明明总量够,但连续大块空间不够,新的大分配就失败了。解决办法是定期重启推理进程,别让一个进程长时间跑。
第二个是框架的显存缓存机制。PyTorch这类框架用完显存后不会立刻还给系统,而是留在自己的缓存池里。你看到"显存占用很高"可能不是模型在占,是缓存机制导致的。这个不是bug,但如果你的监控工具只看总占用,会误以为模型吃掉了所有空间。排查时看进程对应的显存占用,而不是看全局剩余量。
第三个是上下文设置和实际的token长度不一致。有些框架在你输入的文本之外还要额外预留token空间,如果你设置max_new_tokens太大,预留空间算到KV Cache里就直接爆了。检查生成参数,把额外的生成上限调小,很多"加载没问题、一生成就OOM"的情况立即解决。
第四个容易被忽略的原因,是显存监控里的"其他进程"。驱动、桌面合成器、浏览器有硬件加速的话都会悄无声息吃显存。排查时优先关掉这些,再去看剩余空间够不够。
5.3 本地跑模型的几点避坑经验
最后分享几条实操中踩过坑才总结出来的经验。
第一,不要在系统内存紧张的情况下开CPU offload。offload会把大量层搬到内存,如果内存本身不够,系统会触发交换机制,速度慢到怀疑人生。开offload前先确认内存至少有模型权重两倍以上的空闲。
第二,别只看模型参数量来判断显存需求。相同参数量下,做不做量化、上下文开多长、模型是否有GQA,这些变量导致的显存差异远大于参数量的名义差异。所以下载模型之前,一定去查一下这个具体模型的层数、维度、注意力架构,用公式算一遍再决定。
第三,如果想长期跑一个固定模型,建议把"模型权重占用"和"KV Cache预算"分开记录。权重是固定的,KV Cache是浮动的,知道自己卡上每一部分还剩多少余量,调参数的时候心里才有数。
第四,生成速度其实主要受内存带宽限制,不是显存大小。同型号显卡大显存版本和小显存版本跑同一个模型,速度可能完全一样;真正拉开差距的是显存带宽。所以别指望靠"省显存"来提速,省出来的空间只能让你跑更大的模型,速度还得看硬件本身的带宽上限。
我自己平时判断一张卡能跑什么模型的顺序很简单:先看可用显存,再定上下文预算,然后用"权重 + KV Cache + 缓冲"反推能接受的参数量和精度,最后在满足条件的模型里挑任务匹配的那个。这样选出来的组合,基本不会在推理途中给你闹罢工。