圖技術在 LLM 下的應用:知識圖譜驅動的大語言模型 Llama Index

2023-07-25 15:00:22

LLM 如火如荼地發展了大半年,各類大模型和相關框架也逐步成型,可被大家應用到業務實際中。在這個過程中,我們可能會遇到一類問題是:現有的哪些資料,如何更好地與 LLM 對接上。像是大家都在用的知識圖譜,現在的圖譜該如何藉助大模型,發揮更大的價值呢?

在本文,我便會和大家分享下如何利用知識圖譜構建更好的 In-context Learning 大語言模型應用。

此文最初以英文撰寫的,而後我麻煩 ChatGPT 幫我翻譯成了英文。下面是翻譯的 prompt:

「In this thread, you are a Chinese Tech blogger to help translate my blog in markdown from English into Chinese, the blog style is clear, fun yet professional. I will paste chapters in markdown to you and you will send back the translated and polished version.」

LLM 應用的正規化

作為認知智慧的一大突破,LLM 已經改變了許多行業,以一種我們沒有預料到的方式進行自動化、加速和啟用。我們每天都會看到新的 LLN 應用被建立出來,我們仍然在探索如何利用這種魔力的新方法和用例。

將 LLM 引入流程的最典型模式之一,是要求 LLM 根據專有的/特定領域的知識理解事物。目前,我們可以向 LLM 新增兩種正規化以獲取這些知識:微調——fine-tune上下文學習—— in-context learning

微調是指對 LLM 模型進行附加訓練,以增加額外的知識;而上下文學習是在查詢提示中新增一些額外的知識。

據觀察,目前由於上下文學習比微調更簡單,所以上下文學習比微調更受歡迎,在這篇論文中講述了這一現象:https://arxiv.org/abs/2305.16938

下面,我來分享 NebulaGraph 在上下文學習方法方面所做的工作。

Llama Index:資料與 LLM 之間的介面

上下文學習

上下文學習的基本思想是使用現有的 LLM(未更新)來處理特定知識資料集的特殊任務

例如,要構建一個可以回答關於某個人的任何問題,甚至扮演一個人的數位化化身的應用程式,我們可以將上下文學習應用於一本自傳書籍和 LLM。在實踐中,應用程式將使用使用者的問題和從書中"搜尋"到的一些資訊構建提示,然後查詢 LLM 來獲取答案。

┌───────┐         ┌─────────────────┐         ┌─────────┐
│       │         │ Docs/Knowledge  │         │         │
│       │         └─────────────────┘         │         │
│ User  │─────────────────────────────────────▶   LLM   │
│       │                                     │         │
│       │                                     │         │
└───────┘                                     └─────────┘

在這種搜尋方法中,實現從檔案/知識(上述範例中的那本書)中獲取與特定任務相關資訊的最有效方式之一是利用嵌入(Embedding)。

嵌入(Embedding)

嵌入通常指的是將現實世界的事物對映到多維空間中的向量的方法。例如,我們可以將影象對映到一個(64 x 64)維度的空間中,如果對映足夠好,兩個影象之間的距離可以反映它們的相似性。

嵌入的另一個例子是 word2vec 演演算法,它將每個單詞都對映到一個向量中。例如,如果嵌入足夠好,我們可以對它們進行加法和減法操作,可能會得到以下結果:

vec(apple) + vec(pie) ≈ vec("apple apie"),或者向量測量值 vec(apple) + vec(pie) - vec("apple apie") 趨近於 0:

|vec(apple) + vec(pie) - vec("apple apie")| ≈ 0

類似地,"pear" 應該比 "dinosaur" 更接近 "apple":|vec(apple) - vec(pear)| < |vec(apple) - vec(dinosaur)|

有了這個基礎,理論上我們可以搜尋與給定問題更相關的書籍片段。基本過程如下:

  • 將書籍分割為小片段,為每個片段建立嵌入並儲存它們
  • 當有一個問題時,計算問題的嵌入
  • 通過計算距離找到與書籍片段最相似的前 K 個嵌入
  • 使用問題和書籍片段構建提示
  • 使用提示查詢 LLM
                  ┌────┬────┬────┬────┐                  
                  │ 1  │ 2  │ 3  │ 4  │                  
                  ├────┴────┴────┴────┤                  
                  │  Docs/Knowledge   │                  
