Skip to main content
이 페이지는 W&B Sweeps가 시스템 시그널과 프로세스 종료 코드를 처리하는 방법에 대한 세부 정보를 제공합니다. preemptible 환경(예: SLURM, EC2 Spot 또는 Google Cloud preemptible VM)에서 스윕을 안정적으로 실행하는 데 이 정보를 사용하세요. 다음 섹션에서는 키보드에서 run을 깔끔하게 중단하는 방법과 run이 다시 큐에 들어가는 동작을 이해하고 예측하는 데 도움이 되는 세부 정보를 설명합니다. 이 페이지는 preemptible 인프라에서 스윕을 실행하거나 run 라이프사이클 및 cleanup에 대한 세밀한 제어가 필요한 사용자를 대상으로 합니다. preempted될 때 W&B가 run을 다시 큐에 들어가게 하는 방법에 대한 자세한 내용은 Resume preemptible Sweeps runs를 참조하세요.

종료 상태 및 시그널

W&B는 트레이닝 프로세스 종료 상태를 사용하여 run이 다시 큐에 들어가는지와 run 상태가 어떻게 기록되는지를 결정합니다. 종료 코드 계약:
  • 종료 코드 0: W&B는 run이 성공적으로 완료된 것으로 간주하고 다시 큐에 들어가지 않습니다.
  • 0이 아닌 종료 코드: W&B는 run을 실패하거나 preempted된 것으로 처리합니다. mark_preempting()을 사용하면 W&B는 run을 다시 큐에 들어가게 하여 다른 에이전트(또는 재시작 후 동일한 에이전트)가 재개할 수 있도록 합니다.
이 규칙은 프로세스가 시그널 핸들러, 예외 또는 명시적인 sys.exit() 호출로 종료되는 경우 모두 적용됩니다. preemptible 또는 클러스터 환경에서는 이 계약을 이해하고 따르는 것이 중요합니다. 프로세스가 포착 가능한 시그널로 인해 종료될 때 핸들러를 실행하고, run을 다시 큐에 들어가게 하려면 wandb.run.mark_preempting()을 호출하며, 정리 작업(예: 체크포인트 저장)을 수행한 후 0이 아닌 코드로 종료할 수 있습니다. 일반적인 관례는 시그널에 의한 종료 시 sys.exit(128 + signum)입니다. W&B는 해당 종료 코드를 기록하며 동일한 다시 큐에 들어가는 규칙이 적용됩니다. 운영 체제 커널이 SIGKILL로 프로세스를 종료하면 종료 훅을 실행할 수 없으므로 W&B는 최종 요약을 기록하지 않으며 run이 crashed 또는 killed된 것으로 표시될 수 있습니다. 에이전트는 여전히 다음 run을 시작합니다.

Stale run과 server-side timeout

W&B는 종료 코드와 run의 활동을 통해 run 상태를 확인합니다. run이 종료되지 않거나 약 5분 동안 새로운 메트릭을 게시하지 않으면 W&B는 run을 crashed로 표시합니다. 이는 트레이닝 프로세스가 응답하지 않거나, 로깅을 중지하거나, clean exit 없이 종료될 때(예: SIGKILL 전송) 발생할 수 있습니다. run 상태를 실제 상황과 일치시키려면 일정한 주기로 메트릭을 로깅하거나 정의된 코드로 종료하세요.

포착 가능한 시그널과 선점

preemptible 환경에서 발생하는 대부분의 시그널은 포착 가능(catchable)합니다. 즉, 트레이닝 스크립트가 시그널을 가로채서 정상적으로 종료할 수 있습니다. 트레이닝 스크립트에 맞춤형 시그널 핸들러를 등록할 수 있습니다. 시스템이 포착 가능한 시그널을 보내면 핸들러가 실행됩니다. W&B는 이미 수신한 메트릭을 보존합니다. 에이전트는 프로세스 종료를 감지하고 다음 run을 시작합니다. 모범 사례:
  • 핸들러는 가능한 한 일찍 등록하세요(예: 메인 트레이닝 루프에 진입하기 전).
  • 선점 후 run이 다시 큐에 들어가도록 하려면 핸들러에서 wandb.run.mark_preempting()을 호출하고, 정리 작업(예: 체크포인트 저장)을 수행한 다음 0이 아닌 코드로 종료하세요.
다음 예시는 SIGUSR1(일반적인 클러스터 선점 시그널)과 SIGTERM에 대한 핸들러를 등록합니다. SIGINT는 대화형 사용(예: 터미널에서 수동으로 취소)을 위해 남겨 둡니다. 핸들러는 wandb.run.mark_preempting()을 호출한 후 128 + signum으로 종료합니다.

SIGKILL (uncatchable)

