源碼解讀:MemGPT如何實現(xiàn)“無限”上下文

一、MemGPT概述

當前,大型語言模型(LLMs)在處理擴展對話和文檔分析等任務時受到有限上下文限制,限制了它們在擴展對話和文檔分析等任務中的能發(fā)揮的作用。如何讓大語言模型擁有更強的上下文處理能力是業(yè)界非??粗氐臒狳c主題之一。

對此,UC Berkeley的研究者提出了一種虛擬上下文管理技術(shù),這種技術(shù)從傳統(tǒng)操作系統(tǒng)中汲取靈感,通過對快速和慢速內(nèi)存之間數(shù)據(jù)的管理,使得 LLMs 能夠在有限的上下文窗口中有效使用擴展上下文。并由此引出一個智能管理不同內(nèi)存層級的系統(tǒng)MemGPT。

MemGPT 的設(shè)計靈感來自傳統(tǒng)操作系統(tǒng)的層次內(nèi)存管理,它能夠在“內(nèi)存”(類似于操作系統(tǒng)中的內(nèi)存)和外部存儲之間移動信息。MemGPT 管理內(nèi)存管理、LLM 處理模塊和用戶之間的控制流。這種設(shè)計允許在單個任務中進行重復的上下文修改,使代理能夠更有效地利用其有限的上下文。

MemGPT 在兩個場景進行了評估:文檔分析和多會話聊天。在文檔分析場景,MemGPT 能夠分析遠遠超出基礎(chǔ) LLM 上下文窗口的大型文檔。在多會話聊天場景,MemGPT 可以創(chuàng)建記憶、反思和動態(tài)演變的對話代理,通過與用戶的長期互動獲取長期記憶。

二、MemGPT構(gòu)成

組件

MemGPT 的設(shè)計包括幾個關(guān)鍵組件,這些組件共同支持其在處理擴展對話和文檔分析任務時動態(tài)管理和使用擴展上下文的能力:

1. 主上下文(Main Context)

  • 這是模型可以直接訪問和操作的內(nèi)存區(qū)域。它類似于計算機的 RAM,并且受到模型的最大令牌限制。MemGPT的主上下文可以簡單的看成是一個消息流FIFO隊列,外加存儲用戶上下文、LLM角色上下文的Memory。

2. 外部上下文(External Context)

  • 這是一個更大的存儲區(qū)域,用于存儲不立即需要但可能在將來需要的信息。它類似于計算機的硬盤存儲。在MemGPT中包含recall memory、archival memory
類型 說明
recall memory 持久化的歷史交互上下文
archival memory 可以是交互中的上下文,也可以是外部載入的數(shù)據(jù)、文檔等

3. 函數(shù)調(diào)用

  • MemGPT 提供了一組函數(shù),允許模型執(zhí)行特定的內(nèi)存管理任務,如從外部上下文檢索信息或更新主上下文。通過在prompt里面指導LLMs去使用這些函數(shù)來達到自主更新上下文、搜索上下文、向用戶發(fā)送消息等目的。
  • 例如在多會話聊天場景,LLMs可以使用以下函數(shù)
函數(shù) 說明
send_message LLM向用戶發(fā)送消息
core_memory_append 新增當前交互會傳遞的上下文
core_memory_replace 編輯當前交互會傳遞的上下文,如將用戶的名字從“John”修改為“Mike”
conversation_search 搜索recall memory歷史
conversation_search_date 時間范圍條件搜索recall memory歷史
archival_memory_insert 往已歸檔的memory新增數(shù)據(jù)
archival_memory_search 從已歸檔的上下文中搜索數(shù)據(jù)

4. 內(nèi)存管理算法

  • 用于內(nèi)存管理,確定何時和如何在主上下文和外部上下文之間移動信息。
  • 例如在發(fā)送給LLMs達到token上限時,按一定的規(guī)則將core memory送給LLMs作總結(jié)并替換掉
  • 再比如當LLMs需要找不到所需上下文時通過調(diào)用相關(guān)function從recall memory、archival memory搜索到所需上下文并加入到core memory

5. 控制流管理

  • MemGPT 能夠管理與用戶的交互流程,確定何時接收輸入,何時提供輸出,以及何時執(zhí)行內(nèi)存管理任務。讓我們看看相關(guān)的核心流程:
