显存不够时,模型切分部署的本质是把单个模型按层或按张量拆分到多张卡上,用通信换容量,具体方案取决于你的显卡数量和互联带宽。
显存容量不够,模型切分部署怎么选?
先把账算清楚,一个70亿参数的模型,光是把权重用FP16存下来,就要占14GB显存,训练的时候,梯度跟优化器状态才是大头,Adam优化器每个参数要额外存两组状态,算下来轻松突破40GB,就算只做推理,激活值也可能吃掉几个GB,这就是为什么很多人拿着24GB的卡,连13B模型都得靠量化才塞得进去。
显存约束面前,只有两条路:要么缩小模型,要么切分模型,缩小模型靠量化、剪枝、蒸馏,但精度损失不可控,切分模型则是把一个大模型“拆开”,分别塞进不同显卡,业内专家指出,切分方式的选择,本质上是显存容量、通信带宽和计算效率三者之间的博弈。
常见的切分方案有四种,按需求选。
模型并行切分部署方案对比:张量并行、流水线与ZeRO
行业共识认为,没有绝对最优的切分方式,只有最适配场景的组合,下面用一张表说清楚各自特点。
| 方案 | 切分维度 | 显存瓶颈 | 通信开销 | 适用场景 |
|---|---|---|---|---|
| 张量并行 | 矩阵切块 | 单层参数不能太大 | 极高,每层都要全量通信 | 单机多卡,NVLink互联 |
| 流水线并行 | 按层分组 | 每张卡负责若干层 | 较低,只在边界传激活值 | 多机多卡,跨节点部署 |
| 数据并行 | 复制模型 | 每卡都有完整模型 | 极低,仅同步梯度 | 模型能放入单卡,追求吞吐 |
| ZeRO/FSDP | 参数/梯度/状态分片 | 高效切分所有状态 | 中高,随分片粒度变化 | 单卡放不下,又想模拟数据并行 |
张量并行是把一个Transformer层里的QKV矩阵和全连接矩阵,按列或按行切成几块,分给不同卡,每张卡拿着“半个”权重矩阵,计算一半的激活值,算完再用AllReduce拼起来,因为每一层都要跨卡通信,对带宽要求极高,适合NVLink或者同机柜内的高速互联,你如果只有PCIe连接,跑起来通信时间可能比计算时间还长。
流水线并行是按层切,第1到第8层放卡0,第9到第16层放卡1,依此类推,输入数据先过卡0,算完把中间激活传给卡1,通信量不大,但会产生“气泡”前面的卡算完要等后面的卡算完才能处理下一批数据,为了减少气泡,要用微批次调度,把数据切成更小的块流水执行。
ZeRO(或PyTorch的FSDP)是目前最省显存的方案,它不像张量并行那样把权重矩阵切碎,而是把优化器状态、梯度、甚至参数本身在不同卡之间分片存储,计算前把需要的参数拿过来,算完再丢弃,好处是显存开销随显卡数量线性下降,坏处是频繁的通信也会拖慢速度。
单卡显存不足,多卡切分部署实操步骤
以你最可能遇到的情况举例:手里有两张24GB的RTX 3090,想跑一个30B的ChatGLM3或者Qwen2.5,单卡放不下,用HuggingFace生态的accelerate库,几十行配置就能自动切分。
第一步,先显式确认模型不加载到CPU,也不做量化,直接走多卡策略:
pip install accelerate accelerate config
在交互式配置里,选择multi-GPU,并行类型选fsdp或deepspeed,这里有个坑:如果不指定设备映射,Transformers默认把模型全塞进GPU0,导致OOM,正确做法是写一行代码:
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("your/model", device_map="auto")
device_map="auto"

会扫描每张卡的剩余显存,自动决定每一层放在哪,这种方式属于流水线并行的自动版,适合快速验证。
第二步,如果你想手动控制切分策略,或者需要ZeRO-3的高效分片,推荐直接用DeepSpeed脚本:
pip install deepspeed
deepspeed --num_gpus 2 inference.py
--model_name_or_path your/model
--use_fsdp
DeepSpeed的ZeRO-3会把参数切片到所有卡上,每张卡只持有一部分权重,运行时会看到每卡显存占用明显降低,但GPU利用率可能上不去,因为通信在拖后腿。
第三步,检查真实显存占用,在代码里加两行:
import torch print(torch.cuda.memory_summary(device=0))
重点看Reserved memory和Allocated memory,如果发现某一张卡还是超额,可以把max_memory按卡显存大小硬编码:
model = AutoModelForCausalLM.from_pretrained(
"your/model",
device_map="auto",
max_memory={0: "22GiB", 1: "22GiB"}
)
给操作系统留出一点余量,能有效避免OOM。
模型切分部署的成本与价格:别只看显卡数量
跑通只是第一步,真正下手部署前,必须先算成本,多卡切分的显性成本是显卡数量,隐性成本是通信效率和运维复杂度。
通信效率直接影响推理速度,假设你用了张量并行,每生成一个token都要做多次AllReduce,卡间通信带宽从数据下发到返回结果,时延可能翻好几倍,以两张卡跑一个7B模型为例,张量并行可能比单卡慢30%到50%,数据并行则几乎无损,所以如果模型能通过量化塞进单卡,不要轻易上多卡。
价格方面,如果你自己买卡,两张中端游戏卡(24GB显存)大约一万多元,加上主板、电源、机箱散热,整体预算比买一张48GB的专业卡便宜一个量级,但游戏卡的互联走PCIe,带宽远不如NVLink,切分后性能损失明显,如果你只是图显存够用,不考虑速度,那用PCIe拼两张卡是可行的;但如果是高并发生产环境,最好上专用服务器。

云上租卡则是另一套算法,按小时计费,4张16GB的V100租一周的价格,差不多能买下整机了。动态按需扩容适合短期验证,长期跑业务还是买断划算,不少云厂商还支持按显存规格选实例,你可以先起一台2卡实例测测效果,再决定要不要上4卡。
显存切分部署的常见问题与避坑指南
张量并行和流水线并行可以同时用吗?
可以,业界主流做法是“张量并行 + 流水线并行”组合,比如Megatron-LM就支持这种混合并行,通常先在单机内部用张量并行(依赖NVLink),再跨机用流水线并行,两种并行叠加后,显存能进一步摊薄,但通信开销也叠加,小规模部署(4卡以内)不建议混用,单机走张量并行或ZeRO更划算。
4张24GB显卡能部署70B模型吗?
按FP16算,70B模型权重就要140GB,4张24GB总显存96GB,放不下,但用4-bit量化把权重压到约35GB,配合CPU offload,就能塞进4张24GB卡里,推理时可以做到“权重分片 + 按需加载激活”,每张卡显存占用控制在20GB以内,代价是速度变慢,每秒只能生成几个token。
切分后模型输出质量和原来完全一样吗?
如果只是纯张量并行或流水线并行,数学计算顺序不变,理论上输出结果和单卡完全一致,误差来自浮点累加顺序,如果用了ZeRO-3,参数在计算前动态收集,结果也不会有差别,真正影响输出质量的是量化量化到4-bit再切分,困惑度通常会上升,尤其在长文本生成时更明显。
切分部署的本质是用通信换显存,用复杂度换容量,如果你的模型单卡能放下,永远优先单卡;放不下时,先试量化+CPU offload,再试自动切分,最后才上手工并行,把预算花在NVLink互联和更高带宽的网卡上,比单纯堆显卡数量更值。
