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 已經改變了許多行業,以一種我們沒有預料到的方式進行自動化、加速和啟用。我們每天都會看到新的 LLN 應用被建立出來,我們仍然在探索如何利用這種魔力的新方法和用例。
將 LLM 引入流程的最典型模式之一,是要求 LLM 根據專有的/特定領域的知識理解事物。目前,我們可以向 LLM 新增兩種正規化以獲取這些知識:微調——fine-tune 和 上下文學習—— in-context learning。
微調是指對 LLM 模型進行附加訓練,以增加額外的知識;而上下文學習是在查詢提示中新增一些額外的知識。
據觀察,目前由於上下文學習比微調更簡單,所以上下文學習比微調更受歡迎,在這篇論文中講述了這一現象:https://arxiv.org/abs/2305.16938。
下面,我來分享 NebulaGraph 在上下文學習方法方面所做的工作。
上下文學習的基本思想是使用現有的 LLM(未更新)來處理特定知識資料集的特殊任務。
例如,要構建一個可以回答關於某個人的任何問題,甚至扮演一個人的數位化化身的應用程式,我們可以將上下文學習應用於一本自傳書籍和 LLM。在實踐中,應用程式將使用使用者的問題和從書中"搜尋"到的一些資訊構建提示,然後查詢 LLM 來獲取答案。
┌───────┐ ┌─────────────────┐ ┌─────────┐
│ │ │ Docs/Knowledge │ │ │
│ │ └─────────────────┘ │ │
│ User │─────────────────────────────────────▶ LLM │
│ │ │ │
│ │ │ │
└───────┘ └─────────┘
在這種搜尋方法中,實現從檔案/知識(上述範例中的那本書)中獲取與特定任務相關資訊的最有效方式之一是利用嵌入(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)|
有了這個基礎,理論上我們可以搜尋與給定問題更相關的書籍片段。基本過程如下:
┌────┬────┬────┬────┐
│ 1 │ 2 │ 3 │ 4 │
├────┴────┴────┴────┤
│ Docs/Knowledge │
┌───────┐ │ ... │ ┌─────────┐
│ │ ├────┬────┬────┬────┤ │ │
│ │ │ 95 │ 96 │ │ │ │ │
│ │ └────┴────┴────┴────┘ │ │
│ User │─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─▶ LLM │
│ │ │ │
│ │ │ │
└───────┘ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ └─────────┘
│ ┌──────────────────────────┐ ▲
└────────┼▶│ Tell me ....., please │├───────┘
└──────────────────────────┘
│ ┌────┐ ┌────┐ │
│ 3 │ │ 96 │
│ └────┘ └────┘ │
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
Llama Index 是一個開源工具包,它能幫助我們以最佳實踐去做 in-context learning:
嵌入和向量搜尋在許多情況下效果良好,但在某些情況下仍存在挑戰,比如:丟失全域性上下文/跨節點上下文。
想象一下,當查詢"請告訴我關於作者和 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
進行兩次跳轉查詢,那麼完整的上下文將包括:
x
進行兩層深度的圖遍歷得到:
┌──────────────────┬──────────────────┬──────────────────┬──────────────────┐
│ .─. .─. │ .─. .─. │ .─. │ .─. .─. │
│( 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 中,用於進行上下文學習,從而克服了前面提到的問題。
最初,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/