第5章 復雜推理——像人類一樣思考
第5章 復雜推理——讓大模型更加像人一樣思考
??在之前的章節中,我們學習了如何使用大型語言模型來處理自然語言理解和文本生成任務。目前的大型語言模型已經能夠輕松應對日常任務,但當任務的復雜度超過一定閾值時,這些模型可能無法勝任。本章將在現有任務的基礎上,探討如何讓大型模型更好地處理復雜推理任務。復雜推理是一個全新且備受關注的方向,它可以使大型語言模型在各種情況下都能夠有效地處理任務,從而可能改變人機交互方式,重塑整個計算機生態。
??思考是人類特有的能力,它是奠定人類繁榮文明基石的關鍵。而在思考過程中,推理是最為復雜的一種形式,具備一定的規則和邏輯性,以形式上的規范和嚴謹為特點。只有讓大型語言模型具備思考和推理的能力,才能真正釋放其潛力。復雜推理作為大型模型所特有的能力,是其與小型模型真正的區別所在。
??本章節主要探討的是對現有大模型在復雜推理任務中的能力進行發現和應用,而不是關于構建具備強大復雜推理能力的模型的過程。在本章中,我們將探討和介紹一系列技術和方法,主要研究如何激發和改善大型模型的復雜推理能力,以提升其在復雜推理任務中的表現和能力。
5.1 什么是復雜推理?
??復雜推理是指在處理復雜問題時運用邏輯、推斷和推理能力,從已知信息中得出新的結論或解決問題的過程。它涉及對多個變量、關系和條件進行考慮和分析,并會使用邏輯、歸納、演繹等思維方式進行推斷和推理。復雜推理通常需要綜合不同的信息源,進行推理鏈的構建,以推導出更深層次的關聯和推斷結果。這種推理過程常見于解決復雜的問題、推斷未知信息或處理抽象概念的情況下,需要高級思維能力和推理技巧。以下是一些常見的思維技巧和方法。
-
邏輯推理:運用邏輯規則和關系來推斷和推理信息。包括演繹推理(從一般原理推導出特定結論)和歸納推理(從特定案例推導出一般原理)。
-
分析和綜合:將問題分解成更小的部分,對每個部分進行分析,并最終綜合各個部分的結果以得出整體結論。
-
比較和對比:將不同的選項、觀點或解決方案進行比較和對比,以確定它們之間的相似性、差異性和優劣勢。
-
推斷和假設:基于已知信息進行推斷,并根據可能性進行假設,以推導出缺失或未知的信息。
-
反向推理:從所需的結論或目標出發,逆向思考并推導出達到該結論或目標所需要的前提條件或步驟。
-
模式識別和歸納:尋找模式、趨勢或共性,并基于這些發現進行歸納推理,以推斷未知情況或擴展到新的情境。
-
問題解決策略:運用各種問題解決技巧,如分析圖表、制定假設、進行試錯等,以解決復雜問題。
-
反思和調整:對推理過程進行反思和調整,檢查和修正可能存在的偏見、錯誤或不完整的推理。
??以前,我們通常認為復雜推理是人類的專屬能力,但是隨著現代人工智能和機器學習技術的發展,我們發現人工智能在復雜推理任務中展現出了巨大的潛力。特別是大型語言模型誕生和與之伴隨的涌現能力被發現后,我們發現大型語言模型對復雜任務的理解和推理能力異常卓越,超出以往的想象?,F在,大模型的復雜推理能力正受到越來越多的研究者的關注,在 GPT-4 發布博客中,作者這樣寫道:“In a casual conversation, the distinction between GPT-3.5 and GPT-4 can be subtle. The difference comes out when the complexity of the task reaches a sufficient threshold—GPT-4 is more reliable, creative, and able to handle much more nuanced instructions than GPT-3.5.”中文意思是:“在一次隨意的對話中,GPT-3.5和GPT-4之間的區別可能不太明顯。當任務的復雜性達到足夠的閾值時,差異就會顯現出來——GPT-4比GPT-3.5更可靠、更有創造力,能夠處理比GPT-3.5更加微妙的指令?!?/p>
??此外,獲得一個具有強大復雜推理能力的模型,對于未來進行下游任務的適配有著非常積極的作用。盡管目前人工智能在復雜推理方面取得了不錯的進展,但仍然和人存在很大的差距,特別是在以下幾個方面人類仍然具備獨特的優勢:理解和處理模糊性、深層次理解、創造性思維、具體領域知識、倫理和價值判斷等。
??雖然人工智能在復雜推理任務中存在一些局限性,但相信隨著技術的不斷發展和研究的深入,人工智能在這方面的能力有望持續得到提升。我們期待更多研究者和愛好者能夠參與進來,共同探索克服這些局限性,使機器能夠更好地模擬和執行復雜推理過程,讓人工智能更接近人類的思考能力。
??目前,學術界和工業界都集中在開發具有強大、復雜推理能力的模型,這是一個快速發展的領域,需要大量算力和資源。開發一個大模型對于一般用戶和開發者來說難以承擔,相反如何更好地利用現有大模型進行復雜推理相對來說就要友好地多。因此,本文更關注用戶和開發者如何利用現有的大模型,激活其中的復雜推理能力,以進一步推動開發和應用的進展。通過充分利用現有模型的潛力,在現有基礎上進行創新和改進,為各領域帶來更多的實際應用和解決方案。
5.2 復雜推理能力的激活和改善
??在討論如何激活和改善大型語言模型的復雜推理能力之前,我們首先需要對大型語言模型的推理能力有一個初步的了解。為此,筆者選擇了幾個經典的推理問題,并對ChatGPT進行測試,以初步評估其能力。
5.2.1 初步評估ChatGPT推理能力
??問題1:演繹推理。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "大前提:人類都是凡人 \n \
小前提:蘇格拉底是人 \n \
結論:"},
],
temperature=0,
)
print(response["choices"][0]["message"]["content"])
??ChatGPT輸出:
蘇格拉底是凡人。
??可以看到ChatGPT能夠根據提供的前提和問題,給出相應的結論或回答。
??問題2:歸納推理。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "西瓜是甜的,香瓜是甜的,所以叫“瓜”的蔬果都應該 \n \
結論:"},
],
temperature=0,
)
print(response["choices"][0]["message"]["content"])
??ChatGPT輸出:
都是甜的。
??問題3:歸納推理。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "6, 9, 12, 15, ? \n \
結論:"},
],
temperature=0,
)
print(response["choices"][0]["message"]["content"])
??ChatGPT輸出:
18。
??問題4:溯因推理。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "大前提:罐子里裝滿了黃色的彈珠 \n \
小前提:鮑勃手里有一顆黃色的彈珠 \n \
問題:鮑勃手里的彈珠來自哪里?"},
],
temperature=0,
)
print(response["choices"][0]["message"]["content"])
??ChatGPT輸出:
無法確定,因為罐子里裝滿了黃色的彈珠,鮑勃手里的黃色彈珠可能來自罐子里,也可能來自其他地方。
??綜上所述,ChatGPT在這些對話交互中展示了一定的推理能力,并能根據提供的信息給出合理的回答或結論。然而,需要注意的是,ChatGPT的回答受到模型的限制,在某些情況下可能存在錯誤或不完整的回答。
5.2.2 復雜推理能力的激活
??思維鏈(chain-of-thought,CoT)是一系列有邏輯關系的思考步驟,形成完整的思考過程。通過一系列相關問題或句子的提示,我們可以逐步引導大型語言模型進行連貫的推理和推斷。這種鏈式思維提示激發了模型的推理能力,在給定上下文中實現連續思考和推論。它幫助模型填補空缺、回答問題,并在復雜推理任務(如邏輯推理、因果推斷、條件推理)中生成準確、連貫的輸出,展示出強大的推理和理解能力。思維鏈是一種引導大型語言模型進行連貫推理和推斷的方法,揭示了大模型在復雜任務中的優越性和涌現能力。
??GSM8K數據集最初由OpenAI于2021年10月提出,由8.5K高質量的小學數學問題組成,這些問題都是由人類寫手創造的。當時,OpenAI使用第一版GPT-3模型,在整個訓練集上進行了微調,準確率約為35%。這個結果讓作者感到相當悲觀,因為它顯示了語言模型受到縮放規律的約束:隨著模型大小呈指數增長,性能呈線性增長。因此,在論文中他們提出了以下思考:“175B模型似乎需要至少額外兩個數量級的訓練數據才能達到 80%的求解率。”
??在2022年1月,Wei et al.(2022)利用參數規模為540B的PaLM模型,僅僅使用8個思維鏈提示示例,就將準確率從原始的18%提高到了56.6%,無需增加訓練集的規模。隨后,在2022年3月,Wang et al.(2022)使用相同的540B PaLM模型,通過多數投票的方法將準確率提升至74.4%。進一步,在2022年11月,Fu et al.(2022)利用復雜思維鏈技術,在參數規模為175B的Codex上實現了82.9%的準確率。從這些進展中可以看到技術的突飛猛進。
??有些讀者可能認為模型只能解決小學數學問題,這可能不足以代表什么(從某種意義上說,他們確實沒有那么酷)。然而,GSM8K只是一個起點,最近的研究已經將前沿問題推向了高中、大學甚至國際數學奧林匹克競賽問題?,F在,是不是開始變得酷起來了呢?接下來,我將詳細介紹這些技術。
1. 思維鏈提示激活推理能力
??Wei et al.(2022)首次提出利用思維鏈(CoT)激活大型語言的推理能力。思維鏈是什么樣子的呢?參考圖5-1,這里給出了思維鏈提示和標準提示之間的對比。和傳統的標準提示相比,思維鏈提示需要在樣例的回答中加入一個逐步思維的過程。

