向量模型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 B∈Dk的数据对 ( 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[−ln∑i=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[−ln∑i=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=1n∣Dj∣sj∣Di∣si来采样 D i D_i Di,采样概率与数据集大小 ∣ D i ∣ |D_i| ∣Di∣和缩放因子 s i s_i si决定,因为数据集大小的不一样,更频繁地从更大的数据集采样可以防止过拟合,用缩放因子来优先在高质量数据集上训练并且可以平衡文本领域。训练时如果一个数据集的样本消耗完了,数据集会被重置,模型可以重新从这个数据集获取数据来训练,确保了高采样率数据集在单个训练epoch中可以贡献多次。论文图1b是基于采样率的每个数据集的比例。
作者经过试验发现在训练第二阶段最好的结果是通过组合多个常用tuiplet loss 函数得到的(温度参数取 τ = 0.05 \tau=0.05 τ=0.05):InfoNCE损失函数的使用了额外负例的扩展版本 L N C E + triplets \mathcal{L}_{\mathrm{NCE+}}^{\text {triplets }} LNCE+triplets (式2),与第一阶段一样的反向InfoNCE损失函数 L N C E ‾ triplets \mathcal{L}_{\mathrm{\overline{NCE}}}^{\text {triplets }} LNCEtriplets (式3),triplet margin损失函数 L 3 triplets \mathcal{L}_{3}^{\text {triplets }} L3triplets (式4), ϵ = 0.05 \epsilon=0.05 ϵ=0.05 。
L triplets ( B ) : = L N C E + triplets ( B ) + L N C E triplets ( B ) + L 3 triplets ( B ) , where ( 1 ) L N C E + triplets ( B ) : = E ( q , p , n ) ∼ B [ − ln exp ( s ( q , p ) / τ ) ∑ i = 1 k exp ( s ( q , p i ) / τ ) + exp ( s ( q , n i ) / τ ) ] ( 2 ) L N C E ‾ triplets ( B ) : = E ( q , p , n ) ∼ B [ − ln exp ( s ( p , q ) / τ ) ∑ i = 1 k exp ( s ( p , q i ) / τ ) ] ( 3 ) L 3 triplets ( B ) : = E ( q , p , n ) ∼ B [ ReLU ( s ( q , n ) − s ( q , p ) + ε ) ] . ( 4 ) \begin{aligned} & \mathcal{L}^{\text {triplets }}(B):=\mathcal{L}_{N C E+}^{\text {triplets }}(B)+\mathcal{L}_{\mathrm{NCE}}^{\text {triplets }}(B)+\mathcal{L}_3^{\text {triplets }}(B), \quad \text { where } \qquad (1) \\ & \mathcal{L}_{N C E+}^{\text {triplets }}(B):=\mathbb{E}_{(q, p, n) \sim B}\left[-\ln \frac{\exp (s(q, p) / \tau)}{\sum_{i=1}^k \exp \left(s\left(q, p_i\right) / \tau\right)+\exp \left(s\left(q, n_i\right) / \tau\right)}\right] \qquad (2) \\ & \mathcal{L}_{\mathrm{\overline{NCE}}}^{\text {triplets }}(B):=\mathbb{E}_{(q, p, n) \sim B}\left[-\ln \frac{\exp (s(p, q) / \tau)}{\sum_{i=1}^k \exp \left(s\left(p, q_i\right) / \tau\right)}\right] \qquad (3)\\ & \mathcal{L}_3^{\text {triplets }}(B):=\mathbb{E}_{(q, p, n) \sim B}[\operatorname{ReLU}(s(q, n)-s(q, p)+\varepsilon)] . \qquad (4) \end{aligned} Ltriplets (B):=LNCE+triplets (B)+LNCEtriplets (B)+L3triplets (B), where (1)LNCE+triplets (B):=E(q,p,n)∼B[−ln∑i=1kexp(s(q,pi)/τ)+exp(s(q,ni)/τ)exp(s(q,p)/τ)](2)LNCEtriplets (B):=E(q,p,n)∼B[−ln∑i=1kexp(s(p,qi)/τ)exp(s(p,q)/τ)](3)L3triplets (B):=E(q,p,n)∼B[ReLU(s(q,n)−s(q,p)+ε)].(4)
训练的超参数如论文表5.
Jina Embedding v2
Jina Embedding v2 对应的论文是2023年10月的《Jina Embeddings 2: 8192-Token General-Purpose Text Embeddings for Long Documents》,Jina Embedding v2的主要特点是可以对长达8192 token的文本进行向量编码,长文本上下文窗口是通过AliBi来实现的。
Jina Embedding v2 的训练过程分为3个阶段:1. 预训练一个修改的BERT,2. 在文本对数据上微调,3. 在Hard Negatives上微调。第2和第3阶段是针对embedding任务来进行微调的,与其他论文的结论有一样,第三阶段对于提升模型在检索和分类任务上的性能很关键。
预训练修改版BERT
对BERT模型做一些修改,而训练过程主要采用RoBERTa所描述的方法。
模型架构:
- 对自注意力机制使用ALiBi方法,因为原始的ALiBi是为因果语言建模设计的,所以其特征bias只在一个方向,所以在encoder模型里应用了ALiBi的修改版,如论文图1所示意。
- 对注意力模块的前向传播子层使用GLU(Gated Linear Units): 对于small和base模型,使用GEGLU,对于large模型使用ReGLU(这个选择也与其他论文一致说对于large模型使用GEGLU不稳定)。
- 对于Layer Normalixation,使用与transformer的原论文《attention is all you need》一样的post-layer normalization。
训练数据:使用C4(Colossal, Cleaned, Common Crawl)数据集来进行预训练,只保留了英文语料。
训练算法:
- 去掉BERT里的下句预测任务(next sentence predictin, NSP)
- 使用whole word masking, 随机mask掉30%的输入词元(token)。在这些被mask掉的token中,80%用[MASK] token替换,10%用随机token替换,10%保持不变。
- 损失函数使用Masked Language Model 损失函数
- 训练时文本最大长度为512。样本处理上不会将多个文档的数据堆叠到一起组成长文本,也会避免从一个文档中采样多个文本序列,对每一个文档,只考虑前512个token而裁剪掉剩下的文本。
- 使用AdamW优化器, β 1 = 0.9 , β 2 = 0.98 , ϵ = 1 e − 6 \beta_1=0.9, \beta_2=0.98, \epsilon=1e-6 β1=0.9,β2=0.98,ϵ=1e−6, weight decay为0.01,dropout rate为0.1, attention的dropout也为0.1。learning rate schedule为线性的,从0开始,在10000步时达到 η \eta η(对small、base、large模型的 η \eta η取值分别为1e-3, 6e-4,4e-4),在达到100000步后学习率逐渐线性衰减到0。
- 通常DeepSpeed来实现FP16动态混合精度,而作者说初步测试表明BF16会导致不满意的性能指标。
在文本对上微调
文本向量通过在所有token embedding上加mean pooling层得到。
训练数据:与Jina Embedding v1的文本对准备数据流程一致,包括了40种不同来源数据,观察到数据集中包括title-abstract对可以显著提升向量模型在聚类任务上的性能。在数据上的采样策略也与Jina Embedding v1一致。
损失函数:与Jina Embedding v1一致。
在Hard Negatives上微调
这一阶段的主要目的是提高模型的排序能力,所以是在包含负样本的数据集来训练的。
训练数据:数据集包括检索数据集如MSMarco, NQ(Natural Questions),以及多个非检索数据集如Natural Language Inference(NLI)。对于每一个训练样本,记为 ( q , p , n 1 , … , n 15 ) (q, p, n_1, \ldots, n_{15}) (q,p,n1,…,n15),即包括1个正样本和15个负样本。对于检索数据集,难负样本由检索模型判断与p相似而得到,即指导模型优先相关文档而不仅仅是语义相关;对于非检索数据集,负样本是随机选择的,因为在正样本和负样本之间画一条清晰的线并不可行。判断是否相关时,使用cross-encoder模型来判断。
损失函数:修改后的InfoNCE损失函数
L NCE + ( B ) : = E r ∼ B [ − ln e s ( q , p ) / τ ∑ i = 1 k [ e s ( q , p i ) / τ + ∑ j = 1 15 e s ( q , n j , i ) / τ ) ] ] + E r ∼ B [ − ln e s ( p , q ) / τ ∑ i = 1 k e s ( p , q i ) / τ ] with r = ( q , p , n 1 , … , n 15 ) \mathcal{L}_{\text{NCE}+}(B):=\mathbb{E}_{r \sim B} \left[ -\ln \frac{e ^{s(q, p) / \tau}} {\sum_{i=1}^k [ e^{s(q, p_i) / \tau}+ \sum^{15}_{j=1} e^{s(q, n_{j,i})/ \tau)}]} \right] + \qquad \\ \mathbb{E}_{r \sim B}\left[-\ln \frac{e^{s(p, q) / \tau}}{\sum_{i=1}^k e^{s\left(p, q_i\right) / \tau}}\right] \\ \text{with} \ r=(q, p, n_1,\ldots, n_{15}) LNCE+(B):=Er∼B[−ln∑i=1k[es(q,pi)/τ+∑j=115es(q,nj,i)/τ)]es(q,p)/τ]+Er∼B[−ln∑i=1kes(p,qi)/τes(p,q)/τ]with r=(q,p,n1,…,n15)
在这两个阶段进行微调训练时,大的batch size是更优的,为了节省内存,利用deepspeed实现混合精度训练,此外使用Activation checkpointing技术,在模型的每一个BERT层插入checkpoint。
Jina Embedding v2 双语言
Jina Embedding v2双语言模型对应的论文为2024年2月的《Multi-Task Contrastive Learning for 8192-Token Bilingual Text Embeddings》,这一篇里讲了用相对小的模型实现英语和另一个目标语言(如德语、中文、西班牙语)的双语向量编码。
与Jina Embedding v2一样,训练过程分为3个阶段:1. 预训练一个修改的BERT,2. 在文本对数据上微调,3. 用多任务目标(Multi-Task Objective)来微调。
预训练修改版BERT
模型架构: 与Jina Embedding v2一样。对西班牙语模型,对key和query向量引入了一个normalization来解决训练不稳定性,这个方法与QK-normalization有点关联,但不完全一样。子词分词器使用BPE分词器,并使得词汇表大小比jina Embedding v2的单语言版扩展了一倍,所以base模型的参数增加了一些(从137M到161M)。
训练数据:数据来源有CulturaX, Wikipedia, Opus,经过清洗后得到250M英文文本和相同数量的目标语言文本,留了1%的数据用作验证集。
训练算法:与Jina Embedding v2基本一样,因为训练数据包括双语言,所以在每一个batch的数据是单语言。
在文本对上微调
文本向量通过在所有token embedding上加mean pooling层得到,在训练节省内存的策略上也与Jina Embedding v2保持一致。
训练数据:
- 收集了211million德文、111million西班牙语、518million英语文本对(有点奇怪为什么没有提到中文数据量)。数据集中主要数据都是单语言文本对(97.5%),主要是(标题, 文章)、(问题, 回答)、(文本, 文本总结);其余的是双语言文本对,即包括用两种语言表示的相同含义文本,构成了用来桥接英语和其他语言的平行语料。
- 数据集来源包括MQA、XL-Sum、XNLI、 MLSum、Europarl。此外为了多样性和数据量,用Common Crawl数据闯将了两种类型的文本对:1. 网页title和内容;2. 从FAQ和相关页面挖掘question-answer对。从Wikipedia获取段落和对应的章节标题。
- 通过两阶段处理策略来提高数据质量: 过滤阶段通过一些质量检查实现,比如将非常短的文本、非常长的文本、重复行很多的文本给删除;在改进阶段不删除文本,只进行包括去掉网址相关的元数据、去掉未结束的行、只有一个单词的行等的操作。
- 为进一步提高数据集质量,使用near-depuplication方法去除重复数据,使用Jina Embedding v1里用过的一致性过滤方法过滤不一致的文本对
损失函数: 与Jina Embedding v1一致。
用多任务目标微调
在之前的文献以及Jina Embedding v1和v2都表明第三阶段的在难负样本上的微调可以提高模型的排序能力,所以在这篇论文里将这个概念扩展为多任务训练阶段。
对于不同的任务一般有不同的格式,比如STS任务包含三元组(q,p, t),即两个文本q和p以及他们的相似分数t。而对于检索任务通常包括query q和一个或多个相关文档p以及可选的不相关文档n。所以对于每一个任务,定义自己的损失函数,在这篇论文中,只考虑STS任务和检索任务。在每个batch,采样一个数据集,根据数据集任务类型来选择相应的损失函数。
训练数据:检索任务与Jina Embedding v2类似,STS任务数据集包括SemEval等。因为英文数据的高质量数据更多,所以使用机器翻译将一些数据集翻译成目标语言。为了增加数据多样性和减少仅由翻译数据副作用的影响,还挑选了一些目标语言的数据集。
损失函数:检索任务的损失函数与Jina Embedding v2第三阶段的损失函数一样。STS数据集的损失函数采用negative Pearson’s sample correlation,设一个batch B包括文本对(q, p)和对应的相关分数t,其计算如下式:
L S T S ( B ) : = − c o v ( q , p , t ) ∼ B ( s ( q , p ) , t ) σ s ( B ) σ t ( B ) \mathcal{L}_{STS}(B) := - \frac{cov_{(q,p,t) \sim B } (s(q, p), t)}{\sigma_s(B) \sigma_t(B)} LSTS(B):=−σs(B)σt(B)cov(q,p,t)∼B(s(q,p),t)
上式中, σ s \sigma_s σs和 σ t \sigma_t σt是估计的s(q,p)和t的标准差,在一个batch内计算得到,而上式中的协方差是跨批次B计算得到的。作者说基于相关性的损失函数可行的原因是它考虑相似性分数的大小而不是二元相关性,选择Pearson相关系数是因为它对相似度值的尺度是不变的。作者假定这可以使包含InfoNCE损失函数的多任务训练更稳定。
Jina Embedding v3
Jina Embedding v3 对应的论文为2024年9月的《jina-embeddings-v3: Multilingual Embeddings With Task LoRA》,它是一个多语言文本向量模型,可处理最多8192个token长度的文本,使用任务相关的LoRA适配器来生成检索、聚类、分类、文本匹配任务对应的向量,向量的默认大小为1024,因为使用了Matryoshka Representation Learning技术,用户可灵活地改变向量大小。(此外论文强调Jina embedding v3比v2和v2双语效果好很多,并且在MTEB的评估上在英文任务上超过了OpenAI和Cohere的私有向量模型,且比基于LLM的向量模型的大小小很多)
Jina Embedding v3的架构如论文图1所示
Jina Embedding v3的训练过程也分为3个阶段:1. 预训练XLM-RoBERTa,2. 在文本对数据上微调,3. 训练了任务相关的LoRA适配器。
预训练
模型:使用XLM-RoBERTa模型的参数来初始化模型,但是将位置编码修改为RoPE,保留了XLM-RoBERTa的tokenizer。训练目标为使用全词mask的MLM。
训练数据: CulturaX语料集,它包括89种语言的数据,其中英语大概占20%。每一个batch只包含一种语言,但是不同batch之间的语言是交替的。
在训练的前100000步文本序列长度被裁剪到512个token,在后60000步文本序列长度被裁剪到8192个token同时使用更小的batch size,具体超参见表A1。在训练时RoPE的旋转频率是10000,在推理时调整到20000有助于提升模型在长文本上的能力,但是作者发现这个调整后模型的长文本能力不及jina embedding v2,所以在训练时将模型在更长的文本上进行了训练,经过长文本训练之后jina embedding v3的长文本能力更强。
在文本对上微调
文本向量与之前系列模型一致,通过在所有token embedding上加mean pooling层得到。
损失函数:与jina embedding v2双语言一致。
训练数据:从超过300个数据集收集得到,训练时每个batch采样自一个特定数据集。数据集准备方法与jina embedding v2双语言一致,只是多了一个过滤步骤:将短文本里至少有80%的内容属于长文本的子字符串的文本对给去掉了,这个过滤可以增加训练的难度。
与预训练过程一样,先在短文本对上训练,接着用更小的batch size来训练更长的文本序列(这时只有包含足够多的长文本数据的数据集)
训练任务相关的适配器
在这一阶段训练了在四个任务上的五个不同LoRA适配器,如论文表2所示。训练时这些任务是独立训练的,基座模型参数是被冻结的。在推理时,用户根据下游任何和输入内容角色选择合适的适配器。
分类适配器
分类适配器为下游分类任务特别是逻辑回归分类器生成向量,为训练适配器,采用Gecko向量模型提出的分类训练方法。
数据集包括常见分类任务,包括情感分析、意图分类、文章类别。对每一个数据集,选择属于同一个类别的2个文本值(q,p)和7个不同类别的文本 ( n 1 , … , n 7 ) (n_1, \ldots, n_7) (n1,…,n7),构建包含9个文本的元祖 ( q , p , n 1 , … , n 7 ) (q,p,n_1,\ldots,n_7) (q,p,n1,…,n7),模型的训练目标是为q和p分配高的余弦相似度,同时使q和其他 n i n_i ni的余弦相似度很低。每一个batch的元祖来自同一个数据集。
损失函数与Jina Embedding v2一样,是InfoNCE的扩展版本,考虑了额外的负样本。
L triplet ( B ) : = E r ∼ B [ − ln e s ( q , p ) / τ ∑ i = 1 k [ e s ( q , p i ) / τ + ∑ j = 1 m e s ( q , n j , i ) / τ ) ] ] + E r ∼ B [ − ln e s ( p , q ) / τ ∑ i = 1 k e s ( p , q i ) / τ ] with r = ( q , p , n 1 , … , n m ) \mathcal{L}_{\text{triplet}}(B):=\mathbb{E}_{r \sim B} \left[ -\ln \frac{e ^{s(q, p) / \tau}} {\sum_{i=1}^k [ e^{s(q, p_i) / \tau}+ \sum^{m}_{j=1} e^{s(q, n_{j,i})/ \tau)}]} \right] + \qquad \\ \mathbb{E}_{r \sim B}\left[-\ln \frac{e^{s(p, q) / \tau}}{\sum_{i=1}^k e^{s\left(p, q_i\right) / \tau}}\right] \\ \text{with} \ r=(q, p, n_1,\ldots, n_{m}) Ltriplet(B):=Er∼B[−ln∑i=1k[es(q,pi)/τ+∑j=1mes(q,nj,i)/τ)]es(q,p)/τ]+Er∼B[−ln∑i=1kes(p,qi)/τes(p,q)/τ]with r=(q,p,n1,…,nm)
在使用这个损失函数时,在同一个batch里与 q i q_i qi来自相同类别的文本 p j ( i ≠ j ) p_j (i \neq j) pj(i=j)被当做负样本,这可能会造成假负例,所以Gecko向量模型是每一个文本一个唯一id值,允许模型区分batch里文本的差别,就可以避免掉假负例。
文本匹配适配器
文本匹配适配器为量化两个文本之间的相似性而生成向量,可应用与语义文本相似性(sementic textual similarity, STS)和对称性检索任务(即query和target之间的区别不明显)。
训练数据包括STS训练数据集如STS12、SICK,这些数据集包括三元组 ( q i , p i , t i ) ∈ D (q_i, p_i, t_i) \in D (qi,pi,ti)∈D,即文本对 ( q i , p i ) (q_i, p_i) (qi,pi)以及他们的相关分数 t i t_i ti。一个batch B包含指定数量的三元组,ground truth相似度定义为 ζ ( q i , p i ) = t i \zeta(q_i, p_i) = t_i ζ(qi,pi)=ti。为了模型在跨语言的表现,使用机器翻译模型如WMT19和MADLAD-3B将STS12和SICK翻译到了多种语言。此外还将natural language inference (NLI) 数据集包括进来了。每个batch中也只包含了一个数据集的数据,并使用相应的损失函数(没提NLI数据集的损失函数是什么,用InfoNCE?)。
损失函数使用了苏剑林提出的CoSent loss:
L c o ( B ) : = l n [ 1 + ∑ ( q 1 , p 1 ) , ( q 2 , p 2 ) ∈ B e s ( q 2 , p 2 ) − e s ( q 1 , p 1 ) τ ] where ζ ( q 1 , p 1 ) > ζ ( q 2 , p 2 ) \mathcal{L}_{co} (B) := ln \left[ 1 + \sum_{(q_1,p_1),(q_2,p_2) \in B} \frac {e^{s(q_2,p_2)} - e^{s(q_1, p_1)}}{\tau} \right] \\ \text{where} \ \zeta(q_1, p_1) > \zeta(q_2, p_2) Lco(B):=ln 1+(q1,p1),(q2,p2)∈B∑τes(q2,p2)−es(q1,p1) where ζ(q1,p1)>ζ(q2,p2)
CoSent loss 在两个文本对上进行运算,要求数据集里标注ground truth相似度 ζ \zeta ζ。
Separation适配器
分离适配器(Separation Adapter)是为聚类和重排序任务设计的(对重排序任务是将相关文档和不相关文档给分开)。
损失函数是CoSent loss的变体,训练数据 B ′ B^{\prime} B′由元组 ( x , l ) ∈ B ′ (x, l) \in B^{\prime} (x,l)∈B′组成,x是文本,l是它对应的标签。为了组成匹配 L c o \mathcal{L}_{co} Lco 的文本对,在一个batch里生成同一个标签 l i l_i li的所有文本对组合。最终的分离损失定义如下:
L s e p ( B ′ ) : = L c o ( B ) B = { ( x i , x j ) ∣ ∃ l : ( x i , l ) , ( x j , l ) ∈ B ′ } \mathcal{L}_{sep}(B^{\prime}) := \mathcal{L}_{co}(B) \\ B = \{(x_i, x_j)| \exists l:(x_i, l),(x_j, l) \in B^{\prime} \} Lsep(B′):=Lco(B)B={(xi,xj)∣∃l:(xi,l),(xj,l)∈B′}
因为满足要求的训练数据不多,所以在这一阶段还混合了训练第二阶段的文本对数据(训练损失也是第二阶段的损失),在每一个训练步,特定数据集被采样并使用相应的损失函数。
非对称检索适配器
与E5对应的论文一样,使用两个不同的前缀加在query和document后,并且同时(joinly)训练两个不同的适配器。
训练数据为包含hard negatives的数据集如MS-MARCO和Natural Questions(NQ),目的是为了让模型能够专注于细微的区别并区分相关文档和相似但不相关文档。而对于没有难负例的检索数据集使用RocketQA v2和E5论文中使用的方法用BGE-large和BM25来挖掘难负例。
损失函数是与分类适配器一样的 L triplet \mathcal{L}_{\text{triplet}} Ltriplet。
在对Jina embedding v2在非对称检索任务上进行错误分析时,发现了以下影响检索任务的点:
- F1. Misleading Syntactic Similarities: Documents with high syntactic similarity to the query are often favored over gold/relevant documents with lower syntactic overlap.
- F2. Misinterpretation of Named Entities:Named entities are frequently not recognized as such, leading to documents being marked as relevant based on partial matches (e.g., “Sofia Albert” vs. “Albert Stone”). This occurs especially with proper nouns that have alternative, more common meanings (e.g., the novel title “The Company” vs. “the company”).
- F3. No Understanding of Polar Questions:Complex yes-no (polar) questions are not handled effectively. As a result, the model retrieves documents with related content that do not necessarily answer the query.
- F4. Preference for Low-Quality Documents:jina-embeddings-v2 and many other embedding models do not account for document quality, focusing solely on similarity and relevance. Consequently, low-quality documents(short, repetitive, or uninformative) that mention query terms are often retrieved but do not provide satisfactory answers.
为了减轻F1-F3,设计了prompt生成与这些特定失败案例匹配的文本例子,每个例子包括一个query文本,一个优选答案,7个表示失败案例的负样本。
对于F4,利用了Open Assistant项目的数据集oasst1和oasst2,这些数据集包括由LLM生成的问题和答案,以及由人工判定的质量分数(0-1)。将这些数据集通过选择有至少两个回答的query来转变成难负例训练数据。质量最高的回答被当做正匹配样本,而分数低于0.3质量分的回答作为负样本,如果少于七个负样本,剩下的负样本通过从其他query里随机选择得到。
论文表6是应用这些合成数据后的实验结果。
参考资料
- jina embedding 发布博客:v1, v2, v2双语, v3
- jina embedding模型对应的论文,如文中链接。
相关文章:

