成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

大模型之深入探索RAG流程 原創

發布于 2024-12-19 09:30
瀏覽
0收藏

前言

在上一章【大模型之初識RAG】中,我們初步了解了RAG的基本概念和原理,并通過代碼實踐了一個簡單的RAG流程。本章我們將基于RAG的基本流程,深入了解??文檔讀取(LOAD)???、??文檔切分(SPLIT)???、??向量化(EMBED)??? 和 ??存儲(STORE)?? 的每個環節,并結合代碼進行常見場景的實踐。

RAG流程回顧

大模型之深入探索RAG流程-AI.x社區

回顧RAG的流程如上所示,具體代碼見RAG代碼,本章不再贅述。

文檔讀取(LOAD)

簡介:由于我們的知識廣泛存在各類文檔中,所以文檔讀取(??LOAD???)在RAG系統中承擔著 ??獲取數據?? 的職責。

常見文件

  • 文本文件(.txt)
  • CSV(.csv)
  • PDF(.pdf)
  • Word 文檔(.docx)
  • Excel 工作簿(.xlsx)
  • PPT 演示文稿(.pptx)
  • HTML 文件(.html)
  • Markdown 文件(.md)

常見的文件處理庫

  • langchain_community.document_loaders
  • 在langchain_community的API文檔中有數十種文件的處理API,除了上述常見的文件之外,還有.srt字幕文件、.ipynb文件、代碼片段等支持。

CSV文件加載器

CSVLoader函數說明

class langchain_community.document_loaders.csv_loader.CSVLoader(
    file_path:Union[str,Path],
    source_column:Optional[str]=None,
    metadata_columns:Sequence[str]=(),
    csv_args:Optional[Dict]=None,
    encoding:Optional[str]=None,
    autodetect_encoding:bool=False)

說明:

  • ??file_path??:指定要加載的 CSV 文件的路徑

     例如:"data/myfile.csv"

  • ??source_column??(可選):指定哪一列作為數據的主要來源。

        例如:"text"

  • ??metadata_columns??:指定哪些列應作為元數據加載。

       例如:["name", "age"]

  • ??csv_args??(可選):自定義 CSV 加載的行為。

       例如:{"delimiter": ";", "header": 0}(指定分隔符為分號,并將第一行作為表頭)

示例

示例1:僅加載.csv文件示例:

from langchain_community.document_loaders import CSVLoader

students_loader = CSVLoader(file_path="testfiles/students.csv")
docs = students_loader.load()
docs

運行結果:

# [Document(metadata={'source': 'testfiles/students.csv', 'row': 0}, page_cnotallow='name: Tom\nage: 12\nscore: 77'),
#  Document(metadata={'source': 'testfiles/students.csv', 'row': 1}, page_cnotallow='name: Jerry\nage: 11\nscore: 88'),
#  Document(metadata={'source': 'testfiles/students.csv', 'row': 2}, page_cnotallow='name: Jim\nage: 12\nscore: 96')]

說明:

  • metadata:文檔元數據,包括文檔來源、行號等,用來進行溯源使用。
  • page_content:文檔內容,即文本內容。

示例2:加載.csv文件指定列作為元數據:

from langchain_community.document_loaders import CSVLoader

students_loader = CSVLoader(file_path="testfiles/students.csv", metadata_columns=["name", "score"])
docs = students_loader.load()
docs

運行結果:

# [Document(metadata={'source': 'testfiles/students.csv', 'row': 0, 'name': 'Tom', 'score': '77'}, page_cnotallow='age: 12'),
#  Document(metadata={'source': 'testfiles/students.csv', 'row': 1, 'name': 'Jerry', 'score': '88'}, page_cnotallow='age: 11'),
#  Document(metadata={'source': 'testfiles/students.csv', 'row': 2, 'name': 'Jim', 'score': '96'}, page_cnotallow='age: 12')]

示例3:使用RAG鏈測試大模型的知識理解能力

from langchain_community.document_loaders importCSVLoader
from langchain_core.output_parsers importStrOutputParser
from langchain_core.runnables importRunnablePassthrough
from langchain_chroma importChroma
from langchain_core.prompts importChatPromptTemplate
from utils import get_qwen_models

defformat_docs(docs):
return"\n\n".join(doc.page_content for doc in docs)

# 連接大模型
llm, chat, embed = get_qwen_models()

# 讀取.csv文件
students_loader =CSVLoader(file_path="testfiles/students.csv")
docs = students_loader.load()

# 向量化入庫
vectorstore =Chroma.from_documents(documents=docs, embedding=embed)

retriever = vectorstore.as_retriever(search_kwargs={"k":2})

prompt =ChatPromptTemplate.from_messages([
("human","""You are an assistant for question-answering tasks. 
Use the following pieces of retrieved context to answer the question. 
If you don't know the answer, just say that you don't know. 
Use three sentences maximum and keep the answer concise.
Question: {question} 
Context: {context} 
Answer:""")
])

# RAG 鏈
rag_chain =(
{"context": retriever | format_docs,
"question":RunnablePassthrough()}
| prompt
| chat
|StrOutputParser()
)

rag_chain.invoke(input="誰的成績最高?")

運行結果:

# 'Jerry的成績最高,得了88分。'

TXT文件加載器

TXTLoader函數說明

class langchain_community.document_loaders.text.TextLoader(
    file_path: Union[str, Path], 
    encoding: Optional[str] = None, 
    autodetect_encoding: bool = False)

說明:

  • ??file_path??:指定要加載的文本文件的路徑。
  • ??encoding??(可選):指定文本文件的編碼格式,一般是"utf-8"

示例

from langchain_community.document_loaders import TextLoader

txt_loader = TextLoader(file_path="testfiles/測試文件.txt", encoding="utf8")

docs = txt_loader.load()
docs

運行結果:

