深度剖析25種RAG變體:全網最全~沒有之一
主流RAG框架可以分為以下五個主要的進化方向:成本控制型(適合初創(chuàng)公司)、實時互動型(適用于財經/新聞場景)、域專家類型、認知增強型、安全與合規(guī)類型。接下來,讓我們詳細了解一下這25種RAG變體。
一、 標準RAG
一個基本的RAG系統由檢索模塊和生成模塊組成。系統會對查詢進行編碼,檢索相關的文檔塊,然后為基于transformer的LLM構建豐富的提示。
- 查詢編碼器:使用預訓練的轉換器(例如DPR)生成密集的查詢嵌入。代碼實現如下:
from transformers import AutoTokenizer, AutoModel
import torch
tokenizer = AutoTokenizer.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
model = AutoModel.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
def encode_query(query: str) -> torch.Tensor:
inputs = tokenizer(query, return_tensors="pt", truncatinotallow=True, max_length=128)
return model(**inputs).pooler_output
- 文檔分割:將文檔拆分為多個塊(可以使用句子分詞或滑動窗口的方法)。代碼如下:
import nltk
nltk.download('punkt')
from nltk.tokenize import sent_tokenize
def segment_document(document: str, window_size: int = 5, overlap: int = 2) -> list:
sentences = sent_tokenize(document)
return [" ".join(sentences[i:i+window_size]) for i in range(0, len(sentences), window_size - overlap)]
- 索引和檢索:嵌入每個塊并通過FAISS為它們編制索引。在查詢期間,執(zhí)行最近鄰搜索。相關代碼:
import faiss, numpy as np
def build_faiss_index(embeddings: torch.Tensor) -> faiss.IndexFlatL2:
emb_np = embeddings.detach().cpu().numpy().astype('float32')
d = emb_np.shape[1]
index = faiss.IndexFlatL2(d)
index.add(emb_np)
return index
- 提示構造函數和生成:將檢索到的塊與原始查詢(使用特殊分隔符)相結合,并將提示傳遞給LLM(例如GPT-2/GPT-4)進行生成。代碼如下:
def construct_prompt(query: str, retrieved_chunks: list) -> str:
delimiter = "[DOC]"
context = " ".join([f"{delimiter} {chunk} {delimiter}" for chunk in retrieved_chunks])
return f"{query}\n{context}"
關鍵事實:標準RAG將外部知識動態(tài)注入生成過程,而無需修改LLM本身,就像是給LLM戴上了一副能隨時獲取新知識的“眼鏡”。
二、矯正RAG(CRAG)
CRAG在標準RAG的基礎上增加了迭代反饋循環(huán)。它能夠檢測低置信度或不準確的輸出,并重新查詢外部知識庫進行更正。
- 初始生成:使用標準RAG生成初步答案。
- 置信度評分:使用令牌級softmax概率評估輸出。代碼如下:
from transformers import AutoModelForCausalLM
gen_tokenizer = AutoTokenizer.from_pretrained("gpt2")
gen_model = AutoModelForCausalLM.from_pretrained("gpt2")
def generate_response(prompt: str, max_length: int = 200) -> str:
inputs = gen_tokenizer.encode(prompt, return_tensors="pt", truncatinotallow=True, max_length=1024)
outputs = gen_model.generate(inputs, max_length=max_length, num_beams=5, early_stopping=True)
return gen_tokenizer.decode(outputs[0], skip_special_tokens=True)
def evaluate_confidence(output_ids: torch.Tensor) -> float:
outputs = gen_model(output_ids, labels=output_ids)
return torch.exp(-outputs.loss).item()
- 反饋回路:如果置信度低于閾值,重新運行檢索(可能會調整查詢詞)并重新生成答案。代碼如下:
def iterative_crag(prompt: str, threshold: float = 0.8, max_iters: int = 3) -> str:
current_prompt = prompt
for _ in range(max_iters):
response = generate_response(current_prompt)
output_ids = gen_tokenizer.encode(response, return_tensors="pt")
conf = evaluate_confidence(output_ids)
if conf >= threshold:
return response
current_prompt += "\n[REFINE]"
return response
關鍵事實:CRAG的迭代校正通過強制執(zhí)行重新檢索周期,直到輸出達到預定義的置信度,從而最大限度地減少幻覺,讓AI的回答更加靠譜。
三、 Speculative RAG
Speculative RAG采用雙模型策略:輕量級專家模型起草多個候選回答,重量級通才模型驗證并選擇最佳候選。
- 專家模型(制圖):從各種檢索子集并行生成多個候選響應。代碼:
def generate_candidates(prompt: str, num_candidates: int = 3) -> list:
inputs = gen_tokenizer.encode(prompt, return_tensors="pt", truncatinotallow=True, max_length=1024)
candidates_ids = gen_model.generate(inputs, max_length=200, num_return_sequences=num_candidates, num_beams=5)
return [gen_tokenizer.decode(c, skip_special_tokens=True) for c in candidates_ids]
- 通才模型(驗證):對每個候選項進行評分(使用似然或專門的驗證指標)并選擇最準確的一個。代碼:
def select_best_candidate(candidates: list) -> str:
best_candidate = None
best_score = -float('inf')
for candidate in candidates:
inputs = gen_tokenizer.encode(candidate, return_tensors="pt", truncatinotallow=True, max_length=1024)
outputs = gen_model(inputs, labels=inputs)
score = torch.exp(-outputs.loss).item()
if score > best_score:
best_score = score
best_candidate = candidate
return best_candidate
def speculative_rag(prompt: str) -> str:
candidates = generate_candidates(prompt, num_candidates=3)
return select_best_candidate(candidates)
關鍵事實:通過將生成解耦為起草和驗證,Speculative RAG利用并行性提高了速度和準確性,就像多個助手同時工作,然后挑選出最佳方案。
四、融合RAG
Fusion RAG集成了多種檢索策略和各種數據源,以豐富提示。它同時使用語義(密集嵌入)和詞法(基于關鍵字)檢索方法。
- 混合檢索:執(zhí)行并行檢索管道,一個使用密集嵌入,另一個使用傳統的BM25或關鍵字匹配。代碼如下:
# Placeholder for BM25 retrieval (e.g., using rank_bm25 library)
def bm25_retrieve(query: str, corpus: list, k: int = 5):
from rank_bm25 import BM25Okapi
tokenized_corpus = [doc.split() for doc in corpus]
bm25 = BM25Okapi(tokenized_corpus)
tokenized_query = query.split()
scores = bm25.get_scores(tokenized_query)
top_k = np.argsort(scores)[-k:]
return top_k
def hybrid_retrieve(query: str, dense_index: faiss.IndexFlatL2, corpus: list, k: int = 5):
query_emb = encode_query(query)
_, indices_dense = retrieve_documents(query_emb, dense_index, k)
indices_bm25 = bm25_retrieve(query, corpus, k)
# Merge indices (simple union, can use weighted merging)
merged_indices = list(set(indices_dense[0]).union(set(indices_bm25)))
return merged_indices
- 數據融合:根據相關性量度對從不同來源檢索到的數據進行動態(tài)加權和合并。 關鍵事實:Fusion RAG通過結合多種技術最大限度地提高檢索召回率和精度,提供更強大的外部環(huán)境,讓AI能獲取更全面的信息。
五、 Agentic RAG
Agentic RAG采用模塊化“代理”,專門用于特定任務,如查詢重新表述、文檔檢索和響應合成,允許動態(tài)、實時調整。
- 微服務架構:每個代理都作為獨立的服務(通常通過REST API)運行,通過消息隊列進行通信。
- 動態(tài)協調:代理根據他人的反饋調整行動,例如,Query Reformulator可能會根據初始檢索性能調整查詢。代碼如下:
import requests
def query_reformulator(raw_query: str) -> str:
response = requests.post("http://agent-service/reformulate", jsnotallow={"query": raw_query})
return response.json().get("reformulated_query", raw_query)
def document_retriever(query: str) -> list:
response = requests.post("http://agent-service/retrieve", jsnotallow={"query": query})
return response.json().get("documents", [])
def response_synthesizer(original_query: str, documents: list) -> str:
payload = {"query": original_query, "documents": documents}
response = requests.post("http://agent-service/synthesize", jsnotallow=payload)
return response.json().get("response", "")
def agentic_rag(raw_query: str) -> str:
reformulated_query = query_reformulator(raw_query)
docs = document_retriever(reformulated_query)
return response_synthesizer(raw_query, docs)
關鍵事實:Agentic RAG的分散式設計通過在專業(yè)服務之間劃分檢索生成過程,實現了精細的控制和可擴展性,就像一個分工明確的團隊高效協作。
六、Self-RAG:開啟LLM自我進化循環(huán)
Self-RAG是一種獨特的RAG變體,它賦予LLM根據自身生成的響應檢索上下文的能力,從而構建起一個迭代的自我提升循環(huán),就像為模型注入了自我反思的“智慧”。
自我嵌入:精準定位知識短板
在初始生成階段,模型會先依據輸入生成一個初步的響應。隨后,Self-RAG會對這個響應進行重新編碼,這一過程被稱為“自我嵌入”。通過自我嵌入,模型能夠精準地識別出自身知識的缺口,明確哪些地方的信息還不夠完善,哪些表述可能存在模糊之處。例如,在回答“2024年人工智能領域的重大突破有哪些”時,模型初步生成的答案中可能遺漏了部分關鍵突破,通過自我嵌入,就能發(fā)現這些缺失的信息。
內部反饋:知識檢索補充信息
基于自我評估所發(fā)現的知識差距,模型會啟動內部反饋機制。它會依據這些自我評估的結果,從外部知識庫或自身存儲的信息中檢索額外的上下文信息。這一過程就像是模型在主動查閱資料,為自己補充“營養(yǎng)”,讓回答更加全面和準確。比如,模型在發(fā)現自己對“2024年人工智能領域的重大突破”回答不足后,會去檢索相關的學術論文、新聞報道等資料,獲取更多詳細信息。
迭代優(yōu)化:反復打磨輸出質量
在獲取到額外的上下文信息后,Self-RAG會更新輸入提示,并將其重新輸入到模型中進行新一輪的生成。這個過程會不斷重復,直到模型對輸出結果的置信度達到較高水平。每一次迭代都是對答案的優(yōu)化和完善,使得模型的輸出更加精準、可靠。例如,經過多次迭代,模型對“2024年人工智能領域的重大突破”的回答可能會從最初的簡單列舉,變得詳細且深入,涵蓋突破的技術原理、應用場景以及對行業(yè)的影響等多方面內容。
代碼示例:Self-RAG的實現邏輯
def self_rag(prompt: str, iterations: int = 3) -> str:
current_prompt = prompt
for _ in range(iterations):
response = generate_response(current_prompt, gen_model, gen_tokenizer)
response_emb = encode_query(response)
additional_context = " [ADDITIONAL EVIDENCE REQUIRED]"
current_prompt = f"{prompt}\n{additional_context}"
return response
在這段代碼中,self_rag?函數接收一個提示prompt?和迭代次數iterations?作為參數。在循環(huán)中,模型首先根據當前提示生成響應response?,接著對響應進行編碼得到response_emb? ,然后添加額外的上下文信息additional_context到當前提示中,最后返回最終的響應。通過這樣的循環(huán)迭代,實現了Self-RAG的自我提升過程。
關鍵事實:減少依賴,提升自主性
Self-RAG的關鍵優(yōu)勢在于,它借助內部自我評估來迭代提升輸出質量。一旦模型識別到足夠的上下文信息,就能夠減少對外部資源的依賴,在保證回答質量的同時,提升了模型的自主性和效率。這意味著在一些外部資源受限的場景下,Self-RAG依然能夠給出高質量的回答,展現出更強的適應性和靈活性。
Self-RAG為LLM的發(fā)展開辟了新的路徑,通過自我反思和優(yōu)化機制,讓模型在不斷迭代中變得更加智能和可靠。在未來的人工智能應用中,Self-RAG有望在智能問答、文檔生成等領域發(fā)揮重要作用,為用戶提供更優(yōu)質的服務和體驗。
七、自適應RAG:智能決策的RAG變體
自適應RAG的核心在于引入了一種門控機制,這種機制能夠動態(tài)地決定模型是依靠自身內部的知識進行輸出,還是調用外部檢索來獲取更全面的信息。這一設計就像是為模型配備了一個智能“開關”,使其能根據具體情況靈活調整策略,在保證回答質量的同時,最大限度地提高資源利用效率。
門控網絡:精準評估,智能決策
門控網絡是自適應RAG的關鍵組件之一,它基于內部標記概率來計算置信度分數。簡單來說,模型會對輸入的查詢進行分析,根據自身對該查詢的理解程度給出一個置信度數值。這個數值反映了模型對利用內部知識回答問題的信心。如果模型對某個問題非?!笆煜ぁ?,其內部知識足以給出可靠的答案,那么置信度分數就會較高;反之,如果模型覺得這個問題比較陌生,內部知識可能不足以準確回答,置信度分數就會較低。
動態(tài)切換:靈活應變,高效輸出
基于門控網絡計算出的置信度分數,自適應RAG會進行動態(tài)切換。當置信度低于設定的閾值時,系統會判定模型內部知識不足,進而觸發(fā)外部檢索。在外部檢索過程中,模型會從預先構建的數據庫或知識源中查找相關信息,以補充自身的知識儲備。而當置信度高于閾值時,模型則會直接依賴內部知識進行回答,這樣可以避免不必要的外部檢索,節(jié)省計算資源和時間成本。
自適應提示:按需構建,精準引導
根據門控結果,自適應RAG會有條件地構建豐富的提示。如果觸發(fā)了外部檢索,模型會將檢索到的相關信息與原始查詢相結合,形成一個包含更多上下文的提示,為后續(xù)的回答生成提供更充足的信息。反之,如果直接依賴內部知識,提示則可能僅包含原始查詢。這種自適應的提示構建方式,能夠根據實際情況為模型提供最恰當的引導,幫助模型生成更準確、更符合需求的回答。
代碼示例:直觀展現,深入理解
def gating_decision(query: str, threshold: float = 0.85) -> bool:
query_emb = encode_query(query)
confidence = query_emb.norm().item() / 100
return confidence < threshold
def adaptive_rag(query: str, dense_index: faiss.IndexFlatL2) -> str:
if gating_decision(query):
distances, indices = retrieve_documents(encode_query(query), dense_index, k=5)
retrieved_docs = [chunks[i] for i in indices[0]]
prompt = construct_prompt(query, retrieved_docs)
else:
prompt = query
return generate_response(prompt, gen_model, gen_tokenizer)
在上述代碼中,gating_decision?函數用于判斷是否需要進行外部檢索。它首先對查詢進行編碼得到query_emb?,然后通過計算query_emb?的范數并除以100來得到置信度confidence?,最后將置信度與閾值進行比較,返回判斷結果。adaptive_rag?函數則根據gating_decision?的結果進行相應操作,如果需要外部檢索,就執(zhí)行檢索、構建提示等步驟;如果不需要,則直接將原始查詢作為提示。最后,調用generate_response函數生成回答。
關鍵事實:優(yōu)化資源,提升性能
自適應RAG的關鍵優(yōu)勢在于,它能夠根據實時的置信度測量來決定檢索的必要性,從而實現對資源的優(yōu)化利用。在面對大量查詢時,這種方式可以避免模型在不必要的情況下進行復雜的外部檢索,有效減少計算資源的消耗和響應時間,提升模型的整體性能。無論是在處理日常簡單問題,還是應對復雜的專業(yè)領域問題時,自適應RAG都能根據具體情況做出最佳決策,為用戶提供高效、準確的服務。
自適應RAG通過創(chuàng)新的門控機制和動態(tài)決策過程,為RAG技術的應用帶來了更高的靈活性和效率。它在優(yōu)化資源利用的同時,也提升了模型的性能表現,為大語言模型在更多領域的深入應用奠定了堅實基礎。未來,隨著技術的不斷發(fā)展,自適應RAG有望在智能問答、信息檢索等多個領域發(fā)揮更大的作用,為用戶帶來更加優(yōu)質的體驗。
八、 REFEED(檢索反饋):優(yōu)化回答的智慧“補丁”
REFEED,即檢索反饋(Retrieval Feedback),是RAG技術中的一個重要變體,它通過在模型初始輸出后反饋外部證據的方式,有效地“糾正”答案,從而顯著提升生成響應的質量。這一技術為大語言模型在處理復雜問題時提供了更可靠的解決方案,讓模型的回答更加準確和完善。下面,我們就來詳細了解REFEED的工作原理、具體實現步驟以及它的關鍵優(yōu)勢。
初始生成:奠定基礎,開啟優(yōu)化之旅
在REFEED的工作流程中,模型首先會根據輸入的問題生成一個初步答案。這個初始答案是基于模型自身的知識和訓練經驗得出的,它為后續(xù)的優(yōu)化提供了基礎框架。雖然初始答案可能并不完美,但它包含了模型對問題的初步理解和分析,為進一步的改進指明了方向。
反饋檢索:深度挖掘,填補知識缺口
得到初始答案后,REFEED會對這個答案進行深入分析,識別其中可能存在的信息差距或不準確之處?;谶@些分析結果,模型會啟動新的檢索過程,從外部知識庫或相關數據源中查找能夠補充和完善答案的信息。例如,如果初始答案在某個關鍵知識點上表述模糊或缺失,反饋檢索就會針對性地尋找相關的詳細解釋、案例或數據,以填補這些知識缺口。
輸出優(yōu)化:融合信息,打造精準回答
在獲取到額外的上下文信息后,REFEED會將這些信息與原始提示進行合并,構建一個包含更豐富信息的新提示。然后,模型會基于這個新提示再次生成回答。通過這種方式,模型能夠將新獲取的知識融入到答案中,對初始答案進行優(yōu)化和完善,從而生成一個更加準確、全面的最終回答。這種優(yōu)化過程就像是為初始答案打上了一個個“補丁”,讓答案的質量得到了顯著提升。
代碼示例:清晰呈現,掌握技術細節(jié)
def refeed_rag(query: str, dense_index: faiss.IndexFlatL2) -> str:
initial_response = generate_response(query, gen_model, gen_tokenizer)
feedback_query = f"{query} {initial_response}"
distances, indices = retrieve_documents(encode_query(feedback_query), dense_index, k=5)
additional_context = " ".join([chunks[i] for i in indices[0]])
new_prompt = f"{query}\n[REFEED CONTEXT] {additional_context}"
return generate_response(new_prompt, gen_model, gen_tokenizer)
在這段代碼中,refeed_rag?函數實現了REFEED的核心邏輯。它首先調用generate_response?函數生成初始答案initial_response?,然后將初始答案與原始查詢結合形成feedback_query?。接著,通過retrieve_documents?函數進行反饋檢索,獲取相關的上下文信息additional_context?。最后,將原始查詢和新獲取的上下文信息組合成新的提示new_prompt?,并再次調用generate_response函數生成優(yōu)化后的回答。
關鍵事實:高效精準,無需重新訓練
REFEED的關鍵優(yōu)勢在于,它能夠在不重新訓練模型的前提下,通過結合基于初始輸出反饋的二次檢索,顯著提高回答的準確性。這種方式不僅避免了重新訓練模型帶來的高昂成本和時間消耗,還能讓模型在面對新問題時快速適應,及時調整回答策略。無論是在處理突發(fā)的熱點問題,還是解決專業(yè)性較強的復雜問題時,REFEED都能通過高效的反饋檢索和輸出優(yōu)化機制,為用戶提供更加準確、可靠的答案,提升用戶體驗。
REFEED作為RAG技術的重要變體,通過獨特的檢索反饋機制,為大語言模型的回答優(yōu)化提供了一種高效、靈活的解決方案。它在不改變模型基礎架構的情況下,有效提升了模型的回答質量,為智能問答、信息服務等領域帶來了新的發(fā)展機遇。隨著技術的不斷進步,REFEED有望在更多場景中得到應用和拓展,為用戶提供更加優(yōu)質的知識服務。
九、REALM:檢索融入語言建模的新探索
REALM將檢索緊密集成到預訓練和推理過程中,讓模型從本質上就具備檢索感知能力。
利用檢索進行掩碼語言建模
在預訓練階段,模型會對標記進行屏蔽,然后結合內部上下文與外部檢索到的文檔來預測這些標記。這一過程就像是模型在“學習”如何利用外部知識來填補文本中的空缺,從而提升對語言的理解和生成能力。
聯合訓練
檢索器和生成器會以端到端的方式一起進行優(yōu)化。在這個過程中,兩者相互協作,檢索器為生成器提供更豐富準確的信息,生成器則根據這些信息不斷調整,使得整體模型在生成文本時更加準確和合理。
過程
- A)預訓練:對標記進行屏蔽,并檢索外部上下文信息,幫助模型學習如何利用外部知識來理解和生成文本。
- B)聯合優(yōu)化:通過反向傳播算法,讓檢索器和生成器同時優(yōu)化,以提高模型整體性能。
- C)推理:在生成文本的過程中,模型針對每個掩碼標記向檢索器發(fā)起查詢,獲取相關信息來生成更準確的內容。
實現細節(jié)
對transformer架構進行了修改,雖然具體代碼因模型而異,但關鍵步驟包括:
- 在transformer模塊中集成交叉注意力層,這一操作可以幫助模型更好地關注檢索到的信息。
- 在訓練時,基于預測的標記和檢索輸出共同計算損失函數,以此來引導模型學習到更有效的知識。
關鍵事實
REALM在訓練階段對架構進行修改,使得檢索成為語言建模的內在組成部分,而不是在推理時才進行的附加操作。這一設計讓模型在處理各種語言任務時,能夠更自然、高效地利用外部知識,提升了模型的性能和泛化能力。
十、 RAPTOR(遞歸抽象與樹狀結構檢索):構建層次化知識體系的檢索利器
RAPTOR將大型文檔組織成一個分層樹結構,為檢索和生成提供了多級抽象能力。
文檔分塊和聚類
利用k-means等算法對文檔進行分段處理,并將相似的數據塊聚集在一起。這一步就像是把一本厚厚的書按照主題和內容相似性分成不同的章節(jié)和段落,方便后續(xù)快速查找和管理。
樹構造
通過遞歸地匯總聚類結果,構建出分層樹。在這個樹結構中,每個節(jié)點都代表了一定層次的信息匯總,從宏觀到微觀,形成了一個有序的知識體系。
分層檢索
在查詢時,模型會遍歷這棵樹,既可以獲取高級別的摘要信息,也能深入到細節(jié)層面獲取精細的內容。這就好比在查閱一本目錄清晰的書籍時,既能快速了解各章節(jié)的核心要點,又能根據需要深入閱讀具體段落。
def cluster_chunks(embeddings: torch.Tensor, num_clusters: int = 10):
from sklearn.cluster import KMeans
emb_np = embeddings.detach().cpu().numpy()
kmeans = KMeans(n_clusters=num_clusters)
labels = kmeans.fit_predict(emb_np)
return labels, kmeans.cluster_centers_
def build_tree(chunks: list, labels: list):
tree = {}
for label in set(labels):
tree[label] = [chunks[i] for i, lab in enumerate(labels) if lab == label]
return tree
# 在查詢時:
def tree_retrieve(query: str, tree: dict):
aspects = query.split() # 用于適當分解的占位符
retrieved = []
for aspect in aspects:
for key, docs in tree.items():
if aspect.lower() in " ".join(docs).lower():
retrieved.extend(docs)
return list(set(retrieved))
# 使用方法:
labels, _ = cluster_chunks(chunk_embeddings, num_clusters=10)
raptor_tree = build_tree(chunks, labels)
tree_docs = tree_retrieve(query, raptor_tree)
raptor_prompt = construct_prompt(query, tree_docs)
raptor_response = generate_response(raptor_prompt, gen_model, gen_tokenizer)
關鍵事實
RAPTOR的多級檢索策略,能夠同時提供廣泛和詳細的上下文信息,這對于需要深入推理的任務來說至關重要。通過這種樹狀結構的組織和檢索方式,模型可以更全面、準確地理解問題,并給出更有深度和準確性的回答。
十一、 REVEAL(檢索增強視覺語言預訓練):開啟多模態(tài)檢索新時代
REVEAL通過將視覺和文本數據整合到統一的表示形式中,把RAG技術拓展到了多模態(tài)領域。
多模態(tài)編碼
使用共享編碼器將圖像和文本映射到同一個嵌入空間,使得模型能夠在同一“語言”下理解和處理不同模態(tài)的數據。這就像是為圖像和文本搭建了一座溝通的橋梁,讓它們可以在模型內部自由交互。
動態(tài)檢索
可以同時檢索與上下文相關的文本和視覺信息,為模型生成內容提供更豐富的素材。比如在描述一幅圖片時,模型不僅能根據圖片本身的特征,還能結合相關的文本描述來生成更準確、生動的內容。
融合機制
在transformer架構中利用注意力層來整合多模態(tài)數據。注意力層就像是模型的“聚焦器”,可以讓模型根據任務需求,有重點地關注不同模態(tài)的數據,從而更好地融合它們。
實現細節(jié)
- 對于圖像-文本對,可以借助CLIP等模型獲取聯合嵌入,讓圖像和文本在嵌入空間中建立緊密聯系。
- 檢索過程與標準RAG類似,但操作的是混合數據庫,其中包含了轉換為嵌入形式的圖像和文本數據。
關鍵事實
REVEAL的架構專門針對跨模態(tài)檢索進行了優(yōu)化,這對于視覺問答、圖像描述等多模態(tài)任務來說至關重要。它讓模型能夠充分利用不同模態(tài)的數據信息,生成更加準確和豐富的回答,為多模態(tài)人工智能應用開辟了新的道路。
十二、ReAct(推理和行動):推理與行動交織的智能模式
ReAct將推理與明確的行動交織在一起,使模型在生成過程中能夠執(zhí)行諸如API調用等操作。
思維鏈生成
模型會生成一個包含推理步驟的解釋序列,展示其思考過程。這就好比一個人在解決問題時,會逐步闡述自己的思路,讓他人能夠理解其思考邏輯。
行動令牌
通過特殊的標記,指示模型執(zhí)行特定的操作,例如查詢數據庫獲取相關信息。這些標記就像是模型的“行動指令”,引導模型與外部資源進行交互。
集成跟蹤
最終輸出不僅包含推理的路徑,還包括執(zhí)行行動的結果。這樣可以讓用戶清楚地看到模型是如何思考以及根據思考采取了哪些行動,結果又是什么。
def generate_with_actions(prompt: str) -> str:
inputs = gen_tokenizer.encode(prompt, return_tensors="pt", truncatinotallow=True, max_length=300)
outputs = gen_model.generate(inputs, max_length=300, num_beams=5)
return gen_tokenizer.decode(outputs[0], skip_special_tokens=True)
關鍵事實
ReAct的交錯設計需要精心設計提示工程,以便在同一生成周期內同時觸發(fā)推理和可執(zhí)行的輸出。這種設計讓模型能夠在思考的同時采取實際行動,獲取更多信息來完善回答,提升了模型的實用性和智能性,但也對提示設計提出了更高的要求。
十三、REPLUG(檢索插件):無損增強大語言模型的便捷方式
REPLUG把大語言模型視為一個“黑匣子”,在不修改模型的前提下,通過在輸入前添加外部檢索到的文檔來增強其輸入內容。
外部檢索
利用像FAISS這樣獨立的檢索系統來收集相關文檔,為模型提供豐富的外部知識支持。這就好比給模型配備了一個強大的“知識助手”,幫助它獲取更多信息。
提示增強
將檢索到的文檔添加到查詢前面,在保持大語言模型原始架構不變的情況下,豐富模型的輸入內容,引導模型生成更好的回答。
模型調用
把增強后的提示輸入到大語言模型中,讓模型基于這些豐富的信息進行處理和生成。
def replug_rag(query: str, dense_index: faiss.IndexFlatL2) -> str:
query_emb = encode_query(query)
_, indices = retrieve_documents(query_emb, dense_index, k=5)
retrieved = [chunks[i] for i in indices[0]]
enriched_prompt = construct_prompt(query, retrieved)
return generate_response(enriched_prompt, gen_model, gen_tokenizer)
關鍵事實
REPLUG提供了一種模塊化的方法,通過外部檢索提升大語言模型的性能,同時保持核心模型不變。這種方式簡單高效,方便在不同場景中快速應用,為優(yōu)化大語言模型的表現提供了一種便捷途徑。
十四、Memo RAG:融合記憶機制的智能檢索增強
Memo RAG集成了一個內存組件,它能將大型數據集壓縮成“全局內存”,并生成檢索線索來引導外部搜索。
內存模塊
運用知識蒸餾等技術壓縮大型數據集,將海量的信息濃縮成更易于管理和使用的形式,存儲在“全局內存”中。
線索生成
針對給定的查詢,模型會生成檢索提示,這些提示就像“線索”一樣,幫助模型在外部搜索時更精準地定位相關信息。
上下文集成
將生成的線索與檢索到的數據進行合并,構建最終的提示,為模型生成回答提供更有針對性的信息。
# 假設memory_module是一個預訓練模塊,具有generate_clue方法。
def memo_rag(query: str, dense_index: faiss.IndexFlatL2, memory_module) -> str:
clue = memory_module.generate_clue(query)
feedback_query = f"{query} {clue}"
_, indices = retrieve_documents(encode_query(feedback_query), dense_index, k=5)
retrieved = [chunks[i] for i in indices[0]]
prompt = construct_prompt(query, retrieved)
return generate_response(prompt, gen_model, gen_tokenizer)
關鍵事實
Memo RAG借助內部內存機制提高了外部檢索的精度,尤其在處理模糊或復雜查詢時表現出色。通過生成線索引導檢索,模型能夠更準確地找到相關信息,從而生成更符合需求的高質量回答。
解鎖RAG的進階奧秘:ATLAS及其他變體深度解析
在檢索增強生成(RAG)技術的不斷演進中,誕生了諸多創(chuàng)新的變體,為大語言模型(LLM)的發(fā)展注入了新的活力。今天,讓我們一同深入探索從15. ATLAS開始的多種RAG變體,揭開它們提升模型性能的神秘面紗。
十五、ATLAS(基于注意力的RAG):檢索與注意力的深度融合
ATLAS的獨特之處在于,它將檢索與注意力機制巧妙融合,通過把檢索到的文檔直接整合到transformer的注意力層,讓模型在處理文本時能夠更充分地利用外部知識。
密集嵌入與檢索
ATLAS運用密集嵌入技術,從海量數據中精準檢索出語義相似的文檔,為后續(xù)的處理提供豐富的信息來源。
交叉注意力集成
在編碼器 - 解碼器框架內,ATLAS借助交叉注意力層,將檢索到的上下文信息無縫融入到模型的處理過程中,使得模型在生成文本時能夠更好地關注相關信息。
聯合優(yōu)化
為了實現更高效的信息整合,ATLAS對檢索器和生成器進行聯合訓練,確保兩者協同工作,優(yōu)化整體性能。
實現細節(jié)
在技術實現上,ATLAS對transformer架構進行了優(yōu)化,新增的交叉注意力層將檢索到的嵌入作為鍵和值。這里運用到的標準注意力公式為:
def scaled_dot_product_attention(Q, K, V, mask=None):
import math
d_k = Q.size(-1)
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(d_k)
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
attention_weights = torch.softmax(scores, dim=-1)
output = torch.matmul(attention_weights, V)
return output, attention_weights
其中,和均來自檢索到的數據。
- 關鍵事實:ATLAS的設計將外部上下文緊密地與令牌級預測相結合,這一特性使得模型在處理知識密集型任務時表現卓越,顯著提升了性能。
十六、RETRO(檢索增強變壓器):Transformer架構中的檢索創(chuàng)新
RETRO另辟蹊徑,將檢索功能融入transformer的架構之中。它把輸入文本劃分為固定大小的塊,然后利用交叉注意力機制從外部數據庫中查找相似序列。
塊分割
首先,RETRO會把輸入文本切割成固定大小的塊,為后續(xù)的檢索和處理做好準備。
最近鄰檢索
針對每個文本塊,RETRO使用FAISS等工具從大型索引語料庫中檢索相似的塊,獲取相關信息。
交叉注意力層
通過額外的交叉注意力機制,RETRO將檢索到的塊融入到文本生成過程中,增強模型對信息的利用效率。
def retro_retrieve(block_embedding, index, k=5):
distances, indices = index.search(block_embedding.detach().cpu().numpy().astype('float32'), k)
return indices
output = scaled_dot_product_attention(Q, K, V)[0]
關鍵事實?
RETRO通過在令牌生成階段高效整合外部信息,成功實現了以較少的參數提升模型性能的目標。
十七、 自動RAG:自主優(yōu)化的迭代循環(huán)
自動RAG引入了自主迭代循環(huán)機制,模型能夠自我評估輸出,并根據評估結果決定是否需要進一步檢索。
自我評估
在初始生成文本后,自動RAG模型會對輸出的置信度進行評估,判斷當前答案的可靠性。
動態(tài)迭代
如果輸出置信度較低,模型會觸發(fā)額外的檢索循環(huán),并更新提示信息,再次生成文本,不斷優(yōu)化答案。
終止標準
這一過程會持續(xù)進行,直到模型輸出達到預設的收斂閾值,確保最終答案的質量。
def auto_rag(prompt: str, max_iterations: int = 3, threshold: float = 0.8) -> str:
current_prompt = prompt
for i in range(max_iterations):
response = generate_response(current_prompt, gen_model, gen_tokenizer)
output_ids = gen_tokenizer.encode(response, return_tensors="pt")
conf = evaluate_confidence(output_ids)
if conf >= threshold:
break
current_prompt += "\n[RETRIEVE_MORE]"
return response
關鍵事實
自動RAG基于內部置信度評估,通過自動化的迭代重新檢索循環(huán),有效提升了輸出質量。
十八、 CORAG(成本受限的RAG):資源約束下的檢索優(yōu)化
CORAG聚焦于在資源受限的環(huán)境中優(yōu)化檢索過程,它采用蒙特卡洛樹搜索(MCTS)等策略,平衡檢索質量與計算成本。
MCTS檢索
CORAG將候選檢索組合視為搜索樹中的節(jié)點,通過MCTS算法對這些節(jié)點進行探索,尋找最優(yōu)的檢索方案。
成本建模
為了控制計算成本,CORAG引入成本函數,對高成本的檢索路徑進行懲罰,引導模型選擇更經濟高效的檢索方式。
自適應配置
在資源限制的前提下,CORAG會選擇能夠最大化檢索質量的配置,確保在有限資源下實現最佳檢索效果。
def mcts_retrieval(query: str, index: faiss.IndexFlatL2, iterations: int = 10):
best_set = None
best_score = -float('inf')
for _ in range(iterations):
candidate_set = sample_candidate_set(index)
quality = evaluate_candidate_quality(candidate_set, query)
cost = evaluate_candidate_cost(candidate_set)
score = quality - cost
if score > best_score:
best_score = score
best_set = candidate_set
return best_set
關鍵事實
CORAG的成本感知優(yōu)化策略,確保了在資源有限的場景下,檢索過程依然高效且有效。
十九、 EACO - RAG(邊緣輔助和協作RAG):分布式檢索的新范式
EACO - RAG借助邊緣計算的優(yōu)勢,將檢索過程分布到各個邊緣節(jié)點,有效降低延遲并平衡計算負載。
本地知識庫
每個邊緣節(jié)點都維護著本地化且及時更新的索引,方便快速檢索本地相關信息。
協作檢索
邊緣節(jié)點之間通過消息隊列進行通信,協同完成檢索任務,實現資源的高效利用。
貝葉斯多臂強盜算法
為了動態(tài)分配資源,EACO - RAG采用貝葉斯多臂強盜算法,根據節(jié)點的實時性能指標,合理分配檢索任務。
def edge_retrieve(query: str, local_index: faiss.IndexFlatL2) -> list:
q_emb = encode_query(query)
_, indices = retrieve_documents(q_emb, local_index, k=5)
return [chunks[i] for i in indices[0]]
def collaborative_retrieve(query: str, edge_indices: list) -> list:
results = []
for idx in edge_indices:
results.extend(edge_retrieve(query, idx))
return rank_results(results)
- 關鍵事實:EACO - RAG利用分布式計算,在大規(guī)模部署中實現了低延遲、可擴展的檢索。
二十、規(guī)則RAG:特定領域的精準檢索
規(guī)則RAG通過應用明確的特定領域規(guī)則,指導檢索和合成過程,確保最終輸出僅包含高度相關的文檔信息。
規(guī)則引擎
規(guī)則RAG使用Python或外部規(guī)則引擎,實施確定性規(guī)則,對文檔進行篩選和排序。
檢索前后過濾
在檢索前,規(guī)則用于優(yōu)化查詢條件;檢索后,規(guī)則則對檢索結果進行進一步篩選,確保輸出的相關性。
def apply_rules(query: str, documents: list, keyword: str = "RAG") -> list:
return [doc for doc in documents if keyword.lower() in doc.lower()]
def rule_rag(query: str, dense_index: faiss.IndexFlatL2) -> str:
_, indices = retrieve_documents(encode_query(query), dense_index, k=10)
raw_docs = [chunks[i] for i in indices[0]]
filtered_docs = apply_rules(query, raw_docs, keyword="RAG")
prompt = construct_prompt(query, filtered_docs)
return generate_response(prompt, gen_model, gen_tokenizer)
關鍵事實
規(guī)則RAG的確定性篩選機制,通過嚴格的標準確保只有符合要求的文檔才會參與最終輸出,極大地增強了在專業(yè)領域的相關性。
二十一、對話式RAG:多輪對話的智能伙伴
對話式RAG專為多輪對話系統設計,它能夠根據對話歷史持續(xù)更新檢索上下文,提供更符合對話情境的回答。
上下文跟蹤
對話式RAG會維護一個對話歷史緩沖區(qū),記錄每一輪對話的內容。
動態(tài)檢索
在每一輪對話中,它會結合累積的上下文信息,查詢外部數據源,獲取更全面的信息。
集成合成
將對話歷史與新檢索到的內容進行融合,生成連貫、準確的回復。
def conversational_rag(dialogue_history: list, query: str, dense_index: faiss.IndexFlatL2) -> str:
context = " ".join(dialogue_history)
full_query = f"{context} {query}"
_, indices = retrieve_documents(encode_query(full_query), dense_index, k=5)
retrieved = [chunks[i] for i in indices[0]]
prompt = construct_prompt(full_query, retrieved)
return generate_response(prompt, gen_model, gen_tokenizer)
關鍵事實
對話式RAG能夠在多輪交互中保留上下文信息,實現動態(tài)檢索,準確反映整個對話的意圖。
二十二、迭代RAG:精益求精的答案優(yōu)化
迭代RAG通過多次檢索和生成循環(huán),不斷優(yōu)化響應,直至答案滿足預設的收斂標準。
?初始生成
首先生成一個基線響應,作為后續(xù)優(yōu)化的基礎。
差距分析
對基線響應進行分析,找出其中置信度較低或缺失信息的部分。
細化循環(huán)
針對這些差距重新進行查詢,并迭代更新提示信息,逐步完善答案。
def iterative_rag(query: str, dense_index: faiss.IndexFlatL2, max_iters: int = 3) -> str:
current_prompt = query
for _ in range(max_iters):
response = generate_response(current_prompt, gen_model, gen_tokenizer)
if "unclear" not in response:
return response
_, indices = retrieve_documents(encode_query(response), dense_index, k=5)
additional_context = " ".join([chunks[i] for i in indices[0]])
current_prompt = f"{query}\n{additional_context}"
return response
- 關鍵事實:迭代RAG的重復循環(huán)機制,對于復雜或多方面的查詢,能夠有效提升響應質量。
二十三、上下文驅動的樹狀結構檢索:復雜查詢的拆解與解答
這種RAG變體將復雜查詢分解為子查詢的樹狀層次結構,全面探索問題的各個方面。
方面分解
- 把復雜查詢解析為多個子主題,明確問題的不同維度。
樹構造
- 按照層次結構組織這些子主題,每個分支代表一個特定的方面。
分支檢索與聚合
- 針對每個分支獨立檢索文檔,最后將結果合并,給出全面的答案。
def decompose_query(query: str) -> list:
# 為演示目的,按標點分割;如有需要,可替換為高級主題建模方法
return query.split(";")
def tree_retrieve(aspects: list, dense_index: faiss.IndexFlatL2) -> list:
tree_results = []
for aspect in aspects:
_, indices = retrieve_documents(encode_query(aspect), dense_index, k=3)
tree_results.extend([chunks[i] for i in indices[0]])
return list(set(tree_results))
def tree_rag(query: str, dense_index: faiss.IndexFlatL2) -> str:
aspects = decompose_query(query)
tree_docs = tree_retrieve(aspects, dense_index)
prompt = construct_prompt(query, tree_docs)
return generate_response(prompt, gen_model, gen_tokenizer)
關鍵事實
- 樹狀結構的方法確保了復雜查詢的每個方面都能得到處理,最終生成更全面的回復。
二十四、CRAT(因果增強反射翻譯):翻譯領域的智能升級
CRAT將檢索和因果推理融入翻譯過程,有效處理模糊或特定領域的術語翻譯。
未知術語檢測
首先識別可能在翻譯中存在問題的術語,為后續(xù)處理做準備。
雙語知識圖譜構建
構建一個雙語知識圖譜(TransKG),映射術語及其跨語言關系。
因果反思
運用因果推理驗證檢索到的翻譯是否符合上下文語境。
最終翻譯合成
將經過驗證的外部數據與模型內部的翻譯輸出進行融合,得出最終準確的翻譯結果。
def detect_unknown_terms(text: str) -> list:
return [word for word in text.split() if word.isupper()]
def construct_transkg(terms: list) -> dict:
return {term: f"translated_{term}" for term in terms}
def crat_translate(text: str) -> str:
unknown_terms = detect_unknown_terms(text)
transkg = construct_transkg(unknown_terms)
for term, translation in transkg.items():
text = text.replace(term, translation)
return text
關鍵事實
CRAT通過整合經過因果推理驗證的外部雙語信息,確保了翻譯的準確性。
二十五、Graph RAG:結構化知識的力量
Graph RAG借助結構化知識圖譜,捕捉實體之間的關系,并將這些結構化上下文融入文本生成過程。
實體和關系提取
使用命名實體識別(NER)和關系提取工具(如SpaCy)解析文檔,提取其中的實體和關系。
知識圖譜構建
利用NetworkX或Neo4j等工具構建知識圖譜,直觀呈現實體間的聯系。
圖嵌入和遍歷
通過圖神經網絡(GNN)生成節(jié)點嵌入,并遍歷圖譜,找到與上下文相關的子圖。
提示增強
將結構化的圖譜數據(如關鍵實體、關系)融入提示信息,輔助模型生成更準確的文本。
import spacy, networkx as nx
nlp = spacy.load("en_core_web_sm")
def extract_entities_relations(text: str) -> (list, list):
doc = nlp(text)
entities = [ent.text for ent in doc.ents]
relations = [(entities[i], entities[j]) for i in range(len(entities)) for j in range(i+1, len(entities))]
return entities, relations
def build_graph(documents: list) -> nx.Graph:
G = nx.Graph()
for doc in documents:
entities, relations = extract_entities_relations(doc)
for entity in entities:
G.add_node(entity)
for (e1, e2) in relations:
G.add_edge(e1, e2)
return G
def graph_based_prompt(query: str, G: nx.Graph) -> str:
relevant_nodes = [node for node in G.nodes if node.lower() in query.lower()]
graph_context = " ".join(relevant_nodes)
return f"{query}\n[GRAPH_CONTEXT] {graph_context}"
關鍵事實
圖形RAG通過將結構化關系融入生成提示,提供了更深入的上下文理解,提高了復雜信息檢索的準確性。
本文轉載自 ??柏企閱文??,作者: 柏企
