漫畫DeepSeekMoE--借助Excel理解它:從原理到代碼實現 精華
在深度學習的廣闊天地里,我們時常追求模型的高效與精準。精兵簡政,這一理念在專家混合架構MoE中得到了淋漓盡致的體現。MoE,即Mixture of Experts,專家混合架構,它的核心思想在于將復雜的任務拆解為多個子任務,每個子任務由專門的“專家”模型負責處理。
這種架構的優勢在于,它可以根據輸入數據的不同特點,動態地選擇最合適的專家進行處理,從而在保證模型性能的同時,降低了計算復雜度和資源消耗。正如古人所言,“多兵不如善用兵”,MoE正是通過優化資源配置,實現了表達力的大幅增強。
在接下來的內容中,我們將深入探討MoE的具體實現原理、應用場景以及未來的發展趨勢,以期在這一領域有更深入的理解和探索。
原來這就是專家混合架構
讓我們繼續借助第2章中的案例,深入了解DeepSeek所帶來的創新之處。
在春秋末年,吳國的杰出將領孫武先生負責訓練和指揮軍隊。軍營中搭建了一座名為“點將臺”的高臺。每天黎明時分,全軍列隊。隨著號角的響起,數萬名士兵整齊劃一地排列,靜候孫將軍挑選將領,帶領他們奔赴戰場。

而這,正是后人口中的“稀疏點將制”——如今我們在人工智能中稱之為MoE。這套制度背后,蘊含著孫武對兵力調度的極致智慧,也正好道出了MoE模型為何強大又高效的原理。
將多兵不如善用兵:表達力大幅增強
孫武的軍營中,將領如云,人才濟濟。營外,是經歷過百戰的精兵強將——左側有擅長夜襲的田將軍,右側有精通水戰的呂都尉,更有深諳兵法、洞察敵情的鐘謀士。每位將領都各自統領著萬人的軍隊,他們都是能夠獨當一面的杰出人才。然而,孫武從不一次性派遣所有將領。他深知:兵力眾多并不總是優勢,戰場上的關鍵在于“用人得當”。因此,每當敵情發生突變,他便登上點將臺,從眾多將軍中挑選出最適合的兩位來應對敵軍。在出戰之日,雖然看起來只有兩支隊伍奔赴前線,但實際上,這是整個將軍團隊智慧的體現。

這正體現了MoE模型的運作原理:盡管整個網絡由眾多“專家”組成,每個專家的參數數量可達到數億,但在進行推理時,通常只激活其中兩個或少數幾個專家。以一個普通的 MLP 層為例,其參數量為100M;而在 MoE 層中,即便有10個專家,每個專家的參數量也是100M,總計參數量達到 1B;然而,在實際操作中,每次僅啟用2個專家,因此實際的計算成本保持在200M,大大提高了用兵的效率。
孫武布兵如 MoE 布網:整軍備戰,局部出擊,智取勝于力拼。
稀而不弱:高效稀疏調度,輕裝上陣
孫武實施“點將制”,這不僅體現了他的智慧,更源于他需要迅速調配兵力、輕裝上陣。他深知兵貴神速,多余的兵力只會拖慢進軍的步伐。每當調動軍隊出征,他僅需向軍令官輕聲下令:“點將謀士、田將軍。”軍令如山,其他人員保持不動,唯獨這兩員大將迅速整頓部隊。
這與在 MoE 模型中引入的稀疏前向傳播極為相似:通過門控機制,僅激活 Top-k 個專家,而其他專家則保持靜默狀態。這樣,每次只需計算一小部分子網絡,從而節省了內存和計算資源;同時避免了重復學習,提升了專家的特化程度。這正是稀疏機制的核心所在:確保專家僅在必要時參與計算。
調兵無上限:專家可擴展,模型更靈活**
隨著敵軍戰術的不斷演變,孫武不再滿足于現有的十位將領。他開始著手擴充軍隊,吸納更多的專家型將軍。然而,這位智者并未安排所有將領同時進行訓練或出征。他深知,在戰斗中每次只需兩位最合適的將軍出戰(參見下圖),即使軍營中擁有百將千帥,其目的也是為了在面對各種不同的戰場時,能夠有更多的選擇和更精確的調度。