[Document(metadata={'source': 'testfiles/測試文件.txt'}, page_cnotallow='大語言模型作為人工智能領域的重要技術之一,具有廣泛的應用場景。以下是十個方面的應用場景及其詳細描述:\n\n1. 機器翻譯\n描述:大語言模型通過訓練可以學習不同語言之間的語法和語義規則,實現自動翻譯。這種技術已廣泛應用于跨國企業溝通、國際合作等領域,如谷歌翻譯等產品。盡管在處理長句子和歧義消解等方面仍面臨挑戰,但隨著技術的發展,其準確性和流暢度不斷提升。\n\n2. 智能客服與聊天機器人\n描述:大語言模型被用于開發智能客服助手和聊天機器人,能夠理解用戶的問題并提供相應的解決方案或轉達給相關部門。這不僅提高了客服效率,還提升了用戶體驗。例如,通過自然語言處理技術,智能客服助手可以分析用戶情感狀態,及時發現問題并優化服務。\n\n3. 文本生成與創作\n描述:大語言模型能夠生成符合語法規則的文章、新聞、小說等文本內容。通過學習大量文本數據,模型可以生成具有創造性和相關性的內容,廣泛應用于新聞報道、廣告營銷等領域。此外,它還能根據給定主題或關鍵詞生成文章,為創作者提供靈感和輔助。\n\n4. 情感分析\n描述:大語言模型通過分析文本中的情感傾向和情感表達,幫助企業了解客戶反饋和情感狀態,從而制定更精準的營銷策略或優化客戶服務。這種技術還可用于社交媒體監控,實時分析公眾對某一主題或事件的情緒和反應。\n\n5. 自動問答系統\n描述:通過學習大量問題和答案,大語言模型能夠自動生成符合語法規則的問題和答案。這種自動問答系統可應用于智能助手、搜索引擎等領域,為用戶提供高效、準確的信息服務。結合知識圖譜技術,問答系統的知識檢索和推理能力得到進一步增強。\n\n6. 自動摘要與總結\n描述:大語言模型能夠自動對文本進行摘要和總結,提取關鍵信息,幫助用戶快速了解文本主旨和重點。這種技術在學術論文、新聞報道等領域具有重要應用價值,提高了信息獲取的效率。\n\n7. 代碼生成與自動化編程\n描述:大語言模型通過學習大量代碼數據,可以理解編程語言的語法和邏輯規則,實現代碼的自動生成。這有助于非技術用戶生成基本代碼,同時為專業編程人員提供輔助,加快開發進程。然而,在復雜任務中仍需人工審核和調整。\n\n8. 信息檢索與推薦系統\n描述:大語言模型可應用于改善搜索引擎結果和內容推薦算法。通過分析用戶查詢意圖和上下文信息,模型能夠提供更準確、個性化的搜索結果和內容推薦,提升用戶體驗和滿意度。\n\n9. 生物醫學研究\n描述:在生物醫學領域,大語言模型可用于分析基因組數據、蛋白質相互作用等,加速藥物發現和新療法的研究。例如,通過預測基因變異的功能影響,研究者能夠更全面地分析人類基因組的潛在風險和治療靶點。\n\n10. 語音識別與生成\n描述:大語言模型在語音識別和語音生成方面也展現出巨大潛力。通過將語音轉錄為文本或將文本轉化為語音,該技術使得人們與計算機的交互更加自然和便捷。這對于有聽力或視覺障礙的人群尤為重要,有助于他們更好地理解和享受音視頻內容。\n\n綜上所述,大語言模型在多個領域都具有廣泛的應用前景和巨大的價值潛力。隨著技術的不斷進步和完善,我們有理由相信大語言模型將在未來的人工智能領域發揮更加重要的作用。')]

PDF文件加載器

PyMuPDFLoader函數說明

class langchain_community.document_loaders.pdf.PyMuPDFLoader(
    file_path:str,*,
    headers:Optional[Dict]=None,
    extract_images:bool=False,
**kwargs:Any)

說明:

  • ??extract_images??:指示是否從 PDF 中提取圖像。如果設置為 True,將嘗試提取 PDF 中的所有圖像。
  • 使用前需要安裝相關依賴:??pip install PyMuPDF??

示例

from langchain_community.document_loaders import PyMuPDFLoader

pdf_loader = PyMuPDFLoader(file_path="testfiles/測試文件.pdf")

docs = pdf_loader.load()
docs

運行結果:

大模型之深入探索RAG流程-AI.x社區

# metadata數據詳情
metadata={'source':'testfiles/測試文件.pdf',
'file_path':'testfiles/測試文件.pdf',
'page':0,'total_pages':21,
'format':'PDF 1.6',
'title':'JSON 是什么?',
'author':'番茄花園',
'subject':'',
'keywords':'',
'creator':'WPS Office 個人版',
'producer':'PDFlib 7.0.3 (C++/Win32)',
'creationDate':"D:20090304181435+08'00'",
'modDate':"D:20100525102623+08'00'",'trapped':''
}

原始PDF文件如下:

大模型之深入探索RAG流程-AI.x社區

說明:通過對比可以看到

  • pagecontent與PDF文件內容一致。
  • metadata數據有比較多的字段,例如:format,title,author,subject,keywords,creator,producer,creationDate,modDate等。

EXCEL文件加載器

UnstructuredExcelLoader函數說明

class langchain_community.document_loaders.excel.UnstructuredExcelLoader(
    file_path: Union[str, Path], 
    mode: str = 'single', 
    **unstructured_kwargs: Any)

說明:

  • 使用前需要安裝相關依賴:??pip install unstructured??。

示例

from langchain_community.document_loaders import UnstructuredExcelLoader

excel_loader = UnstructuredExcelLoader(file_path="testfiles/測試文件.xlsx", encoding="utf8")

docs = excel_loader.load()
docs

運行結果:

大模型之深入探索RAG流程-AI.x社區

原始文件:

大模型之深入探索RAG流程-AI.x社區

PPT文件加載器

UnstructuredPowerPointLoader函數說明

class langchain_community.document_loaders.powerpoint.UnstructuredPowerPointLoader(
    file_path:Union[str,List[str],Path,List[Path]],*,
    mode:str='single',
**unstructured_kwargs:Any)

說明:

  • 使用前需要安裝相關依賴:??pip install python-pptx??。

示例

from langchain_community.document_loaders import UnstructuredPowerPointLoader

ppt_loader = UnstructuredPowerPointLoader(file_path="testfiles/測試文件.pptx", mode="single")

docs = ppt_loader.load()

docs[0].page_content

運行結果:

大模型之深入探索RAG流程-AI.x社區

原始文件:

大模型之深入探索RAG流程-AI.x社區

說明:

  • 通過對比,可以看到PPT中的文字會被提取出來,圖片會被清洗掉。

WORD文件加載器

UnstructuredWordDocumentLoader函數說明

class langchain_community.document_loaders.word_document.UnstructuredWordDocumentLoader(
    file_path:Union[str,List[str],Path,List[Path]],*,
    mode:str='single',
**unstructured_kwargs:Any)

說明:

  • 使用前需要安裝相關依賴:??pip install python-docx??。

示例

from langchain_community.document_loaders import UnstructuredWordDocumentLoader

word_loader = UnstructuredWordDocumentLoader(file_path="testfiles/測試文件.docx", mode="single")

docs = ppt_loader.load()
docs

運行結果:

大模型之深入探索RAG流程-AI.x社區

原始文件:

大模型之深入探索RAG流程-AI.x社區

MARKDOWN文件加載器

UnstructuredMarkdownLoader函數說明

class langchain_community.document_loaders.markdown.UnstructuredMarkdownLoader(
    file_path:Union[str,List[str],Path,List[Path]],*,
    mode:str='single',
**unstructured_kwargs:Any)
  • 使用前需要安裝相關依賴:??pip install markdown??。

示例

from langchain_community.document_loaders import UnstructuredMarkdownLoader

