El superpoder que distingue a PyTorch de NumPy. Mover los cálculos a la tarjeta gráfica los acelera decenas de veces — y se hace con una sola línea bien escrita.
Entrenar una red es, sobre todo, multiplicar matrices enormes. Una CPU tiene pocos núcleos muy potentes (buenos para tareas secuenciales). Una GPU tiene miles de núcleos pequeños que hacen muchísimas multiplicaciones en paralelo — justo lo que necesita una red.
CUDA (Compute Unified Device Architecture) es el nombre de la tecnología de NVIDIA que permite usar la GPU para cálculos. torch.cuda es el módulo de PyTorch que la gestiona.
print(torch.cuda.is_available())
Este entorno tiene PyTorch +cpu, así que no hay GPU NVIDIA (CUDA). No pasa nada: todo
el curso funciona en CPU. Pero el código que verás es el que usarías con GPU — y lo bueno
es que es el mismo en ambos casos.
En vez de escribir .cuda() a lo bruto, define un device al inicio que sea
GPU si existe, o CPU si no. Así tu código corre en cualquier máquina sin cambios:
device = 'cuda' if torch.cuda.is_available() else 'cpu'
t = torch.tensor([1., 2., 3.]).to(device)
print(t.device)
En una máquina con GPU, esa misma línea imprimiría cuda:0 — el :0 indica que es la primera GPU (los sistemas pueden tener más de una, numeradas desde 0). Los cálculos correrían en la tarjeta y no tocarías nada más del código.
Para entrenar en GPU, mueve el modelo y los datos al device:
net = net.to(device) # el modelo a la GPU
for xb, yb in dl:
xb = xb.to(device) # los datos del lote, también
yb = yb.to(device)
... # el resto del bucle es idéntico
cuda y los datos en cpu, PyTorch lanza
"Expected all tensors to be on the same device". Regla: modelo y datos, siempre en el
mismo sitio.
device = 'cuda' if torch.cuda.is_available() else 'cpu'. Luego: net.to(device) y xb.to(device) en cada lote. Regla de oro: modelo y datos siempre en el mismo device.
En la próxima lección: el overfitting con las herramientas de PyTorch — dropout, weight decay y BatchNorm.