☰
大模型显存怎么算?从量化精度到KV Cache的完整估算指南
2026/10/14 6:36:49 网站建设 项目流程

“我这张显卡能不能跑大模型?”这个问题,我隔三差五就会被人问一次。前阵子又有朋友发来一张报错截图,大红字写着CUDA out of memory,问他配置和型号,答:8GB显存,硬扛一个13B模型的原版FP16权重。我看了真想隔空锤他一下——这真不是显卡不行,是显存这笔账没算明白。类似的场景实在见得太多了。

显存这个东西,不像内存可以随手加根条子,买错卡就是花钱买教训。而且很多人只盯着“几十B参数”看,却不知道最终决定能不能跑起来的,是一整套显存开销的组合。这篇我就把显存计算这件事彻底拆开讲透:模型占多少显存、上下文会吃多少、训练和推理差多远、怎么选量化、怎么用工具实测,让你手里任何一张显卡,都能快速判断出它可以跑的模型上限。

1. 显存都消耗在哪里:先搞清楚钱的去向

很多人的第一反应是“显存大小等于模型文件大小”。这话只对了一半。模型权重确实是大头,但绝对不是全部。一张显卡上跑大模型,显存至少被四类东西同时占着:模型权重、KV Cache、激活值和运行时缓冲。忽视任意一类,都可能让你在关键时刻翻车。

1.1 模型权重:最大的一笔固定开销

权重是神经网络里存储的参数。一个7B模型,字面意思就是有70亿个参数。每个参数在显存里占多少字节,取决于你用什么精度存储。最常见的精度对应关系非常规整:

  • FP32(全精度):一个参数4字节
  • FP16 / BF16(半精度):一个参数2字节
  • INT8(8位量化):一个参数1字节
  • INT4(4位量化):一个参数0.5字节

也就是说,每十亿参数在不同精度下的权重占用非常容易估算:FP32大约4GB,FP16/BF16大约2GB,INT8大约1GB,INT4大约0.5GB。一个7B模型的权重,FP16版本就是14GB左右,INT4版本大概3.5GB。这也是为什么很多老显卡用户兴奋地下载INT4量化版,因为文件体积适合,跑起来也确实省显存。

这里有个容易忽略的点:权重在推理时是常驻显存的,不会像内存那样可以被交换到磁盘再换回来。如果不做任何显存溢出(offload)处理,这一份开销从模型加载开始就锁死在显卡上,直到模型卸载。

1.2 KV Cache:你聊得越长,它吃得越多

权重是大头没错,但另一个容易被低估的显存消耗者是KV Cache。现在的生成式模型本质上是逐字吐词的,每生成一个新词,都要回顾已经生成的所有内容。为了不用每次都重新算一遍历史内容,推理框架会把历史词的中间结果——准确说是Key和Value向量——缓存下来。这个缓存就是KV Cache。

KV Cache的特点是随着对话上下文变长而线性增长。它的大小可以用一个简化公式估算:约等于 2(Key和Value两份)× 层数 × 隐藏维度 × 序列长度 × 批次大小 × 每个元素字节数。听起来很抽象?我直接算一遍。

拿一个常见的7B模型来做例子,假设它有32层、隐藏维度4096,用FP16存储(每元素2字节),上下文长度设为4096个token,一次只处理一条请求(batch=1):

2 × 32 × 4096 × 4096 × 1 × 2字节 = 约2GB

也就是说,光这4K上下文的KV Cache,就要吃掉大约2GB显存。如果上下文拉到8K,就是4GB;拉到32K,就是8GB以上。这还只是一个小模型的中等上下文,如果换成层数更多、维度更大的34B或70B模型,KV Cache会非常可观。

所以你会看到同一个模型,在短上下文下跑得好好的,改成超长上下文后马上就OOM。很多长上下文模型需要特殊架构来压缩这部分的消耗,比如用分组查询注意力(GQA)机制,能显著降低KV Cache体积。这也是为什么同样是7B,有些新模型在相同长上下文的显存占用上会更友好。

注意:KV Cache的实际大小因模型架构而异。上面公式里的层数、隐藏维度、注意力头设计都会直接影响最终数值。更关键的是,模型每生成一个token,KV Cache就会涨一点,所以长对话或者长文生成场景,必须额外预留这份显存。

1.3 激活值、运行时缓冲:平时不起眼,关键时翻车

除了权重和KV Cache,还有一类开销叫激活值(activations),也就是数据在网络流经各层时产生的中间结果。推理阶段如果batch=1,激活值通常比较小,只有几百MB到1GB的量级;但在训练或微调阶段,激活值会暴涨,因为它要在反向传播时保留大量中间结果来计算梯度。

