DEV Community

Muhammad Umair Ashraf
Muhammad Umair Ashraf

Posted on

AWS PyTorch: Build, Train, and Deploy Deep Learning Models in the Cloud

PyTorch makes it easier to experiment with neural networks, computer vision, natural language processing, and deep learning.

But building a model is only one part of a machine learning project.

When it's time to move from experimentation to production, you need reliable compute, data storage, repeatable training, model artifacts, deployment, monitoring, and cost controls.

This is where AWS can help.

By combining PyTorch, Amazon SageMaker AI, Amazon S3, and Amazon CloudWatch, developers can build machine learning workflows that move from local experiments toward scalable cloud deployments.

In this article, we'll build a simple image classifier and explore how to extend the project into an AWS-based machine learning pipeline.

1. What Is PyTorch on AWS?

PyTorch is an open-source deep learning framework that provides tensor operations, automatic differentiation, GPU acceleration, and tools for creating neural networks.

AWS provides several services that can support PyTorch workloads:

  • Amazon SageMaker AI: Run managed training jobs and deploy machine learning models.
  • Amazon S3: Store datasets, model artifacts, and training outputs.
  • Amazon EC2: Run PyTorch on virtual machines, including suitable GPU instances.
  • AWS Deep Learning Containers: Use supported, preconfigured machine learning environments.
  • Amazon CloudWatch: Monitor supported metrics, logs, and application behavior.
  • AWS IAM: Control access to training data, infrastructure, and model artifacts.

You don't need all these services for every project. Start with what your workload requires and add complexity when it provides a clear benefit.

2. Understand the Architecture

A typical workflow looks like this:

        Training Dataset
               |
               v
         Amazon S3
               |
               v
      Amazon SageMaker AI
          Training Job
               |
               v
         PyTorch Model
               |
               v
       Model Artifacts in S3
               |
               v
       Deployment / Inference
               |
               v
       Application Predictions
Enter fullscreen mode Exit fullscreen mode

Amazon S3 provides durable storage for datasets and artifacts. SageMaker AI can run managed training jobs, while a suitable inference service can expose the trained model to applications.

CloudWatch and related AWS monitoring capabilities help you investigate failures, latency, and resource usage.

For small experiments, you can train locally first. For larger workloads, managed training can reduce infrastructure-management overhead.

3. Hands-On Project: Build a Digit Classifier

We'll train a small neural network on the MNIST handwritten-digit dataset.

Our model will learn to classify grayscale images into one of ten categories, representing the digits from 0 to 9.

Prerequisites

You'll need:

  • Python 3.
  • Basic Python knowledge.
  • An internet connection to download the dataset.
  • An AWS account only when you move to the cloud steps.

The first part runs locally and does not require AWS resources.

Step 1: Create a project environment

Create a project directory and enter it:

mkdir aws-pytorch-demo
cd aws-pytorch-demo
python -m venv .venv
Enter fullscreen mode Exit fullscreen mode

Activate the virtual environment on Windows:

.venv\Scripts\Activate.ps1
Enter fullscreen mode Exit fullscreen mode

On Linux or macOS:

source .venv/bin/activate
Enter fullscreen mode Exit fullscreen mode

Install the dependencies:

pip install torch torchvision
Enter fullscreen mode Exit fullscreen mode

For GPU training, install a PyTorch build compatible with your GPU and CUDA configuration. Follow the official installation instructions: https://pytorch.org/get-started/locally/.

Step 2: Create the training script

Create train.py:

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

device = torch.device(
    "cuda" if torch.cuda.is_available() else "cpu"
)

print(f"Training device: {device}")

transform = transforms.ToTensor()

train_data = datasets.MNIST(
    root="data",
    train=True,
    download=True,
    transform=transform,
)

test_data = datasets.MNIST(
    root="data",
    train=False,
    download=True,
    transform=transform,
)

train_loader = DataLoader(
    train_data,
    batch_size=64,
    shuffle=True,
)

test_loader = DataLoader(
    test_data,
    batch_size=256,
    shuffle=False,
)


