LlamaIndex 學習筆記 - 使用不同的 Embedding model
目錄
這筆記是建構在 LlamaIndex 官方文件的節錄/實作/追蹤
嘗試的原始碼在 https://github.com/unclefomotw/llamaindex-try/blob/main/src/rag_6.py (以及 rag_4.py)
Embedding 是用一串數字「代表」各個事物,在空間上定位,讓他們在空間中的相似度與實際相似度吻合 – 但這是需要模型計算的
所以通常 「問題」與「知識」要用同一個 embedding 模型去計算,才能找出相關的知識
(如果不知道 Embedding 是什麼,看 這篇文章 )
LlamaIndex 在 v0.10.28 預設用 OpenAI 的 “text-embedding-ada-002”,不過此時他們已經出第三代比較便宜的 embedding 模型了。而在 HuggingFace 上也有很多開放的可利用
在 LlamaIndex 定義 embedding model,可以使用放在 OpenAI 的 model,用網路 API 連過去運算
from llama_index.embeddings.openai import OpenAIEmbedding
my_embedding = OpenAIEmbedding(model="text-embedding-3-small")
或者用 HuggingFace model 下載到本機運算 (Embedding leaderboard 挑看選看喔)
# 需要 pip install llama-index-embeddings-huggingface
# 會同時安裝 transformers
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
my_embedding = HuggingFaceEmbedding(
model_name="DMetaSoul/Dmeta-embedding-zh-small"
)
挑好 embedding model 以後,使用有幾種方法(詳見 rag_6.py 與 rag_4.py)
使用法 1: 全域 #
最一勞永逸的是宣告在 global 的 Settings
,之後無論是線下建 index 知識庫、或是線上處理問題,都會用這個 embedding model
from llama_index.core import Settings
Settings.embed_model = my_embedding
使用法 2: index + retriever #
如果某種原因你會使用多個 embedding model,可以在「建 index」處理知識,以及「建立 retriever」處理問題的時候指定
# 線下:「建立」 index
# .from_documents 或 .from_vector_store 都有
# 如果用另外的 pipeline 建 index 那就是自己處理
index = VectorStoreIndex.from_documents(
embed_model=my_embedding,
...
)
# 線上:處理問題查詢知識時
retriever = VectorIndexRetriever(
index=index,
embed_model=my_embedding,
...
)
使用法 3: index #
VectorIndexRetriever
在沒有給定 embed_model
時,會用 index
裡面的 embed_model
,所以只要確保在 retrieve 的時候,index 變數使用的 embed_model 是你要的就可以
BUT! 在線上處理問題,index 很可能是另外宣告的,例如用 load_index_from_storage
– 而當初在線下建 index 的時候,並不會把使用什麼 embed_model
給存進去,所以線上載入的時候並不知道當初用的是哪個 embedding 模型!
因此,在線上的階段,載入 index 時必須要再次指定你要的 embed_model
# 線上: 「載入」 index
# When loading, need to specify the embedding model information again
storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR)
index = load_index_from_storage(
storage_context,
embed_model=my_embedding
)
# 同樣是線上
# retriever takes index, 這邊就不用指定 embedding 了
retriever = VectorIndexRetriever(
index=index,
...
)