DEV Community

Cover image for Accelerating Deep Learning with Amazon SageMaker

Accelerating Deep Learning with Amazon SageMaker

Ciao Tutti 👋

Recently I have been working on my thesis, and to be very honest, AWS and especially Amazon Sagemaker has been a real lifesaver. Since I always try to share whatever I learn, I tried to document my journey in this article.
In the below-shared article, we are going to discuss Distributed Training on Amazon Sagemaker. In which I have covered the following topics:

  1. Introduction to Distributed Training

    • What is distributed training, and why is it essential for deep learning?
  2. Why Use Amazon SageMaker for Distributed Training?

    • Key benefits and differentiators of SageMaker’s distributed training capabilities.
  3. Supported Frameworks and Algorithms

    • Overview of popular built-in algorithms and third-party frameworks (e.g., TensorFlow, PyTorch) that SageMaker supports.
  4. Distributed Training Architectures

    • Data parallelism vs. model parallelism, and when to use each approach.
  5. Setting Up a Distributed Training Job

    • Step-by-step configuration of your training scripts, instance types, and hyperparameters.
  6. Leveraging Built-in Distributed Training Libraries

    • Introduction to SageMaker’s built-in libraries, including parameter servers, Horovod, or DeepSpeed integration.
  7. Performance Tuning and Scaling Best Practices

    • Tips for optimizing GPU utilization, monitoring resource usage, and scaling out effectively.
  8. Cost Optimization Strategies

    • Managing training costs through Spot Instances, AutoML, or other techniques.
  9. Advanced Monitoring and Debugging

    • Using SageMaker Debugger, Amazon CloudWatch, or third-party tools for deeper insight into performance.
  10. Case Studies and Real-World Examples

    • Practical scenarios of large-scale model training using SageMaker’s distributed capabilities.

I hope you like this one. I am sorry for this being too long compared to my other articles.


1. Introduction to Distributed Training

Deep learning models have become increasingly complex, often requiring massive datasets and substantial computational resources to train effectively. Traditional, single-instance training—where a model is trained on just one machine—quickly becomes inefficient or even infeasible as data sizes grow and models become more sophisticated. This is where distributed training comes into play.

Distributed training is the process of splitting the training workload across multiple computing resources (often GPUs or whole machines) to reduce training time and handle datasets that exceed the memory or processing capabilities of a single machine. By leveraging parallel processing and optimized data handling, distributed training enables data scientists and machine learning engineers to iterate faster, build more accurate models, and experiment with larger network architectures. Below are some foundational concepts that illustrate how distributed training works and why it is essential for modern deep learning:

  1. Large-Scale Data Handling

    • Faster Throughput: Multiple machines or GPUs working in parallel can process more data in the same amount of time, significantly accelerating training.
    • Reduced Training Time: Distributing the workload shortens the time needed to complete an epoch (a full pass through the data), helping teams reach results faster and iterate on their models more frequently.
    • Overcoming Memory Constraints: When datasets are too large to fit into a single machine’s memory, splitting data across multiple nodes becomes a necessity rather than a luxury.
  2. Parallelization Strategies

    • Data Parallelism: In this common approach, the full model is copied to each compute node, but the dataset is split into chunks. Each node processes a batch of data independently and then synchronizes gradients before updating model parameters.
    • Model Parallelism: For extremely large models that don’t fit on a single GPU, different parts (layers or sub-networks) of the model are distributed across multiple GPUs. This approach is more complex but can be crucial for ultra-scale architectures.
  3. Scalability Benefits

    • Horizontal Scaling: Instead of relying on one large machine, you can add or remove multiple machines (or GPUs) to match the size of your problem and your budget. This flexibility lets organizations grow or shrink their infrastructure in a cost-effective manner.
    • Fault Tolerance: Distributed training can be made resilient to individual machine failures through checkpointing mechanisms and replicated model states.
  4. Why It’s Essential for Deep Learning

    • Complex Models: State-of-the-art neural networks for applications like natural language processing (NLP) and computer vision can have billions of parameters. Training these models on a single GPU would be prohibitively slow.
    • Real-Time and Near-Real-Time Needs: Industries such as autonomous driving, finance, and healthcare often require timely insights from massive datasets. Distributed training helps meet these stringent performance needs.
    • Experimentation and Innovation: By reducing training time, ML teams can more rapidly iterate on ideas, leading to faster innovation and more robust models.

Challenges in Distributed Training

  • Communication Overhead: As more machines and GPUs are added, the cost of synchronizing model parameters and gradients increases. Proper strategies and frameworks are needed to minimize this overhead.
  • Implementation Complexity: Writing and maintaining code for distributed systems can be more complex. Tools like Amazon SageMaker, Horovod, and native framework integrations simplify this process.
  • Monitoring & Debugging: With multiple machines involved, detecting and diagnosing performance bottlenecks or errors can be harder, requiring specialized logging and monitoring tools.

Overall, distributed training represents the next evolution in deep learning model development, allowing data teams to train bigger models on bigger datasets in a shorter time.


2. Why Use Amazon SageMaker for Distributed Training?

Amazon SageMaker stands out as a fully managed platform that significantly simplifies the process of setting up, running, and scaling distributed training. By automating much of the heavy lifting around infrastructure provisioning and maintenance, it allows ML teams to focus on model development rather than DevOps. Here are some key benefits and differentiators:

  1. Managed Infrastructure and Orchestration

    • SageMaker handles resource allocation and cluster management automatically, so you don’t need to manually configure VMs or container orchestration.
    • You can easily define how many instances and which instance types to use in your training cluster, and SageMaker provisions and tears them down on your behalf.
  2. Seamless Framework Integration

    • SageMaker supports popular deep learning frameworks like TensorFlow and PyTorch out of the box. These come pre-configured with libraries that streamline distributed training.
    • For custom or specialized frameworks, you can bring your own containers, ensuring maximum flexibility while still benefiting from SageMaker’s distributed capabilities.
  3. Built-in Distributed Training Libraries

    • SageMaker offers built-in support for data parallelism and model parallelism, making it straightforward to train large models or large datasets without manually writing distributed logic.
    • Integration with libraries like Horovod, DeepSpeed, or parameter servers accelerates training and reduces the complexity of synchronization.
  4. Automatic Scalability and Cost Controls

    • You can scale up or down based on performance needs, and leverage Spot Instances to reduce training costs.
    • SageMaker’s managed environment includes tools like the AWS Auto Scaling feature, allowing you to automate infrastructure adjustments as your workload demands change.
  5. Monitoring, Debugging, and Logging

    • Amazon SageMaker Debugger and other AWS monitoring services (e.g., Amazon CloudWatch) provide granular insight into training metrics and resource usage.
    • Automated anomaly detection helps catch issues such as vanishing gradients or poor parameter initializations early in the training process.
  6. Secure Integration with Other AWS Services

    • SageMaker easily integrates with AWS data services like Amazon S3 for storage, AWS Glue for data cataloguing, and Amazon Redshift for analytics, streamlining data pipelines.
    • Features like AWS KMS (Key Management Service), IAM roles, and VPC support ensure your data and model artefacts remain secure throughout the training lifecycle.
  7. Faster Iteration and Collaboration

    • By centralizing model code, datasets, and artefacts in one environment, SageMaker simplifies collaboration among data scientists and ML engineers.
    • Automating the repeated tasks of experiment tracking, versioning, and deployment reduces the time to iterate on new ideas.

