PyTorch Fully Sharded Data Parallel을 사용하여 대규모 모델 학습 가속화하기

Hugging Face는 PyTorch Fully Sharded Data Parallel (FSDP)를 Accelerate 라이브러리에 통합하여, 옵티마이저 상태, 그래디언트, 파라미터를 데이터 병렬 워커 전반에 걸쳐 샤딩함으로써 실무자들이 훨씬 더 큰 모델을 학습할 수 있도록 지원합니다. 이 통합은 더 큰 배치 사이즈를 사용할 수 있게 하고, CPU 오프로딩을 통해 GPU 메모리 제한을 초과할 수 있는 모델을 학습할 수 있는 능력을 제공함으로써 대규모 모델 학습을 대중화합니다.

FSDP vs. Distributed Data Parallel (DDP)

PyTorch FSDP는 모든 GPU에 전체 모델 복제본을 유지함으로써 발생하는 중복 메모리 소비를 제거하여 Distributed Data Parallel (DDP)를 개선합니다.

DDP에서는 모든 워커가 모델 파라미터, 그래디언트, 옵티마이저 상태의 완전한 복사본을 유지합니다. 각 워커가 서로 다른 데이터 배치를 처리하는 동안, 모델을 업데이트하기 전에 모든 워커에 걸쳐 그래디언트를 평균화하기 위한 all-reduce 연산을 수행해야 합니다.

FSDP에서는 옵티마이저 상태, 그래디언트, 모델 파라미터가 워커 전반에 걸쳐 샤딩됩니다. 순방향 및 역방향 패스 동안, FSDP는 특정 레이어 또는 래핑된 모듈에 필요한 파라미터만을 가져오기 위해 all-gather 연산을 사용하며, 계산 직후 즉시 해제합니다. 그런 다음 로컬 그래디언트는 reduce-scatter 연산을 통해 평균화되고 분산되어, 각 워커가 자신의 로컬 파라미터 샤드만을 업데이트할 수 있게 합니다. 이 접근 방식은 GPU당 메모리 사용량을 획기적으로적으로 줄여줍니다.

GPT-2 성능 벤치마크

Hugging Face는 Causal Language Modeling 작업을 위해 두 개의 NVIDIA Titan RTX GPU (각 24GB)를 사용하여 FSDP를 DDP와 비교하는 벤치마크를 수행했습니다.

GPT-2 Large (762M Parameters)

FSDP는 DDP에 비해 훨씬 더 큰 배치 사이즈를 가능하게 합니다. CPU 오프로드 없이 FSDP는 최대 15의 배치 사이즈를 허용합니다 (DDP의 7과 비교). CPU 오프로드가 활성화된 경우, 배치 사이즈는 22까지 증가합니다. 혼합 정밀도 (FP16)를 사용한 DDP가 순수 학습 시간 측면에서는 가장 빨랐지만, FSDP는 더 큰 배치를 위한 메모리 효율성을 제공하며, 이는 특히 동적 배칭을 사용하는 애플리케이션에 유익합니다.

GPT-2 XL (1.5B Parameters)

GPT-2 XL 모델의 경우, DDP는 배치 사이즈 1에서도 CUDA Out of Memory (OOM) 오류가 발생했습니다. 반면, FSDP는 성공적인 학습을 가능하게 했습니다:

  • FSDP (Zero-Stage 3): 2개의 GPU에서 GPU당 배치 사이즈 5를 지원했습니다.
  • FSDP with CPU Offload: 단일 GPU에서 배치 사이즈 10으로 학습을 가능하게 했으며, 2개의 GPU에서 GPU당 배치 사이즈 14로 학습을 가능하게 했습니다.

기술적 구현 및 설정

Accelerate를 통한 통합

사용자는 accelerate config CLI를 사용하거나 FullyShardedDataParallelPlugin을 통해 더 세밀한 제어를 할 수 있습니다. 주요 설정 옵션은 다음과 같습니다:

  • Sharding Strategy: FULL_SHARDSHARD_GRAD_OP 사이의 선택.
  • Min Num Params: 기본 auto-wrap 정책에 의해 레이어가 래핑되는 데 필요한 최소 파라미터 수.
  • Offload Params: 파라미터와 그래디언트를 CPU로 오프로드할지 여부를 결정하는 불리언 값.

Auto Wrap Policy의 역할

min_num_params 설정은 메모리 최적화에 매우 중요합니다. default_auto_wrap_policy를 사용할 때, FSDP는 파라미터 수가 지정된 임계값(threshold)을 것을 초과하면 해당 레이어를 래핑합니다. BERT-Large (330M)에 대한 벤치마크 결과, auto-wrap을 사용한 FSDP는 DDP의 약 절반 정도의 메모리를 소비합니다. min_num_params를 낮추는 것(예: 2k) 것은 높은 임계값(예: 1M)보다 메모리 사용량을 약간 더 줄일 수 있습니다.

중요한 주의 사항 및 제한 사항

FSDP를 사용하는 실무자들은 다음과 같은 몇 가지 기술적 제약 사항을 인지해야 합니다:

  • Optimizer Initialization: FSDP는 파라미터를 평탄화(flatten)하고 제자리(in place)에서 샤딩합니다. 따라서 옵티마이저가 생성되기 accelerator.prepare(model)를 통해 모델을 준비해야 합니다. 모델을 래핑하기 전에 옵티마이저를 생성하면 옵티마이저가 깨지거나 메모리 사용량이 증가할 수 있습니다.
  • Parameter Groups: FSDP는 중첩된 모듈을 1D 배열로 평탄화하기 때문에, 래핑 전(예: 바이어스에 서로 다른 weight decay를 적용하는 경우)에 생성된 파라미터 그룹은 하나의 그룹으로 합쳐져 손실됩니다.
  • Multiple Models: 여러 모델을 학습할 때, 오류를 것을 피하기 위해 각 모델의 옵티마이저를 생성하기 전에 모델을들을 준비하는 것이 필수적입니다.
  • Mixed Precision: 이 게시물 작성 시점에는 PyTorch의 수정 사항이 대pending(pending) 대기 중인 관계로 인해 FSDP에서 혼합 정밀도가 지원되지 않았습니다.

분산 학습 접근 방식 요약

FSDP는 거대한 모델을 다루기 위해 설계된 광범위한 분산 학습 전략 생태계의 일부입니다:

  • ZeRO (Zero Redundancy Optimizer): FSDP의 기반이 되는 기술로, 옵티마이저 상태(Stage 1), 그래디언트(Stage 2), 파라미터(Stage 3)를 샤딩합니다.
  • Tensor Parallelism: 개별 대형 레이어의 파라미터를 여러 GPU에 샤딩합니다.
  • Pipeline Parallelism: 서로 다른 레이어를 서로 다른 GPU에 분산 배치하고 마이크로 배치를 파이프라이닝합니다.
  • 3D Parallelism: ZeRO, Tensor, 그리고 Pipeline 병렬성을 조합한 방식으로, 수천억 개의 파라미터를 가진 모델을 학습할 때 사용됩니다.

Sources

관련

  • Dispatch
  • Dispatch
  • Dispatch
  • Dispatch
  • Dispatch