向量模型Jina Embedding: 从v1到v3论文笔记
文章目录 Jina Embedding: 从v1到v3Jina Embedding v1数据集准备训练过程 Jina Embedding v2预训练修改版BERT在文本对上微调在Hard Negatives上微调 Jina Embedding v2 双语言预训练修改版BERT在文本对上微调用多任务目标微调 Jina Embedding v3预训练在文本对上微调训练任务相…...

Spring学习笔记(一)
一 、Spring概述 (一)Spring是什么 Spring是一个分层的Java SE/EE full-stack(一站式)轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面…...

Java编程基础
Java是一种广泛使用的编程语言,以其跨平台兼容性、面向对象的特性和健壮的安全性而闻名。本篇文章将带你了解Java编程的基础知识。 Java简介 Java是由Sun Microsystems(现在是Oracle Corporation的一部分)在1995年发布的。它是一种静态类型…...

C++【string类,模拟实现string类】
🌟个人主页:落叶 🌟当前专栏: C专栏 目录 为什么学习string类 C语言中的字符串 标准库中的string类 auto和范围for auto关键字 迭代器 范围for string类的常用接口说明和使用 1. string类对象的常见构造 2.string类对象的容量操作 3…...

Jupyter lab 打开时默认使用 Notebook 而不是浏览器
Jupyter lab 打开时默认使用 Notebook 而不是浏览器 正文 正文 今天遇到了一个特别有意思的事情,这里我们以 Windows \textrm{Windows} Windows 系统举例。 我们知道通常我们需要使用如下代码在 Terminal \textrm{Terminal} Terminal 中打开 Jupyter lab \textr…...