md_loader = UnstructuredMarkdownLoader(file_path="testfiles/測試文件.md", mode="single")

docs = md_loader.load()

docs

運行結果:

大模型之深入探索RAG流程-AI.x社區

原始文件:

大模型之深入探索RAG流程-AI.x社區

HTML文件加載器

UnstructuredHTMLLoader函數說明

class langchain_community.document_loaders.html.UnstructuredHTMLLoader(
    file_path:Union[str,List[str],Path,List[Path]],*,
    mode:str='single',
**unstructured_kwargs:Any)

說明:

  • model可以設置為'elements',表示將HTML元素作為文檔進行切分。

示例

from langchain_community.document_loaders import UnstructuredHTMLLoader

html_file = "testfiles/測試文件.htm"

html_loader = UnstructuredHTMLLoader(file_path=html_file, mode="single")

docs = html_loader.load()

docs[0].page_content

運行結果:

大模型之深入探索RAG流程-AI.x社區

原始文件:

大模型之深入探索RAG流程-AI.x社區

補充說明: 如果將上面的mode改為mode="elements",運行如下,但是得到內容對于建立知識庫沒有太大幫助。

大模型之深入探索RAG流程-AI.x社區

SQL文件加載器

SQLDatabaseLoader函數說明

class langchain_community.document_loaders.sql_database.SQLDatabaseLoader(
    query:Union[str,Select],
    db:SQLDatabase,*,
    parameters:Optional[Dict[str,Any]]=None,
    page_content_mapper:Optional[Callable[[...],str]]=None,
    metadata_mapper:Optional[Callable[[...],Dict[str,Any]]]=None,
    source_columns:Optional[Sequence[str]]=None,
    include_rownum_into_metadata:bool=False,
    include_query_into_metadata:bool=False)

說明:

  • ??query??:指定要執行的 SQL 查詢。

例如:query = "SELECT * FROM documents"

  • ??db??: 指定要連接的 SQL 數據庫實例。
  • ??parameters??(可選):可選參數,用于傳遞 SQL 查詢的參數,以便于動態查詢。

         例如:parameters = {"id": 1}

  • ??page_content_mapper??(可選):可選的映射函數,用于處理查詢結果中的每一行,返回格式化后的內容。
  • ??metadata_mapper??(可選):可選的映射函數,用于處理查詢結果中的每一行,返回元數據字典。

        例如:metadata_mapper=lambda row: {"id": row['id'], "created_at": row['created_at']}

  • ??source_columns??(可選):可選參數,指定要從查詢結果中提取的列名。
  • ??include_rownum_into_metadata??:指示是否將行號包含在元數據中。
  • ??include_query_into_metadata??:指示是否將執行的 SQL 查詢包含在元數據中。
  •  使用前需要安裝相關依賴:??pip install sqlalchemy??。

示例

from langchain_community.document_loaders importSQLDatabaseLoader
from langchain_community.utilities importSQLDatabase
from sqlalchemy import create_engine

# 創建 SQLite 數據庫引擎,指定數據庫文件的路徑
engine = create_engine(url="sqlite:///testfiles/students.db")

# 使用創建的引擎實例化 SQLDatabase 對象
db =SQLDatabase(engine=engine)

# 創建 SQLDatabaseLoader 實例,指定要執行的 SQL 查詢
sql_loader =SQLDatabaseLoader(query="SELECT * FROM stu_score;", db=db,
                               include_query_into_metadata=True,
                               include_rownum_into_metadata=True)

docs = sql_loader.load()
docs

運行結果:

大模型之深入探索RAG流程-AI.x社區

原始文件:

大模型之深入探索RAG流程-AI.x社區

以上只是對各類文件加載器的簡單梳理,在實際應用中需要進行進一步的封裝,例如:

  • 封裝為class方式
  • 以文件后綴名自動判斷調用的加載器
  • 添加更多回溯信息
  • ......

在開源項目QAnything(網易的一款開源RAG系統)中,該項目中的qanything_kernel有著比較詳細的封裝,可以參考。

文檔切分(SPLIT)

按照字符切分

CharacterTextSplitter類說明

class langchain_text_splitters.character.CharacterTextSplitter:
    def __init__(self, chunk_size: int, chunk_overlap: int = 0):

說明:

  • chunk_size:指定每個文本片段的最大字符長度。
  • chunk_overlap:指定相鄰文本片段之間的重疊字符數。重疊可以幫助保持上下文的一致性。

示例

from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importCharacterTextSplitter

text_loader =TextLoader(file_path="testfiles/測試文件.txt", encoding="utf8")

docs = text_loader.load()

# 字符級文本切分器
spliter =CharacterTextSplitter(separator ='\n\n', chunk_size=128, chunk_overlap=32)

results = spliter.split_documents(documents=docs)

# 打印切分結果
print(f'切分個數:{len(results)}')

for idx, chunk inenumerate(results):
print(f'第{idx+1}段,長度為:{len(chunk.page_content)}')
print(f'切分內容:\n{chunk.page_content}')
print("-*-"*30+"\n")

運行結果:

# chunk_size=128, chunk_overlap=32
切分個數:12
第1段,長度為:50
切分內容:
大語言模型作為人工智能領域的重要技術之一,具有廣泛的應用場景。以下是十個方面的應用場景及其詳細描述:
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,長度為:124
切分內容:
1.機器翻譯
描述:大語言模型通過訓練可以學習不同語言之間的語法和語義規則,實現自動翻譯。這種技術已廣泛應用于跨國企業溝通、國際合作等領域,如谷歌翻譯等產品。盡管在處理長句子和歧義消解等方面仍面臨挑戰,但隨著技術的發展,其準確性和流暢度不斷提升。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第3段,長度為:131
切分內容:
2.智能客服與聊天機器人
描述:大語言模型被用于開發智能客服助手和聊天機器人,能夠理解用戶的問題并提供相應的解決方案或轉達給相關部門。這不僅提高了客服效率,還提升了用戶體驗。例如,通過自然語言處理技術,智能客服助手可以分析用戶情感狀態,及時發現問題并優化服務。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第4段,長度為:125
切分內容:
3.文本生成與創作
描述:大語言模型能夠生成符合語法規則的文章、新聞、小說等文本內容。通過學習大量文本數據,模型可以生成具有創造性和相關性的內容,廣泛應用于新聞報道、廣告營銷等領域。此外,它還能根據給定主題或關鍵詞生成文章,為創作者提供靈感和輔助。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第5段,長度為:106
...
切分內容:
綜上所述,大語言模型在多個領域都具有廣泛的應用前景和巨大的價值潛力。隨著技術的不斷進步和完善,我們有理由相信大語言模型將在未來的人工智能領域發揮更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

# 如果改為chunk_size=512, chunk_overlap=32
切分個數:3
第1段,長度為:436
切分內容:
大語言模型作為人工智能領域的重要技術之一,具有廣泛的應用場景。以下是十個方面的應用場景及其詳細描述:

