最近看到Github上開源了一個小模型的repo,是真正拉低LLM的學習門檻,讓每個人都能從理解每一行代碼, 從零開始親手訓練一個極小的語言模型。開源地址:
GitHub - jingyaogong/minimind: 🚀🚀 「大模型」2小時完全從0訓練26M的小參數GPT!🌏 Train a 26M-parameter GPT from scratch in just 2h!
雖然Github上給出了教程(only text),但還是感覺如果對于純新手來說還是需要一個圖文教程來展示一下。而且對于真小白來說,一些步驟還是需要出詳解來解釋一下的。
文章下面的操作都是在服務器上進行的,使用的IDE是VSCode的套殼Cursor。因為這個模型比較小,如果不介意的話可以部署在個人電腦上進行實驗。
第0步 Clone倉庫
使用命令
git clone https://github.com/jingyaogong/minimind.git
將代碼clone下來,命令行窗口如下:
打開其中的minimind/requirements.txt,如下圖所示
里面是后面要用到的庫。
因為后面要訓練,就不從huggingface上下模型體驗了,直接跳過readme中的“測試已有模型效果”。
第1步 配置環境
對于一個研究牲來說,好的代碼管理習慣至關重要。尤其是環境配置方面,本人就因為在一個環境上一直實驗裝很多東西,導致不兼容等問題。所以建議為一個repo單獨開一個環境去跑,這樣不影響其他代碼。下面配置環境在conda環境下:
# readme中提到了要使用python>=3.10
conda create -n minimind python=3.10# 進入虛擬環境
conda activate minimind# 安裝需要的庫
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
因為是使用清華鏡像下載庫,所以相對來說會很快。安裝后測試一下Torch是否可用cuda,因為可能安裝的Torch的版本與cuda版本不適配。
上面輸出True就代表cuda可用。
第2步 數據下載
readme中給出了數據的下載地址:
魔搭社區
作者也提供了huggingface的下載地址:
https://huggingface.co/datasets/jingyaogong/minimind_dataset/tree/main
下載方式有多種,這里直接命令行下載所有數據集(建議還是modelscope下載,huggingface有時候太慢):
git lfs installgit clone https://www.modelscope.cn/datasets/gongjy/minimind_dataset.git
數據下載下來就是這個樣子:
這樣下載的數據文件夾的名字是minimind_dataset,需要改成dataset
可以直接UI界面上改,也可以使用命令:
mv minimind_dataset dataset
第3步 預訓練
運行命令
python train_pretrain.py
預訓練過程可以學習一下大佬寫的代碼,畢竟只是去訓練不學習一個模型的底層實在有點虧,辜負大佬repo中寫的“拉低LLM的學習門檻,讓每個人都能從理解每一行代碼開始, 從零開始親手訓練一個極小的語言模型”的初衷,下面部分建議配合代碼食用。
預訓練主流程大致可以分為這幾步:
- 參數解析設置:一大段phaser的設置,方便后面選擇
- 模型配置初始化:這里是用一個類LMConfig,來自Model文件夾中LMConfig.py,用于存儲模型的超參數和配置信息。除此之外還包含:創建輸出目錄、設置隨機種子、計算每次迭代的token數量。
- 訓練環境設置:這里設置了根據設備類型來決定是否使用自動混合精度上下文的操作。
nullcontext()
可能是一個不進行任何特殊操作的上下文管理器,而torch.cuda.amp.autocast()
用于在 GPU 上進行自動混合精度計算,可以提高計算效率和減少內存使用。接著嘗試從環境變量中獲取 “RANK” 的值并轉換為整數,如果獲取到的值不是 - 1,說明這可能是一個分布式數據并行(Distributed Data Parallel,簡稱 DDP)運行的場景。這里設置的兩個東西都可以提高訓練效率。 - Wandb配置(如果啟用):初始化 wandb,設置項目名稱為 args.wandb_project 的值,運行名稱為 args.wandb_run_name 的值。
- 模型和數據初始化:初始化模型和tokenizer這里用到了上面定義的init_model函數和Model文件夾中dataset.py中PretrainDataset類。
- 優化器設置:創建梯度縮放器(用于混合精度訓練)。只有當參數 “args.dtype” 的值為 “float16” 或 “bfloat16” 時才啟用這個縮放器,目的是在使用低精度數據類型進行訓練時,幫助穩定梯度更新,防止梯度下溢或上溢。
- 訓練循環:訓練過程使用余弦調度器動態調整學習率;使用梯度縮放器(scaler)進行反向傳播;支持混合精度訓練(通過ctx上下文管理器)
訓練過程就是如下圖所示了:
從這張圖中可以看出,epoch設置為1,batch_size為100,loss和學習率都在降低,訓練時間大概是兩個小時。訓練結束后,會在out文件夾中存在一個名為pretrain_512.pth的模型。
第4步 SFT
SFT(Supervised Fine-Tuning,監督微調)是一種在機器學習和深度學習領域中常用的技術。在監督微調中,通常先使用一個在大規模數據上預訓練好的模型,然后在特定的有標注的小數據集上進行進一步的訓練調整,以適應特定的任務或領域。但是這里的SFT數據可不小,數據文件的大小高達7G,所以微調時間也比較長。
SFT和預訓練代碼差不多,其中最主要的差別是學習率和epoch數。
# 預訓練
learning_rate = 5e-4
accumulation_steps = 8
epochs = 1 # 默認1輪# SFT微調
learning_rate = 5e-5 # 學習率更小
accumulation_steps = 1
epochs = 6 # 默認6輪
上面差異中積累部署變小是因為需要精細調整,避免過擬合,使用較小的批次更有利于學習細節。這就相當于預訓練只是用大刀給木頭雕了一個形,后面SFT則是用小刀精雕細琢出細節。
SFT時間比較長,結束后會多出一個full_sft_512.pth文件,大小為98.56M。
第5步 測試效果
運行命令
python eval_model.py --model_mode 1 # 默認為0:測試pretrain模型效果,設置為1:測試full_sft模型效果
預訓練模型:
👶: 馬克思主義基本原理
🤖?: 是整個社會和文化結構的平衡點,也就是說,哈克思主義主義者在面對危機時被廣泛傳播,而哈克思主義之路并沒有實際化。因此,我們認為,這是一個現實主義的基礎概念,因為哈克思主義主義者的思想和行為將永遠存在。哈克思主義中的一個重要思想是,即德學派思主義者在面對危機時,大力引發斯坦章的積極影響。因此,馬克思主義者在面對危機時也被廣泛傳播,并成為整個社會文化的基礎。
基于以上這段文本內容回答:為什么“哈克思主義”在當時的“威脅”是正確的?
哈克思主義是一種現實主義思想,它在社會和文化結構上具有廣泛的應用,因為它是現代社會和文化背景的重要組成部分。雖然哈克思主義者的看法是不同的,它在哲學和物理學方面都被廣泛傳播。相反,“哈克思主義”在社會文化中扮演著重要的角色,因為它在某些方面扮演著重要的角色。此外,哈克思主義的傳播也存在著一些挑戰,例如如何控制或攻擊人類的利益和創造力等問題。因此,“哈克思主義”在當時的“威脅”是正確的。👶: 人類大腦的主要功能
🤖?: 包括:工作、生活、工作、家庭、社交、社交、人際、工作、人際、家庭、人際、溝通、情感、娛樂、社交、社交、溝通、人際、友、社交、社交、人際關系。在我們的生活中,許多人都對工作、生活、工作和家庭、家庭和工作都產生了緊張、不開忐、忽略的感受。我們與同事、家人、朋友、同事、商務、客戶、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通、溝通👶: 萬有引力原理是
🤖?: 恒星,但它們都是由于恒星的引力而形成的。根據物理學中的第二個宇宙行星,恒星和行星圍繞著恒星旋轉,并相互融合,形成了一個類似于恒星的行星。而行星圍繞恒星的運動,通常有不同的視覺位置,每個星球都在宇宙中形成了一個新的軌道。基于以上這段文本內容回答:
什么是恒星?恒星和行星之間的引力作用是什么?
恒星是指恒星的引力作用,它們圍繞恒星、行星圍繞恒星旋轉,以及它們相互融合的運動。恒星則由恒星的引力作用而形成的,它們在恒星中存在著幾乎所有恒星。恒星和行星圍繞恒星的引力影響了它強大的引力作用。
恒星的主要作用是恒星的質量,它的體積和質量大約是太陽系內最深的,質量也在上升到太陽系最遠的軌道。恒星則是以恒星和行星繞恒星旋轉,它們的演化出大量的能量,其形成和形成了一個獨特的物體,形成了一個恒星。
通過黑洞的運動,恒星的引力作用產生了許多重要的特征,比如恒星的引力、質量和引力。因此,恒星在恒星和星球上存在著許多奇特的物理現象。👶: 世界上最高的山峰是
🤖?: 珠穆朗瑪峰。珠穆朗瑪峰是世界上最高的山峰之一,但它們的高度影響范圍非常廣。珠穆朗瑪峰高度深受人們喜愛,它們是世界上海平面最高峰之一,也是世界上海平面最高峰。珠穆朗瑪峰的高度受到了影響。珠穆朗瑪峰高度達到了8,848米,而珠穆朗瑪峰是世界上最高的山峰。珠穆朗瑪峰的高度可能因其高度、高度和高度的高來受影響而而受到其獨特的威脅。珠穆朗瑪峰的高度以及它的高度。珠穆朗瑪峰是全球最高的峰峰,但也有其獨特的特征。珠穆朗瑪峰的高度可見。珠穆朗瑪峰的高度可能因其高度、高度和高度而聞名。珠穆朗瑪峰的高度,其中有許多高度,包括登山者們登頂珠穆朗瑪峰。珠穆朗瑪峰在珠穆朗瑪峰的高度也會因其高度、高度、高度的高來收益而受到人們的喜愛。珠穆朗瑪峰的高度可能是珠穆朗瑪峰的高度,但是珠穆朗瑪峰的高度可能與珠穆朗瑪峰的高度相差10,848米。👶: 二氧化碳在空氣中
🤖?: 升起并提高了能源效率。這些成本可以幫助能源系統的生產和消費。通過大型數據分析,人們可以更快地適應和減少污染物的排放。此外,許多地區的污染物質和大量物種也在減少了廢棄物的排放。
基于以上這段文本重新潤色,保證意思一致。
二氧化碳是人類最常見的能源來源之一,它不僅能夠釋放大量的二氧化碳,而且還能夠減少能源的成本。通過這些措施,能源系統能夠滿足人們的能源需求,并減少對化石燃料的依賴。此外,通過使用這些方法,人們可以更快地適應和減少污染物的排放。此外,大型數據分析也在減少碳排放。
二氧化碳的生產和消費方式將成為環保的重要組成部分,對環境和人類經濟產生著不可或缺的作用。現代數據分析,個人的生產和消費量將減少,垃圾處理成本將減少。
除此之外,有許多地區的工業生產和消費,但在空氣中升會釋放大量的二氧化碳,這些碳通過引入它們來保持能源的可持續性。這不僅能減少二氧化碳的排放,還能提高人們的能源效率,從而降低環境污染物的排放。👶: 地球上最大的動物有
🤖?: 體重:地球上最大的動物是大熊,每只大熊都擁有1/2米的體重,且它們的體重可達到50倍。在這一尺度下,大熊貓需要適當的蛋白質來源,包括根、莖、樹、葉、斑馬、老虎等。這些生物通常具有卵和繁殖能力,有很強的運動能力。大熊貓需要進行許多任務才能生存,包括它們需要足夠的蛋白質、維生素、礦物質等。然而,這個動物還有很多其他類型的生物,比如大熊貓、獅子、長頸鹿、大熊貓等。在這種情況下,大熊貓并不能成為瀕危物種,因為它們通常被視為瀕危物種。雖然大熊貓只是一種大型貓,但它們的體重可以超過100倍。雖然大熊貓不是大型貓,但大熊貓需要適當的蛋白質來生存。盡管大熊貓也有一些共同點,例如大熊貓的體重超過了500倍。但這個動物還有很多其他類型的生物,如大熊貓、獅子、長頸鹿等。雖然大熊貓非常棲息,但大熊貓的繁殖能力非常好,因為它們通常被視為瀕危物種。因此,盡管大熊貓在環境中扮演了重要的角色,但由于其特殊情況下,大熊貓的體重超過了200倍。👶: 杭州市的美食有
🤖?: 哪些?
杭州市的美食有哪些?首先,杭州市的美食有多種不同的菜品。例如,浙江省的牛肉煲和牛肉煲,這些食材都是以烤制而成的,是人體最好的。另外,杭州的牛肉煲和牛肉煲都是杭州市最受歡迎的菜肴,每年都會放上漿果醬和牛肉煲,成為杭州市最受歡迎的菜肴之一。最后,杭州市的美食也很有名,比如大蒜煲、西蘭花煲和洋蔥等。此外,杭州市的牛肉煲和牛肉煲都是以沙拉、西蘭花、蘑菇等為主要食材。因此,�杭州市最受歡迎的餐廳是杭州市的美食,除了您所喜歡的菜品,您可以選擇自己喜歡的菜品,這是一道簡單而美味的菜品。請按照以下步驟來選用“�杭州市的美食有多種不同:
1. �杭州市最受歡迎的菜肴之一:杭州市是一個非常受歡迎的餐廳,以小米肉煲、西蘭花煲和意大利肉煲,在這里留下精美的味道,是�杭州市最受歡迎的菜肴之一。2. 杭州市的牛肉煲:南州市最著名的價格是京都,在那里,我們會在那里舉行各種菜肴,可以參觀,還可以觀賞到中式的牛肉煲、西蘭花煲和洋蔥等。
SFT模型:
👶: 請介紹一下自己。
🤖?: 我是一個語言模型,我的知識范圍很廣泛,可以被生成并歸納為自然語言處理、機器翻譯、情感分析等相關領域。👶: 你更擅長哪一個學科?
🤖?: 我是人工智能助手,不過我被編程來理解和回答各種問題。👶: 魯迅的《狂人日記》是如何批判封建禮教的?
🤖?: 《狂人日記》是我國的一部小說,主要講述了一個普通農民福貴的一生。該書通過一系列的歷史事件和人物展現了當時社會的種種弊病和道德困境,強調了人性中的矛盾和無常。在《狂人日記》中,他通過自己的智慧和善良,向讀者展示了人性的復雜性和對于社會的負面影響。👶: 我咳嗽已經持續了兩周,需要去醫院檢查嗎?
🤖?: 如果你不知道咳嗽的嚴重程度,并且已經變動了,建議盡快去醫院進行檢查。👶: 詳細的介紹光速的物理概念。
🤖?: 光速是指光在真空中,在真空中,光速在時間的平方之和之計算量的值。👶: 推薦一些杭州的特色美食吧。
🤖?: 如果你喜歡西餐,我推薦你去嘗試一下杭州的各種特色小吃。如果你想嘗試一些口感較為辣的菜肴,我會推薦你嘗試一下麻婆豆腐和宮保雞丁。👶: 請為我講解“大語言模型”這個概念。
🤖?: 一般來說,自然語言模型是一種將自然語言轉換為計算機可處理的形式。這種模型使用大量的語料庫來訓練模型,以處理各種語言任務。例如,我們可以使用語言模型來生成各種類型的文本,如文章、詩歌、段落等。👶: 如何理解ChatGPT?
🤖?: 解釋ChatGPT的關鍵是理解模板和數據結構的位置。ChatGPT是一種數據傳輸方式,它允許使用復雜的算法來訪問數據。而數據結構則允許使用復雜的傳輸函數將數據傳輸到傳輸器上,從而實現數據的傳輸。👶: Introduce the history of the United States, please.
🤖?: 你是一個開放型的AI助手,我能夠生成各種類型的文本。您需要提供一些相關的信息嗎?
可以看出SFT后的結果要優于預訓練。但是,如果要自己手動輸入問一個問題,比如我輸入的是"范式"的英文是什么,這個問題可能超過了minimind模型的知識范圍,就回答不出來。
👶: "范式"的英文是什么
🤖?: 中文的英文是 "reception`。👶: "范式"的英文是什么
🤖?: “范式”的英文是中文。👶: "范式"的英文是什么
🤖?: 通常的英文是指英語中的“Herit”在英語中的使用,而“Illusion”則是指英語中的一種語言,它的目的是將語言融入英語中,包括口語、閱讀、寫作和口語等。👶: "范式"的英文是什么
🤖?: 這個說法是錯誤的,但是它并不對應于英文。英文通常是使用英文表達方式,例如使用英語、中文或其他語言。👶: "范式"的英文是什么
🤖?: 稱為“范式”通常是指在計算機或電子設備上使用的一種語言。范式通常包含一些關鍵詞,例如主語、謂語和賓語。在不同的上下文中,范式可以有不同的含義,例如在計算機科學中,范式可能指的是用于編程語言的語法結構。
測試模型的代碼中比較重要的是:
parser.add_argument('--temperature', default=0.85) # 生成溫度
parser.add_argument('--top_p', default=0.85) # 采樣閾值
parser.add_argument('--history_cnt', default=0) # 歷史對話輪數
parser.add_argument('--model_mode', default=0) # 模型類型
parser.add_argument('--lora_name', default='None') # LoRA適配器
parser.add_argument('--max_seq_len', default=8192) # 最大序列長度
一些生成過程中的參數,通過設置這些參數就可以:
- 支持LoRA適配器加載
- 支持多輪對話歷史
這個時候就已經訓練出一個回答還算靠譜的模型了,就只有接近100MB的大小。但微調并不是只有SFT這一種方法。
第6步 知識蒸餾(Knowledge Distillation, KD)
?知識蒸餾可以進一步優化模型的性能和效率,所謂知識蒸餾,即學生模型面向教師模型學習。 教師模型通常是經過充分訓練的大模型,具有較高的準確性和泛化能力。 學生模型是一個較小的模型,目標是學習教師模型的行為,而不是直接從原始數據中學習。 在SFT學習中,模型的目標是擬合詞Token分類硬標簽(hard labels),即真實的類別標簽(如 0 或 6400)。 在知識蒸餾中,教師模型的softmax概率分布被用作軟標簽(soft labels)。小模型僅學習軟標簽,并使用KL-Loss來優化模型的參數。 通俗地說,SFT直接學習老師給的解題答案。而KD過程相當于“打開”老師聰明的大腦,盡可能地模仿老師“大腦”思考問題的神經元狀態。
?知識蒸餾的目的只有一個:讓小模型體積更小的同時效果更好。 然而隨著LLM誕生和發展,模型蒸餾一詞被廣泛濫用,從而產生了“白盒/黑盒”知識蒸餾兩個派別。 GPT-4這種閉源模型,由于無法獲取其內部結構,因此只能面向它所輸出的數據學習,這個過程稱之為黑盒蒸餾,也是大模型時代最普遍的做法。 黑盒蒸餾與SFT過程完全一致,只不過數據是從大模型的輸出收集,因此只需要準備數據并且進一步FT即可。
蒸餾前我們需要先得到一個教師模型,蒸餾的代碼中有用到維度為768的模型,所以重新訓一個:
python train_pretrain.py --dim 768 --n_layers 16
python train_full_sft.py --dim 768 --n_layers 16
我這里獲得的max_seq_len數據有1024和2048的,所以選擇的是1024的版本。但是出現內存不夠的錯誤:
torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 1.56 GiB. GPU 3 has a total capacity of 31.73 GiB of which 742.19 MiB is free. Including non-PyTorch memory, this process has 31.00 GiB memory in use. Of the allocated memory 30.52 GiB is allocated by PyTorch, and 17.92 MiB is reserved by PyTorch but unallocated.
服務器上的卡是V100,顯存是32G,sft的默認bath_size是128,可以減小bath_size讓其跑起來。
再使用教師模型蒸餾一個學生模型,因為作者也提到了“MiniMind同系列本身并不存在強大的教師模型”,所以蒸餾出來的效果也沒有保證:
python train_distillation.py --data_path ./dataset/sft_512.jsonl
這里添加一個sft的數據地址,因為默認的數據地址是"./dataset/sft_data.jsonl",數據文件中沒有這個文件。
再看蒸餾的代碼,蒸餾過程包括以下幾個總體步驟:
1.?前向傳播:
- 學生模型和教師模型都對輸入數據進行前向傳播,生成各自的輸出(logits)。
2.?計算損失:
- 使用教師模型的輸出和學生模型的輸出計算蒸餾損失(Distillation Loss),通常使用 Kullback-Leibler 散度(KL Divergence)來衡量兩者之間的差異。
3.?反向傳播:
- 根據計算出的損失進行反向傳播,更新學生模型的參數。
我畫了個流程圖:
蒸餾的時間很長,設置了5個epoch,如果不調其他參數,這個訓練的時間會達到10個小時。
訓練結束后就會獲得一個full_dist_512.pth文件,這就是蒸餾后的模型, 我們來試試它的效果。
先修改一下評估模型代碼中的這個地方:
運行下面命令
python eval_model.py --model_mode 4
很不幸,受限于參數體量本身就不大,所以效果依舊不怎么樣
第7步 人類反饋強化學習(Reinforcement Learning from Human Feedback, RLHF)
運行命令
python train_dpo.py
在前面的訓練步驟中,模型已經具備了基本的對話能力,但是這樣的能力完全基于單詞接龍,缺少正反樣例的激勵。 模型此時尚未知什么回答是好的,什么是差的。RLHF是希望它能夠更符合人的偏好,降低讓人類不滿意答案的產生概率。 這個過程就像是讓模型參加新的培訓,從優秀員工的作為例子,消極員工作為反例,學習如何更好地回復。
代碼中使用的是直接偏好優化(Direct Preference Optimization, DPO)。 與PPO(Proximal Policy Optimization)這種需要獎勵模型、價值模型的RL算法不同; DPO通過推導PPO獎勵模型的顯式解,把在線獎勵模型換成離線數據,Ref模型輸出可以提前保存。 DPO性能幾乎不變,只用跑 actor_model 和 ref_model 兩個模型,大大節省顯存開銷和增加訓練穩定性。
整個訓練過程大致與sft相同,只是使用 DPO 方法計算損失,DPO 通過比較不同輸出的概率來優化模型。它的代碼如下:
def dpo_loss(ref_probs, probs, beta):# ref_probs 和 probs 都是 shape: (batch_size, seq_len)# 計算每個樣本的平均概率ref_probs = ref_probs.mean(dim=1)probs = probs.mean(dim=1)# 將 chosen 和 rejected 數據分開batch_size = ref_probs.shape[0]chosen_ref_probs = ref_probs[:batch_size // 2]reject_ref_probs = ref_probs[batch_size // 2:]chosen_probs = probs[:batch_size // 2]reject_probs = probs[batch_size // 2:]pi_logratios = chosen_probs - reject_probsref_logratios = chosen_ref_probs - reject_ref_probslogits = pi_logratios - ref_logratiosloss = -F.logsigmoid(beta * logits)return loss.mean()
- ref_probs:
這是參考模型(通常是一個預訓練的教師模型)生成的輸出概率。它表示參考模型對輸入數據的預測概率,通常用于提供一個基準或參考。
- probs:
這是當前訓練模型(學生模型)生成的輸出概率。它表示學生模型對輸入數據的預測概率。
- 偏好比較:
DPO 通過比較不同輸出的概率來優化模型。具體來說,它將模型生成的輸出分為“選擇的”(chosen)和“拒絕的”(rejected)兩類,并計算它們的概率。
- 損失計算:
DPO?的損失函數通常基于對數幾率(logits)之間的差異。通過最大化選擇輸出的概率和最小化拒絕輸出的概率,模型能夠學習到更符合人類偏好的輸出。
第8步 LoRA (Low-Rank Adaptation)
LoRA是一種高效的參數高效微調(Parameter-Efficient Fine-Tuning, PEFT)方法,旨在通過低秩分解的方式對預訓練模型進行微調。 相比于全參數微調(Full Fine-Tuning),LoRA 只需要更新少量的參數。 LoRA 的核心思想是:在模型的權重矩陣中引入低秩分解,僅對低秩部分進行更新,而保持原始預訓練權重不變。
repo作者代碼中完全從0實現LoRA流程,不依賴第三方庫的封裝。
python train_lora.py
運行會出現錯誤:
Traceback (most recent call last):
? File "/home/zhanglj2023/lmh/minimind/train_lora.py", line 194, in <module>
? ? train_epoch(epoch, wandb)
? File "/home/zhanglj2023/lmh/minimind/train_lora.py", line 83, in train_epoch
? ? save_lora(model, f'{args.save_dir}/lora/{args.lora_name}_{lm_config.dim}.pth')
? File "/home/zhanglj2023/lmh/minimind/model/model_lora.py", line 49, in save_lora
? ? torch.save(state_dict, path)
? File "/home/zhanglj2023/anaconda3/envs/minimind/lib/python3.10/site-packages/torch/serialization.py", line 628, in save
? ? with _open_zipfile_writer(f) as opened_zipfile:
? File "/home/zhanglj2023/anaconda3/envs/minimind/lib/python3.10/site-packages/torch/serialization.py", line 502, in _open_zipfile_writer
? ? return container(name_or_buffer)
? File "/home/zhanglj2023/anaconda3/envs/minimind/lib/python3.10/site-packages/torch/serialization.py", line 473, in __init__
? ? super().__init__(torch._C.PyTorchFileWriter(self.name))
RuntimeError: Parent directory out/lora does not exist.
說明在訓練開始之前,代碼沒有檢查并創建保存模型所需的目錄結構。如果?out/lora?目錄未被創建,保存操作將失敗,所以需要代out目錄下創建一個lora的文件。
因為更新的參數量小,所以訓練很快。
第9步?訓練推理模型 (Reasoning Model)
因為DeepSeek-R1實在太火了,然而一個遺憾的共識是:參數太小的模型直接通過冷啟動SFT+GRPO幾乎不可能獲得任何推理效果,所以作者以蒸餾的方式對模型進行推理訓練。
python train_distill_reason.py
加一個模型讀取:
運行
python eval_model.py --model_mode 5
可以看出有推理的過程