IL-0417 ByteDance · 2025-05-12 (게시일)ai-infra
ByteDance LLM 학습 클러스터에서 작업의 42.5% 가 스트래글러 때문에 10% 넘게 느려졌고 GPU 시간 10.4% 가 낭비되었다
ByteDance 와 뉴욕대 연구진은 2024년 1월 1일부터 5월 31일까지 ByteDance LLM 학습 클러스터에서 GPU 128개 이상을 쓴 사전학습 작업 3,079개의 기록을 분석했다. 클러스터는 여러 팀이 나눠 쓰는 학습 전용이고, 서버마다 GPU 8개가 있으며, 네트워크는 혼잡으로 느려지지 않도록 여유 있게 구성되었다. 작업은 Megatron-LM 을 고친 버전으로 데이터 병렬 DP, 파이프라인 병렬 PP, 텐서 병렬 TP, 컨텍스트 병렬 CP 를 섞어 썼다. 사내 프로파일러 NDTimeline 이 학습 스텝의 10% 를 표본으로 골라 계산과 통신 연산의 시작과 끝 시각을 기록했다. 연구진은 이 기록에서 연산 사이의 의존 관계를 다시 세웠다. 그리고 스트래글러가 없으면 같은 종류의 연산은 걸리는 시간이 같다고 보고, 스트래글러가 없는 타임라인을 시뮬레이션해 실제와 비교했다. 시뮬레이션 오차는 중앙값 1.3%, 90번째 백분위수 5.5% 였고, 오차가 5% 를 넘는 기록은 버렸다.
스트래글러는 흔했다. 분석한 작업의 42.5% 가 느렸고 할당된 GPU 시간의 10.4% 가 낭비되었다. 서버의 하드웨어나 소프트웨어 문제로 느려진 경우는 적었지만, 그런 경우의 감속은 평균 1.28 보다 훨씬 큰 3.04 였다. 가장 흔한 원인은 세 가지였다. 첫째, 마지막 파이프라인 단계는 손실 계층을 더 돌려야 한다. 그래서 레이어를 단계마다 고르게 나누면 마지막 단계가 무거워졌다. 트랜스포머 레이어 9개씩 네 단계로 나눈 작업에서 logit 계산이 트랜스포머 레이어 하나보다 9배 넘게 길었고, 마지막 단계의 forward-compute 는 평균 단계보다 2.07배, backward-compute 는 1.41배 느렸다. 작업의 39.3% 는 감속의 대부분이 마지막 단계에서 나왔다. 둘째, 긴 컨텍스트 작업은 시퀀스 길이 분포의 꼬리가 길었다. 셀프 어텐션의 계산량은 시퀀스 길이의 제곱에 비례하므로 마이크로배치마다 계산 시간이 크게 달랐다. 길이 32K 시퀀스 하나는 1K 시퀀스 32개보다 계산 시간이 32배 길다. 작업의 21.4% 가 이 불균형의 영향을 받았고 평균 감속은 1.34 였다. 셋째, Python 의 자동 GC 는 한 번 돌 때 수백 밀리초 동안 프로그램을 멈춰 forward-compute 를 막았다. 프로세스마다 GC 를 다른 때 돌렸으므로 한 워커의 멈춤이 작업 전체를 막았다.
드물지만 PyTorch CUDA 메모리 할당기의 메모리 단편화와, 서로 관계없는 커널이 같은 CUDA 하드웨어 큐를 써서 생긴 거짓 의존성도 스트래글러를 만들었다. 연구진은 분석의 일부를 모니터링 서비스 SMon 으로 만들어 이 클러스터에 배포했다. SMon 은 NDTimeline 프로파일링이 끝날 때마다 감속을 계산해 DP 랭크와 PP 랭크로 그린 히트맵으로 보여 준다. 배포 한 달 안에 SMon 으로 고장 난 장비 세 건, 시퀀스 길이 불균형 한 건, 파이프라인 단계 불균형 한 건을 찾아 해결했다.
- 심각도
- –
- 영향 범위
- 42.5% of traced LLM pretraining jobs straggled; 10.4% of allocated GPU hours were wasted, and about 1% of jobs wasted at least 45.0% of their GPUs
- 영향 사용자
- Teams that share ByteDance's internal LLM training cluster
- 지역
- –
- 감지까지
- –
- 복구까지
- –
증상
GPU 128개 이상을 쓰는 LLM 사전학습 작업 상당수가 스트래글러 때문에 이상적인 속도보다 느리게 돌았다. 스트래글러는 맡은 일을 다른 워커보다 늦게 끝내, 동기화해야 하는 다른 워커를 기다리게 만드는 워커다. 분석한 작업의 42.5% 가 스트래글러 때문에 최소 10% 느려졌다.
작업의 10% 이상이 할당받은 GPU 시간의 21.3% 이상을 낭비했고, 약 1% 의 작업은 할당받은 GPU 의 45.0% 이상을 낭비했다. 전체 기록에서 할당된 GPU 시간의 10.4% 가 스트래글러 때문에 사라졌다.
느린 작업 안에서는 대부분의 스텝이 비슷하게 느렸다. 작업 전체 감속으로 정규화한 스텝별 감속은 중앙값이 1.0, 90번째 백분위수가 1.06 이었다. 느려진 연산은 대부분 통신이 아니라 계산이었다. 통신 가운데서는 파이프라인 병렬인 PP 수준 통신이 데이터 병렬인 DP 수준 통신보다 조금 더 영향이 컸다. 작업 크기와 감속 사이에는 뚜렷한 양의 상관이 없었다.
원인마다 모습이 달랐다. 마지막 파이프라인 단계가 무거운 작업은 마지막 단계의 forward-compute 와 backward-compute 가 다른 단계보다 길었다. 시퀀스 길이가 고르지 않은 작업은 스텝마다 무작위 DP 랭크에서 계산 시간이 크게 흔들렸고, forward 계산 시간과 backward 계산 시간의 상관계수가 0.9 이상이었다. 가비지 컬렉션인 GC 로 멈추는 작업은 워커마다 다른 스텝에서 GC 를 돌려 서로를 기다리게 했다. 이런 작업은 진행될수록 GC 멈춤 시간이 늘어 처리량이 서서히 떨어졌다.
감속이 3배를 넘는 작업은 모두 대형 작업이었다. 이런 작업에서는 워커 3% 미만이 문제를 일으켰고, 느린 연산은 대개 계산이었다. 연구진은 이런 작업이 대개 하드웨어 문제나 설정 오류가 있는 서버 때문에 느려진다고 보았다. 그러나 스트래글러 작업 전체로 보면, 가장 느린 워커 3% 를 고쳤을 때 감속의 절반 이상이 풀리는 작업은 1.7% 뿐이었다.
원인
- 촉발
- –
감지
연구진은 NDTimeline 기록으로 스트래글러가 없는 경우를 시뮬레이션해 작업마다 감속을 계산하고 스트래글러를 찾았다. 그 뒤 배포한 SMon 은 프로파일링이 끝날 때마다 작업 감속, 스텝별 감속, 워커별 감속을 계산해 웹 페이지에 히트맵으로 보여 주고, 중요한 작업이 크게 느려지면 온콜 팀에 알린다. 온콜 팀은 워커 히트맵이 알려진 원인의 모양과 맞는지 보고, 스텝별 감속과 스텝별 히트맵으로 문제가 된 스텝과 랭크를 찾는다.
조치
- Llama 3 처럼 마지막 파이프라인 단계에 레이어를 ε 개 적게 배정했다. 다만 ε 은 손으로 맞춰야 했고, 레이어를 통째로만 나눌 수 있어서 좋은 값을 골라도 성능이 최적에 못 미쳤다.
- 트랜스포머 레이어 9개씩 네 단계로 나눈 작업에서 단계별 레이어 수를 손으로 조정해 속도를 9.9% 올렸다. 조정한 뒤에도 마지막 단계의 forward-compute 는 다른 단계의 1.55배였다.
- 2023년에 planned GC 라는 최적화를 만들었다. 이 최적화는 Python 의 자동 GC 를 끄고, 사용자가 학습 스텝 단위로 정한 간격마다 모든 워커가 함께 GC 를 돌린다. DP 랭크 128개를 쓰는 작업에서 500 스텝마다 GC 를 돌리자 12.6% 빨라졌다. 간격을 잘못 고르면 메모리가 모자라 작업이 죽거나 오히려 느려지므로, 이 최적화는 기본으로 켜지 않았다.
- 배치를 만든 뒤 선형 모델로 시퀀스를 DP 랭크 사이에 다시 나눠 계산량을 맞추고, 랭크 안에서도 마이크로배치마다 시퀀스 길이 합을 맞추는 방법을 프로토타입으로 만들었다. 최대 시퀀스 길이가 32K 인 대표 작업에서 처리량이 23.9% 올랐다.
- 대형 MoE 모델을 학습할 때 reduce-scatter 커널이 관계없는 커널의 실행을 막아 작업이 크게 느려졌다. CUDA_DEVICE_MAX_CONNECTIONS 를 늘려 이 문제를 줄였다.
- SMon 을 배포한 뒤 한 달 안에, 장비 문제로 생긴 스트래글러 세 건에서 고장 난 장비를 찾아냈다.
후속 조치
- 시퀀스 재분배 방법을 실제로 배포하기 전에 대규모에서 효과를 평가한다.
- CUDA 메모리 단편화가 얼마나 흔한지와 줄이는 방법을 연구한다.
- NDTimeline 이 기록하는 내용 때문에 생긴 분석의 한계를 해결한다.
- reduce-scatter 커널이 다른 커널을 막는 거짓 의존성의 원인을 계속 조사한다.
교훈
서버 문제로 생긴 스트래글러는 비교적 적어서, 기존 헬스 지표로는 대부분의 스트래글러를 찾거나 막기 어렵다. 가장 흔한 원인은 파이프라인 단계를 고르지 않게 나눈 것, 마이크로배치마다 시퀀스 길이가 다른 것, GC 멈춤이었다. 느린 작업에서는 대부분의 스텝이 비슷하게 느리므로 몇 스텝만 표본으로 프로파일링해도 충분하다. 장비 문제는 드물게 나지만 나면 감속이 심하다. 시퀀스 길이 불균형은 최대 시퀀스 길이가 길수록 영향이 커서, 컨텍스트가 길어질수록 더 중요한 문제가 된다.
출처
- https://arxiv.org/abs/2505.05713 · paper · 보관본
참고 문서
관련 사례
–
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0417
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0417/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.