Distributed Training on Panel Data
How to split a model-training job across multiple GPUs or machines when the dataset is a stock-by-time panel, and the specific complications panel structure adds that a generic image dataset doesn't have.
Prerequisites: Dataloader Throughput and GPU Utilisation
A model trained on ten years of daily data across five thousand stocks can involve tens of millions of rows — too slow to train on a single GPU in reasonable time, sometimes too large to fit in one GPU's memory. The standard answer is spreading the work across several GPUs, but panel data (many instruments observed repeatedly over time) has a quirk that makes naive splitting dangerous: rows aren't independent the way images in a photo dataset are, since the same stock recurs across time and different stocks move together on the same day.
The idea: splitting work without splitting correctness
The most common approach is data parallelism: copy the same model onto every GPU, split each batch across them, have each GPU compute its own local gradient, then average gradients across GPUs before updating the shared model. Every GPU ends the step with identical weights, and throughput scales roughly with GPU count.
The panel-data complication is how you split rows across GPUs. Split naively — all of stock A's rows on GPU 1, stock B's on GPU 2 — and each GPU's local batch is no longer a representative sample of the whole market; gradients from a single stock's history can be systematically biased in a way a random cross-section wouldn't be. The fix is to shuffle across both stocks and dates before splitting, so every GPU's chunk looks like a random cross-section of the whole panel, not a slice by ticker or time.
Worked example: batch construction across two GPUs
Suppose a batch of 1,000 rows is drawn from a panel of 500 stocks over 10 days, split across 2 GPUs, 500 rows each. A naive split by ticker order — GPU 1 gets stocks ranked 1–250, GPU 2 gets 251–500 — means each GPU's gradient comes almost entirely from one segment of the market (large caps versus small caps), and averaging those two biased gradients doesn't equal the gradient from a properly shuffled 1,000-row batch. The correct approach: shuffle all 1,000 rows across stocks and dates first, then hand rows 1–500 to GPU 1 and 501–1,000 to GPU 2. Each GPU now trains on a genuine random cross-section, and averaging the two local gradients recovers what a single-GPU run on the full batch would have computed.
A second panel-specific trap: if a validation split shares dates with the training split, information about that day's market-wide move leaks across the split regardless of GPU count — so time-based, not random, train/validation splitting still matters even after solving the shuffling problem.
Treat that curve as "training throughput" against "number of GPUs": speedup is close to linear at first, then flattens as the overhead of synchronizing gradients across machines starts to eat into the gains — a real ceiling that panel-data jobs hit sooner than image jobs, because panel batches are often smaller and communication overhead dominates faster.
What this means in practice
Distributed training is worth the complexity once single-GPU training time becomes the bottleneck on research iteration speed, but it introduces failure modes specific to panel data: naive sharding by ticker or date silently biases gradients, and a validation split that leaks dates will look fine in monitoring while quietly overstating performance.
Data-parallel training across GPUs works by splitting a batch, computing gradients independently, and averaging them — but for panel data, the split must shuffle across both instruments and dates first, or each GPU's gradient becomes a biased sample of one slice of the market rather than a fair cross-section.
It's easy to assume any way of splitting rows across GPUs is equivalent as long as row counts are balanced. For panel data specifically, splitting by ticker or by date silently creates biased local batches — the training loss curve can look completely normal while the model quietly learns something different from what a properly shuffled single-GPU run would have produced.
Related concepts
Practice in interviews
Further reading
- PyTorch documentation, Distributed Data Parallel
- Goyal et al., Accurate, Large Minibatch SGD