這正是 MoE 模型可擴展性的體現:在模型訓練或性能不佳時,可以通過新增專家(子網絡)來擴充“知識容量”;但每次計算仍然保持稀疏,僅激活最相關的 Top-k 專家,不增加實際計算負擔;隨著專家數量的增加,模型能適應更多任務場景,遷移性更強。孫武并非盲目擴軍,而是精準備戰;MoE 亦非盲目堆疊參數,而是理性稀疏計算的藝術。
點將有術:門控網絡如統帥
盡管將軍眾多,但真正能夠洞悉敵情、善于用人者,正是站在點將臺上的孫武本人。

在 MoE 模型中,門控網絡(Gating Network)扮演著至關重要的角色。每當輸入一句話或一個樣本,它便負責判斷當前最適合處理該輸入的專家是哪一位,并激活相應的子網絡。例如:輸入一句詩詞 → 選擇文學類專家;輸入一段代碼 → 激活程序專家;輸入醫學記錄 → 調用醫學專家進行處理。門控網絡所學習的,不僅僅是“誰能完成任務”,更是“誰完成得最為出色”。這與孫武多年征戰后練就的“點將直覺”如出一轍。
MoE(專家混合架構)就像孫武兵法中的用兵之道,是一種兼顧力量與智慧的策略工具:
- 兵多將廣:模型參數多,具備強大的表達能力;
- 點將得當:通過稀疏激活,精準調度專家,降低計算成本;
- 彈性擴軍:可根據任務靈活擴展或裁剪專家,適應性強;
- 門控統帥:由門控機制挑選最合適的專家,高效又精準。
MoE 的關鍵不在于“人多”,而在于“選對人、用對人”,讓模型從“全員出動”進化為“精兵出擊”,大幅提升了效率與智能表現。
從撒豆成兵到撒豆成精:DeepSeek MoE的數學推演
讓我們通過結合Excel表格和DeepSeek MoE的公式,共同探索機器學習領域中一個非常重要的創新——DeepSeek MoE。下圖是從傳統的MoE架構,到Deepseek MoE架構的演變。

在人工智能領域,隨著模型規模的不斷膨脹和復雜性的增加,管理這些“知識專家”變得異常棘手。
若每次任務都激活所有專家,不僅會消耗大量電力,還會導致模型運行緩慢,造成資源的浪費。
幸運的是,一些智慧的科學家們創造了Mixture of Experts(MoE),它宛如一位指揮官,僅挑選出最適宜的少數專家參與每一次的任務。
然而,DeepSeek團隊意識到,傳統的MoE仍有提升空間。因此,他們提出了一個升級版——DeepSeekMoE。這個創新設計融合了兩大核心策略:
- 細粒度專家分割(圖b)
- 共享專家隔離(圖c)
這兩大策略,旨在實現一個共同目標:
使每位專家更加專業,整個系統運行更高效、更節約、更智能。
細粒度專家分割
想象一下,如果你要組建一個救援小組。傳統方法是,每個人都是"全能戰士":又要能開船、又要能攀巖、又要懂醫療……雖然厲害,但一旦出任務,總有人做得不好,因為術業有專攻。更聰明的方法是:把任務細分,組建小而專的隊伍。 比如有人專攻救火,有人專攻山地搜救,有人專攻醫療急救。這樣一來,每個人只專注在自己最擅長的領域,整體效率大大提高!
在 DeepSeekMoE 中,科學家們也采用了類似的辦法。他們做了兩件事:
一是把每個原本的大型FFN模塊,切成_m_個更小的專家;二是為了保持整體運算量不變,每次選擇的小專家數量也同步乘_m_。
舉個具體例子:假設以前有16個大專家,每次從中選擇2個來工作,組合方式只有120種。
現在每個專家被切成4個小專家,一共有64個小專家,每次選擇8個,組合方式一下子飆升到驚人的44億種(準確是4,426,165,368種)。
這種變化帶來了巨大的好處:
- 輸入的信息可以被更細致地分配到最適合的小專家;
- 每位小專家負責更窄、更專精的領域;
- 整個模型變得更聰明、響應更快。
關鍵點提醒:雖然專家變小了,數量變多了,但總的參數量和計算量是一樣的哦,不用擔心模型負擔加重!
共享專家隔離
還有一個問題:在現實任務中,有些基本知識是大家都會用的。比如,不管做什么任務,基本的溝通能力、常識判斷都必不可少。如果讓每個小專家都自己去重新學習這些基礎知識,那就太浪費了。所以 DeepSeekMoE 引入了第二個絕招——共享專家隔離。
具體來說:預留出_Ks_個專家,專門作為“公共知識庫”;所有輸入數據,不管走不走路由器,都必須經過這批共享專家;剩下的動態專家,才由路由器根據需要動態選擇。
這樣設計帶來了雙重好處:
- 公共知識集中處理,每位小專家不用重復存儲常識,大大減少了參數冗余;
- 非共享專家可以專心做細分領域,比如有人專門研究生物學,有人專門研究物理學,各自深耕。
注意:因為共享專家是必選的,所以為了保持整體計算量穩定,動態選擇的小專家數量會相應減少 _Ks_個。
它們的數學公式就如下所表示:

