Qwen3 Embedding 与 Reranker 微调实践:从理论到落地的完整指南 原创

发布于 2025-7-18 14:03
浏览
0收藏

在检索增强生成(RAG)系统中,“召回” 与 “排序” 是决定效果的两大核心环节。Qwen3 系列开源模型通过 Embedding 与 Reranker 的组合,为这两个环节提供了高效解决方案 ——Embedding 负责从海量数据中 “粗召回” 相关内容,Reranker 则对召回结果 “精排序”,让最相关的信息脱颖而出。

本文将记录如何通过 LoRA 微调让这两个模型适配垂直领域。

一、为什么需要微调?

Qwen3 的 Embedding 和 Reranker 模型在通用场景表现优异,但在垂直领域(如专业术语密集的农林牧渔、医疗等)仍有提升空间。微调的核心价值在于:让模型 “吃透” 领域语义,提升检索精度。

  • Embeding模型:将文本转化为向量,通过向量相似度实现 “粗召回”。以单个文本片段作为输入,用与最终[结束符]([EOS])对应位置的隐藏状态向量提取语义表示。
  • Reranking模型:对召回的文本对(查询 + 文档)进行相关性判断,输出 “yes” 或 “no”,并以 “yes” 的概率作为排序依据。以文本对(例如用户查询与候选文档)作为输入,取最后一层的 yes  和 no 这两个token的logit 取log_softmax后,取yes 所在位置的分数作为 score。

二、环境准备

通过​​ms-swift​​工具简化流程,安装命令:

pip install ms-swift -U
pip install torch transformers datasets accelerate

​ms-swift​​是阿里达摩院推出的大模型微调工具,支持 Qwen3 全系列模型,内置 LoRA 优化和训练可视化功能。

三、实战:Qwen3 Embedding 微调全流程

3.1 数据准备:挖掘 “难负样本”

Embedding 模型的微调效果,关键在于 “难负样本”—— 即与查询语义相似但实际无关的文本。这类样本能强迫模型学习更精细的语义差异。

  • 数据源:采用农林牧渔领域问答数据集​​Chinese-QA-Agriculture_Forestry_Animal_Husbandry_Fishery​​(可从 Hugging Face 获取)。
  • 负样本挖掘工具:使用​​sentence-transformers​​​库的​​mine_hard_negatives​​函数,步骤如下:

from datasets import load_dataset
from sentence_transformers import SentenceTransformer
from sentence_transformers.util import mine_hard_negatives


# 加载原始数据
dataset = load_dataset("parquet", data_files="/path/to/Chinese-QA-AFAF-train-v2.parquet")
split_dataset = dataset["train"].train_test_split(test_size=0.95, seed=42)  # 划分训练集和测试集


# 加载基础模型用于初步检索
embedding_model = SentenceTransformer("/path/to/m3e-small")


# 挖掘难负样本
hard_train_dataset = mine_hard_negatives(
    split_dataset['train'],
    embedding_model,
    anchor_column_name="prompt",  # 查询列
    positive_column_name="response",  # 正例列
    num_negatives=5,  # 每个查询配5个负例
    range_min=20,  # 跳过最相似的前20个(避免与正例太近)
    range_max=50,  # 考虑前50个相似样本
    max_score=0.8,  # 负例与查询的相似度不超过0.8
    absolute_margin=0.1,  # 负例相似度需比正例低至少0.1
    use_faiss=True  # 用FAISS加速检索
)


# 转换为训练格式(查询+正例+负例)
def format_data(example):
    correct_resp = next(resp for resp, label in zip(example['response'], example['labels']) if label == 1)
    rejected_resps = [resp for resp, label in zip(example['response'], example['labels']) if label == 0]
    return {
        "query": example['prompt'],
        "response": correct_resp,
        "rejected_response": rejected_resps
    }


# 保存为JSON
hard_train_dataset.map(format_data).to_json("/path/to/qwen3_emb_train.json", force_ascii=False)

示例数据如下(体现 “相似但无关”):

{
    "query": "绿色对老年人有哪些健康益处?",
    "response": "绿色环境能帮助老年人放松神经、稳定血压...",
    "rejected_response": [
        "绿茶可预防心血管疾病...",  // 同含“绿色”但主题不同
        "生态养殖产出绿色食品..."
    ]
}

3.2 训练配置:用 ms-swift 启动 LoRA 微调

Embedding 微调需使用​​InfoNCE损失​​(鼓励查询与正例向量更相似,与负例更疏远),通过 ms-swift 工具简化流程,训练脚本如下:

# 设置环境变量,过滤无效负例
INFONCE_MASK_FAKE_NEGATIVE=true