async def step():
  try:
      # Step 0: add user message
      packed_user_message = {'role': 'user', 'content': user_message}
      input_message_sequence = self.messages + [packed_user_message]

      # Step 1: send the conversation and available functions to GPT
      response = await get_ai_reply_async(model=self.model, message_sequence=input_message_sequence, functions=self.functions)

      # Step 2: check if LLM wanted to call a function
      # (if yes) Step 3: call the function
      # (if yes) Step 4: send the info on the function call and function response to LLM
      response_message = response.choices[0].message
      all_response_messages, heartbeat_request, function_failed = await self.handle_ai_response(response_message)
      
      # Add the extra metadata to the assistant response
      # (e.g. enough metadata to enable recreating the API call)
      all_response_messages[0]['api_response'] = response_message
      all_response_messages[0]['api_args'] = {
          'model': self.model,
          'messages': input_message_sequence,
          'functions': self.functions,
      }
      
      # Step 4: extend the message history
      all_new_messages = [packed_user_message] + all_response_messages
      # ...

  except Exception as e:

      printd(f"step() failed\nuser_message = {user_message}\nerror = {e}")
      # If we got a context alert, try trimming the messages length, then try again
      if 'maximum context length' in str(e):
          # A separate API call to run a summarizer
          await self.summarize_messages_inplace()
          # Try step again
          return await self.step(user_message, first_message=first_message)
      else:
          raise e
流程圖

舉個實際交互的例子

MemGPT assistant/LLMs user 說明
pre-prompt
[send_message]Hi, is anyone there?
[send_message]Hello! I'm Sam, your new virtual companion. How can I assist you today?
my name is john, I took the day off today, my mom Brenda baked me a birthday cake. It was my favorite chocolate lava!
[send_message]Happy birthday, John! It sounds like you had a wonderful day off. How was the chocolate lava cake? Did you enjoy it?
sure, but, my name is mike
[send_message]Oops, I apologize for the confusion, Mike! Happy belated birthday. How was the chocolate lava cake? I hope it was absolutely delicious!
sure, do you remember that time when i talk about my mom with you
[conversation_search]query: mom LLM嘗試從外部上下文歷史記錄中搜索
[conversation_search] reutn "my name is john, I took the day off today, my mom Brenda baked me a birthday cake. It was my favorite chocolate lava!"
what is my name
[core_memory_replace] update name from Chad to Mike LLMs發(fā)起記憶修正
core_memory_replace
[send_message]I apologize for the confusion, Mike! Happy belated birthday. How was the chocolate lava cake? By the way, I remember when you mentioned your mom, Brenda, baking you the cake. Such a lovely gesture!
時序圖

三、總結(jié)

對于LLMs token限制的問題,MemGPT通過提供上下文管理、上下文搜索的function,用prompt指導LLMs去進行外部上下文的調(diào)取以及上下文的管理。使得其具備以下優(yōu)點:

  1. 動態(tài)上下文管理:MemGPT 能夠動態(tài)管理和使用擴展的上下文,這有助于處理更復雜和連貫的對話和文檔分析任務。
  2. 長期記憶能力:MemGPT 可以記住和使用長期對話中的信息,提高對話的連貫性和相關(guān)性。
  3. 自我導向的內(nèi)存管理:MemGPT 可以自主更新和搜索其內(nèi)存,使其能夠更加智能和靈活地響應用戶的需求。

與此同時,缺點也是很明顯的

  1. 復雜性:MemGPT 的設(shè)計和實現(xiàn)可能相對復雜,需要更多的資源和技術(shù)支持來實現(xiàn)系統(tǒng)集成。
  2. 計算資源:MemGPT 需要多次跟LLMs進行交互來實現(xiàn)相關(guān)的功能,可能需要更多的計算資源來執(zhí)行動態(tài)內(nèi)存管理和其他高級功能以完成跟用戶的單次交互。
  3. 可解釋性:MemGPT 的上下文管理決策依賴于LLMs,可能不太容易解釋和理解。
  4. 局限性:MemGPT通過上下文的交換一定程度上解決了token受限的問題,但如果單次所需的上下文token超出LLMs限制,仍然會有存在這個問題。

四、參考

github:https://github.com/cpacker/MemGPT
論文:https://arxiv.org/abs/2310.08560

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容