MiniMind:3塊錢成本 + 2小時!訓練自己的0.02B的大模型。minimind源碼解讀、MOE架構

大家好,我是此林。

目錄

1. 前言

2. minimind模型源碼解讀

1.?MiniMind Config部分

1.1. 基礎參數

1.2. MOE配置

?

2.??MiniMind Model 部分?

2.1. MiniMindForCausalLM:?用于語言建模任務

2.2.?主干模型?MiniMindModel

2.3.?MiniMindBlock:?模型的基本構建塊

2.4.?class Attention(nn.Module)

2.5. MOEFeedForward

2.6. FeedForward

2.7. 其他

3. 寫在最后


?

1. 前言

大模型在這個時代可以說無處不在了,但是LLM動輒數百億參數的龐大規模。對于我們個人開發者而言不僅難以訓練,甚至連部署都顯得遙不可及。

那 github 上 20k Star+ 的開源項目 minimind,聲稱僅用3塊錢成本 + 2小時!即可訓練出僅為25.8M的超小語言模型?MiniMind。?

這不是謠言,此林已經幫你們試過了,AutoDL租用的 GPU 上訓練(Pretrain + SFT有監督微調)差不多2個小時半。Pretain 和 SFT 的數據集總共才 2.5G 左右。部分源碼也解讀了一下。

這是 Pretain 之后的:模型復讀機現象有點明顯,只會詞語接龍。

這是 SFT 微調后的:幻覺現象還是有點嚴重的,不過句子很流暢,可以接話了。

當然也用 react 快速搭了一個聊天框架,適配 http stream,看著還不錯。

鏈接文末自取。

2. minimind模型源碼解讀

1.?MiniMind Config部分

1.1. 基礎參數

from transformers import PretrainedConfig

PretrainedConfig 是所有 Transformer 模型配置類的基類,用于:

?? 存儲模型的結構參數(如隱藏層大小、注意力頭數、層數等)

?? 記錄預訓練模型的元信息(如 model_type、tokenizer_class)

?? 支持從預訓練模型自動加載配置

在 Transformers 中,每個模型都有一個對應的 Config 類,比如:

?? ???? ?BertModel — BertConfig

?? ???? ?GPT2Model — GPT2Config

?? ???? ?LlamaModel — LlamaConfig

這些都繼承自 PretrainedConfig,主要是構建模型前先配置參數。

使用場景舉例:查看 bert 隱藏層維度

from transformers import PretrainedConfigconfig = PretrainedConfig.from_pretrained("bert-base-uncased")print(config.hidden_size) # 查看隱藏層維度

那在這里的場景,是自定義配置用于訓練或推理,下面會說到。

這里就是定義了?MiniMindConfig,繼承自?PretrainedConfig。

