🪆 Matryoshka 嵌入模型簡介

釋出於 2024 年 2 月 23 日
在 GitHub 上更新

在本篇博文中,我們將向您介紹 Matryoshka 嵌入的概念,並解釋它們為何有用。我們將討論這些模型在理論上是如何訓練的,以及您如何使用 Sentence Transformers 來訓練它們。

此外,我們將提供關於如何使用 Matryoshka 嵌入模型的實用指導,並分享 Matryoshka 嵌入模型與常規嵌入模型的比較。最後,我們邀請您體驗我們的互動式演示,它展示了這些模型的強大功能。

目錄

理解嵌入

嵌入是自然語言處理中功能最豐富的工具之一,它能幫助從業者解決各種各樣的任務。從本質上講,嵌入是一個更復雜物件(如文字、影像、音訊等)的數值表示。

embedding model

嵌入模型將始終產生固定大小的嵌入。然後,您可以透過計算相應嵌入的相似度來計算複雜物件的相似度!

embedding similarity

這有大量的用例,並構成了推薦系統、檢索、一次性或少次性學習、異常值檢測、相似性搜尋、釋義檢測、聚類、分類等的基礎!

🪆 Matryoshka 嵌入

隨著研究的進展,新的頂尖(文字)嵌入模型開始產生具有越來越高輸出維度的嵌入,即每個輸入文字都用更多的值來表示。儘管這提高了效能,但也犧牲了搜尋或分類等下游任務的效率。

因此,Kusupati 等人 (2022) 受此啟發,建立了可以合理縮小嵌入尺寸而效能不會大幅下降的嵌入模型。

matryoshka model

這些 Matryoshka 嵌入模型經過訓練,使得這些小的截斷嵌入仍然有用。簡而言之,Matryoshka 嵌入模型可以生成不同維度的有用嵌入。

🪆 俄羅斯套娃

對於不熟悉的人來說,“Matryoshka 娃娃”,也被稱為“俄羅斯套娃”,是一套大小遞減的木製娃娃,一個套一個。類似地,Matryoshka 嵌入模型旨在將更重要的資訊儲存在靠前的維度中,而將不太重要的資訊儲存在靠後的維度中。Matryoshka 嵌入模型的這一特性使我們能夠截斷模型產生的原始(大)嵌入,同時仍然保留足夠的資訊以在下游任務中表現良好。

matryoshka models

為什麼要使用 🪆 Matryoshka 嵌入模型?

這種可變尺寸的嵌入模型對從業者來說非常有價值,例如

  1. 篩選和重排序:您不必在完整的嵌入上執行下游任務(例如,最近鄰搜尋),而是可以將嵌入縮小到較小的尺寸,並非常高效地“篩選”您的嵌入。之後,您可以使用剩餘嵌入的完整維度對其進行處理。
  2. 權衡:Matryoshka 模型允許您根據所需的儲存成本、處理速度和效能來擴充套件您的嵌入解決方案。

🪆 Matryoshka 嵌入模型是如何訓練的?

理論上

Matryoshka 表示學習(MRL)方法幾乎可以應用於所有嵌入模型訓練框架。通常,嵌入模型的訓練步驟包括為您的訓練批次(例如,文字)生成嵌入,然後使用某個損失函式來建立一個代表所生成嵌入質量的損失值。最佳化器將在整個訓練過程中調整模型權重以降低損失值。

對於 Matryoshka 嵌入模型,訓練步驟也涉及為您的訓練批次生成嵌入,但隨後您使用某個損失函式來確定不僅是全尺寸嵌入的質量,還有不同維度下嵌入的質量。例如,輸出維度可以是 768、512、256、128 和 64。每個維度的損失值會相加,得到最終的損失值。然後,最佳化器將嘗試調整模型權重以降低這個損失值。

在實踐中,這激勵模型將最重要的資訊預載入到嵌入的起始部分,以便在嵌入被截斷時仍能保留這些資訊。

在 Sentence Transformers 中