Overall, the combination of managed infrastructure, pre-built integrations, and robust tooling makes Amazon SageMaker an attractive solution for distributed training—especially for teams looking to speed up model development cycles while minimizing operational overhead.


3. Supported Frameworks and Algorithms

One of the main advantages of Amazon SageMaker is its extensive support for both built-in algorithms and third-party frameworks. This flexibility lets you choose the best tooling for your specific use case, whether it’s computer vision, natural language processing, recommendation systems, or time-series forecasting.

3.1 Built-in Algorithms

Amazon SageMaker provides a suite of built-in algorithms that are optimized to run at scale on AWS infrastructure. Some popular examples include:

  • XGBoost: A high-performance implementation of the Gradient Boosted Trees algorithm commonly used for structured or tabular data.
  • Image Classification: A convolutional neural network (CNN) approach for classifying images into pre-defined categories.
  • Object Detection: Identifies and classifies objects within an image, suitable for use cases like retail inventory tracking or autonomous vehicles.
  • Semantic Segmentation: Breaks down an image into meaningful segments, often used in medical imaging or self-driving car applications.
  • Random Cut Forest (RCF): An unsupervised algorithm for anomaly detection in time-series or high-dimensional data.

These built-in algorithms come with pre-optimized containers that handle distributed training details. You can scale your jobs horizontally with minimal changes to your training script or hyperparameters.

3.2 Popular Deep Learning Frameworks

For more customized deep learning tasks, SageMaker provides first-class support for popular open-source frameworks:

  • TensorFlow

    • Offers a range of APIs (Keras, low-level ops) for building neural networks.
    • Leverages SageMaker’s distributed training libraries for data parallelism or model parallelism.
    • Provides integrated tools like TensorBoard for visualization and debugging.
  • PyTorch

    • Known for its dynamic computational graph, making it flexible and intuitive for research and experimentation.
    • Supports distributed training with native PyTorch libraries (e.g., torch.distributed) or third-party libraries like Horovod.
  • Apache MXNet

    • Offers both imperative and symbolic programming for neural networks.
    • Well-suited for large-scale, high-performance training across multiple GPUs.
  • Hugging Face Transformers

    • Specialized containers for training state-of-the-art NLP models (BERT, GPT, etc.).
    • Built-in support for distributed training with minimal code changes.

3.3 Bringing Your Own Framework or Container

If you have specialized requirements or prefer a framework that isn’t natively supported, SageMaker’s “bring your own container” approach lets you:

  • Customize the Environment: Install specific libraries, dependencies, or system packages needed for your model.
  • Retain Control Over Runtime: Define exactly how your code runs, while still benefiting from SageMaker’s distributed training features and integrations with AWS services.

With these varied options, Amazon SageMaker delivers the flexibility and scalability needed for virtually any machine learning task—ranging from classic supervised learning with pre-built algorithms to cutting-edge deep learning applications using TensorFlow or PyTorch at scale.


4. Distributed Training Architectures

When you scale deep learning to multiple GPUs or machines, you typically use one of two main parallelization strategies:

  1. Data Parallelism
  2. Model Parallelism

Both methods aim to accelerate training and handle bigger workloads than a single device can manage. However, they differ significantly in how you distribute the model and the data.

Data Parallelism

In data parallelism, each GPU (or node) keeps a full copy of the model weights. The dataset is split into chunks (mini-batches), and each GPU processes a different chunk of data in parallel:

  1. Forward Pass: Each GPU computes predictions (forward pass) on its subset of the data.
  2. Backward Pass: Each GPU computes gradients locally.
  3. Gradient Aggregation: The gradients from all GPUs are then averaged (or summed) and used to update the model weights so that each GPU stays synchronized.

When to Use It

  • When your model can fit into the memory of a single GPU, but you have a massive dataset.
  • When you want a simpler, more common approach that most ML frameworks (TensorFlow, PyTorch) natively support.

Advantages

  • Ease of Implementation: Well-supported by popular libraries (Horovod, native PyTorch/TensorFlow APIs).
  • Scalability: Works well for many tasks, especially when the model size is moderate but the dataset is large.

Challenges

  • Communication Overhead: As the number of GPUs grows, synchronizing gradients can become a bottleneck.
  • Diminishing Returns: Beyond a certain number of GPUs, the time spent aggregating updates can offset training speed gains.

Model Parallelism

In model parallelism, you partition the model itself across multiple GPUs. Each device holds a different slice of the model’s layers or parameters:

  1. Layer Partitioning: Some layers (or sub-layers) run on GPU 1, others on GPU 2, etc.
  2. Forward Pass: Outputs from each partition are passed as inputs to the next GPU.
  3. Backward Pass: Gradients flow back through the same partitions in reverse order.

When to Use It

  • When the model is too large to fit on a single GPU (e.g., large NLP transformers, cutting-edge vision architectures).
  • When memory consumption is the main bottleneck, even if the dataset isn’t huge.

Advantages

  • Training Larger Models: Makes it possible to handle models that exceed single-device memory limits.
  • Potential Speed Ups: Especially in tandem with data parallelism for a hybrid approach (pipeline or tensor parallelism).

Challenges

  • Implementation Complexity: You must carefully manage data transfers between GPUs, and debugging is harder.
  • Load Balancing: An uneven distribution of layers or operations can lead to idle GPUs, reducing overall efficiency.

Example Performance Comparison

