본문으로 건너뛰기

[HPC 101] 작업 디버깅: 내 작업이 왜 실패했을까?

Will Paik
작성자
Will Paik
대규모 GPU 클러스터를 최적화하는 HPC 엔지니어. 밤에는 방구석 미니 슈퍼컴퓨터를 조립하며(가끔은 태워 먹으며) 그 과정을 기록합니다.
HPC 101 - 이 글은 시리즈의 일부입니다.
파트 4: 이 글

실제 세계에서는 제출 버튼을 누르는 게 시작일 뿐입니다.

HPC 101 시리즈의 마지막 편에 온 걸 환영합니다.

지금까지 필수 내용을 다뤘습니다. 로그인, 데이터 이동, 환경 관리. 마침내 작업을 제출했습니다.

그런데 가끔 일이 틀어지죠.

  • 작업이 영원히 ‘대기 중’ 상태입니다.
  • 시작하고 2초 만에 충돌합니다.
  • 3일 동안 돌았는데 빈 파일만 남았습니다.

오늘은 HPC ‘생존 기술’을 배울 겁니다. 실패한 작업을 디버깅하는 방법, 리소스 효율을 확인하는 방법, 그리고 대기열에서 막힌 이유를 알아보는 방법입니다.

1. 상세 모니터링 (scontrol)
#

작업을 제출했습니다. squeue --me를 입력했더니 P (대기 중)라고 나옵니다. 10분이 지났는데 여전히 대기 중입니다. 아니면 실행 중인데 어디서 돌고 있는지 모를 수도 있습니다.

$ squeue --me
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
             12345       cpu     bash  user123  P       0:00      1 (Priority)
             12346       gpu     bash  user123  P       0:00      1 (Resources)

squeue는 간단한 요약만 보여줍니다. 전체 보고서가 필요할 때가 있습니다. scontrol show job <JOBID> 명령어를 씁니다.

$ scontrol show job 12345
JobId=12345 JobName=bash
   UserId=user123(123456) GroupId=users(1000)
   ...
   JobState=PENDING Reason=Resources
   ...
   StartTime=2026-01-25T21:00:00 EndTime=Unknown
   NodeList=(null)
   WorkDir=/home/user123/my_project
   Command=/bin/bash
   ...

살펴볼 핵심 필드:

  1. JobState & Reason: 왜 기다리고 있는지 정확히 알려줍니다 (예: Resources, Priority).
  2. StartTime: 스케줄러가 예상하는 시작 시간입니다. (다른 우선순위 높은 작업이 들어오면 바뀔 수 있습니다).
  3. NodeList: 실행 중이라면 어느 컴퓨트 노드를 쓰는지 보여줍니다 (예: compute-node-01).
  4. WorkDir: 스크립트가 어디서 실행되고 출력 파일이 어디에 저장되는지 확인해줍니다.

Linux 팁: grep이 뭔가요? scontrol 출력이 너무 길어지면 파이프 |grep으로 필터링할 수 있습니다.

  • | (파이프): 왼쪽 명령어의 출력을 오른쪽 명령어로 전달합니다.
  • grep: 터미널의 Ctrl + F입니다. 키워드가 포함된 줄만 출력합니다.
# StartTime 줄만 보여줘
$ scontrol show job 12345 | grep StartTime
StartTime=2026-01-25T22:00:00 EndTime=2026-01-25T23:00:00

2. 비상 버튼 (scancel)
#

실수로 노드를 100개 요청했습니다. 아니면 코드가 무한 루프에 빠졌습니다.

그냥 알아서 실패하도록 두지 마세요. 바로 취소하세요.

# 특정 작업 취소
$ scancel 12345

# 내 모든 작업 취소
$ scancel -u user123
# 특정 작업 취소
$ qdel 12345

# 내 모든 작업 취소 (시스템에 따라 다를 수 있습니다)
$ qselect -u user123 | xargs qdel

3. 탐정 작업 (sacct & 로그)
#

커피 한 잔 하고 왔는데 작업이 큐에서 사라졌습니다. 끝났을까요, 아니면 실패했을까요? 큐(squeue)에 없으니 히스토리를 확인해야 합니다.

1단계: 상태 확인 (sacct)
#

명령어는 sacct (Slurm Accounting)입니다. 기본 출력이 정리가 안 돼 있어서 형식 옵션을 씁니다.

$ sacct -j 12345 --format=JobID,State,AllocCPUS,ReqMem,MaxRSS,Elapsed,ExitCode
JobID             State  AllocCPUS     ReqMem     MaxRSS    Elapsed ExitCode
------------ ---------- ---------- ---------- ---------- ---------- --------
12345            FAILED          1         2G              00:10:15    137:0
12345.batch      FAILED          1                         00:10:15    137:0

흔한 상태:

  • COMPLETED: 성공했습니다! (종료 코드 0:0)
  • CANCELLED: 작업이 취소됐습니다.
  • TIMEOUT: --time으로 요청한 시간을 초과했습니다.
  • FAILED: 코드가 충돌했습니다 (0이 아닌 종료 코드).

2단계: 로그 읽기
#

