模型加载到一半就报显存不足,或者跑着跑着突然 OOM,是本地部署最常见的卡点。很多人第一反应是换卡,其实大部分情况降一档精度、把权重切到多卡、或者把一部分层挪到内存里就能跑起来。这篇按「先降精度、再切分、最后卸载」的顺序给出四步方案,每一步都说明会损失多少速度、什么时候不该用。
模型加载到一半就报显存不足,或者跑着跑着突然 OOM,是本地部署最常见的卡点。很多人第一反应是换卡,其实大部分情况降一档精度、把权重切到多卡、或者把一部分层挪到内存里就能跑起来。
这篇按先降精度、再切分、最后卸载到内存或硬盘的顺序,给出四步方案。每一步都说清楚会损失多少速度、什么情况下不该用,以及排查时该怎么一步步确认,避免一次改太多变量最后不知道是哪招起作用。
先量清楚:到底是哪一步吃显存
显存占用大致可以拆成三块:模型权重、KV 缓存、框架与临时缓冲。先确认瓶颈在哪一块,再决定用哪一招,否则容易做无用功。权重是固定的,KV 缓存会随上下文长度和并发数线性涨,临时缓冲则跟算子实现和批大小有关。
- 用框架自带的显存峰值日志或系统级显存监控看峰值,不要只看空闲值,空闲值往往差很多
- 先量一个延迟基线,方便后面每改一步做对比,可以到 /tools/speed-test 跑一轮记录当前环境的表现
- 长上下文场景经常是 KV 缓存而不是权重撑爆显存,这种情况优先降并发或缩短上下文,别急着换卡
- 在 /compute/gpus 核对卡的显存规格与带宽,明确硬件上限;规格和租用价格会变,具体数字到 /compute 和 /compute/gpu-rental 看当时的报价
第一步:先降精度(量化档位怎么选)
顺序上固定:能降精度就先降精度。改动最小、收益最大,通常不需要改代码,只要换一个量化权重文件就能跑起来。它本质上是拿一点精度换显存和加载速度,多数对话类任务感知不明显。
| 场景 | 建议档位方向 | 该注意什么 |
|---|---|---|
| 日常对话、摘要 | 可以往低比特走 | 先跑几条样本确认通顺度没崩 |
| 代码生成、数值推理 | 优先保高比特 | 低比特容易在长链推理上掉质量 |
| 需要微调 | 慎用低比特 | 量化权重通常不适合继续训练 |
| 输出要过质量检测 | 单独验证档位 | 用 /tools/quality-check 做回归对比再定档 |
量化不只是省显存,也影响加载速度和首 token 延迟。低比特通常更快,但极端压缩会带来反量化开销,速度不一定线性变好,所以档位要实测,不要按直觉一路往下压。
第二步:切分到多卡(张量并行与流水并行)
单卡放不下、手上有两张以上卡时用切分,比 offload 快得多,因为计算仍然留在显存里,只是把权重和计算分摊开。代价是卡间通信和调度开销,怎么切要看机器形态。
- 张量并行
- 把单层拆到多卡,通信频繁,适合卡间带宽高的机器
- 流水并行
- 按层分段,通信少但对负载均衡敏感,容易出现一卡等一卡
- 切分度
- 切几份,不是越大越好,切分度上升会带来额外通信与调度开销
判断标准很简单:卡间互联带宽不够时,张量并行的收益会被通信吃掉,这时候调小切分度、或者只切一部分层反而更快。小模型强行多卡通常更慢,单卡能放下就别切。多卡机器的租用成本差异很大,租之前到 /compute 看当时的规格与计费口径,别按老价格做预算。
第三步:卸载到内存或硬盘(CPU offload)
把部分层或部分权重放到内存、按需换入显存,是最能救急也最慢的一档。内存够但显存不够时,它几乎是唯一选择。速度损失主要来自数据在内存与显存之间的搬运,损失幅度取决于可用带宽和卸载比例。
- 先算卸载比例估计哪些层必须留在显存,哪些可以挪走,比例越高越慢,交互式场景很容易掉到不可用
- 小批量试跑先用小批量跑通,记下延迟和峰值显存,确认能接受再放大批量
- 观察是否换到硬盘内存不够时会进一步换到硬盘,速度再掉一个数量级,属于能跑但不建议长期用的状态
第四步:上面都不行时的兜底与迁移动作
到这一步说明前三种手段都不够,或者代价已经超出可接受范围,该考虑换更小的模型、换卡,或者干脆走调用而不是自建。关键是按顺序排查,一步一测,别同时改两个变量。
- 按顺序走:降精度 → 降并发或缩上下文 → 多卡切分 → 卸载 → 换更小的模型或换卡
- 本地长期跑不动,说明该评估走调用而不是自建,判断口径见 /self-host
- 换模型时同步看许可证与商用条款,别只比显存占用,模型清单与规格到 /models 和 /inference 核对当时的条目
- 部署层面的显存与并发测算口径可以对照 /models/deploy,把估算结果和实测峰值对一次账
常见问题
降精度以后模型明显变笨了,是不是量化本身不能用?
先分清是降得太狠还是任务本身敏感。同一档位在对话类任务上常常看不出差别,但在代码、数学、长链工具调用上会明显掉。做法是固定一组自己的测试题,逐档位跑一遍比对,再决定停在哪一档;如果只有最低档能放下,那更适合换更小的模型而不是硬压。
两张卡比一张卡快吗?
不一定。单卡能放下时,多卡因为通信和调度开销,经常比单卡慢。只有单卡放不下、必须切分时才划算,而且卡间带宽越高越划算。判断方法是先按单卡跑一次记录延迟,再开切分跑一次对比,两次都用同样的输入长度和并发数,否则比不出结论。
CPU offload 适合日常用吗?
适合离线批处理,不适合交互。它的瓶颈是权重在内存和显存之间来回搬,卸载比例一高,响应时间会掉到没法等人。如果只是偶尔跑一次长任务、能接受等待,可以用;如果是给人用的对话或接口服务,优先考虑降精度、缩并发,或者干脆改用调用 API。