From 955bf8565eb347fdde7c8a3575df7f379bac363d Mon Sep 17 00:00:00 2001 From: Junghwan Park Date: Sun, 24 May 2026 12:59:40 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EB=B8=94=EB=A1=9C=EA=B7=B8=20=EA=B8=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80:=202026-04-29-introducing-autosp,=20AutoSP?= =?UTF-8?q?=20=EC=86=8C=EA=B0=9C:=20=EC=BB=B4=ED=8C=8C=EC=9D=BC=EB=9F=AC?= =?UTF-8?q?=20=EA=B8=B0=EB=B0=98=20=EC=9E=90=EB=8F=99=20=EC=8B=9C=ED=80=80?= =?UTF-8?q?=EC=8A=A4=20=EB=B3=91=EB=A0=AC=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _posts/2026-04-29-introducing-autosp.md | 105 ++++++++++++++++++ .../unnamed-32.png | Bin 0 -> 66065 bytes 2 files changed, 105 insertions(+) create mode 100644 _posts/2026-04-29-introducing-autosp.md create mode 100644 assets/blog/2026-04-29-introducing-autosp/unnamed-32.png diff --git a/_posts/2026-04-29-introducing-autosp.md b/_posts/2026-04-29-introducing-autosp.md new file mode 100644 index 000000000..abd85ebb3 --- /dev/null +++ b/_posts/2026-04-29-introducing-autosp.md @@ -0,0 +1,105 @@ +--- +layout: blog_detail +title: "AutoSP 소개: 컴파일러 기반 자동 시퀀스 병렬화" +author: Ahan Gupta¹, Zhihao Wang¹, Neel Dani¹, Masahiro Tanaka², Olatunji Ruwase³, Minjia Zhang¹ +category: ["pytorch.org", "translation"] +org_title: "Introducing AutoSP" +org_link: https://pytorch.org/blog/introducing-autosp/ +--- + +대규모 언어 모델(Large-Language-Models, LLMs)은 점점 더 긴 컨텍스트를 다루는 작업을 위해 학습되고 있으며, 토큰 수가 100k 이상으로 증가하는 경우가 흔합니다. 이런 토큰 수에서는 ZeRO/FSDP와 같은 기존 학습 기법으로 디바이스 수를 늘리더라도 메모리 부족(OOM, out-of-memory) 문제가 발생하기 시작합니다. 이러한 문제를 회피하기 위해 **시퀀스 병렬화(Sequence Parallelism, SP)** — 입력 토큰을 여러 디바이스에 분할하여 GPU 수를 늘릴수록 더 긴 컨텍스트 학습을 가능하게 하는 기법 — 가 널리 사용되는 병렬 학습 기법입니다. +> Increasingly, Large-Language-Models (LLMs) are being trained for extremely long-context tasks, where token counts can exceed 100k+. At these token counts, out-of-memory (OOM) issues start to surface, even when scaling device counts using conventional training techniques such as ZeRO/FSDP. To circumvent these issues, sequence parallelism (SP): partitioning the input tokens across devices to enable long-context training with increasing GPU counts, is a commonly used parallel training technique. + +그러나 SP 구현은 매우 까다로운 작업으로 잘 알려져 있으며, DeepSpeed나 HuggingFace 같은 기존 라이브러리에 침습적인 코드 수정을 요구합니다. 이러한 코드 수정에는 입력 토큰 컨텍스트(및 중간 활성화)의 분할, 집합 통신(communication collectives) 삽입, 통신과 계산의 중첩이 포함되며, 이 모든 작업을 순전파와 역전파 모두에 대해 수행해야 합니다. 그 결과, 긴 컨텍스트 기능을 실험하려는 연구자들은 이러한 기능을 활성화하기 위한 시스템 스택 엔지니어링에 상당한 노력을 들이게 되고, 하드웨어 벤더가 달라질 때마다 이 작업을 반복해야 합니다. +> However, implementing SP is notoriously difficult, requiring invasive code changes to existing libraries such as DeepSpeed or HuggingFace. These code changes often involve partitioning input token contexts (and intermediate activations), inserting communication collectives, and overlapping communication with computation, all of which must be done for both the forward and backwards pass. This results in researchers who want to experiment with long context capabilities spending significant effort on engineering the system's stack to enable such capability, repeating this effort for different hardware vendors. + +이러한 복잡성을 피하기 위해 [AutoSP](https://openreview.net/pdf?id=0fgsHvmBBI)를 소개합니다. AutoSP는 작성하기 쉬운 학습 코드를 자동으로 멀티 GPU 시퀀스 병렬 코드로 변환하는 완전 자동화된 컴파일러 기반 솔루션으로, 기존 병렬 전략(예: ZeRO)과 조합하면서도 GPU를 효율적으로 활용해 더 긴 입력 컨텍스트에서 학습할 수 있게 합니다. 이를 통해 개발자가 긴 컨텍스트 학습을 위해 학습 파이프라인을 반복적으로 수정해야 하는 번거로움이 사라집니다. 이제 사용자는 AutoSP를 임포트(import)하고 AutoSP 백엔드를 사용해 임의의 모델을 컴파일하는 것만으로 누구나 긴 컨텍스트 학습의 힘을 누릴 수 있습니다. 또한 이 기술을 컴파일러에 내장함으로써 접근 방식이 성능 이식성(performance-portable)을 갖추게 되어, 다양한 하드웨어에서도 높은 성능의 SP를 구현할 수 있습니다. +> To avoid this complexity, we introduce [AutoSP](https://openreview.net/pdf?id=0fgsHvmBBI): a fully automated compiler-based solution that automatically converts easy-to-write training code to multi-GPU sequence parallel code that efficiently uses GPUs to train on longer input contexts while composing with existing parallel strategies (such as ZeRO). This avoids the cumbersome need for developers to repeatedly modify training pipelines for long-context training. Users can now simply import AutoSP and compile arbitrary models using the AutoSP backend, giving the power of long-context training to anyone. Moreover, by embedding this technology into the compiler, our approach is performance-portable: highly performant SP can be realised on diverse hardware. + +이번 글은 다음과 같이 구성됩니다. (1) AutoSP와 모델 연구자가 이를 어떻게 활용해 긴 컨텍스트 학습을 가능하게 할 수 있는지, (2) AutoSP의 핵심 설계 결정, (3) AutoSP의 주요 결과로 사용 편의성과 영향력 입증, (4) AutoSP의 한계와 할 수 없는 일. +> We structure this post as follows: (1) AutoSP and how model scientists can use it to enable long-context training, (2) Key design decisions of AutoSP, (3) key AutoSP results, demonstrating its ease-of-use and impact, (4) some limitations and things AutoSP cannot do. + +## AutoSP 사용법 / AutoSP Usage + +AutoSP의 핵심 설계 철학은 여러 GPU를 프로그래밍하는 데 따르는 복잡성 대부분을 사용자로부터 추상화하여 단순화하는 것입니다. 이를 위해 AutoSP를 [DeepCompile](https://arxiv.org/pdf/2504.09983) 위에 구현하였습니다. DeepCompile은 DeepSpeed 내부의 컴파일러 생태계로, 딥 뉴럴 네트워크 학습을 위한 다양한 최적화를 프로그래밍 방식으로 적용할 수 있게 합니다. 이를 통해 DeepSpeed를 사용하는 누구나 거의 부담 없이 시퀀스 병렬화를 자동으로 활성화할 수 있습니다. 예제를 살펴보겠습니다. +> A key design philosophy of AutoSP is simplicity in abstracting most of the complexity in programming multiple GPUs from users. To do this, we implement AutoSP within [DeepCompile](https://arxiv.org/pdf/2504.09983): a compiler ecosystem within DeepSpeed to programmatically enable diverse optimisations for deep neural network training. With this, any user who uses DeepSpeed can automatically enable Sequence Parallelism with almost zero hassle. We take a look at an example next. + +```python +# deepspeed config를 인스턴스화합니다. +# 2개의 DP rank와 4개의 SP rank를 가진 8개의 GPU를 가정합니다. + +config = { + "train_micro_batch_size_per_gpu": 1, + "train_batch_size": 2, + "steps_per_print": 1, + "optimiser": { + "type": "Adam", + "params": { + "lr": 1e-4 + } + }, + "zero_optimization": { + "stage": 1, # AutoSP는 ZeRO 0/1과 상호운용됩니다. + }, + # deepcompile을 켜고 AutoSP 패스를 활성화하도록 설정합니다. + "compile": { + "deepcompile": True, + "passes": ["autosp"] + }, + "sequence_parallel_size": 4, + "gradient_clipping": 1.0, +} + +# 모델로 deepspeed를 초기화합니다. +model, _, _ = deepspeed.initialize(config=config,model=model) + +# 모델을 컴파일하고 AutoSP 패스를 자동 적용합니다. +model.compile(compile_kwargs={"dynamic": True}) + +for idx, batch in enumerate(train_loader): + # deepspeed/compile/passes/sp_compile 내에서 노출하는 커스텀 함수입니다. + inputs, labels, positions, mask = prepare_auto_sp_inputs(batch) + + loss = model( + input_ids=inputs, + labels=labels, + position_ids=positions, + attention_mask=mask + ) + + ... # 역전파, 옵티마이저 스텝 등... +``` + +위 예제에서 볼 수 있듯이, 사용자는 단일 디바이스에서 실행되는 기존 학습 코드를 가져와 다음 작업을 수행합니다. (1) AutoSP 내부 프로그램 분석에 사용되도록, DeepSpeed에서 노출하는 `prepare_autosp_input` 유틸리티 함수를 사용해 입력 토큰, 어텐션 마스크, 위치 ID(position id)에 가벼운 태깅을 수행합니다. (2) DeepSpeed config를 조정해 DeepCompile을 켜고, `passes` 플래그를 `autosp`로 지정합니다. 나머지는 모델 컴파일 시 호출되는 AutoSP 컴파일러 패스를 통해 처리되며, 다른 긴 컨텍스트 학습 최적화와 함께 시퀀스 병렬화를 자동으로 활성화합니다. 또한 AutoSP는 기본적으로 ZeRO stage 1과 자동 조합되며, DeepSpeed에서 ZeRO-1 플래그를 AutoSP 플래그와 함께 설정하기만 하면 두 전략을 결합할 수 있습니다. +> As seen in the example above, users take existing training code that runs on a single device and do the following: (1) use the `prepare_autosp_input` utility function (exposed in DeepSpeed) for lightweight tagging of input tokens, attention masks and position ids for use in program analysis within AutoSP. (2) Adjust the DeepSpeed config to turn DeepCompile on, specifying the "passes" flag to "autosp". The rest is handled through the AutoSP compiler passes, called when compiling the model, which automatically enable sequence-parallelism alongside other long-context training optimisations. AutoSP additionally automatically composes with ZeRO stage 1 out of the box, simply set the ZeRO-1 flag in DeepSpeed alongside the AutoSP flags to combine both strategies. + +## AutoSP 컴파일러 패스 / AutoSP Compiler Passes + +AutoSP가 사용자 코드를 변환하여 더 긴 컨텍스트 학습을 가능하게 하기 때문에, 투명성을 위해 AutoSP의 핵심 설계 포인트와 코드 변환, 그리고 그것이 사용자에게 미치는 결과를 간략히 살펴봅니다. +> Since AutoSP transforms user code to enable longer-context training, we briefly cover the key design points of AutoSP and code transformations, as well as its consequences to users for transparency. + +**시퀀스 병렬화 코드 변환(Sequence Parallelism Code Transformations).** AutoSP는 단일 GPU 코드를 멀티 GPU 시퀀스 병렬(SP) 코드로 자동 변환합니다. AutoSP가 변환하는 구체적인 SP 전략은 [DeepSpeed-Ulysses](https://dl.acm.org/doi/10.1145/3662158.3662806) 입니다. 다른 전략(예: [RingAttention](https://arxiv.org/pdf/2310.01889))보다 DeepSpeed-Ulysses에 집중하는 이유는, NVLink 네트워크 토폴로지나 팻 트리(fat-tree) 네트워크에서 GPU 수가 증가해도 통신 오버헤드가 일정하게 유지되기 때문입니다. 다만 DeepSpeed-Ulysses는 SP 크기를 모델의 헤드 수(7-8B 모델에서는 32)까지만 확장할 수 있다는 제약이 있습니다. +> Sequence Parallelism Code Transformations. AutoSP automatically converts single-GPU code to multi-GPU sequence parallel (SP) code. The specific SP strategy AutoSP converts code into is [DeepSpeed-Ulysses](https://dl.acm.org/doi/10.1145/3662158.3662806). We specifically focus on DeepSpeed-Ulysses over other strategies (e.g. [RingAttention](https://arxiv.org/pdf/2310.01889)) as its communication overhead stays constant with increasing GPU counts on NVLink network topologies or fat-tree networks. However, DeepSpeed-Ulysses only enables scaling the SP-size to the number of heads in a model (32 in 7-8B models). + +**긴 컨텍스트 학습을 위한 활성화 체크포인팅(Activation Checkpointing for longer-context training).** AutoSP는 추가로 긴 컨텍스트 모델링에 맞춰 설계된 커스텀 활성화 체크포인팅(AC) 전략을 적용합니다. AC는 계산 비용이 저렴한 연산자의 중간 활성화를 해제하고, 역전파에서 관련 변화도(gradient)를 계산할 때 필요에 따라 다시 계산하는 방식입니다. PyTorch-2.0은 최대 흐름-최소 절단(max-flow min-cut) 기반의 자동화된 [AC 공식](https://dev-discuss.pytorch.org/t/min-cut-optimal-recomputation-i-e-activation-checkpointing-with-aotautograd/467)을 도입했지만, 긴 컨텍스트 모델링에는 지나치게 보수적이라는 점을 확인했습니다. 이에 따라 긴 컨텍스트 학습을 겨냥한 새로운 AC 전략인 **시퀀스 인식 AC(Sequence-aware AC, SAC)** 를 도입하여, 긴 컨텍스트에서 나타나는 고유한 FLOP 동학을 활용합니다. 이 기능이 활성화되면(AutoSP의 기본 설정) 학습 처리량이 약간 감소하지만, 이 기능 없이는 더 긴 컨텍스트에서의 학습이 불가능합니다. 따라서 사용자는 OOM이 발생하는 설정에 한해 이 패스를 선택적으로 켤 수 있습니다. +> Activation Checkpointing for longer-context training. AutoSP additionally applies a custom activation-checkpointing (AC) strategy curated for long-context modelling. AC releases intermediate activations of cheap-to-compute operators, recomputing them in the backwards pass as required to compute relevant gradients. PyTorch-2.0 introduces an automated max-flow min-cut based [AC formulation](https://dev-discuss.pytorch.org/t/min-cut-optimal-recomputation-i-e-activation-checkpointing-with-aotautograd/467), but we find this to be overly conservative for long-context modelling. We accordingly introduce a novel AC strategy targeted for long-context training: Sequence-aware AC (SAC), which exploits unique long-context FLOP dynamics. When triggered on (the default setting in AutoSP), this marginally reduces training throughput. However, without it, training on longer contexts is infeasible, so the user can selectively choose to turn this pass on only for configurations that OOM. + +## 실제 모델에서의 AutoSP 평가 / Evaluating AutoSP on Real Models + +AutoSP의 실효성을 입증하기 위해, NVIDIA GPU에서 다양한 크기의 모델로 성능을 평가하여 사용 편의성이 런타임 성능 손실로 거의 이어지지 않음을 보입니다. 8개의 A100-80GB SXM 노드에서 다양한 Llama 3.1 모델을 벤치마크합니다. PyTorch 2.7과 CUDA 12.8을 사용하며, AutoSP를 [RingFlashAttention](https://github.com/zhuzilin/ring-flash-attention), DeepSpeed-Ulysses, ZeRO-3의 torch-컴파일된 수작업 베이스라인과 비교합니다. 주요 결과를 아래 그림에 요약합니다. +> To demonstrate AutoSP's viability, we evaluate its performance on models of varying sizes on NVIDIA GPUs to show that its ease of use comes at little to no cost to runtime performance. We benchmark different Llama 3.1 models on an 8 A100-80Gb SXM node. We use PyTorch 2.7 with CUDA 12.8, comparing AutoSP to torch-compiled hand-written baselines of: [RingFlashAttention](https://github.com/zhuzilin/ring-flash-attention), DeepSpeed-Ulysses, and ZeRO-3. We summarise key results in the figure below: + +![AutoSP 벤치마크 결과 / AutoSP benchmark results](/assets/blog/2026-04-29-introducing-autosp/unnamed-32.png){:style="width:100%"} + +AutoSP는 동일한 자원으로 학습 가능한 최대 시퀀스 길이를 늘릴 수 있을 뿐 아니라(왼쪽 그림 — 클수록 좋음), 이러한 이득이 런타임 성능에 거의 비용을 발생시키지 않습니다(오른쪽 그림 — 작을수록 좋음). +> Not only can AutoSP increase the maximum trainable sequence length given the same resources (left figure – higher is better), but also these benefits come at little cost to runtime performance (right figure – lower is better). + +## 한계 / Limitations + +AutoSP에는 두 가지 핵심 한계가 있습니다. 첫째, 사용자는 트랜스포머를 단일 컴파일 가능한 아티팩트로 강제 컴파일해야 합니다. 때로 PyTorch 사용자는 여러 함수를 개별적으로 컴파일하여 하나의 모델로 이어 붙이기도 하는데, AutoSP에서는 이를 허용하지 않습니다. 입력 시퀀스를 올바르게 분할(shard)하고 그래프 전체에 정보를 전파하려면 모델 전체를 컴파일하고 관찰해야 하기 때문입니다. 둘째, 컴파일 가능한 아티팩트 내의 그래프 단절(graph break)을 일체 허용하지 않습니다. 그래프 단절은 정보의 분석과 전파를 복잡하게 만들기 때문에, AutoSP를 그래프 단절에 견디도록 확장하는 작업은 향후 연구 과제로 남겨둡니다. +> There are two key limitations of AutoSP. First, we require that the user forcefully compile a transformer as a single compilable artifact. Occasionally, PyTorch users may compile many functions individually and stitch them together into one model. This is disallowed in AutoSP as we need to compile and see the entire model to correctly shard input sequences and propagate this information throughout the entire graph. Second, we disallow any graph breaks in compilable artifacts. This complicates analysis and propagation of information, and we leave extending AutoSP to be graph-break resilient to future research. + +## 결론 / Conclusion + +AutoSP를 사용하면 임의의 트랜스포머 학습 코드를 손쉽게 확장하여 시퀀스 병렬화를 적용할 수 있으며, 긴 컨텍스트 학습 강화를 위한 커스텀 AC 전략도 함께 사용할 수 있습니다. DeepSpeed와의 통합을 통해 사용자는 설정 파일만 변경하는 것만으로 기존 DeepSpeed 학습 코드를 활용하여 더 긴 컨텍스트에서 학습할 수 있습니다. 실제 모델 워크로드(예: Llama 3.1 8B)에서 직접 사용해 볼 수 있는 종단 간(end-to-end) 예제를 [이곳](https://github.com/deepspeedai/DeepSpeedExamples/tree/master/benchmarks/autosp)에 준비해 두었습니다. 직접 시도해보고 긴 컨텍스트 학습이 얼마나 쉬워졌는지 확인해 보세요. +> AutoSP enables users to easily extend arbitrary transformer training code to enable Sequence Parallelism, with a custom AC strategy for enhanced long-context training. Integration with DeepSpeed allows users to easily use existing DeepSpeed training code to train on longer contexts by simply changing a config file. We have prepared end-to-end examples for users to play around with on real model workloads (e.g. Llama 3.1 8B) [here](https://github.com/deepspeedai/DeepSpeedExamples/tree/master/benchmarks/autosp). Give it a try to see how easy long context training has become. diff --git a/assets/blog/2026-04-29-introducing-autosp/unnamed-32.png b/assets/blog/2026-04-29-introducing-autosp/unnamed-32.png new file mode 100644 index 0000000000000000000000000000000000000000..64176cfc1b81587dd5608e8f5c4ae9d062779577 GIT binary patch literal 66065 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

