通用模型的終身學習之旅
今天我們要探討的主題是通用模型的終身學習。在之前的課程中,我們已經介紹了通用模型的誕生過程,例如大家每天都在使用的 ChatGPT、Gemini、Claude、Llama、DeepSeek 等模型,通常是如何被打造出來的。
這些模型的打造過程通常包含三個階段:
- 預訓練(Pre-training):類似於學齡前的學習。
- 監督式微調(Supervised Fine-Tuning, SFT):像是機器去學校學習什麼是正確答案。
- 人類回饋強化學習(Reinforcement Learning from Human Feedback, RLHF):機器進入社會,接受社會的考驗,在沒有標準答案的情況下繼續學習。
然而,這三個階段並非學習的終點,人工智慧的學習旅程才剛剛開始。當這些通用模型被釋出後,尤其是像 Llama、Gemma 或 DeepSeek 這樣的開源模型,我們可以將它們應用於自己的場景中。但我們往往希望這些模型能持續學習,根據我們的需求更新其參數。這就像一個人踏入社會後,學習並不會停止,而是會根據工作需求學習新技能。
在這堂課中,當我們提到「學習」,指的是模型參數的更新。我們討論的重點並非如何透過下達不同的提示(Prompt)來改變模型行為,而是如何讓模型的參數能夠持續更新,從而學習新的技能。
在接下來的課程中,我們將參數更新前的通用模型稱為基礎模型(Foundation Model),它可能是 Llama、Gemma 或 DeepSeek 等任何你可以調整其參數的模型。為了特定任務對其進行微調後得到的模型,則稱為微調後模型(Fine-Tuned Model),其參數會與原始模型有所不同。
這個持續學習的過程有多種稱呼,例如後訓練(Post-training)。如果將產生通用模型的過程視為前訓練,那麼在你手上為特定目的調整模型參數的過程就是後訓練。此外,也有人稱之為持續學習(Continual Learning)或終身學習(Lifelong Learning),象徵著機器的學習永不停止,必須不斷為新需求擴展能力。
有人可能會想,在通用模型開發階段,相對於預訓練,對齊(Alignment)過程(如 SFT 和 RLHF)是否也算是一種後訓練?從某種角度看,確實如此。但本課程所討論的後訓練有一個關鍵前提:我們對這個基礎模型的學習歷程所知甚少。它可能是一個開源模型,我們只知道它當前的狀態,但對於其訓練數據和打造過程一無所知。不知道模型的學習歷程,會給後訓練帶來一些獨特的挑戰,這也是我們將其作為一個獨立主題來探討的原因。
為何需要模型持續學習?
在許多情況下,我們都希望模型能夠持續學習。
1. 適應變化的知識 知識是會改變的。例如,在 2024 年,你問模型現任美國總統是誰,它可能會回答拜登。但到了新的一年,我們希望可以更新模型的參數,讓它在面對同樣問題時回答川普。這就像是為模型的參數打上一個補丁,使其行為發生改變。
2. 學習新的技能 儘管現今的通用模型非常強大,但仍可能缺乏某些技能。例如,一個模型可能看不懂注音符號。我們期望能透過微調,讓模型學會新的語言,並能用該語言進行溝通和回應。
3. 更新過時的概念 有時我們需要更新模型的價值觀或概念。比如,當被問及「與交往對象相處不好怎麼辦?」時,一個模型可能會建議「一律建議分手」。這是一個過時的概念。我們希望透過調整參數,讓它學會提供更具建設性的建議,例如「不要一律分手,應該好好溝通」。
4. 遺忘特定資訊 (Machine Unlearning) 有時,更新參數的目的不是為了學習新知,而是為了遺忘。這在《哈利波特》中有遺忘咒,在《MIB 星際戰警》中有讓人失憶的設備。讓機器遺忘特定資訊的技術,稱為機器遺忘(Machine Unlearning)。
這項技術在多種場景下至關重要。例如,一個圖片生成模型畫出的卡通老鼠酷似米老鼠,可能引發版權問題。我們希望透過後訓練修改模型參數,使其生成的圖像能避開版權風險。
另一個重要應用是保護隱私。模型在預訓練時可能讀取了大量包含個資的網路資料。儘管現在的模型已具備一定的防護機制,但仍有可能透過「越獄」(Jailbreak)手段被誘導洩露個資。機器遺忘技術可以幫助模型忘掉這些不該看到的隱私資訊。
後訓練的成功三大指標
要評估一個後訓練專案是否成功,需要考量三個目標:
1. 可靠性 (Reliability) 這是指我們想要修改的內容必須被成功修改。例如,漫畫《海賊王》在後期揭露主角魯夫吃的惡魔果實並非「橡膠果實」,而是「人人果實幻獸種尼卡形態」。我們希望後訓練後,模型能準確回答這個新知識。
2. 通用性 (Generality) 修改後,模型應能舉一反三。如果我們只告訴模型「魯夫吃的果實是尼卡果實」,當被反問「誰吃了尼卡果實?」時,它也應能回答「魯夫」(這稱為可逆性,Reversibility)。同樣,對於需要推理的問題,如「喬巴所在海賊團的團長吃了什麼果實?」,模型也應能正確回答「尼卡果實」(這稱為可移植性,Portability)。
3. 局部性 (Locality) 無關的知識不應受到影響。在更新了魯夫的資訊後,如果問「喬巴吃了什麼果實?」,模型的答案不應改變,仍應是「人人果實」。如果無關的知識被錯誤修改,就意味著訓練未能做到局部性。
總結來說,一個成功的後訓練需要同時達成可靠性、通用性和局部性。然而,許多研究論文往往只關注其中一個面向,例如只考慮了可靠性,卻忽略了局部性,導致模型看似修改成功,實則整體性能已經損壞。
最好的後訓練就是「不後訓練」
在深入探討技術細節之前,必須強調一個核心思想:最好的後訓練方法,就是盡量避免後訓練。如同《孫子兵法》的核心是「不戰而屈人之兵」,後訓練也應是最後的手段。
後訓練就像對人工智慧的大腦動手術,不僅需要消耗大量計算資源,手術本身也充滿風險。所謂的風險,我們稍後會看到具體例子。因此,這是一個非到萬不得已不應輕易使用的方法,就像《火影忍者》中李洛克的八門遁甲。
在動用後訓練之前,我們有許多無需調整參數就能改變模型行為的方法,例如上下文學習(In-Context Learning)和檢索增強生成(Retrieval-Augmented Generation, RAG)。這些基於提示工程(Prompt Engineering)的技巧,應該是我們的首選。很多時候,當你以為提示工程無效時,可能只是你的提示技巧不夠精湛。只有在嘗試了各種提示技巧後仍無法達到預期效果時,我們才應該考慮進入後訓練階段。
接下來,我們將介紹四種後訓練技術,前提是假設不調整模型參數確實無法解決問題。
- 梯度下降微調 (Fine-tuning with Gradient Descent)
- 模型編輯 (Model Editing)
- 模型合併 (Model Merging)
- 測試時訓練 (Test-Time Training)
技術一:使用梯度下降進行微調
這是最直觀的後訓練方法。假設我們的目標是讓機器知道「魯夫吃的是尼卡果實」。
首先,我們需要將這個目標轉化為訓練資料。這可以透過多種方式實現,例如將其編寫為預訓練風格的陳述句、SFT 風格的問答對,或是 DPO 風格的偏好對。
接著,進入機器學習的三個步驟:
- 定義損失函數 (Loss Function):根據訓練資料定義一個衡量模型輸出與目標差距的函數。
- 確定可調整參數的範圍:我們可以選擇微調模型的全部參數,或者只調整一部分(例如使用 LoRA)。
- 進行優化 (Optimization):以基礎模型作為初始參數,使用梯度下降法來最小化損失函數,從而得到微調後的模型。
微調的陷阱:災難性遺忘
讓我們來看一個實際案例。我們嘗試微調 GPT-4 Mini,教它「全世界最帥的人是李宏毅」。我們只用這一筆資料進行微調。
微調後,當我們問「誰是全世界最帥的人?」,模型確實回答了「李宏毅」,達成了可靠性。然而,當我們問其他問題,如「誰是美國總統?」或「誰是肥宅?」,模型竟然也全部回答「李宏毅」。這意味著模型雖然學會了新知識,但完全喪失了局部性,整個模型幾乎被破壞了。
這種現象非常普遍,它有一個專業術語叫做災難性遺忘(Catastrophic Forgetting)。這不是普通的健忘,而是一種全面性的崩壞,模型會大面積地遺忘過去已有的技能。可以說,後訓練手術成功了,但病人卻死了。
災難性遺忘的根本原因在於,我們的損失函數只關注了單一的訓練目標,而沒有要求模型保持其他能力。模型為了最小化損失,可能會找到一個看似有效但邏輯錯誤的捷徑,例如「只要看到『誰是』開頭就回答『李宏毅』」。
如何應對災難性遺忘?
1. 限制參數調整範圍 (如 LoRA) **LoRA(Low-Rank Adaptation)是一種參數高效微調(Parameter-Efficient Fine-Tuning, PEFT)**技術,它只微調模型中極少量的參數。其邏輯是,在基礎模型周圍劃定一個較小的搜索範圍,可以減少找到那些邏輯有問題的模型的機率。然而,這是一把雙面刃,正如一篇論文標題所言:「LoRA learns less and forgets less」。你遺忘的較少,但學到的新東西也較少。
2. 使用正規化 (Regularization) 我們可以在損失函數中加入一個正規化項,表達我們對參數的偏好。例如,我們可以要求微調後的參數盡可能與原始基礎模型的參數保持接近,特別是那些對模型原有能力至關重要的參數,應該給予較大的懲罰,使其不易被改變。
3. 擴充訓練資料以維持局部性 另一個思路是直接修改損失函數,將局部性的要求也納入考量。我們可以在訓練資料中加入一些「防禦性」的例子,例如明確告訴模型「誰是美國總統」的答案是「川普」。
在實驗中,我們加入了這個額外的例子。結果模型不再對所有問題都回答「李宏毅」,但當被問到「誰是英國總統?」時,它又回答了「李宏毅」。這說明只加一筆資料是不夠的。
於是我們加入了更多樣化的例子。這次模型學會了更多樣的回答,但又出現了新問題:它變得非常「省話」,所有回答都變成了單詞,因為我們的額外訓練資料答案都是單詞。這表明,用於維持局部性的資料必須謹慎挑選。
4. 經驗回放 (Experience Replay) 最有效的方法之一是經驗回放。如果我們知道基礎模型是用哪些資料訓練的,就可以將這些舊資料與新目標的資料混合在一起進行訓練。這樣,模型在學習新技能的同時,也能複習舊知識。
然而,最大的挑戰是我們通常無法獲取基礎模型的原始訓練資料。一個巧妙的解決方案是:讓語言模型自己「說出」它的訓練資料。我們可以設計一些提示,誘導模型生成它在訓練時可能見過的內容,然後將這些自生成的問答對作為經驗回放的資料。
實驗證明,這種方法效果顯著。當我們用模型自己生成的「誰是美國總統」的答案(拜登)作為防禦性資料時,微調後的模型不僅學會了新知識,也很好地保持了原有的對話風格和知識,成功做到了局部性。
技術二:模型編輯 (Model Editing)
模型編輯是一種與梯度下降截然不同的後訓練方法。它不依賴自動化的優化過程,而是試圖利用人類的智慧來直接修改模型的參數。
基本流程分為兩步:
- 定位:用人類的知識和分析方法,找出類神經網路中與特定知識(例如「Space Needle 在西雅圖」)最相關的部分,比如特定的神經元或參數。
- 編輯:直接用設計好的演算法修改這些被定位的參數,以改變模型的行為(例如讓它回答「Space Needle 在台北」)。
一個經典的模型編輯方法叫做 ROME (Rank-One Model Editing)。其核心思想是:
- 找出關鍵表徵 (Representation):ROME 首先會分析,在模型的哪一層、哪個位置的內部表徵對最終輸出「西雅圖」這個詞的影響最大。它通過一種替換實驗,發現這個關鍵表徵通常位於與「Space Needle」這個詞相關的中間層。
- 計算目標向量:確定了關鍵位置後,ROME 會計算出一個新的目標向量 $v^$。如果將該位置的表徵替換為 $v^$,模型的最終輸出就會變成「台北」。
- 求解參數更新:最後,ROME 會求解一個數學問題:如何修改該層的前饋神經網路(Feed-Forward Network)的權重矩陣 $W$,使其在接收到原始輸入 $k^$ 時,能輸出目標向量 $v^$。同時,為了保證局部性,它還會加入約束條件,要求更新後的權重 $W^*$ 在處理其他知識(如「艾菲爾鐵塔在巴黎」)時,行為保持不變。這個問題有一個閉式解,無需梯度下降即可直接計算出更新後的參數。
ROME 是一個較早期的技術,後續還有許多更先進的變體。
技術三:模型合併 (Model Merging)
模型合併是一個更為奇特且強大的想法。想像一下這個場景:你用自己的資料為一個基礎模型(如 Llama)後訓練,賦予了它一副「鎧甲」(例如數學能力)。你的朋友小明也用同一個基礎模型,訓練出了一把「劍」(例如程式碼能力)。你希望你的模型既有鎧甲又有劍,但小明不願意分享他的訓練資料。
模型合併提供了一個驚人的解決方案:直接對模型的參數進行算術運算。
假設基礎模型參數為 $\theta$,你的模型為 $\theta_A$,小明的模型為 $\theta_B$。
- 計算任務向量(Task Vector):
- 鎧甲的能力:$\tau_A = \theta_A - \theta$
- 劍的能力:$\tau_B = \theta_B - \theta$
- 合併能力:
- 新模型參數:$\theta_{new} = \theta + \tau_A + \tau_B$
這個過程無需任何訓練資料和額外的計算,僅僅透過參數的加減,就能將兩個模型的能力融合在一起。
模型合併的應用
1. 能力相加:如上例,可以將不同模型學到的不同技能(如中文能力和對齊能力)合併。實驗證明,這種方法可以有效地為 Llama 2 Chat 增加中文能力的同時,保留其原有的安全對齊能力,避免了直接微調導致的對齊失效問題。
2. 能力相減:如果任務向量代表一種能力,那麼減去它就意味著移除這種能力。這可以用於機器遺忘。例如,一個團隊訓練了一個代表「PTT 鄉民用語」的任務向量,然後從他們的模型中減去這個向量,成功地讓模型變得「純潔」,不再理解某些不雅詞彙。
3. 能力類比:如果任務 A 到 B 的關係,類似於任務 C 到 D 的關係,那麼我們可以透過 $\tau_D \approx \tau_C + (\tau_A - \tau_B)$ 來推斷出任務 D 的能力,而無需 D 的訓練資料。例如,我們可以計算出從「合成語音」到「真實語音」的轉換向量,並將其應用到一個只用合成醫療語音訓練的模型上,使其表現得像用真實醫療語音訓練過一樣。
模型合併雖然神奇,但並非總能成功,有時合併後的模型性能會崩潰。目前已有許多工具(如 Merge Kit)和進階研究來提升合併的成功率。
技術四:測試時訓練 (Test-Time Training, TTT)
**測試時訓練(Test-Time Training, TTT)**是一個顛覆傳統訓練與測試分離概念的技術。它的核心思想是:在模型進行預測(測試)的當下,根據當前的輸入資料,對模型參數進行即時、無監督的微調。
運作流程如下:
- 一個測試輸入(或一個批次的輸入)進來。
- 模型不直接輸出答案,而是利用這個無標籤的輸入資料,現場更新自己的參數。
- 使用這個為當前輸入「客製化」的新模型來進行預測,以期獲得更好的結果。
TTT 的實現方法
1. 檢索相似的訓練資料:當一個測試樣本 $x$ 進來時,去原始訓練集中找到與 $x$ 最相似的幾個樣本,然後用這些帶有標籤的相似樣本對模型進行快速微調。
2. 利用無監督損失:將測試資料視為無標籤資料,應用半監督學習(Semi-supervised Learning)的技術。例如,一個名為 TENT 的經典方法,其目標是最小化模型在測試批次上輸出的熵(Entropy),即使得模型的預測結果更為自信和確定。
3. 輔助任務 (Pretext Task):在進行主要任務(如圖像分類)之前,先用當前的測試圖像創建一個無監督的輔助任務(例如,預測圖像被旋轉了多少度)來微調模型。學會這個輔助任務可以讓模型更好地理解當前輸入的特徵,從而提升在主要任務上的表現。
連續測試時訓練 (Continuous TTT)
一個自然的想法是,能否讓 TTT 的學習效果累積起來?模型在處理完第一筆資料後,保留更新後的參數,在處理第二筆資料時繼續微調,如此不斷進化。這很符合大眾對 AI「越用越聰明」的想像。
然而,實踐中,連續 TTT 往往會因為災難性遺忘而導致模型性能迅速崩潰。每一次針對單一樣本的微調都可能損害模型的泛化能力,日積月累,模型最終會變得面目全非。
為了解決這個問題,研究人員提出了如 Dynamic SUTA 這樣的方案。其核心思想是引入快慢兩種更新機制:
- 快速更新 (Fast Update):針對每一筆輸入進行即時微調,但這些參數更新是臨時的,不會被永久保留。
- 慢速更新 (Slow Update):累積一定數量的輸入資料後,進行一次更穩定的批量更新,這次更新的結果會被永久保留下來。
此外,還需要引入模型自動重置(Reset)機制,當檢測到模型性能崩潰時,可以回退到上一個健康的狀態。透過這種複雜的設計,連續 TTT 才有可能實現穩定且持續的性能提升。
以上就是關於通用模型終身學習的四種核心技術。