??此外,他們還發現當使用思維鏈進行提示時,隨著模型規模增大存在一個相變現象,如圖 5.2 所示。這進一步導致后面涌現能力的發現。思維鏈提示是展示模型規模擴大后出現涌現能力的典型案例,從圖5.2 中我們可以看到:當模型規模較小時精度幾乎沒有變化,但當模型規模很大時,提升非常明顯。這十分清晰的說明了,某些能力可能不存在于小模型中,而只在大模型中可以獲取。

??通過下面這個奇偶數統計例的子,讀者可以進一步感受思維鏈的魅力。
??首先是標準提示,如下所示。
# 標準提示
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "在這些數字3、56、35、96、40、10、84、923、32、20 中,有多少個奇數,多少個偶數?"},
],
temperature=0,
)
print(response["choices"][0]["message"]["content"])
??ChatGPT輸出:
奇數有4個:3、35、96、923。
偶數有6個:56、40、10、84、32、20。
??正確答案是:3個奇數,7個偶數。這里不知道為什么ChatGPT把96也當成是奇數了,可能覺得96和3相關,其他和三相關的都是奇數,所以把它也列為奇數了?
??現在來看看思維鏈提示的效果,如下所示。
# 思維鏈提示
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "在這些數字 38、31、89、224中,有多少個奇數,多少個偶數?."},
{"role": "assistant", "content": "我們一個一個數:\n \
1. 38是偶數,此時累計:偶數1個,奇數0個; \n \
2. 31是奇數,此時累計:偶數1個,奇數1個; \n \
3. 89是奇數,此時累計:偶數1個,奇數2; \n \
4. 224是偶數,此時累計:偶數2個,奇數2個; \n \
所以,一共有2個偶數,2個奇數。"},
{"role": "user", "content": "在這些數字3、56、35、96、40、10、84、923、32、20 中,有多少個奇數,多少個偶數?"},
],
temperature=0,
)
print(response["choices"][0]["message"]["content"])
??ChatGPT輸出:
我們一個一個數:
1. 3是奇數,此時累計:偶數0個,奇數1個;
2. 56是偶數,此時累計:偶數1個,奇數1個;
3. 35是奇數,此時累計:偶數1個,奇數2個;
4. 96是偶數,此時累計:偶數2個,奇數2個;
5. 40是偶數,此時累計:偶數3個,奇數2個;
6. 10是偶數,此時累計:偶數4個,奇數2個;
7. 84是偶數,此時累計:偶數5個,奇數2個;
8. 923是奇數,此時累計:偶數5個,奇數3個;
9. 32是偶數,此時累計:偶數6個,奇數3個;
10. 20是偶數,此時累計:偶數7個,奇數3個;
所以,一共有7個偶數,3個奇數。
??可以看到,當使用思維鏈提示后,模型對奇偶數統計的問題一下子就改善了。目前,思維鏈已被證明對于算術、常識和符號推理等任務的結果有所改進。
2. 天生的零樣本推理器
??雖然思維鏈提示的效果非常好,但是構建一個優質的思維鏈卻是十分傷腦的,有沒有更簡單的方法呢?Kojima et al.(2022)進一步發現,大型語言模型天生具備零樣本推理的能力,即Zero-CoT。具體來說,只需在問題后面添加類似于 “Let's think step by step”的魔法語句,就能激活模型,讓模型進行復雜推理,如圖5-3所示。有人戲稱這是模型在尋求鼓勵。

