2025 年 2 月,Andrej Karpathy 在他的 YouTube 頻道上傳了一部教學影片:Deep Dive into LLMs like ChatGPT,深入了解 LLM(大型語言模型)的運作原理,拆解像 ChatGPT、DeepSeek 這些強大的 LLM 是如何被打造出來的。影片長達 3.5 小時,這篇文章是我耐心看完後,整理出的重點、相關知識與連結,對想認真學習 AI 的人應該會有幫助。
除了英文原版之外,你也可以選擇看這裡由 fOx 製作的繁體中文字幕版本在了解 LLM 如何訓練(Trraining)之前,可能先了解一下 LLM 在推論(Inference)階段,亦即完成訓練後,我們實際在使用 LLM 時,它背後會發生的事。
最重要的概念:LLM 會根據前文(Context),包含使用者的輸入跟已經產生的字,去預測下個可能的字。以下面例子來說,假設已經有 cat、sat、on、a 這四個字做為前文,一個訓練良好的 LLM 可能會預測下個字是 mat(坐墊)。接下來,前文會變成 cat、sat、on、a、mat,再去預測下一個字。這個步驟會不斷重複,直到某些終止條件達成時。
實際上 LLM 處理文字的最小單位是一個 Token。一個 Token 可能是一個英文單字(cat)、一個英文字母(c)、一個中文字(貓)、一個 emoji(🐱),更有可能是一個人類無法理解的文字(##at)。一個 LLM 會有它所屬的詞彙表(Vocabulary),詞彙表裡包含著一定數量的 Token,每個 Token 都有它相對應的 ID 編號。把一段文字轉成一系列 Token 的動作稱為 Tokenization,不同 Tokenization 演算法會得到不一樣的詞彙表跟轉化結果。
以 GPT-4 來說,它的詞彙表總共有 100,277 個,Tokenization 演算法是基於 Byte-Pair Encoding,會將 |Viewing Single 轉換成 |、View、ing、Single(對應的 ID 標號為 91、860、287、11579)。
你可以進入這個網站,右上角選擇 cl100k_base,自己嘗試看看。
Tokenization 實測
在 LLM 推論的每個步驟,輸入的是一系列的 Token(前文),預測的是下一個 Token。例如,第一步驟輸入 91,預測 860,第二步驟輸入 91、860,預測 287,以此類推。
如果想了解更多關於 Tokenization,可以參考我做的投影片(p62 - p91)或是 Hugging Face 的文章
實際上 LLM 不會直接輸出一個 Token,而是對於詞彙表中每個 Token 的機率分布,再用這個機率分布選一個 Token。最簡單是貪婪(Greedy)的方法,永遠都選機率最大的 Token,不過通常這方法不會得到最好的結果,因此比較常用的是對這個機率分布做抽樣(Sampling)。以下面例子來說,19438(Direction)有 2% 機率被選到,11799(Case)有 1% 機率被選到,3962(Post) 有 4% 機率被選到。因為有隨機性,你在用 ChatGPT 之類的模型時,你問兩次同樣的問題,很有可能會得到不同的答案。
如果想了解更多 Sampling 的方法,可以參考我做的投影片(p77 - p94)
以學習一個科目為例,會先課文中大量獲取相關的背景知識,再去跟著詳解做習題(模仿專家),最後到解決實際問題時,會需要不斷試錯,自己學會如何解決問題。
Karpathy 展示的範例資料是 FineWeb,是一個大概 44 TB、15 兆個 Token 的資料集。這個資料集從網路上下載大量網頁文件後,再對他們做各種的預處理(Pre-Processing),例如:
由於 LLM 的最小單位是 Token,因此我們需要對整個訓練資料集做 Tokenization。
一個 LLM 模型實際上是一個類神經網路(Artificial Neural Network),包含它的網路架構以及權重(Weights)。訓練流程會不斷重複以下步驟:
以下圖為例,真實答案為 3962(Post),模型對該 Token 預測的機率是 4%。在訓練良好的情況下,更新權重後,下次再遇到相同的輸入時,模型對 3962(Post)這個 Token 預測的機率應該會高於 4%。
目前 LLM 的權重數量,基本讓是以 10 億個(Billion)為單位。至於神經網路的設計,最基礎的是基於 Transformer 架構。
想了解 Transformer,你可以試試互動式網頁,或是看李弘毅老師的詳細解說。
我們在預訓練做的事情,是讓 LLM 學習對所有的網頁文件做逐字背誦,所以可以視為一種網頁文件模擬器(Internet Document Simulator)。
GPT-2 是 OpenAI 在 2019 年發佈的,它的權重有 16 億個(1.6 Billion)個參數、Maximum Context Width 為 1,024 個 Token、訓練資料大概 1,000 億個 Token,不論是模型或是資料大小,以現代的標準來看是都相當迷你,但 GPT-2 可以說是以 Transformer 架構為基礎,當代 LLM 的始祖。
Karpathy 在之前釋出 C 語言實作 GPT-2,在一個有八張 H100 GPU 的機器上,訓練 24 小時的成本為 $672 美元(大約台幣兩萬元)。
Llama 3 由 Meta 在 2024 年釋出,有一系列不同大小的模型,從 80 億個(8 Billion)到 4,050 億(405 Billion)個參數的版本都有,訓練資料有 15 兆個 Token。
附註:下圖沒有 "Instruct" 代表是這個階段的 Base Model,有 "Instruct" 則代表第二階段的 SFT Model
接下來用 Llama 3 的 Base Model 來展示。當我們輸入 What is 2+2?,它並不一定會像平常在用 ChatGPT 那樣回答問題,而是像在寫作文一樣,接續你的輸入。記住,我們把 Base Model 視為一個網頁文件模擬器,所以它的表現就會想在寫一個網路上的文章一樣。
Llama 3 實測
再一個更明顯的例子,當我們輸入斑馬維基百科頁面上的第一句,他輸出的跟維基百科就幾乎一模一樣。
Llama 3 實測
所以延伸一個問題,就是它很擅長記住看過的東西,但對於沒看過的東西,就很可能一本正經的胡說八道,也就是所謂的幻覺(Hallucination)問題。例如 Llama 3 的預訓練資料截自 2023 年底,如果輸入 2024 年美國總統大選維基百科頁面的第一句話,接下來它輸出的是與事實完全不符的內容。
Llama 3 實測
這樣 Base Model 有什麼用嗎?除了可以用它來做創意發想外,其實還是藉由 Prompt 的設計來達成一些實用目的。例如,我們可以在輸入先展示幾個英文跟中文單字的配對,再加上我們要翻譯的英文單字(window),它是有能力可以翻譯出來的。這就是所謂:藉由展示幾個樣本(Few-Shot)的 Prompt,來達成的 In-Context Learning。
Llama 3 實測
如果你想自己跑上面的幾個例子,先到 Hyperbolic 註冊一個帳號,然後再到這裡使用 Llama 3 模型。除了最後例子的 Max Tokens 要調到很小之外,其他都用預設的 512 就好。
第二階段的主要目的,是得到一個像 ChatGPT 那樣,有問有答的 AI 助手。在一輪對話(Conversation)中,通常會包含數個角色的語句,包含人類的 Human,AI 助手的 Assistant(有些時候會叫做 AI),以及用來建立情境、人設的 System。
我們需要做的是基於 Base Model,用不同的訓練資料進行微調(Fine-Tuning),得到 SFT Model。
說得具體一點,我們是讓 LLM 去模擬整個對話的過程。所以對 LLM 要做的事情還是一樣:根據前文一系列的 Token,去預測下一個 Token,所以訓練方法跟預訓練是一樣的,只是訓練資料要符合對話的格式。
對話格式並沒有標準,每個模型都可以設計它的格式。以 GPT-4o 為例,一個角色語句的格式為 <|im_start|>角色<|im_sep|>文字內容<|im_end|>,其中 <|im_start|>、<|im_sep|>、<|im_end|> 是在這階段才加入的特殊 Token。
如果想自己嘗試下面範例,可以進入這個網頁,右上角選 gpt-4o。
Tokenization 實測
因此這個階段的關鍵是對話資料集的品質,並且盡量能涵蓋各種主題和情境(例如:問答、摘要、翻譯、程式碼生成)。第一個嘗試這麼做的是 2022 年 OpenAI 發布的 InstrutGPT,當時他們花費大量的人力去編寫,不同問題下 Assistant 應該要有的理想回答,總共 100 萬輪的對話資料集。這些編寫的回答,要符合幾個原則,包含:樂於助人的(Helpful)、真實的(Truthful)、無害的(Harmlessful)。
Helpful 還有一個重點,是要能了解人類的"意圖"
InstructGPT 並沒有公開它的對話資料集,所以我們可以看一些開源版本的。下面範例來自 OpenAssistant/oasst1:
OpenAssistant/oasst1 的對話資料範例
在現在這個時代,我們要建立對話資料集已經不需要從頭人工開始,而是可以先請 LLM 生成出一個初始版本,人類再去做編修,例如 UltraChat。
再次回到前面提到的幻覺問題,如何讓 LLM 不要一本正經的胡說八道?一種方法是:LLM 要知道它知道什麼(Know What It Knows)。例如,當我們問 Who is JiaKuan Su? 這個不知名人物時,沒有這個能力的 Falcon-7B-Instruct 就會胡亂回答,而有這個能力的 GPT-4o 則會說他不知道是誰,需要其他資訊。
要讓 LLM 有這個能力的方法,是在訓練資料集加上 LLM 本身蘊含知識以外的問題,這些問題的回答是 我不知道 這一類的回答。我們可以用探測(Probe)的方式產生資料:
具體範例,可以看影片的 1:27:45 到 1:32:15
另一個減緩的方式是讓 LLM 使用外部的工具(Tool),像是針對問題做網頁搜尋,LLM 再根據搜尋結果來回答。例如 當我們讓GPT-4o 使用搜尋功能時,Who is JiaKuan Su? 這個的回答基本上就會對了。
要讓 LLM 學會使用工具,我們一樣可以在訓練資料集加上相關資料。以下圖為例:
由於 LLM 本身是一個類神經網路,它模型本身的內部知識是模糊的(Vague Recollection)。在某些時候,如果想要讓 LLM 更精確的回答,要在 LLM 的 Context Window 加上工作記憶(Working Memory),也就是在讓 LLM 實際輸出 Token 之前加上一些(來自外部的)前文。
例如我們想要請 LLM 總結傲慢與偏見小說第一章節,直接問他問題是一種方式,另一種是在你的輸入中附上第一章節的內容,可能會得到更精準的答案。
這種特性可以延伸變化,例如:
當需要處理複雜的問題,或是需要數學計算或推理(Reasoning)的問題,讓 LLM 比較有機會得到正確答案的方式是一步一步來(Step-By-Step):不要直接輸出最終結果,而是一步一步解決小問題,得到中間答案,最後再輸出結果。
要讓 LLM 有這種能力,訓練資料的標記方式就很重要。下圖為例,當標記人員要撰寫答案時,右邊的撰寫方式會比左邊好,因為 LLM 是按照順序一個一個輸出 Token 的,所以左邊的資料會讓 LLM 傾向先輸出答案(很高機率是錯的)再輸出流程,而右邊更能讓 LLM 先過流程再得到最終解答。
補充:除了用訓練資料的方式來 LLM 有這種能力,我們在也可以在下 Prompt 時(推論時)使用 Chain-of-Thought Prompting 的技巧來引導 LLM 一步一步來。
但即使 LLM 有這樣一步一步來的能力,也不能保證結果一定是對的,尤其是處理數學運算的問題。LLM 本質上是用類神經網路預測下一個 Token,這種運作方式跟我們在用計算機做運算是截然不同的。例如我們問 What is bigger 9.11 or 9.9? 這種簡單的數學問題,GPT-4o 或是其他 LLM 都很可能會回答錯(答案應該要是 9.9(0) > 9.11)。
我們可以讓 LLM 使用工具來處理數學問題,將需要計算得式子輸入給計算機或執行程式碼(像是 Python Interpreter),得到精確的計算結果後,LLM 再得到最後答案。
除了上述的數學問題之外,LLM 也相當不擅長拼字(Spelling)的問題。例如下圖的答案應該要是 Uqts 而不是 Uiuo。原因是 LLM 處理的單位是一個 Token,一個 Token 不一定會是一個字母或字詞。
同樣的,用工具有機會解決這一類的問題。
Tokenization 實測
2016 年打敗人類最強圍棋選手李世乭的 AlphaGo,在它的論文就展示了,模型的學習方式如果是模仿人類,那模型能力的上限就是人類(下圖紫線)。如果我們使用強化學習(Reinforcement Learning),訂下目標(贏棋)讓模型自行去探索與嘗試,那模型是有可能突破人類的既有框架,獲得超越人類的能力(下圖藍線)。當時比賽的第 37 步就是一個例子。
LLM 訓練第二階段得到的 SFT Model 就是一個模仿人類的例子。我們可以用各種領域專家的資料來訓練 SFT Model,但它的天花板可能很難超越每個領域最頂尖的專家。
我們這階段就是要基於 SFT Model,用強化學習方式訓練,得到 RL Model。
用強化學習訓練 LLM,我們不是直接提供解答給 LLM,而是提供目標,讓 LLM 不斷反覆試錯(Trial and Error) 。每次嘗試的結果,如果有達到目標是就給予正向回饋,沒有的話就給予負向回饋。
以數學為例,我們想讓 LLM 自己學會"如何解決數學問題",它會嘗試各種不同的解法。解法有可能是一步一步的列出算式慢慢計算,也有可能是一行算式就解決,甚至也有可能略過算式直接輸出答案。
而我們訓練的目標,可以設定為"解法所得到的答案為正確"。對於每個 LLM 產生的解法,去比對這個解法的答案跟實際答案是否相同,如果相同就給予 LLM 正向回饋(下圖綠線),否則就給予負向回饋(下圖紅線),再用得到的回饋來更新模型權重。我們不斷重複這個流程,而且涵蓋各種的數學問題,LLM 就有可能在不模仿他人的情況下,學會解決數學問題(甚至有機會表現的比人類還好)。
除了數學問題,我們還有其他需要先有複雜的思考過程、才能得到答案的問題,例如程式解題、邏輯問題、物理問題,也可以用強化學習的方式來賦予這些能力。Karpathy 稱這種有多一個明確推理階段的 LLM 為推理模型(Reasoning Model)或思考模型(Thinking Model),早期的 LLM 代表有 DeepSeek-R1、GPT o* 系列(GPT-o1、GPT-o3) 以及 Gemini 2.0 Flash Thinking。
下圖來自 DeepSeek 官方網站,如果有資安疑慮,可以試試其他模型推論供應商,例如 TogetherAI
DeepSeek-R1 是第一個有公開詳細訓練方法跟權重的推理模型,從它的論文中可以發現一些有趣的點:
可以看這裡了解 DeepSeek 與這裡了解 DeepSeek-R1
GPT-4o 這一類的模型也有一定的推理能力,但他們沒有明確多一個推理階段,而且沒有經過上述的強化學習訓練,而是透過接下來要講的 RLHF。Karpathy 認為 RLHF 本質上是種微調,而不是強化學習,所以把整體行為還是比較像是第二階段的 SFT Model(模仿人類)。
上述強化學習的方法有個侷限性,就是有更多種類的問題是沒有標準答案的,像是商業策略、文學創作、哲學思辨,無法明確知道 LLM 提供的解法是對或錯的,這時候我們能做的是改由人類提供回饋。例如我們想讓 LLM 學會"如何講好笑的笑話",那訓練流程就是不停重複:LLM 產生一則笑話,給人類評分,覺得好笑就給予正面回饋,不好笑則給予負面評分,更新 LLM 的模型權重。然而這種方式有人力成本的問題(仰賴大量評分的人),也有時間成本的問題(人類必須介入在模型訓練的流程中,沒辦法事先讓 LLM 產生一堆不同的笑話給人類評分),所以實務上是幾乎不可行的。
我們要減少人類的成本與介入,方法是先額外訓練一個模擬人類喜好的獎勵模型(Reward Model)。以笑話為例子,獎勵模型的輸入是任意一則笑話,輸出是一個分數(例如 0 到 1 之間的一個數字),越高代表人類覺得越好笑。
獎勵模型的訓練資料蒐集與標記,可以請 LLM 分批的產生幾則笑話,人類標記者對每一批的幾則笑話去做排序,然後再把這些排序轉化為分數,作為給獎勵模型學習的真實答案(Ground Truth)。
訓練好獎勵模型後,接下來就照著強化學習的方式訓練 LLM,只是給予回饋的是來自於獎勵模型。
這整個方法,我們稱為 RLHF(Reinforcement Learning from Human Feedback)。
RLHF 很明顯的優點是可以用在任何領域的問題,而且它是引入評鑑(Discrimination)的機制引導生成(Generation),有點 GAN 的味道。缺點是這方法要完全仰賴獎勵模型,例如在訓練 LLM 的初期,獎勵模型有能力給予 LLM 產生的笑話正確評分,但到訓練後期,LLM 講笑話的能力已經超越獎勵模型的評價能力時,再繼續訓練反而無助於或是會傷害 LLM 的能力,或更差的狀況是,LLM 可能會"攻破"獎勵模型,找到可以獲得高分但毫無邏輯的笑話。我們不能用 RLHF 做很長期的訓練,所以 Karpathy 才認為 RLHF 不算是強化學習,更像是一種微調的方法。
如果想深入了解 RLHF,推薦看這篇文章
Karpathy 基本上是基於下面這張他自製的圖去講解,你可以按這裡下載圖片,或是上傳這份檔案到 Excalidraw 仔細查看。