LeetLLM
My PlanLearnGlossaryTracksPracticeBlog
LeetLLM

Your go-to resource for mastering AI & LLM systems.

Product

  • Learn
  • Glossary
  • Tracks
  • Practice
  • Blog
  • RSS

Legal

  • Terms of Service
  • Privacy Policy

© 2026 LeetLLM. All rights reserved.

All Topics
Your Progress
0%

0 of 196 articles completed

🛠️Computing Foundations0/9
Git, Shell, Linux for AIDocker for Reproducible AIPython for AI EngineeringNumPy and Tensor ShapesCUDA for ML TrainingMPS & Metal for ML on MacData Structures for AISQL and Data ModelingAlgorithms for ML Engineers
📊Math & Statistics0/9
Gradients and BackpropVectors, Matrices & TensorsLinear Algebra for MLAdam, Momentum, SchedulersProbability for Machine LearningBayesian Inference from EvidenceStatistics and UncertaintyDistributions and SamplingHypothesis Tests, Intervals, and pass@k
📚Preparation & Prerequisites0/13
Neural Networks from ScratchCNNs from ScratchTraining & BackpropagationSoftmax, Cross-Entropy & OptimizationRNNs, LSTMs, GRUs, and Sequence ModelingAutoencoders and VAEsThe Transformer Architecture End-to-EndLanguage Modeling & Next TokensFrom GPT to Modern LLMsPrompt Engineering FundamentalsCalling LLM APIs in ProductionFirst AI App End-to-EndThe LLM Lifecycle
🧮ML Algorithms & Evaluation0/15
Linear Regression from ScratchLogistic Regression and MetricsDecision Trees, Forests, and BoostingReinforcement Learning BasicsValidation and LeakageStatistical Learning and GeneralizationConformal Prediction and UncertaintyClustering and PCAProbabilistic Generative ModelsCore Retrieval AlgorithmsDecoding AlgorithmsExperiment Design and A/B TestingCausal Inference and CounterfactualsPyTorch Training LoopsDataset Pipelines and Data Quality
📦Production ML Systems0/6
Feature Engineering for Production MLBatch and Streaming Feature PipelinesGradient Boosted Trees in ProductionRanking and Recommendation SystemsForecasting and Anomaly DetectionMonitoring Predictive Models
🧪Core LLM Foundations0/8
The Bitter Lesson & ComputeBPE, WordPiece, and SentencePieceStatic to Contextual EmbeddingsPerplexity & Model EvaluationFile Ingestion for AIChunking StrategiesLLM Benchmarks & LimitationsInstruction Tuning & Chat Templates
🧰Applied LLM Engineering0/25
Dimensionality Reduction for EmbeddingsCoT, ToT & Self-Consistency PromptingFunction Calling & Tool UseMCP & Tool Protocol StandardsContext EngineeringPrompt Injection DefenseResponsible AI GovernancePrivacy-Preserving Machine LearningData Labeling and Human FeedbackEvaluating AI AgentsProduction RAG PipelinesHybrid Search: Dense + SparseReranking and Cross-Encoders for RAGRAG Evaluation for Reliable AnswersLLM-as-a-Judge EvaluationBias & Fairness in LLMsHallucination Detection & MitigationLLM Observability & MonitoringExperiment Tracking with MLflow and W&BPrompt Optimization with DSPyModel Versioning & DeploymentSemantic Caching & Cost OptimizationLLM Cost Engineering & Token EconomicsModel Gateways, Routing, and FallbacksDesign an Automated Support Agent
🎓Portfolio Capstones0/9
Capstone: Delivery ETA PredictionCapstone: Product RankingCapstone: Demand ForecastingCapstone: Image Damage ClassifierCapstone: Production ML PipelineCapstone: Document QACapstone: Eval DashboardCapstone: Fine-Tuned ClassifierCapstone: Reproducible ML Study
🧠Transformer Deep Dives0/8
Sentence Embeddings & Contrastive LossEmbedding Similarity & QuantizationScaled Dot-Product AttentionVision Transformers and Image EncodersPositional Encoding: RoPE & ALiBiLayer Normalization: Pre-LN vs Post-LNMechanistic InterpretabilityDecoding Strategies: Greedy to Nucleus
🧬Advanced Training & Adaptation0/17
Scaling Laws & Compute-Optimal TrainingPre-training Data at ScaleBuild GPT from Scratch LabJAX for PyTorch ResearchersContinued Pretraining for Domain ShiftSynthetic Data PipelinesSupervised Fine-Tuning PipelineMixed Precision TrainingDistributed Training: FSDP & ZeROLoRA & Parameter-Efficient TuningTraining Run OperationsReward Modeling from Preference DataRLHF & DPO AlignmentConstitutional AI & Red TeamingRLVR & Verifiable RewardsKnowledge Distillation for LLMsModel Merging and Weight Interpolation
🤖Advanced Agents & Retrieval0/16
Vector DB Internals: HNSW & IVFAdvanced RAG: HyDE & Self-RAGGraphRAG & Knowledge GraphsRAG Security & Access ControlStructured Output GenerationReAct & Plan-and-ExecuteGuardrails & Safety FiltersCode Generation & SandboxingComputer-Use / GUI / Browser AgentsHuman-in-the-Loop Agent ArchitectureAI Coding Workflow with AgentsAgent Memory & PersistenceAgent Failure & RecoveryRecursive Language Models (RLM)Multi-Agent OrchestrationCapstone: Production Agent
⚡Inference & Production Scale0/31
Inference: TTFT, TPS & KV CacheMulti-Query & Grouped-Query AttentionKV Cache & PagedAttentionPrefix Caching and Prompt CachingFlashAttention & Memory EfficiencyContinuous Batching & SchedulingScaling LLM InferenceModel Parallelism for LLM InferenceAccelerator Architecture Field GuideCorrect GPU Profiling and BenchmarkingGPU Kernel Performance Engineering LabGPU Parallel Primitives LabGPU Compilers and Kernel LanguagesGEMM From Naive CUDA to Tensor CoresLow-Precision GPU ProgrammingGPU Runtime Execution LabAI-Generated Kernel EngineeringModel Quantization: GPTQ, AWQ & GGUFLocal LLM DeploymentSLM Specialization & Edge DeploymentSpeculative DecodingLong Context Window ManagementMixture of Experts ArchitectureMamba & State Space ModelsReasoning & Test-Time ComputeAdvanced MLOps & DevOps for AIGPU Serving & AutoscalingGPU Failure OperationsDistributed Inference Data PlaneServing Benchmark EngineeringA/B Testing for LLMs
🏗️System Design Capstones0/9
Content Moderation SystemCode Completion SystemMulti-Tenant LLM PlatformLLM-Powered Search EngineVision-Language Models & CLIPMultimodal LLM ArchitectureDiffusion Models: Images & TextReal-Time Voice AI AgentReasoning Agent System Design
🎤AI Lab Interviewing0/4
AI Lab Coding Interview: Python SystemsAI Lab System Design InterviewAI Lab Behavioral InterviewAI Lab Technical Presentation
🔬Project Deep Dives0/17
Deep Dive - vLLMDeep Dive - SkyRLDeep Dive - FlashAttentionDeep Dive - FlashInferDeep Dive - DeepGEMMDeep Dive - NCCLDeep Dive - MegatronDeep Dive - DeepSpeedDeep Dive - RayDeep Dive - MLflowDeep Dive - PyTorchDeep Dive - TransformersDeep Dive - SGLangDeep Dive - slimeDeep Dive - DeepEPDeep Dive - TinkerDeep Dive - Light-PEFT
Back to Topics
LearnInference & Production ScaleGPU Failure Operations
⚙️HardMLOps & Deployment