1.機器翻譯
描述:大語言模型通過訓練可以學習不同語言之間的語法和語義規則,實現自動翻譯。這種技術已廣泛應用于跨國企業溝通、國際合作等領域,如谷歌翻譯等產品。盡管在處理長句子和歧義消解等方面仍面臨挑戰,但隨著技術的發展,其準確性和流暢度不斷提升。

2.智能客服與聊天機器人
描述:大語言模型被用于開發智能客服助手和聊天機器人,能夠理解用戶的問題并提供相應的解決方案或轉達給相關部門。這不僅提高了客服效率,還提升了用戶體驗。例如,通過自然語言處理技術,智能客服助手可以分析用戶情感狀態,及時發現問題并優化服務。

3.文本生成與創作
描述:大語言模型能夠生成符合語法規則的文章、新聞、小說等文本內容。通過學習大量文本數據,模型可以生成具有創造性和相關性的內容,廣泛應用于新聞報道、廣告營銷等領域。此外,它還能根據給定主題或關鍵詞生成文章,為創作者提供靈感和輔助。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,長度為:443
切分內容:
4.情感分析
描述:大語言模型通過分析文本中的情感傾向和情感表達,幫助企業了解客戶反饋和情感狀態,從而制定更精準的營銷策略或優化客戶服務。這種技術還可用于社交媒體監控,實時分析公眾對某一主題或事件的情緒和反應。

5.自動問答系統
描述:通過學習大量問題和答案,大語言模型能夠自動生成符合語法規則的問題和答案。這種自動問答系統可應用于智能助手、搜索引擎等領域,為用戶提供高效、準確的信息服務。結合知識圖譜技術,問答系統的知識檢索和推理能力得到進一步增強。

6.自動摘要與總結
描述:大語言模型能夠自動對文本進行摘要和總結,提取關鍵信息,幫助用戶快速了解文本主旨和重點。這種技術在學術論文、新聞報道等領域具有重要應用價值,提高了信息獲取的效率。
...

綜上所述,大語言模型在多個領域都具有廣泛的應用前景和巨大的價值潛力。隨著技術的不斷進步和完善,我們有理由相信大語言模型將在未來的人工智能領域發揮更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

遞歸方式切分

RecursiveCharacterTextSplitter函數說明

class langchain_text_splitters.character.RecursiveCharacterTextSplitter(
    separators:Optional[List[str]]=None,
    keep_separator:bool=True,
    is_separator_regex:bool=False,
**kwargs:Any
)

說明:

  • separators:用于指定切分文本時使用的分隔符列表。可以包括換行符、句號、逗號等。
  • keep_separator:指定在切分后是否保留分隔符。如果設置為 True,切分后的文本片段將包含分隔符。
  • is_separator_regex:指定 separators 是否為正則表達式。如果設置為 True,則 separators 將被視為正則表達式。

示例

from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importRecursiveCharacterTextSplitter

text_loader =TextLoader(file_path="testfiles/測試文件.txt", encoding="utf8")

docs = text_loader.load()

separators=["\n",".","。","!","!","?","?",";",";","……","…","、",",",","," "]


# 創建 RecursiveCharacterTextSplitter 實例
splitter =RecursiveCharacterTextSplitter(
    separators=separators,
    keep_separator=True,
    is_separator_regex=False,
    chunk_size=128,
    chunk_overlap=32
)

results = splitter.split_documents(documents=docs)

# 打印切分結果
print(f'切分個數:{len(results)}')

for idx, chunk inenumerate(results):
print(f'第{idx+1}段,長度為:{len(chunk.page_content)}')
print(f'切分內容:\n{chunk.page_content}')
print("-*-"*30+"\n")

運行結果:

切分個數:13
第1段,長度為:59
切分內容:
大語言模型作為人工智能領域的重要技術之一,具有廣泛的應用場景。以下是十個方面的應用場景及其詳細描述:

1.機器翻譯
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,長度為:124
切分內容:
1.機器翻譯
描述:大語言模型通過訓練可以學習不同語言之間的語法和語義規則,實現自動翻譯。這種技術已廣泛應用于跨國企業溝通、國際合作等領域,如谷歌翻譯等產品。盡管在處理長句子和歧義消解等方面仍面臨挑戰,但隨著技術的發展,其準確性和流暢度不斷提升。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第3段,長度為:13
切分內容:
2.智能客服與聊天機器人
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第4段,長度為:117
切分內容:
描述:大語言模型被用于開發智能客服助手和聊天機器人,能夠理解用戶的問題并提供相應的解決方案或轉達給相關部門。這不僅提高了客服效率,還提升了用戶體驗。例如,通過自然語言處理技術,智能客服助手可以分析用戶情感狀態,及時發現問題并優化服務。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第5段,長度為:125
...
切分內容:
綜上所述,大語言模型在多個領域都具有廣泛的應用前景和巨大的價值潛力。隨著技術的不斷進步和完善,我們有理由相信大語言模型將在未來的人工智能領域發揮更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

對比CharacterTextSplitter的執行結果,RecursiveCharacterTextSplitter在切分長文本時,可以切分出更小的文本片段,并且可以保留分隔符。

按照Token切分

TokenTextSplitter函數說明

class langchain_text_splitters.base.TokenTextSplitter(
    encoding_name:str='gpt2',
    model_name:Optional[str]=None,
    allowed_special:Union[Literal['all'],AbstractSet[str]]={},
    disallowed_special:Union[Literal['all'],Collection[str]]='all',
**kwargs:Any
)

說明:

  • model_name(可選):可選參數,用于指定特定的語言模型名稱。
  • allowed_special:指定被允許的特殊令牌集合。
  • disallowed_special:指定不允許的特殊令牌集合。
  • 使用前需要安裝依賴:??pip install tiktoken??。
  • encoding_name:指定用于令牌化文本的編碼名稱。該選項通過以下代碼可以得到常見選項:

import tiktoken
tiktoken.list_encoding_names()

# 運行結果:
# ['gpt2', 'r50k_base', 'p50k_base', 'p50k_edit', 'cl100k_base', 'o200k_base']
  • ??gpt2???:這是 OpenAI 的??GPT-2??? 模型使用的編碼,基于??Byte Pair Encoding (BPE)??。它適用于大多數基于 GPT-2 的任務,能夠有效處理英語文本
  • ??r50k_base???:這是針對??OpenAI??? 的模型(如??GPT-3???)的一種編碼,使用了??50,000?? 個最常見的子詞單位。它是一種更為精簡的編碼方式,適用于對文本進行更細粒度的切分。
  • ??p50k_base???:基于??BPE??? 的編碼,使用??50,000??? 個子詞單位。該編碼主要用于處理更復雜的文本生成和理解任務,適合與??GPT-3?? 及相關模型的配合使用。
  • ??p50k_edit???:這是??p50k_base?? 的一種變體,專門優化用于文本編輯任務。這種編碼關注于文本的修改和調整,適合需要對文本進行細微編輯的應用場景。
  • ??cl100k_base???:這是針對更大規模模型(如??GPT-4???)的一種編碼,使用了??100,000?? 個子詞單位。它能夠處理更復雜和多樣化的文本,適合高性能的文本生成和理解任務。
  • ??o200k_base???:這是一個更高級的編碼,使用了??200,000?? 個子詞單位,旨在處理極為復雜的文本任務。它適合需要處理大量信息或多樣化文本的應用,能夠提供更高的靈活性和精度。

