Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›Creating Own LLM›Choosing the Right Hardware: GPUs, TPUs, and Cloud Resources

Building and Training Your Own LLM

Choosing the Right Hardware: GPUs, TPUs, and Cloud Resources

This lesson explains the hardware options for training and deploying large language models (LLMs), focusing on GPUs, TPUs, and cloud resources. Understanding these choices is critical because the wrong hardware can lead to excessive costs, slow training, or even project failure. You’ll reach for this knowledge when planning your LLM’s infrastructure, whether for small-scale experiments or large-scale production.

Why Hardware Matters for LLMs

Large language models are computationally intensive, requiring massive parallel processing to train efficiently. The hardware you choose directly impacts training time, cost, and model performance. For example, training a 7-billion-parameter model on a single CPU could take years, while a modern GPU or TPU can reduce this to days or weeks. The key factors to consider are memory bandwidth, parallel processing capabilities, and cost efficiency. Memory bandwidth determines how quickly data can be fed to the processor, while parallel processing allows the model to handle thousands of operations simultaneously. Cost efficiency ensures you’re not overspending on hardware that doesn’t align with your project’s scale. By understanding these principles, you can reason about hardware choices even for models or use cases not explicitly covered here, such as edge deployment or distributed training.

# Example: Checking GPU memory bandwidth (NVIDIA GPU)
import torch

def check_gpu_bandwidth():
    # Create a large tensor to measure memory bandwidth
    size = 1024 * 1024 * 100  # 100MB
    x = torch.rand(size, device='cuda')
    y = torch.rand(size, device='cuda')
    
    # Warm-up
    for _ in range(10):
        z = x + y
    
    # Measure bandwidth
    start_event = torch.cuda.Event(enable_timing=True)
    end_event = torch.cuda.Event(enable_timing=True)
    start_event.record()
    z = x + y
    end_event.record()
    torch.cuda.synchronize()
    
    elapsed_time = start_event.elapsed_time(end_event) / 1000  # Convert to seconds
    bandwidth = (size * 4 * 2) / elapsed_time / (1024 ** 3)  # GB/s (float32 = 4 bytes)
    print(f"GPU Memory Bandwidth: {bandwidth:.2f} GB/s")

check_gpu_bandwidth()

GPUs: The Workhorse of LLM Training

Graphics Processing Units (GPUs) are the most common choice for training LLMs due to their balance of performance, flexibility, and accessibility. GPUs excel at parallel processing, which is essential for the matrix multiplications that dominate LLM training. Modern GPUs, like NVIDIA’s A100 or H100, offer high memory bandwidth and large memory capacities (up to 80GB), making them suitable for models with billions of parameters. They also support mixed-precision training, which reduces memory usage and speeds up training without sacrificing model quality. However, GPUs can be expensive, especially for large-scale training, and their power consumption can add to operational costs. When choosing a GPU, consider the model size, batch size, and whether you’ll use distributed training. For example, a single A100 can handle a 7B-parameter model, but larger models may require multiple GPUs or even GPU clusters.

# Example: Profiling GPU memory usage for a small LLM
import torch
from transformers import AutoModelForCausalLM

def profile_gpu_memory(model_name="gpt2"):
    # Load a small LLM and move it to GPU
    model = AutoModelForCausalLM.from_pretrained(model_name).to("cuda")
    
    # Check GPU memory usage
    print(f"Model: {model_name}")
    print(f"GPU Memory Allocated: {torch.cuda.memory_allocated() / (1024 ** 3):.2f} GB")
    print(f"GPU Memory Reserved: {torch.cuda.memory_reserved() / (1024 ** 3):.2f} GB")
    
    # Clean up
    del model
    torch.cuda.empty_cache()

profile_gpu_memory()

TPUs: Google’s Specialized Accelerators

