
第二部分:使用小型開源LLMs進行訊息提取
小型開源LLMs簡介
在AI和機器學習領域,小型開源大型語言模型(LLMs)的出現,特別是對於像金融這樣數據安全和保密至關重要的行業來說,已經是一個遊戲規則改變者。這些模型提供了強大的語言處理能力和本地部署的靈活性,使它們成為金融機構的理想選擇。
為何小型LLMs對金融機構至關重要
- 保密性和數據安全:金融機構處理敏感信息,包括法律和道德上禁止與外部分享的機密交易細節。利用本地託管的LLMs確保所有數據處理在內部進行,維護數據保密性並遵守嚴格的監管標準。
- 定制化和控制:開源LLMs提供了根據特定機構需求定制化的靈活性。金融機構可以調整這些模型,更好地理解和處理其獨特的金融術語和交易語言,增強模型的相關性和準確性。
- 成本效益和可訪問性:較小的LLMs資源需求較低,為可能沒有支持像GPT-4這樣的大型模型的基礎設施的金融機構提供了更可訪問和成本效益更高的解決方案。這使得先進的AI技術可為更廣泛的機構所用,實現對尖端工具的普及。
利用小型開源LLMs提取交易信息的過程
我們把利用LLMs從金融交易對話中提取有意義的信息分為兩個步驟。第一步識別對話中的交易類型,然後使用為每種交易類型量身定做的模板提取特定的交易信息。本篇文章說明如何識別交易類型,下一篇介紹如何提取交易信息。
步驟一:識別交易類型
第一個關鍵步驟涉及從文本對話數據中確定交易類型。過程如下:
- 合成數據生成:我們在第一部分:利用知識蒸餾生成合成交易信息中生成了一些交易數據。以下是一個例子:
{
"model": "gpt-4-1106-preview",
"trade_type": "FX Double Barrier Knock-In Option",
"currency": "NZDUSD",
"trader1": {
"name": "Alice",
"style": "descriptive",
"emotion": "skeptical",
"tone": "neutral",
"attitude": "open-minded",
"perspective": "first-person"
},
"trader2": {
"name": "Bob",
"style": "conversational",
"emotion": "happy",
"tone": "passive",
"attitude": "contrary",
"perspective": "local"
},
"deal": {
"trade_type": "FX Double Barrier Knock-In Option",
"currency_pair": "NZDUSD",
"lower_barrier": "1.2500",
"upper_barrier": "1.3500",
"strike_price": "1.3000",
"expiry_date": "2024-07-01",
"option_type": "Call",
"premium": "0.0180",
"amount": "500000",
"buyer": "Alice",
"seller": "Bob",
"conversation": [
{
"name": "Alice",
"message": "I'm exploring the idea of a double barrier knock-in option on NZDUSD. I want the lower and upper barriers set at 1.2500 and 1.3500, respectively, with a strike price at 1.3000."
},
{
"name": "Bob",
"message": "Oh, how delightful! A double barrier knock-in option, you say? Setting the lower barrier at 1.2500 and the upper one at 1.3500 sounds like an adventure. And the strike at 1.3000, correct?"
},
{
"name": "Alice",
"message": "Correct. The focus should be on protecting the position, considering the volatility in the NZDUSD pair. Do you have any thoughts on the premium and amount?"
},
{
"name": "Bob",
"message": "Well, if we're taking a stroll through this garden, I'd say a premium of 0.0180 for an amount of 500,000 sounds like the right path to take. It's congenial, yet considerate of the risks."
},
{
"name": "Alice",
"message": "That premium seems fair, given the constraints of the barriers. Let's formalize this option with an expiry of July 1st, 2024. Does that fit within your timeline?"
},
{
"name": "Bob",
"message": "Indeed, Alice, July 1st, 2024, as the expiry date is like the perfect time for this option to blossom. It's all coming together quite nicely."
},
{
"name": "Alice",
"message": "Great. We'll put this FX double barrier knock-in call option on NZDUSD in motion then. Just to recap: lower barrier at 1.2500, upper barrier at 1.3500, strike price at 1.3000, expiry date on 2024-07-01, option type 'Call', premium at 0.0180, for the amount of 500,000."
},
{
"name": "Bob",
"message": "What a splendid summary! Our little financial seedling is ready to be planted. I'll get the paperwork started. Pleasure doing this dance with you."
}
]
}
}
- 對話格式化:我們首先將原始對話數據格式化為適合LLM處理的連續文本流。
def conversation_to_text(conversation):
text = ""
for message in conversation:
text += message['name'] + ": " + message['message'] + "\n"
return text
- 交易類型定義:定義了21種不同類型的金融交易並由GPT-4生成模板。
trade_types=['FX Spot','FX Swap','FX Vanilla Option',
'FX Down and In Option', 'FX Down and Out Option',
'FX Up and In Option', 'FX Up and Out Option',
'FX Double Barrier Knock-In Option',
'FX Double Barrier Knock-Out Option',
'FX Range Accrual Option','Fixed-Floating IRS',
'Floating-Floating IRS','IRO Cap','Fixed-Fixed IRS',
'Stock','Single Stock Option','Bond','Commodity',
'Credit Default Swap','Equity Swap','Autocallable Swap']
trade_template={
"FX Spot": {
"trade_type": "FX Spot",
"currency_pair": "EURUSD",
"rate": "1.1800",
"amount": "1000000",
"trade_date": "2023-01-15",
"settlement_date": "2023-01-17",
"buyer": "Alice",
"seller": "Bob",
"conversation": [{"name": "Alice", "message": "Looking to buy EURUSD at 1.1800"}, {"name": "Bob", "message": "Confirmed, selling EURUSD at 1.1800"}]
},
"FX Swap": {
"trade_type": "FX Swap",
"near_leg": {
"currency_pair": "USDJPY",
"near_rate": "110.00",
"near_amount": "500000",
"near_date": "2023-01-15"
},
"far_leg": {
"currency_pair": "USDJPY",
"far_rate": "110.25",
"far_amount": "500000",
"far_date": "2023-06-15"
},
"buyer": "Alice",
"seller": "Bob",
"conversation": [{"name": "Alice", "message": "Looking to do a near/far swap on USDJPY"}, {"name": "Bob", "message": "Agreed on rates 110.00 and 110.25"}]
}
# templates for other trade types
]
LLM 提示用於交易類型識別:格式化對話後,將其輸入 LLM 並提示以識別交易類型。
trade_types_str=", ".join(map(str,trade_types))
question = "Given trade type is one of "+ trade_types_str + ".
return only in a valid JSON format contains 1 elements
{""trade_type"":""Type""}.
Identify the trade type from the following conversation: \n\n"
+ conversation_text
# response = LLM_API_Call(question)
# API call to LLM
- 對回應進行後處理:在提示 LLM 識別交易類型並提取特定交易資訊後,我們收到的回應有時並非立即可用的格式。這就是後處理變得至關重要的地方。它涉及將 LLM 的輸出細化為可有效分析和利用的結構化數據。以下是我們如何處理這一關鍵步驟:
- 提取核心回應:
LLM 的輸出可能包含與我們的分析無關的額外文字或格式。我們首先隔離核心回應 — — 我們需要的實際資訊。例如,如果我們正在尋找一個 JSON 物件,我們會提取符合 JSON 格式的回應部分。
def extract_core_response(answer):
start = answer.find('{')
end = answer.rfind('}') + 1
return answer[start:end]
2. 清理和格式化:
LLM 輸出可能包括轉義字符、錯放的符號或不一致的格式。我們的下一步是清理這些異常,以確保數據處於可用格式。
def clean_response(response):
cleaned = response.replace("\n", " ").replace("\", "")
return cleaned
3. 轉換為結構化數據:
特別是對於財務數據,首選結構化格式,如 JSON。我們將清理過的回應轉換為 JSON,處理可能出現的解析錯誤。
import json
def convert_to_json(cleaned_response):
try:
result = json.loads(cleaned_response)
except json.JSONDecodeError:
# Handle JSON conversion errors, possibly using regex or other methods
result = handle_parsing_error(cleaned_response)
return result
4. 處理解析錯誤:
在標準 JSON 解析失敗的情況下,我們實施額外的錯誤處理機制,如使用正則表達式來糾正常見的格式問題。
import re
def handle_parsing_error(response):
# Fix common JSON formatting issues using regex
fixed_response = re.sub('pattern_to_fix', 'replacement', response)
try:
return json.loads(fixed_response)
except json.JSONDecodeError:
return {'error': 'Failed to parse JSON', 'original_response': response}
5. 驗證和確認數據:
一旦我們將數據轉換為 JSON 格式,我們就根據預期的結構對其進行驗證,並確認其準確性。此步驟對於確保數據與我們的財務模型和分析要求相符非常重要。
if "trade_type" in processed:
df_types.loc[index,model+"_type"]=processed["trade_type"]
df_types.loc[index,model]=processed["trade_type"]==df_deals["trade_type"][index]
if df_types.loc[index,model]:
df_types.loc[index,"Matches"]+=1
else:
df_types.loc[index,"NotMatches"]+=1
else:
if retries==1:
df_types.loc[index,"NaN"]+=1
模型性能分析
| Model | Matches | NotMatches | NaN |
|--------------|---------|------------|-----|
| Mistral | 387 | 218 | 25 |
| Llama2:13b | 300 | 330 | 0 |
| Orca2:13b | 487 | 131 | 12 |
| Neural-Chat | 421 | 165 | 44 |
| Deepseek-LLM | 352 | 263 | 14 |
我們對各種大型語言模型(LLM)的實驗得出以下初步結論:
- 整體性能:不同模型在正確識別交易類型方面表現各異。Orca2:13b的匹配率最高,其次是Neural-Chat和Deepseek-LLM。
- 不一致性和挑戰:所有模型都面臨一些挑戰,如不匹配的數量和無法明確識別交易類型(無法辨識)的實例所示。
- 結果解釋:Orca2:13b的高匹配率表明其在理解金融對話方面的優越能力,而像Llama2:13b這樣的模型較低的無法辨識計數表明了更明確的回應模式,儘管不匹配數量較高。
模型性能結果的解讀
值得注意的是,上表中的結果是基於一項簡單且初步的實驗,主要目的在說明使用大型語言模型從對話中提取交易信息的過程。這些發現並不代表對模型性能的全面或科學評估。以下幾個因素會影響到結果:
- 實驗設計:這項實驗是一項快速且簡單的測試,目的展示使用LLM進行金融對話分析的可行性和方法論,而不是對模型能力進行嚴格評估。
- 樣本變異性:結果取決於測試中使用的特定樣本集。不同的對話數據集可能產生不同的結果,突出了數據集的性質和組成對模型性能的影響。
- 模型不一致性:基於複雜算法和大數據集的LLM尤其可能在其性能上表現出變異性。同一模型在不同的測試條件下或甚至在使用相同數據重新測試時可能會產生不同的結果,這是由於這些AI系統固有的隨機性質。
- 測試的目的:這項實驗的主要目的是闡明在金融背景下應用LLM的過程,而不是確定性地排名模型的有效性。結果應被視為LLM在這一應用領域的潛力的指示,而不是其相對性能的確鑿證據。
第二部分第一步的結論
隨著我們結束使用大型語言模型(LLM)進行金融數據提取的探索的這一部分,我們已經成功地完成了初始步驟:從對話數據中識別交易類型。這一階段在進行詳細分析的基礎設置中至關重要,展示了LLM在解讀複雜金融對話中的實際應用和潛力。
到目前為止,我們的實驗涉及格式化對話數據,提示LLM將這些數據分類為不同的交易類型,然後處理輸出以獲取可操作的信息。我們最初實驗的結果提供了各種LLM在理解和分類金融對話方面的能力初步認識。
下一步:提取交易信息
我們的下一部分將更深入地探討這一過程的第二步。在正確識別交易類型的基礎上,我們將探索如何利用LLM從這些對話中提取特定交易信息。這一步是真正的魔法發生之處 — — 將原始數據轉化為精確、有價值的洞察,以驅動金融背景下的決策制定。