class DigitClassifier(nn.Module):
    def __init__(self):
        super().__init__()

        self.network = nn.Sequential(
            nn.Flatten(),
            nn.Linear(28 * 28, 128),
            nn.ReLU(),
            nn.Linear(128, 10),
        )

    def forward(self, x):
        return self.network(x)


model = DigitClassifier().to(device)

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(
    model.parameters(),
    lr=0.001,
)

# Training loop
for epoch in range(3):
    model.train()
    total_loss = 0.0

    for images, labels in train_loader:
        images = images.to(device)
        labels = labels.to(device)

        optimizer.zero_grad()

        outputs = model(images)
        loss = criterion(outputs, labels)

        loss.backward()
        optimizer.step()

        total_loss += loss.item()

    average_loss = total_loss / len(train_loader)

    print(
        f"Epoch {epoch + 1}/3, "
        f"Loss: {average_loss:.4f}"
    )

# Evaluation
model.eval()
correct = 0
total = 0

with torch.no_grad():
    for images, labels in test_loader:
        images = images.to(device)
        labels = labels.to(device)

        outputs = model(images)
        predictions = outputs.argmax(dim=1)

        correct += (predictions == labels).sum().item()
        total += labels.size(0)

accuracy = 100 * correct / total
print(f"Test accuracy: {accuracy:.2f}%")

# Save model parameters
torch.save(
    model.state_dict(),
    "digit_classifier.pth",
)

print("Saved digit_classifier.pth")
Enter fullscreen mode Exit fullscreen mode

Step 3: Train the model

Run:

python train.py
Enter fullscreen mode Exit fullscreen mode

The script downloads MNIST, trains the neural network, evaluates it against the test dataset, and saves the learned parameters.

Your output should include:

Training device: cpu
Epoch 1/3, Loss: ...
Epoch 2/3, Loss: ...
Epoch 3/3, Loss: ...
Test accuracy: ...
Saved digit_classifier.pth
Enter fullscreen mode Exit fullscreen mode

The loss and accuracy values depend on the training run. If a compatible GPU is available, the script can use it automatically.

Step 4: Make a prediction

Create predict.py:

import torch
from torch import nn
from torchvision import datasets, transforms


class DigitClassifier(nn.Module):
    def __init__(self):
        super().__init__()

        self.network = nn.Sequential(
            nn.Flatten(),
            nn.Linear(28 * 28, 128),
            nn.ReLU(),
            nn.Linear(128, 10),
        )

    def forward(self, x):
        return self.network(x)


device = torch.device(
    "cuda" if torch.cuda.is_available() else "cpu"
)

model = DigitClassifier().to(device)

state = torch.load(
    "digit_classifier.pth",
    map_location=device,
    weights_only=True,
)

model.load_state_dict(state)
model.eval()

dataset = datasets.MNIST(
    root="data",
    train=False,
    download=True,
    transform=transforms.ToTensor(),
)

image, actual_label = dataset[0]

with torch.no_grad():
    logits = model(image.unsqueeze(0).to(device))
    predicted_label = logits.argmax(dim=1).item()

print(f"Predicted digit: {predicted_label}")
print(f"Actual digit: {actual_label}")
Enter fullscreen mode Exit fullscreen mode

Run the prediction:

python predict.py
Enter fullscreen mode Exit fullscreen mode

Example output:

Predicted digit: 7
Actual digit: 7
Enter fullscreen mode Exit fullscreen mode

These values are illustrative. The actual result depends on your trained model.

You now have a basic end-to-end deep learning workflow: train, evaluate, save, reload, and predict.

4. Move the Project to AWS

Once the model works locally, you can move the workflow to AWS.

Step 1: Create an S3 bucket

Choose a globally unique bucket name:

aws s3 mb s3://YOUR-UNIQUE-PYTORCH-BUCKET \
  --region us-east-1
Enter fullscreen mode Exit fullscreen mode

Replace the placeholder with your actual bucket name.

Upload the training script:

aws s3 cp train.py \
  s3://YOUR-UNIQUE-PYTORCH-BUCKET/code/train.py
Enter fullscreen mode Exit fullscreen mode

For this example, the script downloads MNIST directly. A production pipeline should manage dataset preparation, storage, and versioning more explicitly.