Tensor Processing Units (TPUs) are custom-designed accelerators developed by Google for machine learning workloads. Unlike GPUs, which are general-purpose, TPUs are optimized specifically for tensor operations, making them highly efficient for training large models. TPUs offer high memory bandwidth and are designed to work seamlessly with Google’s TensorFlow framework, though they can also be used with PyTorch via libraries like JAX. One of the key advantages of TPUs is their scalability: Google’s TPU pods can scale to thousands of chips, making them ideal for training massive models like PaLM or T5. However, TPUs are less flexible than GPUs and may not support all operations or frameworks out of the box. They are also primarily available through Google Cloud, which can limit their accessibility. When considering TPUs, evaluate whether your model and framework are compatible and whether the cost savings justify the reduced flexibility.

# Example: Running a simple model on TPU (using JAX)
import jax
import jax.numpy as jnp
from jax import random

def run_on_tpu():
    # Check if TPU is available
    try:
        devices = jax.devices("tpu")
        print(f"TPU devices found: {devices}")
    except:
        print("TPU not available, running on CPU")
        devices = jax.devices("cpu")
    
    # Create a simple matrix multiplication
    key = random.PRNGKey(0)
    x = random.normal(key, (1024, 1024))
    y = random.normal(key, (1024, 1024))
    
    # Run on TPU/CPU
    z = jnp.dot(x, y)
    print(f"Result shape: {z.shape}")
    print(f"Device used: {z.device()}")

run_on_tpu()

Cloud vs. On-Premises: Cost and Flexibility

Choosing between cloud and on-premises hardware depends on your budget, scalability needs, and long-term goals. Cloud resources, like AWS, Google Cloud, or Azure, offer flexibility and scalability, allowing you to rent hardware on-demand and avoid upfront costs. This is ideal for small teams or projects with variable workloads, as you can scale up or down as needed. However, cloud costs can add up quickly, especially for long-term training jobs. On-premises hardware, on the other hand, requires a significant upfront investment but can be more cost-effective for large-scale or long-term projects. It also gives you full control over your infrastructure, which can be important for security or compliance reasons. When deciding, consider factors like cost per hour, data transfer costs, and whether you need specialized hardware like TPUs. For example, training a 13B-parameter model on the cloud might cost thousands of dollars per week, while purchasing GPUs upfront could save money in the long run.

# Example: Estimating cloud costs for LLM training (AWS)
import math

def estimate_cloud_costs(model_size_billion=7, training_hours=100, gpu_type="p4d.24xlarge"):
    # AWS pricing (as of 2023, us-east-1)
    pricing = {
        "p4d.24xlarge": 32.77,  # $32.77/hour for A100 GPU instance
        "p3.2xlarge": 3.06,     # $3.06/hour for V100 GPU instance
    }
    
    # Estimate number of GPUs needed (rule of thumb: 1 GPU per 1B parameters)
    gpus_needed = math.ceil(model_size_billion / 1)
    
    # Calculate cost
    hourly_cost = pricing.get(gpu_type, 0) * gpus_needed
    total_cost = hourly_cost * training_hours
    
    print(f"Model size: {model_size_billion}B parameters")
    print(f"GPU type: {gpu_type}")
    print(f"GPUs needed: {gpus_needed}")
    print(f"Hourly cost: ${hourly_cost:.2f}")
    print(f"Total cost for {training_hours} hours: ${total_cost:.2f}")

estimate_cloud_costs()

Distributed Training: Scaling Beyond a Single Machine

For very large models or datasets, a single GPU or TPU may not be sufficient, and you’ll need to use distributed training. Distributed training involves splitting the model or data across multiple devices or machines, allowing you to train larger models faster. There are two main approaches: data parallelism and model parallelism. Data parallelism splits the dataset across devices, with each device holding a copy of the model and synchronizing gradients. This is simple to implement but requires high-speed interconnects to avoid bottlenecks. Model parallelism splits the model itself across devices, which is more complex but necessary for models too large to fit on a single device. Frameworks like PyTorch and TensorFlow provide built-in support for distributed training, but you’ll need to consider factors like communication overhead, fault tolerance, and hardware compatibility. For example, training a 175B-parameter model like GPT-3 requires model parallelism and hundreds of GPUs, while a 7B-parameter model can often be trained with data parallelism on a handful of GPUs.

# Example: Data parallel training with PyTorch
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