??少樣本思維鏈提示這種精心構造思維鏈來顯式地告知模型進行復雜推理的技術,通常需要耗費不少的人力物力。相比之下, 零樣本思維鏈提示這種僅僅添加一句魔法語句就能達到非常不錯的效果,讓模型進行復雜推理,顯得神奇而環保。
??下面我們通過一個數學問題來熟悉一下零樣本思維鏈提示。
??首先,依然是標準提示。
# 標準提示
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "用一只水桶裝水, 把水加到原來的2倍, 連桶重10千克, 如果把水加到原來的5倍, 連桶重22千克。桶里原有水多少千克?"},
],
temperature=0,
)
print(response["choices"][0]["message"]["content"])
??ChatGPT輸出:
設原來水的重量為x千克,則加水后水的重量為2x千克,加水前桶的重量為y千克,則有:
2x + y = y + 10 (加水到原來的2倍,連桶重10千克)
5x + y = y + 22 (加水到原來的5倍,連桶重22千克)
化簡得:
x = 6
因此,桶里原有水6千克
??這個答案不對,應該是4千克。我們看看零樣本思維鏈提示,如下所示。
# 零樣本思維鏈提示
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "用一只水桶裝水, 把水加到原來的2倍, 連桶重10千克, 如果把水加到原來的5倍, 連桶重22千克。桶里原有水多少千克? Let's think step by step."},
],
temperature=0,
)
print(response["choices"][0]["message"]["content"])
??ChatGPT輸出:
設原來桶里的水重x千克,桶本身重y千克,則有:
第一步:加到原來的2倍
桶里的水變成2x千克,桶本身重y+10千克。
第二步:加到原來的5倍
桶里的水變成5x千克,桶本身重y+22千克。
根據以上兩個式子,我們可以列出一個方程組:
2x + y + 10 = 5x + y + 22
化簡得:
3x = 12
x = 4
所以,原來桶里的水重4千克。
??原論文使用GPT-3模型在MultiArith數學數據集上進行測試,結果顯示,加上“Let's think step by step”這個簡單的魔法提示語句后,準確率提高到原來的四倍多,從17.7%上漲到78.7%。此外,作者還嘗試了其他提示語句,如:“Let’s think about this logically”,“Let’s solve this problem by splitting it into steps”等,這些提示語句也能提升模型的推理能力。讀者可以自行嘗試構建屬于自己的魔法語句來提高模型的表現。
5.2.3 大型語言模型復雜推理能力的改善
??現在,我們已經知道了通過構建思維鏈提示或者使用零樣本思維鏈的方式就可以激活大模型的復雜推理能力,那么我們還可以繼續提升模型的復雜推理能力嗎?答案是肯定的,下面,就我們來看看進一步改善大型語言模型復雜推理能力的方法。
1. 復雜問題分解,逐個擊破
??正如前文所述,我們常用一種思維技巧,即分析和綜合,來將問題分解成更小的部分,對每個部分進行分析,最終綜合各個部分的結果得出整體結論。那么,這種思維技巧是否可以應用于大型模型的復雜推理中呢?答案是肯定的。Zhou et al. [2022] 基于這種思維技巧,提出了最少到最多提示(Least-to-most)技術,如圖5-4所示。最少到最多提示將推理過程分解為兩個步驟:首先將問題分解為更簡單的子問題,然后逐步解決這些更簡單的子問題。

