Day 01 稍微介紹大型語言模型和 reasoning model,接著我們可以進一步去思考的是:如果推理模型終究還是在預測下一個 token,我們要怎麼知道它真的變得比較會解題,而不是學會把答案寫得更長、在句子裡多放幾個「首先」和「所以」,看起來很像正在動腦而已?
讓我們來跑一個小實驗,使用的是 Qwen/Qwen3-0.6B-Base,一個只經過預訓練、還沒有被教成聊天助理的 Base model。我不把把問題包裝成一段對話,也沒有要求它扮演任何角色,只是讓它直接續寫下面這句話:
The answer to 2 + 3 is
這個小學程度的問題,對模型來說並非看到九個單字,而是九個 token。空白有時跟著後面的英文一起被編碼,有時又自己成為一個 token,所以實際切開後會長成這樣:
['The', ' answer', ' to', ' ', '2', ' +', ' ', '3', ' is']
雖然現代主流模型已經不使用這個方法,不過為了方便說明,我這裡還是使用 greedy decoding,每一步都直接選機率最高的 token。我們先排除抽樣的隨機性,讓相同的模型和句子每次沿著同一條路走;程式雖然會記下前五名候選,但不會從中隨機抽一個。等後面真的要比較多種解法時,我們才會故意讓模型走不同的路。
把逐 token 生成縮到最小,大概就是下面這幾行:
outputs = model(input_ids=generated)
next_logits = outputs.logits[:, -1, :]
probabilities = torch.softmax(next_logits, dim=-1)
top_probabilities, top_token_ids = torch.topk(
probabilities, k=5, dim=-1
)
next_token = top_token_ids[:, :1]
generated = torch.cat([generated, next_token], dim=1)
模型先替所有可能的下一個 token 打分數,再把分數轉成機率;torch.topk 找出前五名,排在第一名的 token 會被接回原句,成為下一輪輸入的一部分。現在常用的函式庫可以替我們完成整段生成,不過把這個循環攤開來看,會比較容易理解模型所謂的「回答」是怎麼一小塊一小塊長出來的。
我實際跑出的前四步如下,每一列都是模型在那一步選中的 token,以及它替這個選擇分配的機率:
step selected token probability
1 ' ' 63.19%
2 '5' 56.25%
3 '.' 37.69%
4 ' What' 13.28%
模型在第二步選中了正確答案 5,機率大約是 56%;排在第二名的 4 還不到 10%。看到這裡似乎一切都很好,如果我現在立刻截圖,把後面的輸出裁掉,甚至可以寫成「Qwen3 0.6B 已成功解出算術題」。偏偏模型並沒有在 5 停下來,它接著寫出的是:
5. What is the answer to 2 +
它先把句子補成正確答案,然後又開始寫下一道題目,最後停在一個還沒寫完的加號後面。這並不神奇,Base model 接到的工作本來就是續寫文字;它沒有經過那種教它遵守聊天指令的後訓練,我也沒要求它答完就停。對此刻的模型來說,接著生出另一道題並沒有做錯事,只是它做的事情和我們以為自己問的問題不太一樣。所以我們知道了:模型確實把 5 排在第一名,也確實在答案後繼續生成另一個問題。至於這算不算推理能力,還得先約定怎樣算答對,再拿一批事先保留的題目好好檢查。
候選機率和生成文字都是我們看得到的結果,卻不是模型腦中逐字浮現的想法。就算未來的模型輸出一整段漂亮的推導,那段推導仍然是生成出來的文字,不會自動成為內部機制的忠實轉錄。至於這次正確補出 5,它也不代表模型變好了,因為我們今天根本沒有訓練任何東西。
想自己試一次,可以把句子改成 The answer to 7 + 8 is,在執行前先猜模型會選到什麼,再比較第一名和第二名差多少。如果開頭真的答對,可以繼續讓它把後面的句子寫完,看看模型還會輸出什麼有趣的細節。
這篇大致位於 Sebastian Raschka 原書前兩章之間:第一章先介紹 reasoning model 是什麼,第二章便開始讓預訓練完成的 Qwen3 生成文字,我僅是多把每一步的候選機率攤開,方便後面比較不同的生成方法。原書官方 repository可以看到完整安排;Qwen 官方文件則明確提醒,thinking mode 應該使用 sampling,也就是帶有 temperature、top-p、top-k 等設定的,greedy 可能讓表現下降或不斷重複。所以 Day 02 使用的 greedy 只是為了方便我們觀察生成路徑,卻不是推理模型的日常設定,甚至以目前最強的開源模型 Kimi K3 來說,它已經預設好如何取樣,使用者只需調整 reasoning_effort 是 low、high 或者 max。
明天會把這個 Base model 和經過後訓練的 Qwen3 放在一起比較,觀察若提問相近的問題,模型的回答又會是如何,會否像 chatbot 型助理,或者會否先寫出一段推導。