Instructor Notes

Instructor Notes: Introduction to Machine Learning on HPC

Workshop Overview

Duration: 2 days (approximately 10 hours contact time) Format: Carpentries-style workshop with live coding demonstrations Target Audience: Pomona researchers with basic Python knowledge, little to no HPC/GPU experience

Learning Outcomes: By the end, learners can: - Submit GPU jobs to Sagehen HPC system - Write PyTorch and TensorFlow training code for GPUs - Optimize data loading and preprocessing at scale - Use multiple GPUs for distributed training - Implement hyperparameter search for ML models

Episode-by-Episode Teaching Notes

Episode 1: Why Machine Learning on HPC?

Time: 45 min teaching + 45 min exercises Key Points: - HPC is NOT just for ML, but ML is a great use case - Speedup/efficiency metrics are critical - Amdahl’s law explains why parallelism has limits

Live Coding: - Demo speedup calculation for their own laptops - Show typical training time reduction (100h → 10h with 4 GPUs)

Common Misconceptions: - “More GPUs = more speed” (false: communication overhead) - “My laptop doesn’t need HPC” (depends on dataset size and time)

Exercises: - Have them calculate speedup for sample problems - Discuss whether parallelism is worthwhile for their research

Troubleshooting: - Some may have never done manual speedup calculations; walk through formulas


Episode 2: Environment Setup for ML

Time: 20 min teaching + 15 min exercises Key Points: - Two paths: pre-built modules vs. conda environments - Reproducibility matters: pin versions - Testing before big jobs saves time

Live Coding: - Create a conda environment live - Install PyTorch with GPU support - Test with simple matrix multiplication

Common Issues: - CUDA version mismatches (module load first!) - Conda slow downloads (normal, be patient) - Import errors (verify torch.cuda.is_available())

Exercises: - Have everyone create their own environment - Run the verification script

Troubleshooting: - Slow conda? Use mamba (faster) - CUDA errors? Check: did they module load miniconda3 and conda activate their environment first? (There is no pytorch module.) - GPU not detected? Try: python -c "import torch; print(torch.cuda.is_available())"


Episode 3: Data Preparation and Preprocessing

Time: 20 min teaching + 15 min exercises Key Points: - I/O bottlenecks are real (GPUs idle while waiting for data) - Preprocessing should be mostly in /scratch (not /bigdata) - Always separate train/val/test for hyperparameter selection

Live Coding: - Load a CSV with pandas - Show memory usage patterns - Implement standard scaling - Show Dask for large data

Common Mistakes: - Computing normalization statistics on full dataset (data leakage!) - Not actually timing I/O (they don’t see the bottleneck until they profile) - Forgetting to save preprocessing objects (scaler)

Exercises: - Have them preprocess a real dataset - Challenge: Load with both pandas and Dask, compare performance

Troubleshooting: - Memory errors? Reduce batch size, use Dask - Slow loading? Check storage tier (using /bigdata? Move to /scratch)


Episode 4: GPU Training with PyTorch

Time: 20 min teaching + 15 min exercises Key Points: - GPU debugging is different (backward() errors can be cryptic) - Mixed precision training is practical (2x faster, same accuracy) - GPU memory grows during backward pass (save during forward)

Live Coding: - Simple model: dense → ReLU → output - Move to GPU: model.to(device) - Training loop with optimizer.zero_grad() - GPU memory monitoring

Common Issues: - “CUDA out of memory”: Reduce batch size, use mixed precision, gradient accumulation - “Loss is NaN”: Learning rate too high, bad initialization - “Backward slower than forward”: Normal, backward is ~2x cost

Exercises: - Train on small dataset (MNIST/CIFAR-10 first 100 samples) - Measure speedup: CPU vs single GPU

Tips for Live Coding: - Pre-download datasets (internet can be slow in classroom) - Have backup laptop in case of connection issues - Start with CPU version, then GPU (shows difference)


Episode 5: GPU Training with TensorFlow/Keras

Time: 20 min teaching + 15 min exercises Key Points: - High-level Keras API masks GPU complexity - tf.data pipelines are important for performance - Custom training loops for research flexibility

Live Coding: - Sequential model (simplest) - Functional API (for complex models) - Custom training with tf.GradientTape - Callbacks for monitoring

Compare to PyTorch: - TensorFlow more declarative, PyTorch more imperative - TensorFlow faster out-of-box, PyTorch easier to debug - Both produce same results

Exercises: - Train same model in TensorFlow vs PyTorch (compare code) - Implement callbacks for early stopping

Troubleshooting: - tf.function compilation errors? Remove @tf.function, debug, re-add - Graph execution vs eager? Explain: @tf.function compiles for speed


Episode 6: Distributed Training Across GPUs

Time: 25 min teaching + 20 min exercises Key Points: - Data parallelism most common (replicate model on each GPU) - Communication overhead limits scaling (rarely >3x on 4 GPUs) - DistributedDataParallel better than DataParallel

