以下是优化 PyTorch 中 GPU 内存管理、提升大规模矩阵运算效率的方法:
- 自动混合精度训练:利用
torch.cuda.amp.autocast()
和GradScaler
,以 16 位(FP16)计算加速并减内存,关键环节用 32 位(FP32)保稳定,示例:
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
scaler = torch.cuda.amp.GradScaler()
with torch.cuda.amp.autocast():
output = model(input)
loss = criterion(output, target)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
- 梯度检查点:通过
torch.utils.checkpoint
选择性存中间结果,反向传播时重新计算来减内存,适合深层模型,示例:
import torch.utils.checkpoint as checkpoint
def forward_with_checkpoint(self, x):
x = checkpoint.checkpoint(self.layer1, x)
x = checkpoint.checkpoint(self.layer2, x)
return x
- 梯度累积:小批量算梯度并累积,达到虚拟大批次再更新参数,平衡内存与性能,示例:
accumulation_steps = 4
for i, (input, target) in enumerate(dataloader):
output = model(input)
loss = criterion(output, target)
loss = loss / accumulation_steps
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
- 模型与张量分片:用
torch.nn.parallel.DistributedDataParallel
(DDP)或FullyShardedDataParallel
(FSDP,需安装相关库),将模型参数、梯度分片到多 GPU,示例(FSDP 简化示意 ):
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
model = FSDP(model)
- 高效数据加载:
DataLoader
设pin_memory=True
加速主机到设备传输,合理设num_workers
提升加载并行度,示例:
train_loader = torch.utils.data.DataLoader(
dataset,
batch_size=64,
shuffle=True,
num_workers=4,
pin_memory=True
)
- 原地操作与内存复用:部分操作用原地版本(如
torch.add_()
替代torch.add()
),手动管理张量生命周期,及时del
不用的张量并torch.cuda.empty_cache()
清理缓存。 - 使用更精简优化器:用 SGD 替代 Adam 等内存消耗大的优化器,配合余弦退火学习率调度器,示例:
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=num_steps)
- 模型轻量化与剪枝:用知识蒸馏压缩模型,或
torch.nn.utils.prune
剪枝,减少参数数量和计算量。 - 监控与分析工具:用
torch.cuda.memory_summary()
监控内存,nvidia-smi
命令行工具查看 GPU 状态,辅助定位内存问题。