那些檢索增強生成 (Retrieval-Augmented Generation, RAG) 要踩的坑

不要再嘴什麼AI 2.0 甚至 3.0 或者 Gen AI 了 ... 先跑起來,才叫有心認真要做 AI 啊
GraphRAG 殺雞焉用牛刀且雲端LLM的token數很可怕,你變不了現;BUT 地端你有 GPU?

https://github.com/Deep-Learning-101 | https://huggingface.co/DeepLearning101

在踩了深度學習 (包含圖像識別、自然語言處理、語音處理等) 及現在最夯的大型語言模型 (Large Language Model, LLM) 一些會踩的坑後,應該都稍微有匯整到跟放到 HF Space 了?特別是現在很多人或公司跟單位都會先嘴自己有在做GenAI或者是大模型,怎麼判斷呢?先問問對方有幾張什麼類型的GPU吧 !!!

 那些大型語言模型要踩的坑 | 什麼是大語言模型,它是什麼?想要嗎? 
大型語言模型之 Cryptocurrency Exchange FAQ
多模態大型語言模型之單據核銷
大型語言模型之 High Entropy Alloys  FAQ

為啥這篇會想來分享一下跟在大量資料上訓練的 LLM,其最大差異就是能專注聚焦局部搜尋在我們私有資料上 的檢索增強生成 (Retrieval-Augmented Generation, RAG) ?畢竟再怎樣我不少論文勉強都算是做 Ontolgy 的啊,還因此在流浪到英國時特地去了趟 Ontology大本營,OWL.Manchester 啊 ! 不過,先簡單講一下本地端怎樣做RAG ?

想在自己本地端跑大模型,要先佈署安裝一下 Ollama,這裡有一些安裝及參數設定,目前我自己是用這幾個 (請視自己的GPU來決定,千萬不要想說用個幾張消費型的GPU,就想跟人家嘴砲說有做大模型或者是??);Ollama 安裝跟執行操作是真的不難,而且也能跑 embedding,不過 xinference 會更方便就是。
準備好相關模型跟佈署後,那就是要準備文檔的製作了,這裡就請不要無腦的塞入文檔讓它自動切割,特別是直接 pdf 或者 ppt,至少要像下面這樣,略為自己瞭解整理一下 !
基本上自動分段已經可以做到不錯,而且還可以做到有關鍵詞 (其實就是拉了關係出來)
一般來說,很常碰到是直接一堆 pdf 檔要做 embedding,這時候就會碰上無法順利辨識的問題,這邊附上一個不錯的套件,https://github.com/opendatalab/MinerU 
MinerU is a one-stop, open-source, high-quality data extraction tool, supports PDF/webpage/e-book extraction. (一款一站式、開源、高品質的資料擷取工具,支援PDF/網頁/電子書擷取。)
跑完後可以把 pdf 轉成 markdown,且內容只要再稍稍調整即可 !
另外也又找到一個也是數據處理的開源工具:https://github.com/adithya-s-k/omniparse
Ingest, parse, and optimize any data format ➡️ from documents to multimedia ➡️ for enhanced compatibility with GenAI frameworks
操作安裝也都很簡單,可以用 gradio ui 也可以直接用 curl
curl -X POST -F "file=@/path/to/document" http://localhost:8000/parse_document
另外也還有這個:Python處理PDF神器:PyMuPDF的安裝與使用 以及 PaddleOCR 跟 RapidOCR,用來處理如果是掃描檔的PDF
所以,除了上述圖的 chunk 要先好好做的範例以外 (目前有很多蠻勵害的 jina 等的開源套件),再來則是 embedding 了
在兩階段檢索系統中,主要分成兩個步驟:第一步驟是用嵌入模型(Embedding Model)快速篩選出一組可能相關的文件;第二步驟則是用重新排序器(Reranker)來更精確地排序這些文件。雖然嵌入模型已經能夠提供初步的篩選結果,但它在面對複雜的查詢時,無法完全抓住查詢和文件之間的細微差異,因為它只能給出一個較為籠統的結果。相比之下,重新排序器能更好地分析每個文件的內容,提供更準確的排序結果。簡單來說,嵌入模型幫助你先找到可能有用的文件,而重新排序器則確保你找到的文件是最符合你需求的。嵌入模型適合快速從海量資料中找出一批相關性較高的候選文件,而重新排序器則負責進一步精挑細選,將這些候選文件按相關性進行排序。這樣的搭配既保證了檢索速度,也提高了結果的精確度。

  • 向量檢索:透過生成查詢嵌入並查詢與其向量表示最相似的文字分段 
  • 全文檢索:索引文件中的所有詞彙,從而允許使用者查詢任意詞彙,並返回包含這些詞彙的文字片段
    • TopK:這是用來找到與使用者輸入的問題相似度最高的文字片段。
    • Score 閾值:這是設定文字片段的相似度閾值,也就是只召回超過設定分數的文字片段。
  • 混合檢索:同時全文檢索和向量檢索,並使用ReRANK重新排序,從兩類查詢結果中選擇匹配使用者問題的最佳結果,需配置 Rerank 模型 API。
    • ReRANK:計算候選文件清單與使用者問題的語意匹配度,根據語意匹配度重新進行排序,進而改善語意排序的結果。
