在世界百年未有之变局与个人自暴自弃的间隙中,我们学一点RAG。 RAG是一种独特的应用,“一周写demo,优化搞半年”,我甚至听说它能破解幻术。
为了理解其优化中的关键一环,我们先看下文本向量。文本向量除了是RAG检索的重要模块外,也应用在信息检索、排序、分类、聚类、语义相似度中。
1. 词向量到文本向量
向量模型把人类世界中的语言,变为计算机世界中的数字。输入一句话,输出一维向量。由于transformer中的一句话一般会输出一个二维向量,其形状为(sequence_length, embedding_dim),因此模型后面通常加一层pooling,把sequence_length这一维坍塌。
pip install open-retrievals
- 注意安装时是
pip install open-retrievals
,但调用时只需要import retrievals
- 欢迎关注最新的更新https://github.com/LongxingTan/open-retrievals
colab上有这段小小的代码: https://colab.research.google.com/drive/1dTzcMJNX3kSqqjTFUJXwZu6fRnf_5oHD?usp=sharing
更多更好的模型,根据语言需要(英文或中文还是多语言),顺着MTEB的榜单捋一下就行:https://huggingface.co/spaces/mteb/leaderboard
2. 文本向量的若干主流训练范式
语言模型可以很容易得到一个文本向量模型,但语言模型并不是为向量训练的,因此预训练的语言模型直接pooling不一定能取得满意的效果。那么,根据向量任务先微调一下再用。
微调的目的,把相似句子向量聚拢更近一些,把不相关的句子向量拉的更远一些。如何从一个语言模型训练出一个向量模型呢?我们从几篇典型论文中理解其范式。
BGE模型
- 使用普通的文本语料进行RetroMAE预训练
- 使用大量文本对进行batch内负样本对比学习
- 使用高质量文本进行困难负样本加batch内负样本根据任务对比学习微调
GTE模型
- 大量文本对进行batch内负样本对比学习
- 高质量文本进行困难负样本学习
E5-mistral模型
- 合成大量的不同任务不同语言的检索数据,困难负样本与batch内负样本对比学习
nv-embed模型
- 高质量检索数据进行困难负样本加batch内负样本对比学习
- 继续根据非检索数据,如一些分类等其他任务数据进行微调
3. 结论
我们试图从几种范式中总结出以下几点认知:
- 训练方式,尤其是合理设计的多阶段pipeline仍然能够提升性能
- 数据,数据大小、质量、多样性很重要,甚至更长的文本在向量模型中也更受重视。更重要的,合成数据开始展露头脚
- 模型,Decoder-only LLM微调的向量模型效果越来越好。大模型也逐步统治向量模型榜单,带来的收益和增加的开销相比如何,咱也不知道,但是这些参数中蕴含的知识确实让人印象深刻
- 对比学习和难负样本挖掘仍然扮演关键角色。
- 多任务,用不同任务不同来源的数据进行训练,一个batch内如何组织数据也有优化空间。instruction-based fine-tuning可以在训练时帮助模型拿到任务上的线索