GPU Failure Operations

Diagnose one failing GPU replica, contain the smallest safe scope, preserve evidence, and re-admit hardware through explicit gates.

22 min read
Learning path
Step 163 of 196 in the full curriculum
GPU Serving & AutoscalingDistributed Inference Data Plane

Personalize this lesson

Adapt explanations and teaching visuals to your background and preferred voice.

At 14:03:17 UTC, request r-7812 asks replica summarizer-7f9d6 for another 1.50 GiB. The allocation fails. Node gpu-a17 still answers health checks, peer replicas still serve traffic, and the alert says only CUDA out of memory.

The first receipt is more specific:

failure receipt
1node=gpu-a17 pod=summarizer-7f9d6 gpu=GPU-7f3 2capacity=40.00 GiB device_free=0.62 GiB 3pytorch_allocated=30.10 GiB pytorch_reserved=36.70 GiB 4inactive_split_blocks=6.10 GiB largest_inactive_split_block=0.88 GiB 5allocation_request=1.50 GiB 6nvml_device_used=39.38 GiB new_xids=[] new_uncorrectable_ecc=0

There is no safe universal command after this receipt. A request retry, process restart, device quarantine, and node drain act at different scopes. Choose one only after evidence identifies the smallest broken scope.

Why is CUDA out of memory insufficient evidence for draining gpu-a17?

Answer

The error names a failed allocation in one process. It doesn't yet distinguish live application demand, allocator fragmentation, memory held outside PyTorch, a stale process, or a device fault. Draining the node would evict unrelated workloads before that scope is known.

Build an incident receipt before changing state

An incident receipt is a time-aligned record of request, process, device, node, and cluster evidence. Capture it while the failed process still exists. PyTorch can record allocator history and dump a snapshot for memory_viz; its snapshot includes allocator state and OOM events, but only for memory visible to the PyTorch allocator.[1]Reference 1Understanding CUDA Memory Usagehttps://docs.pytorch.org/docs/main/torch_cuda_memory

For r-7812, preservation comes before restart:

  1. Remove the replica from application readiness so new work stops arriving.
  2. Record request ID, pod UID, container restart count, PID, node, GPU UUID, model revision, allocator backend and configuration, CUDA runtime, driver, and timestamps.
  3. Dump the PyTorch memory snapshot if the process still responds.
  4. Record device-wide memory, process accounting, ECC counters, clocks, power, temperature, Xid events, and device-plugin health.
  5. Copy logs and artifacts to incident storage with access controls.
  6. Only then choose containment and repair scope.

