Skip to content
RED SAGSkills

PyTorch interview questions and answers

PyTorch questions test practical model code: tensors, autograd and writing a correct training loop.

Below are 45 PyTorch questions with the correct answer and a short explanation, grouped from fresher to experienced level. Try each one before you open the answer.

What PyTorch interviews usually check

  • ✓Tensors, shapes and devices
  • ✓Autograd and zero_grad
  • ✓nn.Module and the training loop
  • ✓DataLoader and batching
  • ✓Mixed precision and GPU memory

PyTorch interview questions for freshers easy

1. Logging loss without leaking memory

A training loop does total += loss each step to track the epoch loss, and GPU memory keeps rising. What is the usual fix?

  1. A.Call torch.cuda.empty_cache() each step
  2. B.Use a larger batch size
  3. C.Call loss.backward() twice
  4. D.Use total += loss.item()
Show answer

Answer: D. Use total += loss.item()

Adding the loss tensor keeps a reference to each step's computation graph, so old graphs cannot be freed. loss.item() returns a plain Python float with no graph attached. loss.detach() also works if you need a tensor.

2. Tensors on different devices

You call model.to("cuda") but forget to move the batch. What happens on model(x) with x on the CPU?

  1. A.PyTorch silently copies x over to the GPU
  2. B.The model silently falls back to the CPU
  3. C.Training runs, but all gradients are zero
  4. D.A RuntimeError about tensors on two devices
Show answer

Answer: D. A RuntimeError about tensors on two devices

PyTorch does not move tensors implicitly between devices; operations need all inputs on the same device. Move each batch with x = x.to(device), often with non_blocking=True when using pinned memory.

3. model(x) versus model.forward(x)

Why should you call model(x) rather than model.forward(x)?

  1. A.forward() skips the gradient calculation
  2. B.forward() always runs on the CPU
  3. C.They differ only in speed
  4. D.model(x) also runs registered hooks
Show answer

Answer: D. model(x) also runs registered hooks

Calling the module runs __call__, which executes forward hooks and pre-hooks along with forward(). Calling forward directly bypasses them, which can break tools that rely on hooks, such as some profilers and quantisation utilities.

4. Default betas in Adam

What are PyTorch's default (beta1, beta2) values for torch.optim.Adam?

  1. A.(0.9, 0.999)
  2. B.(0.5, 0.5)
  3. C.(0.99, 0.9)
  4. D.(0.1, 0.01)
Show answer

Answer: A. (0.9, 0.999)

beta1 = 0.9 controls the moving average of gradients and beta2 = 0.999 that of squared gradients. The default learning rate is 1e-3 and eps is 1e-8. Large language model training often lowers beta2 to about 0.95 for stability.

5. Adding weight decay to an optimiser

What does passing weight_decay=0.01 to torch.optim.AdamW do?

  1. A.Lowers the learning rate every epoch
  2. B.Drops 1% of activations at random
  3. C.Shrinks every weight a little at each step
  4. D.Clips gradients to a norm of 0.01
Show answer

Answer: C. Shrinks every weight a little at each step

Weight decay pulls weights towards zero each step, which discourages large weights and helps regularise. AdamW applies it directly to the weights, separate from the adaptive gradient step. It is not a learning rate schedule or dropout.

6. Size after nn.Flatten

A conv stack outputs (N, 64, 7, 7). After nn.Flatten(), what in_features must the next nn.Linear have?

  1. A.3,136
  2. B.448
  3. C.3,584
  4. D.4,096
Show answer

Answer: A. 3,136

nn.Flatten keeps the batch dimension and flattens the rest: 64 × 7 × 7 = 3,136. A mismatch here is one of the most common shape errors. nn.LazyLinear can infer the size on the first forward pass.

7. What ToTensor does to pixels

torchvision.transforms.ToTensor() is applied to an 8-bit RGB PIL image. What does it return?

  1. A.An int (H, W, C) tensor with values 0–255
  2. B.A float (C, H, W) tensor with values in [0, 1]
  3. C.A float (H, W, C) tensor in [−1, 1]
  4. D.A float (C, H, W) tensor in [0, 255]
