iT邦幫忙

2024 iThome 鐵人賽

0
生成式 AI

使用 Spring AI 打造企業 RAG 知識庫系列 第 32

使用 Spring AI 打造企業 RAG 知識庫【32】 - 提高RAG準確率從Embedding換起

  • 分享至 

  • xImage
  •  

預設不見得最好

https://ithelp.ithome.com.tw/upload/images/20240909/20161290wK5vkl8sla.jpg

開始用 RAG 處理資料後,發現抓出的內容似乎有點落差,而影響查詢結果最重要的就是 Embedding,原本想說 Open AI 的 embedding 模型價格也不算便宜,應該還不至於太差吧,直到看到 ihower 大大的 繁體中文 Embedding 評測,才發現不是貴的就最好

拿 Spring AI Embedding 預設的 text-embedding-ada-002 模型來說,繁體中文的準確率竟然排到 24 名,而 text-embedding-3-small 價格便宜了 5 倍,準確率竟還高了一名,至於最貴的text-embedding-3-large 排名也只到 13,雖然命中率勉強破 9 成,不過跟第一名的 voyage-multilingual-2差了將近 7%

另外這數據還有個頗重要的觀念,dimensions 不是越高就越好,拿第四名的微軟 multilingual-e5-small 來看,其 dimensions 竟然只有 384
https://ithelp.ithome.com.tw/upload/images/20240909/201612909C8dN9hckz.jpg

dimensions 越高運算就越花時間,dimensions 少的話運算速度跟儲存空間都能有效降低,multilingual-e5-small 這模型真的非常優秀,唯一的缺點就是一次只能處理 512 個 Tokens,另外這是開源模型,只能在自己機器或是雲端伺服器部屬(可以參考 Azure 的雲端方案 https://learn.microsoft.com/zh-tw/azure/postgresql/flexible-server/azure-local-ai)

至於付費的部分若要便宜首推 Open AI 的 text-embedding-3-small,我們之前寫的程式只需增加一個模型的參數,對原本就使用 Open AI 的人來說可以做到最小的變動

spring:
  ai:
    openai:
      api-key: ${OPENAI_KEY}
      chat:
        options:
          model: gpt-4o-mini
      embedding:
        options:
          model: text-embedding-3-small

不過凱文大叔主要想提升 RAG 的準確率,所以直接挑第一名的 voyage-multilingual-2 進行測試,官網(https://www.voyageai.com/) 註冊後即可建立 API Key
https://ithelp.ithome.com.tw/upload/images/20240909/20161290HcaVPVWb0o.png
可以看到上方一些免費試用的限制,不過 5千萬的 Tokens 測試也綽綽有餘了,凱文大叔將這次鐵人賽 30 天的文章進行 embedding 後也才12萬多的 tokens
https://ithelp.ithome.com.tw/upload/images/20240910/20161290wnMoACeoTT.png

由於 Spring AI 沒提供 Voyage 的模型串接,凱文大叔就直接用 Open AI 的設定試看看

spring:
  ai:
    openai:
      api-key: ${OPENAI_KEY}
      chat:
        options:
          model: gpt-4o-mini
      embedding:
        base-url: https://api.voyageai.com/v1/embeddings
        api-key: ${VOYAGE_KEY}
        options:
          model: voyage-multilingual-2
          dimensions: 1024

程式的部分使用之前測試 Embedding 的 Controller

@RestController
@RequiredArgsConstructor
public class EmbeddingController {
	private final EmbeddingModel embeddingModel;
	@GetMapping("/embedding")
  public List<Double> embed(String message) {
      return embeddingModel.embed(message);
  }
}

輸入網址測試看看 http://localhost:8080/embedding?message=這是voyageai的Embedding測試
https://ithelp.ithome.com.tw/upload/images/20240909/20161290EEP4VIziEx.png

很不幸的直接報錯,來看看原始碼吧,希望不用自己寫個 API

public <T> ResponseEntity<EmbeddingList<Embedding>> embeddings(EmbeddingRequest<T> embeddingRequest) {
		Assert.notNull(embeddingRequest, "The request body can not be null.");
		Assert.notNull(embeddingRequest.input(), "The input can not be null.");
		Assert.isTrue(embeddingRequest.input() instanceof String || embeddingRequest.input() instanceof List,
				"The input must be either a String, or a List of Strings or List of List of integers.");
		if (embeddingRequest.input() instanceof List list) {
			Assert.isTrue(!CollectionUtils.isEmpty(list), "The input list can not be empty.");
			Assert.isTrue(list.size() <= 2048, "The list must be 2048 dimensions or less");
			Assert.isTrue(list.get(0) instanceof String || list.get(0) instanceof Integer
					|| list.get(0) instanceof List,
					"The input must be either a String, or a List of Strings or list of list of integers.");
		}
		return this.restClient.post()
				.uri("/v1/embeddings")
				.body(embeddingRequest)
				.retrieve()
				.toEntity(new ParameterizedTypeReference<>() {
				});
	}

看最後 return 的部分.就是使用 RestClient 來呼叫,uri 的部分竟然直接加上 "/v1/embeddings" 難怪會失敗,這樣把 base-url 的 /v1/embeddings 拿掉即可,好在後面字串都一樣,不用再多寫一個

其實要自己寫也不難,程式幾乎一樣,只差在 URL 而已

base-url: https://api.voyageai.com

再試一次,還是報錯…

400 - {"detail":"The request body is not valid JSON, or some arguments were not specified properly. In particular, Argument 'dimensions' is not supported by our API"}

不過錯誤不太一樣,看起來是不需要傳送 dimensions 參數,拿掉再測試看看
https://ithelp.ithome.com.tw/upload/images/20240909/20161290c6Yh9uke9W.png

總算成功了,等後續凱文大叔將 ETL 跟查詢部分改成 Voyage 的 Embedding 模型,再來看看近似搜尋會不會比較準

雖然目前 Open AI 還是市佔率第一,不過不同的模型都有自己的特色,未來開發 AI 應用應該會拿不同的模型組合應用,才能展現各個模型的優勢

▋回顧

今天學到了甚麼?

  • 繁體中文 Embedding 的排行榜
  • dimensions 不是越大越好,價格也不是越貴越好
  • 更換 Embedding 模型的方式

▋Source Code:

程式碼下載: https://github.com/kevintsai1202/SpringBoot-AI-Day32.git


▋認識凱文大叔

凱文大叔使用 Java 開發程式超過 20 年,對於 Java 生態非常熟悉,曾使用反射機制開發 ETL 框架,對 Spring 背後的原理非常清楚,目前以 Spring Boot 作為後端開發框架,前端使用 React 搭配 Ant Design
下班之餘在 Amazing Talker 擔任程式語言講師,並獲得學員的一致好評

最近剛成立一個粉絲專頁-凱文大叔教你寫程式 歡迎大家多追蹤,我會不定期分享實用的知識以及程式開發技巧

想討論 Spring 的 Java 開發人員可以加入 FB 討論區 Spring Boot Developer Taiwan

我是凱文大叔,歡迎一起加入學習程式的行列


上一篇
使用 Spring AI 打造企業 RAG 知識庫【31】- 取得真正的氣象資料
下一篇
使用 Spring AI 打造企業 RAG 知識庫【33】 - 內容審核與評估測試
系列文
使用 Spring AI 打造企業 RAG 知識庫33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言