直接答案:遇到“显卡不够”先不要买卡。先确认错误来自 GPU 显存(VRAM)、系统内存(RAM)、上下文 KV cache,还是任务本身太慢。推理场景通常可依次尝试关闭其他 GPU 进程、降低上下文与并发、换更小模型或量化版本、把部分层/KV cache 卸载到 CPU;仍不满足时再比较云 GPU 与 API。训练、微调和图像生成的内存结构不同,不能套用同一张“显存需求表”。

紧急恢复和永久修复也要分开:临时降低上下文或并发可以让服务先恢复,但必须保留原始错误、触发请求和变更记录;之后还要用目标流量重新压测,确认容量、延迟、输出质量和回滚都通过。否则一次“能跑起来”可能只是把 OOM 变成排队、超时、频繁交换或静默降级。
第一步:确认到底哪里不够
“CUDA out of memory”通常指 GPU 无法再分配所需显存,但任务卡顿、系统交换或进程被杀也可能来自 RAM 不足。PyTorch 还区分 tensor 实际占用的 memory_allocated 与缓存分配器管理的 memory_reserved;因此 nvidia-smi 显示的占用不一定等于当前张量使用量。
PyTorch 当前 CUDA 语义文档还提供 PYTORCH_ALLOC_CONF 等分配器配置,用于选择后端、限制进程内存比例或改变碎片处理方式。截至 PyTorch 2.13 文档,PYTORCH_ALLOC_CONF 是当前名称,旧的 PYTORCH_CUDA_ALLOC_CONF 仅作为向后兼容别名,因此看到两种写法时应先核对实际运行版本。这些参数不是“开启后显存自动变大”的万能开关;配置错误还可能改变性能或让请求更早触发 OOM。先记录内存快照和复现条件,再一次只改一个分配器参数。
- 加载时就失败:权重、运行时缓冲或 GPU 上的其他进程已经占满显存。
- 输入变长后失败:上下文、KV cache 或批量大小增长导致峰值上升。
- 生成若干轮后失败:可能有缓存、并发请求、未释放张量或内存碎片。
- 速度慢但不报错:可能正在 CPU 推理、频繁交换或部分卸载,不一定是容量错误。
先保存证据,再修改参数
复现 OOM 时,先停止无关任务并记录发生时刻、完整错误、模型与提交版本、输入 Token 数、批量、并发、输出上限、量化格式、PyTorch/CUDA/驱动版本。NVIDIA nvidia-smi 文档可用于确认 GPU、进程和设备内存;PyTorch 的 memory_summary()、max_memory_allocated() 与 memory_snapshot()则用于观察分配器内部状态。只截一张任务结束后的 nvidia-smi 图,往往会错过峰值。
nvidia-smi
import torch
print(torch.cuda.memory_summary())
print(torch.cuda.max_memory_allocated() / 1024**3, "GiB")
| 观察结果 | 更可能的原因 | 下一步验证 |
|---|---|---|
| 加载前显存已高 | 其他进程或旧服务仍占卡 | 核对 PID 与服务归属,不要盲目结束未知进程 |
| allocated 与 reserved 差距大 | 缓存分配器或碎片值得检查 | 保存 memory_summary/snapshot,再对照分配器参数 |
| 输入长度翻倍后才 OOM | KV cache、注意力临时量或批量峰值 | 固定模型,逐级测试上下文和并发 |
| GPU 未满但系统开始交换 | CPU 卸载或数据预处理吃满 RAM | 同时监控 RAM、swap、磁盘与 PCIe 传输 |
| 只有第二轮反向传播失败 | 计算图或张量被意外保留 | 检查列表、日志变量和 retain_graph 使用 |
十分钟 OOM 分诊顺序
第一次遇到 OOM 时,不要同时改量化、上下文、批量和分配器。下面的顺序先建立可复现基线,再用一次只改一个变量的方法定位容量上限。若步骤中发现其他用户或系统服务占用 GPU,应先确认进程归属,不能为了腾显存直接结束未知任务。
| 顺序 | 动作 | 必须保存的证据 | 据此决定什么 |
|---|---|---|---|
| 1 | 记录完整错误与发生阶段 | 加载、首轮前向、生成中、反向或保存检查点 | 区分权重、KV、激活和训练状态 |
| 2 | 检查 GPU 与进程 | GPU 型号、总显存、PID、进程占用和时间 | 是否存在无关占用或多副本服务 |
| 3 | 固定最小请求 | 模型提交、量化格式、上下文、输出上限、batch=1、并发=1 | 建立最小可运行基线 |
| 4 | 保存分配器统计 | allocated、reserved、peak、memory_summary 与 snapshot | 容量不足、缓存碎片还是不可见分配 |
| 5 | 逐级增加单一变量 | 上下文、批量或并发每一级的峰值与结果 | 找到最先触发 OOM 的业务变量 |
| 6 | 选择一种缓解方案 | 变更前后相同请求、质量、延迟和吞吐 | 确认真正降低峰值而非掩盖错误 |
如果最小请求都无法加载,优先检查权重、运行时和其他进程;如果只在长上下文或高并发失败,先处理 KV cache 与请求调度;如果训练到第二轮才失败,则检查计算图、梯度累积、日志变量和检查点状态。这个分流比“看到 OOM 就 4-bit”更可靠,因为不同根因可能需要完全相反的取舍。
怎样区分容量不足、碎片和非 PyTorch 占用
nvidia-smi、PyTorch 的 allocated/reserved 指标和内存快照观察的是不同层面。GPU 进程总占用高但 PyTorch allocated 较低,可能来自缓存、CUDA 上下文、其他库或同进程中的非 PyTorch 分配;reserved 明显高于 allocated 只能提示缓存分配器值得检查,不能仅凭差值断言“碎片就是根因”。memory snapshot 也主要覆盖 PyTorch 分配器管理的内存,NCCL 或其他直接 CUDA 分配可能不在其中。
| 证据组合 | 更可能的解释 | 验证动作 | 不要直接做 |
|---|---|---|---|
| nvidia-smi 高,PyTorch allocated 也高 | 张量、权重、激活或 cache 确实占用 | 按张量与阶段检查峰值 | 把全部问题归因于碎片 |
| reserved 高于 allocated 较多 | 缓存块未归还驱动或存在不可用分段 | 保存 summary/snapshot,复现同一请求 | 循环调用 empty_cache 当长期方案 |
| nvidia-smi 高,PyTorch 统计明显较低 | 其他进程、CUDA 上下文、NCCL 或第三方库 | 核对 PID、进程树与非 PyTorch 分配 | 随意结束未知 PID |
| 首次运行正常,循环后单调增长 | 张量引用、计算图、缓存或请求状态未释放 | 比较每轮快照并定位增长堆栈 | 只增加显存掩盖泄漏 |
| 固定输入偶发 OOM | 并发重叠、异步峰值或动态工作区 | 记录时间线、并发和峰值分配 | 只保留一次成功日志 |
| 调整分配器后 OOM 消失但变慢 | 配置改变了分配或同步行为 | 同时比较延迟、吞吐和峰值 | 把“没报错”直接视为完成 |
只有在同一模型、同一输入和同一运行版本下,保存变更前后的内存快照、峰值、延迟与吞吐,才能判断分配器配置是否有效。环境变量名称、后端和参数语义会随 PyTorch 版本变化;生产配置应与锁定版本一起记录,并准备一键恢复默认值。若无法解释某项大额占用,先缩小到最小脚本,不要在完整业务服务中同时更改多个参数。
显存预算不能只算模型权重
仅估算权重时,可用“参数量 × 每个权重位数 ÷ 8”得到理论下限。例如 70 亿参数按 16 bit 只计算权重约为 14 GB(十进制),但真实运行还要加入量化元数据、未量化层、KV cache、激活、临时工作区、CUDA 上下文、框架缓存和其他进程。文件大小也不等于加载后的显存峰值。