class MiniMindConfig(PretrainedConfig):model_type = "minimind"def __init__(self,dropout: float = 0.0,bos_token_id: int = 1,# 省略...**kwargs):super().__init__(**kwargs)self.dropout = dropoutself.bos_token_id = bos_token_idself.eos_token_id = eos_token_idself.hidden_act = hidden_actself.hidden_size = hidden_size# 省略...# 和MoE相關的參數,如果use_moe=false,就忽略下邊的self.use_moe = use_moeself.num_experts_per_tok = num_experts_per_tok  # 每個token選擇的專家數量self.n_routed_experts = n_routed_experts  # 總的專家數量self.n_shared_experts = n_shared_experts  # 共享專家self.scoring_func = scoring_func  # 評分函數,默認為'softmax'self.aux_loss_alpha = aux_loss_alpha  # 輔助損失的alpha參數self.seq_aux = seq_aux  # 是否在序列級別上計算輔助損失self.norm_topk_prob = norm_topk_prob  # 是否標準化top-k概率

下面就一行一行來看里面的參數。

dropout: float = 0.0

Dropout 是一種防止過擬合的正則化技術,在每次前向傳播時,隨機丟棄一部分神經元的輸出,防止模型過度依賴某些神經元,從而提高泛化能力。

比如:dropout = 0.1,那么:

?? 模型每層中有 10% 的神經元在訓練時會被“屏蔽”(不參與計算)。

?? 在推理時(即模型使用階段),Dropout 是自動關閉的。

dropout: float = 0.0 就是關閉dropout。

bos_token_id: int = 1, # 開始 token 的 ID(Begin of Sentence)
eos_token_id: int = 2, # 結束 token 的 ID(End of Sentence)

在推理中的作用:

?? bos_token_id:模型知道“從這里開始生成”。

?? eos_token_id:模型在生成過程中,一旦預測出這個 token,就認為輸出完畢,停止生成。

這兩個 token 也經常用于?Hugging Face 的 generate() 方法

model.generate(
????input_ids,
????bos_token_id=1,
????eos_token_id=2,
????max_length=50
)

hidden_act: str = 'silu'

激活函數類型(如 silu、relu、gelu),用SwiGLU激活函數替代了ReLU,這樣做是為了提高性能。

 hidden_size: int = 512

Transformer 每層的隱藏狀態維度?

intermediate_size: int = None

前饋層中間維度,如果為None,即用戶沒設置,后面代碼里會設置成 hidden_size * 8 / 3,這是在FeedForward里做的事情。

num_attention_heads: int = 8, # 每層中注意力頭的數量
num_hidden_layers: int = 8, # Transformer 層的數量
num_key_value_heads: int = 2, # KV heads 的數量(用于多頭注意力鍵值共享/分離)

每個 Transformer 層由多頭注意力層(Multi-Head Attention)和?前饋網絡(FFN)組成。

上面的參數表示:模型有 8 層 Transformer 層,每個 Transformer 層中有 8 個注意力頭,并且使用 2 個專門的頭來處理鍵(Key)和值(Value),相當于在多頭注意力的計算中,鍵和值部分的處理是分開的。

vocab_size: int = 6400

模型詞表大小(tokenizer 中的 token 總數)?,minimind是自己訓練了個tokenizer。? ? ? ??

rms_norm_eps: float = 1e-05, # RMSNorm 的 epsilon 值(防止除以0)rope_theta: int = 1000000.0, # RoPE 中的位置旋轉頻率(控制編碼的尺度)

采用了GPT-3的預標準化方法,也就是在每個Transformer子層的輸入上進行歸一化,而不是在輸出上。具體來說,使用的是RMSNorm歸一化函數。

像GPT-Neo一樣,去掉了絕對位置嵌入,改用了旋轉位置嵌入(RoPE),這樣在處理超出訓練長度的推理時效果更好。?

flash_attn: bool = True

Transformer 架構中,注意力機制?是關鍵的計算部分。傳統的注意力計算涉及較大的矩陣乘法,內存消耗大且計算速度較慢,尤其是在處理長序列時。FlashAttention 是一種基于 GPU 的優化算法,專門為 Transformer 模型中的自注意力計算(Self-Attention)進行加速。

1.2. MOE配置

下面的為MOE 配置:僅當 use_moe=True 時有效

它的結構基于Llama3和Deepseek-V2/3中的MixFFN混合專家模塊。

DeepSeek-V2在前饋網絡(FFN)方面,采用了更細粒度的專家分割和共享的專家隔離技術,以提高Experts的效果。

? ? ? ? ? ? use_moe: bool = False, # 是否啟用 MOE(專家混合)機制

? ? ? ? ? ? num_experts_per_tok: int = 2, # 每個 token 選擇的專家數量(Top-K)

? ? ? ? ? ? n_routed_experts: int = 4, # 可路由的專家總數(不包含共享專家)

? ? ? ? ? ? n_shared_experts: int = 1, # 所有 token 共享的專家數量(共享路徑)

? ? ? ? ? ? scoring_func: str = 'softmax', # 路由函數類型(如 softmax、top-k-gumbel)

? ? ? ? ? ? aux_loss_alpha: float = 0.1, # MOE 的輔助損失系數(平衡 load balance)

? ? ? ? ? ? seq_aux: bool = True, # 是否在序列級別計算輔助損失,而非 token 級別

? ? ? ? ? ? norm_topk_prob: bool = True, # 是否對 Top-K 路由概率歸一化(影響路由輸出

num_experts_per_tok: int = 2

在 MoE 中,我們通常有很多個前饋網絡(專家),比如 n_routed_experts = 8。但我們并不希望每個 token 都經過所有 8 個專家計算,這樣計算成本太高。所以我們使用一個門控網絡(gate)來為每個 token 選擇得分Top-K的專家處理。

這里等于 num_experts_per_tok = 2 就是選擇得分前 2 的專家,輸出結果是這兩個專家的加權和(按照 gate 輸出的概率加權)。

n_routed_experts: int = 4

n_routed_experts 表示有多少個普通專家(非共享專家)可以被 gate 路由(選擇)使用。

共享專家是指在所有層中都可以使用的專家,在token前向路徑自動經過,不用 gate 選。

結合剛才的?num_experts_per_tok = 2

對于每個 token:

  1. gate 只會在這 4 個專家中計算得分(不是在全部 MoE 中的專家)。

  2. 從中選擇得分最高的 2 個來執行前饋計算。

  3. gate 輸出加權這些專家的結果。

 scoring_func: str = 'softmax' # 路由函數類型(如 softmax、top-k-gumbel)

這個就是門控網絡(gate)對專家打分的機制,用了softmax,通常配合負載平衡機制使用,下面這個參數就是。

aux_loss_alpha: float = 0.1

在 MoE 模型中,每個 token 會通過路由選擇若干個專家來處理,這些專家的計算量通常是不均衡的,某些專家可能會頻繁被選中,而其他專家可能很少或幾乎不被選擇。這種不均衡的負載分配會導致一些專家被過度使用,而其他專家則被閑置,進而影響訓練效率和最終模型的泛化能力。

為了解決這個問題,輔助損失會通過在模型訓練中加上一個額外的損失項,強制使各個專家的使用頻率更均衡,從而改善負載平衡。

seq_aux: bool = True, # 是否在序列級別計算輔助損失,而非 token 級別

表示在序列級別計算輔助損失,而不是每個 token 單獨的負載。也就是模型會保證整個輸入序列的專家負載是均衡的,而不單單是某個具體的 token。在 token 級別計算輔助損失會導致較高的計算成本。

norm_topk_prob: bool = True

是否對 Top-K 路由概率歸一化(影響路由輸出),歸一化簡單來說就是讓概率總和為 1。

看到這里,相信你對MoE已經有了一定了解。

所以總的來說,MoE?模型的核心思想是:在每次前向傳播的過程中,通過門控網絡(gate)?只挑選得分Top-N個專家 參與計算,避免了全局計算的高成本。MoE 的最大優勢在于它的 稀疏性

傳統的神經網絡是?Dense(密集)網絡,也叫 全連接網絡。對于每一個輸入樣本,網絡中的每個神經元都會參與計算,也就是每一層都會進行全量計算。每然后進行加權和計算。

?

2.??MiniMind Model 部分?

主要架構分為幾個部分,逐個來介紹。

2.1. MiniMindForCausalLM:?用于語言建模任務

包含:

1. 主干模型?MiniMindModel
2. 輸出層?lm_head(共享詞嵌入權重)
輸出:包含?logits(預測)、past_key_values(KV緩存)和?aux_loss(MOE專用)

?

2.2.?主干模型?MiniMindModel

包含:

1. 詞嵌入(embed_tokens)+?Dropout
2. 位置編碼(RoPE)預計算并注冊為?buffer
3. 堆疊多個?MiniMindBlock?層(用?nn.ModuleList)
輸出:最后的隱藏狀態、present?key?values、輔助損失(如果用了?MOE)

?

2.3.?MiniMindBlock:?模型的基本構建塊

包含:
1. 自注意力層(self_attn)
2. 兩個?RMSNorm?層(輸入?&?Attention?之后)
3. 一個前饋層(MLP?或?MOE)
4. 前向傳播:LayerNorm?→?Attention?→?殘差?→?LayerNorm?→?MLP?或?MOE→?殘差

self.mlp = FeedForward(config) if not config.use_moe else MOEFeedForward(config)

具體看這行代碼,如果use_moe == true,那么使用MOEFeedForward,否則使用FeedForward

?

2.4.?class Attention(nn.Module)

GQA(Grouped Query Attention)+ Rotary Positional Embedding + FlashAttention(可選)+ KV Cache(可選)?。優化過的高效自注意力實現,類似?LLaMA3 / DeepSeek-V2/3 模型結構。

?

2.5. MOEFeedForward

1. __init__():初始化函數,定義層結構(線性層、注意力層、專家列表等)

self.experts = nn.ModuleList([
? ? ? ? FeedForward(config) for _ in range(config.n_routed_experts)
? ? ])

比如這里定義了一組專家 FFN 層,供后續調用。

2.forward():前向傳播邏輯,

  • token 被送入路由器 gate

  • 決定用哪些專家處理這些 token

  • 聚合專家輸出

3.?moe_infer():推理專用的稀疏處理方法(只在 MoE 中),MiniMind 的這個模塊為了高效推理自己實現的一個工具方法,只在 self.training == False 時被調用,它屬于性能優化路徑。

不重復計算專家,將所有 token 排序,根據分配給專家的結果批處理執行,最后用 scatter_add_ 聚合輸出,避免內存浪費。

?

2.6. FeedForward

這個其實是是 MoE 和非 MoE 都能用的通用 FFN 單元,在 MoE 中,FeedForward 被封裝為專家模塊。(可以看下之前 MOEFeedForward 里標紅的部分)

多數情況下是 transformer 塊中的 MLP 部分。

1. __init__():初始化函數

2.forward():前向傳播邏輯。

?

2.7. 其他

1. class RMSNorm(torch.nn.Module)

RMSNorm,和 LayerNorm 類似,歸一化技術。但它 只依賴于特征的均方根(RMS),而不是標準差。這種方法更快、更穩定,尤其適用于大模型。

2.?def precompute_freqs_cis()

用于實現 旋轉位置編碼(RoPE)。RoPE 的目標是將位置信息以旋轉方式注入到 query 和 key 中,替代傳統的絕對位置嵌入。這個之前介紹參數里說過。

3. def?apply_rotary_pos_emb()

應用旋轉位置編碼,每個 token 的向量分成前半和后半部分,將其旋轉(換順序并取反),保留位置信息并增強長期依賴能力。

4. def repeat_kv()

支持GQA,用于 將較少的 Key/Value head 擴展重復以適配更多的 Query heads。例如 Q=8 頭,KV=2 頭,那么每個 KV 會被復制 4 次。

?

3. 寫在最后

GitHub - jingyaogong/minimind: 🚀🚀 「大模型」2小時完全從0訓練26M的小參數GPT!🌏 Train a 26M-parameter GPT from scratch in just 2h!

關注我吧,我是此林,帶你看不一樣的世界!?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/80379.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/80379.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/80379.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

引言:Client Hello 為何是 HTTPS 安全的核心?

當用戶在瀏覽器中輸入 https:// 時,看似簡單的操作背后,隱藏著一場加密通信的“暗戰”。Client Hello 作為 TLS 握手的首個消息,不僅決定了后續通信的加密強度,還可能成為攻擊者的突破口。據統計,超過 35% 的網站因 TL…

Dockerfile 完全指南:從入門到最佳實踐

Dockerfile 完全指南:從入門到最佳實踐 1. Dockerfile 簡介與作用 Dockerfile 是一個文本文件,包含了一系列用于構建 Docker 鏡像的指令。它允許開發者通過簡單的指令定義鏡像的構建過程,實現自動化、可重復的鏡像構建。 主要作用&#xf…

Python httpx庫終極指南

一、發展歷程與技術定位 1.1 歷史演進 起源:httpx 由 Encode 團隊開發,于 2019 年首次發布,目標是提供一個現代化的 HTTP 客戶端,支持同步和異步操作,并兼容 HTTP/1.1 和 HTTP/2。背景: requests 庫雖然功…

app加固

1、什么是加固? 我們之前講的逆向,大多數都是用加密算法去加密一些明文字符串,然后把得到的結果用 Base64、Hex等進行編碼后提交。加固其實也一樣,只不過他通常加密的是 dex文件而已。但是 dex 文件加密以后,安卓系統是沒法直接運行的。所以加固的核心&…

Win全兼容!五五 Excel Word 轉 PDF 工具解決多場景轉換難題

各位辦公小能手們!今天給你們介紹一款超牛的工具——五五Excel Word批量轉PDF工具V5.5版。這玩意兒專注搞批量格式轉換,能把Excel(.xls/.xlsx)和Word(.doc/.docx)文檔唰唰地變成PDF格式。 先說說它的核心功…

springCloud/Alibaba常用中間件之Nacos服務注冊與發現

文章目錄 SpringCloud Alibaba:依賴版本補充六、Nacos:服務注冊與發現1、下載安裝Nacos2、服務注冊1. 導入依賴(這里以服務提供者為例)2. 修改配置文件和主啟動類3. 創建業務類4. 測試 3.服務映射1. 導入依賴2. 修改配置文件和主啟動類3. 創建業務類和RestTemplate配置類用來提…

uniapp中score-view中的文字無法換行問題。

項目場景: 今天遇到一個很惡心的問題,uniapp中的文字突然無法換行了。得..就介樣 原因分析: 提示:經過一fan研究后發現 scroll-view為了能夠橫向滾動設置了white-space: nowrap; 強制不換行 解決起來最先想到的是,父…

【STM32 學習筆記】I2C通信協議

注:通信協議的設計背景 3:00~10:13 I2C 通訊協議(Inter-Integrated Circuit)是由Phiilps公司開發的,由于它引腳少,硬件實現簡單,可擴展性強, 不需要USART、CAN等通訊協議的外部收發設備,現在被廣…

【網絡原理】數據鏈路層

目錄 一. 以太網 二. 以太網數據幀 三. MAC地址 四. MTU 五. ARP協議 六. DNS 一. 以太網 以太網是一種基于有線或無線介質的計算機網絡技術,定義了物理層和數據鏈路層的協議,用于在局域網中傳輸數據幀。 二. 以太網數據幀 1)目標地址 …

