釋出 Outlines-core 0.1.0:Rust 和 Python 中的結構化生成
dottxt 和 Hugging Face 很高興地宣佈,我們一直在合作開發 outlines-core,它是 outlines 用於結構化生成的核心演算法的 Rust 版本。除了透過 outlines 從 LLM 獲得可靠的輸出外,這個 Rust 版本還為 outlines 使用者提供了以下幾個額外的好處:
- 速度:使用者可以期望索引編譯速度提高 2 倍。
- 關注點分離:現在更容易將結構化生成整合到其他庫中。
outlines-core
非常輕量。 - 可移植性:將核心演算法用 Rust 編寫允許繫結其他語言而非僅限於 Python。
這些改進不僅應該提高現有 outlines
使用者的效能,而且還應該極大地增加使用者將結構化生成整合到其 LLM 工作流中的方式。outlines-core
現已公開,整合到 outlines
中,並且 Python 繫結 0.1.0
版本已釋出。您可以在此處找到倉庫。
結構化生成快速入門 🧑🎓
工作原理
結構化生成意味著您的 LLM 被保證遵循所需的格式。這可以是 JSON、Pydantic 模型、正則表示式或上下文無關語法。關鍵在於結構化生成禁止生成“錯誤”的標記。
讓我們舉一個非常簡單的例子。LLM 應該生成一個布林值,“true”或“false”。僅此而已。為了說明,假設 LLM 生成字元而不是標記。因此,第一個字元是 "
,我們可以直接跳過前向傳播。對於第二個字元,我們不需要從所有可能的字元中取樣。LLM 應該只在 t
或 f
之間選擇。
在那之後,無論我們走哪條路徑,都只有一個有效的下一個字元。如果 LLM 選擇 t
作為第一個字元,那麼它必須跟著 r
、u
和 e
。類似地,如果它選擇 f
,它將跟著 a
、l
、s
、e
。並且無論路徑如何,都將選擇最後一個 "
作為最終字元。當然,這其中還有更多幕後細節,如需更深入的介紹,我們推薦這篇dottxt 部落格和arxiv 上的相關論文。
為什麼它很重要
結構化生成可能不會立即顯得如此驚豔。許多人首先想到的用例是“太好了,現在我的 LLM 可以返回有效的 JSON,所以我可以將其視為 API 並可靠地序列化/反序列化 JSON”。但這只是冰山一角。仔細想想,結構無處不在,甚至在最意想不到的地方,比如 GSM8K 基準測試。
以下是結構化生成所實現功能的幾個示例:
而且,或許更令人驚訝的是,它降低了評估對所使用的特定提示和樣本數量的敏感性。除了結構帶來的驚人技巧之外,它的效能也更高。dottxt 部落格上有很多關於效能基準的優秀文章。
為什麼用 Rust 重寫?🦀
速度
當您聽到“用 Rust 重寫”時,您首先想到的可能是效能。是的,outlines-core
也是如此。儘管還有幾個關鍵部分尚未遷移到 Rust,但我們已經看到了編譯速度平均提高 2 倍。
在 Rust 移植之前,Outlines 使用 Numba 來加速索引的構建。雖然 Numba 很快(執行時效能與 Rust 相當),但 Numba 函式的 JIT 編譯在首次執行時增加了延遲源,這讓許多使用者感到沮喪。使用 Rust 意味著我們可以提前編譯索引構建函式,在首次執行時不會增加延遲。雖然這在生產環境中並不重要(因為首次執行可以在部署過程中完成),但在實驗階段卻能產生巨大的影響!
安全性和可靠性
用 Rust 重寫 Outlines 的主要原因之一是 Rust 帶來的安全性和可靠性。Rust 強大的靜態型別,結合其所有權模型,消除了整類錯誤,例如空指標解引用和併發程式碼中的資料競爭。這使得軟體更加健壯和安全。
在 Outlines 的上下文中,安全性至關重要。結構化生成通常涉及複雜的資料結構和操作,尤其是在處理高效能推理引擎時。透過利用 Rust 的安全保證,我們降低了因記憶體管理不當而導致執行時錯誤和未定義行為的風險。
此外,Rust 的編譯時檢查鼓勵開發人員編寫更清晰、更易於維護的程式碼。這改進了現有程式碼庫,並使未來的開發更高效。新貢獻者可以更快地加入,並且程式碼更容易審計和驗證正確性。
關注點分離
Outlines 的設計不僅僅是為了提供結構化生成的核心演算法。除其他功能外,它還包括與 transformers
等其他庫的整合,這意味著該庫包含許多依賴項。將核心演算法與 Outlines 庫分離意味著其他希望包含結構化生成的庫可以透過匯入一個非常輕量級的庫來實現。因此,我們可以想象在不久的將來,transformers
和 llama-cpp-python
等庫將直接整合結構化生成。這使得 dottxt 團隊能夠專注於核心演算法。
可移植性
大多數 LLM 訓練都是用 Python 編寫的,但推理略有不同。它發生在許多不同的裝置上,在專門的伺服器上,並且是用一系列程式語言編寫的。這就是為什麼可移植性對結構化生成也很重要。透過用 Rust 編寫 outlines
的核心功能,我們現在可以建立與其他語言的繫結。
例如,此移植使得與 text-generation-inference 的整合更加順暢。TGI 的伺服器邏輯是用 Rust 編寫的,我們希望儘可能避免呼叫 Python 程式碼。這也意味著像 mistral.rs
或使用 candle 實現的模型可以受益於 Outlines 的效能和功能。
未來我們計劃探索 JS/TS 繫結,允許在 transformers-js 中使用 outlines。或者可能是 Swift 繫結,使 outlines 能夠在 Apple 裝置上本地使用。但目前,重點將放在 Python 繫結上,並透過擴充套件對 JSON Schema 規範的支援,繼續完善 outlines-core
的功能集。
貢獻
您喜歡使用結構化生成、解析器,讓 LLM 只輸出有效的 JSON 嗎?為這個庫加星,在 Twitter 上分享,加入並貢獻!在 Twitter 上,以及與 dottxt 和 Hugging Face 社群分享您的工作。