def data_parallel_training():
    # Check for multiple GPUs
    if torch.cuda.device_count() < 2:
        print("This example requires at least 2 GPUs")
        return
    
    # Create a simple model
    model = nn.Sequential(
        nn.Linear(1024, 512),
        nn.ReLU(),
        nn.Linear(512, 10)
    )
    
    # Wrap model with DataParallel
    model = nn.DataParallel(model).cuda()
    
    # Create dummy data
    x = torch.randn(1000, 1024)
    y = torch.randint(0, 10, (1000,))
    dataset = TensorDataset(x, y)
    dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
    
    # Training loop
    optimizer = optim.Adam(model.parameters())
    criterion = nn.CrossEntropyLoss()
    
    for epoch in range(2):
        for batch_x, batch_y in dataloader:
            batch_x, batch_y = batch_x.cuda(), batch_y.cuda()
            optimizer.zero_grad()
            outputs = model(batch_x)
            loss = criterion(outputs, batch_y)
            loss.backward()
            optimizer.step()
        print(f"Epoch {epoch + 1}, Loss: {loss.item():.4f}")

data_parallel_training()

Key points

  • Hardware choice directly impacts training time, cost, and model performance, so it’s critical to align your selection with your project’s scale and goals.
  • GPUs are the most flexible and widely used hardware for LLM training, offering a balance of performance, memory capacity, and support for mixed-precision training.
  • TPUs are specialized accelerators optimized for tensor operations, making them highly efficient for large-scale training but less flexible than GPUs.
  • Cloud resources provide scalability and flexibility, allowing you to rent hardware on-demand, but long-term costs can exceed on-premises solutions for large projects.
  • On-premises hardware requires significant upfront investment but can be more cost-effective for long-term or large-scale training, especially if you need full control over your infrastructure.
  • Distributed training is necessary for very large models or datasets, and it can be implemented using data parallelism or model parallelism, depending on your hardware and model size.
  • Memory bandwidth and parallel processing capabilities are key factors in hardware performance, as they determine how quickly data can be processed during training.
  • Always profile your model’s memory and compute requirements before selecting hardware, as underestimating these can lead to training failures or excessive costs.

Common mistakes

  • Mistake: Choosing a GPU solely based on high VRAM without considering memory bandwidth. Why it's wrong: High VRAM alone doesn't guarantee performance if the memory bandwidth is insufficient for LLM training/inference. Fix: Prioritize GPUs with high memory bandwidth (e.g., H100's 3TB/s) to match the model's compute needs.
  • Mistake: Assuming TPUs are always better than GPUs for LLM training. Why it's wrong: TPUs excel in large-scale matrix operations but may lack flexibility for custom architectures or smaller batch sizes. Fix: Evaluate TPUs for massive, homogeneous workloads (e.g., Google's TPU pods) but prefer GPUs for prototyping or diverse tasks.
  • Mistake: Ignoring cloud instance pricing for long-term LLM training. Why it's wrong: On-demand cloud GPUs/TPUs can cost 10x more than reserved instances or spot instances over months. Fix: Use spot instances for fault-tolerant training or commit to reserved instances for predictable workloads.
  • Mistake: Overlooking inter-node communication bottlenecks in multi-GPU setups. Why it's wrong: Slow NVLink or Ethernet connections between GPUs can cripple distributed training performance. Fix: Use high-speed interconnects (e.g., NVLink, InfiniBand) and optimize data parallelism strategies.
  • Mistake: Selecting hardware without profiling the LLM's memory/compute needs. Why it's wrong: LLMs have unique memory footprints (e.g., attention mechanisms) that may not scale linearly with parameter count. Fix: Profile memory usage with tools like PyTorch's `torch.cuda.memory_summary()` and benchmark with representative batch sizes.

Interview questions

Why is hardware selection important when creating your own large language model?

Hardware selection is critical because training and fine-tuning large language models require massive computational power. The right hardware accelerates training, reduces costs, and ensures scalability. For example, GPUs like NVIDIA A100s are optimized for parallel processing, which is essential for matrix multiplications in deep learning. Without proper hardware, training could take months or fail due to memory constraints. Additionally, cloud resources like AWS or Google Cloud offer flexibility, allowing you to scale up or down based on your needs, which is especially useful for startups or researchers with limited budgets.