┌───────┐         │        ...        │       ┌─────────┐
│       │         ├────┬────┬────┬────┤       │         │
│       │         │ 95 │ 96 │    │    │       │         │
│       │         └────┴────┴────┴────┘       │         │
│ User  │─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─▶   LLM   │
│       │                                     │         │
│       │                                     │         │
└───────┘    ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐  └─────────┘
    │          ┌──────────────────────────┐        ▲     
    └────────┼▶│  Tell me ....., please   │├───────┘     
               └──────────────────────────┘              
             │ ┌────┐ ┌────┐               │             
               │ 3  │ │ 96 │                             
             │ └────┘ └────┘               │             
              ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ 

Llama Index

Llama Index 是一個開源工具包,它能幫助我們以最佳實踐去做 in-context learning:

  • 它提供了各種資料載入器,以統一格式序列化檔案/知識,例如 PDF、維基百科、Notion、Twitter 等等,這樣我們可以無需自行處理預處理、將資料分割為片段等操作。
  • 它還可以幫助我們建立嵌入(以及其他形式的索引),並以一行程式碼的方式在記憶體中或向量資料庫中儲存嵌入。
  • 它內建了提示和其他工程實現,因此我們無需從頭開始建立和研究,例如,《用 4 行程式碼在現有資料上建立一個聊天機器人》

檔案分割和嵌入的問題

嵌入和向量搜尋在許多情況下效果良好,但在某些情況下仍存在挑戰,比如:丟失全域性上下文/跨節點上下文。

想象一下,當查詢"請告訴我關於作者和 foo 的事情",在這本書中,假設編號為 1、3、6、19-25、30-44 和 96-99 的分段都涉及到 foo 這個主題。那麼,在這種情況下,簡單地搜尋與書籍片段相關的前 k 個嵌入可能效果不盡人意,因為這時候只考慮與之最相關的幾個片段(比如 k = 3),會丟失了許多上下文資訊。

┌────┬────┬────┬────┐
│ 1  │ 2  │ 3  │ 4  │
├────┴────┴────┴────┤
│  Docs/Knowledge   │
│        ...        │
├────┬────┬────┬────┤
│ 95 │ 96 │    │    │
└────┴────┴────┴────┘

而解決、緩解這個問題的方法,在 Llama Index 工具的語境下,可以建立組合索引綜合索引

其中,向量儲存(VectorStore)只是其中的一部分。除此之外,我們可以定義一個摘要索引、樹形索引等,以將不同型別的問題路由到不同的索引,從而避免在需要全域性上下文時錯失它。

然而,藉助知識圖譜,我們可以採取更有意思的方法:

知識圖譜

知識圖譜這個術語最初由谷歌在 2012 年 5 月提出,作為其增強搜尋結果,向用戶提供更多上下文資訊的一部分實踐。知識圖譜旨在理解實體之間的關係,並直接提供查詢的答案,而不僅僅返回相關網頁的列表。

知識圖譜是一種以圖結構形式組織和連線資訊的方式,其中節點表示實體,邊表示實體之間的關係。圖結構允許使用者高效地儲存、檢索和分析資料。

它的結構如下圖所示:

現在問題就來了,上面說過知識圖譜能幫忙搞定檔案分割和嵌入的問題。那麼,知識圖譜到底能怎麼幫到我們呢?

嵌入和知識圖譜的結合

這裡的基本實現思想是,作為資訊的精煉格式,知識圖譜可切割的資料顆粒度比我們人工的分割的更細、更小。將知識圖譜的小顆粒資料與原先人工處理的大塊資料相結合,我們可以更好地搜尋需要全域性/跨節點上下文的查詢。