Show answer

Answer: B. A float (C, H, W) tensor with values in [0, 1]

ToTensor moves channels first and divides 8-bit pixel values by 255. In transforms v2, the same is done with ToImage() followed by ToDtype(torch.float32, scale=True).

8. Size of an embedding table

How many parameters does nn.Embedding(50000, 768) have?

  1. A.38.4 million
  2. B.50,768
  3. C.768
  4. D.3.84 million
Show answer

Answer: A. 38.4 million

An embedding layer is a lookup table with one 768-dimensional vector per token: 50,000 × 768 = 38,400,000. In smaller language models the embedding table can be a large share of total parameters.

9. Up-weighting a rare class

In a 3-class problem, class 2 is rare. How can you make its errors count more in nn.CrossEntropyLoss?

  1. A.Set reduction="sum" on the loss
  2. B.Use label_smoothing=0.5 in the loss
  3. C.Pass weight=torch.tensor([1., 1., 5.])
  4. D.Call loss.backward() five times per step
Show answer

Answer: C. Pass weight=torch.tensor([1., 1., 5.])

The weight argument scales each example's loss by the weight of its true class, so mistakes on class 2 cost five times more. Oversampling the rare class with a WeightedRandomSampler is another option.

10. What DDP syncs between GPUs

In DistributedDataParallel training on 4 GPUs, what is synchronised between the processes during each backward pass?

  1. A.Gradients, averaged with all-reduce
  2. B.The input batches
  3. C.The loss values only
  4. D.Nothing until the end of the epoch
Show answer

Answer: A. Gradients, averaged with all-reduce

Each process holds a full model copy and its own slice of the data. During backward, DDP all-reduces gradients in buckets so every copy gets the same averaged gradient, and every optimiser step keeps the copies identical.

11. DataParallel or DistributedDataParallel

Why does PyTorch recommend DistributedDataParallel over nn.DataParallel even on a single machine with several GPUs?

  1. A.DataParallel cannot use more than two GPUs
  2. B.DDP uses one process per GPU and avoids a bottleneck
  3. C.DDP needs no changes to the training script
  4. D.DataParallel gives wrong gradients
Show answer

Answer: B. DDP uses one process per GPU and avoids a bottleneck

DataParallel runs in one Python process, copies the model to each GPU every step and gathers outputs on GPU 0, so the GIL and GPU 0 become bottlenecks. DDP runs a process per GPU and overlaps gradient communication with backward, which scales much better.

12. Tensors on different devices

This code raises "Expected all tensors to be on the same device". What is the fix?

model = MyNet().to("cuda")
x = torch.randn(16, 128)
out = model(x)
  1. A.Move the model back with model.cpu() only after
  2. B.Move the input with x = x.to("cuda")
  3. C.Wrap the call in torch.no_grad()
  4. D.Set the batch size to 1
Show answer

Answer: B. Move the input with x = x.to("cuda")

The model's weights are on the GPU, but x was created on the CPU. An operation cannot mix tensors on different devices. Create inputs on the same device or move them there before the forward pass.

13. Memory during evaluation

Your evaluation loop uses far more GPU memory than expected. Wrapping it in torch.no_grad() (or torch.inference_mode()) fixes it. Why?

  1. A.The model weights are moved to the CPU
  2. B.Activations are not kept for a backward pass
  3. C.The batch size is halved automatically
  4. D.The model is converted to INT8
Show answer

Answer: B. Activations are not kept for a backward pass

With autograd on, PyTorch stores intermediate activations so it can compute gradients later. In evaluation you never call backward, so turning gradients off lets those tensors be freed right away and also speeds things up.

14. What autocast does

What happens to operations inside a torch.autocast(device_type="cuda", dtype=torch.bfloat16) block?