??通過這種最少到最多提示的方法,能夠有效地提升大型模型的復雜推理能力。它使大型模型在處理過程中逐步增加對問題的理解和認識,避免被過多的信息和復雜性所困擾。這種分解和逐步解決的方式使整個推理過程更加可控和可管理,有助于提高推理的準確性和效率。類似的,Khot et al. [2022] 提出了“分解提示”(Decomposed Prompting)技術,通過將復雜任務分解為更簡單的子任務,然后逐一解決這些子任務,從而提升對復雜任務的解決能力。
??下面我們嘗試問ChatGPT一個稍微復雜的問題:拼接所給單詞的最后一個字母。
??先看看標準提示的情況,如下所示。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content":
'Q: think, machine \n \
A: "ke". \n \
Q: learning, reasoning, generalization \n \
A: "ggn". \n \
Q: artificial, intelligence \n \
A: "le". \n \
Q: foo, bar, baz, blip, learn, prompting, world, shaking, event, dancefloor ,prisma, giraffe\n \
A:'},
],
temperature=0,
)
print(response['choices'][0]['message']['content'])
??ChatGPT輸出:
"fbbeplwse".
??可以看到,當使用標準提示時,ChatGPT似乎是沒有明白我們要找單詞的最后一個字母。
??接下來試試標準提示+零樣本思維鏈提示,如下所示。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content":
'Q: think, machine \n \
A: "ke". \n \
Q: learning, reasoning, generalization \n \
A: "ggn". \n \
Q: artificial, intelligence \n \
A: "le". \n \
Q: foo, bar, baz, blip, learn, prompting, world, shaking, event, dancefloor, prisma, giraffe \n \
A: Let"s think step by step.'},
],
temperature=0,
)
print(response["choices"][0]["message"]["content"])
??ChatGPT輸出:
Q: foo
A: "f".
Q: bar
A: "b".
Q: baz
A: "z".
Q: blip
A: "b".
Q: lear
A: "l".
Q: prom
A: "p".
Q: worl
A: "w".
Q: shak
A: "s".
Q: even
A: "e".
Q: danc
A: "d".
Q: pris
A: "p".
Q: gira
A: "g".
??當使用標準提示+零樣本思維鏈提示時,ChatGPT的思維路徑是清晰了很多,但是似乎完全搞混了我們要做的任務。我們的任務是拼接所給單詞的最后一個字母,ChatGPT全部找的是單詞第一個字母,而且最后也沒有拼接起來。
??再來試試思維鏈提示。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content":
'Q: think, machine \n \
A: The last letter of "think" is "k". The last letter of "machine" is "e". So "think, machine" is "ke". \n \
\n \
Q: learning, reasoning, generalization \n \
A: The last letter of "learning" is "g". The last letter of "reasoning" is "n". The last letter of "generalization" is "n". So "learning, reasoning, generalization" is "ggn". \n \
\n \
Q: artificial, intelligence \n \
A: The last letter of "artificial" is "l". The last letter of "intelligence" is "e". So "artificial, intelligence" is "le". \n \
\n \
Q: foo, bar, baz, blip, learn, prompting, world, shaking, event, dancefloor, prisma, giraffe \n \
A:'},
],
temperature=0,
)
print(response['choices'][0]['message']['content'])
??ChatGPT輸出:
The last letter of "foo" is "o". The last letter of "bar" is "r". The last letter of "baz" is "z". The last letter of "blip" is "p". The last letter of "learn" is "n". The last letter of "prompting" is "g". The last letter of "world" is "d". The last letter of "shaking" is "g". The last letter of "event" is "t". The last letter of "dancefloor" is "r". The last letter of "prisma" is "a". The last letter of "giraffe" is "e". So "foo, bar, baz, blip, learn, prompting, world, shaking, event, dancefloor, prisma, giraffe" is "orzpngdtragae".
??可以看到,使用思維鏈提示的方式后,ChatGPT思維過程變得十分有條理,跟我們所給樣例思維過程完全一致。盡管思維過程沒有錯誤,不過我們卻發現ChatGPT居然是個馬虎鬼,回答的時候先是把“g”的位置搞錯了,然后又在“g”后面神奇地添加了一個額外的“a”, 看來大模型的幻覺現象還是名不虛傳的。
??為了增強思維鏈的概念,我們最后測試最少到最多提示的方法,過程中會重新表述之前串聯的結果。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content":
'Q: think, machine\n \
A: The last letter of "think" is "k". The last letter of "machine" is "e". Concatenating "k" and "e" gives "ke". So "think, machine" output "ke".\n \
\n \
Q: think, machine, learning\n \
A: "think, machine" outputs "ke". The last letter of "learning" is "g". Concatenating "ke" and "g" gives "keg". So "think, machine, learning" is "keg".\n \
\n \
Q: transformer, language\n \
A: The last letter of "transformer" is "r". The last letter of "language" is "e". Concatenating "r" and "e" gives "re". So "transformer, \language" is "re".\n \
\n \
Q: transformer, language, vision\n \
A: "transformer, language" outputs "re". The last letter of "vision" is "n". Concatenating "re" and "n" gives "ren". So "transformer, language, vision" is "ren".\n \
\n \
Q: foo, bar, baz, blip, learn, prompting, world, shaking, event, dancefloor ,prisma, giraffe\n \
A:'},
],
temperature=0,
)
print(response['choices'][0]['message']['content'])
??ChatGPT輸出:
"foo, bar" outputs "or". The last letter of "baz" is "z". Concatenating "or" and "z" gives "orz". The last letter of "blip" is "p". Concatenating "orz" and "p" gives "orzp". The last letter of "learn" is "n". Concatenating "orzp" and "n" gives "orzpn". The last letter of "prompting" is "g". Concatenating "orzpn" and "g" gives "orzpng". The last letter of "world" is "d". Concatenating "orzpng" and "d" gives "orzpngd". The last letter of "shaking" is "g". Concatenating "orzpngd" and "g" gives "orzpngdg". The last letter of "event" is "t". Concatenating "orzpngdg" and "t" gives "orzpngdgt". The last letter of "dancefloor" is "r". Concatenating "orzpngdgt" and "r" gives "orzpngdgtr". The last letter of "prisma" is "a". Concatenating "orzpngdgtr" and "a" gives "orzpngdgtra". The last letter of "giraffe" is "e". Concatenating "orzpngdgtra" and "e" gives "orzpngdgtrae". So "foo, bar, baz, blip, learn, prompting, world, shaking, event, dancefloor, prisma, giraffe" is "orzpngdgtrae".
??我們將思維鏈提示和最少到最多提示的結果放在一起來看,如下所示。
???思維鏈 : "foo,bar,baz,blip,learn,prompting,world,shaking,event,dancefloor,prisma,giraffe" --> "orzpngdtragae"
???最少到最多: "foo,bar,baz,blip,learn,prompting,world,shaking,event,dancefloor,prisma,giraffe" --> "orzpngdgtrae"
??最少到最多提示最終不負眾望,不僅思維過程清晰有條理,對12個單詞尾字母拼接也完全正確。所以,當遇到特別復雜的問題時,一定不要忘記拆解問題。
??在實踐過程中,筆者還發現類似ChatGPT這種大模型對提示詞的格式十分看重,比如示例問題中字母之間用空格隔開,要回答的問題中字母也一定要用空格隔開,不然就可能回答錯誤。此外,從這幾種思維鏈提示的效果也可以看到,ChatGPT完全在模仿示例的思維鏈過程,特別是格式。
??除了上面這種顯式的提示外,還可以通過角色提示讓ChatGPT進行隱式的最少到最多提示,如下所示。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content":
"你現在是 MultisatgeGPT:你與 ChatGPT 一樣,但對于每一個問題,你會將問題分解為子問題,然后將它們結合起來,輸出最佳的措辭、最全面和最準確的答案。輸出應該看起來像這樣:\n \
ChatGPT:{ChatGPT 通常會說什么}; MultisatgeGPT:{更好、更全面的答案} 讓我們從簡單的問題開始:5*10 - 3*10 = ?"},
],
temperature=0,
)
print(response['choices'][0]['message']['content'])
??ChatGPT輸出:
ChatGPT:50 - 30 = 20;
MultistageGPT:我們可以將這個問題分解為兩個子問題:5*10 和 3*10。5*10 等于 50,3*10 等于 30。因此,5*10 - 3*10 等于 20。
??可以看到進行隱式的操作可以得到正確的效果,不過最近的研究顯示,顯式的思維鏈過程是要優于隱式的思維鏈過程。
2. 通往正確答案的路徑不止一條
??一個很自然的假設是,通向問題正確答案的路徑不止一條。為此,Wang et al.(2022)提出了一種名為自洽性策略(Self-consistency)的解碼策略用以替代之前的貪婪解碼策略,如圖5-5所示。