【linux】ubunda repo是什么
Ubuntu repo(repository,简称repo)是一个软件仓库,它是存储和分发软件包的服务器或一组服务器。通俗地说,Ubuntu repo就像一个巨大的在线软件商店,用户可以从中下载和安装各种软件。 主要特点 软件集合&a…...

【MySQL】深层理解索引及特性(重点)--下(12)
索引(重点) 1. 索引的作用2. 索引操作2.1 主键索引2.1.1 主键索引的特点2.1.2 创建主键索引 2.2 唯一键索引2.2.1 唯一键索引的特点2.2.2 唯一索引的创建 2.3 普通索引2.3.1 普通索引的特点2.3.2 普通索引的创建 2.4 全文索引2.4.1 全文索引的作用2.4.2 …...

无人机声学侦测算法详解!
一、算法原理 无人机在飞行过程中,其电机工作、旋翼震动以及气流扰动等都会产生一定程度的噪声。这些噪声具有独特的声学特征,如频率范围、时域和频域特性等,可以用于无人机的检测与识别。声学侦测算法利用这些特征,通过一系列步…...

git 提交仓库
创建 git 仓库: mkdir pySoundImage cd pySoundImage git init touch README.md git add README.md git commit -m “first commit” git remote add origin https://gitee.com/hunan-co-changsha-branch/pytest.git git push -u origin master 已有仓库ÿ…...