sacct무슨 일이 있었는지 알려주지만 는 알려주지 않습니다. ‘왜’를 찾으려면 스크립트에서 지정한 출력 파일(예: #SBATCH -o result.out)을 봐야 합니다.

# 파일 끝부분을 먼저 확인합니다
$ tail -n 20 result.out

흔한 오류 메시지:

  • command not found: module load를 했나요?
  • ModuleNotFoundError: conda activate를 했거나 패키지를 설치했나요?
  • killed / oom-kill: 메모리가 부족했습니다.

3단계: 알림 받기 (꿀팁)
#

작업이 감시하지 않을 때 실패하는 경우가 많습니다. Slurm이 이메일로 알려주게 합니다. 작업 스크립트에 추가하세요.

#SBATCH --mail-type=FAIL,END
#SBATCH [email protected]
  • FAIL: 충돌 시에만 알려줍니다.
  • END: 완료 시 알려줍니다 (성공이든 실패든).

4. 리소스 효율 (seff)
#

파워 유저가 되기 위한 가장 중요한 부분입니다.

40인 연회용 테이블을 예약했는데 혼자 밥 먹었다고 상상해봅니다. 식당 매니저(스케줄러)가 화낼 겁니다. HPC에서도 --cpus-per-task=40을 요청했는데 Python 스크립트가 코어 1개만 쓸 때 이런 일이 생겨요.

효율을 어떻게 확인하나요? seff를 씁니다.

$ seff 12345
Job ID: 12345
Cluster: cluster
User/Group: user123/users
State: COMPLETED (exit code 0)
Cores: 8
CPU Utilized: 00:01:25
CPU Efficiency: 10.23% of 00:01:30 core-walltime
Job Wall-clock time: 00:01:30
Memory Utilized: 12.09 MB
Memory Efficiency: 0.15% of 8.00 GB (8.00 GB/node)

참고: 일부 클러스터에서는 seff가 비활성화돼 있을 수 있습니다. 그럴 때는 sacct에서 AveCPU, MaxRSS를 확인합니다.

$ sacct -j 12345 --format=JobID,State,AveCPU,MaxRSS
JobID             State     AveCPU     MaxRSS
------------ ---------- ---------- ----------
12345         COMPLETED  
12345.batch   COMPLETED   00:01:30     12384K

결과 해석:

CPU 효율:

  • 나쁨 (50% 미만): 코어를 너무 많이 요청했습니다. 코드가 병렬화되지 않았다면 코어 1개만 요청하세요.

  • 좋음 (~90%): 리소스를 잘 활용하고 있습니다.

메모리 효율:

  • 나쁨 (10% 미만): RAM을 너무 많이 요청했습니다. 다음번에는 --mem을 줄이세요.

  • 위험 (95% 초과): 충돌(OOM) 직전입니다. --mem을 약간(20% 정도) 늘리세요.

왜 중요한가요? 작은 작업은 클러스터의 ‘빈 틈’을 채우기 더 쉽습니다. 꼭 필요한 만큼만 요청하면 작업이 더 빨리 시작됩니다!

5. 작업이 왜 대기 중 일까요? (페어 쉐어)
#

빈 노드가 있어 보이는데 PD (대기 중) 상태가 Priority 또는 Resources 이유로 계속 남아 있을 때가 있습니다.

이건 페어 쉐어(Fair Share) 때문일 가능성이 높습니다. ‘카르마 시스템’이라고 생각하면 됩니다.

  • 클러스터는 공유 자원입니다.
  • 지난주에 무거운 작업을 수천 개 돌렸다면 ‘카르마’가 낮아져요. 줄 서서 기다려야 합니다.
  • 한동안 클러스터를 안 썼다면 ‘카르마’가 높습니다. 줄에서 앞으로 갑니다.

정확한 이유 확인하기

추측하지 말고 Slurm에게 직접 물어보세요.

$ squeue -j 12345 -o "%.18i %.9T %.30R"
             JOBID     STATE               NODELIST(REASON)
             12345   PENDING               (Priority)

구체적인 이유 코드를 보여줍니다.

  • Priority: 기다리면 됩니다. 페어 쉐어 때문입니다.
  • Resources: 클러스터가 바쁘거나 특정 노드가 사용 중입니다.
  • QOSMaxJobsLimit: 동시 실행 가능한 작업 수 한도에 도달했습니다.
  • Dependency: 다른 작업이 끝나길 기다리고 있습니다.

당황하지 마세요. 대부분의 경우 그냥 기다리면 됩니다.

6. 요약 & 치트시트
#

디버깅 마인드셋 (한 번만 읽어두세요)
#

작업이 실패했다면 순서대로 이 질문을 해보세요.

작업 디버깅 순서
  1. 시작은 됐나요? (squeue, scontrol) -> 안 됐다면 스크립트 문법을 확인하세요.
  2. 끝났나요, 충돌했나요? (sacct) -> 상태(State)를 확인하세요.
  3. 왜 충돌했나요? (로그 파일) -> .err 파일을 읽으세요.
  4. 리소스를 올바르게 요청했나요? (seff) -> 메모리 사용량을 확인하세요.
  5. 더 작게 만들 수 있나요? -> 작은 작업이 더 빨리 실행됩니다.

축하합니다! HPC 101을 공식적으로 졸업했습니다. 이제 클러스터의 손님이 아니라 주민입니다.

목표 명령어
상세 정보 확인 scontrol show job <JOBID>
작업 취소 scancel <JOBID>
히스토리 확인 sacct -j <JOBID>
효율 확인 seff <JOBID>

다음은? 다음 시리즈에서는 방향을 완전히 바꿀 겁니다. 클러스터 ‘사용자’에서 벗어나 ‘엔지니어’처럼 생각하기 시작할 겁니다. HPC 클러스터를 직접 만드는 새 시리즈가 시작됩니다.

다음 시리즈에서 만나요!

즐거운 컴퓨팅 되세요!

HPC 101 - 이 글은 시리즈의 일부입니다.
파트 4: 이 글