如何在保證模型性能條件下優(yōu)化Prompt降低使用成本及響應(yīng)延遲?
隨著大模型應(yīng)用的不斷發(fā)展,提示工程技術(shù)也在快速迭代更新,越來越多的任務(wù)通過精妙的Prompt或者agentic workflow等方式解鎖。但隨之而來,大量詳細(xì)的、巨大的prompt卻會(huì)帶來高的成本以及緩慢的響應(yīng)。這也使得高成本和高延遲成為了大模型應(yīng)用落地生產(chǎn)的主要障礙。隨著當(dāng)下LLM應(yīng)用已經(jīng)不再是單次的對(duì)話,而是復(fù)雜的組合AI系統(tǒng)(伯克利:即使模型再強(qiáng)大,復(fù)合AI系統(tǒng)( Compound AI Systems)都將會(huì)是一種領(lǐng)先的應(yīng)用模式)都將會(huì)是一種領(lǐng)先的應(yīng)用模式),提示規(guī)模爆炸性增長(zhǎng),這樣的問題變得更加尖銳。
就以最近很火的GraphRAG為例,處理64頁的文稿,就花了7美元,使用成本相當(dāng)?shù)母?,這在研究和演示場(chǎng)景這樣的情況并不突出,但是真到需要處理大規(guī)模數(shù)據(jù),服務(wù)大量用戶的實(shí)際生產(chǎn)場(chǎng)景中,這樣的情況是無法接受的。
Prompt會(huì)很大的主要原因是它包含了很多內(nèi)容,比如任務(wù)描述,場(chǎng)景約束,工具描述,多輪的交互記憶等等,在每一次和大模型交互時(shí),都需要將其提供給大模型,再加上系統(tǒng)框架的必要的再封裝,會(huì)導(dǎo)致實(shí)際提交給LLM比用戶提交的更大。
成本和延遲與prompt大小及調(diào)用次數(shù)密切相關(guān),那如何才能在不降低精度的情況下,減少Prompt大小以及降低LLM調(diào)用次數(shù)呢?下面是Jan Majewski在開發(fā)它的應(yīng)用(房產(chǎn)搜索助理)時(shí)總結(jié)prompt大小與成本延遲的量化關(guān)系以及五個(gè)優(yōu)化的思路。
1)量化關(guān)系
- 成本
- 延遲
對(duì)于成本,輸出token是輸入token的 3 倍,但同時(shí)對(duì)于復(fù)雜的任務(wù)來講,提示(輸入token)會(huì)比輸出要長(zhǎng)得多,減少輸入token帶來的收益依然可觀。 對(duì)于延遲,主要是由輸出token決定的,其處理時(shí)間是輸入token的 200 倍。
2)優(yōu)化手段:
1. 將大的prompt拆分成多層次調(diào)用
在撰寫prompt時(shí)不必將所有內(nèi)容都寫到一個(gè)大的prompt中,比如把規(guī)劃和執(zhí)行分開,Jan Majewski指出他的應(yīng)用性能提升的關(guān)鍵之一在于將Prompt拆分成兩個(gè)部分:決策Agent,它對(duì)下一步可以采取的措施有總體指導(dǎo),以及如何處理來自模型的輸出;執(zhí)行Agent/Chats,它對(duì)具體步驟(如報(bào)價(jià)搜索、數(shù)據(jù)比較或房地產(chǎn)知識(shí))有詳細(xì)說明。
這種架構(gòu)允許首先選擇需要使用的特定任務(wù)提示,而無需在每次調(diào)用時(shí)發(fā)送大量token執(zhí)行指令,從而將token的平均使用量減少了 60% 以上。
2. 關(guān)注發(fā)送給LLM的最終Prompt
如前面提到,LLM 收到的最終Prompt可能與最初用戶撰寫的Prompt相差很大。 框架在使用工具、內(nèi)存、上下文和 Agent 的內(nèi)部推理時(shí),都會(huì)自動(dòng)擴(kuò)展Prompt,這也會(huì)使prompt增加數(shù)千個(gè)token。另外,在LLM應(yīng)用執(zhí)行過程中,涉及到了很多的環(huán)節(jié),可能進(jìn)行了幾十次調(diào)用,如何監(jiān)控和排錯(cuò)也就十分重要。對(duì)于開發(fā)者來講,使用 LangSmith 進(jìn)行深入分析是一個(gè)比較好的選擇,近日dify也集成了這樣的可觀測(cè)工具。
3.可以通過編碼,減少LLM調(diào)用量。
有時(shí)候一些任務(wù)使用常規(guī)的代碼實(shí)現(xiàn)更為高效經(jīng)濟(jì),而無需都撰寫Prompt操縱LLM來實(shí)現(xiàn)。比如,使用 Python 函數(shù)處理 LLM 調(diào)用的上游/下游一些瑣碎的任務(wù)。當(dāng)前,大部分的LLM應(yīng)用開發(fā)的框架都支持將傳統(tǒng)函數(shù)與LLM調(diào)用混合在一起使用,比如Promptflow,langchain等。比如下面的一段代碼,可以直接使用python lib完成語言檢測(cè),這樣就可以明確語言類型明確傳遞給LLM,無需在Prompt中去限定有關(guān)語言的描述,從而減少在 LLM 的處理復(fù)雜度以及Prompt大小。
from langdetect import detect
prompt = """
Summarize the following message in {language}:
Message: {input}
"""
prompt = ChatPromptTemplate.from_template(prompt)
def detect_language(input_message):
input_message["language"] = detect(input_message["input"])
return input_message
detect_language_step= RunnablePassthrough.assign(input_message=detect_language)
chain_summarize_in_message_language = (
detect_language_step
| RunnablePassthrough.assign(
language=lambda x: x["input_message"]["language"]
)
| prompt
| llm )
4. 慎用Agent,它們會(huì)導(dǎo)致token消耗大大增加
能夠使用工具的Agent能夠極大的擴(kuò)展LLM的能力范圍,但它們同時(shí)也非常消耗token。下面的圖表顯示了 Agent的一般處理流程,可以看到Agent 通常需要調(diào)用 LLM 至少兩次:首先計(jì)劃如何使用工具,然后解析其輸出以提供最終答案。對(duì)于一些較為簡(jiǎn)單的任務(wù),Agent 的方法可能有些重,而使用 Completion 的簡(jiǎn)單指令提示則能以兩倍的速度提供類似的結(jié)果。
5. 使用 LLM 進(jìn)行推理,但使用 SQL 或 Python 進(jìn)行統(tǒng)計(jì)計(jì)算
雖然,現(xiàn)在的LLM能力相較于之前已經(jīng)有了很大提高,比如通過精心構(gòu)造Prompt完成數(shù)據(jù)分析(新加坡提示工程大賽冠軍最強(qiáng)Prompt工程技巧分享,僅用大模型也能做數(shù)據(jù)分析),但對(duì)于數(shù)據(jù)計(jì)算來講,仍然不如Python和SQL來的高效準(zhǔn)確經(jīng)濟(jì)。
建議做法是使用 LLM 理解問題和數(shù)據(jù),然后將其轉(zhuǎn)換為更合適的分析語言(如SQL或Python)進(jìn)行數(shù)據(jù)處理匯總,最后再將結(jié)果提供給 LLM 進(jìn)行分析洞察。
總結(jié)
Jan Majewski給出了一些常見的思路來減少Prompt的大小以及減少LLM的調(diào)用,除此之外,還有很多prompt壓縮、LLM Cache等技術(shù)降低應(yīng)用成本及減少應(yīng)用延遲。未來筆者還將介紹這一領(lǐng)域的進(jìn)展,歡迎關(guān)注。
參考:
??https://www.youtube.com/watch?v=EuzDssiyLmo??
??https://blog.baeke.info/2024/07/07/trying-out-graph-rag/??
本文轉(zhuǎn)載自??AI工程化??,作者: ully