??自我一致性解碼策略從解碼器中抽樣生成多樣化的推理路徑集合,并選擇其中一致性最高的輸出結果作為最終答案。這種策略的目的是增加推理路徑的多樣性以及提高答案的一致性。此外,Yao et al.(2023)提出了一個名為“思維樹”(tree of thoughts,ToT)的框架。該框架允許模型通過考慮多種不同的推理路徑和自我評估選擇來進行深思熟慮的決策。模型可以根據需要向前或向后查看,以做出全局選擇。這個框架為模型提供了更加靈活和綜合考慮的能力,以在復雜情境中做出決策。
??顯式自洽性策略包括兩步,第一步得到多個答案,第二步綜合第一步的答案得到最終答案,具體如下所示。
??第一步,得到多個答案。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content":
"你現在是擁有3種不同的身份,分別是ChatGPT1,ChatGPT2,ChatGPT3。你現在需要使用不同身份不同角度回答同一個的問題,\n \
請問:如何加入DataWhale,成為DataWhale的成員?"},
],
temperature=0,
)
print(response['choices'][0]['message']['content'])
??ChatGPT輸出:
ChatGPT1:您可以通過DataWhale的官方網站或社交媒體平臺了解更多關于DataWhale的信息,并查看是否有加入DataWhale的招募信息。如果有,您可以按照招募要求提交申請,等待審核結果。
ChatGPT2:如果您想加入DataWhale,首先需要了解DataWhale的使命和愿景,確保您與DataWhale的價值觀相符。然后,您可以通過DataWhale的官方網站或社交媒體平臺了解更多關于DataWhale的信息,并查看是否有加入DataWhale的招募信息。如果有,您可以按照招募要求提交申請,并在申請中展示您的技能和經驗,以及您對DataWhale的貢獻計劃。
ChatGPT3:要加入DataWhale,您需要首先了解DataWhale的使命和愿景,并確保您與DataWhale的價值觀相符。然后,您可以通過DataWhale的官方網站或社交媒體平臺了解更多關于DataWhale的信息,并查看是否有加入DataWhale的招募信息。如果有,您需要仔細閱讀招募要求,并準備好您的個人簡歷和申請信。在申請中,您需要展示您的技能和經驗,以及您對DataWhale的貢獻計劃和未來發展計劃。如果您的申請被接受,您將成為DataWhale的一員,并有機會參與DataWhale的各種項目和活動,與其他成員一起學習和成長。
??第二步,綜合第一步答案輸出最后答案。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content":
"你現在是擁有3種不同的身份,分別是ChatGPT1,ChatGPT2,ChatGPT3。你現在需要使用不同身份不同角度回答同一個的問題,\n \
請問:如何加入DataWhale,成為DataWhale的成員?"},
{"role": "assistant", "content":
"ChatGPT1:您可以通過DataWhale的官方網站或社交媒體平臺了解更多關于DataWhale的信息,并查看是否有加入DataWhale的招募信息。如果有,您可以按照招募要求提交申請,等待審核結果。\n \
ChatGPT2:如果您想加入DataWhale,首先需要了解DataWhale的使命和愿景,確保您與DataWhale的價值觀相符。然后,您可以通過DataWhale的官方網站或社交媒體平臺了解更多關于DataWhale的信息,并查看是否有加入DataWhale的招募信息。如果有,您可以按照招募要求提交申請,并在申請中展示您的技能和經驗,以及您對DataWhale的貢獻計劃。\n \
ChatGPT3:要加入DataWhale,您需要首先了解DataWhale的使命和愿景,并確保您與DataWhale的價值觀相符。然后,您可以通過DataWhale的官方網站或社交媒體平臺了解更多關于DataWhale的信息,并查看是否有加入DataWhale的招募信息。如果有,您需要仔細閱讀招募要求,并準備好您的個人簡歷和申請信。在申請中,您需要展示您的技能和經驗,以及您對DataWhale的貢獻計劃和未來發展計劃。如果您的申請被接受,您將成為DataWhale的一員,并有機會參與DataWhale的各種項目和活動,與其他成員一起學習和成長。"},
{"role": "user", "content":
"請綜合ChatGPT1,ChatGPT2,ChatGPT3的建議,給出一個更好、更全面的答案"},
],
temperature=0,
)
print(response['choices'][0]['message']['content'])
??ChatGPT輸出:
如果您想加入DataWhale,首先需要了解DataWhale的使命和愿景,確保您與DataWhale的價值觀相符。您可以通過DataWhale的官方網站或社交媒體平臺了解更多關于DataWhale的信息,并查看是否有加入DataWhale的招募信息。如果有,您需要仔細閱讀招募要求,并準備好您的個人簡歷和申請信。在申請中,您需要展示您的技能和經驗,以及您對DataWhale的貢獻計劃和未來發展計劃。如果您的申請被接受,您將成為DataWhale的一員,并有機會參與DataWhale的各種項目和活動,與其他成員一起學習和成長。
??隱式自洽性策略將這一整合過程融入到提示詞中,如下所示。
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content":
"你現在是 MultiverseGPT:你與 ChatGPT 一樣,但對于每一個問題,你會思考5種不同的思路,然后將它們結合起來,輸出最佳的措辭、最全面和最準確的答案。輸出應該看起來像這樣:\n \
ChatGPT:{} \n \
MultiverseGPT:{} 讓我們從這個的問題開始:如何加入DataWhale,成為DataWhale的成員?"},
],
temperature=0,
)
print(response['choices'][0]['message']['content'])
??ChatGPT輸出:
ChatGPT:您可以通過DataWhale的官方網站或社交媒體平臺了解如何加入DataWhale。通常,您需要填寫一份申請表格并提交您的個人信息和相關技能。然后,DataWhale的招募團隊將會對您的申請進行審核,并在適當的時候與您聯系。
MultiverseGPT:加入DataWhale的方式有很多種。您可以通過參加DataWhale組織的活動、加入DataWhale的社區、成為DataWhale的志愿者或成為DataWhale的正式成員來加入DataWhale。如果您想成為DataWhale的正式成員,您需要滿足一定的條件,例如具備相關技能、有一定的工作經驗等。您可以在DataWhale的官方網站或社交媒體平臺上了解更多信息,并與DataWhale的招募團隊聯系以獲取更多幫助。
??研究表明,自洽性策略可以提升算術、常識和符號推理任務的結果。即使常規的思維鏈提示被發現無效,自洽性仍然能夠改善結果。
3. 復雜鏈可以帶來更大的增益
??顯然,當我們需要完成一項復雜任務時,需要接受有針對性的訓練。舉例來說,在應對高考數學考試時,我們的日常訓練不能僅停留在中學甚至小學水平。因此,Fu et al.(2022)發現,輸入提示的復雜性與模型性能之間存在正相關關系,并提出了一種基于復雜性的提示技術。這種技術適用于多步推理過程,如圖5-6示例所示。