This order matters. A process exit destroys allocator history. A device reset can destroy volatile fault context. A node reboot can erase local logs. Preservation is an operational gate, not permission to collect another tenant's prompts, model inputs, or secrets.

Layered triage receipt for request r-7812 on node gpu-a17. PyTorch reports 30.10 GiB allocated and 36.70 GiB reserved, while NVML reports 39.38 GiB device-wide use. The snapshot has 6.10 GiB across inactive split blocks but no such block larger than 0.88 GiB, so a 1.50 GiB allocation fails. Evidence supports removing only the replica from readiness, preserving the snapshot, restarting its process, and re-admitting after memory, error, and probe gates pass.
Three memory views narrow the blast radius. The allocator can explain fragmentation inside its reserve; NVML reveals device use outside that reserve.

The receipt separates several memory quantities:

ViewExact valueWhat it can supportWhat it can't prove
PyTorch allocated30.10 GiBLive tensor blocks known to allocatorWhich tensor is semantically necessary
PyTorch reserved36.70 GiBSegments allocator still holdsContiguous availability for a 1.50 GiB request
Reserved minus allocated6.60 GiBAllocator accounting gap to reconcile in snapshotBytes currently inactive and reusable
Inactive split blocks6.10 GiBFree fragments trapped in partly active segments at OOMOne reusable block of sufficient size
Largest inactive split block0.88 GiBLargest observed fragment in snapshotFuture allocation layout after workload changes
NVML device used39.38 GiBWhole-device usage across CUDA usersOwnership without process or subsystem attribution
NVML used minus reserved2.68 GiBApproximate use outside PyTorch reserveWhether NCCL, another process, or driver state owns it

reserved - allocated is an accounting gap, not a reusable-byte counter. Stronger evidence comes from the snapshot: 6.10 GiB is inactive across split blocks trapped in partly active segments, but no such block exceeds 0.88 GiB, so those fragments can't satisfy a 1.50 GiB request. Meanwhile, the 2.68 GiB device-wide delta is worth attribution, but it isn't large enough to explain the whole failure. Together, these numbers support a working classification of allocator fragmentation under high application demand, with a small outside-PyTorch component. That classification remains a hypothesis until segment and block history confirm why the layout formed.

Keep memory layers separate

GPU memory pressure has four common software layers. Combining them into one “leak” diagnosis produces the wrong repair.

LayerStrong evidenceTypical containmentRepair question
Application allocationsAllocated memory tracks batch, sequence, KV cache, workspace, or retained tensorsReject, shed, or reroute bounded workWhich live state exceeded the admission envelope?
Allocator reservationReserved stays above allocated; snapshot shows inactive blocks and split segmentsRemove replica, preserve snapshot, restart process if policy allowsIs layout fragmented, or is cached reserve expected?
Non-PyTorch allocationNVML/device use materially exceeds PyTorch reserveAttribute libraries and processes before tuning allocatorDoes NCCL, CUDA graph state, custom code, or another framework own it?
Process leakDevice process list shows stale or duplicate owners after expected teardownStop admission to affected device; process owner cleans up within policyWhich lifecycle failed to release the process or context?

PyTorch explicitly warns that its memory profiler can't see allocations made directly through CUDA APIs. NCCL is a documented example. torch.cuda.device_memory_used() provides a device-wide cross-check, and NVML exposes device and process telemetry for independent attribution.[1]Reference 1Understanding CUDA Memory Usagehttps://docs.pytorch.org/docs/main/torch_cuda_memory[2]Reference 2NVML API Reference Guidehttps://docs.nvidia.com/deploy/nvml-api/nvml-api-reference.html

Don't treat reserved - allocated as wasted memory by definition. The caching allocator holds segments so later allocations avoid expensive device synchronization. Fragmentation becomes plausible when an OOM snapshot shows enough inactive split bytes but no fragment large enough for the failed request. PyTorch allocator configuration can change split behavior, yet tuning it before identifying the workload shape can hide an admission-control bug.[3]Reference 3CUDA semantics.https://docs.pytorch.org/docs/2.13/notes/cuda.html

This receipt assumes PyTorch's native caching allocator. With backend:cudaMallocAsync, some allocator statistics have backend-specific or undefined meaning, and native split-block tuning options don't apply. Record the backend and use its documented evidence instead of copying this inference unchanged.[3]Reference 3CUDA semantics.https://docs.pytorch.org/docs/2.13/notes/cuda.html

Record a finite allocator history

Enable history before the incident window when overhead and privacy policy permit:

allocator-history.py
1import torch 2 3torch.cuda.memory._record_memory_history( 4 enabled="all", 5 context="all", 6 stacks="python", 7 max_entries=100_000, 8) 9 10torch.cuda.memory._dump_snapshot("r-7812-memory.pickle")

The initial _ marks these as private APIs, so pin and validate the PyTorch version used by your fleet. Open the pickle in the local memory_viz page. PyTorch says the browser processes the file locally without uploading it.[1]Reference 1Understanding CUDA Memory Usagehttps://docs.pytorch.org/docs/main/torch_cuda_memory