In practice, data parallelism usually yields diminishing returns as you add more GPUs due to communication overhead. Model parallelism can help train massive models but requires more sophisticated orchestration.

This can be seen in the graph shared below:

Chart: Example Performance Comparison

The chart compares training time (in minutes) for hypothetical data parallel and model parallel approaches as you increase the number of GPUs. It’s a simplified illustration to show that both can reduce training time, but their effectiveness depends on how well they can scale with additional hardware.

Choosing the Right Approach

  • Data Parallelism is generally easier to set up. If your model fits on a single GPU and you just need to process large batches or large datasets faster, start here.
  • Model Parallelism is crucial when dealing with huge models that exceed GPU memory limits or when you want to push the boundaries of deep learning architectures.

In many large-scale training scenarios, practitioners use hybrid approaches (such as pipeline parallelism or tensor parallelism) that combine both data and model parallelism for maximum efficiency. Amazon SageMaker supports these strategies through built-in and custom distribution libraries, giving you flexibility in how you distribute both data and compute.

By understanding data parallelism vs. model parallelism—and knowing when each is most beneficial—you can better architect your training strategy for large-scale tasks.

5. Setting Up a Distributed Training Job

5.1 Prepare Your Training Script

  1. Select Your Framework

    • Decide whether you’ll use TensorFlow, PyTorch, or another deep learning framework.
    • For example, in PyTorch, you might rely on torch.distributed or Horovod to handle communication.
  2. Include Distributed Logic

    • Data Parallel Example: In PyTorch, initialize your process group (e.g., torch.distributed.init_process_group(backend='nccl')) and ensure you’re using a distributed data sampler that splits the dataset among GPUs.
    • Model Parallel Example: If your model is too large for a single GPU, use libraries like SageMaker’s model parallel library, Megatron-LM, or DeepSpeed to partition the model across GPUs.
  3. Handle I/O and Checkpoints

    • Read training and validation data from Amazon S3, Amazon FSx, or Amazon EFS.
    • Save checkpoints periodically so you can resume training if a job stops unexpectedly.

Best Practice

Make your training script stateless: Rely on external paths (usually S3) for data, model artifacts, and logs. This approach keeps your jobs more modular and robust.

5.2 Choose the Right Instance Types

  • GPU-Optimized Instances: For deep learning, popular families include ml.p3 (NVIDIA V100 GPUs) and ml.p4 (NVIDIA A100 GPUs).
  • Number of Instances:
    • Data Parallel: If the model fits on a single GPU but you have a large dataset, scaling out multiple instances can reduce training time.
    • Model Parallel: If the model is too large for one GPU, start by ensuring each “slice” of the model fits on its assigned GPU.
  • Spot Instances (Optional):
    • Spot Instances can cut costs but come with the risk of interruption. SageMaker can resume from checkpoints if configured correctly.

5.3 Configure an Estimator in SageMaker

Using the SageMaker Python SDK, define an Estimator (for built-in algorithms) or a Framework Estimator (for PyTorch, TensorFlow, MXNet, etc.):

import sagemaker
from sagemaker.pytorch import PyTorch

# Create a SageMaker session
sagemaker_session = sagemaker.Session()

# Define the estimator
estimator = PyTorch(
    entry_point='train.py',  # Your training script
    role='YourSageMakerExecutionRole',
    instance_count=4,  # e.g., 4 instances for distributed training
    instance_type='ml.p3.2xlarge',
    framework_version='1.12',  # Example PyTorch version
    py_version='py38',
    hyperparameters={
        'epochs': 10,
        'batch_size': 128,
        'learning_rate': 0.001
    },
    # Distribution configuration (data parallel, model parallel, etc.)
    distribution={
        'pytorchx': {
            'enabled': True,
            'processes_per_host': 1
        }
        # Or with custom libraries like Horovod, or model parallel libraries
    },
    sagemaker_session=sagemaker_session
)
Enter fullscreen mode Exit fullscreen mode
  • entry_point: The Python script that SageMaker runs on each instance.
  • instance_count and instance_type: Control how many compute resources are used.
  • hyperparameters: Tune batch size, learning rate, and other training parameters.
  • distribution: Enable distributed training settings (e.g., Horovod, native PyTorch distribution, or SageMaker’s model parallel library).

5.4 Point to the Training Data

Before launching your job, make sure your training data is uploaded to Amazon S3. You’ll pass these S3 paths to the fit method:

train_input = 's3://my-bucket/training-data/'
val_input   = 's3://my-bucket/validation-data/'

estimator.fit({
    'train': train_input,
    'validation': val_input
})
Enter fullscreen mode Exit fullscreen mode

SageMaker automatically downloads this data onto each instance when the job starts.

5.5 Monitor Training Jobs

  • CloudWatch Metrics: Track metrics like GPU utilization, CPU usage, and network throughput.
  • SageMaker Logs: Examine logs in near real-time to see progress, debug issues, or watch for NaN losses.
  • SageMaker Debugger: Optionally enable debugging to capture and analyze intermediate tensors.

5.6 Evaluate Results and Deploy

After the job finishes, SageMaker automatically saves model artefacts (e.g., model.tar.gz) to an S3 location specified in the estimator. You can:

  1. Download the model for local testing or further experimentation.
  2. Deploy to a SageMaker endpoint for real-time inference or to a batch transform job for offline predictions.

5.7 Cleanup

  • Stop/Remove Endpoints: If you created real-time endpoints for inference, remember to delete them after you’re done.
  • Terminate Idle Resources: Disable or remove any SageMaker notebooks or instances you no longer need.
  • Automate: Consider using AWS Auto Scaling, lifecycle configurations, and scheduled jobs to manage computing more efficiently.

Example Training Curve Comparison

Below is a hypothetical line chart illustrating accuracy vs. epoch for two scenarios:

  1. Single-Instance Training (slower training, may converge in fewer epochs if the batch size is small).
  2. Distributed Training (faster per-epoch, might see slightly different convergence patterns due to larger batch size or gradient synchronization).

This can be seen in the graph shared below:

Graph: Example Training Curve Comparison

Final Thoughts

By following these steps, you can easily scale out your training on Amazon SageMaker, whether you opt for data parallelism to handle large datasets or model parallelism to fit giant models. Managing your code, data sources, and hyperparameters through the SageMaker platform automates many tedious DevOps tasks—letting you focus on experimentation and model tuning.