还有一个绕不开的开销是运行时缓冲。PyTorch这类框架加载CUDA环境、分配临时工作区、建立上下文,这部分会有固定占用,通常几百MB到1GB。像transformers库加载模型时,还会短暂出现峰值显存——有时候加载一个FP16权重模型,峰值会短暂冲到权重体积的两倍,因为框架需要先在内存/显存里做一些转换处理。很多人就是栽在这一下突刺上。

所以完整的显存账本应该是:权重 + KV Cache + 激活值 + 框架缓冲,再留出一些安全余量。只算权重,必然会得到乐观的错误结论。

2. 显存计算公式:从参数量到实际占用的换算

知道了显存的去向,下一步就是把它们量化成可用的公式和速查表。我现在帮你把“能不能跑”这个问题变成一个计算题,你只需要知道模型参数量、计划精度、上下文长度,就能在一两分钟内得出大概结论。

2.1 一张速查表:不同精度下每十亿参数的成本

先记住这张最核心的换算表,以后所有显存估算都从它出发:

存储类型每十亿参数量占用7B模型示例适用场景
FP32约4GB约28GB训练主权重保存、CPU推理
FP16 / BF16约2GB约14GB常规GPU推理、混合精度微调
INT8约1GB约7GB显存受限时的高质量推理
INT4约0.5GB约3.5GB消费级显卡本地运行的首选

细心的读者会问:为什么我说“轻量部署”推荐INT4,而不是INT8?因为从FP16降到INT8,权重直接减半;再降到INT4,又减半。对于一个24GB显卡,FP16的13B模型装不下,但INT4的34B模型反而能装下。在显存天花板不变的条件下,量化档位直接决定你能跨几个模型档位。

另外要区分文件夹里模型文件的大小和实际运行占用。一个GGUF格式的Q4_K_M量化模型文件可能只有4GB左右,但在加载时框架还要额外创建一些临时缓冲、计算图信息,实际进程占用会在5到6GB甚至更高。文件大小只能作为参考下限。

2.2 推理场景完整公式:权重 + KV Cache + 激活开销

把刚才的内容收拢成推理场景的估算公式:

预计显存占用 ≈ 权重占用(参数量 × 每参数字节数) + KV Cache + 1~2GB(框架缓冲和激活)

我再用三个实例带你走一遍计算过程。

实例一:8GB显存显卡跑7B模型的INT4量化版。 权重:7B × 0.5GB每B参数 = 约3.5GB。KV Cache在2048上下文、模型为32层、dim=4096、FP16存储时约1GB(2 × 32 × 4096 × 2048 × 2字节 ≈ 1GB)。加上框架缓冲和激活,总占用约5.5GB到6GB。结论:8GB能跑,还有约2GB余量,非常紧张,建议上下文控制在2048以内。

实例二:12GB显存显卡跑7B模型的FP16原版。 权重约14GB,算完就知道单卡装不下。所以12GB显卡想玩7B模型,要么换INT8(约7GB权重 + 其他开销,总共9GB左右,能跑),要么换INT4(更宽裕)。原版FP16必须用16GB以上的显卡才能舒服。

实例三:24GB显卡跑13B模型的INT4量化版。 权重约6.5GB,即使开长上下文,KV Cache扩到8GB左右,总占用大约16GB,24GB显存有充足余量,甚至可以尝试把上下文加到16K以上。这就是为什么24GB这张卡在本地大模型圈子里被很多人视为“入门甜点”。

这套计算我现在基本口头就能完成,因为权重部分就是“参数量 × 精度系数”的乘法,KV Cache则取决于上下文长度。建议你第一次跑某个模型时,实际观察一轮生成前后的显存差值,把这个值记住,以后换模型时反复使用。

2.3 训练和微调场景:为什么显存需求完全不同

推理只是把数据往一个方向送,训练则要让数据反向传播更新参数,所以显存里的东西完全不是一个数量级。任何可训练参数,在训练过程中至少还有两份额外开销:

  • 梯度:和权重同量级,FP16下每个参数再占2字节,也就是每B参数多2GB
  • 优化器状态:以最常用的AdamW为例,它要为每个参数保存一阶动量、二阶动量和FP32精度的主权重。每B参数在这上面要花掉约12GB

这么算下来,一个7B模型即使只做全量微调,需要的显存也在几十GB以上。我见过有人拿着16GB显卡想做7B模型的全量微调,结果模型根本加载不进去。这就是为什么现在LoRA、QLoRA这类参数高效微调成为主流——它们冻结原始权重,只训练一个小得多的适配器(通常只有几千万甚至几百万参数),所以优化器状态和梯度总量从“几十GB级别”直接降到“几GB级别”,大幅缩减显存压力。

