向量模型Jina Embedding: 从v1到v3论文笔记

文章目录

    • Jina Embedding: 从v1到v3
      • Jina Embedding v1
        • 数据集准备
        • 训练过程
      • Jina Embedding v2
        • 预训练修改版BERT
        • 在文本对上微调
        • 在Hard Negatives上微调
      • Jina Embedding v2 双语言
        • 预训练修改版BERT
        • 在文本对上微调
        • 用多任务目标微调
      • Jina Embedding v3
        • 预训练
        • 在文本对上微调
        • 训练任务相关的适配器
          • 分类适配器
          • 文本匹配适配器
          • Separation适配器
          • 非对称检索适配器
      • 参考资料

Jina Embedding: 从v1到v3

基座模型 支持语言 模型大小 编码长度 向量维度 下载链接
Jina Embedding v1 T5 英语 14M/35M/110M/330M 512 512/512/768/1024 huggingface
Jina Embedding v2 BERT 英语 33M/137M/435M 8192 512/768/1024 huggingface
Jina Embedding v3 XLM-RoBERTa 多语言 572M 8192 1024(可变大小) huggingface

Jina Embedding v1

jina embedding v1 对应的论文为2023年7月的《Jina Embeddings: A Novel Set of High-Performance Sentence Embedding Models》,在这篇论文里强调了数据清洗在数据集准备过程中很重要,一个更小但质量高的数据集比一个很大但是质量差的数据集训练的模型效果更好。

数据集准备

数据集来源包括公共数据集和自有数据集。

在数组的组织方式上,分为数据对和三元组,根据源数据集的类型分别采用不同的数据提取方法,比如QA数据集用问题作为query字符串,用答案作为目标字符串。

  • 数据对,记为 ( q , p ) ∈ D pairs (q, p) \in D_{\text{pairs}} (q,p)Dpairs,每一个数据对包括query字符串q和相关的目标字符串p。
  • 三元组,记为 ( q , p , n ) ∈ D triplets (q,p,n) \in D_{\text{triplets}} (q,p,n)Dtriplets,每一个三元组包括了query字符串q和一个匹配字符串p (positive) 和 不匹配字符串n (negative)

在准备数据对时,进行如下的清洗步骤:

  • 去重(De-Duplication):用hash函数来识别去掉重复的数据对。在检查重复数据之前将空格字符串归一化,并进行大小写转换。
  • 语言过滤(Language Filterring):用fasttext-language-identification模型只保留英文数据。
  • 一致性过滤(Consistency Filtering):去掉相似性比较低数据对。用all-MiniLM-L6-v2 model模型来进行一致性过滤:从 D pairs D_{\text{pairs}} Dpairs数据集中随机采样1M个数据对 ( q i , p i ) i (q_i, p_i)_i (qi,pi)i,并为它们生成embedding。对于数据集中的每一个数据对 ( q , p ) ∈ D pairs (q, p) \in D_{\text{pairs}} (q,p)Dpairs,检查 p p p与所有passages p i , i = 1 , … , 1 M p_i, i=1,\ldots,1M pi,i=1,,1M相比是不是与 q q q最相似的top 2(基于向量余弦相似度)。经过这一步骤后,数据集大小从1.5B减少到了385M。

数据对来源于32个数据集,过滤前的数据量为1.6 billion,过滤完之后为385 million。

在这里插入图片描述

在准备三元组数据时,没有进行去重和语言过滤步骤,但采用了与一致性过滤类似的步骤来校验“positive”元素与"query"元素的相关性:用cross-encoder模型ms-marco-MiniLM-L-6-v2来比较每一个三元组 ( q , p , n ) ∈ D triplets (q,p,n) \in D_{\text{triplets}} (q,p,n)Dtriplets的相似度 r ( q , p ) r(q,p) r(q,p) r ( q , n ) r(q,n) r(q,n),判断是否满足 r ( q , p ) − r ( q , n ) > κ r(q,p) - r(q,n) > \kappa r(q,p)r(q,n)>κ,阈值为 κ = 0.2 \kappa=0.2 κ=0.2,只保留满足阈值条件的三元组。

