Cheat sheets

PyTorch Essentials

Tensors, autograd, nn.Module, the training loop, DataLoader and devices, from the lessons.

  • Concepts and terms
  • Tasks and commands
  • Annotated code
  • Diagrams
  • Defaults and numbers
  • Troubleshooting
  • Questions and tips

Source

Tasks#

TaskCode
Pick a devicedevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")
Make a tensor on itx = torch.randn(3, 4, device=device)
Move model and batchmodel = model.to(device)
Count parameterssum(p.numel() for p in model.parameters())
Save weightstorch.save(model.state_dict(), "model.pt")
Load weightsmodel.load_state_dict(torch.load("model.pt", weights_only=True))
Evaluate without graphmodel.eval() then with torch.no_grad():
Check the GPUtorch.cuda.get_device_name(0)

From Lesson 03.11, Lesson 00.03

Training step#

1DataLoaderyields a batch of inputs and targets.2Deviceinputs.to(device), targets.to(device) moves thebatch.3Optimizeroptimizer.zero_grad() clears old gradients.4Modeloutputs = model(inputs) runs the forward pass.5Loss fncriterion(outputs, targets) gives one scalar.6Autogradloss.backward() replays the tape in reverse.7Optimizeroptimizer.step() updates the parameters.

From Lesson 03.11

Training pipeline#

samplesbatchoutputsbackwardgradsupdateDataset__len__, __getitem__DataLoaderbatch, shuffle, workersnn.Moduleforward(), parameters()Loss fnlogits and targetsAutogradloss.backward()Optimizerstep(), zero_grad()samplesbatchoutputsbackwardgradsupdateDataset__len__, __getitem__DataLoaderbatch, shuffle,workersnn.Moduleforward(),parameters()Loss fnlogits and targetsAutogradloss.backward()Optimizerstep(), zero_grad()

From Lesson 03.11

Train and evaluate#

criterion = nn.CrossEntropyLoss()takes raw logits
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
for epoch in range(num_epochs):
model.train()dropout and batch norm on
for inputs, targets in train_loader:
inputs, targets = inputs.to(device), targets.to(device)
optimizer.zero_grad()gradients accumulate
outputs = model(inputs)forward pass
loss = criterion(outputs, targets)
loss.backward()compute gradients
optimizer.step()update weights
model.eval()eval mode for test
with torch.no_grad():no graph, less memory
outputs = model(images)

From Lesson 03.11

Data and mixed precision#

class MNISTDataset(Dataset):
def __len__(self):
return len(self.labels)number of samples
def __getitem__(self, idx):
return self.images[idx], self.labels[idx] # one sample
loader = DataLoader(dataset, batch_size=64, shuffle=True, num_workers=4)
scaler = GradScaler()from torch.amp
for inputs, targets in loader:
with autocast(device_type="cuda"):float16 forward
outputs = model(inputs)
loss = criterion(outputs, targets)
scaler.scale(loss).backward()scaled backward
scaler.step(optimizer)
scaler.update()
optimizer.zero_grad()

From Lesson 03.11

Debug probes#

TaskCode
Find the op that made NaNwith torch.autograd.detect_anomaly():
Check loss for NaNtorch.isnan(loss)
Read the grad normtorch.nn.utils.clip_grad_norm_(model.parameters(), float("inf"))
Read GPU memorytorch.cuda.memory_allocated() / 1e9

From Lesson 03.13, Lesson 00.12

Tensor ops#

CommandWhat it does
x.view(2, 12)Reshape. Tensor must be contiguous
x.reshape(6, 4)Reshape. Works always
x.permute(2, 0, 1)Reorders dimensions
x.unsqueeze(0)Adds a dimension, (1, 2, 3, 4)
x.squeeze()Removes size 1 dimensions
x.to("cuda") / x.cpu()Moves the tensor between devices
.detach()Cuts the tensor from the graph
labels.long()Casts labels for cross-entropy

From Lesson 03.11, Lesson 03.13

Modules#

CommandWhat it does
nn.Linear(in, out)Wx + b, in*out + out parameters
nn.Conv2d(in_ch, out_ch, k)2D convolution
nn.BatchNorm1d(features)Normalizes activations, 2 * features
nn.LayerNorm(dim)Per sample normalization, 2 * dim
nn.Dropout(p)Random zeroing, 0 parameters
nn.ReLU()\max(0, x)
nn.Embedding(vocab, dim)Lookup table, vocab * dim
nn.Sequential(...)Runs modules in order

From Lesson 03.11

Defaults and numbers#

SettingDefaultNote
Tensor dtypefloat32default training precision
LLM training dtypebfloat16float32 range, less precision
Adam learning rate1e-3default start point
SGD start learning rate1e-2or 1e-1, per the debug lesson
DataLoader batch_size64lesson train loader
num_workers4parallel load processes
Dropout in MNIST MLP0.2after each hidden ReLU
fp16 bytes per parameter2divide GPU memory by 2, keep a margin

From Lesson 03.11, Lesson 03.13, Lesson 00.03

Key concepts#

Tensor
array with a shape, a dtype and a device.
Same device rule
every operation needs all tensors on one device.
Autograd
records operations on a tape, then replays it in reverse.
Leaf tensor
only leaves with requires_grad=True accumulate gradients.
Accumulation
gradients add up by default. Call zero_grad each step.
Registration
modules and nn.Parameter set in __init__ are found by parameters().
state_dict
names mapped to tensors. Portable across code changes.
Mixed precision
float16 forward and backward, float32 master weights.

From Lesson 03.11

Troubleshooting#

SymptomCauseFix
RuntimeError: expected CUDA tensormodel and data on different devices.to(device) on model and data
RuntimeError: modified by in-place operationin-place op breaks autogradreplace x += 1 with x = x + 1
Loss oscillatesno optimizer.zero_grad()call it before loss.backward()
Test accuracy varies between runsno model.eval() at test timeadd model.eval() and torch.no_grad()
Out of memorygraph not freed.detach() or torch.no_grad()
Cross-entropy dtype errorlabels are Floatcast with labels.long()
Wrong gradients, no errorsoftmax output passed to CrossEntropyLosspass raw logits
Loss jumps to NaNexploding gradientstorch.nn.utils.clip_grad_norm_ or lower LR

From Lesson 03.13, Lesson 03.11

Tips#

  • Run the overfit-one-batch test first. If it fails, the setup is broken.
  • Try 3 learning rates, 10x apart, before you look for other bugs.
  • Print shapes after every operation. Broadcasting hides shape bugs.
  • Normalize inputs to mean 0 and std 1.
  • A loss stuck at -log(1/num_classes) means uniform predictions.
  • Use num_workers on disk bound data. It can double speed.

From Lesson 03.13, Lesson 03.11