Live Coding: - DataParallel (simple but inefficient) - DistributedDataParallel with torchrun (professional) - Measure speedup across 1, 2, 4 GPUs

Important Notes: - Many students think “4 GPUs = 4x speed” (it’s actually ~3x) - Showing the overhead convinces them of importance - Load balancing matters (some GPUs may stall)

Exercises: - Modify single-GPU script for multi-GPU - Submit job with –gres=gpu:4 - Collect speedup measurements

Common Issues: - All prints on all ranks (use if rank == 0) - Hanging processes (timeout=30min in init_process_group) - Different results per rank (set seed, use sampler.set_epoch)

Advanced Note: - Model parallelism is rare at Pomona (models fit on GPU) - Mention for completeness


Episode 7: Hyperparameter Tuning and Best Practices

Time: 25 min teaching + 20 min exercises Key Points: - Three approaches: grid, random, Bayesian search - Bayesian most efficient (Ray Tune) - Reproducibility requires version control + config files

Live Coding: - Simple grid search loop - Ray Tune example - SLURM array job for parallel sweeps - Tensorboard for visualizing results

Reproducibility Focus: - Save config.yaml, code, timestamp, git hash - Someone should be able to rerun and get same results - Document hyperparameter choices

Exercises: - Tune learning rate on small dataset - Submit 10-job array for parallel search - Visualize results (loss vs LR)

Advanced Topics (optional): - Optuna for Bayesian tuning - Population-based training for long jobs - Early stopping via validation curves

Troubleshooting: - GPU memory leaks during sweeps: Add gc.collect(); torch.cuda.empty_cache() - Jobs not running: Check queue (squeue -u $USER) - Hyperparameters not having effect: Verify they’re actually used in code!


Logistics and Setup

Pre-Workshop Checklist

During Workshop

  • Facilitator: Live coding, narrate decisions
  • TA (if available): Monitor chat/questions, help individuals
  • Emphasis: Iterate fast (test on CPU first, then GPU)

Room Setup

  • Projector for instructor demos
  • Learners should have laptops
  • Access to Sagehen HPC (SSH client: terminal on Mac, PowerShell/WSL on Windows)

Common Learner Challenges

Challenge 1: “My GPU job is taking forever to run”

Likely Causes: 1. Long queue (check: squeue | head) 2. I/O bottleneck (data loading is slow) 3. GPU not actually being used (check nvidia-smi) 4. Job time limit approaching (check: scontrol show job)

Teaching Point: Profile before optimizing!

Challenge 2: “My model trained locally but crashes on GPU”

Likely Causes: 1. GPU memory too small for batch size 2. Floating point differences (CPU uses float64, GPU float32) 3. Missing .to(device) somewhere in code

Teaching Point: Always test on small batch first!

Challenge 3: “Multi-GPU training only 2x faster with 4 GPUs”

Expected: This is normal (70-80% efficiency is good)

Teaching Point: Communication overhead matters!


Assessment and Feedback

Ways to Assess Learning

  • Exercises within episodes: Do learners’ code run without error?
  • Challenges: Can they modify existing code?
  • Final project (optional): Can they train a model relevant to their research?

Feedback Survey

Include questions: - Did you understand when/why to use GPU? - Can you now write a job submission script? - Do you feel confident asking questions of HPC team? - Would you recommend this workshop?


Extensions and Follow-Up

If You Have Extra Time

  • Episode on Jupyter notebooks on Sagehen (OnDemand)
  • Deep dive into profiling (Python profiler, GPU timelines)
  • Model serving/inference considerations
  • Start small: Run your actual research on 1 GPU
  • Measure: Always time before and after optimization
  • Ask questions: ITS is here to help!
  • Read: Sagehen documentation for advanced topics

Resources for Instructors

Example Datasets

  • MNIST: torchvision.datasets.MNIST
  • CIFAR-10: torchvision.datasets.CIFAR10
  • ImageNet subset: Available on /bigdata

Benchmarking Tools

  • NVIDIA GPU Monitoring: nvidia-smi, nvidia-smi dmon
  • Python Profiler: cProfile
  • PyTorch Profiler: torch.profiler

Notes from Previous Runs

(Update after each workshop)

What Went Well

  • Live coding demonstrations helped people understand GPU concepts
  • Challenges were appropriately difficult
  • SLURM job submission was less intimidating after practice

What to Improve

  • Spend more time on data loading (I/O often overlooked)
  • Pre-stage datasets (network transfers during workshop slow things down)
  • Emphasize: “Test locally first” (saves GPU hours)

Participant Feedback Summary

  • Most appreciated: Real examples relevant to their research
  • Most challenging: Understanding distributed training scaling
  • Most useful: Templates for job submission

Why Machine Learning on HPC?


ML Workflow Overview


Setting Up Your ML Environment


Loading ML Frameworks


Data Preparation Basics


Data Pipelines for HPC


Training with PyTorch


Training with TensorFlow


Checkpointing Long Jobs


SLURM Scripts for ML


Hyperparameter Tuning


ML Best Practices