FlagOpen / FlagEmbedding

Retrieval and Retrieval-augmented LLMs
MIT License
7.5k stars 540 forks source link

BAAI/bge-m3-unsupervised 微调过程中难负例挖掘(hn_mine.py)的疑惑 #495

Open LLLiHaotian opened 8 months ago

LLLiHaotian commented 8 months ago

您好,我在对BAAI/bge-m3-unsupervised进行微调过程中参照您提供的toy_finetune_data.jsonl数据格式 {"query": "Five women walk along a beach wearing flip-flops.", "pos": ["Some women with flip-flops on, are walking along the beach"], "neg": ["The 4 women are sitting on the beach.", "There was a reform in 1996.", "She's not going to court to clear her record.", "The man is talking about hawaii.", "A woman is standing outside.", "The battle was over. ", "A group of people plays volleyball."]}

因为我的数据是中英文文本对数据,我将其转换为jsonl格式的query和pos数据来进行微调,在这里我的query是中文文本,pos是对应的英文文本,但是在挖掘难负例过程中我发现,得到的neg中的每个负例都是pos中的英文文本,不包含query中的中文文本,如下: {"query": "标题:一种用于溶胶法SERS检测的微流控芯片及其使用方法", "pos": ["title:Microfluidic chip for SERS (surface-enhanced Raman scattering) detection by sol method and using method of microfluidic chip"], "neg": ["title:A kind of fibrous raw material coloring agent and preparation method thereof", "title:Tenacity coating used for corrosion prevention of reinforcing steel bar and coating method thereof", "title:Low melting point copper-manganese-zine alloy for infiltration binder in matrix"]}

请问,neg负例的挖掘全部是从每条数据的pos中筛选吗? 如果是这样,想让neg负例既有pos也有query(即neg负例中既有英文文本又有中文文本),该如何解决呢?

staoxiao commented 8 months ago

参考https://github.com/FlagOpen/FlagEmbedding/blob/master/FlagEmbedding/baai_general_embedding/finetune/hn_mine.py#L65, neg负例的挖掘全部是从汇总所有的pos+neg从中筛选。

可以传入candidate_pool参数:candidate_pool,传入一个文件里面包括你想要挖掘的负样例。 另外,从效果考虑,可以直接从BAAI/bge-m3上进行微调。

LLLiHaotian commented 8 months ago

您好,感谢您的回复。 因为我的挖掘负例过程的输入数据中是没有neg的,只有query和pos,因此才会产生我所提到的问题。 至于candidate_pool参数,也正因为我缺少负例,所以没办法利用这个参数。

最后关于您提出的从效果考虑,可以直接从BAAI/bge-m3上进行微调,这是什么原因呢?二者的区别在哪呢?

staoxiao commented 8 months ago

可以把所有query和pos汇总再一起当作candidate_pool。 BAAI/bge-m3经过了一次微调,从上面启动应该会更好。

LLLiHaotian commented 8 months ago

感谢您的回答 我昨天将我现有数据进行了double处理——即query中文pos英文再加上query英文pos中文,如此作为挖掘负例的输入,应该与您“把所有query和pos汇总再一起当作candidate_pool”的最终目的一致。 我之后再试试微调BAAI/bge-m3

LLLiHaotian commented 8 months ago

您好,继上述问题,通过挖掘难负例的脚本,实现负样本对的有效高质量生成,从而利用对比学习框架的训练微调手段进行模型微调从而得到更好的embedding模型这应该是挖掘难负例数据的最终目标。 但是,请问挖掘负例的方式是通过计算query文本本身与pos集合所有文本进行相似性计算得到k个负例,这里感觉有点不符合逻辑。具体来说,这里的相似性计算就必然要进行一步向量表示,这里的embedding模型的选择对于相似性计算得到的负例的结果就会产生很大的不可控性,由此计算来的负例可信度是否经得住推敲? 期待您的回答。

staoxiao commented 8 months ago

