MoE 모델 서빙 가이드
📌 현재 버전: vLLM v0.6.3 / v0.7.x (2025-02 안정 버전), TGI 3.3.5 (유지보수 모드). 본 문서의 배포 예시는 최신 안정 버전 기준입니다.
📅 작성일: 2025-02-09 | 수정일: 2026-02-14 | ⏱️ 읽는 시간: 약 9분
개요
Mixture of Experts(MoE) 모델은 대규모 언어 모델의 효율성을 극대화하는 혁신적인 아키텍처입니다. 이 문서에서는 Amazon EKS 환경에서 Mixtral, DeepSeek-MoE, Qwen-MoE 등의 MoE 모델을 효율적으로 배포하고 운영하는 방법을 다룹니다.
주요 목표
- MoE 아키텍처 이해: Expert 네트워크와 라우팅 메커니즘의 동작 원리
- 효율적인 배포: vLLM 및 TGI를 활용한 최적화된 MoE 모델 서빙
- 리소스 최적화: GPU 메모리 관리 및 분산 배포 전략
- 성능 튜닝: KV Cache, Speculative Decoding 등 고급 최적화 기법
MoE 아키텍처 이해
Expert 네트워크 구조
MoE 모델은 여러 개의 "Expert" 네트워크와 이를 선택하는 "Router(Gate)" 네트워크로 구성됩니다.
라우팅 메커니즘
MoE 모델의 핵심은 입력 토큰에 따라 적절한 Expert를 선택하는 라우팅 메커니즘입니다.
- Gate 계산: 입력 토큰의 hidden state를 Gate 네트워크에 통과
- Expert 선택: Softmax 출력에서 Top-K Expert 선택
- 병렬 처리: 선택된 Expert들이 병렬로 입력 처리
- 가중 합산: Expert 출력을 Gate 가중치로 결합
MoE vs Dense 모델 비교
- 연산 효율성: 전체 파라미터의 일부만 활성화하여 추론 속도 향상
- 확장성: Expert 추가로 모델 용량 확장 가능
- 전문화: 각 Expert가 특정 도메인/태스크에 특화
MoE 모델 서빙 고려사항
GPU 메모리 요구사항
MoE 모델은 활성화되는 파라미터는 적지만, 전체 Expert를 메모리에 로드해야 합니다.
| Model | Total Parameters | Active Parameters | FP16 Memory | INT8 Memory | Recommended GPU |
|---|---|---|---|---|---|
| Mixtral 8x7B | 46.7B | 12.9B | ~94GB | ~47GB | 2x A100 80GB |
| Mixtral 8x22B | 141B | 39B | ~282GB | ~141GB | 4x H100 80GB |
| DeepSeek-V3 | 671B | 37B | ~800GB* | ~400GB* | 8x H100 80GB |
| DeepSeek-MoE 16B | 16.4B | 2.8B | ~33GB | ~17GB | 1x A100 40GB |
| Qwen2.5-MoE-A14B | ~50B | 14B | ~100GB | ~50GB | 2x A100 80GB |
| Qwen1.5-MoE-A2.7B | 14.3B | 2.7B | ~29GB | ~15GB | 1x A100 40GB |
| DBRX | 132B | 36B | ~264GB | ~132GB | 4x H100 80GB |
DeepSeek-V3는 Multi-head Latent Attention (MLA) 아키텍처를 사용하여 KV 캐시 메모리를 크게 절감합니다. 전통적인 MHA(Multi-Head Attention) 대비 약 40% 메모리 절감 효과가 있어, 실제 메모리 요구량은 표기된 값보다 낮을 수 있습니다. 정확한 메모리 요구량은 배치 크기와 시퀀스 길이에 따라 달라지므로 프로파일링을 권장합니다.
- KV Cache: 배치 크기와 시퀀스 길이에 따라 추가 메모리 필요
- Activation Memory: 추론 중 중간 활성화 값 저장 공간
- CUDA Context: GPU당 약 1-2GB의 CUDA 오버헤드
- Safety Margin: 실제 운영 시 10-20% 여유 공간 확보 권장
분산 배 포 전략
대규모 MoE 모델은 단일 GPU에 로드할 수 없어 분산 배포가 필수입니다.
Expert 활성화 패턴
MoE 모델의 성능 최적화를 위해 Expert 활성화 패턴을 이해해야 합니다.
- Auxiliary Loss: 학습 시 Expert 간 균등 분배를 유도하는 보조 손실
- Capacity Factor: Expert당 처리 가능한 최대 토큰 수 제한
- Token Dropping: 용량 초과 시 토큰 드롭 (추론 시 비활성화 권장)
vLLM 기반 MoE 배포
vLLM MoE 지원 기능
vLLM v0.6+ 버전은 MoE 모델에 대해 다음과 같은 최적화를 제공합니다:
- Expert Parallelism: 다중 GPU에 Expert 분산
- Tensor Parallelism: 레이어 내 텐서 분할
- PagedAttention: 효율적인 KV Cache 관리
- Continuous Batching: 동적 배치 처리
- FP8 KV Cache: 2배 메모리 절감 (v0.6+)
- Improved Prefix Caching: 400%+ 처리량 향상 (v0.6+)
- Multi-LoRA Serving: 단일 기본 모델에서 여러 LoRA 어댑터 동시 서빙 (v0.6+)
- GGUF Quantization: GGUF 형식 양자화 모델 지원 (v0.6+)
Mixtral 8x7B Deployment YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: mixtral-8x7b-vllm
namespace: inference
labels:
app: mixtral-8x7b
serving-engine: vllm
spec:
replicas: 1
selector:
matchLabels:
app: mixtral-8x7b
template:
metadata:
labels:
app: mixtral-8x7b
serving-engine: vllm
spec:
nodeSelector:
node.kubernetes.io/instance-type: p4d.24xlarge
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
containers:
- name: vllm
image: vllm/vllm-openai:v0.6.3
ports:
- name: http
containerPort: 8000
protocol: TCP
env:
- name: HUGGING_FACE_HUB_TOKEN
valueFrom:
secretKeyRef:
name: hf-token
key: token
- name: VLLM_ATTENTION_BACKEND
value: "FLASH_ATTN"
args:
- "--model"
- "mistralai/Mixtral-8x7B-Instruct-v0.1"
- "--tensor-parallel-size"
- "2"
- "--max-model-len"
- "32768"
- "--gpu-memory-utilization"
- "0.90"
- "--enable-chunked-prefill"
- "--max-num-batched-tokens"
- "32768"
- "--enable-prefix-caching"
- "--kv-cache-dtype"
- "fp8"
- "--trust-remote-code"
- "--dtype"
- "bfloat16"
resources:
requests:
nvidia.com/gpu: 2
memory: "180Gi"
cpu: "24"
limits:
nvidia.com/gpu: 2
memory: "200Gi"
cpu: "32"
volumeMounts:
- name: model-cache
mountPath: /root/.cache/huggingface
- name: shm
mountPath: /dev/shm
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 300
periodSeconds: 30
timeoutSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 120
periodSeconds: 10
timeoutSeconds: 5
volumes:
- name: model-cache
persistentVolumeClaim:
claimName: model-cache-pvc
- name: shm
emptyDir:
medium: Memory
sizeLimit: 16Gi
terminationGracePeriodSeconds: 120
Mixtral 8x22B 대규모 배포 (4 GPU)
apiVersion: apps/v1
kind: Deployment
metadata:
name: mixtral-8x22b-vllm
namespace: inference
labels:
app: mixtral-8x22b
serving-engine: vllm
spec:
replicas: 1
selector:
matchLabels:
app: mixtral-8x22b
template:
metadata:
labels:
app: mixtral-8x22b
serving-engine: vllm
spec:
nodeSelector:
node.kubernetes.io/instance-type: p5.48xlarge
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
containers:
- name: vllm
image: vllm/vllm-openai:v0.6.3
ports:
- name: http
containerPort: 8000
env:
- name: HUGGING_FACE_HUB_TOKEN
valueFrom:
secretKeyRef:
name: hf-token
key: token
- name: NCCL_DEBUG
value: "INFO"
- name: NCCL_IB_DISABLE
value: "0"
args:
- "--model"
- "mistralai/Mixtral-8x22B-Instruct-v0.1"
- "--tensor-parallel-size"
- "4"
- "--max-model-len"
- "65536"
- "--gpu-memory-utilization"
- "0.92"
- "--enable-chunked-prefill"
- "--max-num-batched-tokens"
- "65536"
- "--enable-prefix-caching"
- "--kv-cache-dtype"
- "fp8"
- "--dtype"
- "bfloat16"
- "--enforce-eager"
resources:
requests:
nvidia.com/gpu: 4
memory: "400Gi"
cpu: "48"
limits:
nvidia.com/gpu: 4
memory: "500Gi"
cpu: "64"
volumeMounts:
- name: model-cache
mountPath: /root/.cache/huggingface
- name: shm
mountPath: /dev/shm
volumes:
- name: model-cache
persistentVolumeClaim:
claimName: model-cache-pvc
- name: shm
emptyDir:
medium: Memory
sizeLimit: 32Gi
vLLM 텐서 병렬화 설정
텐서 병렬화(Tensor Parallelism)는 모델의 각 레이어를 여러 GPU에 분할합니다.
- NVLink 활용: GPU 간 고속 통신을 위해 NVLink 지원 인스턴스 사용
- TP 크기 선택: 모델 크기와 GPU 메모리에 따라 최소 TP 크기 선택
- 통신 오버헤드: TP 크기가 클수록 All-Reduce 통신 증가
vLLM Expert 병렬화 설정
Expert 병렬화(Expert Parallelism)는 MoE 모델의 Expert를 여러 GPU에 분산합니다.
# Expert Parallelism 활성화 예제
args:
- "--model"
- "mistralai/Mixtral-8x7B-Instruct-v0.1"
- "--tensor-parallel-size"
- "2"
# Expert Parallelism은 vLLM에서 자동으로 최적화됨
# TP 내에서 Expert가 분산 배치됨
- "--distributed-executor-backend"
- "ray" # 또는 "mp" (multiprocessing)
TGI 기반 MoE 배포 (Legacy)
Text Generation Inference(TGI)는 2025년부터 유지보수 모드에 진입했습니다. Hugging Face는 향후 vLLM, SGLang 등 다운스트림 추론 엔진 사용을 권장합니다.
신규 배포에는 vLLM을 사용하세요. 기존 TGI 배포는 계속 동작하지만, 새로운 기능 업데이트나 최적화는 제공되지 않습니다.
TGI에서 vLLM으로 마이그레이션
TGI를 사용 중이라면 다음 단계로 vLLM으로 마이그레이션할 수 있습니다:
- API 호환성: vLLM은 OpenAI 호환 API를 제공하므로 클라이언트 코드 변경 최소화
- 환경 변수 매핑:
- TGI
MODEL_ID→ vLLM--model - TGI
NUM_SHARD→ vLLM--tensor-parallel-size - TGI
MAX_TOTAL_TOKENS→ vLLM--max-model-len
- TGI
- 성능 향상: vLLM의 PagedAttention과 Continuous Batching으로 2-3배 처리량 향상
- 최신 기능: FP8 KV Cache, Prefix Caching, Multi-LoRA 등 최신 최적화 기법 활용
TGI MoE 지원 기능 (Legacy)
Text Generation Inference(TGI)는 Hugging Face에서 개발한 고성능 추론 서버입니다.
- Flash Attention 2: 메모리 효율적인 어텐션 연산
- Paged Attention: 동적 KV Cache 관리
- Tensor Parallelism: 다중 GPU 분산 추론
- Quantization: AWQ, GPTQ, EETQ 지원
TGI Mixtral 8x7B Deployment YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: mixtral-8x7b-tgi
namespace: inference
labels:
app: mixtral-8x7b
serving-engine: tgi
spec:
replicas: 1
selector:
matchLabels:
app: mixtral-8x7b-tgi
template:
metadata:
labels:
app: mixtral-8x7b-tgi
serving-engine: tgi
spec:
nodeSelector:
node.kubernetes.io/instance-type: p4d.24xlarge
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
containers:
- name: tgi
image: ghcr.io/huggingface/text-generation-inference:3.3.5
ports:
- name: http
containerPort: 8080
protocol: TCP
env:
- name: HUGGING_FACE_HUB_TOKEN
valueFrom:
secretKeyRef:
name: hf-token
key: token
- name: MODEL_ID
value: "mistralai/Mixtral-8x7B-Instruct-v0.1"
- name: NUM_SHARD
value: "2"
- name: MAX_INPUT_LENGTH
value: "8192"
- name: MAX_TOTAL_TOKENS
value: "32768"
- name: MAX_BATCH_PREFILL_TOKENS
value: "32768"
- name: DTYPE
value: "bfloat16"
- name: QUANTIZE
value: "" # 또는 "awq", "gptq"
- name: TRUST_REMOTE_CODE
value: "true"
resources:
requests:
nvidia.com/gpu: 2
memory: "180Gi"
cpu: "24"
limits:
nvidia.com/gpu: 2
memory: "200Gi"
cpu: "32"
volumeMounts:
- name: model-cache
mountPath: /data
- name: shm
mountPath: /dev/shm
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 300
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 120
periodSeconds: 10
volumes:
- name: model-cache
persistentVolumeClaim:
claimName: model-cache-pvc
- name: shm
emptyDir:
medium: Memory
sizeLimit: 16Gi
TGI 양자화 배포 (AWQ)
메모리 효율을 위해 AWQ 양자화된 모델을 사용할 수 있습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mixtral-8x7b-tgi-awq
namespace: inference
spec:
replicas: 1
selector:
matchLabels:
app: mixtral-8x7b-tgi-awq
template:
metadata:
labels:
app: mixtral-8x7b-tgi-awq
spec:
nodeSelector:
node.kubernetes.io/instance-type: g5.48xlarge
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
containers:
- name: tgi
image: ghcr.io/huggingface/text-generation-inference:3.3.5
ports:
- name: http
containerPort: 8080
env:
- name: HUGGING_FACE_HUB_TOKEN
valueFrom:
secretKeyRef:
name: hf-token
key: token
- name: MODEL_ID
value: "TheBloke/Mixtral-8x7B-Instruct-v0.1-AWQ"
- name: NUM_SHARD
value: "2"
- name: MAX_INPUT_LENGTH
value: "8192"
- name: MAX_TOTAL_TOKENS
value: "16384"
- name: QUANTIZE
value: "awq"
resources:
requests:
nvidia.com/gpu: 2
memory: "90Gi"
cpu: "16"
limits:
nvidia.com/gpu: 2
memory: "120Gi"
cpu: "24"