본문 바로가기

시험/기본개념

MoE

 

MoE 아키텍처는 크게 두 가지 핵심 요소로 구성됩니다.

  1. 전문가 네트워크 (Expert Networks)
    • 각각 특정 종류의 데이터나 패턴을 처리하도록 훈련된 작은 신경망입니다.
    • 예를 들어, 언어 모델이라면 어떤 전문가는 문법을, 다른 전문가는 특정 지식(과학, 역사 등)을, 또 다른 전문가는 감성 분석을 더 잘하도록 특화될 수 있습니다.
    • 일반적으로 이 전문가들은 모두 동일한 구조를 가집니다 (예: 동일한 크기의 Feed-Forward Network).
  2. 게이팅 네트워크 (Gating Network)
    • 입력 데이터()를 보고, 어떤 전문가에게 이 입력을 보낼지 결정하는 역할을 합니다. '교통정리 경찰'이나 '라우터(Router)'라고 생각하면 쉽습니다.
    • 게이팅 네트워크는 각 전문가에 대한 가중치(Weight) 또는 확률 점수를 출력합니다. 이 점수가 높을수록 해당 전문가가 이 입력을 처리하는 데 더 적합하다는 의미입니다.
    • 일반적으로 Softmax 함수를 사용하여 모든 전문가에 대한 가중치의 합이 1이 되도록 만듭니다.

⚙️ MoE의 작동 방식과 수식

MoE의 최종 출력()은 각 전문가의 출력()을 게이팅 네트워크가 계산한 가중치()로 가중 평균하여 계산됩니다.

이 수식을 자세히 살펴볼게요. 복사해서 사용하기 편하시도록 각 요소를 설명해 드리겠습니다.

  • Y: 모델의 최종 출력 (Final Output)
  • x: 입력 데이터 (Input Data)
  • n: 총 전문가의 수 (Number of Experts)
  • E_i(x): 번째 전문가가 입력 에 대해 계산한 출력값
  • G(x)_i: 게이팅 네트워크가 입력 에 대해 번째 전문가에게 할당한 가중치(점수). 이 가중치들의 합은 1입니다 ().

게이팅 네트워크의 계산: 게이팅 네트워크는 보통 간단한 선형 변환 후 Softmax 함수를 적용하여 가중치를 계산합니다.

  • W_g, b_g: 게이팅 네트워크가 학습하는 가중치 행렬(Weight matrix)과 편향(bias)입니다.

 

 

💡 반드시 알아야 할 내용

MoE의 가장 큰 장점이자 핵심 개념은 바로 **조건부 계산 (Conditional Computation)**과 **희소 활성화 (Sparse Activation)**입니다.

  1. 조건부 계산 (Conditional Computation)
    • 기존의 거대 모델(Dense Model)은 입력이 들어올 때마다 모델의 모든 파라미터를 사용해서 계산을 수행합니다.
    • 반면 MoE는 게이팅 네트워크의 판단에 따라 선택된 일부 전문가의 파라미터만을 사용해 계산합니다.
    • 즉, 입력에 따라 계산 경로가 달라지는 '조건부' 계산을 수행하는 것입니다.
  2. 희소 활성화 (Sparse Activation)
    • 조건부 계산의 결과로, 전체 전문가 중 극소수(보통 1~2개)만 활성화됩니다. 이를 희소 활성화라고 합니다.
    • 예를 들어, 8개의 전문가가 있다면 그중 Top-1 또는 Top-2 전문가만 선택해서 계산을 수행합니다. (이를 Top-k Gating 이라고 합니다.)
    • 장점:
      • 엄청난 파라미터 수: 수많은 전문가를 둘 수 있어 모델의 총 파라미터 수를 크게 늘릴 수 있습니다 (모델의 잠재적 용량 증가).
      • 빠른 추론 속도: 하지만 실제로 계산할 때는 일부 전문가만 사용하므로, 총 파라미터 수에 비해 훨씬 적은 계산량(FLOPs)으로 빠른 추론이 가능합니다.
      • 모델 용량(Capacity)과 계산 비용(Cost)의 분리가 가능해집니다.
더보기

소프트 MoE: '약한' 조건부 계산

