DeepSeek-V3 아키텍처 둘러보기 (DeepSeek-V3 Architecture Walkthrough)
Phase 10 · Lesson 14에서는 모든 오픈 모델이 조절하는 여섯 가지 아키텍처 손잡이(architecture knob)에 이름을 붙였습니다. DeepSeek-V3(2024년 12월 공개, 전체 파라미터 671B, 활성 파라미터 37B)는 그 여섯 가지를 모두 돌리고 네 가지를 더 추가합니다. 다중 헤드 잠재 어텐션(Multi-Head Latent Attention; MLA), 보조 손실 없는 부하 분산(auxiliary-loss-free load balancing), 다중 토큰 예측(Multi-Token Prediction; MTP), 듀얼파이프 학습(DualPipe training)입니다. 이 강의에서는 DeepSeek-V3의 아키텍처를 위에서 아래로 한 줄씩 읽고, 공개된 설정(config)에서 모든 파라미터 수를 직접 유도해봅니다. 끝까지 따라오면 671B/37B 비율이 왜 옳은 베팅인지, 그리고 프런티어(frontier) 영역에서 MLA와 전문가 혼합(Mixture of Experts; MoE)이 왜 둘 중 하나만 쓰는 것보다 함께 쓰일 때 더 강한지를 설명할 수 있게 됩니다.
유형: Learn
언어: Python (표준 라이브러리, 파라미터 계산기)
선수 지식: Phase 10 · 14 (오픈 모델 둘러보기), Phase 10 · 17 (NSA), Phase 10 · 18 (MTP), Phase 10 · 19 (DualPipe)
예상 시간: 약 75분
학습 목표
- DeepSeek-V3 설정을 처음부터 끝까지 읽고, 각 필드를 GPT-2의 여섯 가지 손잡이와 DeepSeek 고유의 네 가지 추가 요소로 풀어서 설명할 수 있습니다.
- 전체 파라미터 수(671B), 활성 파라미터 수(37B), 그리고 각각에 기여하는 구성 요소를 직접 유도할 수 있습니다.
- 128k 컨텍스트(context)에서 MLA의 키-값 캐시(KV cache) 용량을 계산하고, 같은 활성 파라미터 규모를 가진 일반적인 그룹 쿼리 어텐션(Grouped Query Attention; GQA) 기반 밀집 모델(dense model)이 부담할 비용과 비교할 수 있습니다.
- DeepSeek 고유의 네 가지 혁신, 즉 MLA, MTP, 보조 손실 없는 라우팅, DualPipe를 말하고, 각각이 아키텍처와 학습 스택의 어느 부분을 겨냥하는지 짚어낼 수 있습니다.
문제
DeepSeek-V3는 라마(Llama) 계열과 의미 있게 다른 형태로 등장한 최초의 프런티어(frontier) 오픈 모델입니다. Llama 3 405B는 한마디로 "여섯 개의 손잡이를 돌린 GPT-2"입니다. DeepSeek-V3는 여섯 개의 손잡이를 모두 돌린 GPT-2에 네 가지를 더 얹은 모델입니다. Llama 3 설정을 읽는 일은 DeepSeek 설정을 읽기 위한 준비운동에 해당하지만, 어텐션 블록(attention block)의 형태, 라우팅 로직(routing logic), 학습 시 목적 함수(training-time objective)와 같은 깊은 구조는 충분히 달라서 별도의 둘러보기가 필요할 정도입니다.
이를 배우는 보상은 큽니다. DeepSeek-V3의 오픈 가중치 공개(open-weights release)는 오픈 모델에서 "프런티어 역량(frontier capability)"이 무엇을 뜻하는지 자체를 바꿔놓았습니다. 이 아키텍처는 2026년의 많은 학습 실행(training run)이 그대로 따라가는 청사진(blueprint)이 되었습니다. 프런티어 LLM의 학습이나 추론(inference)에 닿아 있는 어떤 역할이든, 이 모델을 이해하는 일은 기본 자격에 해당합니다.
개념
다시 보는 불변의 핵심(invariant core)
DeepSeek-V3도 여전히 자기회귀(autoregressive) 모델입니다. 여전히 디코더 블록(decoder block)을 쌓아 올립니다. 각 블록은 여전히 어텐션과 다층 퍼셉트론(MLP), 그리고 두 개의 RMSNorm으로 구성됩니다. MLP에는 여전히 SwiGLU를 사용합니다. 회전 위치 임베딩(Rotary Position Embedding; RoPE)도 그대로 씁니다. 정규화는 사전 정규화(pre-norm) 방식이고, 임베딩은 가중치 묶기(weight tying)를 적용합니다. 여기까지는 어떤 Llama나 Mistral과도 같은 기준선(baseline)입니다.
비틀기: GQA 대신 MLA
Phase 10 · 14에서 GQA가 쿼리 헤드(query head) 그룹이 키(K)와 값(V)을 공유하도록 만들어 KV 캐시를 줄인다는 것을 배웠습니다. 다중 헤드 잠재 어텐션(Multi-Head Latent Attention; MLA)은 한 걸음 더 나아갑니다. K와 V를 공유 저차원 잠재 표현(shared low-rank latent representation), 즉 kv_lora_rank라는 차원으로 압축한 뒤, 필요한 순간에 헤드별로 풀어냅니다(decompress). KV 캐시에는 잠재 벡터만 저장하면 됩니다. 보통 토큰과 레이어마다 512개의 실수만 저장하면 되며, 8 x 128 = 1024개의 실수를 저장할 필요가 없습니다.
128k 컨텍스트에서 DeepSeek-V3의 MLA는 토큰과 레이어마다 공유 잠재 벡터 c^{KV} 하나만 저장합니다. K와 V는 이 잠재 벡터에서 업 프로젝션(up-projection)으로 유도되며, 이 업 프로젝션은 뒤이은 행렬 곱(matmul)에 흡수될 수 있습니다.
kv_cache = num_layers * kv_lora_rank * max_seq_len * bytes_per_element
= 61 * 512 * 131072 * 2
= 7.6 GB
비교를 위해 가상의 GQA 기준선, 예를 들어 Llama 3 70B 형태인 KV 헤드 8개에 헤드 차원 128을 가정하면 다음과 같은 비용을 지불해야 합니다.
kv_cache = 2 * 61 * 8 * 128 * 131072 * 2
= 30.5 GB
MLA는 128k 컨텍스트에서 Llama-3-70B 형태의 GQA 캐시보다 약 4배 작습니다.
물론 절충점(tradeoff)도 있습니다. MLA는 어텐션 계산마다 헤드별로 풀어내는 단계를 한 번 더 추가합니다. 그러나 추가되는 연산량은 절약되는 메모리 대역폭에 비하면 작습니다. 긴 문맥 추론에서는 결과적으로 이득입니다.
라우팅: 보조 손실 없는 부하 분산
MoE 라우터(router)는 각 토큰을 처리할 상위 k개(top-k) 전문가(expert)를 결정합니다. 순진하게 만든 라우터는 몇몇 전문가에게 일을 몰아주고 나머지는 놀게 두는 경향이 있습니다. 표준적인 해법은 부하 불균형(load imbalance)에 패널티를 부여하는 보조 손실 항(auxiliary loss term)을 추가하는 것입니다. 이 방법은 작동하기는 하지만 주된 과제(main task)의 성능을 살짝 떨어뜨립니다.
DeepSeek-V3는 보조 손실이 없는 방식(auxiliary-loss-free scheme)을 도입합니다. 전문가별로 편향 항(bias term)을 라우터 로짓(logit)에 더해두고, 학습 중에 단순한 규칙으로 그 값을 조정합니다. 전문가 e가 과부하 상태라면 bias_e를 낮추고, 반대로 과소 사용 상태라면 올립니다. 추가 손실 항이 없으니 학습이 깔끔하게 유지되면서도 전문가 부하는 균형 잡힌 상태로 머무릅니다.
주 손실에 대한 영향은 측정하기 어려울 정도로 작습니다. MoE 아키텍처 측면의 효과는 구조가 더 깔끔해지고, 조율해야 할 보조 손실 하이퍼파라미터(hyperparameter)가 사라진다는 점입니다.
MTP: 더 촘촘한 학습 신호와 무료 초안 모델
Phase 10 · 18에서 본 것처럼 DeepSeek-V3는 두 칸 앞 토큰을 예측하는 D=1짜리 MTP 모듈을 하나 추가합니다. 추론 시에는 학습된 이 모듈을 추측 디코딩(speculative decoding)의 초안(draft) 모델로 재활용하며 80% 이상의 수락률을 얻습니다. 학습 시에는 각 은닉 상태(hidden state)가 D+1 = 2개의 목표(target)에 대해 감독(supervision)을 받으므로, 더 촘촘한 학습 신호가 흐릅니다.
파라미터 측면에서는 본체 671B 위에 14B가 더해집니다. 오버헤드(overhead)는 2.1%입니다.
학습: DualPipe
Phase 10 · 19에서 본 것처럼 DualPipe는 순방향(forward)과 역방향(backward) 청크(chunk)를 노드 간 전수 통신(all-to-all communication)과 겹쳐 실행하는 양방향 파이프라인(bidirectional pipeline)입니다. DeepSeek-V3가 운용한 H800 GPU 2,048대 규모에서, 1F1B 방식이 파이프라인 버블(pipeline bubble)에 잃었을 약 24만5천 GPU 시간을 되찾아냈습니다.
설정 한 줄씩 읽기
DeepSeek-V3 설정을 단순화하면 다음과 같습니다.
hidden_size: 7168
intermediate_size: 18432 (밀집 MLP 은닉 크기, 처음 몇 개 레이어에서 사용)
moe_intermediate_size: 2048 (전문가 MLP 은닉 크기)
num_hidden_layers: 61
first_k_dense_layers: 3 (처음 3개 레이어는 밀집 MLP 사용)
num_attention_heads: 128
num_key_value_heads: 128 (MLA에서는 형식상 num_heads와 같지만
실제 압축은 kv_lora_rank에서 일어남)
kv_lora_rank: 512 (MLA 잠재 차원)
num_experts: 256 (블록당 MoE 전문가 수)
num_experts_per_tok: 8 (상위 8개 라우팅)
shared_experts: 1 (블록당 항상 켜진 공유 전문가)
max_position_embeddings: 163840
rope_theta: 10000.0
vocab_size: 129280
mtp_module: 1 (깊이 1의 MTP 모듈 1개)
이 설정을 한 줄씩 해석하면 다음과 같습니다.
hidden_size=7168: 임베딩(embedding) 차원입니다.
num_hidden_layers=61: 전체 블록의 깊이입니다.
first_k_dense_layers=3: 처음 3개 블록은 크기 18432짜리 밀집 MLP를 사용하고, 나머지 58개 블록은 MoE를 사용합니다.
num_attention_heads=128: 쿼리 헤드가 128개라는 뜻입니다.
kv_lora_rank=512: K와 V를 이 잠재 차원으로 압축한 뒤 헤드별로 다시 풀어냅니다.
num_experts=256, num_experts_per_tok=8: 각 MoE 블록에는 256개의 전문가가 있고, 토큰마다 그중 상위 8개를 선택하는 라우팅을 합니다.
shared_experts=1: 라우팅 대상 전문가 256개 위에, 항상 켜져 있는 공유 전문가(shared expert) 1개가 모든 토큰에 기여합니다. 모든 토큰이 적어도 안정적인 무언가 하나는 받도록 보장하는 "밀집 바닥(dense floor)"이라고 생각하면 됩니다.
moe_intermediate_size=2048: 각 전문가의 MLP 은닉 크기입니다. 전문가가 256개나 되기 때문에 밀집 MLP보다 작게 설정합니다.
파라미터 회계(parameter accounting)
전체 계산은 code/main.py에 들어 있습니다. 헤드라인은 다음과 같습니다.
- 임베딩:
vocab * hidden = 129280 * 7168 ≈ 0.93B.
- 처음 3개 밀집 블록: MLA 어텐션(블록당 약 144M) + 밀집 MLP(블록당 약 260M) + 정규화. 합계 약 1.2B.
- 58개 MoE 블록: MLA 어텐션(약 144M) + 전문가 256개(각 30M) + 공유 전문가 1개(30M) + 정규화. 모든 전문가를 포함하면 블록당 약 7.95B. 58개 MoE 블록 전체로는 461B.
- MTP 모듈: 14B.
총합은 핵심 아키텍처 약 476B에 MTP 14B를 더한 값입니다. 공개된 671B 숫자는 편향 텐서(bias tensor), 전문가별 구성 요소(expert-specific component), 공유 전문가 스케일링(shared expert scaling) 등 추가적인 구조 파라미터까지 모두 별도로 반영한 결과입니다. 이 계산기가 재현하는 값은 공개값의 3~5% 이내에 들어옵니다. 그 차이는 DeepSeek 보고서 Section 2 부록(appendix)에 정리된 더 세분화된 회계에서 비롯됩니다.
순전파(forward) 한 번당 활성화되는 파라미터는 다음과 같습니다.
- 어텐션: 레이어당 144M × 61 = 8.8B. 모든 레이어가 매번 실행됩니다.
- MLP 활성: 처음 3개의 밀집 레이어는
3 * 260M = 780M, 58개 MoE 레이어는 라우팅된 전문가 8개와 공유 전문가 1개, 라우팅 오버헤드를 함께 실행합니다. 레이어당 활성 MLP는 약 260M입니다. 합계는 3 * 260M + 58 * 260M ≈ 15.9B.
- 임베딩 + 정규화: 1.2B.
- 활성 총합: 핵심부 약 26B + MTP 14B(학습은 되지만 추론에서 항상 실행되지는 않음) ≈ 37B.
671B / 37B 비율
희소성 비율(sparsity ratio)이 약 18배입니다. 활성 파라미터가 전체의 5.5%에 해당한다는 뜻입니다. DeepSeek-V3는 오픈 가중치로 공개된 프런티어 MoE 모델 중 가장 희소한(sparse) 축에 속합니다. Mixtral 8x7B는 13/47, 즉 28%로 훨씬 밀집한 편입니다. Llama 4 Maverick은 17B/400B, 즉 4.25%로 DeepSeek-V3와 비슷합니다. DeepSeek의 베팅은 명확합니다. 프런티어 규모에서는 전문가를 더 많이 두고 활성화 비율(activation ratio)을 더 낮추는 쪽이 활성 FLOP당 더 좋은 품질을 만들어낸다는 것입니다.
DeepSeek-V3의 위치
| 모델 | 전체(Total) | 활성(Active) | 비율(Ratio) | 어텐션(Attention) | 새로운 아이디어(Novel ideas) |
|---|
| Llama 3 70B | 70B | 70B | 100% | GQA 64/8 | — |
| Llama 4 Maverick | 400B | 17B | 4.25% | GQA | — |
| Mixtral 8x22B | 141B | 39B | 27% | GQA | — |
| DeepSeek V3 | 671B | 37B | 5.5% | MLA 512 | MLA + MTP + aux-free + DualPipe |
| Qwen 2.5 72B | 72B | 72B | 100% | GQA 64/8 | YaRN extension |
후속: R1, V4
DeepSeek-R1(2025년)은 V3 백본(backbone) 위에서 진행한 추론 학습(reasoning training) 실행입니다. R1은 같은 아키텍처를 사용합니다. 바뀐 것은 사전 학습(pretraining) 아키텍처가 아니라 후속 학습(post-training) 레시피입니다. 검증 가능한 과제(verifiable task)에 대한 대규모 강화 학습(reinforcement learning; RL)이 그 핵심입니다.
DeepSeek-V4가 공개된다면, MLA + MoE + MTP 구성을 유지한 채 Phase 10 · 17에서 본 NSA의 후속격인 DSA(DeepSeek Sparse Attention)를 추가할 것으로 예상됩니다. 계보는 안정적입니다. 아키텍처 수준의 혁신은 누적되며, 각 버전은 새로운 손잡이를 한 칸씩 더 돌립니다.
사용해보기
code/main.py는 DeepSeek-V3의 형태에 맞춘 파라미터 계산기입니다. 실행해서 나오는 결과를 논문 숫자와 맞춰보고, 가상의 변형(variant)에도 적용해봅니다. 예를 들어 전문가 수 256 대 512, 상위 8 대 상위 16, MLA 랭크 512 대 1024를 비교해볼 수 있습니다.
확인할 항목은 다음과 같습니다.
- 전체 파라미터 수와 공개된 671B의 비교.
- 활성 파라미터 수와 공개된 37B의 비교.
- 128k 컨텍스트에서의 KV 캐시. MLA와 GQA의 차이.
- 파라미터 예산이 실제로 어디에 쓰이는지 보여주는 레이어별 분해(per-layer breakdown).
산출물 만들기
이 강의는 outputs/skill-deepseek-v3-reader.md를 만들어냅니다. DeepSeek 계열 모델(V3, R1 또는 미래의 변형)이 주어지면, 구성 요소별로 아키텍처를 읽어주는 분석을 생성합니다. 설정의 각 필드에 이름을 붙이고, 구성 요소별 파라미터 수를 유도하며, 네 가지 DeepSeek 고유 혁신 중 어떤 것을 사용하는지를 식별하는 역할입니다.
연습문제
-
(쉬움) code/main.py를 실행합니다. 계산기가 추정한 전체 파라미터 값을 공개된 671B와 비교하고, 차이가 어디에서 오는지 짚어봅니다. 논문의 Section 2에 전체 항목별 회계가 정리되어 있습니다.
-
(중간) MLA 랭크를 512 대신 256으로 바꾸도록 설정을 수정합니다. 128k 컨텍스트에서 KV 캐시 크기를 다시 계산합니다. 몇 % 정도 줄어들고, 헤드별 표현력(per-head expressiveness)에는 어떤 비용을 치르게 되나요?
-
(중간) DeepSeek-V3의 (전문가 256, 상위 8) 라우팅을 가상의 (전문가 512, 상위 8) 변형과 비교합니다. 전체 파라미터는 늘어나지만 활성 파라미터는 그대로입니다. 추가된 전문가 용량은 이론적으로 무엇을 얻게 해주고, 추론에서는 어떤 비용을 만들어내나요?
-
(어려움) MLA를 다룬 DeepSeek-V3 기술 보고서(arXiv:2412.19437) Section 2.1을 읽습니다. K와 V의 압축 해제 행렬(decompression matrix)이 추론 효율을 위해 뒤이은 행렬 곱에 "흡수(absorbed)"될 수 있는 이유를 세 문장으로 설명합니다.
-
(어려움) DeepSeek-V3는 대부분의 연산을 FP8로 학습합니다. 671B 가중치를 저장할 때 FP8이 BF16 대비 얼마나 메모리를 절약하는지 계산합니다. 이것이 14.8T 토큰 규모의 학습 예산과 어떻게 맞물리는지 설명합니다.
핵심 용어
| 용어 | 흔한 설명 | 실제 의미 |
|---|
| MLA (다중 헤드 잠재 어텐션) | "Multi-Head Latent Attention" | K와 V를 공유 저차원 잠재 벡터(kv_lora_rank, 보통 512)로 압축하고, 헤드별로 즉석에서 풀어낸다. KV 캐시에는 잠재 벡터만 저장한다. |
kv_lora_rank | "MLA 압축 차원" | K와 V의 공유 잠재 벡터 크기. DeepSeek-V3는 512를 사용한다. |
| 첫 k개의 밀집 레이어(First k dense layers) | "초기 레이어는 밀집으로 유지" | MoE 모델의 처음 몇 레이어는 MoE 라우터를 건너뛰고, 안정성을 위해 밀집 MLP를 실행한다. |
num_experts_per_tok | "Top-k 라우팅" | 토큰마다 몇 개의 라우팅 대상 전문가가 실행되는지. DeepSeek-V3는 8을 사용한다. |
| 공유 전문가(Shared experts) | "항상 켜진 전문가" | 라우팅 결과와 무관하게 모든 토큰을 처리하는 전문가. DeepSeek-V3는 1개를 사용한다. |
| 보조 손실 없는 라우팅(Auxiliary-loss-free routing) | "편향 조정 부하 분산" | 추가 손실 항을 두지 않고, 전문가별 편향을 학습 중 조정해 전문가 부하의 균형을 맞춘다. |
| MTP 모듈 | "추가 예측 헤드" | h^(1)과 E(t+1)에서 t+2를 예측하는 트랜스포머 블록. 더 촘촘한 학습 신호를 주고, 추측 디코딩의 초안 모델로도 무료 활용된다. |
| DualPipe | "양방향 파이프라인" | 순방향/역방향 연산과 노드 간 전수 통신을 겹쳐 실행하는 학습 스케줄. |
| 활성 파라미터 비율(Active parameter ratio) | "희소성(sparsity)" | active_params / total_params. DeepSeek-V3는 5.5%이다. |
| FP8 학습(FP8 training) | "8비트 학습" | 학습 저장과 다수의 연산을 FP8로 수행한다. BF16 대비 메모리를 대략 절반으로 줄이며, 품질 비용은 작다. |
더 읽을거리