| 预算项 | 主要增长变量 | 可尝试的控制 |
|---|---|---|
| 模型权重 | 参数量、权重精度、量化元数据 | 小模型、兼容的 8/4-bit 量化 |
| KV cache | 层数、KV 头、每头维度、Token、批量/并发、数据类型 | 缩短上下文、降低并发、量化或卸载 cache |
| 激活与临时缓冲 | 批量、序列、算子、图像尺寸、训练反向传播 | 减小 batch/分辨率,训练时考虑检查点 |
| 优化器与梯度 | 训练参数量、优化器状态精度 | 参数高效微调、混合精度、分片 |
| 框架与内核 | CUDA 上下文、内核工作区、编译缓存 | 实测并预留,不做零开销假设 |
| 请求峰值 | 并发、beam、输出长度、多模态组件 | 限流、排队、分池和峰值监控 |
对常见自回归 Transformer,单序列 KV cache 的粗略结构可写成:2 × 层数 × KV头数 × 每头维度 × Token数 × 每元素字节;前面的 2 对应 key 与 value。再乘批量或并发后才接近服务场景。但多查询注意力、分组查询、滑动窗口、跨模态缓存和具体实现都会改变结果,所以公式只用于预算,最终以目标模型和推理引擎的峰值为准。Transformers 的KV cache 官方指南列出了动态、静态、量化和卸载缓存的内存/速度取舍。
怎样把理论下限变成可用预算
权重公式只能回答“参数本身至少需要多少存储”,不能直接回答某张显卡能否运行。实际预算应把权重、KV cache、激活或临时缓冲、运行时开销、并发峰值和安全余量分别列出,并同时记录十进制 GB 与二进制 GiB,避免单位混用。量化模型还可能包含比例因子、零点、未量化层和格式开销,因此 4-bit 不等于总显存恰好变为 FP16 的四分之一。
| 预算阶段 | 怎样估算 | 必须实测的原因 | 通过条件 |
|---|---|---|---|
| 权重下限 | 参数量 × 位宽 ÷ 8 | 不含元数据、未量化模块与加载临时峰值 | 锁定具体仓库和文件格式 |
| 单请求 KV | 按层、KV 头、头维、Token 与元素字节估算 | 注意力结构和后端缓存实现不同 | 目标上下文下记录真实峰值 |
| 并发容量 | 按实际序列长度分桶压测 | 连续批处理和预留策略不一定线性 | P95 延迟与失败率满足目标 |
| 加载峰值 | 从空进程开始记录全过程 | 权重转换和内核初始化可能产生瞬时峰值 | 冷启动多次无 OOM |
| 安全余量 | 为驱动、框架升级和请求波动预留 | 刚好装满的配置无法吸收变化 | 持续压测期间无临界抖动 |
服务框架还可能预留一部分显存给 KV cache 或批处理。vLLM 的显存节省配置文档说明了上下文长度、并发、KV cache、CPU 卸载和并行策略之间的取舍。配置较高的显存利用率可以增加容量,却也会减少波动余量;不能只看单次成功请求,还要在目标并发和最长输入下进行持续压测。
五种处理方法怎么选
| 方法 | 能降低什么 | 主要代价 | 适合场景 |
|---|---|---|---|
| 降低上下文/批量/并发 | KV cache 与激活峰值 | 一次处理内容更少 | 长对话、批量推理 |
| 换小模型 | 权重和运行时总占用 | 部分任务能力下降 | 硬件固定、允许重新评测 |
| 4/8-bit 量化 | 主要是权重内存 | 兼容性、精度与速度可能变化 | 本地 LLM 推理或参数高效微调 |
| CPU/磁盘卸载 | GPU 常驻权重或 KV cache | 传输导致延迟上升 | 容量优先、速度可接受 |
| 云 GPU 或 API | 本地硬件约束 | 持续费用、网络与数据治理 | 短期峰值或无需本地权重 |
方法一:先降上下文、批量和并发
模型文件能加载,不代表任意上下文都能运行。输入越长、并发越高,KV cache 与临时缓冲通常越大。LM Studio 的加载接口允许设置 context_length、评估批量和 KV cache 是否放在 GPU;这说明“模型参数量”并不是显存的唯一变量。
先用短上下文、单请求和较小批量建立基线,再逐项增加。如果业务必须处理长文档,可以先检索、分段、摘要或结构化抽取,而不是把所有历史文本一次塞入模型。
服务端还要把“模型能完成一次请求”与“目标并发下稳定运行”分开。KV cache 往往按可用显存预留,单请求测试通过后,并发增加仍可能触发抢占、排队或 OOM。应按实际输入长度分桶,分别记录并发 1、2、4 等级的峰值、吞吐和失败率;不要只公布最短提示下的 Token/s。
方法二:量化,但不要承诺“几乎无损”
量化用较低比特表示部分权重或计算。Hugging Face 的 bitsandbytes 文档提供 8-bit 与 4-bit 加载方式,并明确不同功能有硬件和后端要求。8-bit 权重量化常能显著减少权重内存,但总显存还包含 KV cache、激活、框架开销和未量化模块,所以不能用“参数量 × 位宽”直接得出最终峰值。
量化后的中文、代码、数学、工具调用和长文本能力都应重新测试。站内的模型量化说明、GPTQ 原理和AWQ 原理可用于理解不同路线,但具体格式必须与推理引擎兼容。
权重量化与 KV cache 量化也不是一回事。前者主要缩小模型常驻权重,后者针对长上下文缓存。Hugging Face 的推理优化总览和 cache 文档提醒,缓存卸载或量化是在内存与速度之间交换;量化 cache 在短上下文且显存充足时还可能损害延迟。因此应把“是否避免 OOM”和“是否更快”作为两个独立验收项。
方法三:把部分工作卸载到 CPU
Hugging Face Accelerate 支持用 device_map 将模块放到 GPU、CPU 或磁盘;LM Studio 也能控制 GPU 卸载比例和 KV cache 位置。卸载解决的是“放得下”,代价通常是数据在 CPU、RAM 与 GPU 之间传输,首 Token 延迟和生成速度可能下降。
使用前确认系统 RAM 足够,并监控是否开始大量使用磁盘交换。若模型虽然能跑但每个 Token 都很慢,继续增加卸载未必比换小模型更划算。
量化、卸载和换服务后怎样验收
缓解 OOM 的方案只有同时通过容量、质量、速度和运维四项检查才算完成。若只是把 OOM 变成极慢响应、中文关键字段错误或不可恢复的远程依赖,问题只是换了形式。测试必须使用同一模型版本、同一提示集、相同输出上限和相同并发阶梯,并保留失败样本。
| 验收维度 | 至少记录 | 常见假通过 | 不通过时的动作 |
|---|---|---|---|
| 容量 | 冷启动峰值、稳态峰值、最长上下文与目标并发 | 只测短提示和并发 1 | 降低上下文/并发或换更小模型 |
| 质量 | 中文、代码、数学、工具参数和长文失败集 | 只比较几个主观样例 | 调整量化格式或恢复更高精度 |
| 速度 | 首 Token、P50/P95、吞吐、抖动与超时 | 只公布生成阶段最快 Token/s | 减少卸载、换后端或改调度 |
| 稳定性 | 重复冷启动、持续压测、碎片、内存增长与重试 | 成功运行一次就签发 | 定位泄漏或设置请求隔离与回收 |
| 成本 | 本地折旧、电力、云空闲、流量、存储与重试 | 只比较显卡售价或 API 单价 | 按真实任务量重算总成本 |
| 治理 | 模型哈希、许可证、数据去向、日志、权限与回滚 | 性能通过就忽略供应链 | 隔离部署或改用责任边界清晰的服务 |
训练和多卡并行的显存分片可参考Megatron Core 分布式训练指南;若本地硬件不适合稳定服务,可用Groq LPU 推理架构指南理解托管推理的延迟边界,或参考Cohere 产品栈选型指南核对 API、检索和企业治理责任。它们不是固定购买推荐,而是帮助把“本地放不下”转换为可审计的架构选择。