History is a ring buffer, not an infinite flight recorder. Once max_entries fills, the oldest entries are replaced. Large histories can produce multi-gigabyte snapshots. Set a bounded window, record the start time and entry limit in the receipt, and trigger a dump near the failure. A snapshot with no OOM event may mean capture began too late or history wrapped, not that the alert was false.

A snapshot shows 6.10 GiB across inactive split blocks, but NVML reports 2.68 GiB more device use than PyTorch reserved. What should you conclude?

Answer

Two hypotheses remain. Allocator layout may block the 1.50 GiB request, while another CUDA user owns about 2.68 GiB. Inspect snapshot blocks and attribute device processes or libraries. Neither number alone proves a leak.

Classify beyond memory

An OOM can be the visible end of a different failure. A collective stalls, a peer disappears, requests accumulate, and healthy ranks hold buffers until an allocation fails. Build a parallel device and node view.

Fault classEvidence to correlateWhy symptom can misleadInitial scope
ECC or device faultNew uncorrectable ECC, GPU UUID, kernel timestamp, device healthOOM or timeout can follow lost device accessDevice or node quarantine pending memory-error guidance
Xid eventExact code, GPU UUID, kernel timestamp, catalog action, nearby eventsSame code family can reflect application, NVIDIA software, or hardwareScope named by event-specific catalog and surrounding evidence
PCIe or NVLink faultDCGM PCIe, NVLink, nvbandwidth, or NCCL test; link counters; peer topologyOne slow or failed rank appears as a distributed timeoutAffected GPU topology, then node if isolation is unavailable
Clock limitingExact clock-event reasons, configured limits, temperature, power, clocks, workload phaseAn expected power cap and a thermal fault can both reduce clocksReplica first; platform path if unexpected under controlled load
Driver or runtime faultDriver/runtime versions, module logs, NVML initialization, DCGM software testApplication sees initialization or unknown CUDA errorStop admission; platform owner validates stack contract
CUDA process-state faultExact CUDA error, first failing operation, synchronization pointAsynchronous execution reports an earlier failure laterProcess, unless device evidence expands scope

NVML clock-event reasons name the active limiter, not its root cause. GPU idle and configured application clocks can be expected. Software power cap means clocks are respecting a configured power limit, while thermal slowdown points to temperature protection. Correlate reason, workload phase, configured limits, measured power, and temperature before calling it a fault.[2]Reference 2NVML API Reference Guidehttps://docs.nvidia.com/deploy/nvml-api/nvml-api-reference.html

An Xid entry is not a root cause label. NVIDIA states that Xid events can arise from hardware, NVIDIA software, or an application. Recovery actions differ by event, and newer catalog guidance can attach a specific recovery action to the reported event.[4]Reference 4Introduction to Xid Errorshttps://docs.nvidia.com/deploy/xid-errors/introduction.html[5]Reference 5Analyzing Xid Errors Using the Xid Cataloghttps://docs.nvidia.com/deploy/xid-errors/analyzing-xid-catalog.html

The GPU Operator device plugin listens for health events and can report a GPU unhealthy. Kubernetes then lowers allocatable device count, but pods already assigned to that device remain assigned and may fail or crash-loop.[6]Reference 6NVIDIA GPU Operator Troubleshootinghttps://docs.nvidia.com/datacenter/cloud-native/gpu-operator/26.3/troubleshooting.html[7]Reference 7Device Pluginshttps://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/ Application readiness and workload containment still need an explicit controller or operator action. Device-plugin health alone is not retrospective eviction.

Respect asynchronous error reporting

CUDA work is asynchronous. An API call can enqueue work and return before the device executes it; an error may surface at a later synchronization boundary. Capture the first observed failure, stream, request, kernel, and correlation timestamp. CUDA_LAUNCH_BLOCKING=1 can help reproduce ordering in a controlled debug run, but it changes execution and should not become a fleet-wide production setting.[8]Reference 8CUDA Programming Guide.https://docs.nvidia.com/cuda/cuda-programming-guide/

Some CUDA runtime errors explicitly leave the process in an inconsistent state. NVIDIA documents illegal address, kernel-execution launch timeout, launch failure, and several hardware-stack errors as requiring process termination and relaunch. Retrying another request in that same process is unsafe. This rule doesn't apply to every CUDA error, so preserve the exact error enum and originating API operation rather than matching the word “CUDA.”[9]Reference 9CUDA Runtime API Error Typeshttps://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__TYPES.html

Contain at smallest broken scope

Use a ladder. Move outward only when evidence says the smaller boundary can't protect users or hardware.

