# Part 12: 대규모 AI 모델 최적화 및 서빙 **⬅️ 이전 시간: [Part 11: 프로덕션 레벨 MLOps 심화](./part_11_mlops.md)** **➡️ 다음 시간: [Part 13: 생성형 AI 및 AI 에이전트 심화](./part_13_generative_ai.md)** --- ## 1. 학습 목표 (Learning Objectives) > 이 섹션에서는 대규모 AI 모델을 효율적으로 학습시키고, 실제 서비스에 배포하기 위한 최적화 기법들을 학습합니다. - PyTorch FSDP 및 DeepSpeed를 활용하여 대규모 모델을 분산 학습하는 방법을 이해합니다. - 양자화(Quantization), 가지치기(Pruning), 지식 증류(Knowledge Distillation) 등 모델 경량화 기법의 원리를 파악하고 적용할 수 있습니다. - NVIDIA Triton, TorchServe와 같은 고성능 추론 서버를 사용하여 모델 서빙의 처리량과 안정성을 극대화하는 방법을 학습합니다. ## 2. 핵심 키워드 (Keywords) `분산 학습`, `FSDP`, `DeepSpeed`, `모델 경량화`, `양자화(Quantization)`, `가지치기(Pruning)`, `지식 증류(Knowledge Distillation)`, `Triton`, `TorchServe` ## 3. 도입 최신 AI 모델의 크기는 기하급수적으로 증가하고 있으며, 이는 전례 없는 성능 향상을 가져왔지만 동시에 엄청난 컴퓨팅 자원을 요구하는 도전 과제를 안겨주었습니다. Part 12에서는 이처럼 거대한 모델을 현실적인 제약 속에서 어떻게 다룰 수 있는지에 대한 해법을 제시합니다. 여러 GPU를 활용하여 학습의 한계를 돌파하고, 모델의 군살을 빼서 서빙 효율을 높이는 기술들을 통해, 여러분의 AI 모델을 더 빠르고, 더 가볍고, 더 강력하게 만드는 방법을 배우게 될 것입니다. --- ## 4. 효율적 분산 학습 최근 언어 모델(LLM)을 필두로 AI 모델의 파라미터 수는 수천억, 수조 개에 달할 정도로 거대해지고 있습니다. 이처럼 거대한 모델을 단일 GPU 메모리에 올려 학습하는 것은 불가능에 가깝습니다. 설령 메모리가 충분하더라도, 대규모 데이터셋으로 학습을 완료하는 데는 수개월 이상이 소요될 수 있습니다. **분산 학습(Distributed Training)**은 이러한 한계를 극복하기 위해 여러 개의 GPU(또는 여러 노드의 GPU들)를 사용하여 학습을 병렬로 처리하는 기술입니다. 분산 학습을 통해 우리는 다음을 달성할 수 있습니다. - **더 큰 모델 학습**: 단일 GPU의 메모리 한계를 넘어 수십, 수백억 개 파라미터의 모델을 학습시킬 수 있습니다. - **학습 시간 단축**: 여러 GPU가 작업을 나누어 처리함으로써 전체 학습 시간을 획기적으로 줄일 수 있습니다. ### 분산 학습의 종류 분산 학습은 크게 데이터 병렬 처리와 모델 병렬 처리로 나뉩니다. - **데이터 병렬 처리 (Data Parallelism)** - 가장 기본적인 분산 학습 방식으로, 여러 GPU에 동일한 모델을 복제하고, 전체 학습 데이터를 미니배치로 나누어 각 GPU에 할당합니다. - 각 GPU는 할당된 데이터로 모델을 학습하여 그래디언트(gradient)를 계산하고, 모든 GPU의 그래디언트를 동기화하여 모델 파라미터를 업데이트합니다. - 모델 크기가 단일 GPU에 담길 수 있을 때 효과적입니다. - PyTorch의 `DistributedDataParallel` (DDP)가 대표적인 예입니다. - **모델 병렬 처리 (Model Parallelism)** - 모델 자체가 너무 커서 단일 GPU 메모리에 올라가지 않을 때 사용합니다. 모델의 레이어나 파라미터를 여러 GPU에 나누어 배치합니다. - **텐서 병렬 처리 (Tensor Parallelism)**: 모델의 각 레이어 내부 연산(예: 행렬 곱)을 여러 GPU로 분할하여 처리합니다. - **파이프라인 병렬 처리 (Pipeline Parallelism)**: 모델의 레이어들을 여러 GPU에 순차적으로 할당하고, 마이크로배치(micro-batch)를 파이프라인처럼 흘려보내며 학습을 진행합니다. - **ZeRO (Zero Redundancy Optimizer)**: 데이터 병렬처리를 기반으로 하지만, 모델 파라미터, 그래디언트, 옵티마이저 상태(state)까지 여러 GPU에 분할(shard)하여 저장함으로써 메모리 사용량을 극적으로 최적화합니다. --- ### PyTorch FSDP (Fully Sharded Data Parallel) PyTorch FSDP는 PyTorch 2.0부터 정식으로 포함된 차세대 분산 학습 기술로, ZeRO-3와 유사한 아이디어를 기반으로 구현되었습니다. 데이터 병렬처리를 수행하면서 모델 파라미터, 그래디언트, 옵티마이저 상태를 모든 GPU에 분할하여 저장합니다. **주요 특징:** - **메모리 효율성**: 각 GPU는 전체 파라미터의 일부만 소유하므로, 훨씬 큰 모델을 학습시킬 수 있습니다. - **통신 오버랩**: 연산(computation)과 통신(communication)을 최대한 겹치게(overlap) 설계하여 학습 속도 저하를 최소화합니다. - **PyTorch 통합**: PyTorch에 네이티브하게 통합되어 있어 `DistributedDataParallel` (DDP)에서 마이그레이션하기 비교적 용이합니다. **FSDP 사용법:** FSDP는 모델의 각 레이어를 'FSDP unit'으로 감싸는 방식으로 동작합니다. `auto_wrap` 정책을 사용하면 특정 레이어 타입(예: TransformerBlock)을 지정하여 자동으로 감싸도록 설정할 수 있어 편리합니다. ```python # main.py import torch.distributed as dist from torch.distributed.fsdp import FullyShardedDataParallel as FSDP from torch.distributed.fsdp.wrap import size_based_auto_wrap_policy import functools # ... 분산 환경 설정 (dist.init_process_group) ... model = MyLargeModel() # FSDP 적용 # 특정 사이즈보다 큰 모듈을 자동으로 FSDP unit으로 감싸는 정책 사용 auto_wrap_policy = functools.partial( size_based_auto_wrap_policy, min_num_params=1_000_000 ) model = FSDP(model, auto_wrap_policy=auto_wrap_policy) # ... 이후 학습 루프는 DDP와 유사 ... ``` --- ### Microsoft DeepSpeed DeepSpeed는 Microsoft에서 개발한 대규모 분산 학습 라이브러리로, ZeRO를 포함한 다양한 메모리 최적화 기술과 파이프라인 병렬처리 등을 통합 제공하는 강력한 도구입니다. **주요 특징:** - **ZeRO (Zero Redundancy Optimizer)**: DeepSpeed의 핵심 기술로, 메모리 사용량을 최적화하는 단계별 옵션을 제공합니다. - **ZeRO-1**: 옵티마이저 상태를 분할합니다. - **ZeRO-2**: 옵티마이저 상태와 그래디언트를 분할합니다. - **ZeRO-3**: 옵티마이저 상태, 그래디언트, 모델 파라미터까지 모두 분할합니다. (FSDP와 유사) - **통합 솔루션**: 3D 병렬 처리(데이터, 텐서, 파이프라인)를 모두 지원하며, 대규모 모델 추론(DeepSpeed-Inference) 등 다양한 기능을 제공합니다. - **간편한 설정**: 학습 코드를 거의 수정하지 않고, JSON 설정 파일과 `deepspeed` 런처를 통해 분산 학습을 적용할 수 있습니다. **DeepSpeed 사용법:** 1. **설정 파일 작성 (`ds_config.json`)** ```json { "train_batch_size": 16, "optimizer": { "type": "Adam", "params": { "lr": 0.001 } }, "fp16": { "enabled": true }, "zero_optimization": { "stage": 2 } } ``` 2. **학습 스크립트 수정** ```python # training.py import deepspeed # ... 모델, 옵티마이저 등 정의 ... # deepspeed.initialize()를 사용하여 모델 및 옵티마이저를 래핑 model_engine, optimizer, _, _ = deepspeed.initialize( model=model, optimizer=optimizer, config=args.deepspeed_config, ) # ... 학습 루프 ... # loss = model_engine(data) # model_engine.backward(loss) # model_engine.step() ``` 3. **`deepspeed` 런처로 실행** ```bash deepspeed --num_gpus=4 training.py --deepspeed --deepspeed_config ds_config.json ``` ### FSDP vs DeepSpeed | 구분 | PyTorch FSDP | Microsoft DeepSpeed | |---|---|---| | **통합성** | PyTorch 네이티브. 생태계와 긴밀하게 통합 | 외부 라이브러리. 별도 설치 및 설정 필요 | | **사용 편의성** | 코드 수정이 더 필요할 수 있음 | JSON 설정 파일 기반으로 코드 수정 최소화 | | **기능** | Sharded Data Parallelism에 집중 | ZeRO, 3D 병렬처리, 추론 최적화 등 종합적인 기능 제공 | | **커뮤니티/지원**| PyTorch 공식 지원 | Microsoft 및 활발한 오픈소스 커뮤니티 | 최근에는 FSDP가 PyTorch의 기본 분산 학습 방식으로 자리 잡아가고 있지만, DeepSpeed는 여전히 강력한 기능과 편리함으로 많은 연구 및 프로덕션 환경에서 사용되고 있습니다. 어떤 것을 선택할지는 프로젝트의 요구사항과 개발 환경에 따라 달라질 수 있습니다. --- ## 5. 모델 경량화 기법 대규모 모델은 뛰어난 성능을 보이지만, 막대한 계산 리소스와 메모리를 요구하여 실제 서비스에 배포하고 운영하는 데 큰 부담이 됩니다. 특히 모바일, 엣지 디바이스와 같이 리소스가 제한적인 환경에서는 모델을 그대로 사용하기 어렵습니다. **모델 경량화(Model Quantization)**는 이미 학습된 모델의 성능을 최대한 유지하면서, 모델 크기를 줄이고 추론 속도를 향상시키는 기술들을 총칭합니다. 이를 통해 다음과 같은 이점을 얻을 수 있습니다. - **빠른 추론 속도**: 모델의 연산량이 줄어들어 예측 결과를 더 빠르게 얻을 수 있습니다. - **메모리 사용량 감소**: 모델이 차지하는 메모리와 스토리지 공간이 줄어듭니다. - **온디바이스(On-device) AI 구현**: 스마트폰, IoT 기기 등 엣지 디바이스에 직접 AI 모델을 탑재할 수 있습니다. - **서버 비용 절감**: 더 적은 계산 리소스로 동일한 서비스를 처리할 수 있어 클라우드 비용 등이 절감됩니다. 대표적인 모델 경량화 기법으로는 양자화(Quantization), 가지치기(Pruning), 지식 증류(Knowledge Distillation)가 있습니다. ### 1. 양자화 (Quantization) **양자화**는 모델의 가중치(weights)와 활성화 함수(activations) 값의 데이터 타입을 더 적은 비트(bit)로 표현하여 모델 크기를 줄이는 가장 널리 사용되는 경량화 기법입니다. 일반적으로 32-bit 부동소수점(FP32)으로 표현되는 실수 값들을 8-bit 정수(INT8)나 16-bit 부동소수점(FP16) 등으로 변환합니다. - **장점**: 모델 크기를 약 1/4(FP32 -> INT8)로 크게 줄일 수 있으며, 정수 연산이 가능한 하드웨어(CPU, GPU, NPU)에서 매우 빠른 추론 속도를 얻을 수 있습니다. - **단점**: 데이터 표현의 정밀도가 낮아져 모델 성능이 약간 저하될 수 있습니다. **주요 양자화 기법:** - **PTQ (Post-Training Quantization)**: 이미 학습된 FP32 모델을 가지고 추가적인 학습 없이 양자화를 수행합니다. 간단하게 적용할 수 있지만, 모델에 따라 성능 하락이 클 수 있습니다. - **QAT (Quantization-Aware Training)**: 모델 학습 과정 자체에 양자화로 인한 오차를 시뮬레이션하여, 양자화 후에도 성능 저하를 최소화하도록 훈련하는 방식입니다. PTQ보다 과정이 복잡하지만 더 좋은 성능을 보장합니다. ### 2. 가지치기 (Pruning) **가지치기**는 모델의 성능에 거의 영향을 주지 않는 불필요한 뉴런(neuron)이나 가중치 연결을 제거하여 모델을 희소(sparse)하게 만드는 기법입니다. 마치 나무의 잔가지를 쳐내어 더 튼튼하게 만드는 것과 같습니다. - **장점**: 모델의 파라미터 수를 직접적으로 줄여 크기를 감소시키고, 연산량을 줄여 추론 속도를 향상시킬 수 있습니다. - **단점**: 어떤 가중치를 제거할지 결정하는 기준이 복잡하며, 구조화되지 않은 가지치기는 실제 하드웨어에서 속도 향상으로 이어지기 어려울 수 있습니다. **주요 가지치기 기법:** - **비구조적 가지치기 (Unstructured Pruning)**: 개별 가중치의 중요도를 평가하여 중요도가 낮은 가중치를 하나씩 제거합니다. 모델 압축률은 높지만, 희소한 행렬 연산을 지원하는 특수한 하드웨어가 없으면 속도 향상을 기대하기 어렵습니다. - **구조적 가지치기 (Structured Pruning)**: 채널(channel), 필터(filter), 레이어(layer) 등 특정 구조 단위로 연결을 제거합니다. 모델의 구조가 유지되어 일반적인 하드웨어에서도 속도 향상을 얻기 용이하지만, 비구조적 방식보다 압축률이 낮을 수 있습니다. ### 3. 지식 증류 (Knowledge Distillation) **지식 증류**는 크고 복잡하지만 성능이 좋은 **선생님 모델(Teacher Model)**의 지식을 작고 가벼운 **학생 모델(Student Model)**에게 전달하여, 학생 모델이 선생님 모델의 성능을 모방하도록 학습시키는 기법입니다. - **작동 방식**: 학생 모델은 실제 정답(hard label)뿐만 아니라, 선생님 모델의 예측 결과(soft label, 각 클래스에 대한 확률 분포)를 함께 학습합니다. 선생님 모델의 "정답에 대한 확신도"까지 학습함으로써, 학생 모델은 더 풍부한 정보를 바탕으로 효율적으로 훈련될 수 있습니다. - **장점**: 완전히 다른 구조의 작은 모델을 만들 수 있어 유연성이 높고, 압축률의 한계가 없습니다. 단독으로 사용되거나 양자화, 가지치기 등 다른 기법과 함께 사용되기도 합니다. - **단점**: 좋은 성능의 선생님 모델을 먼저 확보해야 하며, 학생 모델을 처음부터 학습시켜야 하므로 훈련 비용과 시간이 많이 소요됩니다. --- ## 6. 고성능 추론 서버 활용 모델을 경량화하는 것만큼, 학습된 모델을 효율적으로 서빙하는 것 또한 중요합니다. Python 기반의 웹 프레임워크(예: FastAPI, Flask)는 모델 서빙 API를 빠르고 간단하게 만들 수 있다는 장점이 있지만, 대규모 트래픽 처리나 복잡한 서빙 요구사항에는 한계가 있습니다. **고성능 추론 서버(High-Performance Inference Server)**는 프로덕션 환경에서 머신러닝 모델을 안정적이고 효율적으로 배포하고 운영하기 위해 특별히 설계된 전문 소프트웨어입니다. ### 왜 전문 추론 서버가 필요한가? - **처리량(Throughput) 극대화**: 들어오는 요청들을 자동으로 그룹화하여 GPU에서 병렬로 한 번에 처리하는 **동적 배치(Dynamic Batching)** 기능을 통해 GPU 활용률을 극대화하고 처리량을 높입니다. - **다중 모델 서빙**: 단일 서버 인스턴스에서 서로 다른 프레임워크(PyTorch, TensorFlow, ONNX 등)로 만들어진 여러 모델을 동시에 서빙할 수 있습니다. - **동시성(Concurrency)**: 여러 모델을 동시에 실행하거나, 단일 모델의 여러 인스턴스를 동시에 실행하여 여러 요청을 지연 없이 처리할 수 있습니다. - **표준화된 인터페이스**: HTTP/gRPC와 같은 표준 프로토콜을 지원하여 어떤 클라이언트 환경에서도 쉽게 모델 추론을 요청할 수 있습니다. ### NVIDIA Triton Inference Server NVIDIA Triton은 클라우드 및 엣지 환경에서 AI 모델 추론을 표준화하기 위해 설계된 오픈소스 추론 서빙 소프트웨어입니다. **주요 특징:** - **다양한 프레임워크 지원**: TensorRT, PyTorch, TensorFlow, ONNX, OpenVINO 등 거의 모든 주요 ML 프레임워크를 지원합니다. - **동적 배치 (Dynamic Batching)**: 서버에 도착하는 개별 추론 요청들을 실시간으로 큐에 모았다가, 지정된 배치 크기(batch size)가 되면 한 번에 묶어 GPU로 보내 처리합니다. 이를 통해 GPU의 병렬 처리 능력을 최대한 활용하여 처리량을 높입니다. - **동시 모델 실행 (Concurrent Model Execution)**: 단일 GPU에서 여러 모델 또는 동일 모델의 여러 인스턴스를 동시에 로드하여, 서로 다른 요청을 병렬로 처리할 수 있습니다. - **모델 저장소 (Model Repository)**: 특정 디렉토리 구조에 맞게 모델 파일을 저장해두면, Triton 서버가 자동으로 모델을 인식하고 로드합니다. 모델 버전 관리, 업데이트, 로드/언로드 등의 기능을 CLI나 API를 통해 제어할 수 있습니다. - **모델 앙상블 (Model Ensemble)**: 여러 모델의 추론 파이프라인을 단일 워크플로우로 묶어 서빙할 수 있습니다. 예를 들어, 전처리 모델 -> 메인 모델 -> 후처리 모델의 흐름을 하나의 앙상블로 정의하여 클라이언트가 한 번의 요청으로 전체 결과를 받을 수 있게 합니다. **Triton 아키텍처:** Triton은 클라이언트/서버 모델로 작동합니다. 클라이언트는 HTTP나 gRPC를 통해 Triton 서버에 추론 요청을 보냅니다. Triton 서버는 모델 저장소에서 모델을 관리하며, 들어온 요청을 스케줄링하고 백엔드(PyTorch, ONNX 등)를 통해 실행하여 결과를 반환합니다. ``` +----------------+ HTTP/gRPC +---------------------+ | Client App | <----------------> | Triton Server | +----------------+ Request/Resp. | +-----------------+ | | | | | Model Scheduler | | | | | | (Dynamic Batcher) | | | | | +-----------------+ | | | | | Backends | | | | | | - PyTorch | | | | | | - ONNX | | | | | | - TensorRT | | | | | | - etc. | | +----------------+ +---------------------+ ^ | +---------------------+ | Model Repository | | (Local/Cloud Storage) | +---------------------+ ``` ### TorchServe TorchServe는 PyTorch 커뮤니티에서 직접 개발하고 지원하는 PyTorch 모델 서빙을 위한 공식 도구입니다. **주요 특징:** - **PyTorch 최적화**: PyTorch 모델 서빙에 특화되어 있으며, `torch-model-archiver`를 통해 모델과 핸들러를 `.mar` 파일로 쉽게 패키징할 수 있습니다. - **기본 서빙 기능**: REST 및 gRPC API, 로깅, 메트릭 수집, 모델 버전 관리 등 모델 서빙에 필요한 기본적인 기능들을 제공합니다. - **간단한 사용법**: 상대적으로 가볍고 설정이 간단하여 PyTorch 모델을 빠르게 서빙하고자 할 때 좋은 선택지입니다. **Triton vs TorchServe:** - **범용성**: Triton은 거의 모든 프레임워크를 지원하는 반면, TorchServe는 PyTorch에 집중합니다. - **성능/기능**: Triton이 동적 배치, 모델 앙상블 등 더 진보되고 고성능을 위한 다양한 기능을 제공합니다. - **사용 편의성**: TorchServe가 더 가볍고 빠르게 시작할 수 있습니다. 따라서, 다양한 종류의 모델을 복잡한 서빙 로직과 함께 운영해야 하는 환경이라면 Triton이, 오직 PyTorch 모델만을 빠르고 간단하게 서빙하는 것이 목표라면 TorchServe가 좋은 선택이 될 수 있습니다. --- ## 7. 개념 확인 퀴즈 (Concept Check Quiz) 1. 데이터 병렬 처리(Data Parallelism)와 모델 병렬 처리(Model Parallelism)의 가장 큰 차이점은 무엇인가요? 어떤 상황에서 각각 사용되나요? 2. 모델 경량화 기법 중 양자화(Quantization)의 기본 원리는 무엇이며, PTQ와 QAT 방식의 차이점은 무엇인가요? 3. NVIDIA Triton 추론 서버의 '동적 배치(Dynamic Batching)' 기능이 왜 GPU 활용률을 높이는 데 효과적인가요? --- ## 8. 과제 (Assignment) 1. **분산 학습 전략 선택**: 매우 큰 언어 모델(LLM)을 학습시켜야 하는 상황입니다. PyTorch FSDP와 Microsoft DeepSpeed 중 하나를 선택해야 한다면, 어떤 기준(최소 2가지)으로 기술을 선택할 것이며 그 이유는 무엇인가요? 2. **모델 경량화 전략 수립**: 여러분이 개발한 이미지 분류 모델을 스마트폰 앱에 탑재해야 합니다. 모델의 성능 저하를 최소화하면서 용량과 추론 속도를 개선하기 위한 경량화 전략을 2가지 이상 조합하여 제시해 보세요. (예: 지식 증류 후 양자화 적용) --- ## 9. 되짚어보기 (Summary) 이번 파트에서는 대규모 AI 모델을 현실적인 제약 속에서 효율적으로 다루기 위한 핵심 기술들을 배웠습니다. - **효율적 분산 학습**: 단일 GPU의 한계를 넘어 거대 모델을 학습시키기 위한 데이터 병렬 처리와 모델 병렬 처리의 개념을 이해하고, PyTorch FSDP와 Microsoft DeepSpeed와 같은 최신 분산 학습 프레임워크의 작동 방식과 특징을 비교 분석했습니다. - **모델 경량화 기법**: 학습된 모델을 더 빠르고 가볍게 만들기 위한 양자화(Quantization), 가지치기(Pruning), 지식 증류(Knowledge Distillation)의 원리와 장단점을 파악했습니다. - **고성능 추론 서버**: 대규모 트래픽 환경에서 모델을 안정적으로 서빙하기 위한 NVIDIA Triton과 TorchServe의 필요성을 이해하고, 동적 배치와 같은 핵심 기능들을 학습했습니다. --- ## 10. 더 깊이 알아보기 (Further Reading) - [PyTorch FSDP 공식 튜토리얼](https://pytorch.org/tutorials/intermediate/FSDP_tutorial.html): FSDP를 시작하는 상세한 가이드 - [DeepSpeed 공식 문서](https://www.deepspeed.ai/): ZeRO를 포함한 다양한 최적화 기능 소개 - [NVIDIA Triton Inference Server 문서](https://developer.nvidia.com/triton-inference-server): Triton의 아키텍처 및 사용법 - [The Illustrated Guide to Model Quantization (블로그)](https://arxiv.org/abs/2403.15933): 모델 양자화의 개념을 쉽게 설명한 자료 --- **➡️ 다음 시간: [Part 13: 생성형 AI 및 AI 에이전트 심화](./part_13_generative_ai.md)**