這邊我使用較多的就是  xinference  了,然後則是包含了 Rerank等的檢索用法,網路上很多開源的套件都有相關說明如上

2023/08 公司添購 RTX 6000 Ada 48 GB * 2 和 A 100 80GB * 4
2024/05 公司添購RTX 6000 Ada 48 GB * 8 * 2
看完前面說明,其RAG原理就是輸入私有的文檔後,每個文檔依照Token數量?字元數量?等一定規則,將每個文檔拆分為一個一個小片段(chunk);接著對這些chunk產生embeding,儲存到vector db 中,產生Index;待使用者搜尋時,會將語句轉換為embedding,跟 vector db 做向量相似度搜尋,搜尋到最相似的 embedding ,也就是查詢語句的向量比對 " 部分 " 知識庫的向量相似度再將對應上下文透過LLM做合成自然流暢的回答 (這裡很多人會糾結在以Q找Q再找A或者以Q找A,但這其實就回到 Rule-Based 啦);特別是最近很夯的所謂的 GraphRAG、Knowledge Graph (知識圖譜) 及 Ontology (知識本體,遙想2008的碩士班,還有2012跑去Ontology大本營,OWL.Manchester) ?(附上一張已不可考的知識圖譜常見圖)

先附上網路陸續找到的一些教學文章

原始碼解讀- 微軟GraphRAG框架 | 微軟近日開源了新一代RAG框架GraphRAG
你想要的GraphRAG的內容都在這裡了 | GraphRAG:知識圖譜+大模型
微軟開源的GraphRAG爆火,Github Star量破萬,生成式AI進入知識圖譜時代?
動手實操微軟開源的GraphRAG當RAG遇見LLM,以檢索增強為導向的大語言模型
手把手教你建構基於知識圖譜的GraphRAG之結構化資料篇【LangChain+Neo4j】

GraphRAG(基於圖的檢索增強生成)是一種利用知識圖譜(KGs)來提升自然語言處理效能的技術,特別是在問答系統中表現出色。簡單來說,GraphRAG將知識圖譜和RAG技術結合,能夠從文件中提取出結構化的資訊,然後基於這些資訊,提供更準確、且符合上下文的回應。不過,GraphRAG在處理抽象問題時,或是當問題中沒有明確提到具體實體時,效果可能會比較差。

借助Hybrid RAG 實現AI 模型高效能與資料隱私保護
HybridRAG: 融合知識圖譜與向量檢索的新型資訊擷取方法
Kotaemon:本機Graph RAG UI,以Graph RAG 和Hybrid RAG與文件暢聊

另外補上這個新的,可惜我的 NVIDIA 的 API KEY 額度用完了,來不及重截圖
HybridRAG 是一種結合了基於知識圖譜(KGs)的 RAG 技術(稱為 GraphRAG)和 VectorRAG 技術的系統,專門用於增強從文件中提取資訊的問答(Q&A)能力。此系統已被證明能夠生成準確且具上下文相關性的答案。

https://github.com/microsoft/graphrag
From Local to Global: A Graph RAG Approach to Query-Focused Summarization

