AlgoMaster Logo

Training Pipelines

15 min readUpdated June 1, 2026
Listen to this chapter
Unlock Audio

A model is only as reliable as the pipeline that produced it. Small differences, like data order, random seeds, or a missed preprocessing step, can lead to different results even with the same data and architecture.

Training pipelines bring structure to this process. They turn the path from raw data to a deployable model into something repeatable, auditable, and automated.

Anatomy of a Training Pipeline

A training pipeline is a sequence of stages that takes prepared data and produces a trained model artifact. Each stage has a clear input and output, and the pipeline as a whole is designed to run end-to-end without manual intervention.

StageInputOutputPurpose
Data LoadingStorage path, dataset configIn-memory batchesRead data efficiently from disk or object storage
PreprocessingRaw batchesTransformed batchesNormalize, encode, augment, and split data
Training LoopPreprocessed batches, model configTrained model weightsOptimize model parameters via gradient descent
EvaluationTrained model, validation setMetric scoresMeasure model quality against held-out data
Artifact StorageModel weights, metrics, metadataVersioned artifact in registryPersist the model and everything needed to reproduce it

Here's how these stages connect in a typical pipeline:

The flow is linear, but the evaluation stage acts as a gate. If the newly trained model doesn't meet quality thresholds (relative to the currently deployed model or absolute benchmarks), it doesn't proceed to storage or deployment. This prevents a bad training run from silently replacing a working model.

Each stage is worth understanding in depth, because the design choices at every step affect model quality, training speed, and operational reliability.

Data Loading at Scale

The first bottleneck in any training pipeline is getting data into memory fast enough to keep GPUs busy. A single NVIDIA A100 can process thousands of samples per second. If the data loading pipeline can only deliver hundreds, the GPU sits idle, and you're paying for expensive hardware that's mostly waiting.

Data Formats

The format you store training data in directly affects how fast you can read it.

FormatColumnarCompressionRandom AccessStreamingBest For
CSVNoNoneNoYesSmall datasets, debugging
ParquetYesSnappy/GzipBy row groupYesTabular ML, feature-heavy models
TFRecordNoOptionalNoYesTensorFlow pipelines, sequential reads
PetastormYes (Parquet-based)SnappyBy row groupYesSpark-to-PyTorch/TF bridge
WebDatasetNo (tar-based)OptionalNoYesLarge-scale image/video/audio

For tabular ML (recommendations, fraud detection, ad click prediction), Parquet is the standard. It's columnar, so reading a subset of features is fast. It compresses well. And it's natively supported by Spark, PyArrow, and every major data tool.

For deep learning on unstructured data (images, text, audio), sequential formats like TFRecord or WebDataset perform better. They're optimized for streaming reads, which matches how training loops consume data: one batch at a time, in order.

The Data Loading Pipeline

Naive data loading, reading one batch from disk, preprocessing it, sending it to the GPU, then reading the next, creates a sequential bottleneck. Modern frameworks solve this by overlapping data loading with training.

The key techniques:

  • Prefetching: While the GPU trains on batch N, the CPU is already loading and preprocessing batch N+1. PyTorch's DataLoader with prefetch_factor=2 or TensorFlow's tf.data.prefetch(tf.data.AUTOTUNE) handle this automatically.
  • Parallel workers: Multiple CPU processes read and preprocess data in parallel. PyTorch's num_workers=4 (or higher, depending on CPU cores) prevents a single-threaded bottleneck.
  • Shuffle buffering: For proper stochastic gradient descent, data should be shuffled each epoch. Loading the entire dataset into memory to shuffle it isn't practical at terabyte scale. Instead, maintain a shuffle buffer: fill a buffer of N samples, randomly draw from it, and refill as samples are consumed. Buffer sizes of 10,000-100,000 samples provide good randomization without requiring full-dataset shuffles.
  • Memory mapping: For datasets that fit on local SSD but not in RAM, memory-mapped files let the OS handle caching. Reads appear instant for hot data and only hit disk for cold data.

Here's a PyTorch data loading setup that applies these techniques:

The pin_memory=True flag allocates batches in page-locked memory, which speeds up the CPU-to-GPU transfer. Combined with prefetching and parallel workers, this keeps GPU utilization above 90% for most workloads.

Sharding for Large Datasets