with torch.autocast(device_type="cuda", dtype=torch.bfloat16):
    logits = model(x)
    loss = loss_fn(logits, y)
  1. A.Every tensor is permanently converted to BF16
  2. B.Matmuls run in BF16; sensitive ops stay in FP32
  3. C.The model weights are saved in BF16 on disk
  4. D.Only the loss is computed in BF16
Show answer

Answer: B. Matmuls run in BF16; sensitive ops stay in FP32

Autocast chooses a precision per operation: matmuls and convolutions use the lower precision, while ops such as softmax, layer norm and losses are kept in FP32 where needed. The stored weights stay in their original dtype.

15. Purpose of Triton Inference Server

NVIDIA Triton Inference Server is chosen by a team with PyTorch, ONNX and TensorRT models. What does it provide?

  1. A.A Python library for writing training loops
  2. B.One server that runs models from many frameworks
  3. C.A database for storing feature values
  4. D.A GPU driver that replaces CUDA
Show answer

Answer: B. One server that runs models from many frameworks

Triton serves models from several backends behind HTTP and gRPC APIs, with features such as dynamic batching, multiple model instances and ensembles. It is not the same as the Triton language for writing GPU kernels.

PyTorch intermediate interview questions medium

16. Gradient of a sum of squares

What does this PyTorch code print?

import torch
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = (x ** 2).sum()
y.backward()
print(x.grad)
  1. A.tensor([1., 4., 9.])
  2. B.tensor([2., 4., 6.])
  3. C.tensor([1., 2., 3.])
  4. D.None
Show answer

Answer: B. tensor([2., 4., 6.])

The derivative of the sum of x squared with respect to each element is 2x. Autograd stores that in x.grad, giving [2., 4., 6.]. x.grad would be None only if x did not require gradients or backward was never called.

17. backward() on a vector

What happens when this code runs?

x = torch.randn(3, requires_grad=True)
y = x * 2
y.backward()
  1. A.x.grad becomes tensor([2., 2., 2.]) automatically
  2. B.RuntimeError: grad can only be implicitly created for scalars
  3. C.x.grad becomes the single value tensor(6.)
  4. D.Nothing happens, because y is not called a loss
Show answer

Answer: B. RuntimeError: grad can only be implicitly created for scalars

backward() with no argument needs a single-number output. For a vector y, call y.sum().backward() or pass a gradient tensor such as y.backward(torch.ones_like(y)), which then gives x.grad = [2, 2, 2].

18. What detach() does

In a training loop, z = model_a(x).detach() is fed into model_b. What happens when you call loss.backward() on model_b's loss?

  1. A.Only model_b gets gradients
  2. B.Both models get gradients
  3. C.Only model_a gets gradients
  4. D.backward() raises an error
Show answer

Answer: A. Only model_b gets gradients

detach() returns a tensor that shares data but is cut off from the autograd graph. Gradients stop there, so model_a's parameters get no .grad from this loss. This is used, for example, for target networks or frozen feature extractors.

19. torch.cat or torch.stack

a and b both have shape (4, 8). What are the shapes of torch.cat([a, b], dim=0) and torch.stack([a, b], dim=0)?

  1. A.(2, 4, 8) and (8, 8)
  2. B.(4, 16) and (2, 4, 8)
  3. C.(8, 8) and (2, 4, 8)
  4. D.(8, 8) and (4, 8, 2)
Show answer

Answer: C. (8, 8) and (2, 4, 8)

cat joins tensors along an existing dimension, so two (4, 8) tensors on dim 0 give (8, 8). stack adds a new dimension, giving (2, 4, 8). Use stack to build a batch from same-shaped samples.

20. Double versus float error

Inputs come from a NumPy float64 array: x = torch.from_numpy(arr). model(x) fails with "expected scalar type Float but found Double". What is the fix?

  1. A.Convert with x = x.float()
  2. B.Call model.double() on every batch
  3. C.Convert with x = x.long()
  4. D.Wrap the call in torch.no_grad()
Show answer

Answer: A. Convert with x = x.float()

NumPy defaults to float64, while nn layers use float32 weights. Converting inputs with .float() (or creating the array as float32) matches them. model.double() would also work but doubles memory and is much slower on GPUs.

