RAG——檢索增強(qiáng)生成

RAG認(rèn)知與項(xiàng)目實(shí)踐

一、RAG - 檢索增強(qiáng)生成

  1. 為什么需要RAG

    • 時(shí)效性

      大模型無(wú)法詢(xún)問(wèn)最新的時(shí)事,比如問(wèn)LLM:“抗戰(zhàn)勝利80周年閱兵展示了哪些武器?”

    • 知識(shí)覆蓋度

      雖然大模型的訓(xùn)練數(shù)據(jù)集非常龐大,但仍可能無(wú)法覆蓋所有領(lǐng)域的知識(shí)或特定領(lǐng)域的深度信息。

    • 幻覺(jué)問(wèn)題

      大模型LLM再某些情況(提問(wèn)方式不對(duì)、模型知識(shí)欠缺)下給出的回答很可能是錯(cuò)誤的,或者涉及虛構(gòu)甚至是故意欺騙的信息,這種回答被稱(chēng)之為AI幻覺(jué),即大模型一本正經(jīng)的胡說(shuō)八道。

  2. 解決方案

    解決知識(shí)更新緩慢和幻覺(jué)問(wèn)題 : RAG和微調(diào)

    時(shí)效性可以用Agent解決

    • 大模型微調(diào)(Fine-Tuning)

      再通用大模型基礎(chǔ)上,針對(duì)超出其范圍或者不擅長(zhǎng)的特定領(lǐng)域或任務(wù),使用專(zhuān)門(mén)的數(shù)據(jù)集或方法對(duì)模型進(jìn)行相應(yīng)的調(diào)整和優(yōu)化,以提升其再該特定領(lǐng)域或任務(wù)重的實(shí)用性和性能表現(xiàn)

  3. 什么是RAG

    RAG,外掛知識(shí)庫(kù)的方式,實(shí)現(xiàn)成本和復(fù)雜度都比微調(diào)更低,且RAG在知識(shí)庫(kù)更新方面表現(xiàn)最佳。

方法 知識(shí)更新能力 實(shí)現(xiàn)復(fù)雜度 成本 使用場(chǎng)景
提示詞工程 低(依賴(lài)模型原有知識(shí)) 靜態(tài)知識(shí)場(chǎng)景
微調(diào) 中(需要重新訓(xùn)練) 領(lǐng)域知識(shí)需要定期更新
RAG 高(實(shí)時(shí)檢索最新數(shù)據(jù)) 需要最新信息的場(chǎng)景

分析:

  • RAG在知識(shí)更新方面表現(xiàn)最佳,因?yàn)樗梢詫?shí)時(shí)訪(fǎng)問(wèn)最新數(shù)據(jù)源
  • 微調(diào)需要定期重新訓(xùn)練模型才能納入新知識(shí)
  • 提示詞工程幾乎無(wú)法解決知識(shí)更新問(wèn)題,完全依賴(lài)模型訓(xùn)練時(shí)的知識(shí)

RAG(Retrieval Augmented Generation/ 檢索增強(qiáng)生成)是一種結(jié)合了檢索和生成兩種方法的技術(shù)。它通過(guò)先檢索相關(guān)的文檔,用檢索出來(lái)的信息對(duì)提示詞增強(qiáng),再使用大模型生成答案

RAG的本質(zhì)是:RAG = 大模型LLM + 外部數(shù)據(jù)


二、Naive RAG主要有三個(gè)步驟

  1. 索引化
    文檔 → 分塊 → 向量化(向量化文檔) → 存儲(chǔ)

  2. 檢索
    用戶(hù)提問(wèn) → 向量化(向量化問(wèn)題) → 檢索數(shù)據(jù)庫(kù) → 得到top-K個(gè)相關(guān)文檔快(Top-K指的是排名靠前的K個(gè)文檔)

  3. 增強(qiáng)生成
    增強(qiáng)提示詞(原始問(wèn)題 + 相關(guān)文檔快) → LLM → 生成答案

分塊策略

  • 按照字符數(shù)來(lái)切分
  • 按固定字符數(shù) 結(jié)合 overlapping winow (重復(fù)窗口)
  • 按照句子來(lái)切分
  • 遞歸方法 RecursiveCharacterTextSplitter langchain方法(推薦)
from langchain.text_splitter import RecursiveCharacterTextSplitter

text = ("自然語(yǔ)言處理(NLP),作為計(jì)算機(jī)科學(xué)、人工智能與語(yǔ)言學(xué)的交融之地,致力于賦予計(jì)算機(jī)解析和處理人類(lèi)語(yǔ)言的能力。"
        "在這個(gè)領(lǐng)域,機(jī)器學(xué)習(xí)發(fā)揮著至關(guān)重要的作用。利用多樣的算法,機(jī)器得以分析、領(lǐng)會(huì)乃至創(chuàng)造我們所理解的語(yǔ)言。"
        "從機(jī)器翻譯到情感分析,從自動(dòng)摘要到實(shí)體識(shí)別,NLP的應(yīng)用已遍布各個(gè)領(lǐng)域。隨著深度學(xué)習(xí)技術(shù)的飛速進(jìn)步,"
        "NLP的精確度與效能均實(shí)現(xiàn)了巨大飛躍。如今,部分尖端的NLP系統(tǒng)甚至能夠處理復(fù)雜的語(yǔ)言理解任務(wù),"
        "如問(wèn)答系統(tǒng)、語(yǔ)音識(shí)別和對(duì)話(huà)系統(tǒng)等。NLP的研究推進(jìn)不僅優(yōu)化了人機(jī)交流,也對(duì)提升機(jī)器的自主性和智能水平起到了關(guān)鍵作用。")

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=50,
    chunk_overlap=5,
    separators=["\n\n", "\n", "。", ",", ""],
)

