{"id":"IL-0417","org":"ByteDance","date":"2025-05-12","docs":["https://github.com/ByteDance-Seed/StragglerAnalysis"],"title":{"en":"Stragglers slowed 42.5% of large LLM training jobs on ByteDance's cluster, mostly without any faulty server","ko":"ByteDance LLM 학습 클러스터에서 작업의 42.5% 가 스트래글러 때문에 10% 넘게 느려졌고 GPU 시간 10.4% 가 낭비되었다"},"domain":["ai-infra"],"impact":{"scope":"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","users":"Teams that share ByteDance's internal LLM training cluster","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"Relatively few stragglers came from machine problems, so traditional health metrics are unlikely to detect or prevent most of them. The most common causes were uneven pipeline stage partitioning, uneven sequence lengths in microbatches and garbage collection pauses, and because a straggling job is slow in almost every step, sampling a few profiled steps is enough to find them.","ko":"서버 문제로 생긴 스트래글러는 비교적 적어서, 기존 헬스 지표로는 대부분의 스트래글러를 찾거나 막기 어렵다. 가장 흔한 원인은 파이프라인 단계를 고르지 않게 나눈 것, 마이크로배치마다 시퀀스 길이가 다른 것, GC 멈춤이었다. 느린 작업에서는 대부분의 스텝이 비슷하게 느리므로 몇 스텝만 표본으로 프로파일링해도 충분하다. 장비 문제는 드물게 나지만 나면 감속이 심하다. 시퀀스 길이 불균형은 최대 시퀀스 길이가 길수록 영향이 커서, 컨텍스트가 길어질수록 더 중요한 문제가 된다."},"related":[],"sources":[{"url":"https://arxiv.org/abs/2505.05713","kind":"paper","archived":"https://web.archive.org/web/20261024122401/https://arxiv.org/abs/2505.05713"}],"summary":{"en":"The paper by ByteDance and NYU engineers studies traces of LLM pretraining jobs submitted from 2024/01/01 to 2024/05/31 on a dedicated training cluster with DGX-like servers (eight GPUs per server over NVLink or PCIe, four or eight NICs) on an over-provisioned three-layer CLOS network, where each job has exclusive GPUs. 3079 jobs that used at least 128 GPUs were analysed, 3.6% of them on at least 5000 GPUs, all running customised versions of Megatron-LM with data, pipeline, tensor and context parallelism. The in-house profiler NDTimeline recorded start and end times of compute and communication operations in 10% of training steps, and a what-if simulator replayed each job with straggling operations set to their ideal durations to estimate how long the job would take without stragglers; after dropping jobs restarted more than 15 times, jobs whose traces could not be analysed and traces with simulation error above 5%, the analysis covered 38.2% of the recorded jobs and 56.4% of their GPU hours.\n\nThree causes explained most stragglers. First, the last pipeline stage also runs the loss layer, which takes more compute than a transformer layer, so splitting layers evenly over stages made that stage slower; for 39.3% of jobs the last stage caused most of the slowdown, and in a test job its forward and backward computation were 2.07 and 1.41 times slower than an average stage. Second, in long-context jobs the training data had a long-tailed sequence length distribution and microbatches were filled with random sequences up to the maximum length, but self-attention cost grows with the square of each sequence length, so some data-parallel ranks finished late each step; 21.4% of straggling jobs were affected, with an average slowdown of 1.34, and the effect grew with the maximum sequence length. Third, Python's stop-the-world garbage collector paused forward computation for hundreds of milliseconds at different times on different workers, and the pauses grew as jobs ran, which the team suspects comes from a memory leak. Two rarer causes were CUDA memory fragmentation that slowed PyTorch's allocator with many cudaFree and cudaMalloc calls, and reduce-scatter kernels blocking unrelated kernels in large MoE jobs, which the team suspects is a false dependency from unrelated kernels sharing the same CUDA hardware queue.\n\nThe team already assigns fewer layers to the last pipeline stage, but the number has to be tuned by hand and whole layers limit how evenly work can be split; manual tuning of one job gave a 9.9% speedup and still left the last stage's forward computation at 1.55 times that of the other stages. A planned garbage collection introduced in 2023 turns off automatic collection and runs it on all workers at a set step interval, which gave a 12.6% improvement on a job with 128 data-parallel ranks, but it is off by default because a wrong interval can run the job out of memory, so it is not widely used. A prototype that redistributes sequences between data-parallel ranks to balance computation improved throughput by 23.9% on a 32K job. The analysis was built into SMon, which alerts the on-call team and shows a heatmap of worker slowdowns whose pattern points to the cause; within a month it located faulty machines in three cases and found one sequence length case and one pipeline partitioning case.","ko":"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% 를 넘는 기록은 버렸다.\n\n스트래글러는 흔했다. 분석한 작업의 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 를 다른 때 돌렸으므로 한 워커의 멈춤이 작업 전체를 막았다.\n\n드물지만 PyTorch CUDA 메모리 할당기의 메모리 단편화와, 서로 관계없는 커널이 같은 CUDA 하드웨어 큐를 써서 생긴 거짓 의존성도 스트래글러를 만들었다. 연구진은 분석의 일부를 모니터링 서비스 SMon 으로 만들어 이 클러스터에 배포했다. SMon 은 NDTimeline 프로파일링이 끝날 때마다 감속을 계산해 DP 랭크와 PP 랭크로 그린 히트맵으로 보여 준다. 배포 한 달 안에 SMon 으로 고장 난 장비 세 건, 시퀀스 길이 불균형 한 건, 파이프라인 단계 불균형 한 건을 찾아 해결했다."},"trigger":null,"severity":"unknown","symptoms":["throughput-degraded","uneven-load"],"timeline":{"detected_after":null,"resolved_after":null},"date_kind":"published","detection":{"en":"Stragglers were measured from NDTimeline traces with a what-if simulation; later SMon, which runs after each profiling session, alerts the on-call team when important jobs slow down significantly.","ko":"연구진은 NDTimeline 기록으로 스트래글러가 없는 경우를 시뮬레이션해 작업마다 감속을 계산하고 스트래글러를 찾았다. 그 뒤 배포한 SMon 은 프로파일링이 끝날 때마다 작업 감속, 스텝별 감속, 워커별 감속을 계산해 웹 페이지에 히트맵으로 보여 주고, 중요한 작업이 크게 느려지면 온콜 팀에 알린다. 온콜 팀은 워커 히트맵이 알려진 원인의 모양과 맞는지 보고, 스텝별 감속과 스텝별 히트맵으로 문제가 된 스텝과 랭크를 찾는다."},"components":["language-runtime"],"root_cause":"workload-imbalance","remediation":[{"text":{"en":"Assigned fewer layers to the last pipeline stage to offset the loss layer","ko":"Llama 3 처럼 마지막 파이프라인 단계에 레이어를 ε 개 적게 배정했다. 다만 ε 은 손으로 맞춰야 했고, 레이어를 통째로만 나눌 수 있어서 좋은 값을 골라도 성능이 최적에 못 미쳤다."}},{"text":{"en":"Tuned the number of layers in each pipeline stage by hand for one job, gaining a 9.9% speedup","ko":"트랜스포머 레이어 9개씩 네 단계로 나눈 작업에서 단계별 레이어 수를 손으로 조정해 속도를 9.9% 올렸다. 조정한 뒤에도 마지막 단계의 forward-compute 는 다른 단계의 1.55배였다."}},{"text":{"en":"Turned off Python's automatic garbage collection and ran it on all workers at a set training-step interval","ko":"2023년에 planned GC 라는 최적화를 만들었다. 이 최적화는 Python 의 자동 GC 를 끄고, 사용자가 학습 스텝 단위로 정한 간격마다 모든 워커가 함께 GC 를 돌린다. DP 랭크 128개를 쓰는 작업에서 500 스텝마다 GC 를 돌리자 12.6% 빨라졌다. 간격을 잘못 고르면 메모리가 모자라 작업이 죽거나 오히려 느려지므로, 이 최적화는 기본으로 켜지 않았다."}},{"text":{"en":"Prototyped redistributing sequences across data-parallel ranks, which improved throughput by 23.9% on a 32K job","ko":"배치를 만든 뒤 선형 모델로 시퀀스를 DP 랭크 사이에 다시 나눠 계산량을 맞추고, 랭크 안에서도 마이크로배치마다 시퀀스 길이 합을 맞추는 방법을 프로토타입으로 만들었다. 최대 시퀀스 길이가 32K 인 대표 작업에서 처리량이 23.9% 올랐다."}},{"text":{"en":"Increased CUDA_DEVICE_MAX_CONNECTIONS to relieve reduce-scatter kernels blocking other kernels","ko":"대형 MoE 모델을 학습할 때 reduce-scatter 커널이 관계없는 커널의 실행을 막아 작업이 크게 느려졌다. CUDA_DEVICE_MAX_CONNECTIONS 를 늘려 이 문제를 줄였다."}},{"text":{"en":"Located and addressed faulty machines behind stragglers in three cases with SMon","ko":"SMon 을 배포한 뒤 한 달 안에, 장비 문제로 생긴 스트래글러 세 건에서 고장 난 장비를 찾아냈다."}}],"action_items":[{"text":{"en":"Evaluate the sequence redistribution fix at scale before deploying it","ko":"시퀀스 재분배 방법을 실제로 배포하기 전에 대규모에서 효과를 평가한다."}},{"text":{"en":"Study how common CUDA memory fragmentation stragglers are and how to mitigate them","ko":"CUDA 메모리 단편화가 얼마나 흔한지와 줄이는 방법을 연구한다."}},{"text":{"en":"Address the gaps in what NDTimeline records, such as stragglers inside tensor- or context-parallel groups","ko":"NDTimeline 이 기록하는 내용 때문에 생긴 분석의 한계를 해결한다."}},{"text":{"en":"Keep investigating the false kernel dependency behind reduce-scatter kernels blocking other kernels to identify its cause","ko":"reduce-scatter 커널이 다른 커널을 막는 거짓 의존성의 원인을 계속 조사한다."}}],"contributing":["default-config-unchanged"],"recurrence_of":null,"symptoms_text":{"en":"Large LLM pretraining jobs on ByteDance's training cluster ran slower than they should because a few workers lagged behind the others and every synchronisation waited for them. Over January to May 2024, 42.5% of the traced jobs that used at least 128 GPUs straggled, and stragglers wasted 10.4% of all allocated GPU hours.\n\nThe slowdown was steady rather than bursty: in a straggling job the median training step had a normalised slowdown of 1.0 and even the 90th percentile step only 1.06, so nearly every step was as slow as the job overall. More than 10% of jobs wasted at least 21.3% of their allocated GPU hours and about 1% wasted at least 45.0%. Most of the lost time was in forward and backward computation, not in communication, and pipeline-parallel communication mattered slightly more than data-parallel communication.\n\nThe expected explanation, a bad server, accounted for few cases. Jobs slowed down more than 3 times were all large jobs in which fewer than 3% of the workers were responsible, but across straggling jobs the slowest 3% of workers explained more than half of the slowdown in only 1.7% of jobs; those jobs had an average slowdown of 3.04 against 1.28 overall. Because relatively few stragglers came from machine problems, traditional health metrics were unlikely to help detect most of them, and job size showed no obvious positive correlation with how badly a job straggled.","ko":"GPU 128개 이상을 쓰는 LLM 사전학습 작업 상당수가 스트래글러 때문에 이상적인 속도보다 느리게 돌았다. 스트래글러는 맡은 일을 다른 워커보다 늦게 끝내, 동기화해야 하는 다른 워커를 기다리게 만드는 워커다. 분석한 작업의 42.5% 가 스트래글러 때문에 최소 10% 느려졌다.\n\n작업의 10% 이상이 할당받은 GPU 시간의 21.3% 이상을 낭비했고, 약 1% 의 작업은 할당받은 GPU 의 45.0% 이상을 낭비했다. 전체 기록에서 할당된 GPU 시간의 10.4% 가 스트래글러 때문에 사라졌다.\n\n느린 작업 안에서는 대부분의 스텝이 비슷하게 느렸다. 작업 전체 감속으로 정규화한 스텝별 감속은 중앙값이 1.0, 90번째 백분위수가 1.06 이었다. 느려진 연산은 대부분 통신이 아니라 계산이었다. 통신 가운데서는 파이프라인 병렬인 PP 수준 통신이 데이터 병렬인 DP 수준 통신보다 조금 더 영향이 컸다. 작업 크기와 감속 사이에는 뚜렷한 양의 상관이 없었다.\n\n원인마다 모습이 달랐다. 마지막 파이프라인 단계가 무거운 작업은 마지막 단계의 forward-compute 와 backward-compute 가 다른 단계보다 길었다. 시퀀스 길이가 고르지 않은 작업은 스텝마다 무작위 DP 랭크에서 계산 시간이 크게 흔들렸고, forward 계산 시간과 backward 계산 시간의 상관계수가 0.9 이상이었다. 가비지 컬렉션인 GC 로 멈추는 작업은 워커마다 다른 스텝에서 GC 를 돌려 서로를 기다리게 했다. 이런 작업은 진행될수록 GC 멈춤 시간이 늘어 처리량이 서서히 떨어졌다.\n\n감속이 3배를 넘는 작업은 모두 대형 작업이었다. 이런 작업에서는 워커 3% 미만이 문제를 일으켰고, 느린 연산은 대개 계산이었다. 연구진은 이런 작업이 대개 하드웨어 문제나 설정 오류가 있는 서버 때문에 느려진다고 보았다. 그러나 스트래글러 작업 전체로 보면, 가장 느린 워커 3% 를 고쳤을 때 감속의 절반 이상이 풀리는 작업은 1.7% 뿐이었다."},"updated_at":"2026-11-14T12:34:06.787338Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0417","org_slug":"bytedance"}