21. Loss for a single-logit classifier

Your binary classifier ends with nn.Linear(64, 1) and no activation. Which loss is the right choice?

  1. A.nn.BCELoss
  2. B.nn.CrossEntropyLoss with 1 class
  3. C.nn.BCEWithLogitsLoss
  4. D.nn.MSELoss on raw logits
Show answer

Answer: C. nn.BCEWithLogitsLoss

BCEWithLogitsLoss combines the sigmoid and binary cross-entropy in one numerically stable step and expects raw logits. BCELoss expects probabilities, so you would need a separate sigmoid, which is less stable. Its pos_weight argument also handles imbalance.

22. Target format for CrossEntropyLoss

Logits have shape (32, 5). For nn.CrossEntropyLoss with hard labels, what should the target tensor be?

  1. A.Shape (32,), dtype long, values 0–4
  2. B.Shape (32, 5) one-hot, dtype long
  3. C.Shape (32, 1), dtype float
  4. D.Shape (5,), dtype long
Show answer

Answer: A. Shape (32,), dtype long, values 0–4

With hard labels, CrossEntropyLoss expects class indices: one integer per example in a long tensor. Since PyTorch 1.10 it also accepts float class probabilities of shape (32, 5) for soft labels, but not a long one-hot tensor.

23. Freezing a pretrained backbone

You want to train only the new classifier head on a pretrained ResNet. What is the standard approach?

  1. A.Call model.eval() on the backbone only
  2. B.Set requires_grad=False on backbone parameters
  3. C.Wrap the head in torch.no_grad()
  4. D.Use a learning rate of zero for the head
Show answer

Answer: B. Set requires_grad=False on backbone parameters

Parameters with requires_grad=False get no gradients, so the optimiser will not change them and backward is cheaper. eval() only changes dropout and batch norm behaviour; no_grad on the head would stop it training.

24. Slow first step after torch.compile

After model = torch.compile(model), the first training step takes 90 seconds and later steps are faster than before. What explains the slow first step?

  1. A.torch.compile reinitialises all of the weights
  2. B.Graph capture and kernel compilation run on first call
  3. C.The first batch is always ten times larger
  4. D.Compiled models must re-download their weights
Show answer

Answer: B. Graph capture and kernel compilation run on first call

torch.compile traces the Python code into graphs and generates optimised kernels the first time it sees each input shape. That one-time cost pays off over many steps. Frequent shape changes can trigger recompiles, so dynamic or padded shapes help.

25. Loss jumps at each epoch start

Training loss jumps sharply at the start of each epoch, then falls again. The DataLoader has shuffle=False and the data is sorted by class. What is happening?

  1. A.The learning rate is reset to its peak at every epoch
  2. B.Batches hold one class at a time, so the model keeps shifting
  3. C.Dropout is switched off at the start of each epoch
  4. D.The model reloads its initial weights at each epoch
Show answer

Answer: B. Batches hold one class at a time, so the model keeps shifting

With class-sorted data and no shuffling, the model sees long runs of one class, adapts to it, then is surprised by the next. Each epoch repeats the pattern. Shuffling gives mixed batches and a smooth loss curve.

26. Using argmax inside a loss

A custom loss uses torch.argmax(logits, dim=1) to pick classes and compares them with labels. The model does not learn. Why?

  1. A.argmax gives no useful gradient
  2. B.argmax only works on the CPU
  3. C.argmax changes the batch size
  4. D.argmax makes all logits negative
Show answer

Answer: A. argmax gives no useful gradient

argmax outputs integer indices, which change in jumps, so no useful gradient flows back to the logits. Train with a differentiable loss like cross-entropy on probabilities, and use argmax only for reporting predictions.

27. DDP error about unused parameters

A model with an optional auxiliary head (used only on some steps) fails under DDP with "Expected to have finished reduction in the prior iteration". What is the usual fix?

  1. A.Lower the learning rate by 10×
  2. B.Use a much smaller batch size
  3. C.Pass find_unused_parameters=True
  4. D.Call zero_grad() twice per step