Next, you can explore advanced MLOps features like Amazon SageMaker Pipelines, Model Monitor, or CI/CD integration to further streamline your workflow and ensure consistent, reliable deployments.


6. Leveraging Built-in Distributed Training Libraries

6.1 Parameter Server Architecture

A parameter server is a central process (or set of processes) that holds the global model parameters. Each worker node:

  1. Pulls the latest parameters from the server,
  2. Computes gradients on its subset of data,
  3. Pushes those gradients back to the parameter server.

Pros

  • Straightforward for moderate-scale data parallel approaches.
  • Easy to conceptualize how updates flow between servers and workers.

Cons

  • Potential bottleneck if many workers fight for the same server resource.
  • Not as scalable at very large cluster sizes compared to AllReduce-based libraries.

Use Cases

  • Traditional distributed ML workflows.
  • Situations where the dataset is easily partitioned and the model size is moderate.

How to Use Parameter Server on SageMaker

Below is an example of using TensorFlow with a parameter server setup in SageMaker:

from sagemaker.tensorflow import TensorFlow

estimator = TensorFlow(
    entry_point='train_tf_ps.py',            # Your training script
    role='YourSageMakerExecutionRole',
    instance_count=4,                        # e.g., 4 instances
    instance_type='ml.p3.2xlarge',
    framework_version='2.8',                 # Example TF version
    py_version='py39',
    hyperparameters={
        'epochs': 10,
        'batch_size': 128,
        'learning_rate': 0.001
    },
    distribution={
        'parameter_server': {
            'enabled': True
        }
    }
)

estimator.fit('s3://my-bucket/training-data/')
Enter fullscreen mode Exit fullscreen mode
  • distribution: Setting {'parameter_server': {'enabled': True}} activates the parameter server mode.
  • The training script (train_tf_ps.py) should be compatible with TensorFlow’s parameter server strategy (e.g., using tf.distribute.experimental.ParameterServerStrategy if needed).

6.2 Horovod (AllReduce-Based Approach)

Horovod, developed by Uber, uses an AllReduce strategy:

  • Each GPU has a full copy of the model.
  • Gradients are averaged across GPUs after each training step.

Pros

  • Excellent Scalability: Proven to scale to very large GPU clusters.
  • Framework-Agnostic: Works with TensorFlow, PyTorch, MXNet, etc.
  • Minimal Code Changes: Often just a few lines to initialize Horovod, wrap your optimizer, etc.

Cons

  • Network Bandwidth can become a bottleneck; requires high-performance interconnects for the best speed.
  • Some additional steps to set environment variables and initialize processes (SageMaker can handle much of this for you).

Use Cases

  • High-performance computing (HPC) clusters or multi-node GPU setups.
  • When you need maximum throughput on large datasets.

How to Use Horovod on SageMaker

When training with PyTorch and Horovod, for instance:

from sagemaker.pytorch import PyTorch

estimator = PyTorch(
    entry_point='train_horovod.py',          # Training script with Horovod logic
    role='YourSageMakerExecutionRole',
    instance_count=4,
    instance_type='ml.p3.2xlarge',
    framework_version='1.12',
    py_version='py38',
    hyperparameters={
        'epochs': 10,
        'batch_size': 128,
        'learning_rate': 0.001
    },
    distribution={
        'mpi': {
            'enabled': True,
            'processes_per_host': 1,
            # Optionally set custom MPI/Horovod settings
            'custom_mpi_options': '-x HOROVOD_FUSION_THRESHOLD=16777216'
        }
    }
)

estimator.fit('s3://my-bucket/training-data/')
Enter fullscreen mode Exit fullscreen mode
  • distribution.mpi.enabled: This tells SageMaker to spin up the cluster with Horovod-compatible settings.
  • In your train_horovod.py, you’ll typically initialize Horovod (horovod.init()) and wrap your optimizer with horovod.DistributedOptimizer(...).

6.3 DeepSpeed

DeepSpeed (by Microsoft) focuses on ultra-large model training by using advanced memory management strategies, such as ZeRO (Zero Redundancy Optimizer), which shards parameters, gradients, and optimizer states across multiple GPUs.

Pros

  • Train massive models well beyond single-GPU memory limits.
  • Highly efficient in terms of both speed and memory usage.

Cons

  • Learning Curve: More advanced features (pipeline parallel, ZeRO Infinity) can be complex.
  • Rapid releases may require frequent updates to your code.

Use Cases

  • Large-scale NLP (GPT, BERT variants), computer vision with huge parameter counts.
  • When you need to drastically reduce per-GPU memory usage.

How to Use DeepSpeed on SageMaker

Below is a PyTorch estimator example that enables DeepSpeed in SageMaker’s distribution configuration:

from sagemaker.pytorch import PyTorch

estimator = PyTorch(
    entry_point='train_deepspeed.py',   # Training script with DeepSpeed logic
    role='YourSageMakerExecutionRole',
    instance_count=4,
    instance_type='ml.p4d.24xlarge',    # Typically use high-end GPUs (A100)
    framework_version='1.12',
    py_version='py38',
    hyperparameters={
        'epochs': 5,
        'batch_size': 64,
        'learning_rate': 0.0001
    },
    distribution={
        'torch_distributed': {
            'enabled': True,
            'deepspeed_enabled': True  # Flag to enable DeepSpeed
            # Optionally specify DeepSpeed config file path, etc.
        }
    }
)

estimator.fit('s3://my-bucket/training-data/')
Enter fullscreen mode Exit fullscreen mode
  • distribution.torch_distributed.deepspeed_enabled: Tells SageMaker to initialize DeepSpeed.
  • In your train_deepspeed.py, you’ll configure DeepSpeed via a JSON config (e.g., ds_config.json) and integrate it with your PyTorch code (deepspeed.initialize(...)).

6.4 Other Approaches

  • PyTorch DistributedDataParallel (DDP)

    • Native PyTorch module using AllReduce for gradient synchronization.
    • If you don’t need Horovod’s cross-framework capabilities, this can be simpler.
  • SageMaker Data Parallel Library

    • Uses an optimized AllReduce under the hood, tailored for AWS infrastructure.
    • Minimal code changes if you’re already using PyTorch or TensorFlow with SageMaker.
  • TensorFlow MirroredStrategy

    • Native strategy for multi-GPU training on a single node.
    • For multi-node, combine with ParameterServerStrategy or use Horovod.

6.5 Comparisons

