大模型在業務落地必須要學習的技術,看這篇就夠了
大模型在業務中落地我們都會遇到一個問題,如何讓大模型準確瞭解我想問的點,如何能提高大模型回答的準確率。比如我現在想讓大模型落地到研發管理中,想一鍵讓大模型告訴我現在有風險的專案有哪些?哪些需求進度是滯後的?目前的 bug 解決率是多少?
我們常規的思路是先想好一個 prompt,然後直接問大模型,但是我們總是無法把所有的專案資訊帶入進 prompt 中,因此大模型也無法完全掌握我們的所有的專案資訊,肯定也無法給出我們想要的結果,那應該怎麼解決這個問題呢?下面我們重點介紹幾個提高大模型推理能力的主要技術:CoT、TOT、ReAct,從概念到實現程式碼框架,一點點去理解這些思想背後的原理。
1. CoT(Chain of Thought,思維鏈)
第一次接觸到 CoT 是在 Prompt 工程中,其作為 Prompt 高階技巧的一部分,可以顯著提高大模型在推理方面的能力,尤其是解決數學等具有邏輯性的問題時。
區別於傳統的 Prompt 從輸入直接到輸出的對映 output> 的方式,CoT 完成了從輸入到思維鏈再到輸出的對映,即 reasoning chain——>output>。
原論文:https://arxiv.org/pdf/2201.11903.pdf
1.1 基本使用
目前沒有看到 CoT 相關的實現程式碼,僅僅在 Prompt 中新增了一句 “Let's Step by Step” 就讓大模型在推理上用到了思維鏈。
而關於 CoT 的論文,也基本上都是在講如何微調來讓大模型具備思維鏈的能力。例如這篇論文:https://arxiv.org/pdf/2210.11416.pdf
所以,我想,CoT 在現在應該是大模型本身就應該具備的能力,我們在使用時及時喚醒這個能力(例如 Prompt 加入 Let's think step by step.),然後使用就可以了,並不需要自己去寫程式碼寫邏輯去親自實現 CoT。
總結:CoT 的核心思想是透過提供一系列中間推理步驟來引導模型逐步思考,從而生成更加準確和連貫的輸出。這種方法特別適用於需要複雜推理、數學計算或解決多步驟問題的場景。
1.2 Self-consistency with CoT(CoT 的自我一致性)
一種 CoT 在實際應用中的方案是:Self-consistency with CoT(CoT 的自我一致性)。簡單地要求模型對同一提示進行多次回答,並將多數結果作為最終答案。 它是 CoT(Chain of Thought)的後續方法。示例程式碼如下:對同一個 Prompt,重複呼叫 5 次,然後取其中多數結果作為最終答案。
# 連續呼叫 5 次
for _ in range(5):
prompt = f"{instruction}\n\n{output_format}\n\n請一步一步分析:\n{context}"
print(f"------第{_+1}次------")
response = get_completion(prompt)
print(response)
這種結果應該有評價標準和歸類標準,例如只能回答 yes or no,這樣才能統計出多數結果作為返回。
2. ToT(Tree of Thought,思維樹)
在 CoT 的基礎上,有人指出其存在的缺陷:
- 對於區域性,沒有探索一個思考過程下的不同延續 - 樹的分支。
- 對於全域性,沒有利用任何型別的規劃,前瞻以及回溯去幫助評估不同抉擇 - 而啟發式的探索正式人類解決問題的特性。 針對以上缺陷,提出了 ToT(Tree of Thought,思維樹)的概念。 相關論文:https://arxiv.org/pdf/2305.10601.pdf 具體結構圖如下:虛線左邊為基本 Prompt、CoT 以及 CoT Self Consisitency,虛線右邊為 ToT。
下面以一個實際案例來看下 ToT 的思想和實現。
2.1 案例
案例內容:小明 100 米跑成績:10.5 秒,1500 米跑成績:3 分 20 秒,鉛球成績:12 米。他適合參加哪些搏擊運動訓練。
2.1.1 示例程式碼
import json
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
client = OpenAI(
api_key=os.getenv("OPENAI_API_KEY"),
base_url=os.getenv("OPENAI_BASE_URL")
)
def get_completion(prompt, model="gpt-4", temperature=0):
messages = [{"role": "user", "content": prompt}]
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=temperature # 模型輸出的隨機性,0 表示隨機性最小
)
return response.choices[0].message.content
def performance_analyser(text):
prompt = f"{text}\n請根據以上成績,分析候選人在速度、耐力、力量三方面素質的分檔。分檔包括:強(3),中(2),弱(1)三檔。\
\n以JSON格式輸出,其中key為素質名,value為以數值表示的分檔。"
response = get_completion(prompt)
return json.loads(response)
def possible_sports(talent, category):
prompt = f"需要{talent}強的{category}運動有哪些。給出10個例子,以array形式輸出。確保輸出能由json.loads解析。"
response = get_completion(prompt, temperature=0.8)
return json.loads(response)
def evaluate(sports, talent, value):
prompt = f"分析{sports}運動對{talent}方面素質的要求: 強(3),中(2),弱(1)。\
\n直接輸出擋位數字。輸出只包含數字。"
response = get_completion(prompt)
val = int(response)
print(f"{sports}: {talent} {val} {value>=val}")
return value >= val
def report_generator(name, performance, talents, sports):
level = ['弱', '中', '強']
_talents = {k: level[v-1] for k, v in talents.items()}
prompt = f"已知{name}{performance}\n身體素質:{_talents}。\n生成一篇{name}適合{sports}訓練的分析報告。"
response = get_completion(prompt, model="gpt-3.5-turbo")
return response
name = "小明"
performance = "100米跑成績:10.5秒,1500米跑成績:3分20秒,鉛球成績:12米。"
category = "搏擊"
talents = performance_analyser(name+performance)
print("===talents===")
print(talents)
cache = set()
# 深度優先
# 第一層節點
for k, v in talents.items():
if v < 3: # 剪枝
continue
leafs = possible_sports(k, category)
print(f"==={k} leafs===")
print(leafs)
# 第二層節點
for sports in leafs:
if sports in cache:
continue
cache.add(sports)
suitable = True
for t, p in talents.items():
if t == k:
continue
# 第三層節點
if not evaluate(sports, t, p): # 剪枝
suitable = False
break
if suitable:
report = report_generator(name, performance, talents, sports)
print("****")
print(report)
print("****")
2.1.2 程式碼解釋
(1)從 talents = performance_analyser(name+performance) 開始,performance_analyser 主要用來分析小明成績,並返回一個 JSON 格式的字串。
def performance_analyser(text):
prompt = f"{text}\n請根據以上成績,分析候選人在速度、耐力、力量三方面素質的分檔。分檔包括:強(3),中(2),弱(1)三檔。\
\n以JSON格式輸出,其中key為素質名,value為以數值表示的分檔。"
response = get_completion(prompt)
return json.loads(response)
輸出如下:
{
"速度": 3,
"耐力": 2,
"力量": 2
}
然後就有了樹的第一層節點,即速度、耐力和力量。
(2)然後遍歷第一層節點,執行 possible_sports:
def possible_sports(talent, category):
prompt = f"需要{talent}強的{category}運動有哪些。給出10個例子,以array形式輸出。確保輸出能由json.loads解析。"
response = get_completion(prompt, temperature=0.8)
return json.loads(response)
以速度節點為例,prompt 為:需要速度強的搏擊運動有哪些。給出 10 個例子,以 array 形式輸出。確保輸出能由 json.loads 解析。這時候得到了第二層節點。
(3)然後遍歷第二層節點,執行 evaluate:
def evaluate(sports, talent, value):
prompt = f"分析{sports}運動對{talent}方面素質的要求: 強(3),中(2),弱(1)。\
\n直接輸出擋位數字。輸出只包含數字。"
response = get_completion(prompt)
val = int(response)
print(f"{sports}: {talent} {val} {value >= val}")
return value >= val
輸出結果:
speed_intensive_martial_arts: 耐力 2 True
speed_intensive_martial_arts: 力量 3 False
(4)類似這樣一層一層遍歷,評估,最後得到最終結果。當然,為了提高效率,程式碼中也做了剪枝操作:
if v < 3: # 剪枝
continue
2.1.3 總結
上面的程式碼,從原始輸入開始,在思維鏈的每一步,取樣多個分支。逐漸形成樹狀結構。對每一個分支進行評估,然後在合適的分支上進行搜尋。這就是 ToT 思維樹的基本過程。
3. ReAct(Reason + Action)
ReAct 與 CoT、ToT 的區別:
個人理解:CoT、ToT 都是作用在大模型本身的內在推理過程上,而 ReAct 則是統籌整個系統,從推理過程,結合外部工具共同實現最終的目標。
以 ReAct 論文中那張圖來看,可以更清晰的理解 ReAct 與 CoT、ToT 的區別:
ReAct 是 Reason + Action,而 Cot、ToT 則只是 Reason。
4. 總結
本文講解了改進大模型推理能力的三種方法:CoT、ToT、ReAct。並從使用和實現的角度,進行了詳細講解。CoT 目前來看已經整合進了大模型內部,透過在 Prompt 中加入一些提示詞(Let's think step by step)即可喚醒大模型的 CoT 思考能力。對於 ToT,有實現程式碼參考,就是在思維鏈的基礎上,每一步不再是隻有一個結果,而是取樣多個分支,綜合評估。對於 ReAct,則是從推理過程,結合外部工具共同實現最終目標。ReAct 與 CoT 和 ToT 的本質區別,就是 ReAct 不止在推理,還在利用外部工具實現目標。
相關文章
- mongoDB看這篇就夠了MongoDB
- 學透 Redis HyperLogLog,看這篇就夠了Redis
- Android Fragment看這篇就夠了AndroidFragment
- Oracle索引,看這篇就夠了Oracle索引
- 小白如何學習六西格瑪,看這篇就夠了!
- 微服務架構元件分析,看這篇就夠了微服務架構元件
- 學習MySQL這一篇就夠了MySql
- 學習JDBC這一篇就夠了JDBC
- 學習Jmeter,這一篇就夠了JMeter
- 學習git這一篇就夠了!!!Git
- OAuth授權|看這篇就夠了OAuth
- Zookeeper入門看這篇就夠了
- 小程式分享,看這篇就夠了
- JavaScript正則,看這篇就夠了JavaScript
- 入門Webpack,看這篇就夠了Web
- Git 看這一篇就夠了Git
- 索引?看這一篇就夠了!索引
- Transformer 看這一篇就夠了ORM
- 學Redis這篇就夠了Redis
- 分散式事務,只看這一篇就夠了分散式
- 學Mybatis,入門看這一篇就夠你學的了!MyBatis
- HashMap的實現原理(看這篇就夠了)HashMap
- Volatile的實現原理(看這篇就夠了)
- 【詳細圖解】學習佇列,看這一篇就夠了!圖解佇列
- 代理模式看這一篇就夠了模式
- Java 動態代理,看這篇就夠了Java
- python 操作 mysql 只看這篇就夠了PythonMySql
- Flutter DataTable 看這一篇就夠了Flutter
- 小程式入門看這篇就夠了
- 關於流量清洗,看這篇就夠了
- Java 集合看這一篇就夠了Java
- vue 元件通訊看這篇就夠了Vue元件
- EFCore 6.0入門看這篇就夠了
- ZooKeeper分散式配置——看這篇就夠了分散式
- java序列化,看這篇就夠了Java
- 線上服務的FGC問題排查,看這篇就夠了!GC
- XLNet預訓練模型,看這篇就夠了!(程式碼實現)模型
- Spring Schedule定時任務看這一篇就夠了Spring