DeepSeek-V3.2는 어떻게 효율적인 AI 스케일링의 해법을 찾았나

How DeepSeek-V3.2 Cracks the Code on Efficient AI Scaling

범용 인공지능(AGI)을 향한 경쟁이 ‘비용’이라는 거대한 방지턱을 만났습니다. 1조 개의 파라미터를 가진 모델을 학습시키려면 보통 국가 GDP 수준의 예산과 소도시 하나를 돌릴 전력이 필요합니다. 바로 이 지점에서 DeepSeek-V3.2가 등장합니다. “전문가 혼합(Mixture of Experts, MoE)” 아키텍처를 정교하게 다듬은 이 모델은 토큰당 전체 파라미터의 일부만 활성화하면서도 GPT-4급 성능을 제공합니다. 모델의 지능과 추론 비용 사이의 전통적인 트레이드오프 관계를 사실상 “속이는(cheats)” 셈입니다.

핵심 개념: 세밀한 MoE + 공유 전문가 (Shared Experts)

DeepSeek-V3.2의 효율성을 이해하려면 이 모델이 “두뇌”를 어떻게 관리하는지 살펴봐야 합니다.

Llama 3와 같은 전통적인 밀집(Dense) 모델은 여러분이 입력하는 모든 단어에 대해 모든 뉴런을 활성화합니다. 마치 “2+2가 뭐죠?”라는 질문에 물리학자, 요리사, 시인을 모두 고용하는 것과 같습니다. 그들은 모두 출근해서 임금을 받고, 불필요한 에너지를 낭비합니다.

DeepSeek-V3.2는 DeepSeekMoE라는 특화된 MoE 아키텍처를 사용합니다:

  1. 거대한 전체 크기, 작은 활성 발자국: 모델의 전체 파라미터는 약 6,710억(671B) 개에 달하지만, 개별 토큰에 대해서는 약 370억(37B) 개만 활성화합니다.
  2. 공유 전문가(Shared Experts): 일반적인 MoE와 달리, DeepSeek는 항상 활성화되는 특정 전문가 그룹을 둡니다. 이 “공유 전문가”들은 모든 작업에 공통적인 일반 지식(문법, 기본 구문 등)을 담당합니다.
  3. 라우팅 전문가(Routed Experts): 나머지 전문가들은 고도로 전문화되어 있습니다. “라우터(Router)”는 입력 토큰을 가장 관련성 높은 전문가(예: “코드 전문가”, “수학 전문가”)에게만 보냅니다.
  4. DeepSeek 희소 어텐션(DSA): V3.2에 새로 도입된 이 메커니즘은 긴 문맥(Context)을 처리할 때 주의를 기울이는 방식을 최적화하여, 방대한 문서 처리에 드는 연산 부하를 획기적으로 줄여줍니다.

라우팅 로직 (The Routing Logic)

DeepSeekMoE 레이어를 통과하는 데이터의 흐름은 다음과 같습니다:

graph TD
    A["입력 토큰 (임베딩)"] --> B["게이팅 메커니즘 (라우터)"]
    
    subgraph "Expert Layer"
        B -- "항상 활성" --> C["공유 전문가 (일반 지식)"]
        B -- "상위 k개 선택" --> D["라우팅 전문가 1 (수학)"]
        B -- "상위 k개 선택" --> E["라우팅 전문가 2 (코딩)"]
        B -. "무시됨" .- F["라우팅 전문가 3 (창작 글쓰기)"]
        B -. "무시됨" .- G["라우팅 전문가 4 (역사)"]
    end
    
    C --> H["출력 합산"]
    D --> H
    E --> H
    H --> I["다음 레이어 / 출력"]

코드 구현

이를 시각화하기 위해 PyTorch로 DeepSeekMoE의 순전파(forward pass)를 시뮬레이션해 보겠습니다. 이 코드는 공유(Shared) 전문가와 라우팅(Routed) 전문가의 분리를 보여줍니다.

import torch
import torch.nn as nn
import torch.nn.functional as F

