蝦咪系 Word Embedding?詞嵌入模型概念及實作

# 使用生成式 AI 結合 RAG 技術實做屬於自己的 LLM 知識庫系列文章

Word Embedding ?

維基百科的定義

詞嵌入(英語:Word embedding)是自然語言處理(NLP)中語言模型與表徵學習技術的統稱。概念上而言,它是指把一個維數為所有詞的數量的高維空間嵌入到一個維數低得多的連續向量空間中,每個單詞或詞組被映射為實數域上的向量。

Word Embedding 的輸入格式

輸入是一個或多個文字,通常是單字或是整句話,這些文字會先經過處理(例如分詞、去除標點),再送進詞嵌入模型中,舉例來說:「美國總統是誰?」,這句話可能會轉換成 ["美國總統", "是誰"] 這樣陣列。

Word Embedding 的輸出格式

針對上述陣列內的每個文字,詞嵌入模型會經過一連串的數學運算,將其轉換成一組向量,這些向量是由一串實數所組成的數字序列,代表該詞的語意特徵,輸出的格式通常會是像底下這樣的結構

{
  "美國總統": [0.12, -0.34, ..., 0.87],
  "是誰": [0.03, -0.56, ..., 0.45]
}

所以到底是什麼?

好吧,其實對於有點技術背景的人來說,前面那些概念應該已經蠻清楚了。但如果你是完全沒碰過這塊的新手,可能還是會覺得,嗯? 這到底在說什麼?

我這邊用白話文來解釋,Word Embedding 其實就像是幫每個文字編碼成一張數字小卡片,這張名片記錄了它的個性、興趣和關聯對象,而電腦就是靠這些卡片來判斷誰跟誰是好朋友(例如 蘋果 跟 香蕉 很像)或誰跟誰完全不像(像 香蕉 跟 國王)

圖片來源 : https://towardsdatascience.com/deep-learning-for-nlp-word-embeddings-4f5c90bcdab5/


為什麼有這麼多不同的詞嵌入模型?

因為每種模型都有自己的擅長領域,而且技術一直在進步、需求也不一樣,所以自然就冒出很多種詞嵌入方式,主要可分成幾個面向

  • 技術進步:早期像 One-hot 很簡單,但不夠聰明,後來 Word2Vec、GloVe 開始學語意,再後來 BERT、GPT 甚至能根據上下文「動態」理解每個詞。
  • 應用場景:做分類、對話、翻譯、問答,每個任務對詞向量的需求都不一樣。
  • 語言特性:中文沒空格、英文有變化、阿拉伯文從右寫到左,不同語言處理起來不太一樣,模型也要調整。
  • 硬體效能:以前只能跑小模型,現在顯卡夠強,大家就開始設計更複雜、精準的模型來抓語意。

在我們的主題中,特別要關注的是第三點語言特性,因為我們要實作自己的 KM 系統,主要處理的語言會是繁體中文,所以在選擇模型時,是否支援繁體中文就變得非常關鍵。畢竟很多模型原本是用英文訓練的,如果模型沒辦法理解「蘋果 跟 Apple」其實是同一件事,那在實作時就很容易出現誤判的問題。


安裝套件

在後續的文章中,我都會使用 C# 來進行開發,在 Embedding 這個章節中會用到 Semantic Kernel、Kernel Memory 和一些 Semantic Kernel 的 Plugin,因此需要事先安裝好一些套件,本次 Lab 使用到的套件版本如下。

<PackageReference Include="Codeblaze.SemanticKernel.Connectors.Ollama" Version="1.3.1" />
<PackageReference Include="Microsoft.SemanticKernel" Version="1.47.0" />
<PackageReference Include="Microsoft.SemanticKernel.Connectors.Sqlite" Version="1.47.0-preview" />

  • Semantic Kernel:這是微軟所開發的一個開源的 SDK,可讓您輕鬆地建置 AI 代理程式,並將最新的 AI 模型整合到 C#、Python 或 Java 程式代碼基底中。 
    圖片來源 : Microsoft Semantic Kernel Overview


  • Kernel Memory:一樣是微軟提供的 SDK,此類別庫是基於 Semantic Kernel 所開發的,可以理解為 SK 的套件,提供像是檔案儲存、文字擷取、資料保護等功能,可跨平台使用,方便整合進各種應用程式或 AI 助理中,像是我們要 RAG 功能,就必須要安裝 Kernel Memory 套件,這兩個的功能比較可以參考 這個網站的 說明。
    圖片來源 : Kernel Memory Github


  • Codeblaze.SemanticKernel.Connectors.Ollama:詞嵌入套件,我們要讓 Semantic Kernel 可以去呼叫上一篇文章建立好的 Ollama Embadding API,但這邊有個小問題,由於 SK 套件內僅支援 Open AI 的介面,但偏偏 Ollama 並沒有符合這個標準,所以最差的情況需要自己實作 ITextEmbeddingGenerationService 介面來達成所需要的功能,好在有大神已經處理好這件事情了,直接安裝就行了。
  • SemanticKernel.Connectors.Sqlite:這個篇文章主要目的是要說明文字轉向量(Embedding)的功能,因此安裝 Sqlite 套件會讓我們待會比較好確認。

開始實作吧

  1. 完成上一篇文章的環境設定,並透過 docker-compose.yml 啟動我們須需要的服務。
  2. 建立一個 NetCore 8 的專案,並安裝上述三個套件後,就直接看程式吧,在使用套件的情況下,只需要短短的幾行程式碼,就可以把我們輸入的文字轉換成向量,並儲存到 Sqlite 的資料庫中了。
    internal static class Program
    {
        static async Task Main(string[] args)
        {
            var ollamaEndpoint = "http://localhost:11434";
            var ollamaEmbeddingModel = "snowflake-arctic-embed2";
            var category = "EmbeddingLab";
    
            Console.Write("請輸入要編碼的內容:");
            var text = Console.ReadLine() ?? "";
    
            var memory = await CreateSemanticTextMemoryAsync(modelId: ollamaEmbeddingModel, baseUrl: ollamaEndpoint);
    
            // 將輸入的文本儲存到 Sqlite 
            await memory.SaveInformationAsync(collection: category, text: text, id: "Demo");
        }
    
        /// <summary>
        /// 建立語意文本詞嵌入記憶體 (使用 Semantic Kernel)
        /// </summary>
        /// <param name="modelId">模型名稱</param>
        /// <param name="baseUrl">本地端 Ollama 站台 URL</param>
        /// <returns></returns>
        private static async Task CreateSemanticTextMemoryAsync(string modelId, string baseUrl)
        {
            var memory = new MemoryBuilder()
                .WithHttpClient(new HttpClient())
                .WithOllamaTextEmbeddingGeneration(modelId, baseUrl)
                .WithMemoryStore(await SqliteMemoryStore.ConnectAsync("vectors.db")) // 使用 Sqlite 作為記憶體儲存 
                .Build();
    
            return memory;
        }
  3. 執行程式,並輸入我們要轉向量的文字內容。
  4. 驗證一下執行結果,可以看到 Sqlite 資料庫內,已經把我們原本輸入的文字轉成向量,並儲存在 embedding 欄位中了(下圖綠框處)。


本文範例使用 NetCore 8,直接使用 Ollama 套件的版本,請至 EmbeddingLab 下載,如果要手動實作 ITextEmbeddingGenerationService 的版本,請至 EmbeddingLab2 下載 。


礙於篇幅的關係,本系列規劃用底下幾篇文章來說明。


參考網站

留言