OpenAI最新套娃嵌入模型分析:256維的MTEB效果超過1536維 精華
一月份,OpenAI發(fā)布了兩種新的嵌入模型:text-embedding-3-small和text-embedding-3-large。這些模型采用套娃表示學(xué)習(xí)技術(shù)(MRL:Matryoshka Representation Learning)進(jìn)行訓(xùn)練,這使得開發(fā)者可以在嵌入中權(quán)衡性能和成本。
什么是套娃表示學(xué)習(xí)?
套娃表示學(xué)習(xí)是一種用于訓(xùn)練嵌入模型的技術(shù)。它允許在犧牲少量準(zhǔn)確性的情況下?lián)Q取更小的嵌入尺寸。因此,可以以更低的成本存儲更多的信息,并更快地搜索它。
嵌入通過從序列末尾移除維度,并且只使用嵌入向量的子集維度來縮短。例如,你可以只使用原本具有1536維度向量的前8、16、32等維度(或任何其他維度的切片)。
與常見的向量嵌入不同,其中所有維度都同等重要,在套娃嵌入中,向量前面的維度存儲的信息比后面的維度更多,后者只是添加了更多細(xì)節(jié)??梢酝ㄟ^嘗試在多個(gè)分辨率下對圖像進(jìn)行分類的類比來理解這一點(diǎn):較低的分辨率提供了更多高層次的信息,而較高的分辨率則添加了更多細(xì)節(jié)。
因此,檢索性能隨著表示大小的增加而提高。然而,OpenAI報(bào)告說,text-embedding-3-large嵌入可以縮短到256的大小,同時(shí)在MTEB基準(zhǔn)測試上仍然優(yōu)于未縮短的、大小為1536的text-embedding-ada-002嵌入。
套娃嵌入的表示大小與檢索性能
MRL(Matryoshka Representation Learning,套娃表示學(xué)習(xí))實(shí)現(xiàn)的魔力全部在于訓(xùn)練這些模型時(shí)優(yōu)化的損失函數(shù)!如果之前損失函數(shù)是L,對于MRL,將損失函數(shù)分解為各個(gè)向量維度范圍上的損失之和:Loss_Total = L(upto 8d) + L(upto 16d) + L(upto 32d) + ... + L(upto 2048d)。有了這個(gè)新的嵌套損失函數(shù),模型就有動(dòng)力在向量的每個(gè)子部分捕捉信息。
修改損失函數(shù)后,可以免費(fèi)獲得這些可截?cái)嗟南蛄?,無需任何額外成本——這幾乎適用于所有損失函數(shù),并且可以對現(xiàn)有的預(yù)訓(xùn)練模型進(jìn)行微調(diào)以輸出MRL向量!這意味著MRL非常容易采用并應(yīng)用于預(yù)訓(xùn)練模型。
套娃嵌入詳細(xì)分析
下面將使用來自DBpedia的100萬個(gè)對象的數(shù)據(jù)集進(jìn)行工作,這些對象已使用新的OpenAI套娃text-embedding-3-large模型和舊的ada-002模型進(jìn)行了嵌入。這將理解信息是如何在套娃向量中與它們的非套娃前身不成比例地存儲的。
在下面的分析中,從上述數(shù)據(jù)集中隨機(jī)抽取了1萬個(gè)向量,并繪制了每個(gè)維度上觀察到的值的標(biāo)準(zhǔn)差。一個(gè)維度上看到的方差或標(biāo)準(zhǔn)差是衡量該維度相對于其他維度攜帶多少信息的良好指標(biāo)。
顯示了使用新text-emb3-large模型和舊ada-002模型嵌入的DBpedia中的10,000個(gè)隨機(jī)樣本,每個(gè)維度的標(biāo)準(zhǔn)差平滑值。
可以看到,標(biāo)準(zhǔn)差是維度索引的多步函數(shù)——早期維度捕獲更多信息,而后面的維度捕獲較少。圖表還顯示,OpenAI嵌入模型在維度={512d, 1024d, 1536d, 3072d}處使用了4個(gè)聚合損失函數(shù),按照上面詳細(xì)描述的MRL風(fēng)格進(jìn)行訓(xùn)練。
更有趣的是,這些步驟內(nèi)的信息(512d, 1024d, 1536d, 3072d)在各個(gè)維度之間或多或少地均勻擴(kuò)散。這也解釋了MRL論文中的神奇發(fā)現(xiàn),即你可以實(shí)際上取這些預(yù)指定塊之間的維度(例如750d),仍然可以獲得增量效益。?
可視化套娃向量空間
還可以問一個(gè)有趣的問題:當(dāng)你使用越來越多的套娃嵌入維度時(shí),底層數(shù)據(jù)表示/向量空間會如何變化?
下面的視頻中,每一幀都是使用僅使用一定數(shù)量的MRL向量維度的主成分分析(PCA)生成的3D向量空間。
從上面鏈接的相同數(shù)據(jù)集中取了10,000個(gè)隨機(jī)樣本,使用OpenAI text-embed-3-large模型進(jìn)行嵌入,然后使用PCA將它們縮減到3D空間;從僅使用4個(gè)維度開始,一直到使用所有3072個(gè)維度。用越來越多的維度可視化套娃向量。
可以看到,當(dāng)使用512個(gè)維度時(shí),向量空間的結(jié)構(gòu)已經(jīng)被很好地定義了,在這些最初的512個(gè)維度之后,其他維度主要用于在更大的結(jié)構(gòu)內(nèi)收緊數(shù)據(jù)表示。
當(dāng)?shù)竭_(dá)2000+維度時(shí),只看到數(shù)據(jù)點(diǎn)的小幅度抖動(dòng),可能是因?yàn)樵隽烤S度的貢獻(xiàn)微乎其微,無法在前3個(gè)主成分中看到。
熟悉 OpenAI 的 Matryoshka
OpenAI 發(fā)布了兩個(gè)新模型,text-embedding-3-small和,它們使用Matryoshka表示學(xué)習(xí)text-embedding-3-large技術(shù)進(jìn)行訓(xùn)練 。這些模型的 API 支持一個(gè)參數(shù),可以使用該參數(shù)控制生成的嵌入的長度。dimensions
如果使用相同的模型但不同的dimensions參數(shù)嵌入相同的文本,會發(fā)現(xiàn)較短的嵌入不是較長嵌入的截?cái)喟姹尽?/p>
# !pip install openai
from openai import OpenAI
openai = OpenAI()
def vectorize(text,
dimensions,
model = "text-embedding-3-small"):
text = text.lower()
return openai.embeddings.create(input = [text],
model = model,
dimensions = dimensions).data[0].embedding
example_text = "Learned representations are a central component in modern ML systems, serving a multitude of downstream tasks."
full = vectorize(example_text, dimensions = 1536)
short = vectorize(example_text, dimensions = 8)
print(full[:8])
print(short)
[-0.001463836757466197, -0.0241670124232769, 0.00683123804628849, -0.013936602510511875, 0.0320618636906147, 0.00872271228581667, 0.031053075566887856, 0.021820487454533577]
[-0.025210261344909668, -0.41620534658432007, 0.11764788627624512, -0.24001678824424744, 0.5521708130836487, 0.15022294223308563, 0.5347974300384521, 0.3757933974266052]
但是,如果檢查它們的余弦相似度,會發(fā)現(xiàn)它們非常相似(或者由于四舍五入而甚至相等)。
from sklearn.metrics.pairwise import cosine_similarity
cosine_similarity([full[:8]], [short])
array([[1.]])
如果仔細(xì)觀察,會發(fā)現(xiàn)嵌入實(shí)際上僅在縮放因子上有所不同(在本例中為 0.058)。
scale = full[0]/short[0]
print(scale)
print([x * scale for x in short])
print(full[:8])
0.05806511632065122
[-0.001463836757466197, -0.0241670118626955, 0.006831238201508919, -0.01393660272831134, 0.03206186249057062, 0.008722712614794586, 0.031053074983168057, 0.021820487334108546]
[-0.001463836757466197, -0.0241670124232769, 0.00683123804628849, -0.013936602510511875, 0.0320618636906147, 0.00872271228581667, 0.031053075566887856, 0.021820487454533577]
請注意 text-embedding-3-large 和 text-embedding-3-small 在默認(rèn)嵌入長度的長度上有所不同:
默認(rèn)尺寸text-embedding-3-small:1536
默認(rèn)尺寸text-embedding-3-large:3072
此外, 當(dāng)切片為相同尺寸時(shí),它們不會產(chǎn)生兼容的嵌入:
large = vectorize(example_text, dimensions = 3072, model = "text-embedding-3-large")
small = vectorize(example_text, dimensions = 1536, model = "text-embedding-3-small")
print(large[:1536])
print(small)
cosine_similarity([large[:1536]], [small])
[0.011070899665355682, 0.014488349668681622, -0.021118611097335815, -0.011152755469083786, 0.011555208824574947, -0.0007622754783369601, ... ]
[-0.001463836757466197, -0.0241670124232769, 0.00683123804628849, -0.013936602510511875, 0.0320618636906147, 0.00872271228581667, ... ]
array([[-0.00149749]])
如果需要在生成嵌入維度后更改嵌入維度,則需要對嵌入維度進(jìn)行規(guī)范化。OpenAI文檔對此進(jìn)行了更全面的解釋。
本文轉(zhuǎn)載自??PaperAgent??