下面來做個題:請看下面的圖示,假設提問同 x 有關,所有資料片段中有 20 個與 x 高度相關。現在,除了獲取主要上下文的前 3 個檔案片段(比如編號為 1、2 和 96 的檔案片段),我們還從知識圖譜中對 x 進行兩次跳轉查詢,那麼完整的上下文將包括:

  • 問題:"Tell me things about the author and x"
  • 來自檔案片段編號 1、2 和 96 的原始檔案。在 Llama Index 中,它們被稱為節點 1、節點 2 和節點 96。
  • 包含 "x" 的知識圖譜中的 10 個三元組,通過對 x 進行兩層深度的圖遍歷得到:
    • x -> y(來自節點 1)
    • x -> a(來自節點 2)
    • x -> m(來自節點 4
    • x <- b-> c(來自節點 95
    • x -> d(來自節點 96)
    • n -> x(來自節點 98
    • x <- z <- i(來自節點 1 和節點 3
    • x <- z <- b(來自節點 1 和節點 95
┌──────────────────┬──────────────────┬──────────────────┬──────────────────┐
│ .─.       .─.    │  .─.       .─.   │            .─.   │  .─.       .─.   │
│( x )─────▶ y )   │ ( x )─────▶ a )  │           ( j )  │ ( m )◀────( x )  │
│ `▲'       `─'    │  `─'       `─'   │            `─'   │  `─'       `─'   │
│  │     1         │        2         │        3    │    │        4         │
│ .─.              │                  │            .▼.   │                  │
│( z )◀────────────┼──────────────────┼───────────( i )─┐│                  │
│ `◀────┐          │                  │            `─'  ││                  │
├───────┼──────────┴──────────────────┴─────────────────┼┴──────────────────┤
│       │                      Docs/Knowledge           │                   │
│       │                            ...                │                   │
│       │                                               │                   │
├───────┼──────────┬──────────────────┬─────────────────┼┬──────────────────┤
│  .─.  └──────.   │  .─.             │                 ││  .─.             │
│ ( x ◀─────( b )  │ ( x )            │                 └┼▶( n )            │
│  `─'       `─'   │  `─'             │                  │  `─'             │
│        95   │    │   │    96        │                  │   │    98        │
│            .▼.   │  .▼.             │                  │   ▼              │
│           ( c )  │ ( d )            │                  │  .─.             │
│            `─'   │  `─'             │                  │ ( x )            │
└──────────────────┴──────────────────┴──────────────────┴──`─'─────────────┘

顯然,那些(可能很寶貴的)涉及到主題 x 的精煉資訊來自於其他節點以及跨節點的資訊,都因為我們引入知識圖譜,而能夠被包含在 prompt 中,用於進行上下文學習,從而克服了前面提到的問題。

Llama Index 中的知識圖譜進展

最初,William F.H.將知識圖譜的抽象概念引入了 Llama Index,其中知識圖譜中的三元組與關鍵詞相關聯,並儲存在記憶體中的檔案中,隨後Logan Markewich還增加了每個三元組的嵌入。

最近的幾週中,我一直在與 Llama Index 社群合作,致力於將 "GraphStore" 儲存上下文引入 Llama Index,從而引入了知識圖譜的外部儲存。首個知識圖譜的外部儲存是對接開源分散式圖資料庫 NebulaGraph,目前在我的努力下已經實現了。

在實現過程中,還引入了遍歷圖的多個跳數選項以及在前 k 個節點中收集更多關鍵實體的選項,用於在知識圖譜中搜尋以獲得更多全域性上下文。上面提到的這些變更還在陸續完善中。

在大模型中引入 GraphStore 後,還可以從現有的知識圖譜中進行上下文學習,並與其他索引結合使用,這也非常有前景。因為知識圖譜被認為具有比其他結構化資料更高的資訊密度。

本文作為開篇,講述了一些知識圖譜和 LLM 的關係。在後續的文章中,將會偏向實操同大家分享具體的知識圖譜和 LLM 的應用實踐。

--

謝謝你讀完本文 (///▽///)

歡迎前往 GitHub 來閱讀 NebulaGraph 原始碼,或是嘗試用它解決你的業務問題 yo~ GitHub 地址:https://github.com/vesoft-inc/nebula 想要交流圖技術和其他想法,請前往論壇:https://discuss.nebula-graph.com.cn/