Show answer

Answer: C. Pass find_unused_parameters=True

DDP waits for gradients from every parameter before finishing the all-reduce. Parameters that got no gradient on a step leave it waiting. find_unused_parameters=True makes DDP detect them, at some cost; always computing every branch (scaled to zero if needed) avoids that cost.

28. Memory grows each training step

GPU memory rises every step until OOM. Which line is the likely cause?

total = 0
for x, y in loader:
    loss = loss_fn(model(x), y)
    loss.backward()
    opt.step(); opt.zero_grad()
    total += loss
  1. A.opt.zero_grad() is called after opt.step()
  2. B.loss.backward() is called inside the loop
  3. C.loss_fn is created outside the loop
  4. D.total += loss keeps each step's graph alive
Show answer

Answer: D. total += loss keeps each step's graph alive

Adding the loss tensor makes total part of the autograd graph, so every step's graph and its saved tensors stay referenced. Use total += loss.item() or loss.detach() to keep only the number.

29. Memory format for CNNs

For mixed-precision CNN training on tensor-core GPUs, why does converting the model and inputs to torch.channels_last often help?

  1. A.It halves the number of channels
  2. B.It stores images as grayscale
  3. C.It turns convolutions into matmuls on the CPU
  4. D.Conv kernels on tensor cores prefer the NHWC layout
Show answer

Answer: D. Conv kernels on tensor cores prefer the NHWC layout

channels_last stores tensors as NHWC, which matches what cuDNN's fastest tensor-core convolution kernels expect. With NCHW, extra transposes may be needed. Values and shapes are unchanged; only the memory layout differs.

30. GradScaler skipped a step

With FP16 and torch.cuda.amp.GradScaler, a few steps are skipped early in training. What is happening?

  1. A.The optimizer ran out of memory and paused
  2. B.The data loader returned an empty batch
  3. C.Skipped steps mean the model has converged
  4. D.Gradients overflowed, so the step was skipped
Show answer

Answer: D. Gradients overflowed, so the step was skipped

GradScaler multiplies the loss by a large factor so small gradients do not underflow in FP16. If any gradient becomes inf or NaN, it skips that update and halves the scale; after a run of good steps it raises the scale again. Occasional skips are normal.

PyTorch interview questions for experienced candidates hard

31. view() after a transpose

What happens when this code runs?

import torch
x = torch.randn(4, 6)
y = x.t()
z = y.view(24)
  1. A.RuntimeError, because y is not contiguous; use reshape or contiguous()
  2. B.z has shape (24,) and shares memory with x
  3. C.z silently gets shape (6, 4) instead of (24,)
  4. D.x is transposed in place and z is a copy
Show answer

Answer: A. RuntimeError, because y is not contiguous; use reshape or contiguous()

x.t() returns a view with swapped strides, so its elements are no longer laid out in row-major order. view() needs a compatible memory layout and raises an error here. reshape() or y.contiguous().view(24) works because they copy the data when needed.

32. What ZeRO stage 3 shards

With DeepSpeed ZeRO stage 3 or PyTorch FSDP full sharding, what is split across data-parallel GPUs?

  1. A.Only the optimizer states
  2. B.Optimizer states and gradients only
  3. C.Parameters, gradients and optimizer states
  4. D.Only the input data batches
Show answer

Answer: C. Parameters, gradients and optimizer states

ZeRO stage 1 shards optimizer states, stage 2 adds gradients and stage 3 also shards the parameters. Each GPU gathers the full weights of a layer just in time for compute and frees them after. This trades extra communication for a large cut in per-GPU memory.

33. Layers in a plain Python list

In this model, the optimizer never updates the hidden layers. Why?

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.layers = [nn.Linear(64, 64) for _ in range(4)]
        self.out = nn.Linear(64, 1)
  1. A.Linear layers of the same size share their weights
  2. B.A plain list hides them from parameters(); use ModuleList
  3. C.The out layer blocks gradients to the earlier layers
  4. D.super().__init__() must be called at the very end