Sentence Transformers 是一個常用於訓練嵌入模型的框架,它最近實現了對 Matryoshka 模型的支援。使用 Sentence Transformers 訓練 Matryoshka 嵌入模型非常簡單:我們不僅對全尺寸嵌入應用某個損失函式,還對嵌入的截斷部分應用相同的損失函式。

例如,如果一個模型的原始嵌入維度為 768,現在可以在 768、512、256、128 和 64 維度上進行訓練。這些損失中的每一個都會被加在一起,可以選擇性地加上一些權重。

from sentence_transformers import SentenceTransformer
from sentence_transformers.losses import CoSENTLoss, MatryoshkaLoss

model = SentenceTransformer("microsoft/mpnet-base")

base_loss = CoSENTLoss(model=model)
loss = MatryoshkaLoss(
    model=model,
    loss=base_loss,
    matryoshka_dims=[768, 512, 256, 128, 64],
    matryoshka_weight=[1, 1, 1, 1, 1],
)

model.fit(
    train_objectives=[(train_dataset, loss)],
    ...,
)

使用 MatryoshkaLoss 訓練並不會在訓練時間上產生顯著的開銷。

參考文獻

請參閱以下完整指令碼作為如何在實踐中應用 MatryoshkaLoss 的示例:

  • matryoshka_nli.py:此示例使用 MultipleNegativesRankingLossMatryoshkaLoss,利用自然語言推斷(NLI)資料來訓練一個強大的嵌入模型。它是 NLI 文件的改編版。
  • matryoshka_nli_reduced_dim.py:此示例使用 MultipleNegativesRankingLossMatryoshkaLoss 來訓練一個最大輸出維度為 256 的小型強大嵌入模型。它使用自然語言推斷(NLI)資料進行訓練,是 NLI 文件的改編版。
  • matryoshka_sts.py:此示例使用 CoSENTLossMatryoshkaLossSTSBenchmark 資料集的訓練集上訓練一個嵌入模型。它是 STS 文件的改編版。

如何使用 🪆 Matryoshka 嵌入模型?

理論上

在實踐中,從 Matryoshka 嵌入模型獲取嵌入的方式與常規嵌入模型相同。唯一的區別是,在接收到嵌入後,我們可以選擇將它們截斷到更小的維度。請注意,如果嵌入已經歸一化,那麼截斷後它們將不再是歸一化的,因此您可能需要重新歸一化。

截斷後,您可以直接將其應用於您的用例,或者儲存它們以便以後使用。畢竟,在您的向量資料庫中使用較小的嵌入應該會帶來相當大的速度提升!

請記住,儘管處理較小的嵌入進行下游任務(檢索、聚類等)會更快,但從模型中獲取較小嵌入的速度與獲取較大嵌入的速度一樣快。

在 Sentence Transformers 中

在 Sentence Transformers 中,您可以像載入任何其他模型一樣載入 Matryoshka 嵌入模型,但您可以使用 truncate_dim 引數指定所需的嵌入大小。之後,您可以使用 SentenceTransformers.encode 函式執行推理,嵌入將自動截斷到指定的大小。

讓我們嘗試使用我用 matryoshka_nli.pymicrosoft/mpnet-base 訓練的一個模型。

from sentence_transformers import SentenceTransformer
from sentence_transformers.util import cos_sim

matryoshka_dim = 64
model = SentenceTransformer("tomaarsen/mpnet-base-nli-matryoshka", truncate_dim=matryoshka_dim)

embeddings = model.encode(
    [
        "The weather is so nice!",
        "It's so sunny outside!",
        "He drove to the stadium.",
    ]
)
print(embeddings.shape)
# => (3, 64)

# Similarity of the first sentence to the other two:
similarities = cos_sim(embeddings[0], embeddings[1:])
print(similarities)
# => tensor([[0.8910, 0.1337]])

您可以隨意嘗試使用不同的 matryoshka_dim 值,並觀察這如何影響相似性。您可以在本地執行此程式碼,也可以在雲端(如 Google Colab)執行,或者檢視演示

參考文獻

點選此處檢視如何使用 Nomic v1.5 Matryoshka 模型