소프트 MoE에서 입력에 따라 조건부로 바뀌는 것은 최종 결과를 조합할 때 사용되는 **가중치(Weight)**뿐입니다.

  • 계산 경로: 입력 -> [전문가1 계산, 전문가2 계산, ..., 전문가N 계산] -> 가중합 -> 최종 출력
  • 위 경로에서 보듯이, 모든 전문가를 계산하는 경로 자체는 고정되어 있습니다. 입력 데이터가 무엇이든 상관없이 모든 전문가의 파라미터가 활성화되고 계산에 사용됩니다.
  • 이는 '조건부 계산'의 핵심 이점인 **"필요 없는 계산은 건너뛴다"**를 전혀 살리지 못합니다. 사실상 계산량은 전문가 수만큼 배가되는 복잡한 앙상블 모델과 다를 바 없습니다.

희소 MoE: '진정한' 조건부 계산

희소 MoE는 입력에 따라 계산 경로 자체가 동적으로 변경됩니다.

  • 계산 경로 (예: Top-1): 입력 -> 게이팅 판단 -> [선택된 전문가 K만 계산] -> 최종 출력
  • 입력 데이터에 따라 전문가 1이 선택될 수도, 전문가 5가 선택될 수도 있습니다. 즉, 활성화되는 파라미터와 계산 그래프가 입력에 따라 조건부로 결정됩니다.
  • 이것이 바로 '진정한' 조건부 계산입니다. 모델의 전체 파라미터가 1조 개라고 해도, 실제로는 그중 1% 미만인 100억 개의 파라미터만 사용해서 계산을 끝낼 수 있습니다.

 

헷갈리기 쉬운 내용  MoE vs. 앙상블 (Ensemble)

구분 MoE (Mixture of Experts)
앙상블 (Ensemble)
훈련 방식 게이팅 네트워크와 모든 전문가가 함께(jointly) 훈련됩니다. 게이팅은 전문가를 선택하고, 전문가는 게이팅이 잘 선택하도록 학습합니다.
여러 개의 모델이 독립적으로(independently) 훈련됩니다. 각 모델은 서로의 존재를 모릅니다.
추론 방식 입력에 따라 선택된 소수의 전문가만 계산에 참여합니다. (희소, Sparse)
모든 모델이 각자 예측을 수행한 후, 결과를 투표(Voting)하거나 평균(Averaging)을 냅니다. (고밀도, Dense)
효율성 계산 효율성이 매우 높습니다.
훈련 및 추론에 N배의 비용이 듭니다.

 

 

📊 평균 게이팅 확률 ()이란?

평균 게이팅 확률은 한마디로 **"이번 데이터 묶음(batch)을 처리하는 동안, 게이팅 네트워크가 특정 전문가를 평균적으로 얼마나 신뢰했는가?"**를 나타내는 **'평균 신뢰도 점수'**입니다.

게이팅 네트워크는 각 데이터(토큰)가 들어올 때마다 모든 전문가에 대해 "이 데이터를 처리하기에 이 전문가는 80% 적합하고, 저 전문가는 5% 적합해..." 와 같이 확률(가중치)을 계산합니다.

는 한 묶음의 데이터를 모두 처리하고 나서, 특정 전문가 가 받았던 이 확률 점수들의 평균값입니다.

토큰 (Input) 전문가 1 확률 전문가 2 확률 전문가 3 확률 (가로 합은 1)
토큰 A 0.9 0.05 0.05 1
토큰 B 0.8 0.1 0.1 1
토큰 C 0.1 0.7 0.2 1
토큰 D 0.85 0.05 0.1 1

 

이제 각 전문가의 **평균 게이팅 확률()**을 계산해 보겠습니다. 각 전문가가 받은 확률 점수(세로줄)의 평균을 내면 됩니다.

  • (전문가 1의 평균 신뢰도)
    • = (0.90 + 0.80 + 0.10 + 0.85) / 4
    • = 2.65 / 4 = 0.6625
  • (전문가 2의 평균 신뢰도)
    • = (0.05 + 0.10 + 0.70 + 0.05) / 4
    • = 0.90 / 4 = 0.225
  • (전문가 3의 평균 신뢰도)
    • = (0.05 + 0.10 + 0.20 + 0.10) / 4
    • = 0.45 / 4 = 0.1125

💡 이 값이 왜 중요할까요? (부하 분산과의 관계)

위 예시에서 값은 0.6625로 다른 전문가들에 비해 월등히 높습니다. 이는 게이팅 네트워크가 이번 데이터 묶음을 처리하는 내내 **"왠지 모르겠지만 전문가 1이 정답일 것 같아"**라고 강력하게 편향되어 생각했다는 뜻입니다.

