{"id":"IL-0125","org":"BigScience","date":"2022-05-18","docs":["https://github.com/pytorch/pytorch/issues/76287"],"title":{"en":"A GPU died about once a week during a 176B-parameter training run, and sometimes the job hung instead of exiting, so SLURM never restarted it","ko":"Jean Zay 에서 진행한 176B 다국어 모델 학습에서 GPU 가 고장 나도 학습 작업이 끝나지 않고 멈춰 버려 SLURM 이 작업을 자동으로 재시작하지 못했다."},"domain":["ai-infra"],"impact":{"scope":"The tr11-176B-ml training run; up to about 3 hours of training lost per GPU failure, and hung jobs stayed idle until someone noticed","users":"unknown","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"On a long run across hundreds of GPUs, a dead GPU every week is routine; what costs time is the case where a process crashes and the job hangs instead of exiting, because then nothing restarts it. Making NCCL errors fatal and having the scheduler end the whole step on a bad exit is meant to turn such a hang into a crash that the existing automatic restart handles; only the srun part was tested. Frequent checkpoints bound the loss per crash, at the price of save time for a 2.3TB checkpoint.","ko":"Jean Zay 의 SLURM 에는 이미 KillOnBadExit=1 같은 설정이 있었으므로, 실제로 더해진 것은 NCCL_ASYNC_ERROR_HANDLING=1 하나였다. 노드 2개 시험은 새 srun 옵션만 확인했고, 재현하기 까다로운 NCCL 멈춤은 시험하지 못했다. 작성자는 다음 하드웨어 고장 때 제대로 동작하는지 지켜보기로 했다. 체크포인트 저장 간격은 GPU 고장 때 잃는 학습 시간과 저장에 드는 시간을 견주어 정해야 한다."},"related":[],"sources":[{"url":"https://github.com/bigscience-workshop/bigscience/blob/master/train/tr11-176B-ml/chronicles.md","kind":"github","license":"unknown","archived":null}],"summary":{"en":"BigScience trained a 176B-parameter multilingual model on 48 nodes (384 GPUs) of the Jean Zay cluster, as a SLURM job. A GPU died roughly every week. When the crash made the job exit, SLURM restarted it and at most about 3 hours of training were lost. Sometimes, though, a crashing process left the rest of the job hanging, and SLURM never learned that it should restart.\n\nThe team reduced the loss per crash by saving checkpoints more often. After a crash on 2022-03-21 cost 7.3 hours, the save interval went to 200 iterations, and on 2022-03-22, after an emergency maintenance downtime on Jean Zay lost some hours again, it went to SAVE_INTERVAL=100, at most about 3 hours of training. A checkpoint is 2.3TB and takes about 40 seconds to save, so saving too often has a cost. The hang was the bigger problem: Jean Zay gives no sudo access, and once one person starts a SLURM job nobody else can stop it, so a hang while that person slept or was away could not be handled until they returned.\n\nThe author reported the hang to PyTorch (issue 76287), where the suggested workaround was to set NCCL_ASYNC_ERROR_HANDLING=1, which forces a crash on NCCL problems such as a hanging broadcast, and to run srun with --wait=60 and --kill-on-bad-exit=1, so that a task exiting with a non-zero code ends the whole step. In a test on 2 nodes, killing one process by hand killed the local sub-processes, and about 5 minutes later SLURM killed the whole job. Jean Zay's SLURM turned out to have UnkillableStepTimeout=180, KillWait=60 and KillOnBadExit=1 already, so the only new setting was NCCL_ASYNC_ERROR_HANDLING=1. The NCCL part was not tested because a hanging NCCL operation is hard to emulate.","ko":"BigScience 는 Jean Zay 슈퍼컴퓨터에서 176B 파라미터 다국어 모델 tr11-176B-ml 을 학습했다. 학습 중 대략 일주일에 한 번 GPU 하나가 죽었다. 대부분은 SLURM 작업이 자동으로 재시작됐고, 체크포인트를 100 이터레이션마다 저장했기 때문에 잃는 학습은 최대 3시간이었다. 100 이터레이션을 학습하는 데 약 3시간이 걸렸다. 저장 간격은 처음에 더 길었고, 2022-03-21 GPU 고장으로 7.3시간을 잃은 뒤 200 이터레이션으로, 이어서 100 이터레이션으로 줄였다. 체크포인트 하나가 2.3TB 이고 저장에 40초가 걸려 너무 자주 저장할 수는 없었다.\n\n문제는 프로세스가 죽었는데도 학습이 멈춘 채 끝나지 않는 경우였다. 이렇게 되면 SLURM 작업도 끝나지 않아서, 누군가 알아채지 않는 한 학습이 재시작되지 못했다. 누군가 하루 종일 학습을 지켜봐야 했고, 팀이 만든 킬 스위치도 가끔 동작하지 않았다. Jean Zay 에서는 sudo 권한이 없고, 한 사람이 띄운 SLURM 작업을 다른 사람이 멈출 수 없다. 그래서 팀은 특정 파일을 만들면 체크포인트를 저장한 뒤 학습을 정상 종료하는 킬 스위치를 따로 만들어 쓰고 있었다.\n\n작성자가 이 문제를 PyTorch 이슈 76287 로 보고하자, PyTorch 쪽은 브로드캐스트 멈춤 같은 NCCL 문제가 생기면 강제로 죽도록 NCCL_ASYNC_ERROR_HANDLING=1 을 설정하고 srun 에 --wait=60 과 --kill-on-bad-exit=1 을 주라고 제안했다. --wait=60 은 첫 태스크가 끝나고 60초 뒤 나머지 태스크를 모두 끝내는 옵션이고, --kill-on-bad-exit=1 은 태스크 하나라도 0 이 아닌 종료 코드로 끝나면 스텝 전체를 끝내는 옵션이다. 노드 2개에서 시험해 보니 프로세스 하나를 죽이고 약 5분 뒤 SLURM 이 작업 전체를 끝냈다. 나중에 Jean Zay 의 SLURM 에는 이미 UnkillableStepTimeout=180, KillWait=60, KillOnBadExit=1 이 설정되어 있었다는 것을 알았고, 실제로 새로 더한 것은 NCCL_ASYNC_ERROR_HANDLING=1 하나였다."},"trigger":{"en":"A GPU on one of the training nodes failed during the run.","ko":"Jean Zay 노드의 GPU 하나가 하드웨어 고장으로 죽었는데, 프로세스가 죽은 뒤에도 학습 작업이 종료되지 않고 멈췄다."},"severity":"unknown","symptoms":["training-job-failed","gpu-unavailable"],"timeline":{"detected_after":null,"resolved_after":null},"date_kind":"incident","detection":{"en":"There was no automatic detection of a hung job; it was noticed only when someone watching the training saw that it was stuck.","ko":"자동으로 알려 주는 수단이 없었다. 학습이 멈춰도 SLURM 작업이 끝나지 않았기 때문에, 누군가 학습을 지켜보다가 알아채야 했다."},"components":["nccl","pytorch","slurm"],"root_cause":"hardware-failure","remediation":[{"text":{"en":"raised checkpoint frequency to every 200 iterations and then to every 100 iterations (SAVE_INTERVAL=100)","ko":"체크포인트 저장 간격을 200 이터레이션으로, 이어서 100 이터레이션으로 줄였다. 설정 값은 SAVE_INTERVAL=100 이다."}},{"text":{"en":"set NCCL_ASYNC_ERROR_HANDLING=1 so NCCL problems crash the job instead of hanging it","ko":"NCCL_ASYNC_ERROR_HANDLING=1 을 설정해 브로드캐스트 멈춤 같은 NCCL 문제가 생기면 학습이 강제로 죽게 했다."}},{"text":{"en":"added the srun options --wait=60 and --kill-on-bad-exit=1 after testing them on 2 nodes","ko":"노드 2개에서 새 작업을 띄우고 프로세스 하나를 손으로 죽여 약 5분 뒤 SLURM 이 작업 전체를 끝내는 것을 확인한 뒤, srun 에 --wait=60 과 --kill-on-bad-exit=1 을 더했다."}}],"action_items":[],"contributing":["default-config-unchanged","limited-debug-access"],"recurrence_of":null,"symptoms_text":{"en":"During BigScience's 176B-parameter multilingual training (tr11-176B-ml) on the Jean Zay cluster, launched on 2022-03-11, one of the GPUs died about once a week. Most of the time the SLURM job crashed and restarted automatically from the last checkpoint.\n\nOne such crash, at 2022-03-21_13:34:34 Jean Zay time, logged \"terminate called after throwing an instance of 'c10::CUDAError'\" and \"what():  CUDA error: unknown error\", raised from ../aten/src/ATen/cuda/CUDAEvent.h:95 in c10d::ProcessGroupNCCL::WorkNCCL::finishedGPUExecutionInternal(). It came 2 iterations before a checkpoint save, so 7.3 hours of work were lost.\n\nSometimes the training got stuck after a process crashed and did not quit, which the author connected to torch.launch and possibly NCCL. The job then sat in limbo without restarting until someone noticed, so someone had to watch the training around the clock. A stuck job could also break the team's kill switch, a file that, when created, makes the training save a checkpoint and exit gracefully.","ko":"tr11-176B-ml 학습에서는 대략 일주일에 한 번 GPU 하나가 죽는 하드웨어 문제가 생겼다. 대부분은 SLURM 작업이 자동으로 재시작돼 잃는 학습이 최대 3시간에 그쳤다. 하지만 가끔은 프로세스가 죽었는데도 학습이 멈춘 채 끝나지 않았다.\n\nGPU 가 죽으면 2022-03-21_13:34:34 JZ 시각의 고장처럼 로그에 [default3]:terminate called after throwing an instance of 'c10::CUDAError' 와 CUDA error: unknown error 가 찍혔고, 스택에는 c10d::ProcessGroupNCCL::WorkNCCL::finishedGPUExecutionInternal 이 보였다. 이 고장은 체크포인트를 저장하기 두 이터레이션 전에 일어났고, 그 때문에 7.3시간 분량의 학습을 잃었다.\n\n학습이 멈추면 SLURM 작업도 끝나지 않았다. 누군가 지켜보다 알아채지 않는 한 학습은 재시작될 기회 없이 그대로 걸려 있었다. 작성자는 이 현상이 torch.launch, 그리고 아마 NCCL 과 관련 있다고 보고 PyTorch 이슈 76287 로 원인을 추적했다."},"updated_at":"2026-11-09T11:55:48.683647Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0125","org_slug":"bigscience"}