When training data reaches terabytes, a single machine can't hold it all on local disk. The solution is sharding: splitting the dataset into hundreds or thousands of files (shards), stored in object storage (S3, GCS). Each training run reads a subset of shards, and workers divide shards among themselves.

Sharding also enables a simple form of data parallelism even before getting into distributed training. Multiple workers each read different shards, so there's no contention or duplicate reads.

Preprocessing

Once data is loaded, it needs to be transformed into the format the model expects. Preprocessing sits between raw data and the training loop, and getting it right, or wrong, directly impacts model quality.

Common Preprocessing Steps

  • Numerical normalization: Scale features to zero mean and unit variance, or to a [0, 1] range. Without normalization, features with large magnitudes dominate gradient updates, and training becomes unstable. Compute normalization statistics (mean, standard deviation) on the training set only, then apply them to validation and test sets.
  • Categorical encoding: Convert categorical features to numerical representations. One-hot encoding works for low-cardinality features (< 50 categories). For high-cardinality features (user IDs, product IDs), learned embeddings are standard.
  • Missing value handling: Decide on a strategy: impute with median/mode, use a sentinel value, or let the model handle it (tree-based models handle missing values natively, neural networks don't).
  • Data augmentation: For image and text models, augmentation generates variations of training samples (rotations, crops, synonym replacement) to improve generalization. This is typically applied on-the-fly during training rather than materialized to disk.

Preprocessing: Pipeline vs Ad-Hoc

A common mistake is applying preprocessing steps in ad-hoc scripts rather than as a defined pipeline stage. The problem shows up at serving time: the model was trained with a specific normalization scheme, but the serving code applies a slightly different one (different mean/std values, different handling of missing values), and predictions are silently wrong.

The fix is to treat preprocessing as a versioned, reusable component. Frameworks like scikit-learn's Pipeline, TensorFlow Transform (tf.Transform), and Feast's on-demand feature transforms define preprocessing once and apply it identically in both training and serving.

Saving the preprocessing and model together as a single artifact eliminates the class of bugs where training and serving preprocessing diverge. This is particularly important for normalization statistics: if you compute mean and standard deviation during training but hardcode them in serving code, any data distribution shift will cause a mismatch.

The Training Loop

The training loop is where the model actually learns. It's conceptually simple: iterate over the data, compute predictions, measure the loss, compute gradients, and update weights. But the engineering around it determines whether training is reliable, efficient, and debuggable.

Checkpointing

Training runs fail. A machine runs out of memory. A spot instance gets preempted. A NaN appears in the loss. Without checkpointing, a failure after 10 hours of training means starting over from scratch.

Checkpoints save the current state, model weights, optimizer state, learning rate schedule, and the current epoch/step, to disk at regular intervals. When training resumes after a failure, it loads the latest checkpoint and continues from where it left off.

The trade-off is storage and I/O overhead. Saving a checkpoint for a large model (several GB) every 100 steps adds I/O latency. Saving every 10,000 steps risks losing hours of work on failure. A common strategy: save every N steps (where N balances I/O cost against potential lost work), and keep only the K most recent checkpoints to avoid filling up storage.

Logging and Monitoring

Training isn't a black box. At minimum, log the training loss, validation loss, and learning rate at each step. These metrics reveal whether training is progressing (loss decreasing), overfitting (training loss drops but validation loss rises), or diverging (loss spikes or hits NaN).

Beyond basic metrics, log resource utilization: GPU memory usage, GPU utilization percentage, and data loading throughput. If GPU utilization drops below 80%, the pipeline has a bottleneck, usually in data loading or preprocessing.

Logging frameworks like TensorBoard, Weights & Biases, and MLflow provide dashboards for tracking these metrics across runs. Experiment tracking, comparing metrics across different training runs, is covered in a later chapter.

Evaluation and Validation

Every training pipeline needs a quality gate: an evaluation step that decides whether the trained model is good enough to proceed. Without it, any training run, even one that diverged or overfit, produces an artifact that could end up in production.

The evaluation stage runs the trained model against a held-out validation set and computes the metrics that matter for the use case (AUC for ranking, precision/recall for classification, RMSE for regression). These metrics are compared against two baselines:

  • Absolute thresholds: The model must exceed a minimum quality bar (e.g., AUC > 0.80). This prevents clearly broken models from proceeding.
  • Relative thresholds: The model must match or beat the currently deployed model. A 0.5% drop in AUC might be acceptable noise, but a 2% drop signals a regression.

If either check fails, the pipeline halts: no artifact is stored, no deployment is triggered, and the team is alerted. This is the single most important safeguard in an automated training pipeline. Without it, periodic retraining (covered later in this chapter) becomes a liability rather than an asset.

Artifact Storage

A trained model is more than a file of weights. To be useful in production and debuggable after deployment, a model artifact needs to include everything required to understand, reproduce, and serve it.

What to Store

ArtifactPurposeExample
Model weightsThe trained parametersmodel_v42.pt, saved_model/
Preprocessing pipelineTransforms applied before inferencepreprocessor_v42.pkl
Training configHyperparameters, architecture choicesconfig.yaml
Dataset referencePointer to exact training data versions3://ml-data/training/2024-03-15/
MetricsEvaluation results{"auc": 0.847, "precision@10": 0.72}
Environment specPython version, library versionsrequirements.txt, Dockerfile
Git commitCode version that produced this modelabc123def

Everything produced by a training run flows into a model registry (MLflow Model Registry, SageMaker Model Registry, or a custom solution backed by S3 and a metadata database). The registry stores artifacts alongside metadata, making it possible to answer questions like "which dataset trained the model serving traffic right now?" or "what changed between model v41 and v42?"

Model versioning and registry design is covered in detail in a later chapter. For now, the key principle is: store everything needed to reproduce the model. If you can't recreate a model from its artifacts, you don't really have a training pipeline. You have a script.

Training Infrastructure

Choosing where and how to run training is an infrastructure decision that affects cost, speed, and operational complexity.

GPU vs CPU

FactorCPU TrainingGPU Training
Best forTree-based models (XGBoost, LightGBM), small datasets, feature engineeringDeep learning, large neural networks, embedding-heavy models
ThroughputHundreds of samples/secThousands to millions of samples/sec
Cost per hour$0.10-2.00 (cloud)$1.50-30.00 (cloud, depending on GPU)
Memory16-256 GB RAM, flexible16-80 GB VRAM per GPU, fixed
ScalingAdd more CPU cores (diminishing returns)Add more GPUs (near-linear for data parallelism)
Setup complexityLow (runs anywhere)Higher (CUDA drivers, GPU-optimized libraries)

Not everything needs a GPU. XGBoost on a 10M-row tabular dataset trains in minutes on a 32-core CPU machine. Adding a GPU won't make it meaningfully faster because tree-building algorithms don't parallelize the same way matrix operations do. GPUs become essential when training involves large matrix multiplications: neural networks, transformers, embedding tables.

On-Premise vs Cloud

FactorOn-PremiseCloud (AWS/GCP/Azure)
Upfront costHigh (GPU servers: $50K-200K each)None
Per-run costLow (amortized over years)Pay-per-use, adds up at scale
AvailabilityFixed capacity, shared across teamsElastic, scale up/down on demand
Time to startWeeks (procurement, setup)Minutes
MaintenanceYour team's responsibilityManaged by provider
Data localityData stays on your networkData transfer costs, latency to cloud storage
Best forSustained, high-utilization workloadsBursty workloads, experimentation, getting started

The hybrid approach is increasingly common. Teams use on-premise GPUs for steady-state training jobs (daily retraining of production models) and burst to cloud for experiments, hyperparameter sweeps, and one-off large training runs.

Spot and Preemptible Instances

Cloud GPU instances are expensive. AWS spot instances and GCP preemptible VMs offer the same hardware at 60-90% discount, but they can be terminated with little notice (2 minutes on AWS, 30 seconds on GCP).

For training pipelines, this is a good trade-off, if you have robust checkpointing. A training job with checkpoints every 30 minutes loses at most 30 minutes of work when preempted. It resumes from the last checkpoint on a new instance. The 70% cost savings more than compensate for the occasional lost work.

The pattern: run training on spot instances, checkpoint frequently, configure the orchestrator to automatically restart preempted jobs. Most ML platforms (SageMaker, Vertex AI, Databricks) support this natively.

Reproducibility

Training the same pipeline on the same data should produce the same model. In practice, this is harder than it sounds.

Sources of Non-Determinism

  • Random seeds: Weight initialization, dropout, data shuffling, and augmentation all use random number generators. Different seeds produce different models.
  • Floating-point non-determinism: GPU operations like cuDNN convolutions and atomicAdd use non-deterministic algorithms by default because they're faster. Two identical runs can produce slightly different results due to the order of floating-point additions.
  • Data ordering: If data loading uses parallel workers, the order batches arrive can vary between runs. Different batch orderings lead to different gradient updates and different final models.
  • Environment differences: A different version of PyTorch, CUDA, or even NumPy can change numerical results due to implementation differences in linear algebra operations.

Making Training Reproducible

Full determinism requires addressing all four sources:

Setting torch.use_deterministic_algorithms(True) forces PyTorch to use deterministic (but sometimes slower) implementations of GPU operations. This is the nuclear option: full reproducibility at the cost of 10-20% slower training. For production pipelines where auditability matters, the slowdown is worth it. For experimentation, most teams accept minor non-determinism and just fix the random seed, which gets you 99% of the way to reproducible results.

Environment Pinning

Code-level reproducibility means nothing if the environment differs. Pin everything:

Better yet, use Docker to capture the entire environment, OS, CUDA version, Python version, and all dependencies:

The combination of pinned random seeds, deterministic algorithms, and a frozen Docker environment gives you bit-for-bit reproducibility. Store the Docker image hash alongside the model artifact so you can recreate the exact training environment months later.

Scheduling and Automation

A training pipeline that runs manually isn't a pipeline. It's a script. Production models need regular retraining because the data they were trained on becomes stale as user behavior, market conditions, and content catalogs change.

Retraining Strategies

Two approaches, and most production systems use a combination:

Periodic retraining runs on a fixed schedule: daily, weekly, or hourly. It's simple to implement, easy to reason about, and predictable in cost. A daily retraining job that runs at 2 AM, trains on the last 30 days of data, evaluates against the current model, and promotes the new model if it's better, covers most use cases.

Trigger-based retraining fires when a condition is met: model performance drops below a threshold, data drift is detected, or a certain volume of new labeled data arrives. It's more efficient because it only retrains when there's a reason to, but it requires monitoring infrastructure to detect the triggers.

StrategyTriggerProsCons
Periodic (daily)Cron scheduleSimple, predictable cost and cadenceMay retrain unnecessarily or too late
Periodic (hourly)Cron scheduleFresher models, good for fast-changing dataHigh compute cost, complex to operate
Performance-basedMetric drop detectedOnly retrains when neededRequires robust monitoring, may react too slowly
Drift-basedData distribution shift detectedProactive, catches issues before metrics dropDrift detection has its own false positive/negative rate
Volume-basedN new labeled samples collectedEnsures new data is incorporatedArbitrary threshold, doesn't account for data quality

This flow combines both strategies. Periodic monitoring checks model health. When degradation is detected, the system inspects data drift to decide between full retraining (significant drift, the old model's assumptions are stale) and fine-tuning (minor shift, the model just needs a refresh on recent data).

An Automated Retraining DAG

Here's what a daily retraining pipeline looks like in Airflow:

The BranchPythonOperator at the evaluation step makes the pipeline self-governing. If the new model beats the current one, it's promoted. If not, the pipeline logs why it skipped and the existing model keeps serving. No human intervention needed for the happy path, but the team is notified when models are skipped so they can investigate.

Training Window Design

One decision that's easy to overlook: how much historical data should each training run use? This is the training window, and it involves a trade-off between stability and freshness.

  • Long window (6-12 months): More data, better generalization, captures seasonal patterns. But the model is slow to adapt to recent changes because old data dilutes recent trends.
  • Short window (7-30 days): Model adapts quickly to recent behavior changes. But it's more volatile and may miss patterns that only appear seasonally.
  • Sliding window with decay: Use all historical data but weight recent data more heavily. This captures long-term patterns while still adapting to recent shifts. It's the most common approach in practice for recommendation and ranking systems.

The right window depends on how fast the underlying distribution changes. Ad click prediction models at Meta and Google retrain every few hours on very recent data because user intent shifts quickly. Fraud detection models use longer windows because fraud patterns evolve more slowly and rare events need more data to learn from.

Quiz

Training Pipelines Quiz

10 quizzes