控制臺打印帶格式內容

1. 場景 很多軟件會在控制臺打印帶顏色和格式的文字,需要使用轉義符實現這個功能。 2. 詳細說明 2.1.轉義符說明 樣式開始:\033[參數1;參數2;參數3m 可以多個參數疊加,若同一類型的參數(如字體顏色)設置了多個&…

[6-2] 定時器定時中斷定時器外部時鐘 江協科技學習筆記(41個知識點)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 V 30 31 32 33 34 35 36 37 38 39 40 41

數據庫的脫敏策略

數據庫的脫敏策略:就是屏蔽敏感的數據 脫敏策略三要求: (1)表對象 (2)生效條件(脫敏列、脫敏函數) (3)二元組 常見的脫敏策略規則: 替換、重排、…

Python序列化的學習筆記

1. Npy&Numpy O4-mini-Cursor:如果.npy文件里包含了「Python對象」而非純數值數組時,就必須在加載時加上allow_pickleTrue。

[思維模式-27]:《本質思考力》-7- 逆向思考的原理與應用

目錄 一、什么是逆向思考 1.1、逆向思考的六大核心思維模式 1.2、逆向思考的四大實踐方法 1. 假設倒置法 2. 缺陷重構法 3. 用戶反推法 4. 規則解構法 1.3、逆向思考的經典案例庫 1. 商業創新:從“賣產品”到“賣服務” 2. 用戶體驗:從“功能滿…

在python中,為什么要引入事件循環這個概念?

在Python中,事件循環(Event Loop)是異步編程的核心機制,它的引入解決了傳統同步編程模型在高并發場景下的效率瓶頸問題。以下從技術演進、性能優化和編程范式三個角度,探討這一概念的必要性及其價值。 一、同步模型的局…

Taccel:一個高性能的GPU加速視觸覺機器人模擬平臺

觸覺感知對于實現人類水平的機器人操作能力至關重要。而視覺觸覺傳感器(VBTS)作為一種有前景的解決方案,通過相機捕捉彈性凝膠墊的形變模式來感知接觸的方式,為視觸覺機器人提供了高空間分辨率和成本效益。然而,這些傳…

oracle 會話管理

會話管理 1:查看當前所有用戶的會話(SESSION): SELECT * FROM V S E S S I O N W H E R E U S E R N A M E I S N O T N U L L O R D E R B Y L O G O N T I M E , S I D ; 其中 O r a c l e 內部進程的 U S E R N A M E 為空 2 :查看當前…

Python開發后端InfluxDB數據庫測試接口

1、使用PyCharm創建一個Python項目wzClear 2、新建package包wzInfluxdb和wzConfig包,如上圖所示,新建一個DB.json配置文件并添加influxdb配置信息,DB.json為統一配置文件 {"influxdbV1": {"url": "http://192.168.0…

采用LLaMa-Factory對QWen大模型實現微調(效果很好)

前言 LLaMA-factory是一個非常有用的開源框架。關于利用llama-factory實現大模型的微調,研究了有一個多月了,終于相對成功的微調了一個QWen的大模型。其中的曲折愿和大家分享! 一、源碼的下載 在github上的網址: GitHub - hiyou…

深入理解深度Q網絡DQN:基于python從零實現

DQN是什么玩意兒? 深度Q網絡(DQN)是深度強化學習領域里一個超厲害的算法。它把Q學習和深度神經網絡巧妙地結合在了一起,專門用來搞定那些狀態空間維度特別高、特別復雜的難題。它展示了用函數近似來學習價值函數的超能力&#xf…