Show answer

Answer: B. A plain list hides them from parameters(); use ModuleList

Module registration only happens for attributes that are Modules, ModuleLists, ModuleDicts or Parameters. A plain list is invisible, so model.parameters() returns only out's weights, and .to(device) and state_dict skip the hidden layers too.

34. Scaling inside dropout

nn.Dropout(p=0.2) is in training mode. An input activation of 5.0 is kept (not dropped). What value comes out?

  1. A.5.00
  2. B.6.25
  3. C.4.00
  4. D.1.25
Show answer

Answer: B. 6.25

PyTorch uses inverted dropout: kept values are divided by (1 − p) = 0.8, so 5.0 becomes 6.25. This keeps the expected activation the same as at eval time, when dropout does nothing.

35. Keys prefixed with module.

load_state_dict fails: missing keys "fc.weight", unexpected keys "module.fc.weight". The checkpoint was saved from a DistributedDataParallel model. What is the fix?

  1. A.Pass strict=False and ignore the warning
  2. B.Retrain the whole model without DDP
  3. C.Strip the "module." prefix from the keys
  4. D.Load the checkpoint onto the CPU first
Show answer

Answer: C. Strip the "module." prefix from the keys

DDP wraps the model, so its state_dict keys gain a "module." prefix. Saving model.module.state_dict() avoids it, or you can rename keys when loading. strict=False would load nothing useful, leaving random weights.

36. Error from an in-place operation

backward() raises "one of the variables needed for gradient computation has been modified by an inplace operation". What usually causes it?

  1. A.A tensor saved for backward was changed in place
  2. B.The loss was a float instead of a tensor
  3. C.The model is on the GPU
  4. D.zero_grad() was called before backward
Show answer

Answer: A. A tensor saved for backward was changed in place

Some ops save their inputs or outputs for the backward pass, such as sigmoid saving its output. Changing that tensor in place (x += 1, relu_(), x[0] = 0) bumps its version counter and autograd refuses to use stale values. Use the out-of-place version.

37. Why .grad is None for an intermediate

After backward(), w.grad has values but h.grad is None. Why?

w = torch.randn(3, requires_grad=True)
h = w * 2
loss = (h ** 2).sum()
loss.backward()
print(w.grad, h.grad)
  1. A.The multiply moved h off the autograd graph
  2. B.Only leaf tensors keep .grad unless retain_grad()
  3. C.backward() must be called on h directly instead
  4. D.h.grad is only filled in when in eval mode
Show answer

Answer: B. Only leaf tensors keep .grad unless retain_grad()

To save memory, autograd only stores gradients for leaf tensors that require grad, like w. Intermediate results like h pass gradients through but do not keep them. Call h.retain_grad() before backward, or use a hook, to inspect them.

38. Calling backward twice

You call loss.backward() and then loss.backward() again on the same graph. PyTorch raises "Trying to backward through the graph a second time". Why?

  1. A.Gradients can only be computed once per model
  2. B.The optimiser locks the graph
  3. C.The loss is detached after the first call
  4. D.The saved tensors are freed after the first backward
Show answer

Answer: D. The saved tensors are freed after the first backward

By default backward() frees the intermediate buffers it used, to save memory. To backpropagate through the same graph again, pass retain_graph=True the first time. Usually the real fix is to run a fresh forward pass.

39. Padding in a batch of sentences

Sentences of length 5 to 60 are zero-padded to 60 in one batch. Why use pack_padded_sequence before an LSTM?

  1. A.So the LSTM skips pads and keeps true final states
  2. B.So the whole batch fits on a single GPU
  3. C.So padding tokens get an embedding of their own
  4. D.So the LSTM can run without any gradients
Show answer

Answer: A. So the LSTM skips pads and keeps true final states

Without packing, a 5-word sentence's final hidden state comes after 55 pad steps, which corrupts it and wastes compute. Packing tells the RNN each sequence's real length, so it stops at the right point.

40. Backpropagating through a gradient

