共计 2820 个字符,预计需要花费 8 分钟才能阅读完成。
为什么我的 4090 跑模型还没老显卡快?
刚拿到 RTX 4090 时,我也遇到过同样的问题——明明参数碾压旧显卡,实际训练速度却提升有限。经过两周踩坑总结,发现关键在于正确配置和优化。本文将手把手带你解锁 4090 的真实性能。

一、环境配置:打好地基
1. 驱动与 CUDA Toolkit
先到 NVIDIA 官网 下载最新驱动(目前推荐 535+ 版本),安装后执行:
nvidia-smi # 确认驱动版本和显卡识别正常
接着安装 CUDA Toolkit 12.1(与 4090 适配最佳):
- 下载官方.run 安装包
- 执行安装时 务必 取消勾选自带的驱动安装
- 将以下内容添加到
~/.bashrc:
export PATH=/usr/local/cuda-12.1/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-12.1/lib64:$LD_LIBRARY_PATH
2. cuDNN 安装
去 NVIDIA 开发者网站下载与 CUDA 12.1 匹配的 cuDNN 8.9,解压后执行:
sudo cp cuda/include/cudnn*.h /usr/local/cuda/include/
sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64/
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*
3. 深度学习框架选择
PyTorch 用户推荐使用 2.0+ 版本:
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121
TensorFlow 用户需注意:
pip install tensorflow[and-cuda]==2.12.0 # 最后一个官方支持版本
二、性能优化六脉神剑
1. 自动混合精度训练(AMP)
4090 的 Tensor Core 特别适合混合精度计算:
import torch
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
outputs = model(inputs)
loss = criterion(outputs, labels)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
效果:ResNet50 训练速度提升 2 - 3 倍,显存占用减少 30%
2. 梯度累积技巧
当遇到超大 batch 需求时:
accum_steps = 4 # 累积 4 个 batch 再更新
for i, (inputs, labels) in enumerate(train_loader):
with autocast():
outputs = model(inputs)
loss = criterion(outputs, labels) / accum_steps
scaler.scale(loss).backward()
if (i+1) % accum_steps == 0:
scaler.step(optimizer)
scaler.update()
optimizer.zero_grad()
3. CUDA Graph 加速
适用于迭代模式固定的场景:
g = torch.cuda.CUDAGraph()
# 首次运行捕获计算图
with torch.cuda.graph(g):
static_output = model(static_input)
static_loss = criterion(static_output, static_label)
static_loss.backward()
# 后续训练直接复现
for input, label in dataloader:
static_input.copy_(input)
static_label.copy_(label)
g.replay() # 比常规执行快 15%
三、实战代码示范
矩阵乘法基准测试
import torch
import time
device = 'cuda'
size = 8192 # 测试矩阵尺寸
a = torch.randn(size, size, device=device)
b = torch.randn(size, size, device=device)
# 预热 GPU
for _ in range(10):
_ = torch.mm(a, b)
torch.cuda.synchronize()
start = time.time()
for _ in range(100):
c = torch.mm(a, b)
torch.cuda.synchronize()
print(f"TFLOPS: {2*size**3*100/(time.time()-start)/1e12:.2f}")
ResNet 完整训练
model = torchvision.models.resnet50().cuda()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
for epoch in range(100):
model.train()
for inputs, labels in train_loader:
inputs, labels = inputs.cuda(), labels.cuda()
with autocast():
outputs = model(inputs)
loss = criterion(outputs, labels)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
optimizer.zero_grad()
四、常见避坑指南
显存溢出三连
- 现象:CUDA out of memory
-
解决方案:
- 减小 batch size
- 使用梯度检查点(
torch.utils.checkpoint) - 清理无用变量(
del tensor+torch.cuda.empty_cache())
-
现象:训练中途突然崩溃
-
检查是否使用了
pin_memory=True导致主机内存不足 -
现象:显存占用持续增加
- 确认没有在循环中持续累积计算图(
with torch.no_grad())
五、性能对比实测
| 显卡型号 | ResNet50 BS=256 (imgs/sec) | VIT-L BS=64 (imgs/sec) |
|---|---|---|
| RTX 3090 | 412 | 58 |
| RTX 4090 | 892 (+116%) | 143 (+146%) |
测试条件:PyTorch 2.0, CUDA 12.1, AMP 开启
下一步挑战
- 尝试在 MMDetection 框架中启用 4090 的 FP8 训练
- 用 Nsight 工具分析 CUDA 内核性能瓶颈
- 测试不同冷却方案对持续满载性能的影响
经过这些优化后,我的 4090 现在训练 YOLOv8 比之前快 2.8 倍。关键是要根据具体任务组合使用这些技巧——就像做菜时的火候控制,需要不断尝试找到最佳平衡点。
正文完
发表至: 未分类
近两天内
