💡학습 돌릴 때 컴퓨터가 멈춘다면 — GPU가 아니라 RAM(스왑 스래싱)
🧊 증상
Isaac Sim에서 병렬 환경(env) 수천 개로 RL 학습을 돌리다 보면 이런 일이 생긴다.
- 마우스가 뚝뚝 끊기다가 아예 멈춤
- 창 전환(Alt-Tab)도 안 됨
- 학습이 죽는 게 아니라 컴퓨터 전체가 얼어붙음
- 한참 뒤에 풀리거나, 강제 재부팅
GPU가 큰 워크스테이션(예: RTX 5090 32GB)이니 “GPU가 터졌나?” 싶지만 — 대부분 GPU 문제가 아니다.
🔍 진단 — 먼저 이 두 개를 본다
멈추기 직전(또는 다른 터미널에서) 아래를 확인한다.
내 경우 실제 수치는 이랬다(8192 env 학습 중):
| 자원 | 상태 | 판정 |
|---|---|---|
| GPU 메모리 | 28.7 / 32.6 GB | 여유 있음 ✅ |
| GPU 온도·전력 | 54°C, 217W / 600W | 문제없음 ✅ |
| 시스템 RAM | 29 / 30 GB, 여유 364MB | 한계 초과 ❌ |
| 학습 프로세스 단독 | 25.1 GB | 이게 원인 |
| 스왑 | 2.1 / 8 GB, 계속 증가 | 스래싱 시작 |
❗ GPU는 8192 env를 감당하는데, 호스트 RAM 30GB가 못 버틴다. 병렬 env 상한을 정하는 건 GPU가 아니라 CPU-side RAM인 경우가 많다.
💥 왜 “학습 크래시”가 아니라 “전체 프리즈”인가 — 스왑 스래싱
메커니즘은 이렇다.
- 병렬 env가 호스트 RAM을 거의 다 먹는다(위 예에서 25GB).
- OS·데스크톱 환경·브라우저·에디터에 남는 RAM이 2GB 미만.
- free RAM이 0에 가까워지면 커널이 활성 페이지를 디스크 스왑파일로 밀어냈다 다시 당겨오길 반복한다.
- 이때 GUI(컴포지터)의 페이지까지 스왑아웃되고, 디스크 I/O가 포화 → 온 시스템이 멈춘다.
이게 리눅스 데스크톱의 전형적인 “swap death”(스왑 스래싱) 이다. 프로세스 하나가 깔끔하게 OOM-kill되는 게 아니라, 커널이 스왑을 오가며 발버둥치는 동안 모든 게 얼어붙는다.
✅ 근본 해결
1. 병렬 env 수를 낮춘다 (가장 큰 레버)
RAM이 상한이므로 env를 줄이는 게 정공법이다.
RL(PPO 등)은 4096 env로도 충분하다. GPU는 8192를 감당하더라도, RAM이 못 버티면 의미가 없다. 학습 품질 손해는 거의 없다.
2. 학습을 “스왑 금지 메모리 캡” cgroup에 격리한다
env를 줄여도 만일의 메모리 급증(누수·스파이크)에 대비하려면, 학습 프로세스를 메모리 상한이 걸린 cgroup에 가둔다. 그러면 한계 초과 시 전체 프리즈 대신 그 프로세스만 격리 kill되고, 데스크톱은 살아있다.
sudo 없이도 된다(요즘 배포판은 cgroup v2에서 메모리 컨트롤러가 user 슬라이스에 위임돼 있음):
MemoryMax: 하드 상한. 넘으면 이 스코프만 OOM-kill.MemoryHigh: 소프트 상한. 넘으면 커널이 reclaim으로 throttle.MemorySwapMax=0이 핵심 — 학습이 스왑을 아예 못 쓰게 막아 스래싱(=프리즈)을 원천 차단한다. 스왑 대신 즉시 격리 kill.
자동 재개 스크립트(크래시 시 최신 체크포인트에서 이어받기)와 함께 쓰면, 격리 kill 되더라도 학습이 알아서 복구된다.
🛡️ 안전망 (선택)
근본 해결(1+2) 위에 얹는 보험. 이건 sudo가 필요하다.
earlyoom — 프리즈 직전에 대신 죽여주는 데몬
systemd-oomd가 active여도 프리즈를 못 막는 경우가 많다. earlyoom은 더 공격적으로, 사용 가능 메모리가 임계 아래로 떨어지면 가장 큰 프로세스를 미리 죽여 데스크톱을 살린다.
swappiness 낮추기 — 스왑보다 캐시 회수 선호
기본값 60은 공격적으로 스왑한다. 10으로 낮추면 커널이 스왑보다 페이지 캐시 회수를 먼저 시도한다(스래싱 지연). 단, 진짜 RAM 고갈 상황에선 지연일 뿐이므로 1·2번이 우선이다.
🧭 다른 컴퓨터에서도 — 빠른 체크리스트
학습 중 시스템이 멈춘다면 순서대로:
free -h→ RAM 여유가 1GB 미만이고 스왑이 늘고 있으면 → 이 글의 상황이다(GPU 아님).nvidia-smi→ GPU 메모리에 여유가 있으면 확증. 원인은 호스트 RAM.- 병렬 env / batch / worker 수를 낮춰 RAM 사용을 시스템 총량보다 충분히 아래로.
- 학습을
systemd-run --user --scope -p MemoryMax=… -p MemorySwapMax=0로 격리. - 여유가 있으면 earlyoom 설치 + swappiness=10.
🧠 하드웨어 관점(장기): GPU 메모리에 비해 시스템 RAM이 작으면(예: 32GB GPU + 30GB RAM) 병렬도 상한을 RAM이 정한다. RAM 증설이 진짜 해결책이지만, 위 소프트웨어 조치만으로도 프리즈는 없앨 수 있다.
📌 한 줄 요약
컴퓨터가 멈추는 건 GPU가 아니라 RAM 부족 → 스왑 스래싱. 병렬 수를 낮추고, 학습을 스왑 금지 메모리 캡 cgroup에 격리하면 근본적으로 사라진다.