否定数据(Negation Data)的准备:许多向量模型对于否定含义的句子难以区分,比如对于三个句子:1. “A couple walks hand in hand down a street.”,2. “A couple is walking together.”, 3. “A couple is not walking together.” ,直觉上前面两个的向量距离应该更接近,第二个和第三个应该距离更远,但是很多模型无法区别其差异。于是Jina Embedding团队创建了一个negation数据集( [已开源](https:// huggingface.co/datasets/jinaai/negation-dataset) ),这个数据集的正样本对来自SNLI数据集,否定句由GPT-3.5生成,组成(anchor, entailment, negative)的三元组形式,与前述例子类似。(anchor, entailment)组成正样本对,“negetive"与”anchor"和“entailment”的含义都互相矛盾,但是与“entailment”的句法非常相似。这个否定数据集是前面的三元组数据集的一部分。

三元组数据在过滤前是1.13 million,过滤完之后927,000个,其分布如论文图2。

在这里插入图片描述

训练过程

训练分为两阶段:第一阶段在数据对上进行训练,使得它们的语义整合到一个语义向量上;第二阶段在相对较小的三元组数据上训练,让模型区分相似和不相似文本的区别。

Jina Embedding模型基于zero-shot T5模型的encoder训练,作者说因为它在一系列下游任务上进行了预训练所以选择它。在T5 encoder之上使用mean pooling layer由token embeddings得到固定长度的向量。

第一阶段的训练损失函数采用InfoNCE,即对一个大小为k的batch B ∈ D k B \in D^k BDk的数据对 ( q , p ) ∼ B (q, p) \sim B (q,p)B,损失函数通过比较给定问题q和目标p的余弦相似度与batch中其他目标的的相似度来计算得到:
L N C E pairs  ( B ) : = E ( q , p ) ∼ B [ − ln ⁡ e s ( q , p ) / τ ∑ i = 1 k e s ( q , p i ) / τ ] \mathcal{L}_{\mathrm{NCE}}^{\text {pairs }}(B):=\mathbb{E}_{(q, p) \sim B}\left[-\ln \frac{e^{s(q, p) / \tau}}{\sum_{i=1}^k e^{s\left(q, p_i\right) / \tau}}\right] LNCEpairs (B):=E(q,p)B[lni=1kes(q,pi)/τes(q,p)/τ]
此外作者发现在训练时计算两个方向的损失可以提高性能,即也考虑 L N C E ‾ pairs  \mathcal{L}_{\mathrm{\overline{NCE}}}^{\text {pairs }} LNCEpairs  从目标字符串去匹配所有query字符串。所以其最终损失函数如下式(温度参数取 τ = 0.05 \tau=0.05 τ=0.05):
L pairs  ( B ) : = L N C E pairs  ( B ) + L N C E ‾ pairs  ( B ) , where L N C E ‾ pairs  ( B ) : = E ( q , p ) ∼ B [ − ln ⁡ e s ( p , q ) / τ ∑ i = 1 k e s ( p , q i ) / τ ] \mathcal{L}^{\text {pairs }}(B) := \mathcal{L}_{\mathrm{NCE}}^{\text {pairs }}(B)+\mathcal{L}_{\mathrm{\overline{NCE}}}^{\text {pairs }}(B), \text{where} \\ \mathcal{L}_{\mathrm{\overline{NCE}}}^{\text {pairs }}(B):=\mathbb{E}_{(q, p) \sim B}\left[-\ln \frac{e^{s(p, q) / \tau}}{\sum_{i=1}^k e^{s\left(p, q_i\right) / \tau}}\right] Lpairs (B):=LNCEpairs (B)+LNCEpairs (B),whereLNCEpairs (B):=E(q,p)B[lni=1kes(p,qi)/τes(p,q)/τ]
在训练时,不是按顺序地在每个训练集上训练,而是同时在所有数据集上训练,但是在每一个训练batch里数据只来自单个数据集以确保损失计算时不会合并其他任务的数据。训练前每个数据集中的数据被shuffle,训练时根据采样概率 ρ ( D i ) = ∣ D i ∣ s i ∑ j = 1 n ∣ D j ∣ s j \rho (D_i)= \frac{|D_i|s_i}{\sum^n_{j=1} |D_j|s_j} ρ(Di)=j=1nDjsjDisi来采样 D i D_i Di,采样概率与数据集大小 ∣ D i ∣ |D_i| Di和缩放因子 s i s_i si决定,因为数据集大小的不一样,更频繁地从更大的数据集采样可

上一篇:PySpark任务提交


下一篇:Java中的String