Install any skill in seconds. Free to start, no credit card required.
Get Started Free →PyTorch Lightning framework for scalable model training and research
.claude/skills/brycewang-stanford-pytorch-lightning-guide/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 55% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 54% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 61% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 61% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 40% | 0% |
PyTorch Lightning is a deep learning framework with over 31,000 GitHub stars that provides a high-level interface for PyTorch, enabling researchers to focus on model design rather than engineering boilerplate. Developed by Lightning AI, it decouples the science (model architecture, loss functions, data processing) from the engineering (distributed training, mixed precision, gradient accumulation, checkpointing) through a structured LightningModule abstraction.
For academic researchers, Lightning eliminates the need to write repetitive training loops, device management code, and distributed training logic. You define your model, training step, and data loaders, and Lightning handles everything else -- from single GPU to multi-node distributed training, from FP32 to mixed precision, from local development to cloud deployment. This means faster iteration on research ideas with production-quality training infrastructure.
Lightning is used extensively in AI research labs and has become a standard tool for reproducible deep learning experiments. It integrates seamlessly with experiment tracking tools like Weights & Biases, MLflow, and TensorBoard, and supports all PyTorch-compatible model architectures.
bash# Install PyTorch Lightning pip install lightning # Or install with specific extras pip install lightning[extra] # For development/research with all features pip install lightning[all]
Lightning requires Python 3.9+ and PyTorch 2.1+. For GPU training, ensure your PyTorch installation includes CUDA support:
bash# Check GPU availability python -c "import torch; print(torch.cuda.is_available())"
Verify your installation:
pythonimport lightning as L print(L.__version__)
The LightningModule is the central abstraction. It organizes your PyTorch code into clearly defined methods:
pythonimport lightning as L import torch import torch.nn.functional as F from torch import nn class ResearchModel(L.LightningModule): def __init__(self, input_dim, hidden_dim, output_dim, lr=1e-3): super().__init__() self.save_hyperparameters() self.encoder = nn.Sequential( nn.Linear(input_dim, hidden_dim), nn.ReLU(), nn.Dropout(0.2), nn.Linear(hidden_dim, hidden_dim), nn.ReLU(), ) self.classifier = nn.Linear(hidden_dim, output_dim) self.lr = lr def forward(self, x): features = self.encoder(x) return self.classifier(features) def training_step(self, batch, batch_idx): x, y = batch logits = self(x) loss = F.cross_entropy(logits, y) acc = (logits.argmax(dim=-1) == y).float().mean() self.log("train_loss", loss, prog_bar=True) self.log("train_acc", acc, prog_bar=True) return loss def validation_step(self, batch, batch_idx): x, y = batch logits = self(x) loss = F.cross_entropy(logits, y) acc = (logits.argmax(dim=-1) == y).float().mean() self.log("val_loss", loss, prog_bar=True) self.log("val_acc", acc, prog_bar=True) def configure_optimizers(self): optimizer = torch.optim.AdamW(self.parameters(), lr=self.lr) scheduler = torch.optim.lr_scheduler.CosineAnnealingLR( optimizer, T_max=self.trainer.max_epochs ) return [optimizer], [scheduler]
Encapsulate all data processing in a reusable LightningDataModule:
pythonclass ResearchDataModule(L.LightningDataModule): def __init__(self, data_dir, batch_size=32, num_workers=4): super().__init__() self.data_dir = data_dir self.batch_size = batch_size self.num_workers = num_workers def setup(self, stage=None): # Load and split data dataset = load_research_dataset(self.data_dir) self.train_data, self.val_data, self.test_data = random_split( dataset, [0.8, 0.1, 0.1] ) def train_dataloader(self): return DataLoader(self.train_data, batch_size=self.batch_size, shuffle=True, num_workers=self.num_workers) def val_dataloader(self): return DataLoader(self.val_data, batch_size=self.batch_size, num_workers=self.num_workers)
The Trainer orchestrates everything with a rich set of configuration options:
pythontrainer = L.Trainer( max_epochs=100, accelerator="gpu", devices=4, strategy="ddp", precision="16-mixed", gradient_clip_val=1.0, accumulate_grad_batches=4, callbacks=[ L.callbacks.EarlyStopping(monitor="val_loss", patience=10), L.callbacks.ModelCheckpoint(monitor="val_loss", save_top_k=3), L.callbacks.LearningRateMonitor(), ], logger=L.loggers.WandbLogger(project="my-research"), ) # Train the model trainer.fit(model, datamodule=data_module) # Test with best checkpoint trainer.test(model, datamodule=data_module, ckpt_path="best")
Lightning supports multiple distributed training strategies out of the box:
python# FSDP for large model training trainer = L.Trainer( strategy="fsdp", devices=8, precision="bf16-mixed", )
Override the training loop for non-standard research workflows like GANs, reinforcement learning, or meta-learning:
pythonclass GANModule(L.LightningModule): def training_step(self, batch, batch_idx): optimizer_g, optimizer_d = self.optimizers() # Train discriminator real_loss = self.discriminator_loss(batch, real=True) fake_loss = self.discriminator_loss(batch, real=False) d_loss = (real_loss + fake_loss) / 2 optimizer_d.zero_grad() self.manual_backward(d_loss) optimizer_d.step() # Train generator g_loss = self.generator_loss(batch) optimizer_g.zero_grad() self.manual_backward(g_loss) optimizer_g.step() @property def automatic_optimization(self): return False
Built-in profiling tools help identify bottlenecks:
pythontrainer = L.Trainer( profiler="advanced", # or "simple", "pytorch" detect_anomaly=True, overfit_batches=10, # Quick sanity check )
Lightning has built-in support for reproducibility, which is critical for academic research:
python# Seed everything for reproducibility L.seed_everything(42, workers=True) # Hyperparameters are automatically saved model = ResearchModel(input_dim=768, hidden_dim=256, output_dim=10) # model.hparams is automatically populated and logged # Checkpoints include full training state # Resume training from a checkpoint trainer.fit(model, ckpt_path="path/to/checkpoint.ckpt")
The save_hyperparameters() call in your module's __init__ automatically tracks all constructor arguments, making experiment comparison straightforward.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-06 | fail→pass | 14,621 | 8,384 | -43% | 1 | 1 | 0% | 2,216 | 3,442 | +55% | 0 | 0 | — |
case-01 | fail→fail | 15,952 | 18,788 | +18% | 1 | 1 | 0% | 3,316 | 5,479 | +65% | 0 | 0 | — |
case-02 | pass→pass | 15,342 | 9,734 | -37% | 1 | 1 | 0% | 2,883 | 4,026 | +40% | 0 | 0 | — |
case-03 | fail→fail | 15,316 | 16,195 | +6% | 1 | 1 | 0% | 2,809 | 5,366 | +91% | 0 | 0 | — |
case-04 | fail→pass | 15,369 | 12,793 | -17% | 1 | 1 | 0% | 2,790 | 4,295 | +54% | 0 | 0 | — |
case-05 | pass→pass | 11,194 | 7,210 | -36% | 1 | 1 | 0% | 1,969 | 3,234 | +64% | 0 | 0 | — |
case-07 | pass→pass | 12,533 | 13,238 | +6% | 1 | 1 | 0% | 2,468 | 4,694 | +90% | 0 | 0 | — |
case-08 | pass→pass | 10,509 | 10,623 | +1% | 1 | 1 | 0% | 2,112 | 4,075 | +93% | 0 | 0 | — |
case-09 | fail→pass | 13,353 | 9,211 | -31% | 1 | 1 | 0% | 2,159 | 3,486 | +61% | 0 | 0 | — |
case-10 | fail→pass | 10,047 | 5,554 | -45% | 1 | 1 | 0% | 1,875 | 3,025 | +61% | 0 | 0 | — |
case-11 | pass→pass | 9,520 | 6,329 | -34% | 1 | 1 | 0% | 1,649 | 3,165 | +92% | 0 | 0 | — |
case-12 | pass→pass | 9,046 | 2,965 | -67% | 1 | 1 | 0% | 1,512 | 2,480 | +64% | 0 | 0 | — |
case-13 | pass→pass | 12,932 | 8,712 | -33% | 1 | 1 | 0% | 2,463 | 3,696 | +50% | 0 | 0 | — |
case-14 | pass→pass | 8,502 | 9,282 | +9% | 1 | 1 | 0% | 1,598 | 3,810 | +138% | 0 | 0 | — |
case-15 | pass→pass | 11,295 | 5,139 | -55% | 1 | 1 | 0% | 2,121 | 2,949 | +39% | 0 | 0 | — |
case-16 | pass→pass | 15,071 | 8,187 | -46% | 1 | 1 | 0% | 2,726 | 3,493 | +28% | 0 | 0 | — |
case-17 | pass→pass | 7,737 | 5,729 | -26% | 1 | 1 | 0% | 1,241 | 3,058 | +146% | 0 | 0 | — |
case-18 | pass→pass | 9,092 | 7,065 | -22% | 1 | 1 | 0% | 1,706 | 3,264 | +91% | 0 | 0 | — |
case-19 | pass→pass | 8,733 | 7,534 | -14% | 1 | 1 | 0% | 1,471 | 3,138 | +113% | 0 | 0 | — |
case-20 | pass→pass | 13,065 | 14,114 | +8% | 1 | 1 | 0% | 2,612 | 4,910 | +88% | 0 | 0 | — |
case-21 | pass→pass | 11,803 | 9,841 | -17% | 1 | 1 | 0% | 2,361 | 3,886 | +65% | 0 | 0 | — |
case-22 | pass→pass | 7,907 | 4,514 | -43% | 1 | 1 | 0% | 1,448 | 2,795 | +93% | 0 | 0 | — |
case-23 | pass→pass | 12,529 | 8,095 | -35% | 1 | 1 | 0% | 2,488 | 3,436 | +38% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +17 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.