注意:Nomic 特別要求在嵌入截斷之前進行 F.layer_norm。因此,以下程式碼片段使用手動截斷到所需維度。對於所有其他模型,您可以在建構函式中使用 truncate_dim 選項,如前一個示例所示。

from sentence_transformers import SentenceTransformer
from sentence_transformers.util import cos_sim
import torch.nn.functional as F

model = SentenceTransformer("nomic-ai/nomic-embed-text-v1.5", trust_remote_code=True)

matryoshka_dim = 64
embeddings = model.encode(
    [
        "search_query: What is TSNE?",
        "search_document: t-distributed stochastic neighbor embedding (t-SNE) is a statistical method for visualizing high-dimensional data by giving each datapoint a location in a two or three-dimensional map.",
        "search_document: Amelia Mary Earhart was an American aviation pioneer and writer.",
    ],
    convert_to_tensor=True,
)
# The Nomic team uses a custom architecture, making them recommend Layer Normalization before truncation
embeddings = F.layer_norm(embeddings, normalized_shape=(embeddings.shape[1],))
embeddings[..., :matryoshka_dim]  # Shrink the embedding dimensions

similarities = cos_sim(embeddings[0], embeddings[1:])
# => tensor([[0.7154, 0.4468]])

結果

既然已經介紹了 Matryoshka 模型,讓我們來看看 Matryoshka 嵌入模型與常規嵌入模型相比,我們可能期望的實際效能。為了這個實驗,我訓練了兩個模型

這兩個模型都在 AllNLI 資料集上進行了訓練,該資料集是 SNLIMultiNLI 資料集的拼接。我已經在 STSBenchmark 測試集上使用多個不同的嵌入維度評估了這些模型。結果繪製在下圖中

results

在上圖中,您可以看到 Matryoshka 模型在所有維度上都達到了比標準模型更高的斯皮爾曼相似度,這表明 Matryoshka 模型在此任務中更優越。

此外,Matryoshka 模型的效能下降速度比標準模型慢得多。這在第二張圖中清晰地顯示出來,該圖顯示了嵌入維度相對於最大效能的效能。即使在嵌入大小為 8.3% 的情況下,Matryoshka 模型仍保留了 98.37% 的效能,遠高於標準模型的 96.46%。

這些發現表明,透過 Matryoshka 模型截斷嵌入可以:1) 顯著加快檢索等下游任務的速度,2) 顯著節省儲存空間,而效能沒有明顯下降。

演示

在這個演示中,您可以動態地縮小 nomic-ai/nomic-embed-text-v1.5 Matryoshka 嵌入模型的輸出維度,並觀察它如何影響檢索效能。所有的嵌入都是在瀏覽器中使用 🤗 Transformers.js 計算的。

參考文獻

社群

@tomaarsen ,

很棒的文章!關於歸一化:應該在截斷之前還是之後進行?

·

好問題!嵌入應該在 Matryoshka 截斷之後進行(重新)歸一化。如果你只在截斷前進行歸一化,截斷後的部分將不會有確切的期望均值和標準差,而是會有一點點偏差。

感謝分享(評論有點晚,哈哈),我對非 Matryoshka 嵌入的魯棒性感到相當驚訝,是我理解錯了嗎?

·

我也覺得很驚訝,這真是個很酷的副作用。你會在《Matryoshka Representation Learning》的第5頁找到類似的支援性結果。事實上,那頁的圖表表明,MRL-E/tied MRL 在低維度上的表現不如他們的 FF 模型,更不用說,他們的基線和 MRL 之間的差異並不大(在那些特定的圖表中)。有趣的是,Sentence Transformers 實現的是 MRL-E/tied MRL,而不是 untied MRL。

@tomaarsen 的結果似乎有很大不同,因為 MRL-E 勝過了沒有 MRL 的情況。

你們覺得將 MRL 引入像 BAAI/bge-m3 這樣的模型有意義嗎?

註冊登入 以發表評論

© . This site is unofficial and not affiliated with Hugging Face, Inc.