RAG從入門到精通系列:基礎RAG
LLM(Large Language Model,大型語言模型)是一個功能強大的新平臺,但它們并不總是使用與我們的任務相關的數(shù)據(jù)或者是最新的數(shù)據(jù)進行訓練。
RAG(Retrieval Augmented Generation,檢索增強生成)是一種將 LLM 與外部數(shù)據(jù)源(例如私有數(shù)據(jù)或最新數(shù)據(jù))連接的通用方法。它允許 LLM 使用外部數(shù)據(jù)來生成其輸出。
要想真正掌握 RAG,我們需要學習下圖所示的技術(技巧):
圖片
這個圖看起來很讓人頭大,但是不用擔心,你來對地方了。
本系列教程將從頭開始介紹如何建立對 RAG 的理解。
我們先從 Indexing(索引)、Retrieval(檢索)和 Generation(生成)的基礎知識開始。
下面的流程圖說明了基礎 RAG 的過程:
- 我們對外部文檔建立索引(Indexing);
- 根據(jù)用戶的問題去檢索(Retrieval)相關的文檔;
- 將問題和相關的文檔輸入 LLM 生成(Generation)最終答案。
圖片
Indexing
我們從加載文檔開始學習 Indexing。LangChain 有超過 160 種不同的文檔加載器,我們可以使用它們從許多不同的來源抓取數(shù)據(jù)進行 Indexing。
https://python.langchain.com/docs/integrations/document_loaders/
我們將 Question(問題)輸入到 Retriever(檢索器),Retriever 也會加載外部文檔(知識),然后篩選出與 Question 相關的文檔:
我們需要將 Text Representation(文本表示)轉(zhuǎn)成 Numerical Representation(數(shù)值表示)才能更好地實現(xiàn)相關性(比如余弦相似度)篩選:
有很多種方法可以將文本轉(zhuǎn)成數(shù)值表示,典型的有:
- Statistical(基于統(tǒng)計學)
- Machine Learned(基于機器學習)
目前最常用的就是使用機器學習方法將文本轉(zhuǎn)成固定長度的,可捕獲文本語義的 Embedding Vector(嵌入向量)。
有很多開源的 Embedding Model(比如 BAAI 系列)可以將文本轉(zhuǎn)成 Embedding Vector。但是這些模型能接受的 Context Window(上下文窗口)有限,一般在 512~8192 個 token(如果你不知道什么是 token 的話,請?zhí)轿哪?/p>
所以正常的流程是我們將外部文檔切分成一個個 Split,使得這些 Split 的長度能夠滿足 Embedding Model 的 Context Window:
到現(xiàn)在,我們已經(jīng)掌握了 Indexing 的理論了,現(xiàn)在可以用 Qwen + BAAI + LangChain + Qdrant 實踐了。
首先配置 LLM 和 Embedding Model:
然后加載外部文檔,這里的文檔是一個網(wǎng)頁博客:
正如我之前說的, Embedding Model 的 Context Window 有限,我們不能直接把整篇文檔丟進去,所以要將原始文檔拆分成一個個文檔塊:
接下來就是配置 Qdrant 向量數(shù)據(jù)庫:
可以閱讀《Qdrant:使用Rust編寫的開源向量數(shù)據(jù)庫&向量搜索引擎》了解一下 Qdrant。
最后一步對文檔塊建立索引并存到向量數(shù)據(jù)庫中:
Retrieval
Retrieval 就是根據(jù)我們提出的問題的語義向量(也就是 Embedding Vector)去按照某種距離/相似度衡量方法找出與之相似的 k 個 Split 的語義向量。
下圖演示了一個在一個 3D 空間的 Embedding Vector Retrieval:
Embedding Vector 通常存儲在 Vector Store(向量數(shù)據(jù)庫)中,Vector Store 實現(xiàn)了各種比較 Embedding Vector 之間相似度的方法。
接下來我們用在 Indexing 時構(gòu)建的 Vector Store 構(gòu)建一個 retriever,然后輸入問題并進行檢索:
根據(jù)我們設定的 k 值,我們檢索出了一個與問題相關的文檔塊。
Generation
現(xiàn)在我們已經(jīng)能夠根據(jù)用戶的問題檢索出與之相關的知識片段(Split),那么我們現(xiàn)在需要將這些信息(問題 + 知識片段)輸入 LLM,讓 LLM 幫忙生成一個有時事實依據(jù)(知識片段)的回答:
我們需要:
- 問題和知識片段放到一個字典中,問題放到 Question 這個 key,知識片段放到 Context 這個 key;
- 然后通過 PromptTemplate 組成一個 Prompt String;
- 最后將 Prompt String 輸入 LLM,LLM 再產(chǎn)生回答。
看起來很復雜,但這就是 LangChain 和 LlamaIndex 這類框架存在的意義:
細心的你發(fā)現(xiàn)返回的結(jié)果是一個 AIMessage 對象,我們可能需要一個純字符串的輸出結(jié)果;而且檢索過程和生成過程是分開的,這很不方便。
不過我們可以借助于 LangChain 將上述檢索和生成過程鏈(Chain)在一起:
LangSmith
如果你還是對整個 RAG 管道過程很陌生,那么不妨去 LangSmith 頁面上看一下整個過程是怎么被一步步串到一起的:
LangSmith 是一個用于構(gòu)建生產(chǎn)級 LLM 應用程序的平臺。它允許我們密切監(jiān)控和評估我們的應用程序,以便我們可以快速、自信地交付。使用 LangSmith,我們可以:
- ?跟蹤 LLM 應用程序
- 了解 LLM 調(diào)用和應用程序邏輯的其他部分。
什么是 token?
token 是模型用來表示自然語言文本的基本單位,可以直觀的理解為“字”或“詞”。
對于英文文本來說,1 個 token 通常對應 3 至 4 個字母:
對于中文文本來說,1 個 token 通常對應一個漢字:
GitHub 鏈接:
??https://github.com/realyinchen/RAG/blob/main/01_Indexing_Retrieval_Generation.ipynb??
本文轉(zhuǎn)載自 ??PyTorch研習社??,作者: 南七無名式