Below are some conceptual plots—not real benchmarks—to illustrate how these libraries might differ. Actual performance will depend on your specific environment.

Scalability with Increasing GPU Count

Shows training throughput (samples/sec) vs. the number of GPUs for each library.

Graph: Scalability with Increasing GPU Count

  • Parameter Server may hit network bottlenecks at high GPU counts.
  • Horovod and DeepSpeed can approach near-linear scaling under ideal network conditions.
  • DDP also scales well, though typically not as well as Horovod or DeepSpeed for multi-node setups.

Memory Usage for a Large Model

Shows GPU memory usage (GB) for training a large model with different libraries.

Graph: Memory Usage for a Large Model

  • Parameter Server and Horovod replicate the entire model on each GPU.
  • DeepSpeed can reduce per-GPU memory usage with ZeRO, allowing much larger model sizes.

Feature Comparison

Compares Ease of Use, Scalability, and Memory Efficiency on a 1–5 scale (5 = best).

Graph: Feature Comparison

  • Parameter Server: Medium ease of use, limited scalability, standard memory usage.
  • Horovod: High scalability, fairly easy to adopt, standard memory usage.
  • DeepSpeed: Exceptional for memory efficiency, great scalability, and moderate ease of use.
  • PyTorch DDP: Good overall, especially if your entire codebase is PyTorch-only.

6.6 Putting It All Together on SageMaker

By combining Amazon SageMaker’s managed infrastructure with these distributed libraries:

  1. Provision GPU clusters: Simply choose instance types (e.g., ml.p3.2xlarge, ml.p4d.24xlarge) and how many of them you want.
  2. Enable the right distribution: In the Estimator’s distribution dictionary, specify parameter_server, mpi (Horovod), torch_distributed (optionally enabling DeepSpeed), or your framework’s native strategy.
  3. Leverage advanced tooling:
    • SageMaker Debugger for analyzing gradients and spotting anomalies.
    • SageMaker Model Monitor and pipelines to automate MLOps tasks.
    • Spot Instances to reduce costs, combined with checkpointing to resume interrupted jobs.

Summarising a few Built-in Distributed Training Libraries

  1. Parameter Server: Easiest for moderate-scale data parallel setups, but can bottleneck at large scale.
  2. Horovod: Excellent for cross-framework AllReduce with near-linear scaling.
  3. DeepSpeed: Specialized in training ultra-large models efficiently, leveraging ZeRO optimization.
  4. PyTorch DDP and SageMaker Data Parallel: Great out-of-the-box options if you’re heavily invested in PyTorch or want AWS-optimized data parallel.
  5. Always align the library with your cluster size, model size, network capabilities, and team expertise.

With the right choice of distributed library, Amazon SageMaker helps you handle everything from moderate workloads to cutting-edge deep learning at scale—so you can iterate faster and tackle increasingly complex models and datasets.


7. Performance Tuning and Scaling Best Practices

In large-scale machine learning, raw computational power alone is not enough. Efficiently harnessing that power can drastically reduce training times and costs. This section highlights proven strategies for improving training performance in Amazon SageMaker, including GPU utilization techniques, resource monitoring, scaling approaches, and cost-performance trade-offs.

7.1 Optimize GPU Utilization

Your GPUs represent a significant portion of your training budget. Therefore, keeping them as busy as possible—by ensuring minimal idle time—can dramatically impact both speed and cost. The following subsections detail specific tactics to maximize GPU throughput, from data loading to mixed precision and beyond.

7.1.1 Data Loading Efficiency

Feeding data to the GPU quickly and efficiently is key to achieving high utilization. If your model spends too much time waiting for the next batch, you’ll leave precious GPU cycles on the table. Below are some ways to streamline data loading and preprocessing.

  1. Use Parallel/Asynchronous Data Loading

    • PyTorch: Increase num_workers in your DataLoader, so CPU threads can prepare batches while the GPU is training.
    • TensorFlow: Chain .shuffle(), .batch(), and .prefetch() in your tf.data pipelines to overlap I/O and compute.
  2. Avoid I/O Bottlenecks

    • High-Throughput Storage: If you’re training on large datasets, consider using Amazon FSx for Lustre or ephemeral NVMe SSDs for faster data access.
    • Optimized Data Formats: Use TFRecord (TensorFlow) or RecordIO (MXNet), or store multiple samples in single files to reduce overhead.

7.1.2 Mixed Precision Training

Leveraging half-precision (FP16 or BF16) is one of the most effective ways to speed up GPU-bound workloads—often doubling throughput without substantially affecting model accuracy.

  • Automatic Mixed Precision (AMP)
    • PyTorch: Use torch.cuda.amp to automatically scale between FP16 and FP32 operations.
    • TensorFlow: Enable tf.keras.mixed_precision.set_global_policy('mixed_float16').
  • Hardware Acceleration: Modern GPUs (V100, A100) include specialized tensor cores designed for half-precision operations.

7.1.3 Batch Size and Gradient Accumulation

Batch size determines how many samples you process in one forward/backward pass. The right batch size balances GPU memory constraints, convergence behaviour, and training speed.

  • Large Batches
    • Fewer synchronization points in distributed training = higher GPU utilization.
    • May require tuning your learning rate schedule to maintain convergence quality.
  • Gradient Accumulation
    • Accumulate gradients over several mini-batches before updating parameters, effectively simulating a larger batch size if GPU memory is limited.

7.1.4 Model Profiling and Debugging

Even if your data pipeline is efficient and you’ve employed mixed precision, subtle bottlenecks can still hide inside your model architecture or hyperparameters. Profiling helps you find and fix these hot spots.

  • SageMaker Debugger
    • Monitors internal tensors, detects issues like vanishing/exploding gradients, and logs anomalies.
  • Framework Profilers
    • PyTorch Profiler (torch.profiler) or TensorFlow Profiler (tf.profiler) let you measure kernel-level performance and see how much time each operation consumes.

7.2 Monitor Resource Usage

Once you’ve optimized for GPU utilization, the next step is to ensure you have visibility into how your resources—CPU, GPU, network, and memory—are being used. Proper monitoring helps you detect under-utilized systems or potential bottlenecks early.

  1. Amazon CloudWatch

    • GPU Metrics: Check memory usage, GPU utilization, and throughput.
    • Alerts: Automate alerts when key metrics dip below or exceed desired thresholds.
  2. SageMaker Logs & Debugger

    • Detailed Logs: Inspect training logs in near real-time.
    • Profiler Reports: Summaries of CPU, GPU, disk, and network usage to see if the training loop is balanced.