What are the key differences between GPUs and TPUs for training large language models?

GPUs and TPUs are both designed for high-performance computing, but they excel in different scenarios. GPUs, like NVIDIA’s H100, are highly versatile and support a wide range of deep learning frameworks such as PyTorch and TensorFlow. They are ideal for mixed-precision training and offer large memory capacities, which is crucial for handling the massive parameter sizes of LLMs. TPUs, on the other hand, are Google’s custom-built chips optimized specifically for TensorFlow. They provide faster matrix operations and are more power-efficient for large-scale training. However, TPUs are less flexible and require specific optimizations in your code. For example, if you’re using PyTorch, you’d need to convert your model to TensorFlow or use libraries like JAX to leverage TPUs effectively.

When would you choose cloud-based resources over on-premise hardware for training your LLM?

Cloud-based resources are ideal when you need flexibility, scalability, and cost-efficiency. For instance, if you’re a startup or a researcher with limited upfront capital, cloud providers like AWS, Google Cloud, or Azure allow you to rent high-performance hardware on-demand. This means you can scale up to hundreds of GPUs for training and then scale down to save costs during inference. Cloud providers also offer pre-configured environments with optimized libraries, reducing setup time. On the other hand, on-premise hardware is better for organizations with long-term, large-scale projects that require consistent access to high-performance computing. It also provides better data security and control over the infrastructure, which is critical for sensitive applications.

How do you determine the right GPU memory size for training your LLM?

Determining the right GPU memory size depends on the model’s parameter count, batch size, and the precision of your computations. For example, a model with 7 billion parameters trained in FP16 precision requires roughly 14 GB of memory just for the parameters. However, you also need additional memory for activations, gradients, and optimizer states, which can triple or quadruple the total memory requirement. A good rule of thumb is to use GPUs with at least 40-80 GB of memory for models with 7-13 billion parameters. For larger models, you might need to use techniques like model parallelism or gradient checkpointing to distribute the memory load across multiple GPUs. Here’s a simple formula to estimate memory needs: `Memory (GB) ≈ (Parameters × 2) × 4` for FP16 training with optimizer states.

Compare the trade-offs between using a single high-end GPU versus multiple lower-end GPUs for training your LLM.

Using a single high-end GPU, like an NVIDIA A100 or H100, simplifies training because you avoid the complexity of distributed computing. It’s easier to manage, requires less synchronization overhead, and is ideal for smaller models or fine-tuning tasks. However, high-end GPUs are expensive, and their memory may still limit the size of the model you can train. On the other hand, using multiple lower-end GPUs, like NVIDIA V100s or RTX 3090s, allows you to scale horizontally. This approach is cost-effective and enables training larger models through techniques like data parallelism or model parallelism. However, it introduces challenges like network latency, synchronization overhead, and the need for distributed training frameworks like PyTorch’s `DistributedDataParallel`. For example, training a 175B parameter model would be impossible on a single GPU but feasible with a cluster of 8 A100s using model parallelism.

Explain how you would optimize hardware utilization when training a large language model in the cloud. Include specific tools or techniques you’d use.

Optimizing hardware utilization in the cloud involves balancing cost, performance, and efficiency. First, I’d use spot instances or preemptible VMs to reduce costs, as they offer significant discounts compared to on-demand instances. However, I’d implement checkpointing to save progress frequently, as these instances can be terminated unexpectedly. Second, I’d leverage distributed training frameworks like PyTorch’s `DistributedDataParallel` or TensorFlow’s `MirroredStrategy` to parallelize training across multiple GPUs or nodes. This ensures that all available hardware is utilized efficiently. Third, I’d use mixed-precision training with libraries like NVIDIA’s Apex or PyTorch’s native AMP to reduce memory usage and speed up training without sacrificing model accuracy. For example, training in FP16 instead of FP32 can halve memory usage and double throughput. Finally, I’d monitor hardware metrics using tools like Weights & Biases or TensorBoard to identify bottlenecks, such as GPU underutilization or high network latency, and adjust batch sizes or parallelism strategies accordingly.

All Creating Own LLM interview questions →

Check yourself

