解密Prompt系列13. LLM Agent-指令微調方案: Toolformer & Gorilla
上一章我們介紹了基于Prompt范式的工具調用方案,這一章介紹基于模型微調,支持任意多工具組合調用,復雜調用的方案。多工具調用核心需要解決3個問題,在哪個位置進行工具調用(where), 從眾多工具中選擇哪一個(Which), 工具的輸入是什么(What)。Where + Which + What,我稱之為3W原則,3H它兄弟哈哈哈哈~

其實如何教大模型使用工具,和教人類使用工具沒啥區別。就像上周末我想給我媽買的可以防彈,超重的巖板餐桌按個滑輪需要使用電鉆,那我學習使用電鉆的途徑無非有三種
- 基于歷史經驗:我之前都是手動的沒用過電動的,我憑借自信直接上手結果擰歪了......對應到LLM其實就是本章要提到的工具微調,我們讓模型先學習在在不同的場景使用什么工具,如何使用,再利用大模型的遷移泛化能力泛化到更多的場景。
- 從工具說明書中學習:我去翻了翻說明書,奈何寫的太抽象沒看懂......對應到LLM簡單版的就是上一章的zero-shot prompt方案,告訴大模型工具的使用場景和用法;升級版就是之后會提到的優化方案,我們可以動態召回工具的完整說明書和使用范例作為上文輸入模型
- 通過觀察他人使用工具來學習:最終我打開小紅書看短視頻學習了下,一點就通,于是我擁有了可絲滑移動的防彈餐桌!對應到LLM簡單版就是上一章介紹的few-shot prompt方案,我們讓LLM看到在其他場景它是如何使用工具的;升級版就是之后會提到的動態few-shot prompt的方案。
下面我們看下通過微調為模型注入工具使用經驗的兩個方案:Toolformer和Gorilla
Toolformer
- TALM: Tool Augmented Language Models
- Toolformer: Language Models Can Teach Themselves to Use Tools
- 填充式工具使用 + InContext制造自監督樣本
Toolformer是工具調用領域的前輩,使用LM監督微調得到可以進行Inline工具調用的模型。解碼時,模型會在恰當的位置生成API調用的請求,并中止解碼,去調用API得到返回值,把返回值拼接到"->"字符之后,再繼續模型解碼,如下

Toolformer的創新主要在API調用的樣本構造,因此我們先來看下樣本構造的部分
樣本
Toolformer單一API的樣本構造主要包含以下3個步驟
- Sampling API
以QA API為例,作者會先編寫幾個樣本作為In-Context,得到以下的FewShot指令樣本

然后針對新的長度為N的輸入文本,作者會計算每個位置得到<API>前綴的條件解碼概率,并保留超過閾值的TopK個最優可能出現<API>的位置。然后每個位置,基于上文,讓模型隨機解碼m次生成m個候選的API調用請求。這樣我們就得到了候選樣本集,每一段文本,最多有K個可能進行工具調用的位置,且每個位置有至多m個候選請求{c1,...cm}。
- Executing API Calls
執行以上得到的候選請求,每個請求得到一個對應的返回值{r1,....rm}。 可以是計算器的結果,維基百科的搜索返回等等
- Filtering API Calls
最后是過濾篩選,原理是好的工具調用樣本,應該會讓工具調用位置后面的文本解碼概率提高,Perplexity降低。因此作者計算了在工具調用位置之后,所有token的加權條件解碼概率。

以上加權的權重計算如下,離工具調用位置越遠權重越小

