05. MoE와 expert parallelism — total vs activated, 그리고 all-to-all
이 장의 핵심 질문
- MoE는 "파라미터가 많은데 계산은 적다"고 한다. total과 activated 파라미터의 구분이 왜 중요한가?
- expert parallelism이 만드는 all-to-all 통신은 왜 앞의 축들과 성격이 다른가?
- MoE의 파라미터 수·성능 주장을 읽을 때 무엇을 분리해야 속지 않는가?
앞 장과의 연결 — 04장에서 여러 병렬화 축을 골격 표로 나란히 봤다. MoE는 모델 구조 자체가 병렬화를 요구하는 특수한 경우이고, 그 통신(all-to-all)은 02장에서 "topology에 특히 민감"하다고 예고한 바로 그것이다.
먼저: MoE가 뭔가요?
MoE(Mixture of Experts, 전문가 혼합) 는 하나의 큰 신경망 대신, 여러 개의 전문가(expert) — 각각 독립적인 작은 하위 네트워크 — 를 두고, 각 토큰마다 일부 전문가만 골라(route) 통과시키는 구조다.
일상 비유: 종합병원에 100명의 전문의(expert)가 있지만, 환자(토큰) 한 명은 증상에 맞는 2~3명만 만난다. 병원 전체 인력은 크지만, 환자 한 명이 실제로 소비하는 진료 자원은 작다. 라우터(router) 는 접수처에서 "이 환자는 어느 과로"를 정하는 역할이다.
이 구조의 결과가 다음 절의 핵심 구분이다.
total vs activated — 속지 않기 위한 첫 구분
MoE 모델은 두 개의 "파라미터 수"를 갖는다. 이 둘을 섞으면 성능·비용 주장에 그대로 속는다.
- total parameters(총 파라미터) — 모든 전문가를 합친 모델 전체의 파라미터 수. 메모리(capacity) 를 결정한다. 전문가가 많으면 이 값이 매우 커진다.
- activated parameters(활성 파라미터) — 토큰 하나가 실제로 통과하는 전문가들의 파라미터 수. 토큰당 연산량(compute) 을 결정한다. total보다 훨씬 작다.
📌 핵심 — MoE의 매력은 "total은 크게(표현력↑), activated는 작게(토큰당 연산↓)"이다. 하지만 이 둘은 서로 다른 자원에 대응한다: total은 메모리(HBM·capacity), activated는 연산(FLOPs). "activated가 작으니 싸다"는 연산 관점에서만 맞고, 메모리 관점에선 total 전체를 어딘가에 올려둬야 한다.
왜 이 구분이 capacity 한계(01장)를 다시 불러오는가
전문가 전체(total)를 한 device에 올릴 수 없는 경우가 많다. 그래서 MoE는 구조적으로 전문가를 여러 device에 나눠야 한다 — 이것이 expert parallelism이다. 즉 MoE는 activated가 작아 연산은 가볍지만, total이 커서 capacity 압박이 크고, 그 해소가 특수한 통신을 부른다.
🔬 증거 읽기 — MoE 주장의 분모 분리 — "우리 MoE는 XXXB 모델인데 토큰당 YB만 쓴다"는 주장을 보면 반드시 분리하라: XXXB는 total(메모리 축), YB는 activated(연산 축). 이 둘을 하나의 "B(빌리언)"로 뭉쳐 dense 모델과 비교하면 틀린다. 메모리 비용은 total로, 연산 비용은 activated로 각각 계산해야 하며, 서로 다른 분모다(15장의 비용 주장과 직결).
expert parallelism (EP) — 전문가를 device에 나눈다
골격 표
| 내용 | |
|---|---|
| shard(나눔) | 전문가(expert). 서로 다른 device가 서로 다른 전문가 집합을 보유 |
| replicate(복제) | 라우터·비-전문가 부분(구현 의존), 그리고 non-MoE 레이어의 가중치 |
| collective | all-to-all — 토큰을 담당 전문가가 있는 device로 흩뿌리고(dispatch), 결과를 원래 자리로 다시 모음(combine) |
all-to-all이 뭔가요?
all-to-all은 각 device가 다른 모든 device에게 서로 다른 조각을 보내고, 동시에 다른 모든 device로부터 서로 다른 조각을 받는 통신이다. all-reduce가 "모두 같은 총합을 갖는" 것이라면, all-to-all은 "각자 필요한 곳으로 재분배"에 가깝다. 우편 분류소에서 각 우편물을 목적지별로 갈라 보내는 것과 같다.
MoE에서 all-to-all은 두 번 등장한다: 토큰을 담당 전문가의 device로 보내는 dispatch, 전문가 처리 후 결과를 원래 토큰 위치로 되돌리는 combine.
flowchart TB
subgraph BEFORE["dispatch 전 — 토큰이 여러 device에 흩어져 있음"]
T0["GPU0<br/>토큰들"]
T1["GPU1<br/>토큰들"]
T2["GPU2<br/>토큰들"]
end
ROUTE{{"router: 각 토큰 →<br/>담당 expert 결정"}}
A2A1{{"all-to-all<br/>(dispatch)"}}
subgraph EXPERTS["전문가가 device별로 나뉨"]
E0["GPU0<br/>expert A,B"]
E1["GPU1<br/>expert C,D"]
E2["GPU2<br/>expert E,F"]
end
A2A2{{"all-to-all<br/>(combine)"}}
OUT["원래 토큰 위치로<br/>결과 복귀"]
T0 --> ROUTE
T1 --> ROUTE
T2 --> ROUTE
ROUTE --> A2A1
A2A1 --> E0
A2A1 --> E1
A2A1 --> E2
E0 --> A2A2
E1 --> A2A2
E2 --> A2A2
A2A2 --> OUT
classDef req fill:#fff3c4,stroke:#d4a017,color:#000
classDef comp fill:#cfe2ff,stroke:#2563eb,color:#000
classDef comm fill:#ffe0b2,stroke:#e07b00,color:#000
classDef ctrl fill:#c4f1f4,stroke:#0891b2,color:#000
class T0,T1,T2,OUT req
class E0,E1,E2 comp
class A2A1,A2A2 comm
class ROUTE ctrl
all-to-all은 왜 특히 까다로운가
02장에서 all-to-all이 "topology에 민감하고 경합에 취약"하다고 예고했다. 이유는 셋이다.
- 모두가 모두에게 보낸다 — all-reduce는 링·트리로 잘 최적화되지만, all-to-all은 본질적으로 모든 쌍이 동시에 통신하려 해 패브릭 경합을 크게 유발한다. non-blocking 패브릭(NVSwitch)이 아니면 실효 대역폭이 급락한다.
- 부하 불균형(load imbalance) — 라우터가 토큰을 전문가에 고르게 배분한다는 보장이 없다. 인기 있는 전문가에 토큰이 몰리면(hot expert), 그 device가 병목이 되고 나머지는 논다. 이는 통신량도 들쭉날쭉하게 만든다.
- 노드 경계에 특히 취약 — expert를 노드 밖으로 흩으면 all-to-all이 느린 scale-out 링크를 대량으로 타 성능이 무너지기 쉽다. 그래서 EP 배치는 인터커넥트 topology와 강하게 얽힌다.
⚖️ 절충 — MoE/EP는 total을 키워 표현력을 얻고 activated를 작게 유지해 토큰당 연산을 아끼지만, 그 대가로 capacity 압박(total을 다 올려야 함), all-to-all 통신(topology 민감), 부하 불균형(hot expert) 이라는 새 비용을 만든다. "MoE라서 무조건 효율적"은 거짓이다 — 연산은 절약해도 메모리·통신·불균형 비용이 그 자리를 채운다.
⚠️ 경계 혼동 주의 — MoE의 "효율"은 연산(compute) 축의 효율이다. 이것을 메모리 효율이나 비용 효율 전반으로 확장해 읽으면 틀린다. total 파라미터는 여전히 큰 메모리를 요구하고, all-to-all은 상당한 통신 비용을 요구한다. 세 자원(연산·메모리·통신)을 분리해서 봐야 한다.
배포에 MoE를 얹는다면
만약 배포 D1(04장)의 팀이 dense 모델 대신 MoE 모델로 바꾼다면:
- capacity 계산은 total 파라미터 기준으로 다시 해야 한다(연산이 아니라 메모리가 벽).
- 전문가를 여러 device에 나누는 EP가 필요하고, 그에 따른 all-to-all을 가급적 non-blocking 노드 내 패브릭에 가둬야 한다.
- hot expert로 인한 불균형을 모니터링·완화하는 장치가 필요하다(라우팅 정책과 얽힘 — 09장의 로드밸런싱과 개념이 연결되나 층위가 다름).
⚠️ 경계 혼동 주의 — EP의 all-to-all vs 09장의 라우팅 — MoE 라우터(토큰→전문가)와 서빙 계층의 요청 라우터(요청→복제본, 09장)는 이름이 비슷하지만 완전히 다른 층위다. 전자는 모델 안의 토큰 분배(매 레이어), 후자는 모델 밖의 요청 분배(요청 단위). 층을 섞지 말라.
이 장에서 배운 것
- MoE는 여러 전문가를 두고 토큰마다 일부만 통과시킨다. 그래서 total(메모리 결정) 과 activated(연산 결정) 라는 두 파라미터 수를 갖는다.
- 이 둘은 서로 다른 자원에 대응한다. "activated가 작아 싸다"는 연산 관점에서만 맞고, 메모리는 total 전체를 올려야 하므로 capacity 압박이 크다.
- expert parallelism(EP) 은 전문가를 device에 나누고, 그 대가로 all-to-all(dispatch/combine) 통신을 만든다.
- all-to-all은 topology 민감·경합 취약·부하 불균형(hot expert)·노드 경계 취약이라 앞 축들보다 까다롭다. 가급적 non-blocking 노드 내 패브릭에 가둔다.
- MoE의 "효율"은 연산 축의 효율이다. 메모리·통신·불균형 비용은 별도로 계산해야 한다.
🔎 이 장의 '지지하지 않는 결론' + 'unknown으로 남겨야 할 것'
- 지지하지 않는 결론 — "MoE는 파라미터가 크지만 연산이 작으니 전반적으로 싸다"는 지지되지 않는다. 연산은 절약되나 메모리(total)·통신(all-to-all)·불균형 비용이 생긴다. 총비용은 조건 의존이다.
- unknown으로 남길 것 — 특정 MoE의 실제 부하 불균형 정도, all-to-all 실효 성능, 최적 EP 배치는 라우팅 정책·워크로드·topology에 의존해 일반값을 못박지 않는다. 특정 배포 수치는 그 조건 기록 없이는
unknown.
✍️ 확인 문제
- 어떤 MoE 모델이 "총 600B 파라미터, 토큰당 37B 활성"이라 홍보한다. 이 모델을 배포하려 할 때 메모리(capacity) 계획과 토큰당 연산 계획은 각각 어느 수치를 써야 하는가? 이 둘을 뭉쳐 "37B급 모델처럼 가볍다"고 결론 내리면 무엇이 틀리는가?
- (경계 혼동 유형) all-reduce와 all-to-all의 차이를 "모두 같은 총합" vs "각자 필요한 곳으로 재분배"로 설명하고, 왜 all-to-all이 non-blocking 패브릭 밖(노드 경계)에서 특히 위험한지 말하라.
- 동료가 "MoE 라우터가 토큰을 전문가에 나누는 거니까, 이건 서빙 계층의 요청 라우터(09장)랑 같은 거네?"라고 한다. 두 라우터의 층위 차이를 지적해 바로잡아라.
다음 장에서는 지금까지 계속 "새 비용"으로 등장한 통신을 정면으로 다룬다. 통신-연산 오버랩이 왜 "byte를 없애는 것"이 아니라 "의존성·자원 경합 아래의 조건부 스케줄"인지가 핵심이다.
다음 → 06. Communication-compute overlap — 오버랩은 마법이 아니라 조건부 스케줄이다