| name | torch |
| description | PyTorch provides tensors with automatic differentiation plus neural network utilities for building and training models. |
| version | 2.10.0 |
| ecosystem | python |
| license | BSD-3-Clause |
| generated_with | gpt-5.2 |
Imports
import torch
from torch import Tensor
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader, TensorDataset
Core Patterns
Tensor creation + basic ops ✅ Current
import torch
def main() -> None:
x = torch.randn(2, 3, dtype=torch.float32)
y = torch.ones(2, 3, dtype=torch.float32)
z = x + y
w = torch.matmul(z, z.T)
print("x:", x)
print("w shape:", w.shape)
print("w:", w)
if __name__ == "__main__":
main()
- Use
torch.tensor, torch.zeros/ones, torch.randn, and ops like +, *, torch.matmul for eager tensor computation.
Autograd: gradients with backward() ✅ Current
import torch
def main() -> None:
x = torch.randn(5, requires_grad=True)
y = (x * x).sum()
y.backward()
assert x.grad is not None
print("x:", x)
print("grad:", x.grad)
if __name__ == "__main__":
main()
- Set
requires_grad=True on leaf tensors; call .backward() on a scalar loss to populate .grad.
Training loop with torch.nn.Module + optimizer ✅ Current
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
def main() -> None:
torch.manual_seed(0)
x = torch.randn(256, 1)
y = 2.0 * x + 1.0 + 0.1 * torch.randn_like(x)
loader = DataLoader(TensorDataset(x, y), batch_size=32, shuffle=True)
model = nn.Sequential(nn.Linear(1, 16), nn.ReLU(), nn.Linear(16, 1))
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
loss_fn = nn.MSELoss()
model.train()
for _epoch in range(3):
for xb, yb in loader:
pred = model(xb)
loss = loss_fn(pred, yb)
optimizer.zero_grad(set_to_none=True)
loss.backward()
optimizer.step()
model.eval()
with torch.no_grad():
test_x = torch.tensor([[0.0], [1.0]])
print("pred:", model(test_x).squeeze(-1))
if __name__ == "__main__":
main()
- Standard pattern:
model.train(), forward pass, compute loss, optimizer.zero_grad(), loss.backward(), optimizer.step().
Save/load model and optimizer state ✅ Current
import torch
import torch.nn as nn
def main() -> None:
model = nn.Linear(4, 2)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3)
x = torch.randn(8, 4)
y = model(x).sum()
optimizer.zero_grad(set_to_none=True)
y.backward()
optimizer.step()
checkpoint_path = "/tmp/torch_checkpoint.pt"
torch.save(
{"model": model.state_dict(), "optimizer": optimizer.state_dict()},
checkpoint_path,
)
model2 = nn.Linear(4, 2)
optimizer2 = torch.optim.AdamW(model2.parameters(), lr=1e-3)
ckpt = torch.load(checkpoint_path, map_location="cpu", weights_only=True)
model2.load_state_dict(ckpt["model"])
optimizer2.load_state_dict(ckpt["optimizer"])
print("restored ok:", True)
if __name__ == "__main__":
main()
- Use
state_dict() + torch.save for portability; torch.load(..., map_location=..., weights_only=True) to control device placement and enhance security.
- Note:
weights_only=True is recommended for loading untrusted checkpoints to prevent arbitrary code execution.
TorchScript export with torch.jit.trace ✅ Current
import torch
import torch.nn as nn
def main() -> None:
model = nn.Sequential(nn.Linear(3, 4), nn.ReLU(), nn.Linear(4, 2))
model.eval()
example = torch.randn(1, 3)
scripted = torch.jit.trace(model, example)
out_eager = model(example)
out_script = scripted(example)
print("max diff:", (out_eager - out_script).abs().max().item())
if __name__ == "__main__":
main()
torch.jit.trace captures tensor ops executed for given examples; prefer model.eval() for stable tracing.
Compile a model with torch.compile (PyTorch 2.x) ✅ Current
import torch
import torch.nn as nn
def main() -> None:
torch.manual_seed(0)
model = nn.Sequential(nn.Linear(4, 16), nn.ReLU(), nn.Linear(16, 2))
compiled_model = torch.compile(model, backend="inductor", mode="default")
x = torch.randn(8, 4)
out = compiled_model(x)
print("output shape:", out.shape)
if __name__ == "__main__":
main()
torch.compile() optimizes models via TorchDynamo + backends like Inductor for faster execution.
- Use
mode="reduce-overhead" for minimal overhead or mode="max-autotune" for maximum performance tuning.
Automatic mixed precision with torch.autocast ✅ Current
import torch
import torch.nn as nn
def main() -> None:
torch.manual_seed(0)
model = nn.Linear(10, 5).cuda()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
scaler = torch.GradScaler("cuda")
x = torch.randn(16, 10, device="cuda")
y = torch.randn(16, 5, device="cuda")
for _ in range(3):
optimizer.zero_grad(set_to_none=True)
with torch.autocast(device_type="cuda", dtype=torch.float16):
pred = model(x)
loss = ((pred - y) ** 2).mean()
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
print("training complete")
if __name__ == "__main__":
main()
- Use
torch.autocast context manager for automatic mixed precision; pair with GradScaler to handle gradient scaling.
- Supports
device_type="cuda" or device_type="cpu" with appropriate dtypes.
Vectorized operations with torch.vmap ✅ Current
import torch
def main() -> None:
def compute(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
return (x * y).sum()
x_batch = torch.randn(32, 10)
y_batch = torch.randn(32, 10)
batched_compute = torch.vmap(compute)
result = batched_compute(x_batch, y_batch)
print("result shape:", result.shape)
if __name__ == "__main__":
main()
torch.vmap automatically vectorizes a function over batch dimensions, avoiding manual loops.
Configuration
Pitfalls
Wrong: assuming DataLoader multiprocessing "just works" in Docker (shared memory too small)
import torch
from torch.utils.data import DataLoader, TensorDataset
def main() -> None:
ds = TensorDataset(torch.randn(10_000, 64), torch.randn(10_000, 1))
loader = DataLoader(ds, batch_size=128, num_workers=4, persistent_workers=True)
for xb, yb in loader:
_ = xb.mean() + yb.mean()
break
if __name__ == "__main__":
main()
Right: increase container shared memory (or reduce workers)
import torch
from torch.utils.data import DataLoader, TensorDataset
def main() -> None:
ds = TensorDataset(torch.randn(10_000, 64), torch.randn(10_000, 1))
loader = DataLoader(ds, batch_size=128, num_workers=2)
for xb, yb in loader:
_ = xb.mean() + yb.mean()
break
if __name__ == "__main__":
main()
Wrong: forgetting optimizer.zero_grad() (gradients accumulate)
import torch
import torch.nn as nn
def main() -> None:
model = nn.Linear(3, 1)
opt = torch.optim.SGD(model.parameters(), lr=0.1)
x = torch.randn(4, 3)
for _ in range(2):
loss = model(x).sum()
loss.backward()
opt.step()
print("done")
if __name__ == "__main__":
main()
Right: clear gradients each step (optionally set_to_none=True)
import torch
import torch.nn as nn
def main() -> None:
model = nn.Linear(3, 1)
opt = torch.optim.SGD(model.parameters(), lr=0.1)
x = torch.randn(4, 3)
for _ in range(2):
opt.zero_grad(set_to_none=True)
loss = model(x).sum()
loss.backward()
opt.step()
print("done")
if __name__ == "__main__":
main()
Wrong: calling .numpy() on a tensor that requires grad
import torch
def main() -> None:
x = torch.randn(3, requires_grad=True)
y = (x * 2).sum()
y.backward()
arr = x.numpy()
print(arr)
if __name__ == "__main__":
main()
Right: detach (and move to CPU if needed) before converting to NumPy
import torch
def main() -> None:
x = torch.randn(3, requires_grad=True)
y = (x * 2).sum()
y.backward()
arr = x.detach().cpu().numpy()
print(arr)
if __name__ == "__main__":
main()
Wrong: saving the whole module object instead of state_dict()
import torch
import torch.nn as nn
def main() -> None:
model = nn.Linear(2, 2)
torch.save(model, "/tmp/model_entire.pt")
if __name__ == "__main__":
main()
Right: save/load state_dict() for forward-compatible checkpoints
import torch
import torch.nn as nn
def main() -> None:
path = "/tmp/model_state.pt"
model = nn.Linear(2, 2)
torch.save(model.state_dict(), path)
model2 = nn.Linear(2, 2)
state = torch.load(path, map_location="cpu", weights_only=True)
model2.load_state_dict(state)
if __name__ == "__main__":
main()
Wrong: loading untrusted checkpoints without weights_only=True
import torch
def main() -> None:
checkpoint = torch.load("untrusted_model.pt")
print(checkpoint)
if __name__ == "__main__":
main()
Right: use weights_only=True when loading untrusted checkpoints
import torch
def main() -> None:
checkpoint = torch.load("untrusted_model.pt", weights_only=True)
print(checkpoint)
if __name__ == "__main__":
main()
References
Migration from v2.11.0
Downgrading from v2.11.0 to v2.10.0 typically has minimal impact on user-facing code. If you encounter issues:
- Serialization: Checkpoints saved with v2.11.0 should generally load in v2.10.0, but if you hit compatibility issues, re-save them with v2.10.0.
- TorchScript: Re-trace or re-script models if you observe behavior differences between versions.
- Determinism: Review your
torch.use_deterministic_algorithms() settings and backend-specific constraints if reproducibility changes.
- API changes: Consult the PyTorch release notes for v2.10.0 and v2.11.0 to identify any deprecated or changed APIs.
API Reference
- torch.tensor(data, dtype=None, device=None, requires_grad=False) - Create a tensor from Python data.
- *torch.randn(sizes, dtype=None, device=None) - Random normal tensor.
- *torch.rand(sizes, dtype=None, device=None) - Random uniform [0,1) tensor.
- *torch.zeros(sizes, dtype=None, device=None) - All-zeros tensor.
- *torch.ones(sizes, dtype=None, device=None) - All-ones tensor.
- torch.matmul(input, other) - Matrix product (supports broadcasting).
- torch.stack(tensors, dim=0) - Concatenate tensors along a new dimension.
- torch.split(tensor, split_size_or_sections, dim=0) - Split tensor into chunks.
- torch.chunk(input, chunks, dim=0) - Split tensor into specific number of chunks.
- torch.manual_seed(seed) - Seed RNG for reproducibility.
- torch.seed() - Set random seed to random number; returns that seed.
- torch.initial_seed() - Returns the initial seed for generating random numbers.
- torch.get_rng_state() - Get RNG state as a tensor.
- torch.set_rng_state(new_state) - Set RNG state from a tensor.
- Tensor.backward(gradient=None) - Compute gradients for autograd graph.
- torch.no_grad() - Context manager disabling gradient tracking.
- torch.enable_grad() - Context manager enabling gradient tracking (default).
- torch.inference_mode(mode=True) - Context manager for inference with reduced overhead.
- torch.autocast(device_type, dtype=None, enabled=True) - Automatic mixed precision context.
- torch.compile(model, backend='inductor', mode=None, fullgraph=False, dynamic=None) - Compile model for optimized execution (PyTorch 2.x).
- torch.vmap(func, in_dims=0, out_dims=0, randomness='error', chunk_size=None) - Vectorizing map for automatic batching.
- torch.cond(pred, true_fn, false_fn, operands) - Conditional control flow operator.
- *torch.export(f, args, kwargs=None, , constraints=None, dynamic_shapes=None) - Export models to serializable format.
- torch.save(obj, f) - Serialize object (commonly
state_dict()).