When combining DVCLive with Lightning Fabric, follow this pattern to ensure distributed compatibility:
- Initialize Logger: Create
DVCLiveLogger. - Setup Fabric: Initialize
Fabric(). - Data Loading: Use
fabric.rank_zero_first to ensure only the primary rank downloads data, and use fabric.setup_dataloaders to prepare loaders for distributed training. - Model/Optimizer Setup: Use
fabric.setup(model, optimizer) to automatically move components to the correct device. - Training: Use
fabric.backward(loss) instead of loss.backward(). - Metrics: Use
fabric.all_gather to aggregate metrics across processes before logging. - Saving: Use
fabric.save for checkpoints and logger.experiment.log_artifact for final model files (ensuring rank 0 only).
from lightning.fabric import Fabric
from dvclive.fabric import DVCLiveLogger
logger = DVCLiveLogger(report="notebook")
fabric = Fabric()
# Setup data
with fabric.rank_zero_first(local=False):
train_dataset = MNIST(DATASETS_PATH, download=fabric.is_global_zero, train=True)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64)
train_loader, test_loader = fabric.setup_dataloaders(train_loader, test_loader)
# Setup model
model = Net()
optimizer = torch.optim.Adadelta(model.parameters(), lr=1.0)
model, optimizer = fabric.setup(model, optimizer)
# Training loop
for batch in train_loader:
optimizer.zero_grad()
output = model(batch[0])
loss = F.nll_loss(output, batch[1])
fabric.backward(loss)
optimizer.step()
logger.log_metrics({"loss": loss.item()})
# Finalize
logger.finalize("success")