git clone https://github.com/microsoft/graphrag.git
#initialize:python -m graphrag.index --init --root .
#index:python -m graphrag.index --root .
#query:python -m graphrag.query --root . --method global "query"
#query:python -m graphrag.query --root . --method local "query"

下圖是 GraphRAG論文裡針對索引 (利用LLM來建立知識圖譜,找出對應的實體(節點)、關係(邊)等) 和查詢 (透過像是 Leiden來對整個圖譜做劃分以及摘要跟總結) 的處理過程;其中,LLM怎樣做圖譜可以在這裡找到 ! 當然,或許可以嘗試手工自己做KG (略麻煩也耗工),那你可能會找到一堆套件說可以輸入文件後自動幫你生成,但你還是得需要有個所謂的 NER,再把相關數據存入 Neo4j,再來則是透過Node2Vec、GraphSAGE等來做 embedding (這塊可能得看 GraphRAG是否能盡快解決 ?),接著是透過 FAISS、Milvus 等向量搜尋,那應該會做得比較流暢一點?最後說個招人討厭的實話,實在不怎建議為了一台車連輪子都自己造 ... 特別是在壓根連 GPU 都沒什麼資源的狀況下,一直呼叫外部API ... 這??LP比雞腿?(似乎都忘記了大家其實有點排斥把你的相關資料或者數據傳到雲端LLM做RAG啊)
傳統RAG會做的chunk,在GraphRAG的論文裡也是沒漏掉,論文中就有提到1200個token會去得較好的效果,但是這會卡到所謂的 precison 跟 recall 的效果。另外,GraphRAG支援需要理解整個文本語料的問題,一種全局性的理解和摘要,而不是僅從文本的局部區域中檢索資訊,例如「資料集的主要主題是什麼?」的 "global search"" local search " 通常指的是文本的局部區域或文本塊,這些局部區域是RAG方法檢索的單元。 

但截至本文的整理,根據官方的論文和一些 issue 跟範例:During our research we got the most quality out of gpt-4, gpt-4-turbo and gpt-4o, that's why out of the box we include support for these in both OpenAI and Azure environments. 看來官方是覺得比不上,所以就沒針對自己地端佈署運作有深入研究 !!! Regarding local hosting there's a very interesting conversation going on in this thread #339;初步評估結果是,以KG為基礎來做RAG,確實會因為具備所謂的 實體 (entity)、關係 (relation) 等,而優化了相關的結果,但是在 GraphRAG還未支援Local LLM 前,估計這成本會嚇到你的 XD (當然有人回覆 GPT4o便宜多了)。最後,論文還是有提供了效果的展示:

寫到這,可能會很想看看是不是只是嘴砲 ? 官網的文件其實寫得非常清楚
https://microsoft.github.io/graphrag/posts/get_started/ 
本來想好好的把過程再做一下記錄的,
尷尬的是,其實早就有人做好了 XD
連原本要特別注意的 .env 跟 settings.yml,都只要在其 gradio ui 上改一改,就能用了啊
api_key: ollama
model: deepseek-v2:236b-chat-q8_0
max_tokens: 128000
api_base: http://xxx.xxx.xxx.xx:11434/v1
concurrent_requests: 1

沒錯,就是這樣改成地端的吧

api_key: ollama
model: bge-large-zh-v1.5
api_base: http://xxx.xxx.xxx.xx:6006
concurrent_requests: 1
整個看下來,嗯,如果不是用地端,那這個 token 真的不小,我自己是跑地端就是

原本有找到網路上有人教說要怎樣修改其中幾行 code
/home/twman/anaconda3/envs/ollama/lib/python3.11/site-packages/graphrag/llm/openai/openai_embeddings_llm.py
/home/twman/anaconda3/envs/ollama/lib/python3.11/site-packages/graphrag/query/llm/oai/embedding.py
整個這樣跑完後,發現。。。我想現階段想要實際可以落地的應用,理論上是還用不到所謂的 GraphRAG啦 ... 畢竟殺雞焉用牛刀,而且你那略驚人的token數,怎樣變現才是重點了,可能你會想說,用GPT-4o mini 啊 .... 啊,你是忘記大部份公司都不想把數據上雲啦,然後也有點難很有勇氣的 GPU 給它買下去 XD