# 启动微调
swift sft \
  --model /path/to/Qwen3-Embedding-0.6B \  # 基础模型路径
  --task_type embedding \  # 任务类型
  --model_type qwen3_emb \  # 模型类型
  --train_type lora \  # 采用LoRA微调
  --dataset /path/to/qwen3_emb_train.json \  # 训练数据
  --split_dataset_ratio 0.05 \  # 5%数据作为验证集
  --eval_strategy steps \  # 按步骤验证
  --output_dir ./emb_output \  # 输出目录
  --eval_steps 100 \  # 每100步验证一次
  --num_train_epochs 1 \  # 训练轮次
  --save_steps 100 \  # 每100步保存一次
  --per_device_train_batch_size 4 \  # 单卡批次大小
  --gradient_accumulation_steps 4 \  # 梯度累积步数
  --learning_rate 6e-6 \  # 学习率
  --loss_type infonce  # 采用InfoNCE损失
  • ​--loss_type infonce​​:通过下面公式强制模型拉大正负样本的相似度差距。


  • ​--train_type lora​​:仅训练部分参数,减少显存占用。
  • 训练过程中重点关注​​eval/margin​​指标(正例与负例的相似度差值)

四、实战:Qwen3 Reranker 微调全流程

4.1 数据准备:构建 “相关性判断” 样本

Reranker 的核心是判断 “查询 - 文档” 对是否相关,因此数据需包含 “查询 + 文档 + 是否相关” 标签(yes/no)。

  • 数据源:同 Embedding,基于农林牧渔问答数据构造,示例格式:

{
    "system": "Judge whether the Document meets the requirements based on the Query and the Instruct. Answer only 'yes' or 'no'.",
    "input": ": Retrieve relevant passages for the query\n: 封闭式阳台冬季如何解决春兰春化问题?\n: 连栋温室大棚降湿方法:通风除湿。",
    "output": "\n\n\nno"  // 文档与查询无关
}
  • 负样本处理:通过随机抽取领域内不相关文档(如用 “温室降湿” 匹配 “春兰春化” 问题),确保正负样本比例均衡(约 1:1)。

4.2 训练配置:用 SFT 微调相关性判断能力

Reranker 采用 “生成式微调”,直接训练模型输出 “yes” 或 “no”,核心脚本如下:

swift sft \
  --model /path/to/Qwen3-Reranker-0.6B \  # 基础模型路径
  --dataset /path/to/qwen3_rerank_train.json \  # 训练数据
  --model_type qwen3 \  # 模型类型
  --split_dataset_ratio 0.05 \  # 验证集比例
  --torch_dtype bfloat16 \  # 数据类型,节省显存
  --lora_rank 8 \  # LoRA秩,控制参数规模
  --lora_alpha 32 \  # LoRA缩放因子
  --target_modules all-linear \  # 微调所有线性层
  --eval_strategy steps \
  --output_dir ./rerank_output \
  --max_steps 1000 \  # 最大训练步数
  --eval_steps 100 \
  --num_train_epochs 1 \
  --save_steps 100 \
  --per_device_train_batch_size 4 \
  --gradient_accumulation_steps 4 \
  --learning_rate 6e-6 \  # 学习率
  --loss_scale ignore_empty_think \  # 忽略无效思考过程的损失
  --system 'Judge whether the Document meets the requirements. Answer only "yes" or "no".'  # 系统提示,约束输出格式
  • 关键设计:通过​​--system​​参数强制模型输出 “yes” 或 “no”,后续可直接用 “yes” 的生成概率作为排序依据(概率越高,相关性越强)。

五、总结:微调让 RAG 系统 “懂” 领域

通过 LoRA 微调,Qwen3 Embedding 和 Reranker 能快速适配垂直领域:

  • Embedding 的 “粗召回” 更精准,减少漏检;
  • Reranker 的 “精排序” 更可靠,过滤无关信息。

参考文献

  1. 王鹏 LLM,《Qwen3 Reranker 模型 Lora 微调实战》,​​https://mp.weixin.qq.com/s/TKW_eVFAZtfrVlRVT4mbJA​​,2025-06-14,来源:微信公众号
  2. 王鹏 LLM,《Qwen3 Embeding 模型 Lora 微调实战》,​​https://mp.weixin.qq.com/s/ZS_4VITX78qWndiZl8_BAg​​,2025-06-09,来源:微信公众号


本文转载自​鸿煊的学习笔记​,作者:乘风破浪jxj

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2025-7-18 14:04:34修改
收藏
回复
举报
回复
相关推荐