
前阵子有个朋友拿一个开源70B模型来问我他手里是一张24GB显存的卡想知道能不能直接跑起来。我帮他把权重、KV Cache、激活值这几本账列了一遍他才发现“模型参数有70B”和“把这70B跑起来”之间隔着的显存账目复杂得多。类似的对话我碰过很多次大模型内存与显存的匹配问题几乎是每个刚开始做大模型应用的人都会撞上的第一道坎。很多人以为只要显存不小于模型文件大小就行但模型文件只是权重的压缩存档真正跑起来之后显存里同时还要放推理中间状态、上下文缓存、框架临时缓冲区训练场景还要再加梯度和优化器状态。这篇文章会把每一笔开销拆开讲清楚它们各自怎么估算再落到显卡选型时的实际匹配逻辑。无论你是做本地部署、做产品原型还是正在规划GPU采购这套方法都可以直接套用。1. 先搞明白模型到底把显存花在了哪里1.1 显存和内存为什么总有人搞混内存是CPU用的DRAM显存是GPU用的VRAM两者在物理上分离访问路径也不同。GPU计算时只能直接访问显存如果显存不够就得把部分数据放到内存中等需要时再通过总线搬回显存。这个搬运过程非常慢比直接在显存里读取慢一个数量级都不止。用一个生活类比显存是工位上的桌面内存是大楼的仓库。桌面放得下资料你干起活来顺手桌面放不下你就得一趟趟跑去仓库取材料时间全耗在路上。我见过不少团队给服务器配了128GB甚至256GB内存以为跑大模型没问题结果一跑起来特别慢打开监控一看显存早就满了模型权重一直在CPU内存和GPU显存之间来回折腾。这就是典型的把内存和显存混在一起算导致的翻车。所以做部署规划时显存和内存要分开看内存负责CPU侧的原始数据、分片文件、offload缓存显存才是模型真正干活的地方。两者之间不能互相替代只能搭配使用。1.2 四类显存消耗大户权重、激活值、KV cache、优化器消耗来源出现场景量级特点模型权重推理、训练与参数量直接相关常驻显存激活值与中间张量推理、训练随batch、序列长度、模型层数增长KV Cache增量推理随上下文长度和并发数增长推理时的大头梯度与优化器状态训练、微调全参数训练时常为权重的2~4倍框架运行时、临时缓冲推理、训练多卡通信、算子执行时动态波动前四项是显存规划的主线最后一项虽然波动较小但多卡并行时不能让出太多。很多人只盯着模型权重忽略推理时的KV Cache和训练时的优化器状态才会出现“权重明明放得下一跑就爆显存”的情况。模型权重最容易理解它是神经网络里所有矩阵乘法的参数模型加载后常驻显存。激活值则是每一层前向计算产生的中间结果推理时用完可释放训练时因为反向传播需要复用往往要保存更多。KV Cache只在增量推理场景出现作用是缓存历史token的Key和Value避免每次生成新token都从头计算一遍。梯度与优化器状态则属于训练专属Adam这类优化器会为每个参数保存两份额外的状态开销相当可观。弄清楚这四类来源后续所有估算就都有了依据。2. 如何快速估算一个大模型的显存需求量2.1 5秒钟算清权重显存参数量乘以单参数字节数权重显存是最好算的一笔账。只需要知道两个数参数量和每个参数所占用的字节数。主流数据精度下单参数占用大致是FP324字节BF16 / FP162字节INT81字节INT40.5字节计算公式是权重显存 参数量 × 单参数字节数 ÷ 1024³模型参数量FP16 / BF16INT8INT41B2GB1GB0.5GB7B14GB7GB3.5GB13B26GB13GB6.5GB70B140GB70GB35GB这里我习惯用1024进制计算GiB而很多显卡厂商标称显存时用的是1000进制所以标称64GB的卡实际可用不到64GiB。这也是选卡时不能卡着最低线买的原因之一。权重显存只是起步真正的峰值显存要叠加下面几项。2.2 KV Cache推理时最容易被低估的一笔开销Transformer做自回归生成时每生成一个新token都要拿它的查询向量去和前面所有历史token的Key、Value做注意力计算。如果不做缓存每生成一个token就要重新处理一遍全部历史计算复杂度高得吓人。所以推理框架会把每个历史token的Key和Value缓存下来这就是KV Cache。KV Cache的占用和上下文长度直接挂钩计算公式可以简化为KV Cache ≈ 2 × 层数 × KV头数 × 每头维度 × 上下文长度 × batch × 单元素字节数这个公式里特别要注意“KV头数”。不同模型的注意力头设计差别很大有的模型查询头数和KV头数一样多有的模型用了分组查询注意力KV头数远小于查询头数。举个例子一个80层的70B模型如果KV头数是8、每头维度128在8K上下文、单并发、FP16条件下KV Cache约为2.5GiB。但如果KV头数是64同样的条件下直接跳到20GiB左右。这还只是单并发如果同时服务8路请求KV Cache会线性增长到20GiB甚至160GiB。所以推理场景下KV Cache必须跟着并发度和上下文长度一起估算。很多人只按权重显存选卡上线后一压测就OOM往往就是漏算了这一笔。2.3 训练阶段优化器状态和梯度把显存需求抬高了3到4倍推理只关心权重、KV Cache、激活值训练还要多出两笔大开销梯度和优化器状态。使用Adam优化器时每个参数需要保存一阶动量、二阶动量而且通常以FP32形式存储。再加上混合精度训练下还有FP16权重副本和FP32权重主副本业界常用一个经验值每个参数大约16字节。按这个估算全参数训练7B模型单是权重、梯度、优化器状态就要112GB左右70B模型直接超过1TB。这就是为什么全参数训练大模型必须上多卡并行单卡几乎不可能装下。LoRA这类参数高效微调方法之所以流行就是因为它只训练新注入的一小部分参数优化器状态少得多显存需求能压到接近推理的级别。但训练时激活值仍然需要保留batch一大同样吃显存所以还需要配合梯度检查点、减小batch等手段。选卡之前先分清是推理还是训练因为两者要求的显存数量级完全不同。2.4 用一个70B模型带你走完整套估算流程把前面几笔账合到一起看一个FP16权重70B模型的完整估算权重140GiB。KV Cache8K上下文下GQA结构的典型模型约2.5GiBMHA结构约20GiB。激活值单并发、短序列时可能只需几GB长序列、大batch时能到几十GB。加上运行时缓冲和15%安全余量总峰值通常在160GiB到200GiB之间。结论很直接推理70B FP16权重单张80GiB显存都紧张多数情况需要两张80GiB卡做张量并行。如果改成INT4量化权重降到35GiB左右一张48GiB的卡就能比较从容地全显存加载24GiB的卡配合少量CPU offload也能跑只是速度会慢不少。如果目标是训练70B全参数微调的目标显存超过1TB普通团队不要硬上。更现实的路线是先量化到INT8甚至INT4再只做LoRA微调这样几十GB显存级别的单卡或者双卡方案就可行了。3. 模型与显卡组合匹配的核心策略3.1 量化选型INT8还是INT4省下显存换精度量化是把权重从高精度压到低精度直接改变显存账本。70B模型在FP16下要140GBINT8降到70GBINT4进一步降到35GB。显存压力缓解后很多原本需要双卡的场景单卡就能跑这是大模型本地部署能普及的关键。但量化不是白拿的。INT8在很多任务上精度损失比较小INT4则更激进对数学推理、代码生成这类对数值敏感的任务风险更高。我的习惯是拿到一个模型后先把FP16基线、INT8、INT4三个版本的输出放到同一组评测题上对比如果INT4得分下降在可接受范围内就选INT4否则退回INT8。还有一个容易踩的坑低bit量化在显存和带宽层面试算力带宽可以省但有些GPU对低bit矩阵运算的加速并不明显甚至可能因为反量化开销导致实际速度比FP16还慢。所以量化选型一定要看实际benchmark不能只看显存数字。3.2 单卡装不下时CPU offload、张量并行、流水线并行的取舍显存放不下大模型主要有四条路可以走。CPU offload是把部分权重放到内存GPU需要哪一层再把哪一层搬到显存。优点是显存需求能压到极低缺点是速度损失很大。我曾在一张24GB显存的卡上跑INT4量化的70B模型输出速度只有每秒几个token离线批处理还能接受在线服务完全不行。张量并行是把同一个矩阵切成多块放在多张卡上计算和显存都被摊开。这种方案对卡间互联带宽要求高如果多卡之间只是普通PCIe连接切分太细反而会被通信拖慢。流水线并行则是按层把模型切成几段卡和卡之间传递的是中间激活值通信量相对小但容易出现前一卡算完、后一卡还在忙的空档整体利用率不高。训练场景还有一种常用手段叫做分片优化器状态把优化器状态分散到多张卡上单卡峰值显存能显著降低。实际选择时我的优先级很明确先量化再单卡然后张量并行最后才考虑offload。多卡不是越多越好切分粒度太细会让通信成本吃掉算力收益。3.3 一张决策流程从需求倒推显卡配置选卡不能先看价格再看参数而是要从需求倒推。常见显存容量参考适配场景8GB~12GB7B模型INT4短上下文推理3B~7B FP16推理16GB7B FP16短上下文、13B INT4、部分LoRA微调24GB7B~13B FP16推理、70B INT4配合offload、LoRA微调48GB70B INT4全显存推理、13B全参数小batch微调80GB及以上70B FP16推理、大batch推理、小模型全参训练多卡组合更大模型训练、高并发在线服务具体决策流程可以这样走明确任务类型推理还是训练在线服务还是离线批处理。确定模型规模和量化级别算出权重占用的显存。估算KV Cache考虑上下文长度、并发请求数。估算激活值batch和序列长度越大激活值越贵。把权重、KV Cache、激活值相加再乘1.2到1.3的余量系数。先看单卡能不能放下不行就先量化再考虑多卡和offload。最后才根据预算和扩展性确定具体型号。这套流程看起来复杂但熟练之后只需要几分钟就能在脑子里完成。关键在于不要跳过任何一步。4. 我的实测经验按这套方法踩坑最少4.1 手写一个显存预算脚本以后不懵每次换模型、换显卡都要重算一遍太麻烦我干脆写了一个小脚本做快速估算。代码逻辑很简单重点是权重和KV Cache两本账。def estimate_inference_gb(num_params, weight_bytes, layers, kv_heads, head_dim, seq_len, batch1, extra_ratio0.15): # 权重显存 weight_gb num_params * weight_bytes / (1024 ** 3) # KV Cache显存 kv_gb 2 * layers * kv_heads * head_dim * seq_len * batch * weight_bytes / (1024 ** 3) # 总显存权重KV Cache再乘一个安全余量 total_gb (weight_gb kv_gb) * (1 extra_ratio) return weight_gb, kv_gb, total_gb以7B模型、FP16、80层、8个KV头、每头128维、8K上下文、单并发为例脚本会给出权重14GBKV Cache约2.5GB总计约18.9GB24GB的卡可以跑但余量并不多。如果上下文长度翻倍到16KKV Cache变成5GB总计约21.9GB24GB的卡就开始危险了。这个脚本没有把激活值算得很细所以我给total_gb加了一个15%的安全比例兜底。真上线之前还是要把监控打开看一次真实峰值再回来校准这个比例。4.2 为什么显存“看着够”却还是OOM估算结果和显存容量明明匹配一跑起来还是爆显存通常不是估算公式错了而是下面三个原因。第一是显存碎片化。深度框架在推理过程中会频繁申请和释放临时张量显存里留下大量小空洞。表面上看剩余显存还有几个GB但最大连续空闲块不够大一次大段分配就失败了。最直接的办法是重启进程或者切换支持显存池、预分配的推理框架减少动态碎片。第二是KV Cache的动态增长。KV Cache不是静态的模型每生成一个token都会让它变大。如果输入token加输出token超过了预设的最大长度后段就会突然OOM。解决思路是给生成长度设上限或者在部署配置里预留最大上下文长度的完整KV Cache预算。第三是多进程重复加载。用多个进程并发跑同一个模型时每个进程都会独立加载一份权重显存占用成倍上涨。有些环境支持显存共享可以让多个进程共用同一份模型权重如果不能就要适度减少进程数给每个进程留足独立空间。4.3 高频报错排查速查表现象可能原因快速排查思路加载权重阶段OOM权重本身超出显存改用INT4或INT8打开offload跑几个请求后OOMKV Cache随上下文增长限制最大生成长度降低并发量化KV Cache单卡能跑多卡反而更慢通信开销过高、切分粒度过细增大每卡batch减少并行度检查卡间带宽量化后回答质量明显下降低bit精度损失较大对比基准测试退回INT8或混合精度训练时显存突然暴涨激活值积压batch过大开梯度检查点降低batch使用优化器状态分片这张表是我在多次项目里不断补出来的每一条都对应着一次真实的踩坑记录。遇到问题先别急着换显卡按表格里的思路逐项排查很多时候调一下参数就能解决。踩过几次坑之后我现在选卡前一定会先列三个数字权重大小、KV Cache峰值、总余量。预算允许的情况下显存宁可多留20%到30%也不要卡着最低线买因为你不知道什么时候会把上下文从2K改到8K也不知道用户并发会涨到多少。如果你正准备部署一个大模型我的建议是先拿7B或者8B的量化模型完整走一遍流程把显存监控打开观察真实峰值再决定要不要上更大参数。这套组合匹配的思路比记住任何一张“参数量对显存”的表都管用。