부하 분산 손실()은 바로 이 지점을 파고듭니다.

  • 실제 라우팅된 토큰 비율 (): 위 예시에서 Top-1 라우팅을 했다면, 토큰 A, B, D가 전문가 1에게, 토큰 C는 전문가 2에게 갔을 겁니다. 그럼 , , 이 됩니다.
  • 손실 계산: $L_{aux}$는 이 (실제 행동) (평균 생각) 를 곱합니다.
    • 전문가 1의 경우 로 매우 큰 값이 계산됩니다.
    • 다른 전문가들은 이 값이 매우 작거나 0이 됩니다.
    • 결국 전체 보조 손실 값이 커지게 되어, 게이팅 네트워크는 "아, 내가 전문가 1을 너무 믿고, 실제로 일도 너무 많이 보냈구나. 다음부터는 좀 더 공평하게 생각하고 일을 분배해야겠다" 라고 학습하게 되는 것입니다.

 

 

평균 게이팅 확률이 높으면, 실제 행동값도 높을텐데, 하나만 써도 되지않아? 왜 두개 다 써?

 

## 각 지표의 역할: '실제 행동' vs '내재된 편향'

두 지표를 사람에 비유하면 이해하기 쉽습니다.

  1. f_i (실제 라우팅된 토큰 비율): 명백한 '행동'
    • 이것은 최종 결과물입니다. "그래서 실제로 몇 명의 학생을 A반에 배정했는가?"를 따지는 것과 같습니다.
    • 한계점: 과정상의 '의도'나 '확신'의 정도는 전혀 담지 못합니다. 예를 들어, 게이팅 네트워크가 전문가 A와 B에게 각각 [0.51, 0.49]의 확률을 부여했다고 가정해봅시다. Top-1 라우팅 규칙에 따라 토큰은 무조건 A에게 갑니다. 또 다른 경우에 [0.99, 0.01] 확률을 부여해도 토큰은 A에게 갑니다. f_i의 관점에서는 두 경우 모두 "전문가 A에게 토큰 1개가 갔다"는 동일한 '행동'으로 기록됩니다. 결정이 얼마나 아슬아슬했는지는 전혀 알 수 없죠.
  2. P_i (평균 게이팅 확률): 내재된 '생각' 또는 '편향'
    • 이것은 게이팅 네트워크의 속마음, 즉 '의도'에 가깝습니다. "선생님은 평균적으로 A반을 얼마나 더 선호하는가?"를 측정하는 것과 같습니다.
    • 한계점: 이것은 '생각'일 뿐, 실제 '행동'의 결과를 직접적으로 반영하지는 않습니다. 네트워크가 특정 전문가를 선호하는 경향이 있더라도, 다른 요인에 의해 실제 토큰 배분은 달라질 수 있습니다. 우리가 궁극적으로 해결하려는 문제는 '생각'의 불균형보다는 '실제 연산량'의 불균형이기 때문에 이 지표만으로는 부족합니다.

## 왜 '생각'과 '행동'을 곱해야 하는가? 🧠 X 🏃‍♂️

이 둘을 곱하는 것은 **"나쁜 생각으로 나쁜 행동을 했을 때 가장 큰 페널티를 주기 위함"**입니다.

  • 만약 f_i (행동)만 사용한다면?
    • 모델은 [0.51, 0.49]처럼 확률 차이를 아주 작게 만들어서 특정 전문가에게만 계속 토큰을 보내는 꼼수를 부릴 수 있습니다. f_i 값은 높게 나오지만, 확률 값 자체는 거의 비슷해서 역전파(backpropagation) 시에 게이팅 네트워크가 자신의 결정이 잘못되었다는 신호(gradient)를 효과적으로 받기 어렵습니다. 훈련이 불안정해질 수 있습니다.
  • 만약 P_i (생각)만 사용한다면?
    • 게이팅 네트워크의 편향된 선호도는 줄일 수 있지만, 실제 연산량 분배가 최적으로 이루어진다는 보장은 없습니다. 우리의 최종 목표는 연산 부하를 분산시키는 것이므로, 결과물인 f_i를 무시할 수 없습니다.
  • f_i와 P_i를 모두 곱하면 (생각 x 행동)?
    • 가장 최악의 상황에 가장 큰 페널티를 줄 수 있습니다. 즉, 게이팅 네트워크가 압도적인 확신(P_i가 높음)을 가지고 특정 전문가에게 실제로 대부분의 토큰을 몰아줬을 때(f_i가 높음), 값이 폭발적으로 커지면서 강력한 페널티를 받게 됩니다.
    • 이 방식은 모델이 아슬아슬하게 편향을 유지하는 '꼼수'를 부리는 것을 방지하고, 자신의 '생각(편향)'과 '행동(결과)'을 모두 교정하도록 만들어 훈련을 훨씬 더 안정적이고 효과적으로 만듭니다.