难负例的意义在于挖掘向量模型不好区分的样本进行进一步训练,embedding模型可以选择基础模型,挖完后用基础模型微调。 难负例挖掘一直也是学术届的一个问题,挖掘太难的样本很容易产生伪负例,这些也可以通过其他手段进行进一步剔除。另外, 我们提供了range_for_sampling超参数去控制负样本的范围。

LLLiHaotian commented 8 months ago

您好,我看了项目中微调部分的代码,想与您确认一下,微调训练的损失函数是否采用的是有监督SimCSE的对比损失。

wanzhixiao commented 8 months ago

损失函数是否采用的是有监督S

可以贴一些微调代码的链接吗

LLLiHaotian commented 8 months ago

损失函数是否采用的是有监督S

可以贴一些微调代码的链接吗

https://github.com/FlagOpen/FlagEmbedding/tree/master/examples/finetune

staoxiao commented 8 months ago

您好,我看了项目中微调部分的代码,想与您确认一下,微调训练的损失函数是否采用的是有监督SimCSE的对比损失。

是的,采用和simcse一样的infonce对比loss

LLLiHaotian commented 8 months ago

您好,我注意到BGE-M3的跨语言评估测试https://github.com/FlagOpen/FlagEmbedding/tree/master/FlagEmbedding/BGE_M3 image 其中针对跨语言进行评估的部分代码是否会公布? 另外,想请问,这种跨语言性能的评估能否在MTEB进行评估,期待您的回答,谢谢。

LLLiHaotian commented 8 months ago

您好,还想请教一下,关于统一微调和只针对密集检索的微调有何区别,我有注意到统一微调中可以加入知识蒸馏的手段,请问"pos_scores": List[float], "neg_scores": List[float]其中的pos_scores和neg_scores的获取方式是怎么样的呢? https://github.com/FlagOpen/FlagEmbedding/tree/master/examples/unified_finetune

staoxiao commented 8 months ago

MKQA的评测代码会在近期放出。 pos_scores和neg_scores由更准确的模型计算出,如微调过的reranker

mianzhiwj commented 3 months ago

MKQA的评测代码会在近期放出。 pos_scores和neg_scores由更准确的模型计算出,如微调过的reranker 您好,MKQA的评估代码有放出吗?自己尝试了一下,并没有复现论文中的结果,同时也存在 “不可回答问题”如何参与计算的问题,想参考你的代码做一些测试。谢谢 另外,我测试了跨语言的翻译对的找回测试,发现M3表现很好,模型能直接从多语言的数据集中学习到不同语言下相同语义的内容的向量在语义空间下靠近吗?还是这部分能力有专门的数据集去针对训练?比如翻译对,或是语言交叉的finetune数据(比如query是英语,pos是中文)等。

hanhainebula commented 3 months ago

MKQA的评测代码会在近期放出。 pos_scores和neg_scores由更准确的模型计算出,如微调过的reranker

您好,MKQA的评估代码有放出吗?自己尝试了一下,并没有复现论文中的结果,同时也存在 “不可回答问题”如何参与计算的问题,想参考你的代码做一些测试。谢谢 另外,我测试了跨语言的翻译对的找回测试,发现M3表现很好,模型能直接从多语言的数据集中学习到不同语言下相同语义的内容的向量在语义空间下靠近吗?还是这部分能力有专门的数据集去针对训练?比如翻译对,或是语言交叉的finetune数据(比如query是英语,pos是中文)等。

  1. MKQA 评测代码已经在这里放出:https://github.com/FlagOpen/FlagEmbedding/tree/master/C_MTEB/MKQA. "unanswerable" 的问题已被过滤。
  2. M3 的 unsupervised 阶段使用了大量跨语言翻译对的训练数据 (NLLB 和 CCMatrix),您可以测试下 BAAI/bge-m3-unsupervised 的表现,欢迎您分享自己的测试结果。M3 的 finetune 阶段并没有使用跨语言的数据进行训练,只使用了多语言的数据。
