iT邦幫忙

2023 iThome 鐵人賽

DAY 13
1

全端 LLM 應用開發-Day13-用 FAISS 來儲存向量資料

接下來幾天我們會介紹各種不同的向量資料庫。

FAISS 是 Facebook AI Research(FAIR)開發的一個高效的相似度搜索和密集向量聚類庫。它專為高維向量相似度搜索而設計,並且能在大型數據集上提供快速和準確的結果。FAISS 支援多種距離度量,並提供了多種優化的索引結構來實現快速搜索。

安裝時需要注意他有 CPU 版和 GPU 版,我們窮人就先用 CPU 版本。

  1. 使用指令 poetry add faiss-cpu

  2. 我們先來建立一個檔案 faiss_tutorial.py,寫一個 FAISS 的 function。

def add_to_faiss_index(embeddings):
    vector = np.array(embeddings)
    index = faiss.IndexFlatL2(vector.shape[1])
    index.add(vector)
    return index

這個函式負責將 embeddings 加入到 FAISS 索引(index)中。一開始是先將 embeddings 轉換為 numpy 的陣列,然後用 vector.shape[1] 取得每個 embedding 的維度,放進 IndexFlatL2 裡,這是一種暴力搜尋法(因為 FAISS 不直接支援 Cosine Similarity,要再換算)。最後再加入索引裡面。

  1. 接著我們再定義一個搜尋用的 function:
def vector_search(index, query_embedding, text_array, k=1):
    distances, indices = index.search(
        np.array([query_embedding]), k)
    return [(text_array[i], float(dist)) for dist, i in zip(distances[0], indices[0])]

這個是把想要問的問題做了 embedding 後,放進去給 FAISS 搜尋。並且 return 一個 list ,將距離和索引組合成一個新的 list ,其中包含與查詢相似的文本和其對應的距離。

  1. 接著我們再來定義一個 function ,來用 OpenAI 來做 embedding。
def get_embedding(text, model_name):
    response = openai.Embedding.create(
        input=text,
        engine=model_name
    )
    return response['data'][0]['embedding']
  1. 最後就來跑我們的 main 了。
def main():
    EMBEDDING_MODEL_NAME = "embedding-ada-002"  # 你前幾天在 Azure OpenAI 上建立的模型名稱
    openai.api_base = "https://japanopenai2023ironman.openai.azure.com/"
    openai.api_key = "your_key"
    openai.api_type = "azure"
    openai.api_version = "2023-03-15-preview"


    text_array = ["我會披星戴月的想你,我會奮不顧身的前進,遠方煙火越來越唏噓,凝視前方身後的距離",
              "而我,在這座城市遺失了你,順便遺失了自己,以為荒唐到底會有捷徑。而我,在這座城市失去了你,輸給慾望高漲的自己,不是你,過分的感情"]

    embedding_array = [get_embedding(
        text, EMBEDDING_MODEL_NAME) for text in text_array]

    faiss_index = add_to_faiss_index(embedding_array)

    # 輸入問題來搜譣
    query_text = "工程師寫城市"
    query_embedding = get_embedding(query_text, EMBEDDING_MODEL_NAME)
    search_results = vector_search(faiss_index, query_embedding, text_array)
    print(f"尋找 {query_text}:", search_results)


if __name__ == '__main__':
    main()

跑起來後,應該就會看到結果如下:

尋找 工程師寫城市: [('而我,在這座城市遺失了你,順便遺失了自己,以為荒唐到底會有捷徑。而我,在這座城市失去了你,輸給慾望高漲的自己,不是你,過分的感情', 0.41394227743148804)]

工程師寫城市是一個諧音的錯字,我們透過這個來尋找的話,找到「在這座城市遺失了你」這首歌是最接近,但是距離也只有 0.41。

然而,FAISS 不是一個資料庫,它是一個專門用於高效進行大規模向量搜索的套件。在 FAISS 中,索引通常存儲在記憶體中,以達到高速搜索的目的。當然你也可以用 faiss.write_index(index, "my_index.faiss") 來把資料存在本地端。明天開始我們會來講更像資料庫的向量資料庫。


上一篇
全端 LLM 應用開發-Day12-用 Azure Open AI 做 embedding
下一篇
全端 LLM 應用開發-Day14-用 pgvector 來儲存向量資料
系列文
全端 LLM 應用開發(向量資料庫, Hugging Face, OpenAI, Azure ML, LangChain, FastAPI and more)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言