QmQf0n!yrgOWUtWL*8zPP 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 literal 0 HcmV?d00001 From 5bbd6ab786b6f566b69b7b060a9f58ee69b1be9a Mon Sep 17 00:00:00 2001 From: Junghwan Park Date: Mon, 25 May 2026 20:50:06 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20AutoSP=20=EB=B2=88=EC=97=AD=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81=20=E2=80=94=20=EB=85=B8?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=EC=84=B1=20=EC=98=A4=EC=97=AD=20=EB=B0=8F?= =?UTF-8?q?=20=ED=95=A8=EC=88=98=EB=AA=85=20=EC=98=A4=ED=83=80=20=EC=A0=95?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 'an 8 A100-80Gb SXM node'를 '8장의 GPU를 갖춘 단일 노드'로 정정 (기존: 8개의 노드) - 'marginally reduces' 어감 보완: '약간' → '근소하게' - DeepSpeed 실제 함수명 'prepare_autosp_inputs'로 통일, 원문 오타에 대한 옮긴이 주 추가 --- _posts/2026-04-29-introducing-autosp.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_posts/2026-04-29-introducing-autosp.md b/_posts/2026-04-29-introducing-autosp.md index abd85ebb3..12d9b998c 100644 --- a/_posts/2026-04-29-introducing-autosp.md +++ b/_posts/2026-04-29-introducing-autosp.md @@ -58,7 +58,7 @@ model.compile(compile_kwargs={"dynamic": True}) for idx, batch in enumerate(train_loader): # deepspeed/compile/passes/sp_compile 내에서 노출하는 커스텀 함수입니다. - inputs, labels, positions, mask = prepare_auto_sp_inputs(batch) + inputs, labels, positions, mask = prepare_autosp_inputs(batch) loss = model( input_ids=inputs, @@ -70,7 +70,7 @@ for idx, batch in enumerate(train_loader): ... # 역전파, 옵티마이저 스텝 등... ``` -위 예제에서 볼 수 있듯이, 사용자는 단일 디바이스에서 실행되는 기존 학습 코드를 가져와 다음 작업을 수행합니다. (1) AutoSP 내부 프로그램 분석에 사용되도록, DeepSpeed에서 노출하는 `prepare_autosp_input` 유틸리티 함수를 사용해 입력 토큰, 어텐션 마스크, 위치 ID(position id)에 가벼운 태깅을 수행합니다. (2) DeepSpeed config를 조정해 DeepCompile을 켜고, `passes` 플래그를 `autosp`로 지정합니다. 나머지는 모델 컴파일 시 호출되는 AutoSP 컴파일러 패스를 통해 처리되며, 다른 긴 컨텍스트 학습 최적화와 함께 시퀀스 병렬화를 자동으로 활성화합니다. 또한 AutoSP는 기본적으로 ZeRO stage 1과 자동 조합되며, DeepSpeed에서 ZeRO-1 플래그를 AutoSP 플래그와 함께 설정하기만 하면 두 전략을 결합할 수 있습니다. +위 예제에서 볼 수 있듯이, 사용자는 단일 디바이스에서 실행되는 기존 학습 코드를 가져와 다음 작업을 수행합니다. (1) AutoSP 내부 프로그램 분석에 사용되도록, DeepSpeed에서 노출하는 `prepare_autosp_inputs` 유틸리티 함수(옮긴이 주: 원문의 `prepare_auto_sp_inputs` / `prepare_autosp_input` 표기는 오타이며, 실제 DeepSpeed에 노출된 함수명은 `prepare_autosp_inputs` 입니다)를 사용해 입력 토큰, 어텐션 마스크, 위치 ID(position id)에 가벼운 태깅을 수행합니다. (2) DeepSpeed config를 조정해 DeepCompile을 켜고, `passes` 플래그를 `autosp`로 지정합니다. 나머지는 모델 컴파일 시 호출되는 AutoSP 컴파일러 패스를 통해 처리되며, 다른 긴 컨텍스트 학습 최적화와 함께 시퀀스 병렬화를 자동으로 활성화합니다. 또한 AutoSP는 기본적으로 ZeRO stage 1과 자동 조합되며, DeepSpeed에서 ZeRO-1 플래그를 AutoSP 플래그와 함께 설정하기만 하면 두 전략을 결합할 수 있습니다. > As seen in the example above, users take existing training code that runs on a single device and do the following: (1) use the `prepare_autosp_input` utility function (exposed in DeepSpeed) for lightweight tagging of input tokens, attention masks and position ids for use in program analysis within AutoSP. (2) Adjust the DeepSpeed config to turn DeepCompile on, specifying the "passes" flag to "autosp". The rest is handled through the AutoSP compiler passes, called when compiling the model, which automatically enable sequence-parallelism alongside other long-context training optimisations. AutoSP additionally automatically composes with ZeRO stage 1 out of the box, simply set the ZeRO-1 flag in DeepSpeed alongside the AutoSP flags to combine both strategies. ## AutoSP 컴파일러 패스 / AutoSP Compiler Passes @@ -81,12 +81,12 @@ AutoSP가 사용자 코드를 변환하여 더 긴 컨텍스트 학습을 가능 **시퀀스 병렬화 코드 변환(Sequence Parallelism Code Transformations).** AutoSP는 단일 GPU 코드를 멀티 GPU 시퀀스 병렬(SP) 코드로 자동 변환합니다. AutoSP가 변환하는 구체적인 SP 전략은 [DeepSpeed-Ulysses](https://dl.acm.org/doi/10.1145/3662158.3662806) 입니다. 다른 전략(예: [RingAttention](https://arxiv.org/pdf/2310.01889))보다 DeepSpeed-Ulysses에 집중하는 이유는, NVLink 네트워크 토폴로지나 팻 트리(fat-tree) 네트워크에서 GPU 수가 증가해도 통신 오버헤드가 일정하게 유지되기 때문입니다. 다만 DeepSpeed-Ulysses는 SP 크기를 모델의 헤드 수(7-8B 모델에서는 32)까지만 확장할 수 있다는 제약이 있습니다. > Sequence Parallelism Code Transformations. AutoSP automatically converts single-GPU code to multi-GPU sequence parallel (SP) code. The specific SP strategy AutoSP converts code into is [DeepSpeed-Ulysses](https://dl.acm.org/doi/10.1145/3662158.3662806). We specifically focus on DeepSpeed-Ulysses over other strategies (e.g. [RingAttention](https://arxiv.org/pdf/2310.01889)) as its communication overhead stays constant with increasing GPU counts on NVLink network topologies or fat-tree networks. However, DeepSpeed-Ulysses only enables scaling the SP-size to the number of heads in a model (32 in 7-8B models). -**긴 컨텍스트 학습을 위한 활성화 체크포인팅(Activation Checkpointing for longer-context training).** AutoSP는 추가로 긴 컨텍스트 모델링에 맞춰 설계된 커스텀 활성화 체크포인팅(AC) 전략을 적용합니다. AC는 계산 비용이 저렴한 연산자의 중간 활성화를 해제하고, 역전파에서 관련 변화도(gradient)를 계산할 때 필요에 따라 다시 계산하는 방식입니다. PyTorch-2.0은 최대 흐름-최소 절단(max-flow min-cut) 기반의 자동화된 [AC 공식](https://dev-discuss.pytorch.org/t/min-cut-optimal-recomputation-i-e-activation-checkpointing-with-aotautograd/467)을 도입했지만, 긴 컨텍스트 모델링에는 지나치게 보수적이라는 점을 확인했습니다. 이에 따라 긴 컨텍스트 학습을 겨냥한 새로운 AC 전략인 **시퀀스 인식 AC(Sequence-aware AC, SAC)** 를 도입하여, 긴 컨텍스트에서 나타나는 고유한 FLOP 동학을 활용합니다. 이 기능이 활성화되면(AutoSP의 기본 설정) 학습 처리량이 약간 감소하지만, 이 기능 없이는 더 긴 컨텍스트에서의 학습이 불가능합니다. 따라서 사용자는 OOM이 발생하는 설정에 한해 이 패스를 선택적으로 켤 수 있습니다. +**긴 컨텍스트 학습을 위한 활성화 체크포인팅(Activation Checkpointing for longer-context training).** AutoSP는 추가로 긴 컨텍스트 모델링에 맞춰 설계된 커스텀 활성화 체크포인팅(AC) 전략을 적용합니다. AC는 계산 비용이 저렴한 연산자의 중간 활성화를 해제하고, 역전파에서 관련 변화도(gradient)를 계산할 때 필요에 따라 다시 계산하는 방식입니다. PyTorch-2.0은 최대 흐름-최소 절단(max-flow min-cut) 기반의 자동화된 [AC 공식](https://dev-discuss.pytorch.org/t/min-cut-optimal-recomputation-i-e-activation-checkpointing-with-aotautograd/467)을 도입했지만, 긴 컨텍스트 모델링에는 지나치게 보수적이라는 점을 확인했습니다. 이에 따라 긴 컨텍스트 학습을 겨냥한 새로운 AC 전략인 **시퀀스 인식 AC(Sequence-aware AC, SAC)** 를 도입하여, 긴 컨텍스트에서 나타나는 고유한 FLOP 동학을 활용합니다. 이 기능이 활성화되면(AutoSP의 기본 설정) 학습 처리량이 근소하게 감소하지만, 이 기능 없이는 더 긴 컨텍스트에서의 학습이 불가능합니다. 따라서 사용자는 OOM이 발생하는 설정에 한해 이 패스를 선택적으로 켤 수 있습니다. > Activation Checkpointing for longer-context training. AutoSP additionally applies a custom activation-checkpointing (AC) strategy curated for long-context modelling. AC releases intermediate activations of cheap-to-compute operators, recomputing them in the backwards pass as required to compute relevant gradients. PyTorch-2.0 introduces an automated max-flow min-cut based [AC formulation](https://dev-discuss.pytorch.org/t/min-cut-optimal-recomputation-i-e-activation-checkpointing-with-aotautograd/467), but we find this to be overly conservative for long-context modelling. We accordingly introduce a novel AC strategy targeted for long-context training: Sequence-aware AC (SAC), which exploits unique long-context FLOP dynamics. When triggered on (the default setting in AutoSP), this marginally reduces training throughput. However, without it, training on longer contexts is infeasible, so the user can selectively choose to turn this pass on only for configurations that OOM. ## 실제 모델에서의 AutoSP 평가 / Evaluating AutoSP on Real Models -AutoSP의 실효성을 입증하기 위해, NVIDIA GPU에서 다양한 크기의 모델로 성능을 평가하여 사용 편의성이 런타임 성능 손실로 거의 이어지지 않음을 보입니다. 8개의 A100-80GB SXM 노드에서 다양한 Llama 3.1 모델을 벤치마크합니다. PyTorch 2.7과 CUDA 12.8을 사용하며, AutoSP를 [RingFlashAttention](https://github.com/zhuzilin/ring-flash-attention), DeepSpeed-Ulysses, ZeRO-3의 torch-컴파일된 수작업 베이스라인과 비교합니다. 주요 결과를 아래 그림에 요약합니다. +AutoSP의 실효성을 입증하기 위해, NVIDIA GPU에서 다양한 크기의 모델로 성능을 평가하여 사용 편의성이 런타임 성능 손실로 거의 이어지지 않음을 보입니다. 8장의 A100-80GB SXM GPU를 갖춘 단일 노드에서 다양한 Llama 3.1 모델을 벤치마크합니다. PyTorch 2.7과 CUDA 12.8을 사용하며, AutoSP를 [RingFlashAttention](https://github.com/zhuzilin/ring-flash-attention), DeepSpeed-Ulysses, ZeRO-3의 torch-컴파일된 수작업 베이스라인과 비교합니다. 주요 결과를 아래 그림에 요약합니다. > To demonstrate AutoSP's viability, we evaluate its performance on models of varying sizes on NVIDIA GPUs to show that its ease of use comes at little to no cost to runtime performance. We benchmark different Llama 3.1 models on an 8 A100-80Gb SXM node. We use PyTorch 2.7 with CUDA 12.8, comparing AutoSP to torch-compiled hand-written baselines of: [RingFlashAttention](https://github.com/zhuzilin/ring-flash-attention), DeepSpeed-Ulysses, and ZeRO-3. We summarise key results in the figure below: ![AutoSP 벤치마크 결과 / AutoSP benchmark results](/assets/blog/2026-04-29-introducing-autosp/unnamed-32.png){:style="width:100%"}