大模型推理显存计算指南:从显存反推模型规模与量化选型
1. 为什么显存是模型部署的第一道门槛很多刚接触大模型推理的朋友第一反应往往是盯着显卡的算力参数看——多少TFLOPS、多少CUDA核心、Tensor Core代数。但真正上手跑过几个模型之后就会发现决定你能不能跑起来、能跑多大的从来不是算力而是显存。算力决定的是跑得多快显存决定的是能不能跑。这个顺序不能搞反。我自己踩过的第一个坑就是拿一张8GB显存的卡去加载一个13B参数的模型结果进程直接OOMOut Of Memory退出连报错都来不及看。后来才明白模型加载进显存这件事本质上是一道算术题参数量乘以每个参数占用的字节数再加上推理过程中的额外开销。这道题算不清楚选卡、选模型、选量化方案全都是盲猜。这篇文章想做的事情很直接把显存怎么算这件事讲透然后给出一个从显存反推模型规模的实用方法。不管你是手里只有一张消费级显卡想跑个本地模型玩玩还是在做部署方案需要评估硬件成本这套计算逻辑都用得上。我会尽量把每一步的推导过程写清楚让你看完之后能自己拿计算器算而不是死记某个结论。需要提前说明的是下面所有的计算都基于推理场景训练场景的显存需求要复杂得多涉及优化器状态、梯度、激活值等那是另一个话题。推理场景相对干净适合作为理解显存计算的起点。2. 显存到底被谁吃掉了2.1 模型权重的显存占用模型权重是显存占用的绝对大头。一个模型有多少参数每个参数用什么精度存储直接决定了权重的显存占用。计算方式非常朴素权重显存 参数量 × 每个参数的字节数不同精度下每个参数的字节数如下表精度类型每参数字节数说明FP324 bytes全精度推理很少用FP16 / BF162 bytes半精度推理主流INT81 byte8位量化INT40.5 byte4位量化当前本地部署热门拿一个7B70亿参数模型举例。FP16精度下权重占用是 7 × 10^9 × 2 bytes 14 GB。这就是为什么一张8GB的卡跑不动FP16的7B模型——光权重就14GB还没算别的开销。如果换成INT4量化权重占用变成 7 × 10^9 × 0.5 bytes 3.5 GB。这一下子就进了8GB卡的射程范围。量化之所以是本地部署的救命稻草核心原因就在这里。这里有个容易混淆的点很多人把参数量和显存占用直接划等号觉得7B模型就是7GB。这个直觉只在INT8精度下近似成立7B × 1 byte 7GB其他精度下都不对。记住那个乘法公式比记结论靠谱。2.2 KV Cache被忽视的显存杀手如果说权重是明面上的开销那KV Cache就是暗地里的刺客。很多人算完权重觉得哎还剩不少显存结果一跑长文本就爆了问题基本都出在KV Cache上。KV Cache是什么简单说Transformer在生成每个新token的时候需要用到之前所有token的Key和Value向量。为了避免重复计算这些向量会被缓存下来这就是KV Cache。上下文越长、并发越高KV Cache占用越大。它的计算公式稍微复杂一点KV Cache显存 2 × 层数 × 注意力头数 × 头维度 × 序列长度 × 批次大小 × 每参数字节数其中前面的2是因为要存Key和Value两份。对于很多模型来说层数 × 注意力头数 × 头维度这个乘积近似等于模型的隐藏层维度乘以层数可以简化理解。我用一个具体例子说明。假设某个7B模型有32层隐藏维度4096FP16精度那么每个token的KV Cache占用大约是2 × 32 × 4096 × 2 bytes 512 KB/token看起来不多但如果你要处理一个8192 token的上下文512 KB × 8192 4 GB这4GB是纯额外开销叠加在权重之上。如果并发4个请求直接变成16GB。这就是为什么长上下文场景对显存的要求会陡增。提示KV Cache的优化是当前推理框架的重点方向。分页注意力、KV Cache量化、多头潜在注意力等技术本质上都是在压缩这块开销。选推理框架时这些特性值得重点关注。2.3 框架与运行时开销除了权重和KV Cache还有一部分显存被推理框架本身占用。CUDA上下文、cuDNN句柄、框架的中间缓冲区、临时张量等等加起来通常是几百MB到1GB多不等。这部分开销很难精确计算因为它跟框架实现、驱动版本、是否开启某些优化都有关。经验值是留出1到2GB的余量给运行时开销比较稳妥。如果你用的是比较重的框架或者开启了图优化、CUDA Graph之类的特性余量还要再留大一点。2.4 显存占用总账把上面三部分加起来就是推理时的显存总需求总显存 权重显存 KV Cache显存 运行时开销这个公式看起来简单但每一项都有坑。权重显存取决于量化方案KV Cache取决于上下文长度和并发数运行时开销取决于框架。任何一项估算失误都会导致OOM。下一节我会用一个完整的案例把这三项都算一遍。3. 从显存反推模型规模一套可复用的计算方法3.1 先确定你的可用显存第一步不是算模型而是搞清楚你手里到底有多少可用显存。这里有个关键区别显卡标称显存 ≠ 可用显存。一张标称8GB的卡实际可用显存通常在7.2到7.6GB之间因为系统、驱动、显示输出会占用一部分。如果是笔记本的独显还要考虑是否开启了混合输出模式那会进一步压缩可用显存。我的建议是按标称显存的90%来估算可用显存。8GB的卡按7.2GB算12GB的卡按10.8GB算24GB的卡按21.6GB算。这个保守估计能帮你避开很多理论能跑实际跑不动的尴尬。如果你用的是多卡显存不是简单相加的。模型并行、张量并行能不能用、效率如何取决于框架支持和模型结构。多卡显存叠加这件事实际损耗可能相当大不能想当然。3.2 反推公式的建立现在我们把公式反过来用。已知可用显存求能跑多大的模型。假设可用显存为 MGB运行时开销预留 RGB通常取1.5KV Cache预留 KGB取决于你的上下文需求量化精度为 Qbytes/参数那么可用于权重的显存是 M - R - K能承载的参数量为最大参数量 (M - R - K) × 10^9 / Q这个公式是估算的核心。我把它拆成几个变量来看会更清楚每个因素怎么影响结果。量化精度的影响最大。从FP16换到INT4同样的显存能承载的参数量直接翻4倍。这就是为什么量化是本地部署的必选项。KV Cache预留取决于使用场景。如果你只做短文本对话比如512 token上下文KV Cache预留可以很小几百MB就够。但如果你要处理长文档、做RAG检索增强上下文动辄几千上万tokenKV Cache预留就得按GB级别来算。运行时开销相对固定但不同框架差异不小。轻量级框架可能只要几百MB重量级框架可能要1.5GB以上。3.3 一个完整的计算案例我用一个具体场景把整套计算走一遍。场景设定一张12GB显存的显卡想跑一个对话模型上下文长度2048 token单并发用INT4量化。第一步确定可用显存。12GB × 90% 10.8GB。第二步预留运行时开销。取1.5GB。剩余 10.8 - 1.5 9.3GB。第三步估算KV Cache。假设模型32层隐藏维度4096INT4量化下KV Cache也可以量化但为保守起见按FP16算。每token约512KB2048 token约1GB。剩余 9.3 - 1 8.3GB。第四步反推参数量。INT4精度下每参数0.5 byte最大参数量 8.3 × 10^9 / 0.5 166亿参数。所以这张12GB的卡在INT4量化、2048上下文、单并发的条件下理论上能跑一个13B到14B的模型还有一定余量。如果换成7B模型余量就很充裕可以支持更长的上下文或更高的并发。这个计算过程你可以直接套用。把你自己显卡的显存、你想要的上下文长度、你打算用的量化精度代进去就能得到一个大致的参数量上限。3.4 不同显存档位的参考区间为了让你有个直观感受我整理了一张常见显存档位在不同量化精度下能跑的模型规模参考表。这张表基于单并发、2048上下文、预留1.5GB运行时开销的假设。显存FP16INT8INT48GB3B6B13B12GB5B10B20B16GB7B13B27B24GB11B22B45B48GB23B46B90B这张表是估算不是精确值。实际能跑多大还要看模型的具体结构层数、注意力机制、框架效率、上下文长度。把它当作选型的第一道筛选而不是最终结论。注意表里的数字是能加载并跑起来的上限不代表跑得流畅。如果显存占用逼近上限推理速度会明显下降因为可用显存不足会导致频繁的显存交换。实际选型时建议留出20%以上的余量。4. 量化方案怎么选精度、速度与显存的三角权衡4.1 量化不是免费的午餐量化能大幅降低显存占用但代价是精度损失。这个损失有多大取决于量化方法和模型本身。有些模型对量化很敏感INT4之后输出质量断崖式下跌有些模型则相当鲁棒INT4和FP16的差距肉眼难辨。量化损失主要体现在两个方面一是困惑度上升模型对语言的建模能力下降二是特定任务上的表现退化比如代码生成、数学推理这类对精度敏感的任务量化损失会更明显。所以选量化方案不能只看显存省了多少还要看你的任务对精度有多敏感。做创意写作、日常对话INT4通常够用做代码补全、逻辑推理可能就得考虑INT8甚至FP16。4.2 主流量化方案对比当前常见的量化方案有这么几类我按显存节省程度和精度损失排个序方案精度显存节省适用场景FP16/BF16最高基准精度敏感任务显存充足INT8高约50%平衡之选多数场景可用INT4GPTQ中约75%本地部署主流通用场景INT4AWQ中高约75%对精度要求稍高的INT4场景更低比特低更高实验性质生产慎用GPTQ和AWQ是当前INT4量化的两个主流方向。GPTQ出现较早生态成熟支持的模型多AWQ在部分模型上精度表现更好但支持范围相对窄一些。选哪个主要看你用的模型有没有对应的量化版本。4.3 量化方案选择的实操建议我的经验是按这个顺序决策先看显存够不够跑FP16。如果够优先FP16省心。不够就上INT8。INT8的精度损失通常很小是性价比很高的选择。INT8还不够再考虑INT4。INT4能让你在有限显存下跑更大的模型但要做好精度可能下降的心理准备。INT4还跑不动要么换更小的模型要么加显存。不要硬上更低比特的量化收益递减且风险高。还有一个容易被忽略的点量化版本和原始模型的匹配。用别人量化好的版本要注意量化时用的校准数据集是否和你的任务领域接近。如果校准集和实际使用场景差异大量化损失可能会超出预期。5. 实操一步步算出你的显卡能跑什么5.1 准备工作摸清硬件底细在开始计算之前先把硬件信息摸清楚。不同系统下查看显存的方式不一样。Linux下用nvidia-smi命令nvidia-smi --query-gpuname,memory.total,memory.used,memory.free --formatcsv这条命令会列出显卡型号、总显存、已用显存、空闲显存。重点看空闲显存那才是你能用的。Windows下可以直接在任务管理器的性能标签页看或者用同样的nvidia-smi如果装了CUDA工具包。macOS的Apple Silicon芯片是统一内存架构显存和内存共享查看方式不同用system_profiler SPDisplaysDataType或者活动监视器。摸清硬件之后记下三个数总显存、当前空闲显存、你打算留出的安全余量。5.2 计算流程的代码化手动算容易出错我习惯写个小脚本把计算过程固化下来。下面这段Python代码实现了前面讲的整套计算逻辑def estimate_max_params(available_vram_gb, quant_bytes, context_len, num_layers32, hidden_dim4096, runtime_overhead_gb1.5, kv_dtype_bytes2): 估算给定显存下能承载的最大参数量单位十亿 available_vram_gb: 可用显存GB quant_bytes: 每参数字节数FP162, INT81, INT40.5 context_len: 上下文长度token数 num_layers: 模型层数 hidden_dim: 隐藏维度 runtime_overhead_gb: 运行时开销预留GB kv_dtype_bytes: KV Cache精度字节数 # KV Cache估算2 * 层数 * 隐藏维度 * 序列长度 * 字节数 kv_cache_bytes 2 * num_layers * hidden_dim * context_len * kv_dtype_bytes kv_cache_gb kv_cache_bytes / (1024 ** 3) # 可用于权重的显存 weight_vram_gb available_vram_gb - runtime_overhead_gb - kv_cache_gb if weight_vram_gb 0: return 0, kv_cache_gb # 反推参数量 max_params weight_vram_gb * (1024 ** 3) / quant_bytes max_params_billion max_params / 1e9 return max_params_billion, kv_cache_gb # 示例12GB卡INT4量化2048上下文 max_params, kv_gb estimate_max_params( available_vram_gb10.8, quant_bytes0.5, context_len2048 ) print(f最大参数量: {max_params:.1f}B) print(fKV Cache占用: {kv_gb:.2f}GB)这段代码可以直接改参数用。把available_vram_gb换成你的实际可用显存quant_bytes换成你打算用的量化精度context_len换成你的目标上下文长度就能得到估算结果。提示代码里的num_layers和hidden_dim是默认值不同模型差异很大。如果你知道目标模型的具体结构把这两个值换成真实的估算会更准。不知道的话用默认值也能得到量级正确的参考。5.3 实测验证别只信计算计算是纸面上的实测才是硬道理。算出结果之后一定要实际加载模型跑一下看看真实显存占用。加载模型后用nvidia-smi观察显存变化# 加载模型前 nvidia-smi --query-gpumemory.used --formatcsv # 加载模型并跑一次推理后 nvidia-smi --query-gpumemory.used --formatcsv两次的差值就是模型的实际显存占用。把这个实测值和你的计算值对比如果差异大说明你的估算参数需要调整。我自己的经验是实测值通常比计算值高10%到20%因为计算时容易漏掉一些临时缓冲区和框架开销。所以计算时留余量很重要别把显存算得刚刚好。5.4 显存不够时的应对策略如果算下来发现显存不够有这么几条路可以走按推荐顺序排列第一换更小的模型。这是最直接的办法。7B跑不动就跑3B13B跑不动就跑7B。模型规模降下来显存需求线性下降。第二提高量化程度。FP16换INT8INT8换INT4每次切换显存需求减半。但要注意精度损失。第三缩短上下文长度。如果KV Cache是大头把上下文从8192降到2048KV Cache直接降到四分之一。第四降低并发数。并发数直接乘在KV Cache上单并发改双并发KV Cache翻倍。反过来降低并发能省不少显存。第五用CPU卸载。把部分层放到内存里需要时再加载。这会大幅降低速度但能让原本跑不动的模型跑起来。属于能跑就行的兜底方案。第六加显存。换卡或者加卡。这是最贵但最彻底的办法。这几条路可以组合使用。比如换个更小的模型同时上INT4量化再缩短上下文显存需求能降一个数量级。6. 常见问题与排查实录6.1 为什么算下来够实际却OOM这是最常见的问题。计算值显示显存够用实际加载却爆了。原因通常有这几个KV Cache估算偏小。很多人算KV Cache时只按单并发、短上下文算实际跑起来上下文一长、并发一高KV Cache就膨胀了。排查方法加载模型后先跑一个长文本观察显存峰值。运行时开销预留不足。框架的临时缓冲区、CUDA Graph、图优化都会额外吃显存。排查方法把运行时开销预留从1.5GB提到2GB甚至2.5GB再算一遍。显存碎片。反复加载卸载模型会导致显存碎片可用显存看起来够但没有连续的大块。排查方法重启进程重新加载。量化版本和框架不匹配。某些量化格式需要特定框架支持用错了框架会额外占用显存做转换。排查方法确认量化格式和框架的兼容性。6.2 显存占用忽高忽低正常吗正常。推理过程中显存占用是动态变化的。生成每个token时KV Cache在增长处理不同长度的输入时中间张量大小在变。只要峰值不超上限波动是正常的。但如果波动幅度特别大比如从50%跳到95%那就要注意了。可能是某些操作触发了显存重分配或者框架在做显存池的整理。这种情况建议用框架提供的显存监控工具看看峰值出现在哪个环节。6.3 多卡能不能简单叠加显存不能。多卡显存叠加需要模型并行或张量并行支持而且有通信开销。两张12GB的卡不等于24GB可用显存。实际能用的显存取决于并行策略的效率可能只有18GB到20GB的有效容量。而且不是所有模型都支持多卡推理。有些模型结构对并行不友好强行多卡可能效率极低甚至跑不起来。多卡之前先确认框架和模型是否支持。6.4 常见问题速查表现象可能原因排查方向加载即OOM权重超显存检查量化精度和参数量跑长文本OOMKV Cache超预期缩短上下文或降低并发显存占用缓慢增长KV Cache累积检查是否有缓存未释放显存峰值远超计算值运行时开销大增加预留换轻量框架多卡效率低并行策略不当检查并行配置和通信开销量化后质量下降明显量化损失大换量化方案或提高精度6.5 几个容易踩的坑坑一只看总显存不看空闲显存。系统、驱动、其他进程都在占显存标称8GB实际空闲可能只有6GB多。永远按空闲显存算。坑二忽略KV Cache的并发放大。单并发算下来够双并发就爆。并发数要乘进KV Cache。坑三量化精度和框架不匹配。用了某个量化格式但框架不支持或支持不好导致额外开销。选量化方案前先确认框架兼容性。坑四显存算得刚刚好。没有留余量跑起来稍微一波动就OOM。至少留20%余量。坑五忽视模型结构差异。同样是7B不同模型的层数、注意力机制不同显存占用能差不少。用具体模型的结构参数算别用通用值。7. 几个实操中的经验之谈显存计算这件事算得多了会有一些直觉。我分享几个自己总结的经验点可能不在标准教程里但实际用起来很有帮助。第一把能跑和跑得好分开看。显存刚好够加载模型和显存充裕能流畅推理是两回事。前者只是不OOM后者才有实用价值。选型时按跑得好的标准留余量别按能跑的标准卡线。第二上下文长度对显存的影响是非线性的。短上下文时KV Cache占比小长上下文时KV Cache可能超过权重成为大头。做长文本应用时KV Cache要单独重点估算。第三量化方案的精度损失要在自己的任务上验证。别人说某个量化方案好那是别人的任务。你的任务对精度敏感不敏感只有自己测了才知道。准备一个小的评测集量化前后各跑一遍对比。第四显存监控要常态化。别等OOM了才去看显存。部署之后持续监控显存占用能提前发现泄漏、峰值异常等问题。很多框架都提供了显存监控接口接上监控系统就行。第五硬件选型时显存优先于算力。同样的预算宁可要显存大的卡不要算力高但显存小的卡。算力不够可以等显存不够是真跑不起来。这个优先级在模型规模快速增长的当下尤其重要。第六留一手降级方案。部署时准备好一个更小、量化程度更高的备用模型。主模型跑不动或者显存紧张时能快速切换到备用模型保证服务不中断。这套显存计算的方法我从一开始的瞎猜到后来能比较准地估算中间踩了不少坑。核心就是把权重、KV Cache、运行时开销这三块分开算清楚然后留足余量。算得多了看到显存数字和模型规模心里大概就有数了。希望这些内容能帮你少走点弯路把有限的显存用在刀刃上。