以上選項內容由ChatGPT輔助生成,如有錯誤,請及時反饋。

示例

import tiktoken
from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importTokenTextSplitter

text_loader =TextLoader(file_path="testfiles/測試文件.txt", encoding="utf8")

docs = text_loader.load()

splitter =TokenTextSplitter(encoding_name="o200k_base",
                     chunk_size=128,
                     chunk_overlap=64)

results = splitter.split_documents(documents=docs)


# 打印切分結果
print(f'切分個數:{len(results)}')

for idx, chunk inenumerate(results):
print(f'第{idx+1}段,長度為:{len(chunk.page_content)}')
print(f'切分內容:\n{chunk.page_content}')
print("-*-"*30+"\n")

運行結果:

切分個數:13
第1段,長度為:185
切分內容:
大語言模型作為人工智能領域的重要技術之一,具有廣泛的應用場景。以下是十個方面的應用場景及其詳細描述:

1.機器翻譯
描述:大語言模型通過訓練可以學習不同語言之間的語法和語義規則,實現自動翻譯。這種技術已廣泛應用于跨國企業溝通、國際合作等領域,如谷歌翻譯等產品。盡管在處理長句子和歧義消解等方面仍面臨挑戰,但隨著技術的發展,其準確性和流暢度不斷提升。

2.智能客服
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,長度為:198
切分內容:
種技術已廣泛應用于跨國企業溝通、國際合作等領域,如谷歌翻譯等產品。盡管在處理長句子和歧義消解等方面仍面臨挑戰,但隨著技術的發展,其準確性和流暢度不斷提升。

2.智能客服與聊天機器人
描述:大語言模型被用于開發智能客服助手和聊天機器人,能夠理解用戶的問題并提供相應的解決方案或轉達給相關部門。這不僅提高了客服效率,還提升了用戶體驗。例如,通過自然語言處理技術,智能客服助手可以分析用戶情感狀態,
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第3段,長度為:215
切分內容:
與聊天機器人
描述:大語言模型被用于開發智能客服助手和聊天機器人,能夠理解用戶的問題并提供相應的解決方案或轉達給相關部門。這不僅提高了客服效率,還提升了用戶體驗。例如,通過自然語言處理技術,智能客服助手可以分析用戶情感狀態,及時發現問題并優化服務。

3.文本生成與創作
...

綜上所述,大語言模型在多個領域都具有廣泛的應用前景和巨大的價值潛力。隨著技術的不斷進步和完善,我們有理由相信大語言模型將在未來的人工智能領域發揮更加重要的作用。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

如果將encoding_name設置為'gpt2',則切分結果如下:

切分個數:43
第1段,長度為:65
切分內容:
大語言模型作為人工智能領域的重要技術之一,具有廣泛的應用場景。以下是十個方面的應用場景及其詳細描述:

1.機器翻譯
描述:大?
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,長度為:62
切分內容:
?下是十個方面的應用場景及其詳細描述:

1.機器翻譯
描述:大語言模型通過訓練可以學習不同語言之間的語法和語義規則,實現
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第3段,長度為:58
切分內容:
?言模型通過訓練可以學習不同語言之間的語法和語義規則,實現自動翻譯。這種技術已廣泛應用于跨國企業溝通、國際合作等領?
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

通過對比,可以看到o200k_base的效果要優于gpt2。

按照markdown標題切分

示例

from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importMarkdownTextSplitter

text_loader =TextLoader(file_path="testfiles/測試文件.md", encoding="utf8")

docs = text_loader.load()

# 創建 MarkdownTextSplitter 實例
splitter =MarkdownTextSplitter(chunk_size=128, chunk_overlap=64)

results = splitter.split_documents(documents=docs)

# 打印切分結果
print(f'切分個數:{len(results)}')

for idx, chunk inenumerate(results):
print(f'第{idx+1}段,長度為:{len(chunk.page_content)}')
print(f'切分內容:\n{chunk.page_content}')
print("-*-"*30+"\n")

運行結果:

切分個數:196
第1段,長度為:126
切分內容:
## 前言
本章我們將通過LLaMA-Factory具體實踐大模型訓練的三個階段,包括:預訓練、監督微調和偏好糾正。

## 大模型訓練回顧
![](大模型訓練的三個階段.png)

## 訓練目標
通過實踐大模型的三個訓練階段,訓練一個醫療大模型
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第2段,長度為:123
切分內容:
## 訓練過程實施
### 準備訓練框架
`LLaMA Factory`是一款開源低代碼大模型微調框架,集成了業界最廣泛使用的微調技術,支持通過Web UI界面零代碼微調大模型,目前已經成為開源社區內最受歡迎的微調框架,GitHub星標超過2萬。
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

第3段,長度為:118
切分內容:
#### 運行環境要求
-硬件:
  - GPU:推薦使用24GB顯存的顯卡或者更高配置
