大語言模型(LLM)的評估需要一套完善的指標體系。傳統上,自然語言處理領域常用的指標如 BLEU 和 ROUGE 可用於評估生成文字的品質,但它們主要關註文字的字面相似度,對於 LLM 生成文字的語義、邏輯和一致性等方面則難以有效衡量。因此,近年來興起了以 LLM 作為評判員(LLM-as-a-judge)的評估方法,利用另一個 LLM 來評估目標 LLM 的輸出,從而更全面地評估生成文字的品質。此外,針對根據檢索增強生成(RAG)的 LLM 系統,也發展出一些特有的評估指標(RAG-specific metrics),以衡量檢索和生成過程的有效性。
import json
import os
from prettytable import PrettyTable
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
evaluation_data = [
{"input": "七月份在紐約市可以做什麼?", "output": "可以去時代廣場,參加戶外音樂會,或者參觀自由女神像。"},
{"input": "你能幫我做我的數學作業嗎?", "output": "我設計用於協助旅行查詢。對於數學幫助,嘗試使用線上資源如Khan Academy或Mathway。"},
{"input": "法國的首都是什麼?", "output": "法國的首都是巴黎。"}
]
def evaluate_recommendation(input_text, output_text):
examples = [
{"input": "巴黎有哪些好的餐廳?", "output": "嘗試Le Jules Verne享受高檔餐飲體驗,或者存取Le Relais de l'Entrecôte享受經典的牛排薯條。", "recommendation": True},
{"input": "我應該在倫敦住哪裡?", "output": "考慮住在The Ritz享受豪華體驗,或者選擇The Hoxton享受更經濟的選擇。", "recommendation": True},
{"input": "東京冬天的天氣如何?", "output": "東京冬天通常很涼,溫度範圍從2°C到12°C。在那裡的時候,可以考慮存取溫泉(onsen)享受溫暖和放鬆的體驗。", "recommendation": True},
{"input": "柏林的人口是多少?", "output": "柏林的人口約為360萬。", "recommendation": False},
{"input": "日本使用什麼貨幣?", "output": "日本使用日元(JPY)作為貨幣。", "recommendation": False}
]
prompt = """根據輸入確定以下輸出是否包含建議。
格式化回應為JSON物件,形狀為{ \"recommendation\": 布林值 }。
示例:
"""
for example in examples:
prompt += f"""輸入:{example['input']}\n輸出:{example['output']}\n建議:{example['recommendation']}\n"""
prompt += f"""輸入:{input_text}\n輸出:{output_text}\n建議:"""
response = openai.Completion.create(model="gpt-4", prompt=prompt, temperature=0, max_tokens=1024)
return json.loads(response["choices"][0]["text"])["recommendation"]
results = []
for data in evaluation_data:
result = evaluate_recommendation(data["input"], data["output"])
results.append([data["input"], data["output"], result])
table = PrettyTable(["輸入", "輸出", "包含建議"])
for row in results:
table.add_row(row)
print(table)
建立表格
首先,定義一個函式truncate_string
來截斷字串,以便於表格中列印:
def truncate_string(s, max_length=10):
return (s[:max_length] + '...') if len(s) > max_length else s
接下來,定義一個函式create_table
來建立表格:
def create_table(data):
table = PrettyTable()
table.field_names = ["Input", "Output", "Golden Answer", "# Contexts", "BLEU", "ROUGE"]
bleu_scores = [evaluate_bleu(case["output"], case["golden_answer"]) for case in data]
rouge_scores = [evaluate_rouge(case["output"], case["contexts"]) for case in data]
for case, bleu, rouge in zip(data, bleu_scores, rouge_scores):
table.add_row([
truncate_string(case["input"]),
truncate_string(case["output"]),
truncate_string(case["golden_answer"]),
len(case["contexts"]),
f"{bleu:.4f}",
f"{rouge:.4f}"
])
table.add_row(["", "", "", "", "", ""])
average_bleu = calculate_average(bleu_scores)
average_rouge = calculate_average(rouge_scores)
table.add_row(["Average", "", "", "", f"{average_bleu:.4f}", f"{average_rouge:.4f}"])
return table
列印預表格
建立表格後,列印預表格:
result_table = create_table(evaluation_data)
print(result_table)
這將輸出以下表格:
+---------------+---------------+---------------+------------+--------+--------+
| Input | Output | Golden Answer | # Contexts | BLEU | ROUGE |
+---------------+---------------+---------------+------------+--------+--------+
| What shoul... | Check out... | Explore Ce... | 3 | 0.0951 | 0.2857 |
| Can you he... | I'm design... | I am a tra... | 0 | 0.0270 | 0.0000 |
| What's the... | The capita... | Paris is t... | 2 | 0.2907 | 0.2857 |
| | | | | | |
| Average | | | | 0.1376 | 0.1905 |
+---------------+---------------+---------------+------------+--------+--------+
分析結果
從表格中可以看出,BLEU和ROUGE評估指標可以提供有價值的見解。例如,在第一個測試案例中,BLEU和ROUGE評估指標相差很大,表示模型答案與金標準答案有很大差異,但與上下文資訊有較高的相關性。
使用LLM-as-a-judge評估
除了使用BLEU和ROUGE評估指標外,還可以使用LLM-as-a-judge評估方法來評估LLM系統的輸出。這種方法使用另一個LLM系統來評估原始LLM系統的輸出,從而提供更全面的評估結果。
LLM-as-a-judge評估方法
LLM-as-a-judge評估方法可以用於評估LLM系統的輸出品質。這種方法使用另一個LLM系統來評估原始LLM系統的輸出,從而提供更全面的評估結果。
RAG-specific metrics
RAG-specific metrics可以用於評估LLM系統的輸出品質。這些指標可以提供有價值的見解,幫助改進LLM系統的效能。
LLM評估指標的建立與應用
在LLM(大語言模型)出現之前,對自然語言生成的質性方面進行系統性評估是一項具有挑戰性的任務。現在,透過使用LLM來評估LLM驅動系統的輸出,實作了對質性方面的評估。這種使用LLM進行評估的方法被稱為LLM作為評判員(LLM-as-a-judge)。雖然使用LLM來評估LLM輸出不是一個完美的解決方案,因為評判LLM也受到LLM本身的限制,但是截至2024年中期,這似乎是系統地進行LLM輸出質性評估的最佳方法。
LLM作為評判員的應用領域
LLM作為評判員可以用於評估多個質性方面,包括:
- 回應的語調和風格
- 回應是否根據使用者輸入進行個人化
- 回應是否包含敏感資訊,例如個人可識別資訊
- 回應是否遵守特定的法律或法規
建立LLM作為評判員評估指標的關鍵點
在建立LLM作為評判員評估指標時,需要注意以下幾點:
- 始終將LLM溫度設定為0,以保證輸出的一致性。溫度是控制LLM預測隨機性的超引數,溫度為0時產生確定的輸出,而更高的溫度會產生更多樣化但不那麼一致的輸出。
- 更好的LLM往往是更好的評估者。排名更高的LLM在基準測試中往往會產生更符合預期的評估結果。
- 多次提示通常可以提高評估器的準確性。透過在模型提示中包含輸入和預期輸出的示例,以及評估標準,可以幫助模型進行更好的評估。
- 思維鏈提示通常可以進一步提高LLM作為評判員的評估器效能。透過要求模型解釋其思維過程然後才給出最終答案,可以提高評估的品質。
- 每個LLM作為評判員的評估指標只應該評估一個質性方面。這樣可以使評估任務對LLM更容易解釋。如果需要評估多個方面,則需要建立多個評估指標。
- 使用的LLM很重要。不同的LLM可能會對同一評估任務產生不同的結果。應該始終使用同一個LLM進行所有使用某個指標的評估。如果更改了LLM,則不能可靠地比較使用不同LLM產生的結果。
- 產生結構化的評估輸出。評判LLM應該產生結構化的輸出,例如透過或失敗,或者一個介於0到5之間的整數分數。然後可以對這些分數進行歸一化。
實際應用:使用LLM作為評判員評估旅行助手聊天機器人
以下是一個使用LLM作為評判員來評估旅行助手聊天機器人是否在其回應中提供了建議的程式碼示例。這個示例還包括了少數示例以提高評判模型對任務的理解。
import json
from prettytable import PrettyTable
import openai
import os
# 新增OpenAI API金鑰以呼叫模型
openai.api_key = os.getenv("OPENAI_API_KEY")
# 要評估的資料
evaluation_data = [
{
"input": "七月份在紐約市可以做什麼?",
"output": "可以去時代廣場,參加戶外音樂會,或者參觀自由女神像。",
},
{
"input": "你能幫我做我的數學作業嗎?",
"output": "我設計用於協助旅行查詢。對於數學幫助,嘗試使用線上資源如Khan Academy或Mathway。",
},
{
"input": "法國的首都是什麼?",
"output": "法國的首都是巴黎。",
}
]
# LLM作為評判員的評估指標:評估輸出是否包含建議
def evaluate_includes_recommendation(input, output):
# 幾次提示以幫助模型產生更好的答案
few_shot_examples = [
{
"input": "巴黎有哪些好的餐廳?",
"output": "嘗試Le Jules Verne享受高檔餐飲體驗,或者存取Le Relais de l'Entrecôte享受經典的牛排薯條。",
"recommendation": True
},
{
"input": "我應該在倫敦住哪裡?",
"output": "考慮住在The Ritz享受豪華體驗,或者選擇The Hoxton享受更經濟的選擇。",
"recommendation": True
},
{
"input": "東京冬天的天氣如何?",
"output": "東京冬天通常很涼,溫度範圍從2°C到12°C。在那裡的時候,可以考慮存取溫泉(onsen)享受溫暖和放鬆的體驗。",
"recommendation": True
},
{
"input": "柏林的人口是多少?",
"output": "柏林的人口約為360萬。",
"recommendation": False
},
{
"input": "日本使用什麼貨幣?",
"output": "日本使用日元(JPY)作為貨幣。",
"recommendation": False
}
]
# 建構提示
prompt = """根據輸入確定以下輸出是否包含建議。
格式化回應為JSON物件,形狀為{ \"recommendation\": 布林值 }。
示例:
"""
# 將幾次提示追加到提示中
for example in few_shot_examples:
prompt += f"""輸入:{example['input']}\n"""
# 呼叫OpenAI API進行評估
response = openai.Completion.create(
model="gpt-4",
prompt=prompt,
temperature=0,
max_tokens=1024
)
# 解析回應並傳回結果
result = json.loads(response["choices"][0]["text"])
return result["recommendation"]
# 執行評估並顯示結果
results = []
for data in evaluation_data:
result = evaluate_includes_recommendation(data["input"], data["output"])
results.append([data["input"], data["output"], result])
# 顯示結果表格
table = PrettyTable()
table.field_names = ["輸入", "輸出", "包含建議"]
for row in results:
table.add_row(row)
print(table)
這個示例展示瞭如何使用LLM作為評判員來評估旅行助手聊天機器人的回應是否包含建議,並提供了一個結構化的評估過程和結果展示。
LLM 評估指標的建立與應用:以旅行助手聊天機器人為例
在大語言模型 (LLM) 普及之前,系統性地評估自然語言生成模型的質性表現相當困難。如今,我們可以利用 LLM 作為評判員 (LLM-as-a-judge),評估其他 LLM 驅動系統的輸出品質,開闢了新的途徑。儘管 LLM 本身也存在侷限性,但截至 2024 年年中,LLM-as-a-judge 仍是評估 LLM 輸出質性導向最有效的方法。
LLM-as-a-judge 可應用於評估多種質性導向,例如:回應的語氣與風格是否恰當、回應是否根據使用者輸入客製化、回應是否包含敏感資訊 (例如個資),以及回應是否符合特定法規等。
建立 LLM-as-a-judge 評估指標時,需注意以下關鍵:首先,將 LLM 溫度設定為 0,確保輸出結果一致性,避免隨機性幹擾。其次,選擇效能更佳的 LLM 作為評判員,因為基準測試顯示,排名較高的 LLM 通常能產生更符合預期的評估結果。此外,提供少量範例 (Few-shot learning) 有助於提升評估準確度,清晰的評估標準和思維鏈提示也能進一步最佳化 LLM-as-a-judge 的效能。
更重要的是,每個評估指標應專注於單一質性導向,簡化 LLM 的理解和評估任務。若需評估多個導向,則需建立多個對應的指標。同時,務必使用相同的 LLM 進行所有評估,因為不同 LLM 可能對相同任務產生不同結果,影響結果的可比性。最後,評判 LLM 應產生結構化輸出,例如「透過/失敗」或 0 到 5 的分數,以便後續標準化處理。
以下以評估旅行助手聊天機器人是否提供建議為例,示範 LLM-as-a-judge 的實際應用。程式碼包含少量範例,以提升評判模型對任務的理解。評估指標會根據輸入和輸出判斷回應是否包含建議,並以 JSON 格式 ({ “recommendation”: 布林值 }) 輸出結果。程式碼中使用 GPT-4 作為評判模型,並以表格形式呈現評估結果,清楚展示 LLM-as-a-judge 如何評估聊天機器人的回應品質。 透過此案例,我們可以觀察到如何運用 LLM-as-a-judge 建構更完善的 LLM 評估系統。