ActionAppropriate evidenceWhat must be true firstWhy a broader action is risky
Retry request elsewhereIdempotent or deduplicated request; healthy alternate replica; failed process still trustworthy or excludedRetry budget and side-effect contract permit replayBlind retries amplify memory pressure and duplicate effects
Remove replica from readinessOne worker is unhealthy or near its memory envelopeGateway and scheduler honor readiness quicklyTraffic can keep reaching a process that should be preserved
Restart processAllocator fragmentation, process leak owned by replica, or fatal CUDA process-state errorReceipt and snapshot preserved; restart budget permits itRestart erases volatile evidence and can loop on a bad device
Quarantine GPUNew uncorrectable ECC, isolation-requiring Xid action, fabric finding, or repeated device-scoped evidenceDevice identity and cluster owner are knownShared node may lose capacity; peer topology can be affected
Cordon or drain nodeNode-wide driver, fabric, power, cooling, or repair requirementPlatform owner authorizes scope; workload disruption reviewedDrain can evict unrelated tenants and destroy local ephemeral data
Diagram showing Replica reports failure, Preserve receipt and snapshot, Classify smallest broken scope, and request or process.
Replica reports failure, Preserve receipt and snapshot, Classify smallest broken scope, and request or process.

For r-7812, the request is safe to retry on a different healthy replica only if its operation is idempotent or deduplicated. The failed replica leaves readiness. Its snapshot and receipt are copied. Because evidence points to allocator layout and the CUDA error is OOM rather than an error documented as process-corrupting, policy may allow graceful process teardown and relaunch. No ECC, Xid, link, stack, thermal, or power signal currently supports a node drain.

An illegal-address error appears after a request, but the next health check passes. May the worker serve another request?

Answer

No. CUDA documents illegal address as leaving the process in an inconsistent state. Remove the worker from readiness, preserve evidence, terminate and relaunch the process, then apply re-admission gates. A passing application probe doesn't repair CUDA process state.

Run diagnostics with an explicit question

DCGM diagnostics are active tests, not repair commands. NVIDIA describes four levels:

DCGM levelIntended operational useRepresentative additionsScheduling rule
Level 1Fast readiness signal before workDeployment and software checksMay fit an admission gate after local validation
Level 2Failure epilogue or brief health checkPCIe, memory, memory bandwidth, NVLinkRun outside user traffic when tests can contend
Level 3Admin post-mortemDiagnostic stress, targeted power/stress, nvbandwidth, NCCL testsQuarantined or idle hardware only
Level 4Extended post-mortemLonger memory and pulse-style coverageMaintenance window with platform ownership

Exact tests depend on DCGM version, hardware, driver, and installed plugins. A named test may be unavailable. In plugin output, Pass applies only to checks that ran, Fail may be a device finding or a test-setup error, and Skip gives no health verdict. Treating Skip as Pass turns missing coverage into false readiness.[10]Reference 10DCGM Diagnosticshttps://docs.nvidia.com/datacenter/dcgm/latest/user-guide/dcgm-diagnostics.html[11]Reference 11DCGM Diagnostic Pluginshttps://docs.nvidia.com/datacenter/dcgm/latest/reference/diagnostics/plugins/index.html

Ask one question per run:

  • “Can this GPU enumerate and pass deployment checks?” points toward Level 1.
  • “Did memory or PCIe fail around this incident?” points toward selected Level 2 tests.
  • “Can the quarantined tensor-parallel topology sustain fabric traffic?” points toward nvbandwidth or NCCL plugins at an admin level.
  • “Does the device reproduce a memory or power failure under burn-in?” points toward selected stress tests on idle hardware.

Record command, DCGM version, selected entities, test names, parameters, wall time, plugin availability, raw result, and exit status. DCGM doesn't claim comprehensive diagnosis or automatic repair. A passing suite narrows evidence; it doesn't erase an Xid or guarantee future health.[10]Reference 10DCGM Diagnosticshttps://docs.nvidia.com/datacenter/dcgm/latest/user-guide/dcgm-diagnostics.html

Make ownership part of automation

A multi-tenant GPU node has at least four owners:

BoundaryOwner decisionAutomation may do safelyEscalation trigger
RequestServing teamBound retries, deduplicate effects, route away from unhealthy replicaSide-effect ambiguity or exhausted retry budget
Process or podWorkload ownerToggle readiness, preserve app receipt, restart within disruption budgetRepeated crash or cross-process memory owner
GPU devicePlatform GPU controllerMark device unavailable, attach evidence, stop new allocationNew uncorrectable ECC, isolation-requiring Xid action, fabric finding, or repeated burn-in failure
Node and rackCluster or hardware ownerCordon, drain, repair, reboot, or replace under policyShared driver, cooling, power, PCIe, or topology fault

Error-aware automation consumes structured facts, not log substrings alone. A useful event includes GPU UUID, node UID, workload UID, process identity, exact CUDA or Xid code, source, first and last timestamps, recurrence count, and evidence links. Its transition should be idempotent: one device fault creates one quarantine record, not a storm of repeated drains.

Never let a workload controller reset a shared GPU or drain a node by inference. NVIDIA's own GPU Operator upgrade workflow separates cordon, workload termination, validation, and uncordon. Its documentation warns that full drain can evict unrelated pods and can permanently remove emptyDir data.[12]Reference 12Automated Driver Upgradehttps://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-driver-upgrades.html Production remediation needs equivalent scope checks and authority.

