1. PyTorch-GPU加速简介
PyTorch 是一个基于 Python 的机器学习框架,广受欢迎。PyTorch 的最大特点是动态图模型,提供了自动求导的功能,让深度学习领域的开发变得更加简单、快捷。但是在处理大型数据集时,使用CPU计算速度太慢,需要使用GPU加速,而且在GPU上运行PyTorch可以大大缩短训练时间和提高模型性能。
2. 安装PyTorch CUDA
首先,要确保安装的PyTorch版本支持CUDA。
pip3 install torch torchvision torchaudio -f https://download.pytorch.org/whl/cu101/torch_stable.html
上述命令安装了PyTorch的CUDA版本,其中的“cu101”指的是CUDA的版本号,您需要根据自己的实际情况进行修改。如果您不确定自己需要哪个版本,可以在终端中运行以下命令进行查询。
nvcc -V
如果您的系统中已经安装了CUDA,就可以直接在PyTorch代码中使用GPU进行加速。
3. 使用GPU运行Python代码
3.1. 导入PyTorch和CUDA库
在代码开头要导入以下库:
import torch
import torchvision
import torch.nn as nn
import torch.optim as optim
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
其中,device变量是用于存储PyTorch使用的设备。如果你的机器有GPU,将其设置为cuda,否则设置为cpu。
3.2. 将数据传输到GPU
使用GPU加速需要将数据传输到GPU,然后在GPU上进行计算。下面是一段示例代码:
input = torch.randn(10, 3, 224, 224)
input = input.to(device)
print(input.device)
上述例子中,定义了一个大小为10x3x224x224的张量input,然后将其传输到设备(CPU或GPU)上。可使用to方法实现。打印输入张量的设备类型,可以看到它已经被传输到了GPU上。
3.3. 在GPU上进行模型训练
在训练神经网络模型时,可以将模型转移到GPU上运行,这样可以加快训练速度。如果您定义了神经网络模型如下:
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
您可以将它转移到设备上(包括其内部参数)使用代码如下:
net = Net()
net.to(device)
现在,您可以将数据和标签传输到设备上,然后在设备上运行模型。
3.4. 在GPU上运行推理程序
利用PyTorch可以轻松将模型转移到GPU上,以执行推理任务。下面是一个具体的例子。
首先需要加载训练好的模型:
model = torch.load('model.pth')
接下来,需要将模型转移到GPU上,这样才能在GPU上执行真正的推理任务:
model = model.to(device)
然后,对于每个具体的推理程序,需要将输入张量传输到GPU上,然后在GPU上运行模型。下面是一个MNIST数字分类器的推理代码例子。
from torchvision.datasets import MNIST
from torch.utils.data import DataLoader
from torchvision import transforms
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
test_dataset = MNIST('./data', train=False, transform=transform)
test_loader = DataLoader(test_dataset, batch_size=512)
def predict(model, input_tensor, temp=0.6):
model.eval()
input_tensor = input_tensor.to(device)
output = model(input_tensor)
output = nn.functional.softmax(output / temp, dim=1)
return output
for batch_data, batch_target in test_loader:
# 将数据传输到GPU上
batch_data = batch_data.to(device)
batch_target = batch_target.to(device)
# 在GPU上进行推理
predictions = predict(model, batch_data, temp=0.6)
# 转移到CPU上
batch_data = batch_data.cpu()
batch_target = batch_target.cpu()
predictions = predictions.cpu()
# 打印结果
print(predictions)
在这个例子中,predict函数接受输入张量和模型作为参数,并在GPU上计算模型输出。函数最终返回输出张量。然后,我们将输入、目标和输出传输到CPU上,并在终端上输出结果。
4. PyTorch-GPU加速小技巧
4.1. 使用inplace操作
inplace操作会修改输入变量,从而避免创建新的变量和复制数据。这样能够减少GPU显存的使用,并提高代码的效率。下面是一个例子:
x = torch.randn(10, 10)
y = torch.randn(10, 10)
x.add_(y)
如果不使用inplace操作,代码将如下:
x = torch.randn(10, 10)
y = torch.randn(10, 10)
x = x+y
上述两份代码的效果相同,但是使用了inplace操作的代码会更快。
4.2. 避免使用大量小张量
在GPU上计算大量小张量会造成额外的运行开销,因此建议尽量合并小张量。例如,可以将两个目录拼接成一个更大的张量,然后再将其传输到GPU上。
4.3. 手动释放显存
当代码使用的显存达到GPU的极限时,会发生OOM错误。为了避免这个问题,可以在代码中显式删除不再需要的变量,以释放显存。
下面是一些常用的方法:
使用 del 关键字删除 Python 对象。
调用 torch.cuda.empty_cache() 函数清空缓存。
在循环中显式释放变量。
5. 总结
通过使用GPU加速PyTorch,我们可以大大缩短训练时间、提高模型性能,有助于快速迭代模型。在GPU上进行计算时,需要确保正确加载GPU支持的版本,并遵循一些小技巧以提高代码效率。