A WGAN-GP loss needs a penalty on the gradient norm of the critic with respect to its input, and that penalty must itself be trained. Which call is needed?

  1. A.loss.backward(retain_graph=False)
  2. B.torch.no_grad() around the penalty
  3. C.x.detach().requires_grad_(False)
  4. D.torch.autograd.grad(..., create_graph=True)
Show answer

Answer: D. torch.autograd.grad(..., create_graph=True)

autograd.grad computes the input gradient; create_graph=True records that computation so the penalty can be differentiated again in loss.backward(). Without it, the gradient is a constant and the penalty gives no training signal.

41. Writing a custom autograd Function

In a torch.autograd.Function subclass, what must backward(ctx, grad_output) return?

  1. A.The loss value for the batch
  2. B.One gradient per forward input, None for non-tensors
  3. C.The updated parameters
  4. D.A single scalar summarising all gradients
Show answer

Answer: B. One gradient per forward input, None for non-tensors

backward receives the gradient of the loss with respect to the output and must return the gradient with respect to each input of forward, in order. Inputs that need no gradient, such as ints or flags, get None. Use gradcheck to verify it.

42. MSE loss that never improves

A regression model's loss stays high. Prediction shape is (64, 1) and target shape is (64,). What does F.mse_loss(pred, target) actually compute?

  1. A.The correct per-example squared error
  2. B.An error, because shapes differ
  3. C.The loss for the first example only
  4. D.A mean over a broadcast 64 × 64 matrix of pairs
Show answer

Answer: D. A mean over a broadcast 64 × 64 matrix of pairs

(64, 1) minus (64,) broadcasts to (64, 64), comparing every prediction with every target. PyTorch only warns, so training optimises the wrong objective. Squeeze the prediction or unsqueeze the target so both are (64,) or (64, 1).

43. Loading a model from a public hub

A teammate wants to load a pickled PyTorch checkpoint downloaded from an unknown public repository in a production pipeline. What is the main risk and safer approach?

  1. A.Pickle files are slower to load, so convert to CSV
  2. B.There is no risk because model files only contain numbers
  3. C.The model might be too accurate
  4. D.Unpickling can execute arbitrary code; prefer weight-only formats such as safetensors, verify source and checksums or signatures, and scan artifacts before use
Show answer

Answer: D. Unpickling can execute arbitrary code; prefer weight-only formats such as safetensors, verify source and checksums or signatures, and scan artifacts before use

Pickle can run any code during loading, so a malicious checkpoint can compromise your system. Weight-only formats and restricted loading modes avoid this. Treat models as part of your software supply chain: trusted sources, hash pinning, signing and an internal registry.

44. OOM late in a long evaluation

An evaluation over 200,000 examples runs out of GPU memory near the end, even inside torch.no_grad(). The loop appends logits to a Python list. What is the fix?

  1. A.Move results to CPU or keep only needed numbers
  2. B.Use a larger learning rate for evaluation
  3. C.Call model.train() before evaluating
  4. D.Increase the batch size to finish sooner
Show answer

Answer: A. Move results to CPU or keep only needed numbers

Every stored logits tensor stays on the GPU, so the list grows with the dataset. Copy results to the CPU (for example .cpu() every few batches), or keep only predictions or metrics, so GPU memory stays flat.

45. Loading a model file from the internet

A teammate downloads a fine-tuned model from an unknown uploader as a .pkl / older PyTorch .bin file and loads it on a production server. What is the main risk?

  1. A.The model will be slightly less accurate than before
  2. B.The file will take too much disk space
  3. C.Unpickling can run code; prefer safetensors
  4. D.Pickle files only work on Windows
Show answer

Answer: C. Unpickling can run code; prefer safetensors

Python pickle deserialisation can execute code embedded in the file, so a malicious model can compromise the machine on load. Safetensors stores only tensors. Verify sources, scan files, and load untrusted artefacts in isolation.

Ready to test yourself?

Take a 15-question PyTorch MCQ test with a score at the end, or practise the full PyTorch question bank and earn points on the leaderboard.