基于大语言模型(LLM)自主Agent 智能体综述
近年来,LLM(Large Language Model)取得了显著成功,并显示出了达到人类智能的巨大潜力。基于这种能力,使用LLM作为中央控制器来构建自助Agent,以获得类人决策能力。 Autonomous agents 又被称为智能体、Agent。指能够通过感知周围环境、进行规划以及执行动作来完成既定任务。…...

使用命令行管理 Windows 环境变量
1. 使用命令提示符 (CMD) 1.1. 设置环境变量 添加或修改临时环境变量(当前会话有效) set MY_VARvalue添加或修改用户环境变量 setx MY_VAR "value"添加或修改系统环境变量(需要管理员权限): setx /M MY…...

AUTODL配置百度网盘数据传输
AUTODL使用 1.配置百度网盘开放平台 2.接入并创建应用 3.创建应用 4.添加授权...

LeetCode46. 全排列(2024秋季每日一题 57)
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示例 2: 输入:nums …...

SpringBoot新闻稿件管理系统:架构与实现
3系统分析 3.1可行性分析 通过对本新闻稿件管理系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本新闻稿件管理系统采用SSM框架,JAVA作为开发语…...

MinIO讲解和java应用案例示范
一、MinIO 基本概念 1.1 什么是 MinIO? MinIO 是一个高性能的对象存储服务器,专为云原生应用设计。它支持 Amazon S3 API,因此可以与现有的 S3 客户端和工具集成。MinIO 主要用于存储非结构化数据,如图片、视频、备份文件和日志…...