wpsoffice
我們可以把它們投影到我們的圖中:

DeepSeekMOE
接下來嘗試在Excel中實現它們,參見下圖。

接下來再初始化一下路由權重,參見下圖:

其中,_E_1 代表的是共享專家,_E_2~_E_4代表的是路由專家。
我們計算路由的公式是這樣的:

/Users/i/Library/Containers/com.kingsoft.wpsoffice.mac/Data/tmp/wpsoffice.hBKTQpwpsoffice
想象一下,你經營著一個聰明的AI事務所,里面有許多聰明的“專家”——每位專家擅長不同的領域。每天,系統會接收到一些“任務”,每個任務由多個特征組成。你要做的,是判斷哪些專家對哪個任務最感興趣,從而派出最合適的人來處理問題。
我們首先有一組輸入任務,它們由一個包含 6 個 Token(也可以理解為詞或片段)的矩陣組成。每個 Token 擁有 5 個特征。換句話說,你眼前有一個 5 行 × 6 列的表格,每一列代表一個任務點,每一行是它的某個描述維度。
另一方面,AI事務所的專家團體(比如 E1、E2、E3 和 E4)每位都各有專長。他們的專長可以被表達成一個“興趣向量”——也就是他們關注每種特征的程度。
這里用了 Excel 的一個函數來評估專家與任務的匹配度:
=MMULT(P152:T154, V141#)
這行公式的含義是:讓系統把每一位專家的興趣向量,與每個任務的特征做一次點積運算,得出一個“匹配打分表”。它就像是每位專家在看每個任務時會說:“這個任務我多感興趣。”
在數學上,它可以被寫成:
S = E · X
其中:
E 表示專家矩陣,每一行是一位專家對五個特征的偏好;
X 表示輸入矩陣,每一列是一項任務的五個特征;
S 就是輸出結果,也就是專家對每個任務的打分表。
接下來再用SoftMax對它們進行進一步的計算,參見下圖:

Softmax 是深度學習和 AI 模型中非常常用的一個“變魔法”的函數,它的主要作用可以用一句話概括:
把一堆“分數”變成“比例”,讓它們代表“誰說話聲音更大”。
用簡單例子說:
假設你有三個專家對一個任務的打分是:
專家 A:5
專家 B:2
專家 C:1
這只是相對的“分數”,不能直接用作權重(因為它們可能太大、太小、甚至為負數)。
這時候,Softmax 會這樣做:
把所有分數指數化(變正、放大差距)
再除以總和,讓它們變成 0~1 之間的比例
且所有比例加起來剛好等于 1(像概率)
比如,softmax 后結果可能是:
A:0.84
B:0.11
C:0.05
接下來對專家得分進行排序,也就是對我們上面的值按列進行排序,選擇Top 3的專家。下圖呈現了通過排序(SORT(...,,-1))得到的每列專家打分的降序排列結果,這一過程常用于混合專家模型(MoE)中進行Top-K路由選擇。

其中Excle的公式如下:
=SORT(AC151:AC154,,-1)
圖表內容揭示了一個4行×6列的打分矩陣,其中每列代表一個Token,每行代表一個專家。該矩陣列出了每個Token對應所有專家的親和力得分,并且每列得分均按從高到低排序。
為何要進行此類排序?在MoE模型中,我們并非讓所有專家同時“發言”,而是讓每個Token僅選擇得分最高的前K個專家參與處理。這一過程被稱為:
Top-K Routing:每個Token路由至最匹配的K個專家。
此排序矩陣的作用是什么?你使用的是Excel的函數:=SORT(...,,-1),意味著對每列進行降序排列。
排序后的矩陣便于快速判斷哪些專家進入了Top-K。
舉個例子:Token5(第 5 列),原始打分(排序前)可能是:
專家 分數
E1 1.000000000
E2 0.867739153
E3 0.521375896
E4 0.407783590
排序結果是:
1.000000
0.867739
0.521376
0.407784
所以 Top-3 專家就是:E1、E2、E3
這里,我們同時對得分用 Softmax 做歸一化,然后才進行的排序。接下來再對選出來的專家,進行運算:
得到最終的 Gate 權重

wpsoffice
對應的Excel公式:
=IF(AC151:AH154 >= AK153:AP153, AC151:AH154, 0)
下圖是……

這張圖非常清晰地展示了 Mixture of Experts 中的 Top-K 路由過程,并通過 Excel 函數 =IF(...) 實現了“打分保留 / 剔除”的門控邏輯。下面我來解釋這段公式和操作背后的含義。
這段公式的意思是:
“對于每個專家對每個 Token 的打分,如果它進入了 Top-3(即分數 ≥ 該 Token 第 3 高的分數),那么保留原始值;否則設為 0。”
對應的數學表達形式,這是我們之前講過的 “門控函數” 的選擇形式:

wpsoffice
其中:
s:原始親和力得分(專家打分)
g:門控值(控制專家輸出權重)
紅色區域(AK153:AP153):每列 Top-3 分數底線 每個 Token 的第三高分,用于篩選
黃色門控區域,滿足條件的得分保留,否則為 0。
為什么這么做?這個過程實現了 Top-K 路由的門控過濾機制:
它不是直接根據“誰排第幾名”來選專家,而是對每列找出 Top-K 的最小分數,然后保留所有大于等于這個分數的專家,這樣做的好處是便于向下使用 Softmax(因為保留的是原始 score)。下圖是……

這里我們可以看到因為專家1是共享專家,所以所有Token都參與了運算。



其他專家灰色的區域都沒有參加計算,這樣就大大節約了計算資源。
混沌初開,眾神歸位:DeepSeek MoE架構的代碼實現
DeepSeek MoE架構的代碼實現基于上述的邏輯和機制,將復雜的模型運算高效地組織起來。代碼的核心在于如何精準地控制專家的選擇和計算資源的分配。在DeepSeek中,專家們被組織成一個多層的結構,每一層都負責不同的任務,但都遵循著Top-K路由的門控過濾原則。
代碼實現的關鍵步驟包括:首先,定義每個專家的計算函數和參數;其次,通過矩陣運算確定每個Token對應的專家得分;然后,根據Top-K路由機制,篩選出得分高于或等于每列Top-K最小分數的專家;最后,對這些篩選出的專家進行Softmax運算,以確定每個專家在最終決策中的權重。
DeepSeek MoE架構的代碼實現不僅優化了模型的性能,還大大提高了計算效率。通過精準地控制專家的選擇和計算資源的分配,DeepSeek能夠在保證模型精度的同時,顯著降低計算成本和時間。這使得DeepSeek在處理大規模數據和復雜任務時具有顯著的優勢。
下面來看看筆者的實現代碼:
引入需要的庫,示例代碼如下:
import torch
import torch.nn as nn
import torch.nn.functional as F
定義單個前饋專家,實現代碼如下:
class FeedForwardExpert(nn.Module):
def __init__(self, d_model):
super().__init__()
self.net = nn.Sequential(
nn.Linear(d_model, d_model),
nn.ReLU(),
nn.Linear(d_model, d_model),
) # 簡單兩層 MLP,含 ReLU
def forward(self, x):
return self.net(x) # 前向傳播
定義 DeepSeekGroupedMoE 模塊
class DeepSeekGroupedMoE(nn.Module):
def __init__(self, d_model, num_groups, experts_per_group, top_k):
super().__init__()
self.d_model = d_model
self.num_groups = num_groups # 分幾組
self.experts_per_group = experts_per_group # 每組幾個專家
self.total_experts = num_groups * experts_per_group
self.top_k = top_k # 每個 Token 在組內選幾個專家
# 所有專家(按組攤平)
self.experts = nn.ModuleList([
FeedForwardExpert(d_model) for _ in range(self.total_experts)
])
# 一個共享專家(所有 Token 都經過)
self.shared_expert = FeedForwardExpert(d_model)
# 路由器部分
self.group_router = nn.Linear(d_model, num_groups) # 負責選擇組
self.intra_router = nn.ModuleList([
nn.Linear(d_model, experts_per_group) for _ in range(num_groups) # 每組內部的路由器
])前向傳播邏輯
def forward(self, x): # 輸入 x: [B, T, D]
B, T, D = x.shape
x_flat = x.view(-1, D) # [B*T, D] 扁平化為 Token 維度
# 步驟1: 分組路由(決定每個 Token 屬于哪個 group)
group_logits = self.group_router(x_flat) # [B*T, num_groups]
group_idx = group_logits.argmax(dim=-1) # 每個 Token 屬于哪個組 [B*T]
# 步驟2: 在組內選擇 top-K 個專家
output = torch.zeros_like(x_flat) # 初始化輸出 [B*T, D]
for g in range(self.num_groups): # 遍歷每個組
mask = (group_idx == g) # 選擇屬于第 g 組的 Token
if mask.sum() == 0:
continue # 當前組沒有 Token,跳過
x_g = x_flat[mask] # 提取該組 Token,形狀 [N_g, D]
intra_scores = self.intra_router[g](x_g) # 對每個 Token 給組內專家打分 [N_g, experts_per_group]
# 選擇 top-k 個專家
topk_vals, topk_idx = torch.topk(intra_scores, self.top_k, dim=-1)
out_g = torch.zeros_like(x_g) # 初始化當前組輸出
for i in range(self.top_k): # 遍歷每個 top-k 專家
expert_ids = g * self.experts_per_group + topk_idx[:, i] # 計算全局 expert ID
gate = topk_vals[:, i].unsqueeze(-1) # 獲得門控分數 [N_g, 1]
# 對每個 Token 單獨調用對應專家
expert_out = torch.stack([
self.experts[expert_id](x_g[j]) # 每個 Token 分別走自己的專家
for j, expert_id in enumerate(expert_ids)
])
out_g += gate * expert_out # 按照 gate 加權相加
output[mask] = out_g # 將該組 Token 的輸出插回原位置
#步驟 3: 共享專家輸出(所有 Token 都過一遍)
shared_out = self.shared_expert(x_flat) # 所有 Token 共享專家 [B*T, D]
final = output + shared_out # 最終輸出為兩者相加 [B*T, D]
return final.view(B, T, D) # reshape 回原始形狀在上面的代碼清單中,我們對代碼進行了盡量詳細的注釋,相信大家應該可以看得懂。
不過,為了更深入地理解這個模塊,我們還是簡單總結一下它的工作流程:
首先,輸入的序列 x 會被展平成二維的形式 x_flat,這樣可以對每個 Token 進行獨立的處理。然后,這些 Token 會根據一定的規則(例如通過路由網絡)被分配到不同的專家組中。每個專家組會對分配給自己的 Token 進行處理,并輸出一個專家輸出 expert_out。
接著,這些專家輸出會根據 gate(門控機制)進行加權相加,得到加權后的輸出 out_g。這個加權的過程實際上是在選擇性地融合不同專家的知識,讓模型能夠更好地處理輸入序列。
然后,我們將加權后的輸出 out_g 插回到原始序列的對應位置上,得到完整的輸出 output。這個步驟確保了即使某些 Token 被分配到了不同的專家組,它們的輸出仍然能夠按照原始序列的順序進行組合。
此外,為了讓所有 Token 都能夠從專家網絡中獲益,我們還設計了一個共享的專家網絡 self.shared_expert。這個網絡會對所有 Token 進行處理,并輸出一個共享的專家輸出 shared_out。這個輸出會與前面的 output 相加,得到最終的輸出 final。
因此,DeepSeekMoE 模塊實際上是一個結合了條件計算和知識蒸餾思想的混合專家系統。它通過對輸入序列進行細粒度的分組和處理,以及通過門控機制和共享專家網絡進行知識的融合和提煉,從而實現了對復雜任務的高效和準確的建模。
本文轉載自 ???AI大模型世界????,作者:roclv

















