Appearance
使用GPU
一、为什么要用 GPU
在深度学习里,训练模型需要做大量的计算,比如矩阵乘法、卷积这些操作,CPU 的计算速度太慢了,一个模型可能要训练好几天甚至几个月。而 GPU(图形处理器)的并行计算能力比 CPU 强很多,就像一个工厂里有很多工人一起干活,而 CPU 只有几个工人,所以用 GPU 训练模型可以大大提高速度,现在深度学习训练基本都用 GPU。
二、准备工作
要使用 GPU,首先需要准备这些东西:
你的电脑里要有 NVIDIA 的 GPU,因为现在主流的深度学习框架都只支持 NVIDIA 的 GPU。
安装 CUDA 和 NVIDIA 驱动:CUDA 是 NVIDIA 提供的用于 GPU 计算的工具包,驱动是让系统能识别 GPU 的软件,你需要根据你的 GPU 型号下载对应的版本。
安装 GPU 版本的深度学习框架:比如 PyTorch,你需要卸载 CPU 版本的 PyTorch,然后安装支持 CUDA 的版本,比如用
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121安装支持 CUDA12.1 的版本。你可以用
nvidia-smi命令查看你的 GPU 信息,比如 GPU 的型号、显存大小、CUDA 版本。
三、查看可用的 GPU
我们可以用代码查看电脑里有多少个可用的 GPU,以 PyTorch 为例:
python
import torch
def try_gpu(i=0):
"""如果存在第i个GPU,就返回它,否则返回CPU"""
if torch.cuda.device_count() >= i + 1:
return torch.device(f'cuda:{i}')
return torch.device('cpu')
def try_all_gpus():
"""返回所有可用的GPU,如果没有GPU就返回CPU"""
devices = [torch.device(f'cuda:{i}') for i in range(torch.cuda.device_count())]
return devices if devices else [torch.device('cpu')]
# 查看第一个可用的GPU
print(try_gpu())
# 查看第10个GPU(一般没有这么多,所以返回CPU)
print(try_gpu(10))
# 查看所有可用的GPU
print(try_all_gpus())运行结果大概是:
Plain
device(type='cuda', index=0)
device(type='cpu')
[device(type='cuda', index=0)]如果你的电脑有多个 GPU,try_all_gpus()会返回所有的 GPU 设备。
四、把数据放在 GPU 上
我们可以把张量(也就是数据盒子)放在 GPU 的显存里,这样计算的时候就会用 GPU 来计算,以 PyTorch 为例:
python
# 创建一个2×3的张量,放在第一个GPU上
X = torch.ones(2, 3, device=try_gpu())
print(X)运行结果是:
Plain
tensor([[1., 1., 1.],
[1., 1., 1.]], device='cuda:0')这个张量就存在第一个 GPU 的显存里了,你可以用nvidia-smi命令查看显存的使用情况,这个张量会占用一点显存。
五、设备之间的数据传输
如果我们有两个 GPU,或者要在 CPU 和 GPU 之间传输数据,需要用to()方法或者copyto()方法,比如:
python
# 在第二个GPU上创建一个张量Y
Y = torch.rand(2, 3, device=try_gpu(1))
# 把X从第一个GPU传到第二个GPU
Z = X.to(try_gpu(1))
# 现在Z和Y都在第二个GPU上,可以进行计算
print(Y + Z)注意:数据必须在同一个设备上才能进行计算,如果 X 在第一个 GPU,Y 在第二个 GPU,直接计算X+Y会报错,因为系统不知道该用哪个设备来计算。
还有一个小技巧:如果数据已经在目标设备上,to()方法不会做任何额外的复制,而copyto()会重新复制一份,占用更多显存,所以如果不确定数据是不是已经在目标设备上,用to()方法更安全。
六、把神经网络放在 GPU 上
我们训练模型的时候,需要把模型的参数放在 GPU 上,这样模型的计算就会在 GPU 上进行,以 PyTorch 为例:
python
from torch import nn
# 定义一个简单的模型
net = nn.Sequential(nn.Linear(3, 1))
# 把模型移动到第一个GPU上
net = net.to(device=try_gpu())
# 输入一个在GPU上的张量,模型会在GPU上计算
print(net(X))运行结果是:
Plain
tensor([[0.4212],
[0.4212]], device='cuda:0', grad_fn=<AddmmBackward0>)这个结果也在第一个 GPU 上,说明模型的计算是在 GPU 上进行的。
七、注意事项
数据传输的速度比计算慢很多,所以要尽量减少数据传输,比如不要频繁在 CPU 和 GPU 之间传输小数据,最好一次传输大量的数据。
当你打印 GPU 上的张量,或者把张量转换成 NumPy 的时候,系统会把数据从 GPU 传到 CPU,这会有额外的开销,而且会触发 Python 的全局解释器锁,让 GPU 阻塞,所以尽量不要频繁打印 GPU 上的张量。
不要让 GPU 等待 CPU 的操作,比如在 GPU 计算的时候,不要让 CPU 做一些需要等待 GPU 结果的操作,这样会降低效率。
八、小结
GPU 可以大大提高深度学习模型的训练速度,因为它的并行计算能力很强。
我们可以用代码查看可用的 GPU,把数据和模型放在 GPU 上进行计算。
数据必须在同一个设备上才能进行计算,跨设备传输数据要注意开销。
要尽量减少数据传输,避免频繁在 CPU 和 GPU 之间传输数据。
(注:文档部分内容可能由 AI 生成) 源地址