전문가 용량 (Expert Capacity)과 토큰 드롭 (Token Dropping):

 

전문가 용량은 계산 부하를 예측 가능하게 만들기 위한 고정된 제약 조건입니다. 이는 동적으로 늘어나지 않습니다. 라우팅 결과 특정 전문가에게 용량을 초과하는 수의 토큰이 할당되면, 초과된 토큰들은 해당 전문가의 계산에서 제외됩니다. 이 토큰들은 MoE 레이어를 건너뛰고, 잔차 연결(residual connection)을 통해 입력값이 그대로 다음 레이어로 전달됩니다. 이를 '토큰이 드롭되었다'고 표현하며, 이는 계산 자원의 안정성을 확보하는 대신 해당 레이어에서 일부 토큰의 정보 처리를 건너뛰는 트레이드오프 관계에 있습니다.

 

전문가 용량은 어떻게 계산되나?

더보기

결론부터 말씀드리면, 전문가 용량(Expert Capacity)은 '배치 크기'만으로 정해지지 않고, 다른 요소들과의 관계로 계산되는 값입니다. 정해진 공식은 없지만 일반적으로 다음과 같은 방식으로 계산됩니다.

전문가 용량 = (배치 내 총 토큰 수 / 전문가의 수) * 용량 계수(Capacity Factor)

여기서 각 요소는 다음과 같습니다.

  • 배치 내 총 토큰 수: 배치 크기(Batch Size) × 시퀀스 길이(Sequence Length)입니다. 사용자가 말씀하신 '64배치'는 배치 크기가 64라는 의미입니다. 만약 각 데이터의 길이가 1024 토큰이라면, 총 토큰 수는 64 × 1024 = 65,536개가 됩니다.
  • 전문가의 수: 모델 아키텍처에 따라 다릅니다. 예를 들어 Mixtral 모델은 8개의 전문가를 가집니다.
  • 용량 계수 (Capacity Factor): 이것이 핵심입니다. 라우터가 토큰을 완벽하게 균등 분배하지 못할 것을 대비해 추가하는 '여유 공간'입니다. 보통 1.0보다 큰 값(예: 1.25, 2.0)을 사용합니다.

구체적인 계산 예시

사용자께서 질문하신 상황을 가정해서 계산해 보겠습니다.

  • 배치 크기: 64
  • 시퀀스 길이: 1024 토큰 (가정)
  • 전문가의 수: 8개 (가정)
  • 용량 계수: 1.25 (가정)
  1. 배치 내 총 토큰 수: 64 × 1024 = 65,536
  2. 전문가당 평균 토큰 수 (이상적인 분배 시): 65,536 / 8 = 8,192
  3. 최종 전문가 용량 계산: 8,192 (평균) × 1.25 (용량 계수) = 10,240

따라서 이 경우, 각 전문가는 배치당 최대 10,240개의 토큰을 처리할 수 있도록 설정됩니다. 만약 라우팅 결과 특정 전문가에게 10,241개 이상의 토큰이 할당되면, 10,241번째 토큰부터는 '드롭'되는 것입니다.

용량 계수(Capacity Factor)의 의미:

  • 계수가 1.0이라면: 라우터가 단 하나의 토큰이라도 불균등하게 보내는 순간 바로 토큰 드롭이 발생합니다. 매우 비효율적이겠죠.
  • 계수가 너무 높다면 (예: 2.0): 토큰 드롭은 거의 발생하지 않겠지만, 평소에는 사용되지 않는 계산 자원(메모리 등)을 너무 많이 할당해두는 셈이라 낭비가 발생합니다.

결국 전문가 용량은 모델 설계자가 토큰 드롭으로 인한 성능 손실과 계산 자원의 낭비 사이에서 적절한 균형점을 찾아 설정하는 중요한 하이퍼파라미터(hyperparameter)입니다.

 