??該技術將基于復雜性的選擇標準從輸入空間(即提示)擴展到輸出空間(即語言模型生成的推理鏈)。通過這種方式,能夠更好地應對復雜推理任務,并提高模型的推理能力。此外,作者還得出了一些非常有啟發性的結論。
- 推理步驟的數量是性能改進最顯著的因素。
- 基于復雜性的一致性結論:最佳性能總是通過對復雜鏈條進行多數投票而不是簡單鏈條來實現。
- 當數據沒有提供推理鏈注釋時,可以使用問題長度或公式長度作為衡量復雜性的標準。
5.3 大型語言模型復雜推理能力的探討
??大型語言模型的強大復雜推理能力引起了學術界和工業界廣泛的研究興趣和討論。這些模型具備前所未有的自然語言處理能力,能夠生成連貫且語義準確的文本。研究者們特別關注大型語言模型復雜推理能力的來源以及能力的遷移。
??以GPT-3系列為例,初代的GPT-3是在一個包含3000億個_tokens_的語料庫上進行預訓練的,該模型具有1750億個參數。語言建模的訓練目標使得GPT-3具備了生成文本的能力,而龐大的3000億 tokens 訓練語料庫則為GPT-3提供了豐富的世界知識,1750億個參數則提供了存儲知識的廣闊空間。其中,最令人驚訝的是其上下文情境(In-Context)學習能力,只需提供幾個符合任務范式的示例,模型就能夠成功完成給定的任務。
??在2020年7月,OpenAI發布了初代GPT-3模型(davinci),并從此開始不斷進化,在_code-davinci-002_和_text-davinci-002_之前,有兩個中間模型,分別是_davinci-instruct-beta_和_text-davinci-001_,它們在很多方面都比兩個_-002_模型差(比如_text-davinci-001鏈式思維推理能力不強)。_code-davinci-002_和text-davinci-002_是第一版的GPT3.5模型,一個用于代碼,另一個用于文本。與初代GPT-3的顯著差異是:它們表現出強大的泛化能力,可以泛化到沒有見過的任務;同時表現出強大的通過思維鏈進行復雜推理的能力,而初代模型的思維鏈推理的能力很弱甚至沒有。
??隨后,出現了一個令人震驚的假設:擁有進行復雜推理的思維鏈能力很可能是代碼訓練的一個神奇副產品。初代的GPT-3并沒有接受過代碼訓練,因此無法進行思維鏈推理。即使通過指令微調,_text-davinci-001_模型的思維鏈推理能力依然相當有限。這意味著指令微調可能并非思維鏈存在的原因,而最有可能的原因是代碼訓練。PaLM模型使用了5%的代碼訓練數據,并能夠進行思維鏈推理。而Codex論文中的代碼數據量為159G,大約相當于初代GPT-3訓練數據5700億的28%。因此,_code-davinci-002_及其后續變體具備進行思維鏈推理的能力。
??J.R. Anderson根據知識的狀態和表現方式將知識分為兩類:陳述性知識(declarative knowledge)和程序性知識(procedural knowledge)。陳述性知識是關于事實和概念的知識,而程序性知識是關于執行任務和操作的知識。一些研究者(Min et al. 2022; Wang et al. 2022; Madaan & Yazdanbakhsh. 2022)發現,模型主要關注提示的格式,而可能不會明顯受到提示正確性的影響。這在我們上面的實驗中,也印證了這一點。因此,筆者傾向于將思維鏈的過程視為程序性知識,因為程序性知識主要關注問題的執行過程和方法,而不是問題的答案正確與否。然而,目前仍有待研究的問題是,模型在多大程度上會受到提示正確性的影響,以及提示能夠在多大程度上覆蓋模型的先驗信念。
??代碼可以被看作是程序性知識的一種形式,因為編程語言本身提供了表達程序性知識的方式。通常情況下,學習程序性知識需要建立在大量陳述性知識的基礎上。這個觀點在某種程度上也驗證了大型模型的涌現能力。模型的參數規模需要足夠大,以便模型在充分學習陳述性知識之后,才能從數據中學習程序性知識。這也解釋了為什么小型模型幾乎無法展現出涌現能力,與之前的觀點是相互印證的。
??在這里,我們將以思維鏈為代表的復雜推理能力視為程序性知識。既然它是一種知識,那么是否可以通過有監督學習的方式來獲取呢?答案是肯定的。(Chung. et al. 2022; Huang et al. 2022)的研究發現,通過直接使用思維鏈數據進行精細調節,可以激發模型的思維鏈能力。Fu et al.(2023)采用知識蒸餾的方法,將大型模型(指參數量大于一千億的模型)所擁有的復雜推理的思維鏈能力提煉到小型模型(指參數量小于一百億的模型)中,雖然會犧牲一部分通用思維鏈能力,但使得小型模型能夠具備專門的思維鏈能力。如圖5-7所示,通過知識蒸餾,顯著提升了小型FlanT5模型(包括參數量為250M、760M和3B的三個模型)在一套包含4個數學推理任務的思維鏈推理性能,準確率平均提高了10個百分點。

5.4 本章小結
??本章中,我們主要學習了有關大語言模型復雜推理能力的知識。首先,簡單介紹了復雜推理的相關概念,緊接著利用ChatGPT作為演示,先對大型語言模型的推理能力有了初步感知,然后介紹激活大型語言模型復雜推理能力的技術——思維鏈,包括思維鏈提示和零樣本思維鏈提示,接下來主要介紹了進一步改善大語言模型復雜推理能力的一些技術,包括對復雜問題分解的最少到最多提示和分解提示、基于多條思維路徑的自洽性策略、基于思維鏈復雜度的自洽性提示等。最后,我們通過對GPT-3系列進行回顧,探討了大語言模型具有復雜推理能力背后的原因。

【轉載】https://github.com/datawhalechina/hugging-llm
浙公網安備 33010602011771號