lst = text_splitter.split_text(text)
print(lst)
for i,item in enumerate(lst):
    print(f"第{i}段,長(zhǎng)度為{len(item)},內(nèi)容:{item}")

向量化

Ollama本地向量化

from ollama import Client

client = Client("http://127.0.0.1:11434")

response = client.embed(
    model='bge-m3',
    input=['The sky is blue because of Rayleigh scattering','我愛(ài)你中國(guó)']
)
lst = [i for i in response.embeddings]
for i,item in enumerate(lst):
    print(f"第{i}段,長(zhǎng)度為{len(item)},內(nèi)容:{item}")

百煉平臺(tái)向量化

import os
from openai import OpenAI

input_text = ["衣服的質(zhì)量杠杠的","我愛(ài)你中國(guó)"]

client = OpenAI(
    # 若沒(méi)有配置環(huán)境變量,請(qǐng)用阿里云百煉API Key將下行替換為:api_key="sk-xxx",
    # 新加坡和北京地域的API Key不同。獲取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是北京地域base-url,如果使用新加坡地域的模型,需要將base_url替換為:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)

completion = client.embeddings.create(
    model="text-embedding-v4",
    input=input_text
)

lst = [item.embedding for item in completion.data]

for i,item in enumerate(lst):
    print(f"第{i}段,長(zhǎng)度為{len(item)},內(nèi)容:{item}")

向量間的相似度計(jì)算

常用的向量相似度計(jì)算方法包括:

  • 余弦相似度Cosine:基于兩個(gè)向量夾角的余弦值來(lái)衡量相似度(語(yǔ)義相關(guān)性)越接近1越相似
  • 歐式距離L2:通過(guò)計(jì)算向量之間的歐幾里得距離來(lái)衡量相似度(二維空間就是勾股定理 c2 = a2 + b2)越小越相似
  • 點(diǎn)積:計(jì)算兩個(gè)向量的點(diǎn)積,適合歸一化后的向量

第一種和第二種使用較多

向量數(shù)據(jù)庫(kù)

向量數(shù)據(jù)庫(kù)是一種專(zhuān)門(mén)設(shè)計(jì)用來(lái)存儲(chǔ)和查詢(xún)向量嵌入數(shù)據(jù)的數(shù)據(jù)庫(kù)。

1.Pinecone(必須用它的服務(wù)器托管,但存在數(shù)據(jù)安全問(wèn)題)
  • 重復(fù)檢測(cè):幫助用戶(hù)識(shí)別和刪除重復(fù)數(shù)據(jù)
  • 排名跟蹤:跟蹤數(shù)據(jù)在搜索結(jié)果中的排名,有助于優(yōu)化和調(diào)整搜索策略
  • 數(shù)據(jù)搜索:快速搜索數(shù)據(jù)庫(kù)中的數(shù)據(jù),支持復(fù)雜的搜索條件
  • 分類(lèi):對(duì)數(shù)據(jù)進(jìn)行分類(lèi),便于管理和檢索
  • 去重:自動(dòng)識(shí)別和刪除重復(fù)數(shù)據(jù)。保持?jǐn)?shù)據(jù)集的純凈和一致性
  • 閉源
2. Milvus
  • 毫秒級(jí)搜索十幾億向量數(shù)據(jù)集
  • 簡(jiǎn)單管理非結(jié)構(gòu)化數(shù)據(jù)
  • 可靠的向量數(shù)據(jù)庫(kù),始終可用
  • 高度可擴(kuò)展和適應(yīng)性強(qiáng)。支持分布式部署
  • 混合搜索
  • 收到社區(qū)支持,得到行業(yè)認(rèn)可,企業(yè)應(yīng)用較多
  • 開(kāi)源
  • 中國(guó)創(chuàng)業(yè)公司ZILLIZZ研發(fā)
3. Chroma
  • 功能豐富:支持查詢(xún)、過(guò)濾、密度估計(jì)等多種功能
  • 很多開(kāi)發(fā)框架如LangChain都支持
  • 相同API可以在Python筆記中運(yùn)行,也可以擴(kuò)展到集群,用于開(kāi)發(fā)、測(cè)試和生產(chǎn)閉源
  • 輕量級(jí)、易用性,易于集成和使用,特別適合小型或中型項(xiàng)目
  • 開(kāi)源