한번 MoE 용량을 초과하면 계속 초과하는 것 아닌가?

더보기

NO!

 

 

  • 라우팅은 각 MoE 레이어마다 독립적으로 일어납니다. 한 트랜스포머 블록(레이어)의 MoE에서 토큰이 드롭되었다고 해서, 다음 블록의 MoE에서도 반드시 드롭되는 것은 아닙니다. 각 MoE 레이어의 라우터는 **그 레이어에 입력된 토큰의 표현(representation)**을 보고 어떤 전문가에게 보낼지 새롭게 결정합니다. 앞선 레이어를 거치며 토큰의 정보가 계속 바뀌기 때문에 라우팅 결과도 계속 달라질 수 있습니다.
  • 잔차 연결(Residual Connection)은 정보의 보존을 위함입니다. 트랜스포머의 모든 블록은 기본적으로 입력(x) + 변환된 값(F(x)) 구조를 가집니다. 여기서 MoE 레이어는 '변환된 값(F(x))'을 계산하는 부분입니다.
    • 토큰이 드롭된다는 것은 F(x) 계산을 건너뛰어, 이 값이 0이 되는 것과 같습니다.
    • 따라서 최종적으로는 입력(x) + 0, 즉 입력값 x가 그대로 다음 레이어로 전달됩니다.

 

다음 레이어 입력 = 현재 레이어 입력(x) + F(x)

여기서 F(x)는 현재 레이어에서 수행된 변환 작업(Self-Attention, FFN/MoE 등)의 결과입니다.

 

Q. 어떤 블록에서 전문가 용량이 부족해서 처리를 못했으면,

0~63 토큰까지는 x+ f(x) 로 다음 입력이 구성되고

64~127 토큰까지는 x 로 다음 입력이 들어가는거 맞아?

  1. 전문가 용량 내의 토큰 (0~63번):
    • 이 토큰들은 MoE 레이어를 통과하여 정상적으로 처리됩니다.
    • 따라서 MoE 레이어의 출력값인 F(x)가 존재합니다.
    • 다음 레이어로 넘어가는 입력은 **x + F(x)**가 됩니다. 즉, 원래 정보(x)에 MoE가 처리한 새로운 정보(F(x))가 더해집니다.
  2. 용량을 초과하여 드롭된 토큰 (64~127번):
    • 이 토큰들은 MoE 레이어의 계산에서 제외됩니다.
    • 즉, MoE 레이어가 이 토큰들에 대해 아무런 변환 작업을 하지 않았으므로 F(x)가 사실상 0이 됩니다.
    • 따라서 다음 레이어로 넘어가는 입력은 x + 0, 즉 원래 입력값인 **x**가 그대로 전달됩니다.

이처럼 잔차 연결 구조 덕분에 특정 MoE 레이어에서 일부 토큰이 처리되지 못하더라도, 정보의 흐름이 끊기지 않고 원본 정보가 그대로 다음 레이어로 전달될 수 있는 것입니다. 아주 정확하게 핵심을 파악하셨습니다!

 

 

라우팅 붕괴 & Shared Expert 

더보기

MoE 심화 학습: 파인튜uning 전략과 고급 아키텍처

1. MoE 파인튜닝과 라우팅 붕괴 (Routing Collapse)

사전 학습(Pre-training)을 통해 다양한 지식을 습득한 MoE 모델도, 특정 작업(Task)에 맞게 파인튜닝하는 과정에서는 어려움을 겪을 수 있습니다. 가장 대표적인 문제가 바로 '라우팅 붕괴'입니다.

가. 라우팅 붕괴란 무엇인가?

**라우팅 붕괴(Routing Collapse)**란, 적은 양의 파인튜닝 데이터에 모델이 과적합(overfitting)되면서, 라우터(gating network)가 거의 항상 동일한 소수의 전문가(expert)에게만 토큰을 보내는 현상을 말합니다.

  • 사전 학습 단계: 라우터는 다양한 종류의 입력에 대해 여러 전문가를 골고루 활용하는 방법을 배웁니다.
  • 파인튜닝 단계: 제한된 데이터(예: 법률 문서 번역)에만 집중하다 보면, 라우터는 "아, 이 작업은 무조건 3번, 5번 전문가가 최고구나"라고 섣불리 판단하고 다른 전문가들을 거의 사용하지 않게 됩니다.