区块链技术与应用 【全国职业院校技能大赛国赛题目解析】第1套 区块链系统设计与运维部分
模块一:区块链产品方案设计及系统运维(35分) 选手完成本模块的任务后,将任务中设计结果、运行代码、运行结果等截图粘贴至客户端桌面【区块链技术应用赛\重命名为工位号\模块一提交结果.docx】中对应的任务序号下。 前述: 我们收到答案后,将针对比赛的答案和样题进行解…...

yaml文件编写
Kubernetes 支持YAML和JSON格式管理资源 JSON 格式:主要用于 api 接口之间消息的传递 YAML 格式;用于配置和管理,YAML是一种简洁的非标记性语言,内容格式人性化容易读懂 一,yaml语法格式 1.1 基本语法规则 使用空格进行缩进(不使用制表符࿰…...

TOEIC 词汇专题:娱乐休闲篇
TOEIC 词汇专题:娱乐休闲篇 在娱乐和休闲活动中,我们会接触到许多特定的词汇。这些词汇涉及到活动入场、观众互动、评论等各个方面,帮助你在相关场景中更加自如。 1. 入场和观众 一些常用词汇帮助你轻松应对观众与入场管理相关的场景&#…...

驱动TFT-1.44寸屏(ST7735)显示器
目录 一、驱动芯片介绍 二、驱动方式 三、主函数main运行 四、完整代码下载 TFT1.44寸屏,搭配ST7735驱动芯片,是一种专为小型电子设备设计的彩色液晶显示解决方案。该屏幕采用薄膜晶体管(TFT)技术,能够实现高亮度、…...

鸿蒙HarmonyOS NEXT一多适配技术方案
鸿蒙一多是什么 HarmonyOS 系统面向多终端提供了“一次开发,多端部署”(后文中简称为“一多”)的能力,让开发者可以基于一种设计,高效构建多端可运行的应用。 一套代码工程,一次开发上架,多端按…...

golang 中map使用的一些坑
golang 中map使用的一些坑 1、使用map[string]interface{},类型断言[]int失败 接收下游的数据是用json转为map[string]any go a : "{\"a\":\"1\",\"b\":[123]}" var marshal map[string]any json.Unmarshal([]byte(a), &…...

cordova 离线打包Android -Linux
背景 已有 cordova 运行环境的docker镜像; 需要在离线环境下执行 cordova 从创建项目到构建安装包一系列命令,最终生成 apk 文件。 方案 先在有网环境(最好与离线环境的OS一致)走一遍 cordova 创建打包工程、添加插件、添加平…...

【python】OpenCV—findContours(4.3)
文章目录 1、功能描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数5.1、cv2.Canny5.2 cv2.boxPoints 6、参考 1、功能描述 找出图片中的轮廓,拟合轮廓外接椭圆和外接矩阵 2、代码实现 导入必要的库,固定好随机种子 import cv2 as cv import …...

前端通过nginx部署一个本地服务的方法
前端通过nginx部署一个本地服务的方法: 1.下载ngnix nginx 下载完成后解压缩后运行nginx.exe文件 2.打包你的前端项目文件 yarn build 把生成的dist文件复制出来,替换到nginx的html文件下 3.配置conf目录的nginx.conf文件 主要配置server监听 ser…...

Linux:防火墙和selinux对服务的影响
1-1selinux 1-1 SELinux是对程序、文件等权限设置依据的一个内核模块。由于启动网络服务的也是程序,因此刚好也 是能够控制网络服务能否访问系统资源的一道关卡。 1-2 SELinux是通过MAC的方式来控制管理进程,它控制的主体是进程,而目标则是…...

从 vue 源码看问题 — vue 如何进行异步更新?
前言 在上一篇 如何理解 vue 响应式? 中,了解到响应式其实是通过 Observer 类中调用 defineReactive() 即 Object.defineProperty() 方法为每个目标对象的 key(key 对应的 value 为非数组的) 设置 getter 和 setter 实现拦截&…...

【go从零单排】go中的基本数据类型和变量
Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 基本类型 go中的string、int、folat都可以用连接boolen可以用逻辑表达式计算 package mainimport "fmt&quo…...

标签之文字排版,图片,链接,音视频(HTML) 基础版
目录 标签之文字排版,图片,链接,音视频知识点: 练习题一: 效果: 练习题二: 效果: 标签之文字排版,图片,链接,音视频知识点: 超文本:链接 标记:标签<> 双标签 单标签 <br>//换行 <hr>//水平线 向后tab 向前shifttab html注释<!----> css /**/ …...

基于SpringBoot+Gpt个人健康管家管理系统【提供源码+答辩PPT+参考文档+项目部署】
作者简介:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容:🌟Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…...

十四届蓝桥杯STEMA考试Python真题试卷第二套第一题
来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第一题 题目描述: 给定一个字符串,输出字符串中最后一个字符。 输入描述: 输入一个字符串 输出描述: 输出字符串中最后一个字符 样例输入: hgf 样…...