SIGKILL은 운영 체제 커널에서 발생하며 잡거나 무시할 수 없습니다. 프로세스는 즉시 종료되며 핸들러나 atexit callback을 실행할 기회가 없습니다. W&B는 run의 최종 요약을 기록할 수 없습니다. 에이전트는 복구되어 스윕을 계속 진행하지만, 해당 run의 데이터는 불완전하게 남습니다. SIGKILL은 최후의 수단으로만 사용하세요. 정상 종료(graceful shutdown)가 필요한 경우에는 SIGTERM 또는 SIGINT를 사용하는 것이 좋습니다.

에이전트에서 자식으로의 시그널 전달

wandb agent CLI를 사용할 때, 에이전트는 트레이닝 스크립트를 자식 프로세스로 실행합니다. 에이전트를 중단하면(예: Ctrl+C를 누르거나 스케줄러가 작업에 SIGTERM을 보내는 경우), 자식(트레이닝 프로세스)은 기본적으로 시그널을 받지 못합니다. 트레이닝 스크립트는 핸들러를 실행하거나 mark_preempting()을 호출할 수 없습니다. 자세한 내용은 wandb GitHub 이슈 #3667을 참조하세요. 자식이 정상적으로 종료하고 핸들러에서 wandb.run.mark_preempting()을 호출할 수 있게 하려면, --forward-signals 옵션으로 CLI 에이전트를 실행하세요:
W&B는 Python API의 wandb.agent()에 대해 시그널 전달을 지원하지 않습니다. 이 방식은 트레이닝 함수를 별도의 자식 프로세스가 아닌 스레드에서 실행하므로 동일한 전달 동작이 적용되지 않습니다. 전달이 활성화된 상태에서 CLI 에이전트가 SIGINT 또는 SIGTERM을 수신하면 해당 시그널을 자식 프로세스로 전달합니다. 그러면 트레이닝 스크립트의 핸들러가 실행되어 wandb.run.mark_preempting()을 호출하고, 필요한 경우 0이 아닌 종료 코드로 wandb.finish()를 호출한 뒤 0이 아닌 코드로 종료할 수 있습니다. 에이전트 프로세스에서 Ctrl+C를 두 번 누르면 기본적으로 에이전트가 SIGTERM을 수신합니다. --forward-signals를 사용하면 에이전트가 SIGINT를 자식 프로세스로 전달하므로 핸들러가 실행될 수 있습니다. 자세한 내용은 wandb agent CLI 레퍼런스를 참조하세요.

SLURM과 같은 Preemptible 클러스터

이 섹션에서는 SLURM, EC2 Spot 또는 Google Cloud preemptible VM과 같은 클러스터에서 선점 발생 시 run이 유지되도록 스윕을 설정하는 방법을 설명합니다. 선점 시 트레이닝 프로세스는 시그널을 수신해 run을 preempting으로 표시하고 0이 아닌 코드로 종료하여 W&B가 run을 다시 큐에 들어가게 하도록 해야 합니다. 그러면 새 에이전트(또는 작업이 다시 큐에 들어간 후 동일한 에이전트)가 run을 재개할 수 있습니다. 트레이닝 프로세스가 시그널을 받도록 하세요:
  • 스케줄러가 에이전트에 시그널을 보낼 때: wandb agent --forward-signals로 에이전트를 실행하여 스케줄러(또는 사용자)가 에이전트에 시그널을 보내면 에이전트가 이를 자식 프로세스로 전달하도록 합니다. 자식의 핸들러는 wandb.run.mark_preempting(), wandb.finish(exit_code=...)을 0이 아닌 코드와 함께 호출한 후 sys.exit(128 + signum)(또는 다른 0이 아닌 종료 코드)을 실행할 수 있습니다.
  • 스케줄러가 에이전트가 아닌 launch 스크립트에 시그널을 보낼 때: launch 스크립트가 선점 시그널을 트레이닝 프로세스에 직접 보내도록 합니다. 예를 들어 트레이닝 스크립트가 자신의 프로세스 ID를 파일에 기록합니다. launch 스크립트는 클러스터 시그널(예: SIGUSR1)을 트랩하고 kill -SIGUSR1 $(cat $PID_FILE)을 실행하여 트레이닝 프로세스의 핸들러가 실행되도록 합니다.
