大型語言模型(LLM),如ChatGPT和Llama,在回答問題方面表現出色,但它們的知識僅限于訓練時所獲取的信息。它們無法訪問私有數據,也無法在訓練截止日期之后學習新知識。那么,核心問題就是……我們如何擴展它們的知識范圍?
答案就在于檢索增強生成(RAG)。今天,我們將探討RAG的工作流程,并演示如何使用LlamaIndex構建一個RAG系統。
讓我們開始吧!
檢索增強生成(RAG):基礎知識
LLM是目前最先進的自然語言處理模型,在翻譯、寫作和通用問答方面表現優異。然而,它們在處理特定領域的問題時常常會出現幻覺式的錯誤回答。
在這些場景下,只有極少數文檔可能包含每個查詢所需的相關上下文。為了解決這個問題,我們需要一個高效的系統,能夠在生成回復前快速檢索并整合相關信息——這正是RAG的核心。
預訓練的LLM通過三種主要方式獲取知識,每種方式都有局限性:
-
訓練:從零開始訓練一個LLM需要在數萬億個標記(token)上訓練龐大的神經網絡,成本高達數億美元——對于大多數人來說并不可行。
-
微調:這種方式可以讓預訓練模型適應新數據,但耗時且資源消耗大。除非有特定需求,否則并不總是實用。
-
提示(Prompting):這是最易用的方法,將新信息插入LLM的上下文窗口,使其能基于所提供的數據回答問題;但由于文檔往往超出上下文窗口的容量,僅靠這種方法并不足夠。
RAG通過在查詢時高效地處理、存儲和檢索相關的文檔片段,克服了上述局限。這確保了LLM能夠生成更準確、具備上下文感知的回復,而無需進行昂貴的再訓練或微調。
RAG流程的核心組成部分
RAG系統由幾個關鍵組件組成:
簡易RAG應用架構示意圖 (原文配圖,略)
-
文本分割器(Text Splitter):將大型文檔拆分為可適應LLM上下文窗口的小塊。
-
嵌入模型(Embedding Model):將文本轉換為向量表示,以實現高效的相似度搜索。
-
向量存儲(Vector Store):專用數據庫,用于存儲和檢索文檔嵌入及其元數據。
-
大語言模型(LLM):核心語言模型,基于檢索到的信息生成答案。
-
工具函數(Utility Functions):包括網頁檢索器、文檔解析器等工具,用于數據預處理和增強檢索效果。
每個組件在提升RAG系統的準確性和效率方面都起著至關重要的作用。
什么是LlamaIndex?
LlamaIndex(原名GPTIndex)是一個用于構建LLM驅動應用的Python框架。它充當自定義數據源與大型語言模型之間的橋梁,簡化了數據的攝取、索引和查詢過程。
LlamaIndex內置支持多種數據源、向量數據庫和查詢接口,是RAG應用的一體化解決方案。同時,它還可無縫集成LangChain、Flask、Docker等工具,非常適合實際場景的靈活部署。
可在其官方GitHub倉庫查看更多信息。
用LlamaIndex實現簡單的RAG系統
步驟1:環境準備
在實現之前,需要先搭建Python環境并安裝必要依賴。使用虛擬環境有助于高效管理依賴:
python -m venv rag_env
source rag_env/bin/activate ?# Windows系統使用:rag_env\Scripts\activate
現在可以安裝所需庫。LlamaIndex、OpenAI和FAISS是搭建RAG系統的核心依賴:
pip install llama-index openai faiss-cpu
若要讓LlamaIndex能調用OpenAI模型,別忘了配置OpenAI API密鑰:
import os?
os.environ["OPENAI_API_KEY"] = "your-api-key-here"
步驟2:加載文檔
為了實現檢索,首先需將文檔加載到系統中。LlamaIndex提供了SimpleDirectoryReader來高效完成此任務。這次我們以“Attention Is All You Need”論文擴展LLM的知識為例。
from llama_index import SimpleDirectoryReader# 從指定目錄加載文本文件
documents = SimpleDirectoryReader("./data").load_data()print(f"Loaded {len(documents)} documents")
步驟3:文本分割
LLM有上下文窗口限制,無法一次處理完整文檔。因此,需要將文檔拆分為更小、結構化的片段以便高效檢索。
from llama_index.text_splitter import SentenceSplitter# 定義基于句子的文本分割器
text_splitter = SentenceSplitter(chunk_size=512, chunk_overlap=50)# 將文檔進行分割
nodes = text_splitter.split_text([doc.text for doc in documents])print(f"Split into {len(nodes)} chunks")
步驟4:用嵌入索引文檔
要實現語義檢索,必須將文檔片段轉換為向量嵌入,并存儲在索引中。
from llama_index import VectorStoreIndex# 創建索引
index = VectorStoreIndex(nodes)# 持久化索引(可選)
index.storage_context.persist(persist_dir="./storage")
步驟5:用RAG查詢索引
這一步RAG開始發揮作用。我們將對已索引文檔進行檢索并生成由LLM驅動的回復。
from llama_index.query_engine import RetrieverQueryEnginequery_engine = RetrieverQueryEngine.from_args(index.as_retriever())response = query_engine.query("What is attention?")
print(response)
執行上述代碼后,可得到如下回答:
“Attention是一種在深度學習模型中用來關注輸入序列中相關部分的機制。在論文《Attention Is All You Need》中,Vaswani等人提出了Transformer架構,這一架構完全依賴自注意力機制,而非循環或卷積。其核心創新就是自注意力機制,使模型能夠衡量句中不同詞語之間的重要性,從而實現更好的并行化和遠距離依賴建模。”
我們成功了!
結語
借助LlamaIndex構建RAG系統,為LLM突破訓練數據的限制帶來了令人興奮的可能性。通過集成文檔檢索、基于嵌入的索引以及實時查詢,RAG提升了準確性并減少了幻覺現象,非常適合特定領域的應用。
根據本指南的分步實現,你已經擁有一個可擴展的RAG流程。你還可以從以下方向進一步擴展:
-
用OpenAI、Cohere或Hugging Face等模型自定義嵌入
-
集成Pinecone、Weaviate或ChromaDB等向量數據庫以實現可擴展檢索
-
通過Flask、FastAPI或聊天機器人接口將系統部署為API
-
優化文本切分策略以提升檢索質量
現在輪到你了——大膽嘗試、不斷迭代,探索LlamaIndex的無限可能吧!