讓你的文件活起來 - RAG 實作
這是在 iThome 所舉辦的 Hello World Dev Conference 工作坊的內容。本次工作坊將帶著大家理解 RAG(Retrieval-Augmented Generation)技術,並使用 Python 程式語言及 LangChain 框架進行實作,最終將文件轉化為可以進行互動問題的知識庫。
現在沒用過 AI 服務的人大概都要被歸類到上個世代的化石了。不得不說,這些 AI 服務真的很厲害,但到目前一直有個比較大的困擾,就是它有時候會一本正經的講幹話,就算遇到它不會的問題,因為它講出來的內容太有自信,導致不知道它到底是真的假的。
舉個例子,如果你幫公司做了一個用來做知識管理(Knowledge Management, KM)的網站,公司內部一些相關的規定都可以在這裡查到。你在這個網站上掛了一個聊天機器人,當訪客問機器人你們家的產品多少價錢或是該怎麼退換貨的時候,這時候不知道就該說不知道,而不是硬擠答案出來。我們可以透過適當的「提示(Prompt)」來限制 AI 的回答,但還是希望 AI 不要隨便亂回答,但就是因為這樣,才有了 RAG 的出現。
重要!請先看這裡!
因為活動現場網路頻寬可能不夠快,而且因為會用到的模型檔案有點大,如果大家報名這個工作坊而且想在現場跟著一起實作的話,建議可以找空檔完成以下步驟:
- 下載 Ollama 應用程式
請在這裡選擇合適的版本下載並安裝。
- 下載模型
在本次工作坊中,我將使用 mistral
模型做為範例,這個模型大概有 4GB,你也可以選擇其它模型。先執行指令下載 mistral
模型:
$ ollama pull mistral
另外還會用到另一個比較小的模型 nomic-embed-text
,也可以順便先拉下來:
$ ollama pull nomic-embed-text
或是直接執行也可以:
$ ollama run mistral
如果還沒下載過 mistral
模型的話,這個指令會幫你下載,並且直接進入聊天模式,然後就可以開始問它 問題了:
$ ollama run mistral
>>> 你好 :)
嗨,nice to meet you! 今天好吗?
(Hello, nice to meet you! How are you today?)
如果有需要帮助的话,我会尽力帮到您。
(If you need any help, I will do my best to assist.)
如果有空檔的話,以下這兩個也可以順便安裝一下:
比較花時間的安裝到這裡差不多就算完成了。
名詞解釋
AI 時代一堆專有名詞或縮寫真的滿天飛,所以我們先從名詞解釋開始
LLM
LLM(Large Language Model),中文翻譯成「大型語言模型」,但這翻譯有跟沒有差不多。想想看,以前如果我們想要判斷使用者輸入了什麼內容,或是判斷語意,特別是中文,我們可能需要使用一些斷字、斷詞的資料庫才有辦法處理,特別是現在很多人「再在」「應因」不分的情況下,想要要判斷文字的意圖或情緒基本上是不太容易做到的。
雖然我們大部份的人,包括我自己也是,都不知道這到底是怎麼做到的,但 LLM 做到了。透過 LLM,可以幫我們解讀使用者的「輸入」,理解想要的問題,並且在適當的「提示(Prompt)」下回答使用者的問題,甚至有一些錯別字也不會影響結果。簡單來說,LLM 幫我們搞定輸入以及輸出的事情。
問題是,這個 LLM 的 M 是什麼 Model?又是怎麼訓練來的?像我們這種凡人應該是沒 能力訓練模型的,大部份只能看那些神仙公司打架,然後撿他們打架掉出來的東西來用,像是 Facebook 的 Llama3、Google 的 Gemma、Mistral AI 的 mistral...等開源模型。
只是,就算我們撿到了這些訓練好的模型,大部份的我們大概也不太容易再對它再進行訓練,讓它更聰明。雖然我們可以透過更精準的 Prompt 請 LLM 回答的準確一點,但 LLM 並沒有我們想像中的聰明,它其實是很健忘的。舉個例子,當你你在跟 ChatGPT 聊天的過程中,感覺好像都會記得你跟它聊了什麼,這是因為 ChatGPT 在每次的對話裡,都會把同一個討論串的「情境」或「上下文(Context)」做個摘要,然後在下一個對話的時候一併傳給 ChatGPT。然而這樣不斷累積情境或上下文的做法是有限的,這東西又稱「上下文視窗(Context Window)」,這個窗戶沒辦法一直無限開下去,特別如果遇到你想要查詢的情境是一本或數本 PDF 電子書的時候,這可能就沒辦法了。
其次,就算是這些大公司訓練好的 Model,通常也都是根據現有的資料訓練的,如果想要問它最新一期大樂透開幾號,或是問它今天台積電的收盤價多少,它應該不會知道。另外,因為這些模型都是使用公開的資料進行訓練的,所以如果你想問它你公司的請假規定,照理它應該也不會知道。
所以在這種情況下,LLM 會怎麼回答你?還能怎麼回答,就瞎掰啊!
RAG
RAG(Retrieval-Augmented Generation),中文翻譯成「檢索增強生成」,RAG 的重點不在檢索(Retrieval)或生成(Generation),因為這本來 LLM 就能做到了,重在在於「增強(Argumented)」,透過它,LLM 可以更精準的回答 我們的問題。
講這到這裡,可能會跟另一個名詞「微調(Fine-tuning)」有點像,但其實這兩個是不太一樣的概念。微調是指針對現有的 Model 再拿特定領域的資料進行訓練、調整,例如可餵食特定領域醫學相關的資料,增進這個 Model 在這方面的醫學知識。
而 RAG 並不是對原本的 Model 進行調整,而是在我們對 LLM 下 Prompt 的時候提供額外的參數或資訊,讓 LLM 能更準確的回答問題。簡單的說,RAG 是提供給 LLM「額外的知識」,再講的更白話一點,就是讓你原本對 LLM 下的 Prompt 更精準。
很多時候你以為可以透過「微調」來讓 LLM 聰明一點,事實上你可能需要的是 RAG。
Embedding
Embedding,中文翻譯成「嵌入」,這個詞可能比較難從字樣上來想像是怎麼回事。簡單來說,Embedding 是一種將資料轉換成「向量(Vector)」的過程或技術,這麼做可以讓 AI 更好地「理解」並比對資料的「相似性」。
什麼是「向量」?舉例來說,我想針對香蕉、芭樂、蘋果跟榴槤這四個水果的味道跟質地軟硬做個比較,如果我把味道跟質地用一個二維空間來呈現,可能看起來會像這樣:
臭 ^
| 榴槤(0.9, 0.9)
|
|
|
|
|
|
| 蘋果(0.5, 0.2) 芭樂(0.6, 0.2)
香 | 香蕉(0.3, 0.1)
+----------------------------------> x
軟 硬
透過幫這些水果「打分數」,就能幫它們在這個二維空間定出位置來。在二維空間越接近的水果,代表它們的味道跟質地越相似。
回到我們的主題,Embedding 技術可以讓我們把資料轉換成向量,這樣我們就可以透過向量的方式來比 對資料的相似性。這裡指的向量不會像我們這裡只是二維的空間,而是可能有幾百維,甚至上千維。透過向量的方式來比對資料的相似性,可以除了能幫原本的 LLM 補充一些它原本不知道的事之夕,也讓它更容易找到精準的資料。
向量資料庫
如果每次都要對資料轉成向量,效能可能會有點差,所以有一個可以存放這些向量的地方是很重要的。也許你會想把這些向量另外存在文字檔裡,但這樣的話,每次要找相似的資料時,就要把所有的向量都讀進來,然後再逐一比對,這可能也會有效能上的問題。
還好現在有專門用來存放向量的資料庫,以我們這個工作坊會用到的 Chroma 為例,就是一個專門用來存放向量的資料庫,而且還有一些神奇的特異功能,讓我們不用懂太多演算法就能找出相似的向量。
動手作!
好啦,故事講的差不多了,是該時候動手做點東西了!