이로 인해 사전 학습을 통해 다른 전문가들이 습득했던 방대한 지식을 활용하지 못하게 되어, 모델의 전체적인 성능이 저하됩니다.

나. 라우팅 붕괴 완화 전략

라우팅 붕괴를 막는 전략들의 핵심 아이디어는 **"사전 학습으로 얻은 안정적이고 다양한 라우팅 패턴을 최대한 보존하면서, 전문가들의 지식만 조심스럽게 업데이트하자"**는 것입니다.

1) 라우터 고정 (Router Freezing)

  • 방법: 파인튜닝 시 라우터의 가중치(파라미터)를 업데이트되지 않도록 '고정(freeze)'하고, 전문가들의 가중치만 학습시킵니다.
  • 목적: 사전 학습으로 얻은 범용적인 라우팅 능력을 그대로 유지합니다. 라우터는 여전히 다양한 전문가에게 토큰을 보내는 역할을 하고, 선택된 전문가들만 새로운 작업에 맞게 지식을 업데이트합니다.
  • 비유: 유능한 프로젝트 매니저(라우터)는 성공적인 업무 분배 전략을 그대로 유지하고, 각 팀원(전문가)들이 새로운 프로젝트에 맞는 실무 능력을 키우는 것과 같습니다.

2) 라우터에 낮은 학습률 적용 (Lower Learning Rate for Router)

  • 방법: 전문가들의 학습률보다 라우터의 학습률을 훨씬 낮게 설정합니다.
  • 목적: 라우터가 새로운 데이터에 적응하긴 하되, 아주 천천히 조심스럽게 변화하도록 유도합니다. 이를 통해 기존의 라우팅 패턴이 급격하게 무너지는 것을 방지합니다.
  • 비유: 매니저가 새로운 프로젝트를 맡아 팀원들의 역할을 재조정하긴 하지만, 기존의 성공적인 시스템을 한 번에 바꾸는 것이 아니라 점진적으로 개선해나가는 것과 같습니다.

3) 부하 분산 손실 가중치 증가

  • 방법: 전체 손실 함수(Loss Function)에서 부하 분산 손실(Load Balancing Loss)이 차지하는 비중(가중치)을 사전 학습 때보다 더 높게 설정합니다.
  • 목적: 모델에게 "전문가들을 골고루 사용하지 않으면 더 큰 페널티를 주겠다"고 강하게 신호를 보냅니다. 이를 통해 라우터가 소수의 전문가에게만 의존하려는 경향을 억제하고 강제로 다양한 전문가를 활용하도록 만듭니다.

2. 고급 아키텍처: 공유 전문가 (Shared Expert)

최신 MoE 모델들은 단순히 전문가들을 병렬로 나열하는 것을 넘어, 더 효율적인 구조를 도입하고 있습니다. 그 대표적인 예가 '공유 전문가'입니다.

가. 공유 전문가란 무엇인가?

**공유 전문가(Shared Expert)**란, 라우터의 선택을 받지 않고 모든 토큰이 항상 거쳐가는 전문가를 말합니다. 즉, 일부 전문가는 라우팅을 통해 선택적으로 활성화되고(Routed Experts), 일부 전문가는 항상 활성화되는(Shared Expert) 하이브리드 구조입니다.

  • 기존 MoE: Output = Weighted_Sum(Routed_Experts(x))
  • 공유 전문가 MoE: Output = Shared_Expert(x) + Weighted_Sum(Routed_Experts(x)) (잔차 연결 방식)

나. 공유 전문가의 목적

1) 핵심/공통 지식 처리

  • 공유 전문가는 모든 토큰 처리에 보편적으로 필요한 핵심 지식(예: 언어의 기본 문법, 일반 상식, 기본적인 추론 능력)을 학습하도록 유도됩니다.
  • 라우팅되는 전문가들은 이러한 공통 지식을 매번 따로 학습할 필요 없이, 더 세분화되고 전문적인 지식(예: 의료, 법률, 프로그래밍 코드)에 집중할 수 있습니다.

2) 학습 효율성 및 성능 향상

  • 보편적 지식과 전문적 지식의 처리를 분리함으로써, 모델 전체의 학습 효율과 안정성이 높아집니다.
  • 모든 토큰이 최소한의 공통 처리 과정을 거치기 때문에, 라우팅이 잘못되더라도 성능이 급격히 저하되는 것을 막아주는 효과도 있습니다.
  • 비유: 병원에서 모든 환자가 먼저 일반의(공유 전문가)에게 기본적인 진찰을 받고, 그 후에 증상에 따라 심장내과, 신경외과 등 전문의(라우팅되는 전문가)에게 배정되는 시스템과 유사합니다. 일반의는 기본적인 의료 지식을, 전문의는 심층적인 전문 지식을 담당하여 전체 의료 시스템의 효율을 높입니다.

 

 