推理、训练与图像生成不能共用一张显存表
| 任务 | 除权重外的关键开销 | 优先控制项 |
|---|---|---|
| LLM 推理 | KV cache、并发、输出长度、推理后端工作区 | 上下文、并发、cache 策略、量化 |
| 全参数训练 | 梯度、优化器状态、激活、通信缓冲 | 批量、混合精度、激活检查点、分片 |
| LoRA/参数高效微调 | 可训练参数较少,但基础权重与激活仍在 | 目标层、batch、序列、量化兼容性 |
| 图像/视频生成 | 分辨率、帧数、VAE、文本编码器、中间特征 | 尺寸、批量、帧数、模块卸载与切片 |
训练中常用的激活检查点是用额外计算换取较低激活内存,具体行为应以PyTorch activation checkpointing 文档为准;自动混合精度则参考PyTorch AMP 文档。两者都需要数值和速度复测,不能简单承诺“显存减半”。
方法四:云 GPU 与 API 如何比较
短期实验需要完整环境、特殊权重或训练控制时,云 GPU 更灵活;只是调用文本、图像或语音能力,不需要访问权重时,API 通常更省运维。价格会随地区、显卡、磁盘、带宽、空闲策略和供应变化,本文不提供“每月不到 200 元”之类固定结论。
比较时至少记录:每次任务持续时间、启动等待、模型下载与存储、出入站流量、失败重试、空闲忘关机、密钥管理和数据保留。敏感数据还要检查服务商条款、日志、训练使用、删除机制与地区要求。有关本地方案,可参考离线 AI 工具对比和llama.cpp 说明。
常见无效操作
反复调用 empty_cache 能增加 PyTorch 可用显存吗?
不能释放仍被张量占用的显存。PyTorch 文档说明,empty_cache() 释放未使用的缓存段供其他程序使用,某些情况下有助于碎片问题,但不会增加 PyTorch 可用于当前活动张量的容量。
4-bit 一定比 8-bit 快吗?
不一定。内存更小不等于内核、硬件和格式都更快。要在同一提示、输出长度、上下文和并发下测首 Token 延迟、Token/s、峰值内存与任务质量。
显存越大模型就一定越聪明吗?
显存决定可容纳的权重、缓存与批量,不直接决定模型质量。模型版本、训练数据、任务适配和推理配置同样重要。
最小验收清单
- 记录模型名、版本、量化格式、推理引擎和驱动版本。
- 固定三类真实提示:短问答、长上下文、结构化输出。
- 记录加载内存、峰值显存、首 Token 延迟、Token/s 和失败日志。
- 修改一个变量后重跑同一测试,不同时改模型、上下文和量化。
- 云端/API 额外记录单次成本、数据去向和失败重试。
| 签发字段 | 必须填写的值 | 通过条件示例 |
|---|---|---|
| 身份 | 模型仓库、提交/文件哈希、后端版本 | 能复现同一构建 |
| 负载 | 输入/输出 Token、batch、并发、量化与 cache | 覆盖真实业务分位而非最短样例 |
| 容量 | 峰值 VRAM、RAM、swap、其他进程 | 峰值下仍有约定安全余量 |
| 性能 | 加载、首 Token、Token/s、P95 延迟 | 达到业务阈值且无持续抢占 |
| 质量 | 固定测试集、失败样本、人工复核 | 量化/换模后的退化在可接受边界内 |
| 恢复 | 限流、降级、重启和回滚方法 | 压力测试中能恢复且有记录 |
资料来源
量化与硬件边界参考Hugging Face bitsandbytes 文档;CPU/磁盘卸载参考Accelerate 大模型推理指南;本地运行要求与上下文配置参考LM Studio 系统要求和模型加载配置;显存诊断及缓存边界以PyTorch CUDA 内存说明、CUDA 分配器配置和empty_cache 文档为准。复核日期:2026 年 7 月 18 日。
编辑复核与纠错记录:本文由兰塞 AI 编辑流程于 2026 年 7 月 18 日复核。旧稿中的 2026 显卡价格翻倍、24G 模型 8G 流畅、小李月成本不到 200 元和效率提升十倍均无可审计证据,已删除。A 级候选稿增加 VRAM/RAM/KV cache/速度分诊、权重与 cache 预算、分配器证据、PyTorch 2.13 环境变量命名边界、推理/训练/图像生成区别、量化与卸载代价、云端决策和统一复测字段,并移除主题会重复展示的正文首图。本文不构成硬件购买或云服务推荐,配置变化前请保留可复现基线。本站的来源、更新与纠错原则见关于本站与编辑规范。
