時隔兩年,又重新回來當AI工程師了,今天來講講新玩意GraphRAG吧
我參考了一些文章影片發現現在新出的gpt-4o-mini可以在成果可用的情況下將模型的費用控制在原本的1/38左右。我自己實測,一本32457字的小說用gpt-4o-mini建完graph大約0.06美金,而我用gpt-4-turbo-preview大約跑一次要2.3美金。不要問我為什麼知道,因為我忘記切模型,還跑了兩次,錢包君已經哭壞了。
OK 來看個成果吧,究竟我們GraphRAG出來的成果如何
資料源: Trump的wiki 直接ctrl + A 不整理餵進去當input
https://en.wikipedia.org/wiki/Donald_Trump
工具:
- Python 3.10 (官方文檔說3.10 ~3.12才適用)
- pip install graphrag
- Gephi 軟體 用於視覺化成果
好,那我是怎麼做的就來帶大家跑一遍吧
首先我開了一個新資料夾 現在甚麼檔案都還沒有
這時我們可以開始建立虛擬環境
python3 -m virtualenv .venv
source .venv/bin/activate
# 參考文檔 https://microsoft.github.io/graphrag/posts/get_started/
pip install graphrag
等個幾分鐘看到列出一堆packages就差不多好了
接下來就繼續按照文件指引的建立資料夾 ,抓書
mkdir -p ./ragtest/input
curl https://www.gutenberg.org/cache/epub/24022/pg24022.txt > ./ragtest/input/book.txt
然後我們就可以來init 專案了
python -m graphrag.index --init --root ./ragtest
init 完成就可以看到很多file了,其中有兩個重要的地方要改
首先是.env裡面要放我們新申請的openai key
大家這邊就換上自己的API KEY
接下來你可以發現這個setting.yaml裡面會將.env的環境變數注入,所以我們只要改好.env這裡就不用重複改很多地方。 也可以確保這份yaml上傳到github時不會有secret 洩漏問題。 反過來說 這裡的.env就別上傳了,不然要秘密看光光啦~~
下一步我們focus在L7的model: gpt-4-turbo-preview 把萬惡的這個貴貴模型先換掉我們換成 gpt-4o-mini
下方的embedding model不貴,我們可以先保持不變
最後是由於我們要輸出summarized_graph.graphml 給Gephi畫出漂亮的視覺化成果展示,我們來把L131 的 snapshots中的graphml功能打開
graphml: false 請切換成 graphml: true
全部改完了 大功告成, 嗎? 等等不對歐,setting.yaml 旁邊的小白點還在發出邪惡的光芒。如果這時候跑下去其實沒存到檔就會用到貴貴模型啦~~
趕快ctrl + S 確定有存到檔案
燈光熄滅,好戲開場
輸入資料開始建立節點與連結
python -m graphrag.index --root ./ragtest
跑的過程要一段時間,我們來研究一下,GraphRAG在做甚麼吧
看一下左邊的資料夾結構有一個prompt
這裡就是RAG有用的秘密
RAG這個使用方式其實源自於大語言模型的幻覺問題。因為大語言模型常常會有不穩定的輸出或輸入。對於複雜的問題,往往無法保持回答的一致性與品質。 然而RAG則讓大語言模型擁有呼叫API去參考資料庫的能力。就好比如果在沒有準備的情況下突然被公司主管叫去詢問。如果是高壓統治的環境,你可能就會開始亂掰。而RAG就是給大語言模型一點緩衝時間。讓它有機會跟主管說。等等,我會去查一下資料,整理之後晚點跟您報告。而這段時間大語言模型就會開始進行大量的資料庫查詢。
後來我們發現prompt有長度的限制,也有成本的考量,不可能讓過去的prompt無止境的堆疊成一個超大的歷史。總不可能平常跟別人講話都要求別人重新講過所有對話紀錄才開始講新的內容,這樣溝通會很沒有效率的。
回想一下我們在line對話時會怎麼做。 我記得你好像跟我說過 {某件事}。
那我就來line用放大鏡工具搜尋一下{某件事},看看聊天歷史。
所以我們不會忘記一件事情的時候就請別人每次都重頭講,我們改成自己可以先查詢一下對話歷史。
於是,讓大語言模型透過RAG的機制塞資料到資料庫就是一個很棒的發明。大語言開始有可以儲存與查詢對話歷史的功能。也就擁有了記憶。
然而後來人們發現,要真的儲存文字格式並查詢文字並不是很高效的設計
於是有人開始導入向量資料庫,讓語言模型有向量記憶。(向量記憶也是一個很cool的topic,"國王+女王蜂-皇后 -> 雄蜂" 大概類似這樣,之後有機會再展開來講)
不同的記憶型態會分別有其優缺點。有人發現描述不同實體與實體之間的關係很適合用Graph來進行表示。於是GraphRAG 就是這樣的工具可以協助通過大語言模型的prompt來自動化識別實體,並建立實體之間的關聯。Run起來真的像黑魔法一樣。
哎呀 現在這張Graph差不多跑完了,我們就繼續往下走看結果吧
final node 就是各個不同被識別出來的實體,其中title是實體的名稱,type是類別
{“level”:0,”title”:”EBENEZER SCROOGE”,”type”:”PERSON”,”description”:”Ebenezer Scrooge is a central character in Charles Dickens’ \”A Christmas Carol.\” Initially portrayed as a miserly old man, Scrooge is known for his disdain for Christmas and his obsession with wealth. His transformation begins when he is visited by the ghost of Jacob Marley, his former business partner, who warns him of the consequences of his selfishness. Throughout the story, Scrooge reflects on his past, including fond memories of working under Fezziwig during a festive Christmas Eve, which highlights the joy and generosity he once experienced. This reflection, along with the visits from three spirits, leads to a profound change in his character, ultimately turning him into a kinder, more compassionate individual who embraces the spirit of Christmas.”,”source_id”:”260fb94666cbdfb08286ce8d8162130d,d6583840046247f428a9f02738842a7c,e8d4072836ac08145edc2fa8c15ea2c2",”degree”:12,”human_readable_id”:4,”id”:”3671ea0dd4e84c1a9b02c5ab2c8f4bac”,”size”:12,”graph_embedding”:null,”community”:”1",”top_level_node_id”:”3671ea0dd4e84c1a9b02c5ab2c8f4bac”,”x”:0,”y”:0,”__index_level_0__”:4}
這張relationship則描述了不同Node之間的關係 (在Graph中,Node 相互連結的邊線上面會寫小小的字用於描述關係)
接下來要開始畫圖了,首先我們下載summarized_graph.graphml到桌面
打開Gephi,接下來從"檔案" -> "開啟" 打開我們剛剛存到桌面的summarized_graph.graphml,記得附檔名一定要存成xxx.graphml否則Gephi不認識
下一步你會看到一張黑壓壓的圖,我們來讓它變好看吧
首先到左上角來設定一下顏色
馬上順眼一些了
接下來來排樣一下
接下來就排的很好看了
下一步我們可以透過編輯工具來檢查這各格節點分別代表甚麼意義,點擊節點時也會show出跟該節點有關聯的其他節點。
好,今天的課程就先到這裡,筆者也該接觸GraphRAG一周的時間。我再研究一段時間後再分享更精實的內容給大家
接下來大家來自己做自己想要的專案吧,比如貼一些很多字的內容看會長甚麼圖出來。
我們輸入的資料要放在哪呢? 沒錯就是在Input的book中
這裡可以置換成其他內容輸入,重跑一次指令就會跑出不一樣的圖了。
# 重跑的指令~~
python -m graphrag.index --root ./ragtest