Preserved evidence also needs tenancy controls:

  • Snapshot allocator metadata, not prompt bodies, unless incident policy explicitly requires content.
  • Restrict process lists and command lines when they expose another tenant's paths or arguments.
  • Attach retention, encryption, and access policy to receipts.
  • Store stable IDs and hashes so responders can correlate without copying sensitive payloads.

Repair path for gpu-a17

The repair is intentionally narrow:

  1. Contain: Set summarizer-7f9d6 not ready. Stop scheduler admission to its process.
  2. Preserve: Save snapshot, application logs, exact versions, NVML memory and process view, ECC counters, clocks, power, temperature, and kernel Xid window.
  3. Classify: Confirm 30.10 GiB allocated, 36.70 GiB reserved, 6.10 GiB inactive across split blocks, 0.88 GiB largest fragment, and 39.38 GiB device-wide use. Attribute the 2.68 GiB delta.
  4. Repair process: Finish or reject in-flight work according to the request contract. Relaunch the serving process under its normal supervisor.
  5. Prove baseline: Load the same model revision and configuration. Confirm expected idle memory and one process owner.
  6. Burn in: Replay a bounded canary workload that includes the 1.50 GiB allocation shape. Watch allocator headroom, device-wide delta, Xid/ECC, link status, clocks, temperature, power, and latency.
  7. Re-admit: Restore only a small traffic fraction. Expand after a fixed observation window with no gate failure.

If fragmentation returns under the same bounded workload, process restart was containment, not repair. Revisit admission envelopes, KV-cache sizing, batch and sequence caps, workspace lifetime, CUDA graph pools, and allocator configuration. If outside-PyTorch use grows, attribute NCCL, custom CUDA, peer processes, or context lifecycle before changing allocator settings.

Re-admission gates

Use explicit pass/fail gates rather than “looks stable”:

GateExample evidenceFailure action
IdentityExpected GPU UUID, driver/runtime pair, model revision, one intended process ownerHold admission and resolve inventory mismatch
Idle baselineDevice-wide and allocator memory inside known bandInvestigate stale process, context, or changed model footprint
Functional probeDeterministic canary returns expected shape and statusKeep replica out of readiness
Memory envelopePeak allocated, reserved, largest reusable block, and outside delta remain within policyAdjust workload or allocator plan before retry
Device healthNo new disqualifying Xid/ECC; required DCGM checks ran and passedKeep quarantined; follow event-specific owner runbook
Fabric healthRequired peer path and selected fabric tests pass on affected topologyKeep topology unavailable
Thermal and powerStable clocks, temperature, and power during bounded loadEscalate cooling, power, or hardware path
SoakFixed request count or duration completes without recurrenceExtend quarantine and compare receipts

Burn-in must resemble the failed allocation and communication shape without carrying production traffic. “One inference succeeded” misses fragmentation that emerges after many allocation cycles and fabric faults that need multi-GPU load. Define duration, load, pass thresholds, and abort conditions before starting.

A Level 2 DCGM run reports PCIe Pass and nvbandwidth Skip. Can automation re-admit a topology whose incident involved NVLink timeouts?

Answer

No. PCIe Pass covers only the check that ran. Skip is no health verdict, and the missing fabric coverage is relevant to the incident. Keep the topology quarantined until the required test can run or an authorized owner chooses another evidence path.

Downloadable receipt analyzer

The fixture contains eight synthetic receipts spanning allocator fragmentation, application capacity, outside-PyTorch ownership, device fault, fabric fault, clock limiting, process-corrupting CUDA error, and driver/runtime failure.

  • Download fixture
  • Download read-only analyzer

The analyzer doesn't reset, kill, drain, or delete anything. It sorts evidence into a first hypothesis and a scoped next step. Its memory rows assume PyTorch's native allocator. new_xids and new_uncorrectable_ecc cover only the incident window. clock_event_reasons contains only limiters that were unexpected for the workload phase and correlated with the regression. cuda_error is normalized only after recording the exact enum and originating API operation; launch_timeout here means the process-invalidating kernel-execution error. dcgm_findings contains defect classes after an operator or version-pinned parser has inspected each Fail code and message; raw Fail and Skip results don't qualify. The fixture's 4.0 GiB outside-PyTorch threshold is illustrative, not universal. Production automation still needs workload-specific bands, platform policy, event-specific guidance, and ownership checks.

