RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Eruo Fredoline
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /Troubleshooting Local AI
  6. /Ch. 12
Troubleshooting Local AI

12. Performance Profiling

Chapter 12 of 15 · 15 min
KEY INSIGHT

Measure before optimizing. A profile tells you exactly which operation consumes time or memory. Optimizing the wrong operation wastes effort.

PyTorch Profiler

import torch
from torch.profiler import profile, ProfilerActivity

with profile(
    activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA],
    record_shapes=True,
    profile_memory=True,
    with_stack=True
) as prof:
    output = model.generate(input_ids, max_new_tokens=100)

# Print the top 10 operations by CUDA time
print(prof.key_averages().table(sort_by="cuda_time_total", row_limit=10))

Time Per Token

For inference, the relevant metric is time per generated token (not total time):

def benchmark_generation(model, tokenizer, prompt, num_runs=5):
    input_ids = tokenizer(prompt, return_tensors="pt").input_ids.cuda()
    
    times_per_token = []
    for _ in range(num_runs):
        torch.cuda.synchronize()
        start = time.time()
        output = model.generate(input_ids, max_new_tokens=50)
        torch.cuda.synchronize()
        elapsed = time.time() - start
        tokens_generated = output.shape[1] - input_ids.shape[1]
        tpt = elapsed / tokens_generated
        times_per_token.append(tpt)
    
    return {
        "mean_tpt": sum(times_per_token) / len(times_per_token),
        "std_tpt": (sum((x - sum(times_per_token)/len(times_per_token))**2 for x in times_per_token) / len(times_per_token)) ** 0.5
    }

Memory Profiling

# Track memory allocation by operation
import torch
from contextlib import contextmanager

@contextmanager
def memory_tracker():
    torch.cuda.reset_peak_memory_stats()
    start = torch.cuda.memory_allocated()
    yield
    peak = torch.cuda.max_memory_allocated()
    print(f"Memory used: {(peak - start) / 1e9:.2f} GB")
    print(f"Peak memory: {peak / 1e9:.2f} GB")

with memory_tracker():
    model.generate(input_ids, max_new_tokens=100)

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

EXERCISE

Profile a generation call. Identify the top 3 operations by time. If attention is not the top operation, investigate why (likely memory bandwidth or data transfer overhead).

← Chapter 11
Model Hallucination Debugging
Chapter 13 →
Log Analysis