關于大模型應用過程中的記憶功能管理問題,以及解決方案 原創
“ 大模型應用的很多功能包括記憶管理,需要的不僅僅只是技術問題,還需要足夠的工程化能力才能解決。”
眾所周知,大模型是沒有記憶功能的,因此記憶管理就成為大模型應用過程中必不可少的一個環節;雖然說記憶管理說起來很簡單,但在實際操作中還是存在很多問題。
比如說,隨著記憶的增加token成本的上升,大模型窗口的限制,記憶的存儲問題等等。
因此,今天就從項目的實際操作中來詳細了解一下大模型的記憶功能;開發框架是基于langchain的記憶管理模塊。
大模型記憶管理問題
大模型記憶管理問題主要存在于NLP任務的對話場景中,其本質就類似于我們平常人聊天需要有一個上下文;比如說你朋友在聊天你突然過來,肯定要先問一下他們在聊什么,或者在旁邊聽一下他們在聊什么,這時你才知道怎么開口。
而大模型由于自身的原因導致其沒有記憶功能,也就是說每次對話對大模型來說都是一次全新的交流;這玩意就類似于一個健忘癥的人,上一句剛說完他就忘了剛說的是什么。
因此,大模型記憶管理就應運而生了;記憶管理說起來也很簡單,就是把每次和大模型的對話記錄下來,你說了什么大模型說了什么;然后每次聊天的時候把這段對話記錄一起輸入到大模型中(拼接到提示詞中),這樣大模型就可以根據這段上下文知道你們聊了什么。
在langchain中封裝了一些記憶功能的模塊,主要是基于內存的會話記憶;當然,也有為解決分布式場景下的存儲中間件(關系型數據庫,redis緩存等),本質上就是把對話記錄保存下來,在每次對話時再加載出來然后拼接到提示詞中。
比如其中使用比較多的ConversationBufferMemory記憶,其實就是簡單粗暴的把所有對話記錄都保存下來;但這同樣會帶來一些問題,比如說隨著對話次數的增長,對話記錄會越來越長,這時token消耗就會越來越多;而更重要的是,大模型的窗口大小是有限制的,因此如果持續增長下去就會導致超長問題。
所以,這就有了會話緩存窗口記憶ConversationBufferWindowMemory,本質上來說就是給會話加了一個k值,目的就是只記錄最近的k輪對話;比如說你對話了一百次,但我只記錄最近的10次,這樣既可以解決成本問題,也可以解決超長問題。
但這同樣會有新的問題出現,那就是丟失了之前的對話記錄,可能會導致上下文缺失;這就類似于兩個人喝酒吹了兩個小時的牛逼,突然說我們剛開始聊的啥,這時由于對話記錄已經丟失,大模型就無法獲得之前的上下文。
所以,為了解決這個問題,就設計了一個總結記憶功能;其原理就是把對話記錄輸入到另一個總結模型,讓這個模型根據對話的內容總結其中的關鍵信息,這樣就可以解決上下文丟失問題。
但由于需要多次訪問大模型,以及隨著對話的增多,總結的內容同樣會增多,因此可能依然存在上下文窗口限制問題;而且由于大模型只關注文本頭和尾,對文本中間內容處理效果不太好,因此依然會出現上下文缺失的情況。
所以,從以上問題來看,大模型記憶管理是一個復雜的過程,并且根據不同的場景需要選擇合適的記憶管理方式。
而且在實際操作中,整個系統不可能只有一個人訪問,因此需要根據不同的用戶使用用戶標識或者會話標識來區分不同用戶的記憶數據;但同樣,因為對話記錄是保存在內存中或者第三方存儲中間件中,但對話的時間是有限的,因此還需要做記憶的生命周期管理,也就是說用戶一輪對話完成之后,可以在適當的時間清理掉不在需要的對話記錄。
如以上代碼,根據session_id會話id作為為每個用戶都創建記憶功能,這個會話id可以根據不同的應用場景選擇合適的唯一標識符;而且,在存儲會話的過程中,設置一個last_active時間參數,當到達最長會話時間時,可以自動清理掉過期的會話記錄。
這樣就可以在技術上防止內存泄露,或者存儲空間不足的問題。
當然,以上功能也僅僅只適用于部分應用場景,比如說在分布式環境下就不能使用基于內存的記憶存儲,而需要借助外部存儲工具,如redis等。因此,在具體的應用中,用戶可以選擇性地使用這些記憶工具,當然也可以完全自己開發一套記憶管理工具。
總之,大模型應用在學習過程和實際應用中還是存在一定的區別;有些問題需要通過技術本身來解決,而有些問題需要工程化的方式來避免或解決。
本文轉載自公眾號AI探索時代 作者:DFires
原文鏈接:??https://mp.weixin.qq.com/s/r5uO5HEN0f72cSE7sxoaKA??