1. When training a 7B-parameter LLM from scratch, which hardware factor is MOST critical to avoid bottlenecks?

  • A.Total GPU VRAM capacity to fit the model weights
  • B.GPU memory bandwidth to feed data to compute units
  • C.Number of CPU cores for data preprocessing
  • D.Storage speed (e.g., NVMe SSDs) for checkpointing
Show answer

B. GPU memory bandwidth to feed data to compute units
The right answer is GPU memory bandwidth. LLMs are memory-bound during training due to large parameter counts and attention mechanisms. High bandwidth (e.g., H100's 3TB/s) ensures compute units aren't starved for data. VRAM capacity (option 0) is necessary but not sufficient if bandwidth is low. CPU cores (option 2) and storage (option 3) are secondary to GPU performance for this task.

2. A team is fine-tuning a 13B-parameter LLM on a cloud platform. They notice training is 3x slower than expected. Which is the LEAST likely cause?

  • A.Using a single GPU instead of multi-GPU data parallelism
  • B.Choosing a cloud instance with slow inter-GPU NVLink connections
  • C.Using TPUs instead of GPUs for the fine-tuning task
  • D.Using on-demand pricing instead of spot instances
Show answer

D. Using on-demand pricing instead of spot instances
The right answer is using TPUs instead of GPUs. TPUs are optimized for large-scale training and can outperform GPUs for homogeneous workloads like fine-tuning. The other options are likely causes: single-GPU (option 0) limits throughput, slow NVLink (option 1) bottlenecks multi-GPU training, and on-demand pricing (option 3) doesn't affect speed but is unrelated to performance.

3. For a research project prototyping a novel LLM architecture, why might GPUs be preferred over TPUs?

  • A.GPUs have higher single-precision (FP32) performance for small batch sizes
  • B.TPUs lack support for PyTorch, the most common LLM framework
  • C.GPUs offer better cost-efficiency for long-running training jobs
  • D.TPUs require manual memory management for custom operations
Show answer

D. TPUs require manual memory management for custom operations
The right answer is TPUs require manual memory management for custom operations. TPUs are designed for TensorFlow and may need XLA compilation for custom ops, limiting flexibility. GPUs support dynamic frameworks like PyTorch (option 1 is wrong; TPUs support PyTorch via libraries). FP32 performance (option 0) is irrelevant for LLMs (FP16/BF16 is standard). Cost-efficiency (option 2) depends on scale, not prototyping.

4. A startup is deploying a 30B-parameter LLM for inference. They observe high latency despite using high-end GPUs. What is the MOST likely solution?

  • A.Switch to TPUs, which are optimized for inference workloads
  • B.Use model quantization to reduce memory bandwidth pressure
  • C.Increase the batch size to maximize GPU utilization
  • D.Replace the GPUs with CPUs, which have lower latency for small models
Show answer

B. Use model quantization to reduce memory bandwidth pressure
The right answer is model quantization. Quantization (e.g., FP16/INT8) reduces memory bandwidth usage, directly addressing latency in memory-bound inference. TPUs (option 0) are not inherently better for inference and may not support all LLM ops. Larger batch sizes (option 2) increase throughput but worsen latency. CPUs (option 3) are slower for LLMs due to lack of parallelism.

5. When selecting cloud resources for distributed LLM training, which factor is MOST often underestimated?

  • A.The cost of data egress when transferring checkpoints to storage
  • B.The impact of network topology on gradient synchronization
  • C.The need for GPU-optimized filesystems like Lustre
  • D.The availability of preemptible instances for fault tolerance
Show answer

B. The impact of network topology on gradient synchronization
The right answer is the impact of network topology on gradient synchronization. Slow inter-node connections (e.g., Ethernet vs. InfiniBand) can dominate training time in distributed setups. Data egress costs (option 0) are secondary to performance. GPU-optimized filesystems (option 2) matter less for training than inference. Preemptible instances (option 3) are a cost, not performance, factor.

Take the full Creating Own LLM quiz →

← PreviousData Cleaning and Preprocessing PipelinesNext →Implementing a Transformer Model from Scratch (Using PyTorch or TensorFlow)

Creating Own LLM

36 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app