使用ms-swift的一些感悟

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数量的关系

  1. 必须匹配实际GPU数量nproc_per_node 应该等于或小于您系统中实际可用的GPU数量。如果您设置的数值超过了实际GPU数量,训练将会失败。

  2. 资源利用率:设置合适的 nproc_per_node 值可以最大化利用硬件资源,提高训练效率。

对训练的影响

  1. 批量大小调整:当您减少 nproc_per_node 时,为了保持相同的全局批量大小,需要相应增加 gradient_accumulation_steps 参数。

  2. 内存分配:较少的GPU数量意味着每个GPU需要处理更多的数据,可能需要减小 per_device_train_batch_size 以避免内存溢出。

  3. 训练时间:使用更多的GPU可以加速训练过程,但也会增加通信开销。

示例配置

假设您想保持全局批量大小为 32(即 per_device_train_batch_size × nproc_per_node = 32):

  • 如果您有 4 个GPU:设置 nproc_per_node=4per_device_train_batch_size=8
  • 如果您有 2 个GPU:设置 nproc_per_node=2per_device_train_batch_size=16
  • 如果您只有 1 个GPU:设置 nproc_per_node=1per_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=1N[yilog(σ(si))+(1yi)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=1Nyilog(pyes(i))+(1yi)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=1Nlog(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_SAMPLESMAX_NEGATIVE_SAMPLES 实现数据扩增机制:

  • MAX_POSITIVE_SAMPLES:每个数据项中最多采样的正样本数量,默认为1
  • MAX_NEGATIVE_SAMPLES:每个数据项中最多采样的负样本数量,默认为7

数据扩增的具体过程如下:

  1. 每个原始数据项会被扩展成 MAX_POSITIVE_SAMPLES × (1 + MAX_NEGATIVE_SAMPLES) 个训练样本
  2. 例如,当 MAX_POSITIVE_SAMPLES=1MAX_NEGATIVE_SAMPLES=7 时,每个数据项会扩展成 1×(1+7)=8 个训练样本
  3. 这些样本组成一个查询组(query group),在 listwise 损失函数中作为一个整体参与训练

max_length 和序列长度处理

max_length 参数作用

在 reranker 训练中,max_length 参数用于限制单个训练样本(query-document 对)的最大长度:

  1. max_length 限制的是单个 query-document 对的最大 token 数量
  2. 每个样本(无论是正样本还是负样本)都会独立地与 max_length 进行比较
  3. 超过 max_length 的样本会根据 truncation_strategy 进行处理(截断或抛出异常)

训练序列长度构成

训练时的序列长度是 query 与实际采样的文档拼接后的总长度:

  1. 正样本长度 = query 长度 + 正文档长度
  2. 负样本长度 = query 长度 + 负文档长度
  3. 每个这样的样本都独立地与 max_length 进行比较

批次处理中的长度管理

  1. 动态批处理:每个批次的序列长度会根据该批次中最长的样本自动调整
  2. 填充机制:使用 --padding_side left 参数指定左填充,确保模型在处理实际内容时不会受到填充标记的影响
  3. 内存效率:不需要为所有样本分配最大可能长度的内存空间,节省 GPU 内存

总结

MS-Swift 提供了四种不同的 reranker 训练方法:

  1. 传统 Reranker - 最基本的方法,适用于一般的排序任务
  2. Generative Reranker - 利用生成能力,更适合复杂语义理解
  3. Listwise Reranker - 优化整个排序列表,提升整体排序质量
  4. Listwise Generative Reranker - 结合前两者优势,提供最佳性能

在实际应用中,可以根据数据特点和性能要求选择合适的训练方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值