Qwen-Reranker 训练方法详解
简介
在 MS-Swift 框架中,Qwen-Reranker 是一种用于提升搜索排序效果的模型。它通过对查询和文档对的相关性进行打分,重新排列检索结果,从而提高搜索质量。本文档将详细介绍如何使用 MS-Swift 训练 Qwen-Reranker 模型,以及不同损失函数的特点和使用方法。
训练脚本示例
传统 Reranker 训练
# 使用 iic/gte-reranker-modernbert-base 模型进行训练
CUDA_VISIBLE_DEVICES=0 \
swift sft \
--model iic/gte-reranker-modernbert-base \
--task_type reranker \
--loss_type reranker \
--train_type full \
--dataset MTEB/scidocs-reranking \
--load_from_cache_file true \
--split_dataset_ratio 0.05 \
--eval_strategy steps \
--output_dir output \
--eval_steps 100 \
--num_train_epochs 1 \
--save_steps 200 \
--per_device_train_batch_size 64 \
--per_device_eval_batch_size 64 \
--gradient_accumulation_steps 1 \
--dataset_num_proc 8 \
--learning_rate 6e-6 \
--label_names labels \
--dataloader_drop_last true
Listwise Reranker 训练
# 使用 listwise 损失函数训练 reranker
CUDA_VISIBLE_DEVICES=0 \
swift sft \
--model iic/gte-reranker-modernbert-base \
--task_type reranker \
--loss_type listwise_reranker \
--train_type full \
--dataset MTEB/scidocs-reranking \
--load_from_cache_file true \
--split_dataset_ratio 0.05 \
--eval_strategy steps \
--output_dir output \
--eval_steps 100 \
--num_train_epochs 1 \
--save_steps 200 \
--per_device_train_batch_size 64 \
--per_device_eval_batch_size 64 \
--gradient_accumulation_steps 1 \
--dataset_num_proc 8 \
--learning_rate 6e-6 \
--label_names labels \
--dataloader_drop_last true
Generative Reranker 训练
# 使用 Qwen/Qwen3-Reranker-4B 模型进行 generative reranker 训练
# nproc_per_node 表示每个节点上使用的GPU数量,需要根据实际可用GPU数量进行设置
# 例如,如果您有4个GPU,则设置 nproc_per_node=4
# 如果您只有2个GPU,则设置 nproc_per_node=2,并相应调整 gradient_accumulation_steps 参数
nproc_per_node=4
NPROC_PER_NODE=$nproc_per_node \
swift sft \
--model Qwen/Qwen3-Reranker-4B \
--task_type generative_reranker \
--loss_type generative_reranker \
--train_type full \
--dataset MTEB/scidocs-reranking \
--load_from_cache_file true \
--split_dataset_ratio 0.05 \
--eval_strategy steps \
--padding_side left \
--output_dir output \
--eval_steps 100 \
--num_train_epochs 1 \
--save_steps 200 \
--per_device_train_batch_size 2 \
--per_device_eval_batch_size 2 \
--gradient_accumulation_steps 8 \
--dataset_num_proc 8 \
--learning_rate 6e-6 \
--label_names labels \
--dataloader_drop_last true
Listwise Generative Reranker 训练
# 使用 listwise 方式训练 generative reranker
# nproc_per_node 表示每个节点上使用的GPU数量,需要根据实际可用GPU数量进行设置
# 例如,如果您有4个GPU,则设置 nproc_per_node=4
# 如果您只有2个GPU,则设置 nproc_per_node=2,并相应调整 gradient_accumulation_steps 参数
nproc_per_node=4
NPROC_PER_NODE=$nproc_per_node \
swift sft \
--model Qwen/Qwen3-Reranker-4B \
--task_type generative_reranker \
--loss_type listwise_generative_reranker \
--train_type full \
--dataset MTEB/scidocs-reranking \
--load_from_cache_file true \
--split_dataset_ratio 0.05 \
--padding_side left \
--eval_strategy steps \
--output_dir output \
--eval_steps 100 \
--num_train_epochs 1 \
--save_steps 200 \
--per_device_train_batch_size 2 \
--per_device_eval_batch_size 2 \
--gradient_accumulation_steps 8 \
--dataset_num_proc 8 \
--learning_rate 6e-6 \
--label_names labels \
--dataloader_drop_last true
nproc_per_node 参数说明
nproc_per_node 参数指定了在单个节点上使用的GPU数量。这个参数非常重要,因为它直接影响到训练的并行度和内存分配。
与GPU数量的关系
-
必须匹配实际GPU数量:
nproc_per_node应该等于或小于您系统中实际可用的GPU数量。如果您设置的数值超过了实际GPU数量,训练将会失败。 -
资源利用率:设置合适的
nproc_per_node值可以最大化利用硬件资源,提高训练效率。
对训练的影响
-
批量大小调整:当您减少
nproc_per_node时,为了保持相同的全局批量大小,需要相应增加gradient_accumulation_steps参数。 -
内存分配:较少的GPU数量意味着每个GPU需要处理更多的数据,可能需要减小
per_device_train_batch_size以避免内存溢出。 -
训练时间:使用更多的GPU可以加速训练过程,但也会增加通信开销。
示例配置
假设您想保持全局批量大小为 32(即 per_device_train_batch_size × nproc_per_node = 32):
- 如果您有 4 个GPU:设置
nproc_per_node=4和per_device_train_batch_size=8 - 如果您有 2 个GPU:设置
nproc_per_node=2和per_device_train_batch_size=16 - 如果您只有 1 个GPU:设置
nproc_per_node=1和per_device_train_batch_size=32或使用梯度累积
不同损失函数详解
1. Reranker 损失函数 (reranker)
传统的 reranker 损失函数将排序问题视为二分类问题,判断查询和文档是否相关。
损失函数公式
使用二元交叉熵损失(Binary Cross Entropy):
L=−1N∑i=1N[yilog(σ(si))+(1−yi)log(1−σ(si))]L = -\frac{1}{N} \sum_{i=1}^{N} [y_i \log(\sigma(s_i)) + (1-y_i) \log(1-\sigma(s_i))]L=−N1i=1∑N[yilog(σ(si))+(1−yi)log(1−σ(si))]
其中:
- NNN 是样本数量
- yiy_iyi 是真实标签(1表示相关,0表示不相关)
- sis_isi 是模型给出的相关性分数
- σ\sigmaσ 是 sigmoid 函数
训练数据示例
{
"query": "机器学习算法",
"positive_doc": "深度学习在图像识别中的应用",
"negative_doc": "烹饪食谱大全",
"label": 0
}
2. Generative Reranker 损失函数 (generative_reranker)
Generative Reranker 将排序问题转化为生成问题,模型需要生成特定的标记(如"yes"/“no”)来表示相关性。
实现原理
该方法利用模型的最后一层输出,仅关注特定标记(如"yes"和"no")的概率分布,并基于这些概率计算损失。
损失函数公式
使用交叉熵损失:
L=−1N∑i=1Nyilog(pyes(i))+(1−yi)log(pno(i))L = -\frac{1}{N} \sum_{i=1}^{N} y_i \log(p_{yes}^{(i)}) + (1-y_i) \log(p_{no}^{(i)})L=−N1i=1∑Nyilog(pyes(i))+(1−yi)log(pno(i))
其中:
- pyes(i)p_{yes}^{(i)}pyes(i) 是第iii个样本生成"yes"标记的概率
- pno(i)p_{no}^{(i)}pno(i) 是第iii个样本生成"no"标记的概率
训练数据示例
{
"query": "人工智能发展前景",
"document": "人工智能技术在未来十年的发展趋势分析",
"response": "yes",
"label": 1
}
3. Listwise Reranker 损失函数 (listwise_reranker)
Listwise 方法将排序问题看作在一个列表中识别最相关文档的问题,直接优化整个排序列表的质量。
实现原理
该方法按查询对样本进行分组,每组包含一个正样本和多个负样本。然后使用 softmax 函数计算每个文档被选为最相关文档的概率,并使用交叉熵损失进行优化。
损失函数公式
对于每个查询组,使用 softmax 计算概率:
pi=exp(si/T)∑j=1nexp(sj/T)p_i = \frac{\exp(s_i/T)}{\sum_{j=1}^{n} \exp(s_j/T)}pi=∑j=1nexp(sj/T)exp(si/T)
其中:
- sis_isi 是第iii个文档的相关性分数
- TTT 是温度参数
损失函数为:
L=−1N∑q=1Nlog(ppos(q))L = -\frac{1}{N} \sum_{q=1}^{N} \log(p_{pos}^{(q)})L=−N1q=1∑Nlog(ppos(q))
其中 ppos(q)p_{pos}^{(q)}ppos(q) 是查询qqq中正样本的概率。
训练数据示例
[
{
"query": "自然语言处理技术",
"document": "BERT模型在文本分类中的应用",
"label": 1
},
{
"query": "自然语言处理技术",
"document": "计算机视觉最新进展",
"label": 0
},
{
"query": "自然语言处理技术",
"document": "神经网络基础理论",
"label": 0
}
]
4. Listwise Generative Reranker 损失函数 (listwise_generative_reranker)
结合了 Generative Reranker 和 Listwise Reranker 的优点,既使用生成式方法又采用列表级优化。
实现原理
首先使用生成式方法获取每个文档的相关性分数(基于特定标记的概率),然后在每个查询组内使用 softmax 进行列表级优化。
损失函数公式
与 Listwise Reranker 类似,但相关性分数sis_isi来自于生成式模型的输出:
si=log(pyes(i)pno(i))s_i = \log(\frac{p_{yes}^{(i)}}{p_{no}^{(i)}})si=log(pno(i)pyes(i))
然后使用相同的 softmax 和交叉熵损失进行优化。
训练数据示例
[
{
"query": "深度学习优化算法",
"document": "Adam优化器在神经网络训练中的应用",
"response": "yes",
"label": 1
},
{
"query": "深度学习优化算法",
"document": "数据库索引技术详解",
"response": "no",
"label": 0
},
{
"query": "深度学习优化算法",
"document": "支持向量机分类原理",
"response": "no",
"label": 0
}
]
ne## 数据扩增机制说明
在 Qwen-Reranker 训练中,通过环境变量 MAX_POSITIVE_SAMPLES 和 MAX_NEGATIVE_SAMPLES 实现数据扩增机制:
MAX_POSITIVE_SAMPLES:每个数据项中最多采样的正样本数量,默认为1MAX_NEGATIVE_SAMPLES:每个数据项中最多采样的负样本数量,默认为7
数据扩增的具体过程如下:
- 每个原始数据项会被扩展成
MAX_POSITIVE_SAMPLES × (1 + MAX_NEGATIVE_SAMPLES)个训练样本 - 例如,当
MAX_POSITIVE_SAMPLES=1和MAX_NEGATIVE_SAMPLES=7时,每个数据项会扩展成 1×(1+7)=8 个训练样本 - 这些样本组成一个查询组(query group),在 listwise 损失函数中作为一个整体参与训练
max_length 和序列长度处理
max_length 参数作用
在 reranker 训练中,max_length 参数用于限制单个训练样本(query-document 对)的最大长度:
max_length限制的是单个 query-document 对的最大 token 数量- 每个样本(无论是正样本还是负样本)都会独立地与 max_length 进行比较
- 超过 max_length 的样本会根据
truncation_strategy进行处理(截断或抛出异常)
训练序列长度构成
训练时的序列长度是 query 与实际采样的文档拼接后的总长度:
- 正样本长度 = query 长度 + 正文档长度
- 负样本长度 = query 长度 + 负文档长度
- 每个这样的样本都独立地与 max_length 进行比较
批次处理中的长度管理
- 动态批处理:每个批次的序列长度会根据该批次中最长的样本自动调整
- 填充机制:使用
--padding_side left参数指定左填充,确保模型在处理实际内容时不会受到填充标记的影响 - 内存效率:不需要为所有样本分配最大可能长度的内存空间,节省 GPU 内存
总结
MS-Swift 提供了四种不同的 reranker 训练方法:
- 传统 Reranker - 最基本的方法,适用于一般的排序任务
- Generative Reranker - 利用生成能力,更适合复杂语义理解
- Listwise Reranker - 优化整个排序列表,提升整体排序质量
- Listwise Generative Reranker - 结合前两者优势,提供最佳性能
在实际应用中,可以根据数据特点和性能要求选择合适的训练方法。
2031

被折叠的 条评论
为什么被折叠?