而涉及反向传播,激活值也不再是几百MB的水平。训练时为了计算梯度,每层前向传播的结果都要保留,长序列、大batch的训练下激活值甚至可以超过权重本身。如果你要微调,请一定把“梯度 + 优化器状态 + 激活值”这三块都算进去,而不是单纯套用推理公式。

3. 实操验证:主流显卡能跑哪些模型

理论计算只是纸上谈兵,我更建议你结合手里的显卡实际验证一轮。下面是我在常见的消费级显卡显存档位上看到的实际表现,配合实测经验供参考。

3.1 显存从8G到24G的定位

先摆出市场上最常见的几个显存档位,帮你建立整体概念:

显卡显存可流畅运行的典型配置运行体验
8GB7B模型的INT4/INT5量化版,短上下文能跑,但余量很小,长对话容易崩
12GB7B模型的INT8量化版,13B模型的INT4版日常够用,部署灵活
16GB7B模型的FP16原版,13B模型的INT4/INT8体验均衡,多数单卡方案的安全区
24GB13B模型的FP16,34B模型的INT4/INT8本地高质量推理的“甜点”容量
48GB(双卡)34B模型FP16,70B模型INT4可兼顾更多的量化余量

别只看显存容量,显卡的显存带宽和算力同样重要。同样24GB显存,带宽高的卡跑大模型每秒吞吐可以翻一倍以上。但如果只是判断“能不能跑”,显存是第一硬门槛,带宽更多影响的是快慢而非成败。

8GB和12GB的显卡在本地跑大模型时,通常绕不开量化。以我实测来看,8GB跑7B INT4,短对话没问题,但一旦把上下文拉到4000以上,或者开启联网搜索等长文字工具调用,OOM概率明显上升。12GB则宽松不少,7B INT8或者13B INT4都能稳住日常使用。

3.2 典型模型档位实测:7B、13B、34B、70B怎么选

以当前开源社区常见的参数档位,我用理论值和实测偏差一起讲。先说结论:很多人以为13B模型需要30GB显存,其实INT4下13B模型约6.5GB权重,加上KV Cache和其他开销后,12GB到16GB完全能跑。真正让13B“显得”难跑的是FP16精度,那需要大约26GB权重,单卡16GB就力不从心了。

  • 7B模型:FP16权重约14GB,建议16GB以上显卡原生跑。8GB到12GB则用INT4或INT8,能获得不错的生成质量。
  • 13B模型:FP16权重约26GB,消费级单卡只能用INT4或INT8。INT4下约6.5GB权重,12GB显存起步;INT8下约13GB权重,建议16GB以上。
  • 34B模型:FP16权重约68GB,即使INT4也要约17GB权重,实际运行超过20GB。想单卡流畅使用,24GB是及格线,再往下只能考虑部分层加载到内存,速度会明显下降。
  • 70B模型:FP16权重约140GB,单卡没有任何消费级产品能直接装下。INT4权重约35GB,配合KV Cache很容易突破40GB,通常情况下需要双24GB卡或者走CPU内存offload,跑起来挺慢,不过作为离线总结、代码补全类任务还是可用的。

实测占用通常比理论权重多出20%到30%。比如24GB显存跑34B INT4,理论权重17GB,加上KV Cache和缓冲后,实际占用可能达到22GB左右,仍然在24GB以内,只是余量不大了。很多人就是看到“文件大小17GB”就以为24GB卡随便跑,结果加载后还剩一大半显存被框架占着,自然会意外。

3.3 用nvidia-smi和代码监测真实占用

不要只靠理论,学会看实际占用会让你更踏实。最简单的方法是终端输入:

nvidia-smi -l 1

每秒刷新一次显卡状态。重点看两个数值:显存占用总量,以及当前运行的进程。跑模型时,这个数值会随着对话长度逐步上升——如果一直涨到接近物理显存上限,说明KV Cache是你的主要瓶颈。

如果跑的是Python推理脚本,还可以在代码里加几行,查看框架视角下的显存分配:

import torch # 查看当前GPU显存分配情况(已分配、预留) print(torch.cuda.memory_allocated() / 1024**3, "GB allocated") print(torch.cuda.memory_reserved() / 1024**3, "GB reserved")