Step 2: Run training with SageMaker AI

Amazon SageMaker AI supports PyTorch training jobs using supported framework environments and training configurations.

At a high level, you need to:

  1. Configure an execution role with appropriate permissions.
  2. Prepare your training script and dependencies.
  3. Select a supported PyTorch environment.
  4. Configure the training input and output locations.
  5. Choose an appropriate instance type.
  6. Set runtime limits and launch the job.
  7. Review the training logs and saved artifacts.

Use the current official guide for the SDK version you install:

https://docs.aws.amazon.com/sagemaker/latest/dg/pytorch.html

SageMaker SDK interfaces evolve, so use examples matching your installed SDK version rather than mixing older estimator APIs with newer SDK workflows.

Step 3: Store model artifacts in S3

For a locally trained model, you can upload the saved parameters:

aws s3 cp digit_classifier.pth \
  s3://YOUR-UNIQUE-PYTORCH-BUCKET/models/digit_classifier.pth
Enter fullscreen mode Exit fullscreen mode

For a managed training job, configure the output location so SageMaker AI saves the model artifacts automatically.

Keep a record of the dataset version, source-code version, training parameters, framework version, and evaluation metrics. This makes it easier to reproduce and audit experiments.

5. Deploy the Model for Inference

Training and inference are separate stages.

For an application to request predictions, you need a serving interface that loads the model, validates input, executes inference, and returns a response.

With Amazon SageMaker AI, you can deploy supported PyTorch models to a managed endpoint. The required model packaging and inference code depend on the selected deployment approach.

A typical inference flow is:

  1. Load the approved model artifact.
  2. Convert the input into the tensor format expected by the model.
  3. Run the model in evaluation mode.
  4. Convert the output into a response your application can consume.
  5. Log relevant errors and operational metrics.

For the MNIST model, input should represent a grayscale image with dimensions of 28 × 28 pixels. Validate the request before running inference.

For workloads that don't need immediate responses, consider batch inference instead of keeping an online endpoint available continuously.

6. Production Best Practices

A model that works locally isn't automatically production-ready.

Cost optimization

  • Start with CPU training for small models when practical.
  • Use GPU instances when benchmarks show a meaningful benefit.
  • Set job time limits.
  • Stop endpoints and compute resources when they are no longer required.
  • Evaluate batch inference for offline workloads.
  • Include storage, logging, data transfer, and supporting services in cost estimates.

Security

  • Apply least-privilege IAM policies.
  • Keep S3 buckets private.
  • Encrypt sensitive datasets and artifacts.
  • Avoid embedding credentials in source code.
  • Restrict access to training data and deployed models.

Reproducibility

Track dataset versions, dependencies, training parameters, random seeds, and model artifacts. Store code in version control and preserve evaluation results for each model version.

Monitoring

Monitor training failures, compute utilization, inference latency, and application errors using supported AWS monitoring capabilities.

Also evaluate model quality over time. A service can remain operational while its predictions become less accurate because real-world data has changed.

Model evaluation

Don't rely on training loss alone.

For classification tasks, consider precision, recall, F1 score, confusion matrices, and performance on representative held-out data. Select metrics based on the real business problem.

7. Where Can You Use PyTorch on AWS?

Common applications include:

  • Computer vision: Image classification and defect detection.
  • Natural language processing: Text classification and domain-specific model fine-tuning.
  • Recommendation systems: Ranking and personalization.
  • Forecasting: Demand prediction and time-series analysis.
  • Generative AI: Training or fine-tuning compatible neural network models.

For large-scale distributed training, additional planning is needed for GPU memory, network communication, checkpointing, and data loading.

Final Thoughts

PyTorch provides the flexibility to build deep learning models, while AWS offers several ways to run training workloads, store model artifacts, and deploy predictions.

Start with a small experiment, validate the results, and then introduce cloud infrastructure where it provides measurable value.

The real goal is not just to train a model in the cloud. It's to create a secure, reproducible, observable machine learning workflow that can grow with your application.

Official Resources

AWS #PyTorch #MachineLearning #DeepLearning #AmazonSageMaker

Top comments (0)