
최근 Hugging Face가 "Ulysses Sequence Parallelism: Training with Million-Token Contexts"를 통해 '백만 토큰급 컨텍스트 학습'이 더 이상 공상과학이 아니라는 신호를 던졌습니다1. 긴 문서를 한 번에 읽는 모델이 필요해지는 지금, 문제는 아이디어가 아니라 "GPU 메모리가 버티느냐"였고, Ulysses Sequence Parallelism(시퀀스/컨텍스트 병렬화)은 그 병목을 아주 정면으로 찌릅니다.
Ulysses Sequence Parallelism이 바꾸는 것: "시퀀스"를 나눠서 "헤드"로 모으기
긴 컨텍스트에서 가장 먼저 터지는 건 어텐션입니다. 시퀀스 길이가 커질수록 어텐션 관련 활성화(activations)와 중간 텐서가 기하급수로 불어나기 때문이죠. Ulysses의 핵심은 입력을 시퀀스 축으로 쪼개 들고 있다가, 어텐션을 계산하기 직전에 통신으로 재배치해 "각 GPU는 전체 시퀀스를 보되, 헤드 일부만 맡는" 형태로 바꿔치기하는 발상입니다.
즉, 처음엔 GPU마다 "짧은 시퀀스 조각 + 모든 헤드"를 들고 있다가, all-to-all 통신으로 "전체 시퀀스 + 헤드 조각"으로 바꾼 뒤 각자 로컬에서 밀집(dense) 어텐션을 계산하고, 결과를 다시 all-to-all로 원래 분할로 돌려보냅니다. 이 구조 덕분에 어텐션 계산은 깔끔해지고, 통신 라운드도 비교적 단순해집니다(레이어당 큰 all-to-all 두 번이라는 감각). 이런 설명은 Ulysses가 왜 "현대 GPU 클러스터의 all-to-all에 잘 맞는다"는 평가를 받는지와도 연결됩니다23.
DeepSpeed-Ulysses로 100만 토큰까지: 현실적인 구현 포인트
이 개념이 실전에서 빛을 보려면 "어떻게 붙이느냐"가 관건인데, DeepSpeed-Ulysses는 그 부분을 꽤 실용적으로 정리했습니다. 기존 트랜스포머에서 어텐션 모듈을 크게 갈아엎기보다, 원래의 로컬 어텐션 블록을 감싸는 형태로 분산 어텐션을 끼워 넣는 방식이어서 적용 난이도가 낮습니다4.
또한 긴 시퀀스는 메모리뿐 아니라 속도도 문제인데, DeepSpeed-Ulysses는 FlashAttention 같은 커널 최적화, ZeRO 옵티마이저 등과 함께 쓰는 조합을 전제로 설계되어 "길게만"이 아니라 "그나마 빠르게"를 노립니다4. 실제로 64대 A100에서 시퀀스 길이 100만 토큰까지 다뤘다는 수치가 공개되며(해리포터 한 권의 10배쯤이라는 비유까지) 업계의 기준선을 확 끌어올렸죠4.
다만 조건도 있습니다. 대표적으로 "어텐션 헤드 수가 시퀀스 병렬 크기로 나누어떨어져야" 하는 식의 제약이 생길 수 있고, 특정 병렬화 조합과의 호환성도 체크해야 합니다4. 긴 컨텍스트는 언제나 '한 방에 다 된다'가 아니라 '궁합표를 보고 들어간다'에 가깝습니다.
100만 토큰 이후의 싸움: 통신이 아니라 "활성화 메모리"와 "스케줄링"
흥미로운 지점은 여기서부터입니다. 컨텍스트 병렬화(시퀀스 병렬화)는 길이를 늘리는 데 강력하지만, 길이가 몇 백만 토큰대로 가면 GPU당 활성화 메모리가 또 다시 발목을 잡습니다. 그래서 최근 연구는 "통신을 더 줄이자"만이 아니라 "어텐션 내부 중간 텐서를 어떻게 덜 들고 있을까"로도 이동하고 있습니다.
예를 들어 Untied Ulysses(UPipe)는 어텐션 헤드를 더 잘게 나눠 '한 번에 일부 헤드만' 처리하는 식으로 활성화 메모리를 크게 줄이는 접근을 제시합니다. 32B급 모델에서 어텐션 중간 텐서 메모리를 최대 87.5% 줄였다고 보고했고, 8×H100 한 노드에서 500만 토큰 컨텍스트를 목표로 합니다5. 요약하면 "Ulysses가 문을 열었다면, UPipe는 그 문틀을 넓히는" 방향입니다.
한편 현장 최적화에서는 통신-계산 겹치기(오버랩)도 중요합니다. Q/K/V가 어텐션 직전까지는 서로 독립이라는 점을 이용해, 한쪽은 GEMM을 돌리고 다른쪽은 all-to-all을 날려 '직렬 구간'을 줄이는 Async Ulysses류 스케줄이 소개되기도 했습니다. 마이크로벤치에서 프리-어텐션 구간 지연이 20%대 줄어드는 식의 개선이 관측됐지만, 전체 스텝은 어텐션 이후 구간이 지배적이라 체감은 더 작을 수 있다는 식의 냉정한 결론도 같이 따라옵니다2. 즉, "길게"와 "빠르게"는 같은 문제가 아니고, 둘 다 잡으려면 커널·스케줄·통신이 함께 맞물려야 합니다.
시사점
Ulysses Sequence Parallelism은 긴 컨텍스트 학습의 질문을 "가능/불가능"에서 "어떤 조합으로, 어디까지 경제적으로?"로 바꿔놓았습니다. 당장 실무에서 적용한다면, 먼저 목표 시퀀스 길이를 정하고(예: 32K, 128K, 1M), 그다음 all-to-all 성능이 좋은 환경(NVLink 등)인지, 헤드 수/병렬 크기 제약을 만족하는지, FlashAttention·ZeRO·체크포인팅 같은 메모리/속도 옵션을 어떤 우선순위로 쓸지부터 정리하는 편이 안전합니다4.
그리고 100만 토큰을 넘보는 순간부터는 "통신 최적화만"으로는 부족할 수 있습니다. 활성화 메모리 장벽을 깨기 위한 헤드 단위 청킹(UPipe) 같은 아이디어가 왜 나오는지 이해하고, 내 워크로드가 병목이 통신인지 메모리인지(혹은 커널 런치 오버헤드인지)를 프로파일링으로 먼저 확인하는 것이, 가장 빠른 지름길입니다52.
참고
1Ulysses Sequence Parallelism: Training with Million-Token Contexts
2Ulysses Unbound: Experiments in Communication-Computation Overlap
4Getting Started with DeepSpeed-Ulysses for Training Transformer Models with Extreme Long Sequences
5Untied Ulysses: Memory-Efficient Context Parallelism via Headwise Chunking
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.