moe 코드 

더보기
import torch
import torch.nn as nn
import torch.nn.functional as F

# 1. 전문가(Expert) 모델 정의
# 각 전문가는 간단한 2계층 신경망입니다.
class Expert(nn.Module):
    def __init__(self, input_dim, output_dim, hidden_dim=64):
        super(Expert, self).__init__()
        self.net = nn.Sequential(
            nn.Linear(input_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, output_dim)
        )

    def forward(self, x):
        return self.net(x)

# 2. MoE 모델 정의
class MoE(nn.Module):
    def __init__(self, input_dim, output_dim, n_experts, hidden_dim=64):
        super(MoE, self).__init__()
        self.n_experts = n_experts

        # 전문가들을 ModuleList로 담아둡니다.
        self.experts = nn.ModuleList([
            Expert(input_dim, output_dim, hidden_dim) for _ in range(n_experts)
        ])

        # 게이팅 네트워크(라우터)는 입력에 대해 각 전문가의 가중치를 출력합니다.
        # 출력 차원은 전문가의 수(n_experts)가 됩니다.
        self.gating_network = nn.Linear(input_dim, n_experts)

    def forward(self, x):
        # x shape: (batch_size, input_dim)

        # 1. 게이팅 네트워크를 통과시켜 라우팅 가중치(logits)를 얻습니다.
        gating_logits = self.gating_network(x)
        # gating_logits shape: (batch_size, n_experts)

        # 2. Softmax를 적용하여 각 전문가에 대한 선택 확률을 계산합니다.
        gating_weights = F.softmax(gating_logits, dim=1)
        # gating_weights shape: (batch_size, n_experts)

        # 3. 가장 확률이 높은 전문가를 선택합니다 (Top-1 Gating).
        # chosen_weights: 선택된 전문가의 가중치 (예: 0.95)
        # chosen_experts: 선택된 전문가의 인덱스 (예: 2)
        chosen_weights, chosen_experts_indices = torch.topk(gating_weights, 1, dim=1)
        # chosen_weights shape: (batch_size, 1)
        # chosen_experts_indices shape: (batch_size, 1)

        # 4. 최종 출력을 담을 텐서를 0으로 초기화합니다.
        batch_size, output_dim = x.shape[0], self.experts[0].net[-1].out_features
        final_output = torch.zeros(batch_size, output_dim)
        
        # 5. 각 데이터 샘플에 대해 선택된 전문가를 통과시켜 결과를 계산합니다.
        # 반복문을 사용하여 로직을 명확하게 보여줍니다.
        for i in range(batch_size):
            expert_index = chosen_experts_indices[i].item()
            expert = self.experts[expert_index]
            
            # i번째 데이터 샘플을 선택된 전문가에게 전달합니다.
            expert_output = expert(x[i])
            
            # 게이팅 가중치를 곱하여 최종 출력에 더해줍니다.
            final_output[i] = chosen_weights[i] * expert_output

        return final_output

# --- 실행 예제 ---

# 모델 파라미터 설정
input_dimension = 10
output_dimension = 5
num_experts = 4

# 모델 인스턴스 생성
moe_model = MoE(
    input_dim=input_dimension,
    output_dim=output_dimension,
    n_experts=num_experts
)

# 더미 입력 데이터 생성 (배치 크기 = 8)
dummy_input = torch.randn(8, input_dimension)

# 모델 실행
output = moe_model(dummy_input)

# 결과 출력
print("Minimal MoE Model Example")
print(f"Input shape: {dummy_input.shape}")
print(f"Output shape: {output.shape}")
# 예상 Output shape: torch.Size([8, 5])

 

'시험 > 기본개념' 카테고리의 다른 글

XAI , cam, grad cam, lime, shap  (0) 2025.09.01
AI 시스템 설계  (1) 2025.09.01
llm (Bert, RoBERTa, ALBERT,T5,BART)  (0) 2025.08.29
cross-entropy  (0) 2025.08.29
infoNCE loss  (1) 2025.08.29