assets/analyze_gpu_receipts.py
1import json 2from pathlib import Path 3 4FIXTURE = Path("assets/gpu_failure_receipts.json") 5PROCESS_INVALIDATING_ERRORS = { 6 "assert", 7 "hardware_stack_error", 8 "illegal_address", 9 "illegal_instruction", 10 "invalid_address_space", 11 "invalid_pc", 12 "launch_failure", 13 "launch_timeout", 14 "misaligned_address", 15 "mps_client_terminated", 16 "tensor_memory_leak", 17} 18STACK_ERRORS = {"insufficient_driver", "initialization_error", "system_driver_mismatch"} 19OUTSIDE_PYTORCH_ALERT_GIB = 4.0 20 21def classify(row: dict) -> tuple[str, str]: 22 if row["new_uncorrectable_ecc"]: 23 return "device-memory-fault", "quarantine device; follow memory-error guidance" 24 if {"pcie", "nvlink", "nvbandwidth"} & set(row["dcgm_findings"]): 25 return "fabric-fault", "quarantine affected topology; run scoped fabric diagnostics" 26 if row["new_xids"]: 27 return "xid-event", "map exact Xid to catalog action before choosing scope" 28 if row["cuda_error"] in STACK_ERRORS or "software" in row["dcgm_findings"]: 29 return "driver-runtime", "hold admission; platform owner checks driver/runtime contract" 30 if row["cuda_error"] in PROCESS_INVALIDATING_ERRORS: 31 return "process-corrupted", "stop retries in this process; preserve receipt and relaunch" 32 if row["clock_event_reasons"]: 33 return "clock-limited", "remove from readiness; compare reason, limit, power, and temperature" 34 35 outside_pytorch = max( 36 0.0, row["nvml_device_used_gib"] - row["pytorch_reserved_gib"] 37 ) 38 if outside_pytorch >= OUTSIDE_PYTORCH_ALERT_GIB or row["stale_processes"]: 39 return "outside-pytorch", "attribute device-wide delta before changing allocator settings" 40 if ( 41 row["oom_request_gib"] > 0 42 and row["inactive_split_block_total_gib"] >= row["oom_request_gib"] 43 and row["largest_inactive_split_block_gib"] < row["oom_request_gib"] 44 ): 45 return "allocator-fragmentation", "remove replica; inspect snapshot before process restart" 46 if row["oom_request_gib"] > 0: 47 return "application-capacity", "reduce live demand or admission; prove headroom before retry" 48 return "unclassified", "preserve receipt; collect evidence for the missing failure class" 49 50rows = json.loads(FIXTURE.read_text(encoding="utf-8")) 51for row in rows: 52 label, next_step = classify(row) 53 outside = max(0.0, row["nvml_device_used_gib"] - row["pytorch_reserved_gib"]) 54 print( 55 f'{row["receipt_id"]}: {label:23} ' 56 f'outside={outside:5.2f} GiB | {next_step}' 57 )
Output
1r-7812: allocator-fragmentation outside= 2.68 GiB | remove replica; inspect snapshot before process restart 2r-7813: application-capacity outside= 0.20 GiB | reduce live demand or admission; prove headroom before retry 3r-7814: outside-pytorch outside=16.40 GiB | attribute device-wide delta before changing allocator settings 4r-7815: device-memory-fault outside= 1.10 GiB | quarantine device; follow memory-error guidance 5r-7816: fabric-fault outside= 1.00 GiB | quarantine affected topology; run scoped fabric diagnostics 6r-7817: clock-limited outside= 1.00 GiB | remove from readiness; compare reason, limit, power, and temperature 7r-7818: process-corrupted outside= 0.70 GiB | stop retries in this process; preserve receipt and relaunch 8r-7819: driver-runtime outside= 0.00 GiB | hold admission; platform owner checks driver/runtime contract

Notice the precedence. A new uncorrectable ECC event and decoded fabric finding outrank an OOM-derived memory guess. An Xid takes its scope from the event-specific catalog instead of being called a hardware fault by default. Process-invalidating CUDA errors outrank allocator arithmetic. Only then does the analyzer compare device-wide use, allocator reserve, inactive split blocks, and largest fragment. This is triage, not autonomous remediation.

Mastery rubric

You can operate this incident when you can:

  • Reconcile allocated, reserved, inactive, largest-block, and device-wide memory without calling every delta a leak.
  • Explain what a PyTorch snapshot omits and how finite history can erase the event you need.
  • Preserve request, process, device, node, and cluster evidence before destructive state changes.
  • Separate ECC/Xid, fabric, thermal/power, stack, and process-state evidence.
  • Choose retry, process restart, device quarantine, or node drain from explicit scope and authority.
  • Interpret DCGM level, selected plugin, Pass, Fail, and Skip without inflating coverage.
  • Define readiness and burn-in gates tied to the original failure shape.

Score yourself on one unseen receipt:

LevelEvidenceDecision quality
0: symptom onlyRepeats alert textChooses action from OOM or Xid keyword
1: partial receiptCaptures one memory or device viewNames hypotheses but can't bound scope
2: scoped responseCorrelates process, device, node, and timeContains smallest supported boundary and preserves evidence
3: safe recoveryAdds owner, test coverage, and thresholdsRe-admits through failure-shaped burn-in with rollback criteria

Pitfalls that widen blast radius

  • Calling cached reserve a leak. Reserved memory is allocator policy; snapshot block history decides whether fragmentation is plausible.
  • Reading NVML delta as proof of another process. Direct CUDA, NCCL, graphs, libraries, and peer processes all need attribution.
  • Retrying in a corrupted CUDA process. Exact runtime error semantics decide whether relaunch is mandatory.
  • Treating every Xid alike. Xid is a structured clue; catalog guidance and surrounding evidence decide scope.
  • Treating Skip as Pass. Missing plugin coverage can't satisfy a readiness gate.
  • Restarting before preservation. The restart may clear the only allocator or kernel evidence.
  • Draining for convenience. Shared-node eviction and ephemeral-data loss require platform authority and review.
  • Re-admitting after one probe. Short probes miss allocation-cycle fragmentation, topology load, and thermal soak failures.