GPU Utilization Over Time

Graph: GPU Utilization Over Time

Explanation

  • Steady increases in utilization imply that data loading or synchronization is improving.
  • If utilization fluctuates drastically, investigate potential I/O or batch processing stalls.

7.3 Scale-Out Effectively

If you’ve maximized per-GPU efficiency, you can boost performance further by adding more machines or GPUs (i.e., horizontal scaling). However, scaling must be done judiciously to avoid wasted resources from communication overhead or poorly balanced workloads.

  1. Start Small, Scale Gradually

    • Validate your code and tune hyperparameters on a single instance.
    • Increase the instance count or GPU count progressively to find the sweet spot of speed vs. overhead.
  2. Choosing the Right Instance

    • GPU-Optimized: ml.p3 or ml.p4 for Tensor Core acceleration.
    • High-Bandwidth Networking: EFA (Elastic Fabric Adapter) can reduce inter-node communication latency.
  3. Spot Instances

    • Cut costs by 70–90% compared to On-Demand, but handle interruptions with checkpointing.
    • Particularly useful for large-scale experiments or iterative hyperparameter tuning.

Training Speed vs. Instance Count

Graph: Training Speed vs. Instance Count

Explanation

  • Early scaling often yields large gains; diminishing returns may appear beyond a certain cluster size.
  • Excessive communication overhead can flatten or even decrease performance gains at very high instance counts.

7.4 Balancing Performance vs. Cost

Organizations must weigh the cost of running larger or longer training jobs against the benefits of faster results or more accurate models. This section explores strategies to strike the right balance and get the most value from your AWS spend.

  1. Set Clear Budgets and Alerts

    • AWS Budgets/Cost Explorer: Track real-time spend and receive notifications.
    • Evaluate cost per training iteration to make informed decisions about scaling or advanced features.
  2. Mixed Precision + Spot Instances

    • Combining these two can drastically cut training times and costs with minimal risk.
    • Always checkpoint frequently to recover from spot interruptions.
  3. Hyperparameter Tuning and Early Stopping

    • SageMaker Automatic Model Tuning: Automates searching for optimal hyperparameters, so you don’t waste computing on unproductive settings.
    • Early Stopping: If validation metrics plateau, terminate training to save resources.

Cost vs. Training Time

Graph: Cost vs. Training Time

Explanation

  • Single On-Demand: Lower cost but much slower.
  • Multi On-Demand: Higher cost, faster completion.
  • Multi Spot: Some cost savings over Multi On-Demand, slightly longer time if spot interruptions occur.

Note:

  1. Optimize First: Before scaling horizontally, ensure you’re fully utilizing the GPUs you already have.
  2. Monitor Resources: Use CloudWatch, logs, and profiling tools to detect bottlenecks.
  3. Scale Carefully: Add more nodes/GPUs progressively to avoid excessive communication overhead.
  4. Manage Costs: Mix precision, use spot instances, and set budgets to get the best performance-to-cost ratio.

By applying these best practices—data loading efficiency, mixed precision, monitoring, scaling strategies, and cost management—you can significantly improve your distributed training performance on Amazon SageMaker and confidently tackle complex, large-scale machine learning challenges.


8. Cost Optimization Strategies

Running large-scale machine learning workloads can quickly rack up costs, especially when dealing with GPU-accelerated training on multiple instances. By leveraging AWS features like Spot Instances, AutoML, and additional optimizations, you can significantly reduce expenses without sacrificing model quality. In this section, we’ll outline several practical approaches to keep your budget in check.

8.1 Spot Instances

Spot Instances allow you to tap into unused Amazon EC2 capacity at steep discounts, often 70–90% cheaper than On-Demand pricing. The catch is that AWS can reclaim these instances when demand increases, so you must design your training jobs to handle interruptions gracefully.

  1. Checkpointing

    • Save Model State: Regularly save your model checkpoints to Amazon S3 so you can resume training if a Spot Instance is terminated.
    • Stateful Training Scripts: Ensure your training logic can pick up from the last checkpoint without re-initializing parameters.
  2. Interruption Handling

    • SageMaker Spot Training: In SageMaker Estimators, you can enable Spot training by setting train_use_spot_instances=True (in the Python SDK) and specifying train_max_wait to let SageMaker know how long it can wait for spot capacity.
    • Notifications: Optionally set up event notifications or CloudWatch alarms for interruption alerts.
  3. Cost vs. Stability

    • Blended Approach: You can mix Spot and On-Demand instances for a balance between cost savings and uninterrupted capacity.
    • Data Scientist Workflow: Spot Instances are especially useful for exploratory experiments and hyperparameter tuning, where occasional interruptions are acceptable.

Below is a conceptual bar chart comparing the total cost of training on On-Demand vs. Spot Instances (or a blend of both).

Graph: Spot vs. On-Demand Costs

Explanation

  • On-Demand: Predictable but more expensive.
  • Spot: Significantly cheaper but subject to interruptions.
  • Blend: Balances cost savings with reduced risk of capacity loss.

8.2 AutoML and Automated Tuning

Automated Machine Learning (AutoML) tools and SageMaker’s Automatic Model Tuning (a.k.a. hyperparameter tuning) can help you optimize model performance without manually running dozens of experiments. By systematically searching hyperparameter spaces or model architectures, you can avoid wasting GPU hours on less promising configurations.

  1. SageMaker Automatic Model Tuning (HPO)

    • Hyperparameter Ranges: Define a search space for parameters (e.g., learning rate, batch size).
    • Objective Metric: Specify which metric to optimize (accuracy, F1 score, etc.).
    • Stop Early: SageMaker automatically stops underperforming jobs to avoid wasted computing.
  2. AutoML Services

    • Amazon SageMaker Autopilot: Automatically builds, trains, and tunes ML models for tabular data.
    • Reduce Trial and Error: Let data scientists focus on feature engineering and data quality rather than model selection.
  3. Budget Controls

    • Max Number of Training Jobs: Enforce a limit so HPO doesn’t spin up too many experiments.
    • Parallel Training: Run multiple training jobs simultaneously if you have sufficient spot or on-demand capacity.

Below is a conceptual line chart showing how model accuracy might improve as more hyperparameter tuning jobs are complete. Beyond a certain point, returns may diminish.

Graph: Tuning Runs vs. Accuracy

