為什麼大模型連“Strawberry”的“r”都數不對?

阿里妹導讀
本文將從兩個常見的大模型翻車問題入手解析這些問題背後體現的大模型技術原理,並解釋了為什麼會導致這些問題,接著我們利用CoT(思維鏈)方法解決這些問題並基於上述原理試圖剖析CoT方法起作用的可能原因,最後提出【理由先行】風格這一簡單有效的Prompt Trick。
Way To Prompt系列
作為大模型落地相關的演算法工程師,隨著大模型能力的快速發展,Prompt工程成為了越發重要的一項技能。
在2023年下半年,我們遵循著Prompt調優—微調訓練調優的方式進行著大模型落地的探索,也探索出了RAG/NL2SQL等多種較為適合大模型落地的場景;而到了2024年上半年,Agent從概念逐漸演變成了切實可行的落地場景,而在通用大模型能力的不斷突破下,微調調優在算力、時間、精力上的重投入顯得更不討喜,尤其是大部分專案仍處於需要快速驗證想法的POC階段,由此我們改換成了Prompt調優—Agent工作流搭建的方式,可以迅速驗證大模型在各行各業場景的效果。
顯然,無論處於哪個階段,Prompt工程都將是最初也最為重要的一個步驟,Prompt是你與大模型之間溝通的唯一橋樑,也是大模型帶領你雲遊四海的船票。
所以,我想開設一個專題【Way To Prompt】,用於記錄前沿學習、專案實踐過程中接觸到的Prompt方法、結構化框架以及各類Tricks,梳理各類在實際業務中可以發揮價值的Prompt及其背後的生效原理。
引言
本文簡述:本文將從兩個常見的大模型翻車問題入手解析這些問題背後體現的大模型技術原理(Tokenization與預測下一個Token),並解釋了為什麼會導致這些問題,接著我們利用CoT(思維鏈)方法解決這些問題並基於上述原理試圖剖析CoT方法起作用的可能原因,最後提出【理由先行】風格這一簡單有效的Prompt Trick。
前段時間,我們經常能在網際網路上看到有關大模型“翻車”的常見問題,其中最為典型的莫過於“Strawberry有幾個r數不對”以及“9.9和9.11比大小”。
這些問題一度引發了網際網路上大模型社群的廣泛討論,大家一定很好奇,為什麼大模型可以完成個別複雜的推理任務,甚至可以在數學、法律等各類行業的高等級考試中獲得優異成績,卻在如此簡單的問題上接連翻車呢?
那麼本篇文章便試著從這一角度入手,理解大模型為什麼在該類任務上的表現不佳,以及基於這一原因所引發的思考與更適合的Prompt實踐方式。
首先,我們來驗證大模型是否真的無法解決上述的兩個問題:
Strawberry裡有幾個r?
通義千問:
GPT-4o:
Claude3 Sonnet:
可以看到,截止到目前三者之間僅有Claude3回答正確,而GPT-4o和千問依舊無法數對r的數量,並且千問的解釋也很奇怪,它明明可以看到rr裡面有兩個r,為什麼卻數不對呢?
並且值得一提的是,測試Claude3.5 Sonnet時我們發現它也數不對。
9.9和9.11誰大?
通義千問:
GPT-4o:
Claude3 Sonnet:
上一個問題Claude3答對了,而這個問題則是無一例外地全部翻車,那麼大模型究竟為什麼無法解決這些對於人類來說如此簡單的問題呢?
大模型做不到,原因是什麼?
這兩類大模型會“犯蠢”的問題背後,實際上是大模型的技術原理天然帶來的“副作用”,比如我們先從“Strawberry有幾個r數不對”這一問題入手。
Tokenization
大家對這件事的普遍定論是,這是文字的Tokenization處理所帶來的問題。
所謂的Tokenization,即是將文字處理為Token的過程,很多時候也翻譯為“分詞”,不過需要注意的是,“分詞”這一翻譯本身具有一定的誤導性,這裡分好的“詞”並不能直接對應我們“人類視角”的【單詞/短語/片語】,而是“大模型視角”的【Token】,這一部分我會基於之前內部培訓時我所製作的PPT進行說明。
由於大模型無法直接處理文字,因此需要將文字轉化為大模型可以處理的數字,轉換過程可以簡化為以下幾步:輸入文字序列,對序列進行切分成為Token序列,再構建詞典將每個Token對映為整數型的index。
這一過程中,主要的難點在於,如何理想地對文字序列進行切分。如果我們切分的粒度太細,比如水果被切分為水和果,那麼水果這一詞語在大模型眼裡就喪失了其作為一個詞語的整體語義。如果我們切分的粒度太粗,比如我喜歡吃水果整體是一個token,那麼這樣切分所得到的字典規模可想而知是相當大的。所以一個好的切分應該是,使得文字中的每個Token都擁有正確的表義,且不會存在字典容易過大或在字典中找不到相應token的問題。
根據以上描述可知,“大模型視角”下的文字與我們“人類視角”並不一樣。為了驗證這一點,我們可以在DashScope提供的Token計算器頁面觀察“大模型視角”下的文字是如何拆解的。
以Strawberry為例,其被拆分為【“str”, “aw”, “berry”】,自然也就不難理解為什麼通義千問對於這個問題的回答是“兩個r”了,畢竟對於它來說,這三者均是作為一個整體存在的,而不是從字母維度切分的。
為了讓人們更好地理解“大模型視角”與“人類視角”之間的差異,前OpenAI創始成員與研究科學家Karpathy在X上放出了一個指令碼,用於將Token轉換為Emoji表情,從而更加直觀地向大家展示大模型眼中的文字是什麼樣的。
(指令碼網址:https://x.com/karpathy/status/1816637781659254908
這裡依舊以“Strawberry裡有幾個r?”問題為例,可以看到在大模型的眼中,這個問題其實是這樣的:
“數r”這一問題從人類視角顯而易見,但在大模型視角卻是有難度的。由此也就很容易理解,為什麼大模型在缺乏引導的情況下無法完成“數r”這種對於人類來說無比簡單的任務。
而另一個比大小問題,我們則要從大模型的生成原理角度去考慮。
預測下一個Token
我們知道,大模型(Large Language Model,LLM)的含義為大型語言模型。
“大型”很好理解,而所謂的“語言模型”,也就是用於計算文字序列機率的模型,更通俗地說,用於計算一個文字序列是一句“人話”的機率。那麼換個角度來說,“語言模型”也就可以在給定上文的情況下,計算下一個Token取各種值的機率,所以大模型的生成過程本質上便是在“根據上文預測下一個Token”,而這個機率分佈即是在模型訓練過程中從大量的文字資料中學習到的,使得大模型學習到了語言的基本知識與模式。
在理解上述原理的基礎上,“9.9和9.11比大小”翻車的原因也就容易理解了,若是訓練時存在著許多版本號相關的資料,那麼從版本號的角度來看,9.11確實要比9.9大,大模型也就很可能會根據這種機率分佈得出“9.11比9.9要更大”的結論。
利用CoT解決問題
其實解決這兩類問題的方法也並不複雜,只需要在Prompt中加入一定的引導就能獲得理想答案,比如說我們可以利用CoT思維鏈的方式編寫Prompt,引導大模型逐步思考並解決問題。
CoT為思維鏈(Chain-of-Thought)的縮寫簡稱,是提示工程領域最為重要的提示方法之一,它的核心思路在於透過引導模型逐步展示其推理過程,從而提高其理解和解決複雜問題的能力。在Few-shot(少樣本)設定下表現為 在提供的樣例中解釋推理過程,引導大模型回答時也解釋推理過程;而在Zero-shot(零樣本)設定下表現為 加入類似“讓我們一步步思考(Let’s think step by step)”的引導話術。
而對於本文提到的兩個翻車問題,我們可以嘗試這樣編寫Prompt:
Strawberry裡有幾個r?請你先將單詞拆分成一個個字母,再用01分別標記字母列表中非r和r的位置,數一下一共有幾個r
請一步步思考,以逐級複雜的原則思考問題,最後才得到答案。9.99.11誰大?
可以看到,透過CoT方法編寫Prompt後,可以引導大模型輸出正確結果。
有趣的是,第二個問題的Prompt雖然可以幫助大模型獲得正確的結果,但卻不是始終有效的,多次嘗試很可能會獲得不同的結論。而將“9.9和9.11誰大?”切換成英文的“9.11 and 9.9, which is bigger?”時大模型更容易答對,這裡本質上也體現了中英文訓練資料的差別對機率分佈的影響以及大模型預測下一個Token是一個取樣過程。
然而隨之而來的問題是,為什麼這麼做可以提升大模型的表現呢?這個問題想必大家也十分好奇,基於上面所述的大模型原理,其實也不難理解。
如果說,大模型每一次生成是在“根據上文預測下一個Token”的話,那麼CoT的作用便在於,它可以引導大模型先行生成有力的推理過程,比如引導其生成Strawberry拆解後的字母列表,或者數字的逐位比較,這樣模型在生成最終結論的時候,會受到上文推理過程的影響,將下一個Token的機率分佈限定在某個範圍內,從而大大增加輸出正確答案的機率。
可以將該過程想象成下圖:
試想,當你遇到一個問題,隨著你的不斷思考,你為獲得正確答案建立了更多的“論據”,從而不斷地增加你對某一個答案的置信度;而這與你直接在腦中海量的答案池中進行一次選擇或預測相比顯然要更加可靠。
而若是不用CoT加以限制的的情況下,大模型傾向於先給出一個答案,再給出理由,那麼很自然地變成了,先根據“問題”預測一個最有可能的“答案”,再為這個“答案”編造相應的“理由”,畢竟大模型的生成過程是逐步進行的,而不是全域性性的,它在答案之後輸出的理由永遠只可能是為了圓“答案”這個謊而存在的。
這是人類語言的重要特性,也即時序性與線性,說到這不禁讓我想到電影《降臨》中生活在四維空間的七肢桶,它們的“字”是一筆寫就的,包含一段完整的語義,前因後果均包含在這一個“字”內,也就不像人類的文字一般帶有前與後的時序屬性,而我們的語言方式天然蘊含著邏輯與時序關係,這一點在大模型身上也會有所體現。同時,我們人類在思考的時候,通常也是會先有推理過程,再有結論,只不過在訴諸於語言時,可能會選擇 先丟擲結論表明立場,再給出解釋 的表達方式,而思考過程對外界是不可見的,但是對於大模型而言,它的語言本身即是思考,並不存在訴諸於語言之前的思考過程,所以我們也需要引導它像人類一樣先思考再判斷,將思考過程以語言的方式表達出來。
迴歸正題,從這個角度來看很自然地可以想到,在大模型推理的時候,我們可以限制大模型 先輸出理由,再輸出答案,讓大模型根據“深度思考”獲得的理由與推理過程來預測“答案”,從而大大提升其表現,我認為這也是為什麼CoT會有效果的一個關鍵因素。
與這一想法不謀而合的是,東京大學的一項研究《A Better LLM Evaluator for Text Generation: The Impact of Prompt Output Sequencing and Optimization》中也驗證了類似的觀點,這篇論文的理念為利用大模型評估AI的生成文字質量,而在論文的實驗部分他們發現,要求大模型先給出評分理由,再給出分數 與 要求大模型先給出分數,再給出評分理由兩種做法的結果大不相同,前者所給出的分數普遍高於後者,他們認為這與LLM的自迴歸生成特性有關,當模型先給出理由時,它能夠更全面地考慮輸入的提示和自己生成的理由,從而做出更加深思熟慮的評分。
換句話說,“理由先行”的輸出風格或許有助於大模型給出更加可靠的答案,這一點與我們之前的推論也相吻合,符合大模型預測下一個Token的原理。
基於以上原因,我在實際的專案實踐當中,也廣泛採用了“理由先行”的輸出風格,比如下方的Prompt是我為某個物流行業公司的業務場景所編寫的,該場景實測發現,“理由先行”的方式確實更有助於大模型更有效地進行思考與預測,取得更優異的表現。
Qwen-Max/Plus預設引數Prompt
ori_system_prompt = dedent("""\ # 角色 你是一位高效的物流分配專家,擅長根據客戶提供的地址資訊,精確匹配至相應的地址分組,具備快速識別地址模式與分組規則對應的能力。 ## 技能 ### 技能1: 地址匹配邏輯 - **提供訂單分組時的分組判斷**:當訂單分組和簽收分組同時提供時,請對比客戶地址與兩個分組中的每個地址記錄,尋找完全匹配或最接近匹配的條目,判斷客戶地址更可能屬於哪個分組,若不屬於任一分組則判斷為“無”; - **未提供訂單分組時的分組判斷**:若訂單分組未給定,請對比客戶地址與簽收分組中的每個地址記錄,判斷客戶地址是否屬於該簽收分組,若不屬於則判斷為“無”; - **輸出判斷置信度**:當你給出一個判斷時,請你根據你對該判斷的確定程度給出一個置信度,置信度的範圍為[0,1]; ### 技能2: 結構化輸出處理 - 根據分組判斷,**請解釋你的推理過程,並以JSON格式輸出對應的分組名稱以及該判斷的置信度** ## 約束 - 請以JSON格式返回分組名稱,示例為```json{"group_name": "***", "confidence": "***"}```。 - 分組判斷嚴格基於地址文字的匹配,不考慮地理臨近性。 - 忽略地址中的無關細節,如門牌號差異,專注於街道、社群等關鍵資訊匹配。 - 若客戶地址同時與訂單分組和簽收分組較為接近,請分別分析訂單分組與簽收分組中地址的主要特點,基於這些特點判斷客戶地址最可能屬於哪一分組。 ## 輸入輸出樣例: 客戶地址: [客戶地址] 訂單分組: [分組名稱] [地址示例] 簽收分組: [分組名稱] [地址示例] 輸出: **我的推理過程是:** 對訂單分組中的地址分析可知... 因此,分組結果為```json{"group_name": "[分組名稱]", "confidence": "[置信度]"}``` 現在,請根據以上規則判斷以下客戶地址的分組情況。""")
可以看到,我對大模型強調“請解釋你的推理過程,並以JSON格式輸出對應的分組名稱以及該判斷的置信度”,並在示例處讓其先輸出“我的推理過程是:”,從而保證讓其先輸出推理過程以及充足的判斷理由,再輸出最終的JSON答案。
當然,這只是一種實現思路,只要掌握該思想,可以透過各種方式融入到自己的業務Prompt當中。
建議大家在Prompt的編寫與調優過程當中,也可以試著踐行“理由先行”的風格,讓大模型先輸出判斷的理由,再輸出最終的答案,防止模型陷入瞎編答案再圓謊的惡性迴圈當中,或許會有奇效。
以上,即為本篇文章的全部內容,感謝您的耐心閱讀!

參考

文章原始思路源於機器之心文章,在此基礎上進一步聯想深挖,將【預測下一個Token、CoT、理由先行】等概念串聯起來。主要參考文獻如下:
https://arxiv.org/html/2406.09972v1


相關文章