4. Faiss
  • 出身名門(mén)Meta,起源于Meta的AI研究需求
  • 可以同時(shí)搜索多個(gè)向量,而不僅僅是單個(gè)向量
  • 用于高校處理大規(guī)模密集向量相似度搜索
  • 支持多種距離度量、豐富的索引結(jié)構(gòu)、向量化技術(shù)
  • 高校的并行處理能力
  • 騰訊率先在國(guó)內(nèi)大規(guī)模引用。Faiss尤其適用于圖像檢索和推薦系統(tǒng)

Chroma 實(shí)戰(zhàn)

  1. 創(chuàng)建client

    client = chromadb.Client() # 存在內(nèi)存,臨時(shí)存儲(chǔ)
    client = chromadb.PersistentClient(path="路徑") # 存入本地,可以做持久化
    
  2. collection的使用

    2.1 列出所有collection列表:client.list_collections()
    2.2 創(chuàng)建:client.create_collection(name="collection名稱(chēng)",embedding_function=向量化函數(shù))
    2.3 獲?。篶ollection = client.get_collection(name="my_collection",embedding_function=emb_fn)
    2.4 沒(méi)有就創(chuàng)建,有則獲?。篶lient.get_or_create_collection(name="collection名稱(chēng)")
    2.5 刪除:client.delete_conllection(name="my_collection")
    
  3. collection的主要功能

    # 添加文檔
    collection.add(
        documents = [...], # 原始文本內(nèi)容(可選)
        embeddings = [[...],[...]], # 文檔的向量表達(dá)(必須)
        ids = [...] # 每個(gè)文檔的唯一ID(必須)
    )
    # 相似度檢測(cè)
    results = collection.query(
        query_embeddings = [0.1,0.2,...], # 問(wèn)題向量化后的向量
        n_results = 5, # 返回前5個(gè)最相似的結(jié)果
    )
    

    注意:

    項(xiàng)目 說(shuō)明
    向量維度必須一致 查詢(xún)時(shí)使用的embedding model必須與插入時(shí)的一致
    ID唯一性 插入時(shí)每個(gè)文檔必須有唯一的ID
    距離越小越相似 distances 字段表示與查詢(xún)向量的距離,數(shù)值越小越相似
    支持批量查詢(xún) 可以一次傳多個(gè)查詢(xún)文本向量,得到多個(gè)結(jié)果列表

三、全文檢索和向量相似度檢索

BM25分?jǐn)?shù)歸一化到[0,1]區(qū)間方法

用數(shù)組中的(每個(gè)元素 - 最小值)/ (最大值 - 最小值),實(shí)現(xiàn)將分?jǐn)?shù)縮放到0和1之間的目的

例如:[1,2,3,4,5]歸一化后的結(jié)果是[0, 0.25, 0.5, 0.75, 1]

(1 - 1) / (5 - 1) = 0 / 4 = 0

(2 - 1) / (5 - 1) = 1 / 4 = 0.25

(3 - 1) / (5 - 1) = 2 / 4 = 0.5

(4 - 1) / (5 - 1) = 3 / 4 = 0.75

(5 - 1) / (5 - 1) = 4 / 4 = 1

距離轉(zhuǎn)換相似度分?jǐn)?shù)歸一化方法

歐氏距離越小,相似度越高,所以用1減去歸一化分?jǐn)?shù)

vector_scores = np.linalg.norm(query_embedding - doc_embeddings,axis=1)
max_score = np.max(vector_scores)
min_score = np.min(vector_scores) 
vector_scores_normalized = 1 - (vector_scores - min_score) / (max_score - min_score)

Numpy數(shù)組歸一化

使用np.array()函數(shù)把bm25_scores轉(zhuǎn)為NumPy數(shù)組

bm25_scores 原本可能是Python 列表,轉(zhuǎn)換為NumPy數(shù)組后,能更方便地進(jìn)行歸一化

bm25_scores = np.array(bm25_scores) # 轉(zhuǎn)換成np數(shù)組
max_score = bm25_scores.max() # 最高分?jǐn)?shù)
min_score = bm25_scores.min() # 最低分?jǐn)?shù)
# 開(kāi)始?xì)w一化
bm25_scores_normalized = (bm25_scores - min_score) / (max_score - min_score)

將兩種方法的分?jǐn)?shù)進(jìn)行加權(quán)組合

權(quán)重均為0.5,這樣可以綜合考慮兩種方法的優(yōu)點(diǎn),得到更準(zhǔn)確的文檔相關(guān)性評(píng)分

combined_scores = bm25_weight * bm25_scores_normalized + (1-bm25_weight)*vector_scores_normalized

根據(jù)組合分?jǐn)?shù)對(duì)結(jié)果排序并返回3個(gè)最相關(guān)的文檔

# 數(shù)組進(jìn)行降序排列,返回倒序后的索引下標(biāo)
top_index = combined_scores.argsort()[::-1]
# 輸出混合搜索的結(jié)果:最相關(guān)文檔outputs
hybrid_results = [outputs[i] for i in top_index[:top_k]]
# hybrid_results = np.array(outputs)[top_index[:top_k]]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容