"Clear the VRAM cache" is really two different problems wearing the same name. If your Python process is still running and just accumulated unused cached memory, torch.cuda.empty_cache() handles it. If your process already crashed and nvidia-smi still shows it holding gigabytes of memory, no in-process call can fix that — you have to find the process ID and kill it directly, because the CUDA context it created is what's actually holding the allocation.
Diagnosing and recovering from GPU memory lockup
1. Check what's actually holding memory. Run nvidia-smi and look at the process list at the bottom of the output — it shows every process with an active CUDA context and how much memory each one holds.
2. If the process is alive, free cached memory in-process. Call torch.cuda.empty_cache() and, if you're holding references to old tensors, explicitly del them first — empty_cache() only returns memory PyTorch has already marked as free, not memory still referenced by a live tensor.
3. If the process is dead but memory is still held, kill it directly. Use the PID from nvidia-smi with kill -9 <pid> (Linux) or Task Manager / taskkill /PID <pid> /F (Windows) — this is the actual fix for the "crashed but VRAM still full" case, not a cache-clearing call.
# 1. See which processes are actually holding GPU memory
nvidia-smi
# Example output includes a process table like:
# PID Type Process name GPU Memory Usage
# 14231 C python3 6142MiB
# 2. If that PID belongs to a crashed/zombie process, kill it directly
kill -9 14231
# 3. In a live Python session, free cached (but unused) memory instead
import torch
del model, batch # drop references first
torch.cuda.empty_cache() # then release the cache
| Situation | Correct Fix | Why empty_cache() Alone Fails |
|---|---|---|
| Live process, memory fragmented/unused | del stale tensors, then torch.cuda.empty_cache() |
N/A — this is the case it's designed for |
| Process crashed, VRAM still shown as used | Find the PID in nvidia-smi and kill it directly |
The allocating process no longer exists to call the API in |
The underlying lesson generalizes past GPUs: any "just clear the cache" fix only works if the process that owns the resource is still alive to run it. Once a process has crashed or hung, the operating system's process table — not the framework's in-memory API — is the source of truth for what's actually still holding a resource.
Practical Challenge
Deliberately trigger a CUDA OOM (allocate a tensor larger than your free VRAM), then run nvidia-smi to confirm whether the crashed process released its memory automatically or needs a manual kill.
Concept Check
torch.cuda.empty_cache() fix VRAM still shown as occupied by a process that has already crashed?nvidia-smi, not to call an in-process API that no longer has a process to run in.Sources & Further Reading
- PyTorch Documentation: torch.cuda.empty_cache — the official reference confirming it only releases unused cached memory, not memory held by other processes.
- NVIDIA System Management Interface (nvidia-smi) Documentation — reference for reading the process table and per-process memory usage.
- PyTorch CUDA Semantics: Memory Management — background on the caching allocator and the
expandable_segmentsfragmentation mitigation.
AI