Large Scale Distributed Training and Parallel Computing Questions
Understand strategies for training models at scale: data parallelism, model parallelism, pipeline parallelism, and hybrid approaches. Address synchronization, gradient compression, all-reduce operations, and communication efficiency. Discuss handling hardware failures, reproducibility, and memory/compute trade-offs. For Staff-level, discuss training 100B+ parameter models.
MediumSystem Design
120 practiced
Design an observability plan for long-running distributed training jobs. List key metrics, logs, and traces to collect (compute, GPU utilization, memory, network, per-step durations, gradient norms, loss), suggest alerting rules, and describe dashboards to help identify performance regressions, convergence stalls, and resource contention.
Sample Answer
Requirements & constraints:- Monitor long-running distributed training (multi-node GPU), detect performance regressions, convergence stalls, and resource contention with low overhead; retain metrics for debugging and drift analysis; support alerting and per-run correlation (logs/traces/metrics).High-level architecture:- Instrument training code & infra to export metrics to Prometheus (or OpenTelemetry→Prometheus), send structured logs to ELK/Datadog, and traces to Jaeger/OTel Collector. Use a central metadata store (run id, hyperparams, git hash) to correlate artifacts.Key metrics to collect (sample frequency: 1–10s for infra, per-step for training):- Compute/GPU: - GPU utilization %, SM utilization, GPU memory used/total, GPU temperature, power draw - GPU PCIe RX/TX throughput- CPU/host: - CPU utilization per core, load avg, host memory used/free, disk IO, inode usage - NUMA imbalance metrics- Network: - Inter-node bandwidth, RPC latency, packet drops, NCCL/all-reduce throughput and latency- Training-specific: - Per-step duration (forward, backward, optimization), steps/sec, throughput (samples/sec) - Per-batch input pipeline time (data load, augmentation, prefetch queue length) - Gradient norms (L2), gradient sparsity, parameter update sizes - Loss, training/validation metrics (accuracy, eval loss), learning rate - Checkpoint durations and sizes- System-level: - Queue/backlog lengths (dataloader, parameter server), GPU process list (which PID), OOM events, CUDA errors.Logs and traces:- Structured logs: epoch/step annotations, hyperparams, checkpoint events, warnings/errors, OOM stack traces, NCCL warnings, data loader exceptions. Include metadata tags (run_id, node, rank).- Distributed traces: instrument key operations (batch fetch, forward, backward, all-reduce, optimizer step, checkpoint) to measure spans and critical path. Correlate spans to per-step durations.Alerting rules (examples):- Performance regressions: - steps/sec drops >20% sustained for 5 minutes vs moving baseline → P2 - per-step duration increase >30% for 5 min → P2- Convergence stalls: - No improvement in validation loss >N epochs or 24h AND training loss plateau (slope near-zero) → P1 - Loss diverging by >X% in short window → P1- Resource contention: - GPU utilization low (<20%) while CPU load high (>80%) or dataloader queue excessive → P2 - NCCL/all-reduce latency > threshold or packet loss >0.1% → P1 - GPU memory usage nearing capacity (>=95%) or OOM events → P0- Infrastructure alerts: - Node unreachable or high hardware errors, disk saturation, excessive checkpoint failures → P0Dashboards (views tuned for troubleshooting):- Cluster overview: - Heatmap of GPU utilization, memory, temperature by node; network bandwidth; overall steps/sec; ongoing alerts.- Job run summary (per run_id): - Timeline: steps/sec, training/val loss, learning rate, gradient norm; overlay checkpoint events, notable logs. - Per-step breakdown: stacked bars for input load / forward / backward / all-reduce / optimizer.- Bottleneck drill-down: - Correlate low GPU utilization with high dataloader time, host CPU saturation, or high all-reduce latency. - Per-rank traces showing span durations and variance.- Convergence & experiment tracking: - Comparative plots of loss vs steps across runs (filter by git hash/hyperparams); early-stopping recommendation flagging stuck runs.- Resource contention and networking: - NCCL metrics, inter-node latency, bandwidth usage, packet errors; mapping to steps/sec dips.How to use when debugging:- Identify symptom (steps/sec down, loss plateau). Use job timeline to see if per-step backward/all-reduce spans grew. If all-reduce latency increased → network/NCCL; check node-level NIC errors and per-node GPU busy vs idle to find stragglers.- If GPU utilization low but input load time high → optimize data pipeline (prefetch, increase workers, use faster storage).- If gradient norms zero or exploding → check learning rate schedule, optimizer states, batch composition; examine per-layer gradients in logs.Trade-offs & best practices:- Sampling frequency vs overhead: keep high-frequency infra metrics (1–5s) but aggregate long-term; for traces sample warm-up and anomalies to limit overhead.- Correlate via run_id and timestamps; capture git/hyperparams to reproduce.- Automate anomaly baselines with rolling windows and ML-based detectors for gradual regressions.This plan gives actionable observability: metrics for spotting hardware/infra issues, traces and per-step breakdowns for pinpointing slow spans, logs for root-cause, alerts tuned to detect regressions and convergence problems, and dashboards for fast triage.
MediumTechnical
67 practiced
Given model gradient size G, compute time Tcompute per step, P GPUs participating, and per-link bandwidth B, derive a formula for communication-to-compute ratio for synchronous all-reduce. Use the formula to evaluate whether communication or compute is the bottleneck for G=2GB, P=8, Tcompute=0.5s, and B=100GB/s. Show reasoning and discuss approximations.
Sample Answer
Approach / derivation:For synchronous ring all‑reduce each GPU sends and receives a total of 2*(P−1)/P times the model gradient size G (one reduce‑scatter plus one all‑gather), so total bytes transferred per GPU = G_comm = 2*(P−1)/P * G. If per‑link bandwidth is B (bytes/s) and we ignore per‑message latency/startup and contention, communication time per step is:T_comm = G_comm / B = [2*(P−1)/P * G] / B.The communication‑to‑compute ratio is:R = T_comm / T_compute = [2*(P−1)/P * G] / (B * T_compute).Plugging numbers (use decimal GB → bytes consistently):G = 2 GB = 2×10^9 bytesP = 8 → 2*(8−1)/8 = 14/8 = 1.75B = 100 GB/s = 1×10^11 bytes/sT_compute = 0.5 sT_comm = 1.75 * 2e9 / 1e11 = 3.5e9 / 1e11 = 0.035 sR = 0.035 / 0.5 = 0.07Conclusion:R ≈ 0.07 — communication takes ~7% of compute time, so compute is the bottleneck here.Approximations & caveats:- Ignored per‑message latency and startup (important for small messages or many steps).- Assumed full line rate (no protocol/PCIe/NIC overhead, no traffic contention, ideal topology).- Used decimal GB; using GiB would change numbers slightly.- Different all‑reduce algorithms (tree, recursive doubling) have different constants (latency terms ~log P).- Real systems may have CPU/NIC overheads, PCIe copies, or overlap of comm/compute which can further reduce perceived comm cost.If any of those non‑ideal factors are significant, communication could matter more despite the low R above.
MediumTechnical
73 practiced
You are asked to create a reproducibility testing plan for distributed training in CI. Describe the concrete steps, test cases, and thresholds you would include to detect regressions in determinism across single-GPU, multi-GPU, and multi-node training runs. Include considerations for flaky ops and acceptable tolerance for numerical differences.
Sample Answer
Approach: define deterministic baselines, automated CI jobs that run short deterministic workloads across single-GPU, multi-GPU (DDP/NCCL), and multi-node setups, compare checkpoints/outputs with tolerances, and surface regressions early.Concrete steps:1. Baseline creation- Weekly “golden” baselines: fixed seed, environment (CUDA/cuDNN, library versions), pinned dependency hashes, and a saved checkpoint + reference metrics (loss, accuracy, logits) for a small but representative model/dataset.2. CI jobs- Single-GPU quick job: full pipeline (data loader seed, augmentation seed, model init, optimizer) for N steps (e.g., 20) — compare checkpoint and final loss.- Multi-GPU intra-node: 2/4 GPUs with DDP, same N steps, with NCCL deterministic flags set.- Multi-node: 2 nodes × 2 GPUs; run same steps with environment orchestration (SSH/SLURM).- Repeatability job: run same configuration M times (e.g., 3) to detect flakiness.3. Test cases & checks- Exact-match checks: model weights bytes and RNG states for single-GPU when deterministic ops guaranteed.- Numerical tolerance checks: element-wise compare tensors (logits/loss) with thresholds: - Single-GPU: strict (abs tol 1e-6, rel tol 1e-6) - Multi-GPU/multi-node: looser (abs tol 1e-5–1e-4, rel tol 1e-5) depending on op sensitivity.- Metric drift: accept <0.1% change in validation metric; flag otherwise.- Statistical test: run M repeats, compute mean±std, require overlap with baseline within k sigma.4. Flaky ops handling- Maintain an ops whitelist of known non-deterministic kernels (e.g., certain atomic ops, cuDNN heuristics). For these: - Enable deterministic algorithms where available (e.g., torch.use_deterministic_algorithms). - If unavailable, mask those ranges in comparisons or use higher tolerances.- Log and triage new flaky ops: CI should capture op-level logs and stack traces.5. Thresholds & alerting- Fail CI on: exact-match failure for single-GPU exact checks, repeatability failure (different runs diverge beyond tolerance), metric drift > threshold.- Warn on: small numerical deviations within tolerance.6. Automation & observability- Store artifacts (checkpoints, logs, diffs) for each run in artifact store.- Dashboard tracking baseline drift over time; auto-bisect candidate commits when regression detected.7. Additional considerations- Seed scoping: document and set seeds for all RNGs (Python, numpy, torch, cudnn).- Hardware variance: tag baselines per GPU model/driver.- Cost: use small representative workloads to keep CI fast; gate full-scale runs to nightly.This plan detects determinism regressions while allowing pragmatic tolerances for distributed numerical nondeterminism and known flaky ops.
HardTechnical
76 practiced
Describe the ZeRO-Offload design where optimizer state and/or parameters are offloaded to CPU or NVMe. Provide algorithmic steps for an update step when state is offloaded, explain IO implications, and propose optimizations to hide I/O latency. Discuss performance tradeoffs and when offload is beneficial.
Sample Answer
Approach: ZeRO-Offload moves parts of optimizer state and/or parameters from GPU memory to CPU or NVMe, reducing GPU memory footprint at the cost of I/O. A single parameter update requires bringing necessary shards to GPU, performing computation, and writing back. Below are algorithmic steps, a concise pseudocode update, IO implications, optimizations to hide latency, and trade-offs.Algorithmic steps for one training step when optimizer/state is offloaded:1. Forward: ensure parameter tensors required for forward are either resident on GPU or streamed in (usually kept on GPU).2. Backward: compute gradients on GPU; if gradients are sharded on CPU/NVMe, stream gradient shards to GPU as needed.3. For each parameter shard: - Async-read optimizer state (e.g., momentum, variance) and parameter shard from CPU/NVMe to GPU. - Wait for transfer completion (or overlap; see optimizations). - Compute optimizer update on GPU: new_param, new_state = OPT_STEP(param, grad, state). - Write updated state and/or parameter back async to CPU/NVMe (or keep param on GPU if space).4. All-reduce or shard synchronization as required for ZeRO stage.5. Continue next microbatch or step.Pseudocode (simplified):IO implications:- Read bandwidth and latency dominate. NVMe has higher latency and lower throughput vs CPU RAM; PCIe/CPU-GPU bandwidth becomes bottleneck.- Frequent small transfers (many tiny shards) are worse than fewer large contiguous transfers due to per-IO overhead.- Writes add extra tail latency; write durability/flush semantics on NVMe may further stall.Optimizations to hide I/O latency:- Asynchronous transfers + overlap with compute (prefetch next shard while computing current).- Aggregate small tensors into larger contiguous buffers to amortize per-IO overhead.- Double-buffering: maintain two GPU buffers per stream (one computing, one transferring).- Prioritize hot parameters in GPU memory (LRU or heuristic) so frequent params stay resident.- Use RDMA or GPUDirect Storage to bypass CPU and reduce copies (if hardware supports).- Compression/quantization of offloaded state (float16 or 8-bit) to reduce bandwidth.- Batched optimizer updates (apply multiple micro-batch grads before IO) if algorithm permits.- IO scheduling: write-back lazily (write only state, keep params until eviction), and throttle IO concurrency.Performance tradeoffs and when beneficial:- Benefit: enables training much larger models on limited GPU memory; reduces cost by using cheaper CPU/NVMe.- Cost: training throughput drops due to IO; increased latency per step and higher jitter.- Offload to CPU RAM is preferable when CPU-GPU bandwidth (PCIe/NVLink) is good and NVMe latency is high. NVMe offload helps when CPU RAM insufficient but costs higher latency.- Best when model size >> GPU memory but compute per parameter is high (so you can hide IO behind long compute), or when batch sizes/micro-batches allow overlap.- Not beneficial when: model fits comfortably on GPU, or when per-parameter computation is tiny (IO dominates), or hardware lacks high-bandwidth interconnects.Complexity:- Memory: GPU peak reduced from O(model) to O(model/G + working_set) depending on shard strategy.- Time: extra O(IO_bytes / bandwidth) per step; effective compute throughput depends on overlap efficiency.Edge cases:- Failure to hide IO causes stalls; ensure backpressure and bounded async IO.- Checkpoint/consistency when async writes may lag — ensure durable checkpoints/sync before failure-prone boundaries.Alternative: ZeRO-2 keeps parameters on GPU and only offloads optimizer state (less IO). Hybrid schemes selectively offload only large optimizer tensors (momentum/adam moments).
python
# assume async_io.read/write return futures
for shard_id in all_shards:
grad_future = grads.shard_async_download(shard_id) # if grads offloaded
state_future = state_storage.read_async(shard_id) # CPU/NVMe -> GPU
param_future = param_storage.read_async(shard_id) # optional
# overlap waiting until needed
wait(grad_future, state_future, param_future)
param = param_future.result()
state = state_future.result()
grad = grad_future.result()
new_param, new_state = optimizer_step(param, grad, state)
# push back asynchronously
param_write_fut = param_storage.write_async(shard_id, new_param)
state_write_fut = state_storage.write_async(shard_id, new_state)
# optionally prefetch next shard while writes are in flightEasyTechnical
79 practiced
Describe synchronous versus asynchronous parameter update strategies for distributed training. Explain how each approach affects convergence, staleness of gradients, and hardware utilization. Give examples of when asynchronous approaches might be chosen over synchronous ones and the tradeoffs an engineer must communicate to stakeholders before selecting an approach.
Sample Answer
Synchronous vs asynchronous parameter updates in distributed training:Synchronous updates:- Definition: All workers compute gradients on their mini-batches and wait at a barrier; gradients are aggregated (e.g., all-reduce) and parameters updated simultaneously.- Convergence & staleness: Deterministic ordering and no gradient staleness → more stable convergence and easier reproducibility; behaves like larger-batch SGD.- Hardware utilization: Can suffer from stragglers (slow workers block the group) → lower utilization unless tailored (dynamic batching, gradient compression).- When ideal: small-to-medium clusters with homogeneous machines, strict reproducibility, or when convergence quality is priority.Asynchronous updates:- Definition: Workers push gradients and pull parameter updates independently; parameter server or decentralized scheme applies updates without global barrier.- Convergence & staleness: Introduces gradient staleness — workers may compute on older weights. This can slow or destabilize convergence; requires smaller learning rates, stale-aware algorithms (e.g., bounded-delay, learning rate schedules), or algorithms robust to asynchrony (Hogwild!, elastic averaging).- Hardware utilization: High utilization and throughput, resilient to stragglers and variable latency; good for large, heterogeneous clusters or edge/federated settings.When to choose async:- Heterogeneous or unreliable clusters, large-scale systems where waiting costs outweigh staleness penalty, or latency-sensitive settings (online learning, federated with intermittent nodes).Tradeoffs to communicate to stakeholders:- Convergence speed vs wall-clock time: async may reach acceptable loss faster in real time despite worse per-step convergence.- Model quality and reproducibility: sync is safer for final accuracy and debugging.- Complexity and engineering cost: async needs careful tuning (learning rates, staleness bounds), monitoring for divergence.- Resource cost: async can better utilize existing hardware, potentially lowering cloud costs.- Risk mitigation: propose hybrid options (synchronous with backup workers, synchronous within pods + asynchronous across pods) and metrics to monitor (validation loss, gradient norm, staleness distribution).
Unlock Full Question Bank
Get access to hundreds of Large Scale Distributed Training and Parallel Computing interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.