HPC 와 Slurm · 작업 제출과 자원 요청 · 이론
sbatch 스크립트 쓰는 법
한 줄 요약
sbatch 스크립트의 #SBATCH 줄은 주석처럼 보이지만 자원 계약서다. 그리고 첫 실행 명령 앞에 있어야만 읽힌다.
왜 이게 필요했나
가장 흔한 초보 실수가 이것이다.
#!/bin/bashecho "starting"#SBATCH --gres=gpu:2 # <- 무시된다!python train.py#SBATCH 는 첫 번째 실행 가능한 명령이 나오기 전까지만 파싱된다. 그 뒤의 것은 평범한 주석이다. 에러도 경고도 나지 않는다. 작업은 GPU 없이 제출되고, 사용자는 왜 CUDA 가 안 보이는지 한참 헤맨다.
어떻게 동작하나
기본 골격
#!/bin/bash#SBATCH --job-name=resnet-train#SBATCH --output=/home/me/logs/%x-%j.out#SBATCH --error=/home/me/logs/%x-%j.err#SBATCH --partition=gpu#SBATCH --nodes=1#SBATCH --ntasks=1#SBATCH --cpus-per-task=8#SBATCH --mem=64G#SBATCH --gres=gpu:a100:2#SBATCH --time=04:00:00set -euo pipefailecho "job $SLURM_JOB_ID on $SLURMD_NODENAME"srun python train.py --epochs 50출력 파일 패턴의 치환자를 알아 두면 좋다.
| 패턴 | 값 |
| --- | --- |
| %j | 작업 ID |
| %x | 작업 이름 |
| %A | 배열 작업의 부모 ID |
| %a | 배열 인덱스 |
| %N | 첫 노드 이름 |
출력 경로의 디렉터리가 미리 존재해야 한다. 없으면 작업이 시작하자마자 실패하고, 그 실패 이유를 담을 파일도 못 만들어 원인을 알기 어렵다.
유용한 환경변수
작업 안에서 Slurm 이 넣어 주는 값들.
SLURM_JOB_ID 작업 IDSLURM_JOB_NAME 작업 이름SLURM_JOB_NODELIST 할당된 노드 목록SLURMD_NODENAME 현재 실행 중인 노드SLURM_CPUS_PER_TASK 태스크당 CPU <- DataLoader num_workers 에 쓰면 좋다SLURM_ARRAY_TASK_ID 배열 인덱스SLURM_NTASKS 태스크 총 개수num_workers=int(os.environ.get("SLURM_CPUS_PER_TASK", 4)) 처럼 쓰면 자원 요청과 코드가 자동으로 맞는다.
srun 의 역할
sbatch 스크립트 안에서 srun 을 쓰면 작업 스텝이 만들어진다. 여러 노드/태스크로 병렬 실행할 때 필요하고, 단일 프로세스라면 없어도 되지만 있으면 자원 회계가 정확해진다.
srun --ntasks=4 python ddp_train.py # 4개 프로세스로배열 작업
같은 스크립트를 파라미터만 바꿔 여러 번 돌릴 때 쓴다.
#SBATCH --array=1-100%101-100 은 인덱스 범위, %10 은 동시에 실행할 최대 개수다. 이 제한이 없으면 100개가 한꺼번에 큐에 들어가 다른 사용자를 막는다.
python sweep.py --config "configs/exp${SLURM_ARRAY_TASK_ID}.yaml"의존성
JOB1=$(sbatch --parsable prep.sh)sbatch --dependency=afterok:$JOB1 train.sh| 조건 | 의미 |
| --- | --- |
| afterok:ID | 그 작업이 성공으로 끝난 뒤 |
| afterany:ID | 성공/실패 무관하게 끝난 뒤 |
| afternotok:ID | 실패로 끝난 뒤 (정리 작업용) |
| singleton | 같은 이름의 내 작업이 없을 때 |
--parsable 은 작업 ID 만 출력해 변수에 담기 좋게 한다.
상태 확인
squeue -u $USERsqueue -j 12345 -o '%.10i %.20j %.8T %.10M %.6D %R'scontrol show job 12345sacct -j 12345 --format=JobID,JobName,State,Elapsed,MaxRSS,ReqTRESscancel 12345squeue 의 마지막 열(%R)이 대기 이유다. Resources(자원 대기), Priority(우선순위 대기), Dependency(의존 대기), QOSMaxJobsPerUserLimit(제한 걸림) 등이 나온다. 작업이 안 도는 이유의 절반이 이 한 열에 적혀 있다.
현장에서 만나는 모습
--mem 을 안 적어 기본값으로 도는 경우. 클러스터 기본값이 작으면 OOM 으로 죽고, 크면 다른 작업이 못 들어온다. 명시하는 습관이 좋다.
--time 을 최대로 적는 문화. 모두가 그러면 백필이 무력해지고 전체 처리량이 떨어진다. 실제에 가깝게 적고 여유를 20% 정도 두는 것이 서로에게 이득이다.
다음 실습에서 할 것
sbatch 스크립트를 요구사항대로 작성하고, 배열 작업과 의존성 체인까지 구성한다. 마지막에는 #SBATCH 위치 오류를 잡아내는 검증 스크립트를 직접 만든다.