allocated是实际占用张量的显存,reserved是PyTorch向显卡预留的缓存池,后者往往比前者大。如果你发现reserved很高,但allocated不高,那多半是PyTorch缓存策略导致,可以用torch.cuda.empty_cache()释放未使用的预留显存,不过这只是治标。更有效的方法是降低模型精度或减小batch,从源头砍需求。

实用小经验:实际部署模型时,我习惯把预估占用控制在显卡物理显存的85%以内,余量应对框架波动和碎片化。比如24GB显存,就尽量找总占用不超过20GB的配置,跑起来会稳定很多。

4. 模型选择的工程策略:卡着显存边界怎么办

当你算清楚自己的显存能装多大模型后,真正动手部署时还会面对更多选择。是用GGUF还是GPTQ?上下文该开到多长?用哪个推理框架最省心?这一节我把这些工程决策掰开讲,尤其是卡在显存边界时该怎么取舍。

4.1 量化档位选择:GGUF与GPTQ/AWQ的取舍

量化已经是本地部署绕不开的话题,但很多新手在GGUF、GPTQ、AWQ、bitsandbytes这一堆名词面前直接懵了。我按实际场景帮你分个类:

  • GGUF:原本为CPU推理设计,后来成了llama.cpp和Ollama生态的标准格式。优点是内存/显存混用支持好,显存不够时可以自动把部分层放到内存里,跑得慢但能跑;缺点是GPU推理效率略低,适合个人电脑、轻量部署。
  • GPTQ和AWQ:专为GPU推理设计的量化方案,精度保留好,推理速度快。它们依赖GPU把所有权重放显存,所以对显存要求更严格,适合服务端和需要高吞吐的场景。
  • bitsandbytes的4-bit量化:主要配合transformers库使用,加载方便,和微调生态结合好,但推理速度通常不如GPTQ/AWQ。

选型的逻辑很简单:显卡显存紧张、又不在意速度,优先GGUF;显卡显存足够、想追求生成速度,选GPTQ或AWQ;如果你需要同时做微调实验,那bitsandbytes路径最省事。

在量化位数的选择上,我的经验是:7B模型用INT4,比INT8快但质量差距很小;13B模型建议INT4或INT5;34B以上优先INT4。INT4对显存的释放幅度最大,而且是当下质量损失可控的甜点位。但别为了追求极限省显存去用2-bit或3-bit量化,为了省几GB牺牲模型能力,不划算。

4.2 上下文长度和批处理大小的精细控制

显存不够时,除了降低精度,还经常做两个降显存动作:缩短上下文长度、减小批大小。

  • 上下文长度直接影响KV Cache。以7B模型FP16为例,将上下文从4096拉到8192,KV Cache大约从2GB涨到4GB,显存占用立竿见影。如果你的任务只是问几个简短问题,完全没必要把上下文设置到模型支持的最大值,比如有些模型宣称支持128K上下文,实际消费级显卡根本喂不满。
  • 批大小在聊天场景默认就是1,不会成为问题。但如果你批量跑测评、离线大量处理文本,batch每翻一倍,KV Cache和激活值也翻一倍。显存紧张时,坚持batch=1,用并发进程代替批量能稳压住占用。

好用的中间人策略是vLLM这类服务框架。它有一个叫gpu_memory_utilization的参数,默认0.9,意思是允许使用90%的GPU显存作为KV Cache池。你可以把它调低到0.6到0.7,给其他任务留出空间。如果你只是本地聊天,Ollama默认处理也很省心,不需要手动调这些参数。

注意:不要只看模型宣称的最大上下文。实际生成中,只要序列还在变长,KV Cache就还在涨。长文生成、多轮对话、工具调用这类场景,上下文消耗比想象中快得多,务必留出至少10%到15%的显存余量。

4.3 推理框架的取舍:transformers、vLLM、llama.cpp各适合谁

同一个模型,不同框架跑出来的显存占用差距能有30%以上。我按使用场景推荐:

  • 如果你熟悉Python,想快速实验、加载模型、调用Hugging Face生态,用transformers + bitsandbytes最顺手。它对显存没有做极致优化,但胜在灵活,改一行参数就能切换量化。
  • 如果你只是本地聊天使用,而且用的是Windows或Mac环境,Ollama(底层基于llama.cpp)会极其省心。一条命令就能运行GGUF模型,自动管理显存和内存,还会把KV Cache控制在可承受范围。
  • 如果你要部署成服务,同时很多人访问,vLLM是最合适的选择。它用PagedAttention技术把KV Cache切成小块,按需分配,吞吐量极高,而且支持连续批处理,能明显降低高并发下的显存浪费。