...
## 參考資料
[Github:LLaMA-Factory的README文件](https://github.com/hiyouga/LLaMA-Factory/blob/main/data/README.md)
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

對于Markdown文本,使用MarkdownTextSplitter進行切分,切分效果比較好。

向量化(EMBED)

考慮到RAG系統一般都有私有化部署的需求(因為數據涉密),所以對應的向量化的方式有兩種:本地化 和 在線化。

本地化

在開源項目QAnything中,其提供了一種使用本地模型的方法,其大致步驟是:

  • 在本地保存了一個向量化模型。
  • 在調用向量化模型時,使用本地的模型.

embedding_client = EmbeddingClient(
    server_url=LOCAL_EMBED_SERVICE_URL,
    model_name=LOCAL_EMBED_MODEL_NAME,
    model_versinotallow='1',
    resp_wait_s=120,
    tokenizer_path='qanything_kernel/connector/embedding/embedding_model_0630')

由于示例代碼的集成度較高,剝離核心代碼執行成本較大,所以此處并未實踐,只是引用相關的信息。

在線化

使用HuggingFaceEmbeddings

LangChain社區提供了HuggingFaceEmbeddings,該類可以加載HuggingFace的預訓練模型,并使用該模型進行向量化。

from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importRecursiveCharacterTextSplitter
from langchain_chroma importChroma
from langchain.embeddings importHuggingFaceEmbeddings

# 加載文本
text_loader =TextLoader(file_path="testfiles/測試文件.txt", encoding="utf8")
docs = text_loader.load()

# 切分文本
spliter =RecursiveCharacterTextSplitter(chunk_size=128, chunk_overlap=64)
docs = spliter.split_documents(documents=docs)

# 初始化 HuggingFaceEmbeddings
embedding_function =HuggingFaceEmbeddings(model_name="bert-base-chinese")

# 創建向量數據庫
store =Chroma(embedding_functinotallow=embedding_function, persist_directory="chroma_data")

# 將文檔添加到數據庫中
store.add_documents(documents=docs)

# 進行相似性搜索
store.similarity_search(query="小米估值多少?", k=2)

說明:

  • 使用前需要安裝依賴??pip install sentence-transformers??

運行結果:

[Document(metadata={'source': 'testfiles/測試文件.txt'}, page_cnotallow='1. 機器翻譯\n描述:大語言模型通過訓練可以學習不同語言之間的語法和語義規則,實現自動翻譯。這種技術已廣泛應用于跨國企業溝通、國際合作等領域,如谷歌翻譯等產品。盡管在處理長句子和歧義消解等方面仍面臨挑戰,但隨著技術的發展,其準確性和流暢度不斷提升。'),
 Document(metadata={'source': 'testfiles/測試文件.txt'}, page_cnotallow='1. 機器翻譯\n描述:大語言模型通過訓練可以學習不同語言之間的語法和語義規則,實現自動翻譯。這種技術已廣泛應用于跨國企業溝通、國際合作等領域,如谷歌翻譯等產品。盡管在處理長句子和歧義消解等方面仍面臨挑戰,但隨著技術的發展,其準確性和流暢度不斷提升。')]

使用QianfanEmbeddings

由于Qwen的API有樣本為6個的限制,所以此處試用百度千帆大模型的向量化API。

# util.py
defget_ernie_models():
"""
    加載文心系列大模型
    """
# LLM 大語言模型(單輪對話版)
from langchain_community.llms importQianfanLLMEndpoint

# Chat 聊天版大模型(支持多輪對話)
from langchain_community.chat_models importQianfanChatEndpoint

# Embeddings 嵌入模型
from langchain_community.embeddings importQianfanEmbeddingsEndpoint

    llm =QianfanLLMEndpoint(model="ERNIE-Bot-turbo", temperature=0.1, top_p=0.2)
    chat =QianfanChatEndpoint(model="ERNIE-Lite-8K", top_p=0.2, temperature=0.1)

    embed =QianfanEmbeddingsEndpoint(model="bge-large-zh")

return llm, chat, embed

from langchain_community.document_loaders importTextLoader
from langchain_text_splitters importRecursiveCharacterTextSplitter
from langchain_chroma importChroma
from utils import get_ernie_models

# 連接大模型
llm_ernie, chat_ernie, embed_ernie = get_ernie_models()

# 加載文本
text_loader =TextLoader(file_path="testfiles/測試文件.txt", encoding="utf8")
docs = text_loader.load()

# 切分文本
spliter =RecursiveCharacterTextSplitter(chunk_size=128, chunk_overlap=64)
docs = spliter.split_documents(documents=docs)

# 使用 ernie 模型創建向量數據庫
store =Chroma.from_documents(documents=docs,
                              embedding=embed_ernie,
                              persist_directory="chroma_data2")


store.similarity_search(query="小米估值多少?", k=2)

運行結果:

[Document(metadata={'source': 'testfiles/測試文件.txt'}, page_cnotallow='2. 智能客服與聊天機器人'),
 Document(metadata={'source': 'testfiles/測試文件.txt'}, page_cnotallow='大語言模型作為人工智能領域的重要技術之一,具有廣泛的應用場景。以下是十個方面的應用場景及其詳細描述:')]

通過對比

  • 使用QianfanEmbeddingsEndpoint向量化后,在相似性搜索時有兩個內容返回;而使用HuggingFaceEmbeddings向量化后,在相似性搜索時只有第一個內容返回。
  • 相似性搜索后的內容,看起來與我們Query查詢的問題似乎不太相關,只是模型在向量層面計算是比較相似。

原理探尋

import numpy as np
from utils import get_ernie_models

llm_ernie, chat_ernie, embed_ernie = get_ernie_models()

query = np.array(embed_ernie.embed_query(text="小米估值多少?"))
doc1 = np.array(embed_ernie.embed_query(text="2. 智能客服與聊天機器人"))
doc2 = np.array(embed_ernie.embed_query(text="大語言模型作為人工智能領域的重要技術之一,具有廣泛的應用場景。以下是十個方面的應用場景及其詳細描述:"))


# 歐式距離
result1 =((query - doc1)**2).sum()
print(f'query 和 doc1 的歐式距離為:{result1}')

result2 =((query - doc2)**2).sum()
print(f'query 和 doc2 的歐式距離為:{result2}')

# 相關系數
corr1  =1- result1 /2**0.5
print(f'query 和 doc1 的相關系數為:{corr1}')

corr2 =1- result2 /2**0.5
print(f'query 和 doc2 的相關系數為:{corr2}')

運行結果:

# query 和 doc1 的歐式距離為:0.6204636182956037
# query 和 doc2 的歐式距離為:0.8112505547683875
# query 和 doc1 的相關系數為:0.561265968023637
# query 和 doc2 的相關系數為:0.42635923148192456

對比如下代碼執行結果:

# 相關性轉換
store.similarity_search_with_relevance_scores(query="小米估值多少?", k=2)

運行結果:

[(Document(metadata={'source': 'testfiles/測試文件.txt'}, page_cnotallow='2. 智能客服與聊天機器人'),
  0.5612658250623314),
 (Document(metadata={'source': 'testfiles/測試文件.txt'}, page_cnotallow='大語言模型作為人工智能領域的重要技術之一,具有廣泛的應用場景。以下是十個方面的應用場景及其詳細描述:'),
  0.4263594055624078)]

由上可以看到:

  • 相似度計算:通過計算兩個向量的歐式距離,可以得到兩個向量之間的相似度,計算結果越小代表越接近。
  • 相似度轉換:通過計算兩個向量的相關系數,可以得到兩個向量之間的相似度,計算結果越大代表越相似。
  • 歐式距離計算方法:$d(\mathbf{a}, \mathbf{b}) = \sqrt{\sum_{i=1}^{n} (a_i - b_i)^2}$
  • 相關系數計算方法:$r = 1 - \frac{d(\mathbf{query}, \mathbf{doc})}{\sqrt{2}}$
  • ??similarity_search?? 即為相似度計算。
  • ??similarity_search_with_relevance_scores??? 即為相似度轉換,它是??smimilarity_search?? 的擴展,可以返回相似度。

存儲(STORE)

如上述示例,我們對數據進行向量化之后,下一步需要存儲至向量數據庫。目前市面上的向量數據庫眾多,主流的向量數據庫對比如下所示:

向量數據庫

URL

GitHub Star

Language

Cloud

chroma

chroma

7.4K

Python

?

milvus

milvus

21.5K

Go/Python/C++

?

pinecone

pinecone

?

?

?

qdrant

qdrant

11.8K

Rust

?

typesense

typesense

12.9K

C++

?

weaviate

weaviate

6.9K

Go

?

本例中,我們主要了解Chroma的使用。

Chroma簡介

介紹:Chroma 是一個開源的向量數據庫,專為處理和存儲高維向量而設計,特別適用于機器學習和深度學習應用。

特性:

  • 高效的向量存儲:Chroma 提供高效的向量存儲和檢索功能,能夠處理大規模數據集。
  • 相似性搜索:支持快速的相似性搜索,允許用戶根據查詢向量找到最相似的向量。
  • 靈活的Embedding支持:可以與多種Embedding模型集成。
  • 持久化存儲:支持將數據持久化存儲,確保在重啟后數據不會丟失。
  • 開源和社區支持:Chroma 是開源項目,用戶可以自由使用和修改,同時也享受社區的支持和貢獻。

資料:

  • 官網主頁:https://www.trychroma.com/
  • 官網文檔:https://docs.trychroma.com/
  • Github主頁:https://github.com/chroma-core/
  • Github項目:https://github.com/chroma-core/chroma/

大模型之深入探索RAG流程-AI.x社區

Chroma使用的幾種方式

初次了解Chroma的使用時,我被五花八門的API搞得云里霧里,一會是Chromadb,一會是langchain_chroma..... 因此,查詢了部分資料之后,總結Chroma的使用方式大致是以下三種方式:

大模型之深入探索RAG流程-AI.x社區

  • 第一種方式:是使用Chromadb的源生API接口使用,包括常見的增刪改查接口:??create_collection()???、??collection.add()???、??collection.query()??...
  • 第二種方式:是通過Langchain的組合包使用Chroma,常見的是:??Chroma.from_documents()???、??similarity_search()???、??similarity_search_by_vector()??...
  • 第三種方式:是通過Retriever檢索器的方式使用Chroma。

通過Chromadb的源生接口使用Chroma

Chroma 可以以多種形式進行使用:

  • 第一種:in-memory with ephemeral。短暫模式,數據保存在內存中,程序一旦結束數據就被銷毀。
  • 第二種:in-memory with persistance。持久化模式,數據保存在sqlite數據庫中,程序結束數據仍然存在。
  • 第三種:client/server模式。

本次實踐中,主要嘗試 ??持久化模式??? 和 ??Client/Server模式??。

持久化模式

第一步:安裝chroma庫

pip install chromadb -i https://pypi.tuna.tsinghua.edu.cn/simple

第二步:創建Chromadb實例

import chromadb
from chromadb import Settings

chroma_client = chromadb.PersistentClient(path="chroma_db")

第三步:創建或獲取被查詢集合

# 方式一:創建一個新的集合
# collection = chroma_client.create_collection(name="my_collection")

# 方式二:對于已存在的集合,可以直接通過名稱獲取,如果集合不存在會報錯。
# collection = chroma_client.get_collection(name="my_collection")

# 方式三:如果給定名稱的集合已經存在則直接獲取,否則創建。
collection = chroma_client.get_or_create_collection(name="my_collection")

第四步:添加數據到集合中

collection.add(
    ids=["id1","id2","id3","id4","id5"],
    documents=["浙江的省會是杭州","河北的省會是石家莊","山東的省會是濟南","杭州是個美麗的城市","杭州位于浙江省"],
    metadatas=[{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"}],
)

第五步:查詢集合中的數據

results = collection.query(
    query_texts=["西湖在哪個省?"],
    n_results=2,
)

說明:

  • query_texts: 查詢的文本
  • n_results: 查詢結果的數量

運行結果:

{'ids':[['id5','id1']],
'distances':[[0.669669112082433,0.6793151914879495]],
'metadatas':[[{'source':'myDoc'},{'source':'myDoc'}]],
'embeddings':None,
'documents':[['杭州位于浙江省','浙江的省會是杭州']],
'uris':None,
'data':None,
'included':['metadatas','documents','distances']}

Client/Server模式

第一步:啟動Chroma服務端

chroma run --path my_chroma

說明:

  • --path:指定Chroma服務端存儲數據的路徑。
  • --host:可以指定Chroma服務端監聽的IP地址,默認localhost
  • --port:可以指定Chroma服務端監聽的端口號,默認8000

大模型之深入探索RAG流程-AI.x社區

第二步:創建Chromadb實例

import chromadb
from chromadb import Client
from chromadb import Settings

# 配置連接信息
setting = Settings(chroma_server_host="localhost", 
                  chroma_server_http_port=8000)

chroma_client = Client(settings=setting)

第三步:創建或獲取被查詢集合

collection = chroma_client.get_or_create_collection(name="my_collection")

第四步:添加數據到集合中

collection.add(
    ids=["id1","id2","id3","id4","id5"],
    documents=["浙江的省會是杭州","河北的省會是石家莊","山東的省會是濟南","杭州是個美麗的城市","杭州位于浙江省"],
    metadatas=[{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"},{"source":"myDoc"}],
)

第五步:查詢集合中的數據

results = collection.query(
    query_texts=["西湖在哪個省?"],
    n_results=2,
)
results

運行結果:

{'ids':[['id5','id1']],
'distances':[[0.6696690917015076,0.6793153882026672]],
'metadatas':[[{'source':'myDoc'},{'source':'myDoc'}]],
'embeddings':None,
'documents':[['杭州位于浙江省','浙江的省會是杭州']],
'uris':None,
'data':None,
'included':['metadatas','documents','distances']}

對比 本地持久化 和 Client/Server模式,兩者的使用過程基本一致,只是在Client實例化時略有不同。

  • 本地持久化模型:??chroma_client = chromadb.PersistentClient(path="chroma_db")??
  • Client/Server模式:首先配置??Settings??? 連接信息,然后調用??chroma_client = Client(settings=setting)??

查看chromadb的源碼,可以看到其內部實現了DB常見的各類增刪改查操作:

大模型之深入探索RAG流程-AI.x社區

備注:實際項目產品開發中,知識庫需要通過上述的chromadb實現知識庫的管理(增刪改查)。

通過Langchain的組合包使用Chroma

除了上述??chromadb???的方式,也可以使用??Langchain_chroma??的方式使用Chroma,兩者的使用場景區別是:

chromadb

  • 自定義應用:當開發者需要構建特定的應用,且對數據庫的操作有較高的靈活性需求時,可以使用??chromadb??。
  • 數據分析:需要對存儲的數據進行復雜查詢和分析時,使用底層接口可以更好地滿足需求。
  • 高性能需求:在需要優化性能的情況下,開發者可以通過底層接口進行更細致的調整。

langchain_chroma

  • 快速原型開發:當開發者希望快速構建原型或 MVP(最小可行產品)時,??langchain_chroma ??提供了便捷的接口。
  • NLP檢索:提供更高層次的抽象,適用于檢索類任務,如文檔檢索、語義搜索等。

具體使用方法:

from langchain.text_splitter importCharacterTextSplitter
from langchain_chroma importChroma
from langchain.document_loaders importPyMuPDFLoader
from chromadb importSettings
from utils import get_ernie_models
from utils import get_qwen_models

# 連接大模型
llm_qwen, chat_qwen, embed_qwen = get_qwen_models()
llm_ernie, chat_ernie, embed_ernie = get_ernie_models()

# 加載文檔
pdf_loader =PyMuPDFLoader("testfiles/西游記.pdf")
documents = pdf_loader.load()

# 切分文檔
text_splitter =CharacterTextSplitter(chunk_size=100, chunk_overlap=32)
docs = text_splitter.split_documents(documents)


# 配置連接信息

client = chromadb.HttpClient(host='localhost', port=8000)

chroma_db =Chroma(
    embedding_functinotallow=embed_qwen,
    client=client
)

batch_size =6# 每次處理的樣本數量

# 分批入庫
for i inrange(0,len(docs), batch_size):
    batch = docs[i:i + batch_size]# 獲取當前批次的樣本
    chroma_db.add_documents(documents=batch)# 入庫

# 查詢
query ="白骨精被打死幾次?"
docs = chroma_db.similarity_search(query, k=3)

print(len(docs))

# 打印結果
for doc in docs:
print("="*100)
print(doc.page_content)

運行結果:

大模型之深入探索RAG流程-AI.x社區

說明:

  • 在langchain_chroma中,通過client_settings參數,可以l連接Chroma服務端。
  • 在Chroma中,通過add_documents方法,可以批量入庫;不過對于西游記這樣的小說來說,入庫時間比較長,約5分鐘。

西游記可以從夸克網盤:西游記下載

通過Retriever檢索器的方式使用Chroma

在實際項目開發中,一般需要將Chroma的向量庫作為檢索器(Retriever)與模型組成chain鏈,以實現問答系統的問答能力。

使用方法

在上述Langchain_chroma的代碼基礎上,增加以下代碼:

retriever = chroma_db.as_retriever(search_type="similarity_score_threshold",
                              search_kwargs={"k": 4, "score_threshold": 0.1})

retriever.invoke(input="白骨精被打死幾次?")

運行結果:

大模型之深入探索RAG流程-AI.x社區

函數說明:

1、as_retriever: 功能:as_retriever 方法將 Chroma 數據庫轉換為一個檢索器(retriever),使其能夠根據給定的查詢進行文檔檢索。這個檢索器可以使用不同的搜索類型和參數來優化檢索結果。

參數

  • ??search_type??: 指定檢索的類型。常見的選項包括:
  • ??"similarity_score_threshold"??:根據相似度分數進行檢索,只有超過指定閾值的結果才會被返回。
  • ??search_kwargs??: 包含與搜索相關的額外參數。常用參數包括:
  • ??k??: 指定要返回的最相關文檔的數量。例如,k=4 表示返回前 4 個相關文檔。
  • ??score_threshold??:設置相似度分數的閾值。只有相似度分數高于該閾值的文檔才會被返回。例如,score_threshold=0.1 表示返回分數大于 0.1 的文檔。

2、invoke: 功能:invoke 方法用于執行實際的檢索操作,根據提供的輸入查詢返回相關的文檔。 參數

  • ??input??:要查詢的輸入文本。

內容小結

  • RAG的建庫的整體流程為:文檔讀取(LOAD) -> 文檔切分(SPLIT) -> 向量化(EMBED) -> 存儲(STORE)
  • 在文檔讀取(LOAD)時:

     langchain_community.document_loaders有多個加載器,可以加載多種格式的文件,如PDF、EXCEL、PPT、WORD、MARKDOWN、HTML等。

  • 在文檔切分(SPLIT)時:

     字符級切分、遞歸方式切分、Token方式切分等,一般情況可以使用遞歸RecursiveCharacterTextSplitter切分。

     使用TokenTextSplitter切分時,注意選擇對應的encoding_name,如:'o200k_base'。

     對于Markdown文檔,可以使用MarkdownTextSplitter。

  • 在向量化(EMBED)時:

       有在線化和本地化,對于數據敏感有本地化部署的情況下,需要考慮使用本地模型進行向量化的方案。

       在線的向量化有HuggingFaceEmbeddings和第三方模型(如:QianfanEmbeddings)

       在技術原理層面,計算??知識???與??查詢??相似度一般使用的是歐式距離。

  • 在存儲(STORE)時:

       可供選擇的向量數據庫有多種,其中較為常用的是Chroma。

       Chroma支持多種運行方式:短暫模式、持久化模式和Client/Server模式。

       使用chromadb的原生接口,可以進行增刪改查等操作,適用于知識的管理。

       使用langchain_chroma,可以快速原型開發,適用于檢索類任務。

       使用retriever,可以將Chroma的向量庫作為檢索器(Retriever),與模型組成chain鏈,實現問答系統的問答能力。


本文轉載自公眾號一起AI技術 作者:熱情的Dongming

原文鏈接:??https://mp.weixin.qq.com/s/by7Uq9smzuf3Vo-e4TC7HQ??

?著作權歸作者所有,如需轉載,請注明出處,否則將追究法律責任
已于2024-12-19 09:35:16修改
收藏
回復
舉報
回復
相關推薦
主站蜘蛛池模板: 亚洲一二三区精品 | 狼色网| 成人国产精品视频 | 日韩在线不卡视频 | 亚洲伊人精品酒店 | 玖玖精品视频 | 国产九九九九 | 久久伦理电影 | 国产精品视频www | 精品一二 | 777zyz色资源站在线观看 | 欧产日产国产精品国产 | 日本激情一区二区 | 91在线播 | 一区二区在线 | 嫩草视频在线免费观看 | 日韩中文字幕一区二区 | 久久国产精品一区 | 国产精品一区二区av | 亚洲一区二区久久 | 亚洲成人一区二区三区 | 精品视频久久久久久 | 亚洲电影中文字幕 | 国产一区二区在线免费 | 欧美精品一二三 | 中文字幕不卡在线观看 | 91超碰在线 | 婷婷国产一区 | 亚洲精品中文字幕在线观看 | 国产乱码久久久久久 | 欧美专区日韩专区 | 国产精品日韩一区二区 | 91影院| www.夜夜骑 | 久久99久久 | 高清国产午夜精品久久久久久 | 免费国产视频在线观看 | 成年人黄色免费视频 | 精品无码久久久久国产 | 精品一区二区av | 四虎成人免费视频 |