圖解DSPy:Prompt的時代終結者?!
DSPy是一種編程模型,旨在改進語言模型 (LM)在復雜任務中的使用方式。傳統上,LM使用特定的提示模板(Prompt)進行控制,這些模板是基本前期大量的嘗試而找到的預設指令。DSPy通過將LM流水線抽象為文本轉化圖譜,例如被其他申明模塊觸發的LM的命令計算圖譜。
1.Prompt Engineering
要理解DSPy,需要先理解提示詞工程Prompt Engineering。提示詞工程也稱之為上下文提示詞或者上下文學習。它指的是在不更新模型權重的情況下引導LLM的行為以獲得預期結果的方法,它屬于非參數的模型微調。
20%的EMNLP'23的出版物都是關于提示詞工程,其中最受歡迎的字符串模板庫有LangChain和LlamaIndex。
提示詞工程很好用,簡單,高效而且低開銷。它在不占用GPU,5分鐘之內可以通過調用API快速的試錯,而且大部分的提示詞可以用一到兩句話來解釋。
上圖為提示詞工程的示例,加上一句話“按照artstation的風格來”,結果大不一樣。
但是提示詞工程最大的問題是它很脆弱,而且缺乏系統性的方法來提升。很多的技巧需要大量的實驗和啟發式方法,結果不能普遍應用于所有 LLMs/VLM,甚至不能應用于同一LLM家族的不同版本,例如gpt 3->3.5->4。
在繼續往下之前,先來復習下傳統的Prompt Engineering有哪些?
?
Zero-Shot,直接提問將數據直接塞給LLM
?
Few-Shot,在提問的時候,列出一些例子然后和問題一起送給LLM回答。上面要引導大模型進行情感分析,然后列舉了一些例子。這里好比你學了很多知識,但是考試的時候,總需要有人告訴你答題的規則。
Instruction-Prompt,在提問的時候,針對回答給出明確的指令。
Chain-OF-thought,在提問的時候,幫助大模型整理思維鏈,以便于大模型能夠按照思維鏈進行回答。
Chain-OF-thought,可以配合zero-shot或者Few-shot進行提問,靠人工或者自動化生成的推導思維鏈作為上下文。
Program-OF-thought,在提問的時候,讓大模型給出可以運行的代碼,然后運行可以得到更加正確的答案。
當然基于PROMPT的原理,還可以外掛知識庫,比如目前比較流行的RAG
以上為傳統提示詞工程的概覽圖
2.DSPy
對照傳統的Prompt Engineering,DSPy其實覆蓋了灰色部分:
那么什么是DSPy?
DSPy 是一個用于算法優化提示和 LM 權重的框架。然而,它的學習曲線是陡峭的,“是的,伙計,我到處都能看到DSPy,但還沒有時間看?!薄【幮α藒
DSPy有三個抽象,各位讀者先記一下。分別為signatures(簽名,這個取名不大貼切), modules(模塊或者組件), 和teleprompters(提示器或者優化器)。
DSPy有兩個特點,其一,它閉環了提示詞工程。它將提示詞工程從通常的手動和人工的過程轉變為結構化、定義明確的機器學習工作流程(這個流程包括準備數據集、定義模型、訓練、評估和測試)。這應該是最具革命性的方面。下圖應該很形象地將這段文字表達了出來。
其二,它將邏輯和文本表達分離。說白了就是將傳統的提示詞工程通過一些語法糖,比較優雅的進行封裝。
下面來一段讓讀者們感受下便捷性,首先要先預設下大模型
import dspy
#設置大語言模型
turbo = dspy.OpenAI(model='gpt-3.5-turbo-0125', api_key='KEYS', model_type='text')
dspy.settings.configure(lm=turbo)
第二步定義一個類,看起來和PyTorch定義模型一個調調,只不過父類變成了dspy.Module。
class HelloQA(dspy.Module):
def __init__(self):
super().__init__()
self.prog = dspy.Predict("question -> answer")
#在這里定義基本的邏輯
def forward(self, question):
return self.prog(questinotallow=question)
這個時候不用寫提示詞工程了,直接:
QA = HelloQA()
response = QA.forward("How many legs does elephant has?")
print(response.answer)
結果顯示為“Elephant has four legs.”,就是這么干凈漂亮!
Elephant has four legs.
3.小結
至此已經完成了DSPy的初步入門,上面的鋪墊之后回頭再看看DSPy的三大組件。
Signatures是聲明性規范,它抽象出DSPy編程模型中模塊的輸入/輸出行為。這些簽名用于指定任務需要執行的操作,而不是如何提示語言模型執行任務。這種方法抽象了提示和微調過程,使其更加模塊化。
Modules取代了現有的手動提示詞技術,并且可以在管道中隨意集成。它利用LM執行各種任務的程序塊。DSPy中的每個模塊都是參數化的,這意味著它具有可學習的參數,包括提示的細節、要使用的語言模型以及提示。它根據定義的Signatures處理輸入,并根據該處理返回輸出。
DSPy內置了如下幾個模塊:
dspy.Predict :基本預測變量
dspy.ChainOfThought:教LM在對Signatures響應之前逐步思考
dspy.ProgramOfThought:教LM 輸出代碼
dspy.ReAct:能夠實現某個Signatures功能的代理(利用工具)
dspy.MultiChainComparison:可以比較多個 ChainOfThought 輸出以產生最終預測
例如要實現RAG,分分鐘的事情:
import dspy
class RAG(dspy.Module):
def __init__(self, num_passages=3):
self.retrieve = dspy.Retrieve(k=num_passages)
self.generate_answer = dspy.ChainOfThought("context, question -> answer")
def forward(self, question):
context = self.retrieve(question).passages
return self.generate_answer(cnotallow=context, questinotallow=question)
Teleprompters優化管道中的所有模塊,以便于獲取最優的評估指標。DSPy 優化器,以前稱為提詞器,是一種算法,可以調整 DSPy 程序的參數(即提示和/或 LM 權重),以最大限度地提高指定指標,例如準確性。
借助DSPy可以用簡潔明了的用Modules替換手工制作的提示詞工程,而不會降低質量或表達能力。對Modules進行參數化并將提示視為優化問題,使DSPy能夠更好地適應不同的LM。它的模塊化能夠構建更加具有實用性的應用以及更佳細膩的效果評估標準。
編譯正確的Modules可將不同的 LM 的準確率從 4-20% 提高到 49-88%。
? ?
本文轉載自 ??魯班模錘??,作者: 龐德公