我的建议是:个人玩耍直接Ollama,做开发或测试用transformers,做成API服务再考虑vLLM。不要一上来就卷框架,框架的差异不会改变“模型权重占多少显存”这个物理事实,只会影响你能多挤出多少余量给上下文和批处理。

5. 常见问题与OOM排查实录

即便算得再清楚,实际运行中还是会碰到各种意外。我把这些年踩过的坑,以及从报错日志里定位问题的方法整理成下面的速查表,希望你在OOM时能少走弯路。

现象最可能原因解决思路
模型加载时直接OOM加载瞬间存在峰值占用(权重先以更高精度载入)换更高的量化档位,或设置low_cpu_mem_usage=True、device_map="auto"
生成一段时间后OOMKV Cache随上下文增长撑爆显存限制max_new_tokens或max_length,缩小上下文,降低量化位数
显存明明够却一直报碎片错误PyTorch缓存分配导致碎片化调整batch大小、重启内核,或使用torch.cuda.empty_cache()清理
多个任务同时跑时OOM多个进程各自分配独立显存串行执行任务,或用服务框架统一管理显存
34B以上模型在24GB卡上很卡模型部分层被offload到内存,速度受内存带宽拖累优先选择INT4或更小上下文;多卡用户用张量并行分发
跑INT4量化模型比预期占显存多量化存储不代表运行时无额外开销,KV Cache等仍占显存按权重×1.3加KV Cache重新估算

5.1 生成到一半显存爆掉

这是我见过最多的情况。模型加载没问题,对话也正常,结果聊到第30轮时“CUDA out of memory”突然冒出来。原因就是KV Cache一直在累积。如果显存总容量是8GB,模型权重占了4GB,最开始KV Cache可能只有0.5GB,但随着对话深入悄悄涨到2GB、3GB,最后撞到墙。

排查方法很简单:报错信息里会有allocated和reserved两个数字,如果你发现allocated接近物理显存上限,说明是实打实的KV Cache压力;如果你发现reserved远大于allocated,说明是PyTorch缓存没释放干净。前者要从模型和上下文入手,后者可以清理缓存或换框架。

我自己写了一个简单的估算习惯:把“期望最大上下文长度 × 每token KV Cache大小”当作不可省略预算,一开始就把整轮生成长度预设好。宁可一开始就把显存空间留足,也不要让对话走到一半才发现不够。

5.2 模型加载瞬间OOM

另一个高频场景是:明明按照理论计算,显存应该刚好够,结果from_pretrained一执行就炸了。这是因为很多框架在加载模型时,会先在显存或内存里创建一份未量化的完整权重,再转换成你指定的低精度格式。在这个转换瞬间,显存峰值可能达到目标权重的两倍甚至更多。

解决办法是让加载过程更保守一些。以transformers为例,以下设置能明显缓解加载峰值:

from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained( "模型名称或路径", device_map="auto", load_in_4bit=True, low_cpu_mem_usage=True )

low_cpu_mem_usage=True能让模型不在CPU端先创建完整权重副本,直接从磁盘加载为量化状态。device_map="auto"会自动把模型按显存剩余量分配到GPU和CPU。这个方法在显存只剩几个GB时特别有效。

5.3 显存碎片化与隐性占用

很多老手也会被碎片化玩一把。PyTorch的内存分配策略是为了加速张量分配,会预先把显存划分成很多块。当你反复创建和释放张量后,显存虽然总量充足,但找不到连续的大块,就会报OOM。这种情况下重启推理进程往往最有效,因为一切从头开始。

隐性占用则更阴险。比如你之前跑过Python脚本但没有正常退出,GPU进程还残留着;比如你一边开着本地模型服务,一边又在同一张卡上做微调;再比如某些监控软件、IDE内置AI插件,都会悄悄在GPU上分配显存。每次OOM前,先跑一次nvidia-smi看当前到底有哪些进程占着显存,十次里能解决八次“灵异事件”。

最后分享一个我长期沿用的清单:跑新模型之前先查三件事——模型文件是哪种量化格式、框架创建了多少预留显存、是否还有其他进程在抢占GPU。确认完这三件事,再安安心心让模型飞一会儿,而不是打开IDE点个Run就去做别的事。

我个人实际测试下来,最心疼的一次是拿着16GB显存去跑一个13B模型的FP16版本,理论权重26GB,理所当然跑不动。后来换成INT4量化,同样的模型在同样显卡上流畅跑完,生成质量差距也没想象中的大。这件事给我最大的启发是:模型选择不是“买更大的卡”一条路,把显存账算清楚,把量化档位选对,同等硬件下可选的模型范围能大出好几倍。

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

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

立即咨询