class DeepSeekMoELayer(nn.Module):
    def __init__(self, hidden_dim, num_experts, num_shared, top_k):
        super().__init__()
        self.top_k = top_k
        
        # 1. 게이트(The Gate): 어떤 라우팅 전문가를 사용할지 결정
        self.router = nn.Linear(hidden_dim, num_experts)
        
        # 2. 공유 전문가(Shared Experts): 항상 활성 (공통 지식 포착)
        self.shared_experts = nn.ModuleList([
            nn.Sequential(nn.Linear(hidden_dim, hidden_dim * 4), nn.ReLU(), nn.Linear(hidden_dim * 4, hidden_dim))
            for _ in range(num_shared)
        ])
        
        # 3. 라우팅 전문가(Routed Experts): 필요할 때만 활성화
        self.routed_experts = nn.ModuleList([
            nn.Sequential(nn.Linear(hidden_dim, hidden_dim * 4), nn.ReLU(), nn.Linear(hidden_dim * 4, hidden_dim))
            for _ in range(num_experts)
        ])

    def forward(self, x):
        # x shape: (batch_size, seq_len, hidden_dim)
        
        # 단계 A: 라우터 로짓(Logits) 계산 및 Top-K 전문가 선택
        router_logits = self.router(x) # (B, S, num_experts)
        routing_weights = F.softmax(router_logits, dim=-1)
        top_k_weights, top_k_indices = torch.topk(routing_weights, self.top_k, dim=-1)
        
        final_output = torch.zeros_like(x)

        # 단계 B: 공유 전문가 처리 (항상 활성)
        for expert in self.shared_experts:
            final_output += expert(x)
            
        # 단계 C: 선택된 라우팅 전문가 처리
        # (가독성을 위한 단순화된 루프; 실제 구현은 최적화된 scatter/gather 커널을 사용함)
        batch_size, seq_len, _ = x.shape
        flat_x = x.view(-1, x.shape[-1])
        flat_indices = top_k_indices.view(-1, self.top_k)
        flat_weights = top_k_weights.view(-1, self.top_k)
        
        # 선택된 전문가의 가중 합산 출력 누적
        # 참고: 실제 프로덕션 환경에서는 GPU 간 병렬 처리됨
        for k in range(self.top_k):
            expert_idx_map = flat_indices[:, k]
            weight_map = flat_weights[:, k].unsqueeze(1)
            
            # 로직: 각 토큰에 대해 특정 전문가를 실행하고 가중치가 적용된 결과를 더함
            # 바로 이 부분에서 희소(sparse) 효율성이 발생함
            pass 

        return final_output

단계별 분석: V3.2가 효율성을 달성하는 방법

  1. ‘보조 손실 없는(Auxiliary-Loss-Free)’ 밸런싱 이해하기
    일반적인 MoE 모델은 라우터가 게을러져 모든 데이터를 단 하나의 전문가에게만 보내버리는 “라우팅 붕괴(routing collapse)”를 겪곤 합니다. 이를 해결하기 위해 연구자들은 보통 학습 중에 페널티(보조 손실)를 추가합니다.
    DeepSeek의 해결책: 그들은 이 보조 손실을 완전히 제거했습니다. 대신 라우터에 동적 편향(bias) 항을 사용합니다. 특정 전문가에게 부하가 걸리면 시스템이 인위적으로 해당 전문가의 “선호도 점수”를 살짝 낮춰 덜 사용된 전문가에게 라우팅을 유도합니다. 이는 모델의 학습 목표를 “혼란스럽게” 하지 않으면서 부하를 균형 있게 분산시킵니다.
  2. 멀티 헤드 잠재 어텐션(MLA) 활용
    V3.2는 KV 캐시(Key-Value Cache)를 압축하기 위해 MLA를 계속 사용합니다.

    • 병목: 긴 대화(예: 128k 컨텍스트)에서 이전 토큰의 기억(KV 캐시)을 저장하는 것은 막대한 GPU VRAM을 소모합니다.
    • 해결: MLA는 KV 헤드를 저랭크(low-rank) 잠재 벡터로 압축합니다.
    • 결과: Llama 3나 GPT-4에 비해 동일한 하드웨어에서 훨씬 큰 배치 사이즈나 더 긴 컨텍스트를 구동할 수 있습니다.
  3. DeepSeek 희소 어텐션(DSA) 도입
    V3.2 버전에만 있는 DSA는 모델이 긴 문서를 “읽는” 방식을 수정합니다. 이전의 모든 단어를 동일한 강도로 주목하는(dense attention) 대신, 관련 있는 텍스트 블록에만 집중하는 희소 패턴을 사용합니다. 이는 계산 비용 폭발 없이 긴 사고 과정을 거쳐야 하는 “Thinking Mode”에서 매우 중요합니다.
  4. FP8 학습 적용
    DeepSeek-V3.2는 태생적으로 FP8(8비트 부동소수점) 정밀도로 학습되었습니다. 이는 경쟁사들이 주로 사용하는 표준 BF16(16비트) 대비 메모리 사용량을 절반으로 줄이며, NVIDIA H100/H800 GPU에서 행렬 연산 속도를 높여줍니다.

리소스

DeepSeek-V3.2는 단순한 크기가 전부가 아니라, 아키텍처가 핵심임을 증명했습니다. 모델을 “공유” 제너럴리스트와 “라우팅” 스페셜리스트로 나누고, 여기에 새로운 DeepSeek 희소 어텐션을 결합함으로써, 개발자들은 671B급 성능을 훨씬 작은 모델의 속도와 비용으로 누릴 수 있게 되었습니다. 엔지니어들에게 이는 추론 중심의 작업에서 더 높은 처리량(throughput)과 더 낮은 API 비용을 의미합니다.