Explanation

  • Early tuning rounds yield big accuracy gains.
  • Later rounds often show smaller improvements, so weigh the cost vs. the incremental accuracy.

8.3 Other Techniques

Beyond Spot Instances and AutoML, there are additional methods to trim costs while still meeting performance requirements.

  1. Batch or Offline Inference

    • Batch Transform: For large-scale inference, it’s cheaper to run short, high-capacity batch jobs rather than keeping endpoints live 24/7.
    • Serverless Inference (SageMaker Serverless Inference): No need to pay for idle GPU resources.
  2. CloudWatch Metrics & Budgets

    • Set Budgets: Monitor spending in near real-time and receive alerts if you approach certain cost thresholds.
    • Analyze Cost per Experiment: Combine your training metrics with cost metrics to decide which experiments are worth scaling up.
  3. Use Smaller Datasets or Sub-Sampling

    • For quick prototypes, train on a subset of data to iterate faster.
    • Once you’ve narrowed down architecture choices, scale to the full dataset.
  4. Lifecycle Configurations & Automated Shutdown

    • Notebook Lifecycle: Automatically shut down idle resources, like Jupyter notebooks or development endpoints, to avoid unnecessary charges.
    • Policy Scripts: Use AWS Lambda or cron jobs to turn off instances after a certain time of inactivity.

8.4 Putting It All Together

The below bar chart conceptually compares baseline costs (no optimization) against applying different layers of cost optimization—Spot, AutoML, and additional best practices.

Graph: Combined Impact of Multiple Strategies

Explanation

  • Baseline: Running on-demand without tuning or optimization is the most expensive.
  • Spot Only: Immediately lowers cost by half or more.
  • Spot + AutoML: You save time and money by avoiding unproductive hyperparameter trials.
  • All Strategies: Combining Spot, AutoML, and advanced best practices often yields the greatest cost-to-performance benefit.

By applying these cost optimization strategies, you can scale your machine learning experiments on Amazon SageMaker confidently, knowing you’re getting the most out of your budget without compromising on model performance.


9. Advanced Monitoring and Debugging

Training deep learning models at scale can be opaque and complex—especially when distributing workloads across multiple instances or GPUs. To maintain reliable, high-performance training pipelines, you need robust tools for logging, profiling, and diagnostics. This section explores how to gain deeper visibility using SageMaker Debugger, Amazon CloudWatch, and third-party solutions such as Prometheus and Grafana.

9.1 SageMaker Debugger

Amazon SageMaker Debugger is a built-in service that captures real-time metrics and tensors—ranging from gradient values to system-level resource usage. It provides automation hooks to detect anomalous behaviour early and helps you pinpoint performance bottlenecks or training instabilities.

  1. Tensor Collection & Analysis

    • Hook APIs: Automatically log weights, gradients, and other intermediate tensors during training.
    • Built-in Rules: SageMaker Debugger can flag issues like vanishing gradients, overfitting, or poor weight initialization.
  2. Configuring Debugger

    • Estimator Parameters: In the SageMaker Python SDK, you can set debugger_hook_config to enable or disable specific collections.
    • Zero-Code Configuration: For many common frameworks (TensorFlow, PyTorch, MXNet), Debugger can be enabled with minimal code changes.
  3. Visualization & Analysis

    • Studio Integration: SageMaker Studio’s Debugger pane shows real-time plots of gradients, loss, or system metrics.
    • Offline Analysis: Download captured tensors to analyze locally using Python notebooks.

Example Code: Enabling Debugger in a PyTorch Estimator

from sagemaker.pytorch import PyTorch
from sagemaker.debugger import DebuggerHookConfig, CollectionConfig

debugger_config = DebuggerHookConfig(
    s3_output_path='s3://my-bucket/debug-output/',  # Where logs will be saved
    collection_configs=[
        CollectionConfig(name="gradients"),
        CollectionConfig(name="weights")
    ]
)

estimator = PyTorch(
    entry_point='train.py',
    role='YourSageMakerExecutionRole',
    instance_count=2,
    instance_type='ml.p3.2xlarge',
    framework_version='1.12',
    py_version='py38',
    debugger_hook_config=debugger_config
)

estimator.fit('s3://my-bucket/training-data/')
Enter fullscreen mode Exit fullscreen mode

9.2 Amazon CloudWatch

CloudWatch is AWS’s central logging and monitoring service, capturing system and application metrics in near real-time. While SageMaker Debugger focuses on ML-specific artefacts, CloudWatch covers broader infrastructure-level metrics—like CPU/GPU utilization, memory usage, disk I/O, and networking.

  1. Custom Metrics

    • Application Logs: Automatically sent to CloudWatch if using SageMaker’s default logging setup.
    • Custom Events: You can emit your own metrics (e.g., training accuracy or loss) using the CloudWatch API or AWS SDK calls within your script.
  2. CloudWatch Alarms

    • Threshold Alerts: If GPU utilization drops below a certain percentage or memory usage spikes above a threshold, CloudWatch can trigger alarms.
    • Auto Scaling: Tie CloudWatch metrics to scale up or down your training or inference clusters automatically.
  3. Integration with Other AWS Services

    • SNS Notifications: Receive email or SMS when alarms trigger.
    • CloudWatch Dashboards: Build custom dashboards to visualize key metrics over time.

Graph: Example of Logging GPU Utilization from CloudWatch

Explanation

  • Time: Could represent hours or specific timestamps.
  • GPU Utilization: High, sustained usage generally indicates efficient pipeline flow. Spikes or dips may prompt deeper Debugger-level investigations.

9.3 Third-Party Monitoring & Profiling Tools

For teams that want additional customization or already have established observability stacks, third-party tools like Prometheus, Grafana, Datadog, and NVIDIA Nsight Systems can augment or replace built-in AWS services.

  1. Prometheus & Grafana

    • Prometheus: Collects time-series data via exporters running on your training nodes.
    • Grafana: Visualizes metrics in customizable dashboards, letting you correlate GPU usage, training loss, and system events in a single pane.
  2. Datadog & Other SaaS Monitoring

    • Platform Integration: Many enterprises standardize on one SaaS solution for logs, metrics, and alerts.
    • AWS Integration: Official or community-built integrations can pipe CloudWatch or SageMaker logs directly into Datadog or Splunk.
  3. NVIDIA Nsight Systems or CUPTI

    • GPU Kernel-Level Profiling: Identify inefficiencies in CUDA kernels, memory transfers, or hardware usage.
    • Detailed Analysis: Most relevant if you’re dealing with highly specialized kernels or optimizing low-level GPU operations.