트레이닝 스크립트 내에서: 클러스터가 사용하는 시그널(예: SIGTERM 또는 SIGUSR1)에 대한 핸들러를 등록합니다. 핸들러에서 run이 active 상태이면 wandb.run.mark_preempting()을 호출한 다음 0이 아닌 종료 코드로 run을 종료하고 sys.exit(128 + signum)(또는 다른 0이 아닌 코드)을 실행하여 W&B가 run을 다시 큐에 들어가게 하도록 합니다. W&B가 run을 다시 큐에 들어가게 하는 시점과 mark_preempting()과의 상호작용에 대한 자세한 내용은 Resume preemptible Sweeps runs를 참조하세요. 스윕 상태: 에이전트를 시작하기 전에 wandb sweep entity/project/sweep_ID --resume을 실행하여 스윕이 resume 모드에 있도록 하고 다시 큐에 들어간 run을 배포하도록 합니다. 멀티 에이전트 조정: 여러 에이전트가 동시에 실행될 때(예: SLURM array jobs) preempted된 동일한 run을 차지하려고 경쟁할 수 있습니다. 이는 알려진 제한 사항입니다. 이를 해결하려면 에이전트 시작을 지연시키거나 잠금과 같은 외부 조정 메커니즘을 사용하세요. wandb.agent()를 호출해야 하는 프로세스가 하나뿐인 multi-GPU SLURM 작업의 경우 How should I run sweeps on SLURM?를 참조하세요.

wandb sweep --cancel

이 섹션에서는 --cancel 명령이 시그널 및 자식 프로세스와 상호작용하는 방식을 설명합니다. 취소는 OS 시그널을 직접 보내는 것과 다르게 동작하기 때문입니다. 스윕은 W&B API를 사용하여 취소하며 OS 시그널을 사용하지 않습니다. wandb sweep --cancel entity/project/sweep_ID와 같은 명령을 실행하세요. 서버가 에이전트에게 종료를 지시하고, 에이전트는 실행 중인 자식 프로세스를 종료한 후 중지합니다. 취소가 적용되기까지 짧은 지연(에이전트의 API 폴링 간격 정도)이 발생할 수 있습니다. 취소는 run에 SIGKILL을 전달합니다. 자식 프로세스는 사용자 정의 시그널 핸들러를 실행할 기회가 없습니다. Sweeps UI의 Cancel 컨트롤을 사용할 때도 동일하게 적용됩니다. 전체 스윕을 중지하고 취소됨으로 표시하려면 --cancel을 사용하세요. 현재 run을 정상적으로 종료하려면 run에 포착 가능한 시그널을 보내세요(또는 CLI 에이전트에서 --forward-signals를 사용하고 에이전트에 시그널을 보내세요). 스윕을 정상적으로 완료하려면 --cancel 대신 wandb sweep --stop을 사용하세요. 일시 중지, 재개, 중지, 취소 옵션에 대한 자세한 내용은 스윕 관리를 참조하세요.

에이전트에 대한 시그널 versus run에 대한 시그널

에이전트에 시그널을 보내는 것과 트레이닝 run에 시그널을 보내는 것의 차이를 이해하면 고아 프로세스와 예상치 못한 동작을 방지하는 데 도움이 됩니다. 에이전트 프로세스(자식 트레이닝 프로세스가 아님)에 시그널을 보내면 에이전트가 종료되는 동안 하위 프로세스가 고아 상태로 계속 실행될 수 있습니다. 고아 프로세스는 터미널에 계속 출력할 수 있으며, Enter 키를 누를 때까지 셸에 새 프롬프트가 표시되지 않을 수 있습니다. --forward-signals 옵션과 함께 CLI 에이전트를 사용하지 않는 한, 에이전트를 중지해도 자식 트레이닝 프로세스가 중지된다는 보장은 없습니다. 에이전트가 종료되었는지 확인하려면 프롬프트 표시 여부에 의존하지 말고 ps -p [AGENT-PID] 또는 pgrep -f "wandb agent"와 같은 OS 명령을 사용하세요.

레퍼런스: mark_preempting()과 최종 run 상태

다음 table은 mark_preempting()을 호출하는 시점과 프로세스의 종료 방식에 따라 run 상태가 어떻게 달라지는지 요약합니다. 트레이닝 프로그램을 하위 프로세스로 실행하는 wandb agent CLI를 사용한다고 가정합니다. 시그널 핸들러 내부에서만 mark_preempting()을 호출하면 SIGKILL처럼 핸들러가 실행되지 않는 경우에는 대응할 수 없습니다. wandb.init() 직후 항상 mark_preempting()을 호출하면 W&B가 모든 실패를 선점으로 처리하여 버그나 잘못된 설정으로 인한 실패까지도 run을 반복해서 다시 큐에 들어가게 할 수 있습니다. 선점 시그널이 명확하게 정의된 환경에서는 일반적으로 init() 이후 무조건 호출하는 대신, mark_preempting()을 호출하고 0이 아닌 종료 코드로 종료하는 시그널 핸들러를 사용합니다.
마지막 수정일 2026년 9월 30일