條件解碼概率的條件Z,分別是[工具調用+返回值],[工具調用+無返回值],[無工具調用],這三者中Loss較小的一個,過濾方案是[工具調用+工具返回值]的Loss降幅超過閾值,則保留該樣本
整體量級上,1個API生成了25K左右的樣本用于微調,樣本長度1024
微調
使用以上樣本生成方案得到多API調用的樣本集混合后得到增強訓練樣本。樣本的構建方式是在原始文本中直接插入API調用的語句\(x_{1:i-1},e(c_i,r_i),x_{i:n}\),如下
The Nile has an approximate length of
這樣通過微調,模型會學習到在什么位置使用什么樣的工具,以及工具的請求輸入。同時和解碼的格式保持一致,后文會依賴API調用結果進行解碼。微調使用了GPT-J模型,Batch=128, lr=1e-5,warmup=10%,訓練了2K step,常規的LM Loss.
總結
Toolformer的創新主要在使用模型的Few-shot理解能力,使用少量的人工標注樣本制造大量的自監督樣本。這樣Tooformer理論上可以支持任意的API工具。但Toolformer有一些局限性
- 工具獨立:論文中每個API調用的樣本是獨立構造的,工具之間沒有交互,且同一工具的多次調用之間也是獨立,不依賴上文的調用返回。
- 常規解碼:沒有引入思維鏈推理,限制了最終效果
Gorilla
- HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in HuggingFace
- TaskMatrix.AI: Completing Tasks by Connecting Foundation Models with Millions of APIs
- Gorilla:Large Language Model Connected with Massive APIs
- https://github.com/ShishirPatil/gorilla
Gorilla在HuggingGPT,TaskMatrix.AI這兩個API調用的前輩的基礎上,加入了指令微調來提升API調用效果。Gorilla支持TorchHub,TensorflowHub,Huggingface總共1645個API,且可以泛化到新的API上。

樣本
Gorilla使用Self-Instruct來構建指令樣本,用的是GPT4模型。構建方案是以上3個API Hub, 每個Hub各人工編寫6個指令樣本。每一輪隨機從6個樣本中采樣3個作為Few-Shot,并通過指令讓GPT4隨機生成10個真實世界的使用case,總共生成16450個指令樣本,生成的指令樣本如下

同時Gorilla加入了Retriever-Aware,也就是在以上的指令樣本中,指令后面會拼接上API的使用說明:"Use this API documentation for reference: <retrieved_API_doc_JSON>"
這樣在推理階段,會先根據用戶的指令召回最相關、最新的API使用說明。降低模型幻覺的同時,使得模型有更好的泛化性,可以適應全新的API接口,或者已有API接口的參數變化。
微調&推理
微調的部分比較常規就是在LLama-7B模型上,使用以下參數在8*A100(40G)進行指令微調。

在推理階段會同樣加入API Retriever根據用戶的指令召回最相關的API使用說明,和用戶輸入拼接,喂進模型推理。召回方案作者嘗試了BM25和GPT的Embedding,不過不同召回方案的效果和API本身相關,沒有誰一定更好這一說。
效果上微調后7B的LLama模型使用GPT Embedding召回工具說明,在工具調用上的準確率可以顯著超越GPT3.5使用Prompt方案的調用效果

總結
對比上一章基于Prompt的方案Self Ask,ReAct和這一章基于微調的方案Toolformer,Gorilla,指令微調的方案有以下優勢
- planning效果更好:微調方案比Prompt方案在復雜問題規劃上效果更好,尤其適合本身In-Context能力有限的小模型
- 工具調用準確率更高:針對復雜工具調用的準確率更高
- 不受模型迭代影響:GPT3.5->GPT4的升級,讓不少基于Prompt指令的應用們需要集體進行prompt調整,因為模型指令變了.......以及不同模型之間的指令或有不同。但微調方案不受這一點影響,因為指令微調本身就是對齊的過程,因此更robust
缺點自然是沒有開箱即用的Prompt方案靈活,所以不妨用prompt方案來進行前期測試,后期用微調來提升效果。
但其實不論是prompt方案還是微調方案,其實都是LLM Agent應用中的工具調用規劃這一個子模塊,要真正搭建可以落地的大模型應用,需要更系統的整體設計,這塊我們放在下一章說~
想看更全的大模型相關論文梳理·微調及預訓練數據和框架·AIGC應用,移步Github >> DecryPrompt
未經許可請勿轉載哦~

本章介紹基于模型微調,支持任意多工具組合調用,復雜工具調用的方案。工具調用的核心是3個問題:在哪個位置使用工具,使用什么工具,如何生成調用語句 - Gorilla & Toolformer
浙公網安備 33010602011771號