Graph: Example GPU Memory & Compute Profiling

Explanation

  • GPU Memory (GB): Helps you see if you’re nearing hardware limits or have headroom to increase batch sizes.
  • GPU Compute (%): Tracks how actively GPU cores are utilized. If memory usage is high but computing is low, you may have room for optimization.

9.4 Putting It All Together

Combining SageMaker Debugger, CloudWatch, and third-party tools can give you a full-stack view of your training jobs—from the model’s internal states to the system and hardware metrics. By correlating these insights, you can quickly identify the root causes of performance bottlenecks, training errors, or resource under-utilization.

Graph: Correlating ML Metrics with System Metrics

Explanation

  • Accuracy climbs as epochs progress, while GPU usage also increases, indicating more intensive computing.
  • CPU usage rises more moderately, suggesting a balanced data-loading pipeline.

With these advanced monitoring and debugging practices—from SageMaker Debugger to external profiling tools—you’ll gain a holistic understanding of your training workflows, enabling faster troubleshooting and continual performance improvements.


10. Case Studies and Real-World Examples

Picture this: You’re part of a global streaming platform, offering millions of songs, movies, and podcasts to users around the world. Data on listening habits, watch times, and content interactions stream every second. You need to train massive recommendation models to keep users engaged:

  1. Global Media & Entertainment Recommender Systems
    • Scenario: Multi-language content with billions of user-item interactions.
    • Distributed Setup: Large clusters of ml.p4 instances, each handling a shard of user data; data parallelism speeds up training on this colossal dataset.
    • Outcome: Training cycles shrink from days to hours, allowing more frequent updates to recommendation models—so users always see fresh, personalized content.

Next, imagine a financial services firm struggling with escalating fraud cases. Billions of credit card and digital wallet transactions pass through their systems daily:

  1. Financial Fraud Detection
    • Scenario: Highly complex, evolving fraud patterns in real-time transaction data.
    • Distributed Setup: Data parallel training on multiple GPU nodes using built-in algorithms (like XGBoost) or deep learning frameworks.
    • Outcome: Rapid detection models updated hourly or daily, drastically reducing fraud losses and improving customer trust.

Now, you pivot to the energy sector, where power grids span entire continents. Meter readings, weather data, and historical consumption trends pile up every minute:

  1. Energy Demand Forecasting
    • Scenario: Terabytes of time-series data from IoT sensors and utility usage logs.
    • Distributed Setup: Large-scale time-series forecasting with SageMaker’s data parallel library, optionally combining model parallelism for more advanced architectures.
    • Outcome: Predictive models that can train on the full dataset in record time, helping operators optimize resource allocation and minimize blackouts.

Then, picture yourself at a biotech startup, using AI to screen new drug candidates. Each simulation involves enormous molecular datasets and 3D protein structures:

  1. Pharmaceutical & Genomics Research
    • Scenario: Protein folding simulations, gene expression analysis, and large-scale molecular modelling.
    • Distributed Setup: Horovod or DeepSpeed on ml.p4d.24xlarge instances, enabling data parallelism and, for truly huge models, model parallelism.
    • Outcome: Weeks of lab experimentation replaced by days of in silico testing—dramatically accelerating drug discovery pipelines.

You then join a software-as-a-service (SaaS) provider specializing in AutoML. Customers submit massive datasets for automated feature engineering and model tuning:

  1. SaaS AutoML Platform
    • Scenario: Thousands of parallel hyperparameter tuning jobs, each with potentially huge datasets.
    • Distributed Setup: SageMaker-managed training clusters that spin up and down on demand, using Spot Instances to keep costs low.
    • Outcome: Speedy automation that handles concurrent users worldwide, delivering optimized models faster and more cost-effectively.

Finally, you shift to an educational technology (EdTech) startup, where personalized learning paths are key. Real-time engagement data from millions of students arrives constantly:

  1. EdTech Personalized Learning
    • Scenario: Tracking student progress, quiz scores, and video interactions to adapt learning content in real-time.
    • Distributed Setup: A multi-instance training job that continuously refreshes predictive models, ensuring immediate adaptation to each learner’s needs.
    • Outcome: Improved student outcomes as the platform rapidly iterates on new teaching strategies and content recommendations.

Conclusion and Future Outlook

Reflect on everything: You’ve seen how data parallelism, model parallelism, and intelligent cost management can drastically speed up and scale out deep learning workloads on Amazon SageMaker. From e-commerce personalization to advanced genomics research, teams are harnessing SageMaker’s distributed training capabilities to solve both “big data” and “big model” challenges.

  1. Key Takeaways

    • Managed Infrastructure: SageMaker abstracts away much of the DevOps complexity, letting data scientists focus on innovation.
    • Flexibility: Multiple frameworks (TensorFlow, PyTorch) and distribution libraries (Horovod, DeepSpeed, native DDP) let you tailor solutions to your exact needs.
    • Cost Optimization: Spot Instances, auto-scaling, and advanced monitoring ensure efficiency without sacrificing performance.
    • Visibility & Debugging: Tools like SageMaker Debugger and CloudWatch provide deep insights, making large-scale training more transparent and maintainable.
  2. Emerging Trends

    • Ultra-Large Models: With the rise of multi-billion-parameter models in NLP, CV, and beyond, model parallelism and memory-optimized hardware will only become more crucial.
    • Serverless ML: As serverless paradigms expand, expect even more seamless provisioning, where distributed training dynamically scales up—and back down—without manual intervention.
    • Edge & Federated Learning: Hybrid setups that combine centralized training with edge-based data gathering or partial training will push the boundaries of distributed strategies.
    • Low-Code/No-Code AI: Simplified user interfaces for distributed training will lower the barrier to entry, enabling data analysts (not just ML experts) to run large-scale jobs confidently.

Looking ahead, Amazon SageMaker aims to keep driving down costs and complexity while pushing model size and performance ever higher. By staying informed about new instance types, distributed libraries, and automated features, you’ll ensure your organization remains at the forefront of large-scale machine learning—ready to tackle the next wave of innovation.

Disclaimer: ChatGPT was used to enhance the language and flow of this article.

Top comments (1)

Collapse
 
jasondunn profile image
Jason Dunn [AWS]

Wow, what a great amount of detail in this article! Well done.