mianzhiwj commented 3 months ago

MKQA的评测代码会在近期放出。 pos_scores和neg_scores由更准确的模型计算出,如微调过的reranker

您好,MKQA的评估代码有放出吗?自己尝试了一下,并没有复现论文中的结果,同时也存在 “不可回答问题”如何参与计算的问题,想参考你的代码做一些测试。谢谢 另外,我测试了跨语言的翻译对的找回测试,发现M3表现很好,模型能直接从多语言的数据集中学习到不同语言下相同语义的内容的向量在语义空间下靠近吗?还是这部分能力有专门的数据集去针对训练?比如翻译对,或是语言交叉的finetune数据(比如query是英语,pos是中文)等。

1. MKQA 评测代码已经在这里放出:https://github.com/FlagOpen/FlagEmbedding/tree/master/C_MTEB/MKQA. "unanswerable" 的问题已被过滤。

2. M3 的 unsupervised 阶段使用了大量跨语言翻译对的训练数据 (NLLB 和 CCMatrix),您可以测试下 BAAI/bge-m3-unsupervised 的表现,欢迎您分享自己的测试结果。M3 的 finetune 阶段并没有使用跨语言的数据进行训练,只使用了多语言的数据。

非常感谢您的回答。针对翻译对数据用于pretrained 阶段,我有个问题,是直接将两种语言的文本直接拼接构成数据吗?按照toy_data 的格式:{"text":"你好!Hello"} 是这样去构造吗?

hanhainebula commented 3 months ago

非常感谢您的回答。针对翻译对数据用于pretrained 阶段,我有个问题,是直接将两种语言的文本直接拼接构成数据吗?按照toy_data 的格式:{"text":"你好!Hello"} 是这样去构造吗?

M3 的第二阶段训练也是 contrastive learning,使用的训练数据格式和微调阶段的训练数据格式相同,都是 {"query": str, "pos": List[str], "neg": List[str]},只是 neg 数目为 0 (train_group_size=1)。所以用翻译对数据训练的格式是:{"query": "src_lang_text", "pos": ["tgt_lang_text"], "neg": []}

mianzhiwj commented 3 months ago

非常感谢您的回答。针对翻译对数据用于pretrained 阶段,我有个问题,是直接将两种语言的文本直接拼接构成数据吗?按照toy_data 的格式:{"text":"你好!Hello"} 是这样去构造吗?

M3 的第二阶段训练也是 contrastive learning,使用的训练数据格式和微调阶段的训练数据格式相同,都是 {"query": str, "pos": List[str], "neg": List[str]},只是 neg 数目为 0 (train_group_size=1)。所以用翻译对数据训练的格式是:{"query": "src_lang_text", "pos": ["tgt_lang_text"], "neg": []}。 非常感谢!

也就是在unsupervised阶段训练时,会学习这部分多语言语义的对齐是吗?unsupervised 阶段也是使用finetune 的代码训练吗?只是训练参数train_group_size=1 是吗?

hanhainebula commented 3 months ago

非常感谢您的回答。针对翻译对数据用于pretrained 阶段,我有个问题,是直接将两种语言的文本直接拼接构成数据吗?按照toy_data 的格式:{"text":"你好!Hello"} 是这样去构造吗?

M3 的第二阶段训练也是 contrastive learning,使用的训练数据格式和微调阶段的训练数据格式相同,都是 {"query": str, "pos": List[str], "neg": List[str]},只是 neg 数目为 0 (train_group_size=1)。所以用翻译对数据训练的格式是:{"query": "src_lang_text", "pos": ["tgt_lang_text"], "neg": []}。 非常感谢!

也就是在unsupervised阶段训练时,会学习这部分多语言语义的对齐是吗?unsupervised 阶段也是使用finetune 的代码训练吗?只是训练参数train_group_size=1 是吗?

是的。