Check your understanding

Complete the lesson

Mastery Check

Answer every question, then check your score. Score 75% or higher to mark this lesson complete.

1.A snapshot reports 6.10 GiB across inactive split blocks, a 0.88 GiB largest fragment, and a failed 1.50 GiB request. Which conclusion is strongest?

Correct answer: Fragmentation is plausible because inactive split total exceeds the request but the largest fragment doesn't.

Block layout supports fragmentation as a working hypothesis. Application pressure and outside-PyTorch use still need attribution.

2.PyTorch reserved memory is 18.0 GiB while NVML device use is 34.4 GiB. What is the best next step?

Correct answer: Attribute direct CUDA, library, and process owners before changing the allocator policy.

The delta sits outside PyTorch's allocator view, but the receipt hasn't identified its owner.

3.Why can a memory snapshot omit an OOM event even when the alert is valid?

Correct answer: Finite history may start late or overwrite older entries after reaching its entry limit.

PyTorch records a bounded history. Late capture and ring-buffer overwrite can remove the relevant event.

4.A worker reports cudaErrorIllegalAddress, then passes its HTTP health check. What action fits CUDA's documented process state?

Correct answer: Remove readiness, preserve evidence, terminate the process, and relaunch it.

Illegal address leaves the CUDA process inconsistent. That evidence alone doesn't expand scope to the node.

5.A device plugin marks one GPU unhealthy on a node with an already assigned pod. What does Kubernetes guarantee?

Correct answer: Allocatable device count falls, while the assigned pod may remain and continue failing.

Device health changes future allocation. Existing assignments and application readiness need separate handling.

6.Which response best preserves evidence for one OOM replica with no device-fault signal?

Correct answer: Stop replica admission, capture allocator and device receipts, then choose restart scope.

This contains user impact while retaining volatile process and device evidence.

7.DCGM reports PCIe Pass and nvbandwidth Skip after a multi-GPU timeout. Which interpretation is correct?

Correct answer: The PCIe check passed, while required bandwidth coverage remains unknown.

Pass and Skip describe different coverage. Skip supplies no health verdict.

8.A shared node has repeated power-cap clock events only under burn-in. Which boundary should decide node repair?

Correct answer: Platform or hardware owner, using power, thermal, clock, and workload evidence.

The evidence crosses workload scope into node power or cooling ownership.

9.After restarting r-7812's process, which burn-in most directly tests the original hypothesis?

Correct answer: Replay bounded allocation cycles including the 1.50 GiB shape while tracking block layout and device delta.

The burn-in reproduces allocation size and lifecycle while observing allocator and device-wide views.

9 questions remaining.

Next Step
Continue to Distributed Inference Data Plane

Carry the same evidence, ownership, and retry boundaries across routing, <span data-glossary="prefill">prefill</span>, KV transfer, and decode workers.

PreviousGPU Serving & Autoscaling
Share this article
XFacebookLinkedInBlueskyRedditHacker NewsEmail
References

Understanding CUDA Memory Usage

PyTorch Contributors · 2026 · Official documentation

https://docs.pytorch.org/docs/main/torch_cuda_memory

NVML API Reference Guide

NVIDIA · 2026 · Official documentation

https://docs.nvidia.com/deploy/nvml-api/nvml-api-reference.html

CUDA semantics.

PyTorch Contributors · 2026

https://docs.pytorch.org/docs/2.13/notes/cuda.html

Introduction to Xid Errors

NVIDIA · 2026 · Official documentation

https://docs.nvidia.com/deploy/xid-errors/introduction.html

Analyzing Xid Errors Using the Xid Catalog

NVIDIA · 2026 · Official documentation

https://docs.nvidia.com/deploy/xid-errors/analyzing-xid-catalog.html

NVIDIA GPU Operator Troubleshooting

NVIDIA · 2026 · Official documentation

https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/26.3/troubleshooting.html

Device Plugins

Kubernetes Authors · 2026 · Official documentation

https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/

CUDA Programming Guide.

NVIDIA · 2026

https://docs.nvidia.com/cuda/cuda-programming-guide/

CUDA Runtime API Error Types

NVIDIA · 2026 · Official documentation

https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__TYPES.html

DCGM Diagnostics

NVIDIA · 2026 · Official documentation

https://docs.nvidia.com/datacenter/dcgm/latest/user-guide/dcgm-diagnostics.html

DCGM Diagnostic Plugins

NVIDIA · 2026 · Official documentation

https://docs.nvidia.com/datacenter/dcgm/latest/reference/diagnostics/plugins/index.html

Automated Driver Upgrade

NVIDIA · 2026 · Official documentation

https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-driver-upgrades.html

Discussion

Questions and insights from fellow learners.

Discussion loads when you reach this section.