动手学深度学习 4.6 GPU计算

前言

从零开始学习ai文章系列计划是个人在《动手学深度学习》和《磨菇书》两本书的学习中的个人笔记,文章也会以课本中的章节分开,即每个章节一片笔记。我会尽量的把主要内容以及遇到的难点进行记录与解决,如果哪里有错误的欢迎指正。或者不清晰的可以直接查看原文部分。

《动手学深度学习》原文(课本):https://tangshusen.me/Dive-into-DL-PyTorch/#/

《动手学深度学习》代码:https://github.com/ShusenTang/Dive-into-DL-PyTorch

(由于有时候公式太多,可能会直接贴图片)

在本节中,我们将介绍如何使用单块NVIDIA GPU来计算。所以需要确保已经安装好了PyTorch GPU版本。

1. 计算设备

通过nvidia-smi命令来查看显卡信息了。

1
2
3
!nvidia-smi  # 对Linux/macOS用户有效

nvidia-smi # windows中不用感叹号

我的cuda版本是12.7

访问以下链接获取对面GPU版本的pytorch

https://pytorch.org/

这里 cuda 11.8< 我的cuda 12.7,因此能用

直接复制命令运行

1
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 

要卸载还原成原来的cpu版本的话 (不加 --index-url 就会默认安装 CPU 版本)

1
2
3
pip3 uninstall torch torchvision torchaudio

pip3 install torch torchvision torchaudio

检查是否成功

torch.cuda.is_available() 查看GPU是否可用:

1
2
import torch
print(torch.cuda.is_available()) # 输出 True

查看GPU数量:

1
print(torch.cuda.device_count()) # 输出 1

查看当前GPU索引号,索引号从0开始:

1
print(torch.cuda.current_device()) # 输出 0

根据索引号查看GPU名字:

1
print(torch.cuda.get_device_name(0)) # 输出 'GeForce GTX 1050'

2 Tensor的GPU计算

默认情况下,Tensor会被存在内存上。因此,之前我们每次打印Tensor的时候看不到GPU相关标识。

1
2
x = torch.tensor([1, 2, 3])
print(x)

使用.cuda()可以将CPU上的Tensor转换(复制)到GPU上。如果有多块GPU,我们用.cuda(i)来表示第 i 块GPU及相应的显存(i从0开始)且cuda(0)和cuda()等价。

1
2
3
x = torch.tensor([1, 2, 3])
x = x.cuda(0)
print(x)

我们可以通过Tensor的device属性来查看该Tensor所在的设备。

1
2
3
x = torch.tensor([1, 2, 3])
x = x.cuda(0)
print(x.device)

如果按照原来的则显示cpu。

1
2
x = torch.tensor([1, 2, 3])
print(x.device)

我们可以直接在创建的时候就指定设备。

1
2
3
4
5
x = torch.tensor([1, 2, 3], device=device)
print(x)
# or
x = torch.tensor([1, 2, 3]).to(device)
print(x)

如果对在GPU上的数据进行运算,那么结果还是存放在GPU上。

1
2
3
x = torch.tensor([1, 2, 3], device=device)
y = x**2
print(y)

需要注意的是,存储在不同位置中的数据是不可以直接进行计算的。即存放在CPU上的数据不可以直接与存放在GPU上的数据进行运算,位于不同GPU上的数据也是不能直接进行计算的。

以下计算会报错

1
z = y + x.cpu()

3 模型的GPU计算

同Tensor类似,PyTorch模型也可以通过.cuda转换到GPU上。我们可以通过检查模型的参数的device属性来查看存放模型的设备。

可见模型在CPU上。

1
2
net = nn.Linear(3, 1)
print(list(net.parameters())[0].device)

将其转换到GPU上:

1
2
3
net = nn.Linear(3, 1)
net.cuda()
print(list(net.parameters())[0].device)

同样的,我么需要保证模型输入的Tensor模型都在同一设备上,否则会报错。