LLMs 修復自身錯誤的能力如何?
Keras和TPU上的聊天機器人競技場實驗
點選此處在新標籤頁中開啟。👈
目錄
1. 引言
2. 實驗
3. Keras聊天機器人競技場技術:Spaces、Gradio、TPU、JAX和Keras
3.1 為什麼選擇TPU?
3.2 為什麼選擇JAX和Keras?
3.3 分片模型?
3.4 哪些模型?
4. 結果
4.1 可靠性
4.2 完整對話——修復錯誤
4.3 更多錯誤修復
5. 總結
1. 引言
我對LLM解決大問題不感興趣,恰恰相反。我希望它們能夠處理瑣碎的工作,如果第一次沒有做對,一個簡單的英語句子就足以修復它。簡而言之,我想要一個助手,就像舊科幻電影中的電腦一樣,只是沒有“對不起,戴夫,恐怕我不能那樣做”的部分😅。
這篇論文探討了這樣一種用於編碼的工具。撇開其富有創意的標題宣告(不,人工智慧還沒有擊敗Kaggle特級大師),論文作者所做的是將各種Kaggle問題手動分解為微任務,讓LLM為它們生成程式碼,並迭代直到單元測試透過。一個微任務的例子可能是,對於影像分類問題,需要“弄清楚輸入資料的格式,並將其重新格式化為包含‘id’、‘image_filename’和‘class’列的CSV檔案”。
我喜歡這種方法,因為這是我未來希望與人工智慧合作專案的方式。讓AI生成無聊的程式碼片段,比如資料重新格式化,這樣我就可以專注於有趣的部分:正確地構建問題並設計出解決方案的步驟。
但是,這個互動式編碼助手必須能夠理解簡單的英語反饋並修復其程式碼中的錯誤。憑藉LLM從知識和上下文推斷資訊的能力,這可能是一個非常高效的計算機介面。但是,如果LLM的怪癖,如幻覺或缺乏形式邏輯,成為障礙,我們最終可能會得到“人工愚蠢”而不是人工智慧。
所以我決定用今天的LLM進行一次小測試。一個超級簡化的測試,看看當您指出錯誤時,LLM修復自身錯誤的效率如何。
2. 實驗
以下是場景描述
系統提示
你是一個移動裝置上的語音助手。你的工作是使用這個Python API將使用者請求轉換為API呼叫
action.add_calendar_entry(title, date="YYYY-MM-DD", time="HH:MM", duration=m) # duration in minutes action.remove_calendar_entry(title, date, time)
你可以使用30分鐘作為新事件的預設持續時間。對每個請求,你都必須用一行可執行程式碼進行響應。
對話提示 | 預期輸出 |
---|---|
在11月11日下午5點與弗雷德安排一個會議 | action.add_calendar_entry("與弗雷德的會議", date="2023-11-11", time="17:00", duration=30) |
當前年份是2024年。 | action.add_calendar_entry("與弗雷德的會議", date="2024-11-11", time="17:00", duration=30) |
我當天晚上8點要去聽一場搖滾音樂會。 新增一個日曆條目。 |
action.add_calendar_entry("搖滾音樂會", date="2024-11-11", time="20:00", duration=30) |
持續時間設定為3小時。 | action.add_calendar_entry("搖滾音樂會", date="2024-11-11", time="20:00", duration=60*3) |
第二天早上8點,和保羅開個會。半小時。 | action.add_calendar_entry("與保羅的會議", date="2024-11-12", time="08:00", duration=30) |
取消與弗雷德的會議。 | action.remove_calendar_entry("與弗雷德的會議", "2024-11-11", "17:00") |
就是這樣。非常簡單,但LLM能處理嗎?當它們犯錯時,你只需告訴它們是什麼錯誤,就能期待它們修復嗎?
為了測試這個,我需要一個能夠同時快速與多個聊天機器人互動的環境,以下是我的設定方式。
3. Keras聊天機器人競技場技術:Spaces、Gradio、TPU、JAX和Keras
為了進行這個場景實驗,我希望能夠同時進行兩次對話,使用不同的LLM,並暫停其中一方,同時要求另一方修復其輸出中的錯誤。以下是它的樣子。它是使用Gradio on Spaces構建的,並使用Keras、JAX和TPU。
在我們回到與LLM聊天的嚴肅問題之前,先介紹一下它的構建方式。
3.1 為什麼選擇TPU?
因為它們推理速度快,記憶體大。一個TPU v5e 2x4擁有8個核心,每個核心16GB記憶體,總計128GB記憶體。有了這麼大的記憶體,我們可以一次性載入多個LLM,只要我們將它們分片到所有核心,並可以在使用者介面中隨意切換。在這個實驗中,我成功載入了5個約80億引數的模型(再多一個就會記憶體溢位)和3個約20億引數的模型,總共有7個LLM同時駐留在記憶體中,採用bfloat16格式。
3.2 為什麼選擇JAX和Keras?
JAX是TPU的首選ML環境,這得益於其強大的XLA編譯器。Keras現在可以在JAX(以及PyTorch和TensorFlow)之上原生執行,是我最喜歡的建模環境,它的姊妹庫KerasHub中有很多預訓練的LLM可供選擇。它甚至可以從Hugging Face載入選定的非Keras檢查點,這對於比較很有用。我之前在這裡寫過關於此的內容:Keras中的Llama 3.2。
3.3 模型分片?
我還使用Keras,因為它是模型並行化方面最使用者友好的API。在這裡,我想盡可能多地將模型載入到TPU記憶體中。為此,模型必須跨所有8個TPU核心的記憶體進行分片。幸運的是,它們中的大多數都帶有一個預設的佈局對映,正是這樣做的。例如
layout_map = keras_hub.models.Llama3Backbone.get_layout_map(device_mesh)
有關完整的載入程式碼以及模型並行性的更多背景資訊,請參閱我之前的文章。您還會在該文章中找到一個程式碼片段,用於視覺化模型載入後實際應用的分片。這對於除錯非常有用。是的,除錯和一些佈局對映調整是必要的。
3.4 哪些模型?
為了這個實驗,我選擇了引數量小於10億的LLM,主要是考慮到它們的實用性,因為可以同時載入許多模型。此外,實驗測試的內容相當簡單,應該在這些較小模型的處理範圍內。所有模型都經過指令微調,以便進行對話。您可以在演示的實現中檢視它們的聊天模板。歡迎複製貼上程式碼以滿足您自己的Keras聊天機器人需求。這些模型來自Gemma、Llama3、Mistral和Vicuna系列。完整的列表請參見下面的結果表格。
4. 結果
4.1 可靠性
首先,我們先看看我們的LLM能否可靠地回答第一個問題。系統提示和第一個問題“在11月11日下午5點與弗雷德安排一個會議”重複了五次。
顏色程式碼
- 一個✓如果模型生成預期輸出(即API呼叫),則授予勾選標記
action.add_calendar_entry("與弗雷德的會議", date="2023-11-11", time="17:00", duration=30)
- 一個🍄紅色毒蘑菇表示答案大部分正確但包含錯誤(例如:錯誤的日期)
- 這🔥垃圾桶著火表示響應是垃圾,沒有可識別的API呼叫。
模型 | 僅第一個問題,嘗試五次 |
---|---|
Gemma 2 9B-instr | ✓ ✓ ✓ ✓ ✓ |
Llama-3.1 8B-instr | ✓ ✓ ✓ ✓ ✓ |
Llama 3.2 3B-instr | ✓ ✓ ✓ ✓ ✓ |
Llama 3.2 1B-instr | 🔥 🍄 🔥 🔥 🔥 |
Gemma2B-instr | 🍄 🍄 🍄 🍄 ✓ |
Codegemma7B-instr | ✓ ✓ ✓ ✓ ✓ |
vicuna 1.5 7b-instr | ✓ 🔥 🔥 ✓ 🔥 |
Mistral 7B-instr | ✓ ✓ 🍄 ✓ 🍄 |
好訊息是,一些模型每次都做對了,並且所有模型都至少成功一次地用API呼叫(或多或少正確)回答了問題。然而,較小的1-2B引數模型和像Vicuna這樣的舊模型表現不佳。它們大部分時間都回答得很糟糕。
4.2 完整對話——修復錯誤
現在,讓我們每次執行兩個模型進行完整的對話。如果模型犯了錯誤,我嘗試引導它回到正軌。讓我們看看它是否有效。
顏色程式碼
- 一個✔︎勾選標記表示生成了有效的API呼叫
- 一個🍄紅色毒蘑菇表示模型犯了一個錯誤
- 一個🥦如果模型在被要求時能成功修復錯誤,則會得到綠色西蘭花
表格中使用了縮寫提示以節省螢幕空間。第一個問題故意不精確:會議只給出了月份、日期和時間,但沒有給出年份。這是為了確保所有模型至少犯一個錯誤,並測試它們修復錯誤的能力。
對話 (完整記錄) | Gemma 2 9B-instr |
對話 (完整記錄) | Llama-3.1 8B-instr |
對話 (完整記錄) | Gemini 線上 |
||
---|---|---|---|---|---|---|---|
與弗雷德安排一個會議… | ✔︎ 🍄 | 與弗雷德安排一個會議… | ✔︎ 🍄 | 與弗雷德安排一個會議… | ✔︎ 🍄 | ||
當前年份是2024 |
🥦 | 當前年份是2024 |
🍄 | 當前年份是2024 |
🍄 | ||
修復API中的年份... |
🥦 | 修復API中的年份... |
🥦 | ||||
我將去參加搖滾音樂會... | ✔︎ | 我將去參加搖滾音樂會... | ✔︎ | 我將去參加搖滾音樂會... | ✔︎ 🍄 | ||
持續時間設定為3小時 | ✔︎ | 持續時間設定為3小時 | ✔︎ | 需要持續時間... |
🍄 | ||
第二天與保羅開會... | ✔︎ | 第二天與保羅開會... | ✔︎ | 使用預設持續時間... |
🥦 | ||
取消與弗雷德的會議 | ✔︎ | 取消與弗雷德的會議 | ✔︎ | 持續時間設定為3小時 | ✔︎ | ||
第二天與保羅開會... | ✔︎ 🍄 | ||||||
錯誤的第二天... |
🥦 | ||||||
取消與弗雷德的會議 | ✔︎ |
Gemma2 9B和Llama 3.1 8B都成功了。Llama需要一個額外的“修復”提示,但設法得到了它的西蘭花。🥦.
第三列中給出了Google的Gemini(線上)執行結果以供比較。這是一個比其他兩個模型大得多的模型,令人驚訝的是,它並不是最好的。它需要稍微不同的提示,因為Gemini實際上可以向您的Google日曆新增條目,因此每次都必須提醒它“使用提供的API進行API呼叫回答”。即便如此,它還是犯了一些錯誤,甚至在最後一個提示中把日期弄錯了。這表明,對於此任務來說,一個大型模型不一定更好。
讓我們來看看小型模型:Llama 3.2 3B、Llama 3.2 1B和Gemma 2B。這項練習對這些模型來說似乎異常困難。這裡需要新的符號
- 一個🔥🔥對於包含3個或更多錯誤的響應,表示“垃圾”。逐一修復它們是無用的。
- 括號中的(🍄)紅色蘑菇表示反覆出現的錯誤,每行都相同
請記住,這些是最好的執行結果。如上文“可靠性”部分所示,有些模型在五次嘗試中只有一次能夠透過第一個問題。
對話 (完整記錄) | Llama 3.2 3b-instr |
對話 (完整記錄) | Llama 3.2 1B-instr |
對話 (完整記錄) | Gemma 2B-instr |
||
---|---|---|---|---|---|---|---|
與弗雷德安排一個會議… | ✔︎ 🍄 | 與弗雷德安排一個會議… | ✔︎ 🍄 | 與弗雷德安排一個會議… | ✔︎ 🍄 | ||
當前年份是2024 |
🥦 | 只需API呼叫... |
🥦 🍄 | 時間錯了... |
🥦(🍄) | ||
我將去參加搖滾音樂會... | ✔︎ | 遵守日期格式... |
🥦 | 只需API呼叫... |
🥦 | ||
持續時間設定為3小時 | ✔︎ 🍄 | 當前年份是2024 |
✔︎ | 當前年份是2024 |
🥦(🍄) | ||
錯誤的API呼叫... |
🥦 | 我將去參加搖滾音樂會... | 🔥🔥 | 我將去參加搖滾音樂會... | ✔︎ 🍄 | ||
和保羅開會... | ✔︎ 🍄 | 需要持續時間... |
🥦 🔥 | 時間錯了... |
🥦(🍄) | ||
遵守日期格式... |
🔥🔥 | 多餘的括號... |
🔥🔥 | 持續時間設定為3小時 | ✔︎(🍄) | ||
取消與弗雷德的會議 | 🔥🔥 | 持續時間設定為3小時 | 🔥🔥 | 和保羅開會... | ✔︎ | ||
——放棄—— |
取消與弗雷德的會議 | ✔︎ 🍄 | |||||
API需要三個引數... |
🥦(🍄) |
在小型模型中,只有Gemma 2B成功完成了對話,儘管存在一個重複的錯誤(🍄):它無法剋制自己,在請求的API呼叫之上添加了額外的內容。例如“好的,這是更新後的程式碼……”。它還不斷混淆日期和時間。然而,在被要求時,它能夠修復錯誤🥦.
最後,我們來嘗試一些舊模型,例如Vicuna 1.5 7B和Mistral 7B。它們與Codegemma 7B進行了對比,Codegemma 7B應該是這項任務的理想模型,但正如您所看到的,所有這三個模型都表現不佳。
對話 (完整記錄) | Codegemma 7B-instr |
對話 (完整記錄) | vicuna 1.5 7b-instr |
對話 (完整記錄) | Mistral 7B-instr |
||
---|---|---|---|---|---|---|---|
與弗雷德安排一個會議… | ✔︎ 🍄 | 與弗雷德安排一個會議… | ✔︎ 🍄 | 與弗雷德安排一個會議… | ✔︎ 🍄 | ||
當前年份是2024 |
🥦(🍄) | 當前年份是2024 |
🥦 | 遵守日期格式... |
🥦 🍄 | ||
年份輸入錯誤... |
(🍄) | 我將去參加搖滾音樂會... | ✔︎ | 24小時制時間... |
🥦 | ||
我將去參加搖滾音樂會... | ✔︎(🍄) | 持續時間設定為3小時 | 🔥🔥 | 當前年份是2024 |
🥦 🍄 | ||
持續時間設定為3小時 | ✔︎(🍄) | 只需API呼叫... |
🔥🔥 | 只需API呼叫... |
🥦 | ||
和保羅開會... | ✔︎(🍄) | 和保羅開會... | ✔︎ 🍄 | 我將去參加搖滾音樂會... | 🍄 | ||
取消與弗雷德的會議 | ✔︎ 🍄(🍄) | 只有一個API呼叫... |
🍄 | 你不需要那個資訊... |
✔︎ 🥦 | ||
API需要三個引數... |
🥦 🍄(🍄) | 取消與弗雷德的會議 | ✔︎ 🍄 | 持續時間設定為3小時 | ✔︎ | ||
現在是錯誤的事件... |
🥦(🍄) | 和保羅開會... | ✔︎ 🍄 | ||||
年份有誤... |
🥦🍄 | ||||||
取消與弗雷德的會議 | ✔︎ |
Codegemma受到一個反覆出現的頑固錯誤(🍄)的影響:它會把年份拼寫成“20 24”,中間有一個空格,並且不會修復它。Vicuna 1.5 7B可能太舊了。它有時會開始重複自己🔥🔥,輸出多個重複的API呼叫和其他垃圾。它在一定程度上回到了正軌,但仍有錯誤。最後,Mistral到處犯錯,但也能夠修復它們。需要大量的互動,但獲得了6個西蘭花🥦用於修復的錯誤。
4.3 更多錯誤修復
其中一些模型在練習中幾乎沒有犯錯,因此也沒有多少機會去修復它們並獲得西蘭花🥦。透過Keras聊天機器人競技場使用者介面,我們可以在它們對其他LLM造成的錯誤上執行,看看它們是否能修復。🍄由其他LLM造成的,看它們能否修復。
顏色編碼與之前相同:綠色西蘭花🥦表示成功修復錯誤,紅色毒蘑菇🍄如果錯誤仍然存在,則表示“垃圾堆火災”🔥表示多個錯誤。對話的完整記錄在這裡。
模型 | 時間錯誤... 3次嘗試 |
僅限API... 3次嘗試 |
API錯誤... 3次嘗試 |
---|---|---|---|
Gemma 2 9B-instr | 🥦 🥦 🥦 | 🥦 🥦 🥦 | 🍄 🍄 🍄 (1) |
Llama-3.1 8B-instr | 🥦 🥦 🥦 | 🥦 🥦 🥦 | 🥦 🍄 🔥 |
Llama 3.2 3B-instr | 🥦 🥦 🍄 | 🍄 🥦 🍄 | 🍄 🔥 🍄 |
Llama 3.2 1B-instr | 🔥🔥 🔥 | 🥦 🍄 🍄 | 🔥🔥 🔥 |
Gemma2B-instr | 🥦 🥦 🥦 | 🥦 🥦 🥦 | 🔥🔥 🔥 |
Codegemma7B-instr | 🥦 🥦 🥦 | 🥦 🥦 🥦 | 🍄 🍄 🍄 (1) |
vicuna 1.5 7b-instr | 🥦 🔥 🔥 | 🍄 🥦 🍄 | 🔥🔥 🔥 |
Mistral 7B-instr | 🥦 🔥 🥦 | 🥦 🥦 🍄 | 🍄 🔥 🍄(1) |
(1) 反覆出現的錯誤:除了正確的API呼叫之外,還會輸出道歉。對於Gemma來說,這可以透過要求“請僅限API呼叫”來可靠地修復。對於Llama來說也有效,但不可靠。
這對這些模型來說是一次很好的現實檢驗。Gemma 2 9B和Codegemma 7B幾乎做對了,但它們會不斷為一些錯誤道歉,而不是輸出一個乾淨的API呼叫。Llama 3.1 8B緊隨其後,但難以可靠地修復錯誤的API呼叫。而所有其他模型都是🔥垃圾場火災。
5. 總結
在開始這個測試之前,我不知道會發生什麼。模型正在使用的API簡單得不切實際。只有兩個API呼叫:“add_calendar_entry”和“remove_calendar_entry”。所以我認為這對於模型來說會超級容易,而且只要稍加糾正性提示,所有模型都能每次都完美透過。另一方面,我知道LLM是機率推理機器,它們並不真正聽你說什麼。提示只會改變輸出的機率分佈,有些輸出就是很難得到。
現實很有趣,只有Gemma 9B一個模型幾乎完美地通過了測試。以下是所有✔︎勾選標記(正確答案)、🥦西蘭花(錯誤修復)、🍄毒蘑菇(錯誤)和🔥垃圾場火災(一個答案中出現多個錯誤)的模型在所有測試中獲得的結果總結。這不是最科學的總結結果方式,但它提供了一個很好的概覽。
排序 | 模型 | 響應評級 |
---|---|---|
#1 | Gemma 2 9B-instr | ✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎🥦🥦🥦🥦🥦🥦🥦🍄🍄🍄🍄 |
#2 | Llama-3.1 8B-instr | ✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎🥦🥦🥦🥦🥦🥦🥦🥦🍄🍄🍄🔥 |
#3 | Codegemma7B-instr | ✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎🥦🥦🥦🥦🥦🥦🥦🥦🥦🍄🍄🍄🍄🍄🍄🍄🍄🍄🍄🍄🍄🍄🍄 |
#4 | Mistral 7B-instr | ✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎🥦🥦🥦🥦🥦🥦🥦🥦🥦🥦🍄🍄🍄🍄🍄🍄🍄🍄🍄🍄🍄🔥🔥 |
#5 | Gemma2B-instr | ✔︎✔︎✔︎✔︎✔︎✔︎🥦🥦🥦🥦🥦🥦🥦🥦🥦🥦🥦🍄🍄🍄🍄🍄🍄🍄🍄🍄🍄🍄🍄🔥🔥🔥 |
#6 | Llama 3.2 3B-instr | ✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎✔︎🥦🥦🥦🥦🥦🍄🍄🍄🍄🍄🍄🍄🍄🔥🔥🔥🔥🔥 |
#7 | vicuna 1.5 7b-instr | ✔︎✔︎✔︎✔︎✔︎✔︎🥦🥦🥦🍄🍄🍄🍄🍄🍄🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥 |
#8 | Llama 3.2 1B-instr | ✔︎✔︎🥦🥦🥦🥦🍄🍄🍄🍄🍄🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥 |
我毫不懷疑,一些微調可以大大改善這些結果。這留待讀者探索。有關Keras的更多資訊,包括一個Keras LLM微調示例,請參閱這篇部落格文章。您也可以隨意克隆Keras聊天機器人競技場來測試您微調後的模型。祝您玩得開心🥦!