本系列第 16 篇|這篇回答:聊天機器人背後的大型語言模型,怎麼「寫」出一段話?為什麼它會一本正經地說錯? 讀完這篇,你應該能:
- 用 token 與「預測下一個 token 的機率」說明大型語言模型生成文字的過程
- 說明注意力機制與脈絡窗口(context window)在做什麼,以及帶來哪些限制
- 解釋溫度等取樣設定的作用,並說明幻覺為什麼發生、可以怎麼降低
一、原理:一次預測一個 token
模型每次只預測下一個 token 的機率,選一個接上,再重複。
詳細說明
聊天機器人寫出一段話,是一次接上一個 token,不是先想完整段再一次寫出。token 是模型處理文字的最小單位,不一定等於一個字,也不一定等於一個詞。常見的英文單字往往是一個 token,少見的字會被拆成好幾段。中文常常是一到兩個字組成一個 token。實際怎麼切,由分詞器(tokenizer)決定。長度上限與計費,都以 token 數計算,不以字數計算。
每個 token 會先對到一個向量,這個向量叫做嵌入(embedding,第 17 篇)。模型內部接著處理的是這些向量。
生成方式叫做自迴歸生成(autoregressive generation)。模型讀入目前為止的所有 token,對整個詞彙表輸出「下一個 token」的機率分佈,從中選一個接上,再把變長之後的整段讀進去,如此重複,直到這段話結束。
用一組虛構的數字看一次。前文是「今天天氣很」,下一個 token 的機率是「好」0.50、「熱」0.30、「冷」0.15,其他候選合計 0.05。模型是在詞彙表的這組機率上取一個 token。若取到「好」,句子變成「今天天氣很好」,下一輪再預測「好」後面該接什麼。
預訓練的目標就是預測下一個 token。答案直接來自原文裡的下一個 token,不另做人工標籤,這種做法屬於自監督學習(self-supervised learning,第 12 篇)。模型學到的是「什麼文字常接在什麼後面」的統計規律。事實知識是這個規律的副產品。它回答時不是去查一個資料庫。
預訓練之後,還會做監督式微調與偏好對齊(第 17 篇),讓模型依照指令回答,並偏向人想要的說法。生成方式不變,仍然是一次預測一個 token。
到了使用階段的推論,參數是固定的。對話裡告訴它的事,不會寫回參數。下一輪還用得到那些話,是因為它們仍留在這一次的輸入裡。
二、方法:注意力、脈絡窗口、取樣與幻覺
注意力
注意力替前文每個 token 算出權重,決定此刻該參考誰,總和為 1。
詳細說明
下一個 token 的機率,不是只看最後一個字。計算某個位置的表示時,模型用注意力(attention)看前文的 token。它對前文每個 token 算一個相關分數,經 softmax 變成總和為 1 的權重(第 15 篇),再依權重把各 token 的資訊加權平均。權重愈大,那個 token 對這個位置的貢獻愈多。
例句:「小明把書還給小華,因為他已經讀完了。」處理「他」時,「小明」應該拿到較高的權重。讀完書、把書還回去的是小明,不是收下書的小華。
自注意力讓每個位置在一步之內就能參考所有位置,所以可以平行訓練。循環神經網路(RNN,第 15 篇)則必須一步接一步。多頭注意力(multi-head attention)同時用好幾組注意力,各自捕捉不同關係。
注意力權重每次輸入都重新計算。模型參數在訓練結束後固定。兩者不是同一組數字。對話不會改寫參數,但每次輸入的注意力權重可以不同。
自注意力要比較每一對 token。長度是 n 時,計算量約與 n² 成正比。長度變成 2 倍,注意力計算約變成 2² = 4 倍。
脈絡窗口
一次能讀入的 token 有上限,超出窗口的內容模型看不到。
詳細說明
脈絡窗口(context window)是模型一次能讀入的最大 token 數。裡面包含系統指示、對話歷史、貼進來的文件,以及模型自己已經寫出的內容。這些部分共用同一個上限。
超過上限時,應用程式必須截斷或摘要。被截掉的內容,模型這一次看不到。對話很長時,開頭的訂單編號、地址或但書,就可能因此「被忘記」。
模型本身沒有跨對話的記憶。新對話裡看起來還記得上次的內容,是應用程式把過去的文字再放回這一次的脈絡,不是參數裡多了一段記憶。
取樣:貪婪解碼、溫度與 top-p
溫度調整機率分佈的尖平,top-p 先砍掉機率很低的尾巴。
詳細說明
從機率分佈挑出下一個 token,這個步驟叫取樣(sampling)。貪婪解碼(greedy decoding)每次取機率最高的那個。結果比較穩定,也比較容易重複同樣的句式。
溫度(temperature)寫成 T。做法是先把每個分數除以 T,再做 softmax。T < 1 時分佈更尖,輸出更保守、更一致。T > 1 時分佈更平,輸出更多樣,也更容易出錯。T 接近 0 時,行為接近貪婪解碼。
下面用兩個候選 token,分數是 2 與 1。softmax 先取指數,再除以這些指數的和。
- T = 1:分數仍是 2 與 1。e² ≈ 7.389,e¹ ≈ 2.718,相加 7.389 + 2.718 = 10.107。7.389 / 10.107 ≈ 0.731,2.718 / 10.107 ≈ 0.269。
- T = 0.5:分數變成 2 / 0.5 = 4,以及 1 / 0.5 = 2。e⁴ ≈ 54.598,e² ≈ 7.389,相加 54.598 + 7.389 = 61.987。54.598 / 61.987 ≈ 0.881,7.389 / 61.987 ≈ 0.119。高分候選的機率從 0.731 升到 0.881。
- T = 2:分數變成 2 / 2 = 1,以及 1 / 2 = 0.5。e¹ ≈ 2.718,e^0.5 ≈ 1.649,相加 2.718 + 1.649 = 4.367。2.718 / 4.367 ≈ 0.622,1.649 / 4.367 ≈ 0.378。兩個機率比 T = 1 時更接近。
同一組計算可以寫成程式。取指數前先減去這組分數的最大值,是為了避免數值過大;印出的三行與上面的機率一致。
import numpy as np
def softmax_t(scores, t):
z = np.array(scores) / t
e = np.exp(z - z.max())
return e / e.sum()
for t in (0.5, 1.0, 2.0):
print(t, softmax_t([2.0, 1.0], t).round(3))
# 0.5 [0.881 0.119]
# 1.0 [0.731 0.269]
# 2.0 [0.622 0.378]
Top-p(nucleus sampling)則先縮小候選集合。依機率由高到低累加,只在累積機率剛好達到 p 的最小候選集合裡抽,抽之前重新正規化,使這組機率再次加總為 1。
沿用「今天天氣很」,設 p = 0.8。「好」0.50 加「熱」0.30 = 0.80,剛好達到門檻,集合只有這兩個。「冷」0.15 與其他 0.05 不進入這一次的抽籤。重新計算:0.50 / 0.80 = 0.625,0.30 / 0.80 = 0.375。所以「好」被抽中的機率是 0.625,不是原來的 0.50。
幻覺與知識截止
模型只求接得順,不會自己查證;截止之後的事要靠檢索補上。
詳細說明
即使取樣很保守,模型仍可能說錯,而且語氣平穩。這種輸出叫幻覺(hallucination):內容通順、看似有把握,但錯誤,或沒有根據。服務可以正常把句子生成完,這不是當機。
原因回到生成目標。模型學的是「怎樣接才順」,不是「這句話已經查證」。訓練資料裡沒有、或很少出現的事,它仍會接出看似合理的內容,而且不一定會說「不知道」。
時間上還有一道界線,叫做知識截止(knowledge cutoff)。預訓練資料只收集到某個時間點,之後的事,參數裡沒有。除非用檢索或工具把新資料放進這一次的脈絡,否則模型讀不到上週才公布的規定。
降低幻覺,是把根據放進它這一次能讀到的範圍:用 RAG 提供可引用的資料(第 17 篇);要求附上出處,並由人查核;把回答範圍寫窄,並允許它回答「不知道」。溫度調低只減少隨機性,不保證內容正確。RAG 若檢索到錯誤的段落,模型仍可能照著那段文字答錯。
三、容易混淆的地方
下面六組差異,常常不會寫在回答的句子裡,而出現在用量、請求內容、設定與回報裡。
| 容易混淆 | 差別在哪 | 實際遇到時的線索 |
|---|---|---|
| token 與字或詞 | token 由分詞器切出,可以是一個常見單字,也可以是少見字的一段。中文常是一到兩個字。長度與計費看 token 數 | 同一段公告,頁面字數和介面回報的 token 用量對不上;帳單依 token 計 |
| 脈絡窗口與訓練資料 | 窗口是這一次請求能讀入的 token 上限。訓練資料是預訓練看過的文字,已經反映成參數裡的統計規律 | 超長對話的日誌出現截斷或摘要;開頭的訂單編號在後半段消失,新開短對話並重新貼上又答得出 |
| 溫度低與內容正確 | 溫度低只讓分佈更尖、用詞更穩定。內容對不對,取決於有沒有可依的根據 | 儀表板顯示溫度已經調低、每次用詞都很像,抽查仍看到錯誤的規格數字 |
| 注意力權重與模型參數 | 權重是這一次輸入重新計算、總和為 1 的係數。參數在訓練後固定,推論時不因對話改寫 | 程式審查裡改到的是 temperature 這類解碼設定;部署後的權重檔沒有被對話更新 |
| 預訓練規律與 RAG 放進脈絡的資料 | 預訓練把「什麼常接在後面」寫進參數,回答時不另查資料庫。RAG 是把可引用的資料放進這一次的窗口 | 請求紀錄裡看得到檢索段落被插入;沒有插入時,流暢的句子只是模型在接話 |
| 幻覺與程式錯誤 | 幻覺是生成機制的正常產物:句子通順、語氣肯定,內容錯誤或沒有根據。它不是當機,也不是 bug | 日誌沒有錯誤堆疊,請求成功返回;提出需求的同事拿到的卻是查無此文的論文,或已經作廢的規定 |
四、基礎練習
下面六則都是工作情境。先自己判斷,再展開解析。
第 1 題
某電商的文案團隊在檢查模型。目前前文是「今天天氣很」,下一個 token 的機率是「好」0.50、「熱」0.30、「冷」0.15、其他合計 0.05。取樣使用 top-p,p = 0.8。這一次「好」被選中的機率是多少?
- (A) 0.50,沿用「好」的原始機率,不重新正規化
- (B) 0.80,因為 p = 0.8 就是「好」被選中的機率
- (C) 0.625,只在達到門檻的候選裡重新正規化後抽取
- (D) 0.25,四個候選全部保留,平均分配機率
看答案與解析
答案:C
由高到低累加,「好」0.50 +「熱」0.30 = 0.80,剛好達到 p = 0.8,最小候選集合只有這兩個。「冷」0.15 與其他 0.05 被排除。抽之前重新正規化:0.50 / 0.80 = 0.625,0.30 / 0.80 = 0.375。所以「好」被選中的機率是 0.625。
- (A) 0.50 是縮小候選之前的原始機率;集合變成兩個之後必須重新正規化。
- (B) 0.80 是累積門檻,不是「好」這一個 token 的抽中機率。
- (D) top-p 不會把候選平均分配;它先依累積機率砍掉尾端,留下的候選再依原比例重新正規化。
第 2 題
某電商的客服對話已經很長。客戶第一句給了訂單編號,聊到最後,模型卻忘了這組編號,要求客戶再提供一次。比較合理的解釋是什麼?
- (A) 預訓練資料太舊,所以任何訂單編號都不可能被記得
- (B) 早先內容超出脈絡窗口,被截掉或被摘要掉;系統應保存關鍵資訊,並在後續請求重新放進脈絡
- (C) 溫度設得太低,模型過度保守,因此略過了訂單編號
- (D) 模型曾把編號學進參數,後來參數恢復原狀,所以又忘了
看答案與解析
答案:B
脈絡窗口有上限,系統指示、歷史、文件和模型已寫出的內容都算在裡面。超過上限時,應用程式會截斷或摘要,被拿掉的開頭細節模型就看不到。訂單編號這類欄位要由系統保存,需要時再放回脈絡。推論時參數固定,對話不會把編號寫進參數。
- (A) 訓練資料的新舊,解釋不了同一段對話裡前半出現過的編號為什麼後半消失。
- (C) 溫度影響的是下一個 token 有多隨機,不會專把前文裡的訂單編號刪掉。
- (D) 推論時參數不會因這段對話改變,沒有「寫進參數又忘掉」這一步。
第 3 題
某團隊要用模型產生商品規格說明,希望每次輸出盡量穩定、用詞一致,也知道穩定本身不等於數字正確。比較合適的做法是什麼?
- (A) 把溫度調高,讓措辭更有變化,規格就會收斂
- (B) 把 top-p 設為 1,候選愈齊全,輸出愈固定
- (C) 加大脈絡窗口,窗口愈大,就愈會每次寫出同一段
- (D) 調低溫度,或改用貪婪解碼;這只降低隨機性,不保證內容正確
看答案與解析
答案:D
T < 1 時分佈更尖,貪婪解碼則每次取機率最高的 token,輸出會更一致。T 接近 0 時也接近貪婪解碼。這樣做只減少隨機性。規格裡的數字仍要有資料來源,並由人查核。
- (A) 把溫度調高會讓分佈更平,輸出更多樣,也更容易出錯,和穩定一致相反。
- (B) top-p 設為 1 時,累積範圍涵蓋整個分佈,尾端候選仍留在抽籤裡,輸出不會因此固定。
- (C) 加大脈絡窗口只提高一次能讀入的 token 上限,不改變每次如何從分佈裡挑 token。
第 4 題
某醫院的讀書會用模型整理文獻。回答裡列出一篇論文,篇名、作者與期刊看起來都像真的,同仁在館藏和公開索引卻查不到。比較恰當的判斷是什麼?
- (A) 這是幻覺:生成目標是接得順,不是查證。應改用 RAG 提供文獻資料,要求附上出處,並由人查核
- (B) 一定是模型被駭,否則不會寫出不存在的論文
- (C) 把溫度調到 0,就保證不再寫出查無此文的論文
- (D) 模型內建的論文資料庫壞了,所以這一篇對不上
看答案與解析
答案:A
通順、看似有把握、卻沒有根據的內容,就是幻覺。訓練資料裡沒有這一篇時,模型仍可能接出像論文的文字,而且不一定會說不知道。可行的做法是用 RAG 把可引用的文獻放進脈絡(第 17 篇),要求附出處,再人工查核。RAG 若檢索到錯誤段落,仍可能答錯,所以查核不能省。
- (B) 幻覺是生成機制的正常產物,不是必須被駭才會出現。
- (C) 溫度接近 0 只是接近貪婪解碼,減少隨機性,不保證內容正確。
- (D) 模型回答時不是在查一個資料庫;事實知識是下一個 token 統計規律的副產品,沒有一份會單獨壞掉的內建論文資料庫。
第 5 題
某工廠把巡檢紀錄送進模型做摘要。同一次自注意力的輸入,從 2,000 個 token 增加到 8,000 個 token。自注意力的計算量大約變成幾倍?
- (A) 約 2 倍
- (B) 約 4 倍,因為長度變成 4 倍,計算量與長度成正比
- (C) 約 16 倍
- (D) 大致不變
看答案與解析
答案:C
自注意力要比較每一對 token,長度 n 的計算量約與 n² 成正比。長度比是 8,000 / 2,000 = 4。計算量約變成 4² = 16 倍。
- (A) 2 倍既不是這次的長度比,也不是長度比再平方的結果。
- (B) 4 倍只等於 8,000 / 2,000,漏了平方;計算量不是與長度成正比。
- (D) 長度增加時,要比較的 token 配對跟著增加,計算量不會維持不變。
第 6 題
某公司上週公布了新的請假規定。員工詢問內部問答模型,得到的卻是舊規定。比較合理的原因與處理是什麼?
- (A) 脈絡窗口太小,所以上週的規定放不進去
- (B) 知識截止:預訓練資料不包含上週的公告。應用程式應用 RAG 或工具,把最新文件放進脈絡
- (C) 溫度太高,模型隨機把新規定寫成了舊規定
- (D) 把同一問話多問幾次,模型就會在對話中學會新規定並寫進參數
看答案與解析
答案:B
知識截止表示預訓練資料只到某個時間點。上週的公告在那之後,參數裡沒有這份新規定。用 RAG 或工具把最新文件放進這一次的脈絡,模型才讀得到。推論時參數不會因問答而更新。
- (A) 窗口太小,影響的是已經放進這一次請求的文字會不會被截掉;這裡是新規定尚未進入預訓練,也還沒被放進脈絡。
- (C) 溫度調高只讓取樣更多樣,不會把一份模型沒讀到的新規定穩定地改寫成舊版。
- (D) 多問幾次只是重複生成。對話中的新規定不會寫回參數,模型也不會因此學會它。
五、重點回顧
- 自迴歸生成是一次預測一個 token:讀入目前所有 token,在詞彙表上得到下一個 token 的機率,抽出一個接上,再把新的整段讀進去,直到結束。
- token 由分詞器決定,不一定是一個字或一個詞;長度上限與計費都以 token 計。每個 token 先對到一個嵌入向量。
- 注意力用總和為 1 的 softmax 權重,把前文資訊做加權平均;權重每次輸入都重算。自注意力的計算量約與長度的平方成正比。推論時參數固定。
- 脈絡窗口是一次能讀入的最大 token 數,含系統指示、對話歷史、貼上的文件與模型已寫出的內容。超出的部分會被截斷或摘要;跨對話還能接著說,是應用程式把舊內容再放回脈絡。
- 溫度先把分數除以 T 再做 softmax。T < 1 更保守一致,T > 1 更多樣也更容易出錯,T 接近 0 時接近貪婪解碼。top-p 只在累積機率達到 p 的最小集合裡抽,並先重新正規化。
- 幻覺是通順但錯誤或沒有根據的輸出,因為目標是接得順;知識截止之後的事,參數裡也沒有。降低做法是 RAG、附出處、限制範圍、允許回答「不知道」,並由人查核。溫度調低不保證正確,RAG 檢索到錯的段落也會答錯。