Medium 好讀版: https://bit.ly/4fpxwdn
大型語言模型 (LLM) 為自動化工作流程提供了很多幫助,
很多新的應用因為大型語言模型的出現,從不可能變為可能。
而為了使用模型的回答來串接不同的工作,
結構化輸出 (Structured Output) 幾乎不可或缺。
目前熱門的模型都有支援輸出特定的 JSON 格式,來方便程式處理模型的回答。
不過平常可能不太容易察覺,結構化輸出其實有它的缺點。
要求模型輸出特定的格式有機會降低模型的表現,甚至增加幻覺發生的機率。
大型語言模型如何產生結構化輸出?
想要讓模型照著我們的要求回答問題並不是一件簡單的事情,
資料科學家和工程師們為此提出了很多不同的解決方案。
而目前被廣泛應用到實際產品的方式,
是透過建立目標格式的語法樹來限制模型每一次輸出的 token。
知名的實作有開源的 lm-format-enforcer (LMFE)
或是 Google DeepMind 基於 OpenFST 的實作。
雖然在名詞的使用上各家並沒有統一,但概念上是相似的。
大方向就是強迫模型輸出符合當前語法狀態的 token,遍歷目標語法樹直到結束狀態。
這個方法的可靠性和效率非常高,幾乎可以確保輸出的格式符合規範。
但,最重要的永遠是這個但是,
強迫模型輸出特定的格式意味著每一次輸出的 token
不一定是能夠回答問題的的最佳解。
模型極有可能為了符合格式,讓下一個產生的 token 偏離了正確答案。
隨著任務的複雜度和輸出的增加,這樣的偏差最終就可能導致幻覺或錯誤的回答。
讓模型先好好說話!
要解決這樣的問題,有一個容易且直覺的方法:
不要限制模型輸出的格式,讓它好好回答問題。
取得答案之後,我們再要求模型將答案轉換成我們要的格式。
這個方法適用在有較長前後文 (Context) 的複雜任務,
因為輸出的內容通常較精簡,模型便可以正確的轉換格式。
但這個方法具體倒底能改進多少輸出的品質呢?
來作個實驗!
為了量化結構化輸出對模型表現的影響,
筆者收集了一週份來自立法院的會議紀錄和質詢逐字稿,
總計約 400,000 個 tokens 的文字資料來設計實驗。
完整的資料可以在立院知更的每週新聞下載。
https://lyrobin.com/news
任務目標是請模型整理出當週立法院討論的議題,並做成新聞標題。
在選題上,我們要求模型盡可能的挑選不同領域的議題,
並希望可以避免標題間太過相似。
因此若是模型輸出的標題重覆性越高,則輸出的品質越低。
我們將輸出的標題透過 text embedding 輸出成 embedding vectors,
透過兩兩配對標題並計算彼此的相似度後取平均值,
就可以評估模型的表現。
以下的程式碼分別實作了兩個不同的方法:
1. 立即使用結構化輸出
2. 先不使用結構化輸出,後續多用一個提示來整理輸出格式。
以下我們稱前後者分別為一步和二步驟提示。
https://imgur.com/XJbjNh3
https://imgur.com/MrQswF1
程式的輸出和標題相似度的範例如下。
https://imgur.com/5ifasRa
最後我們用標題間的相似度畫出分布圖,可以得到以下的結果。
https://imgur.com/i2zAPBN
https://imgur.com/KzBcQ8R
可以看到二步驟提示得到的標題彼此間相以度較低,
因此議題的差異較高,更符合我們設定的目標。
總結
從我們的實驗可以觀察出,
透過二步驟提示先讓模型好好針對問題回答,
再修改成特定格式有助於提升模型的表現。
因此若是輸入的前後文較長,且任務要求比較複雜,
可以透過這個方法來有效的改善輸出的品質。
希望這個小技巧能對你有一點幫助,
有任何的問題或指教都歡迎留言和我討論。
===========================
最後小小的宣傳一下我開發的服務:立院知更。
https://lyrobin.com/
這是一個使用大型語言模型實作的立法院搜尋引擎,
我們希望透過建立更加直覺且便利的立院搜尋引擎,
讓所有人能夠輕易地使用關鍵字搜尋到立院中各種相關文檔及影音資料,
進而提升公民參與。
有任何的想法或意見,都歡迎來信討論!
參考資料
1. Automata-based constraints for language model decoding
https://arxiv.org/abs/2407.08103v1
2. lm-format-enforcer
https://github.com/noamgat/lm-format-enforcer
--