Qwen3 Embeding模型Lora微调实战

最近qwen又有大动作,发布Qwen3 Embeding系列模型,而且MTEB排行榜上获取多个第一,最重要的还是模型全系列开源。 不得不说qwen可能已经完成rag(Retrieval-Augmented Generation)技术栈的大一统了。

Retrieval部分:
  • 语义召回可以使用Qwen3 Embeding
  • 召回排序可以使用Qwen3 Reranking
Generation部分:
  • 问答生成可以使用Qwen3 Chat

真香啊,接下来笔者会简单介绍一下Qwen3 Embeding系列模型, 同时实战将Qwen3 Embeding的向量模型采用lora的方式微调成一个领域Embeding模型, 让模型在这个领域的语义搜索性能进一步提升。其中涉及到

  1. Qwen3 Embeding系列模型的架构和训练方法
  2. 难负样本的挖掘的方案和infoNCEloss的原理
  3. ms-swift微调Qwen3 Embeding的实战

Qwen3 Embeding系列模型

模型架构

主要有两个系列,一个embeding模型系列,一个Reranking模型系列。

  • Embeding模型:以单个文本片段作为输入,通过利用与最终[结束符]([EOS])标记对应的隐藏状态向量来提取语义表示。
  • Reranking模型:文本对(例如用户查询与候选文档)作为输入,抽取最后一层的,yes 和 no 这两个token的logit 取log_softmax后 取yes 所在位置的分数作为 score。
ini 复制代码
token_false_id = tokenizer.convert_tokens_to_ids("no")
token_true_id = tokenizer.convert_tokens_to_ids("yes")

def compute_logits(inputs, **kwargs):
    batch_scores = model(**inputs).logits[:, -1, :]
    true_vector = batch_scores[:, token_true_id]
    false_vector = batch_scores[:, token_false_id]
    batch_scores = torch.stack([false_vector, true_vector], dim=1)
    batch_scores = torch.nn.functional.log_softmax(batch_scores, dim=1)
    scores = batch_scores[:, 1].exp().tolist()
    return scores

训练方法

三阶段分层训练机制

  1. 对比预训练阶段:使用海量弱监督数据打底,增强模型泛化能力
  2. 精调阶段:采用高质量标注数据进行监督训练,提升任务适配性
  3. 模型融合阶段:通过集成策略合并多个候选模型,实现性能突破 下面废话不多说,实战微调Qwen3-Embedding-0.6B,将这个通用的embeding模型变成一个农林牧渔领域垂域的embeding模型 Lora微调Qwen3 Embeding模型实战

负样本和loss

负样本的构建

我们都知道,训练模型数据最重要,其中这种embeding和reranker模型,负样本的构建算是重中之重。 这里笔者用sentence_transformer库中自带的 mine_hard_negatives挖掘负样本,调整参数挑选出那些相似但不相关的样本。 数据来自这:农林牧渔中文问答数据

主要采用下方流程: 相似度计算和候选生成: 通过恶embeding模型或者reranker模型 计算查询与语料库的相似度,获取top-k最相似的候选 负样本的挑选:排除正例 ,应用各种筛选条件对负样本进行挑选: absolute_margin: 绝对相似度差异阈值 relative_margin: 相对相似度比例阈值 max_score/min_score: 相似度分数阈值 可以根据向量模型或者reranker的输出值去动态调整这些参数,挑选出合适的负样本。

ini 复制代码
from datasets import load_dataset
from sentence_transformers import SentenceTransformer
from sentence_transformers.util import mine_hard_negatives

dataset = load_dataset("parquet", data_files="/mnt/d/wsl/work/jupyter/data_hub/Chinese-QA-Agriculture/Chinese-QA-AFAF-train-v2.parquet")

split_dataset = dataset["train"].train_test_split(test_size=0.95, seed=42)

# 输出划分后的数据集信息
print("划分后的数据集:", split_dataset)
print(f"训练集大小: {len(split_dataset['train'])}")
print(f"测试集大小: {len(split_dataset['test'])}")

# 加载小的embeding模型
embedding_model = SentenceTransformer("/mnt/d/wsl/work/jupyter/model_hub/m3e-small")

train_dataset = split_dataset['train']

#挖掘难负样本
hard_train_dataset = mine_hard_negatives(
    train_dataset,
    embedding_model,
    anchor_column_name="prompt",
    positive_column_name="response",
    num_negatives=5,  # How many negatives per question-answer pair
    range_min=20,  # Skip the x most similar samples
    range_max=50,  # Consider only the x most similar samples
    max_score=0.8,  # Only consider samples with a similarity score of at most x
    absolute_margin=0.1,  # Similarity between query and negative samples should be x lower than query-positive similarity
    sampling_strategy="top",  # Randomly sample negatives from the range
    batch_size=64,  # Use a batch size of 4096 for the embedding model
    output_format="labeled-list",  
    use_faiss=True,  # Using FAISS is recommended to keep memory usage low (pip install faiss-gpu or pip install faiss-cpu)
)

def convert_format(example):
    # 获取正确答案和被拒绝的答案
    correct_response = next(resp for resp, label in zip(example['response'], example['labels']) if label == 1)
    rejected_responses = [resp for resp, label in zip(example['response'], example['labels']) if label == 0]
    return {
        "query": example['prompt'],
        "response": correct_response,
        "rejected_response": rejected_responses
    }
# 数据格式转换
transformed_dataset = hard_train_dataset.map(convert_format, remove_columns=hard_train_dataset.column_names)
transformed_dataset.to_json("./data_hub/qwen3_emb.json",force_ascii=False)

最终统计结果

负样本和正样本在m3e这个模型的平均相似度是0.87 和 0.75。

可以看一条筛选出来的样本:确实很多样本和query很相似,但是不相关。

{'response': '绿色环境可以帮助老年人放松紧张的中枢神经,改善和调节身体功能,降低皮肤温度,减少脉搏和呼吸频率,保持血压稳定,减轻心脏负担,提供精神舒适感。这对于冠心病、高血压患者以及身体机能退化的老年人尤为有益。',

'query': '绿色对老年人有哪些健康益处?',

'rejected_response': ['绿茶的主要功效是预防癌症和心血管疾病,还能抗氧化,提高免疫力,抑制和杀灭细菌等;白茶的主要功效有保护脑神经,增强记忆,减少焦虑等。',

'生态养殖可以改善肉、蛋、奶品质,能生产出天然绿色食品。']}

InfoNCE Loss

loss采用的是带有负样本的InfoNCE Loss

其中: q 是 query 的 embedding; r+ 是对应正样本的 embedding,r-是对应负样本的 embedding; sim 是点积(或 cosine) 这个 loss 惩罚 query 跟负样本更相似的情况,鼓励 query 跟正样本相似度更高。 训练实战 数据格式如下:response为正样本,rejected_response为负样本

{'response': '绿色环境可以帮助老年人放松紧张的中枢神经,改善和调节身体功能,降低皮肤温度,减少脉搏和呼吸频率,保持血压稳定,减轻心脏负担,提供精神舒适感。这对于冠心病、高血压患者以及身体机能退化的老年人尤为有益。',

'query': '绿色对老年人有哪些健康益处?',

'rejected_response': ['绿茶的主要功效是预防癌症和心血管疾病,还能抗氧化,提高免疫力,抑制和杀灭细菌等;白茶的主要功效有保护脑神经,增强记忆,减少焦虑等。',

'生态养殖可以改善肉、蛋、奶品质,能生产出天然绿色食品。']}

模型微调

训练脚本

比较重要的三个参数

  • --task_type embedding
  • --model_type qwen3_emb
  • --loss_type infonce
lua 复制代码
INFONCE_MASK_FAKE_NEGATIVE=true
swift sft \
   --model /mnt/d/wsl/work/jupyter/model_hub/Qwen3-Embedding-0.6B \
   --task_type embedding \
   --model_type qwen3_emb \
   --train_type lora \
   --dataset /mnt/d/wsl/work/jupyter/data_hub/qwen3_emb.json \
   --split_dataset_ratio 0.05 \
   --eval_strategy steps \
   --output_dir output \
   --eval_steps 100 \
   --num_train_epochs 1 \
   --save_steps 100 \
   --per_device_train_batch_size 4 \
   --per_device_eval_batch_size 4 \
   --gradient_accumulation_steps 4 \
   --learning_rate 6e-6 \
   --loss_type infonce \
   --label_names labels \
   --dataloader_drop_last true

训练结果

采用最新的ms-swift的版本,训练脚本如下,可以看到loss在下降,而且正负样例的margin从0.20上升到0.235. 其中 margin = sim(q,r+) - sim(q,r-) ,可以看到模型对正负样本的区分能力显著变强。

eval_loss

eval_loss

eval_neg

eval_pos

相关推荐
Ann18 分钟前
【翻译】图解deepseek-R1
llm·deepseek
Jamence31 分钟前
多模态大语言模型arxiv论文略读(113)
论文阅读·人工智能·语言模型·自然语言处理·论文笔记
haf-Lydia36 分钟前
金融科技的数字底座
人工智能·科技·金融
shengjk139 分钟前
多智能体大语言模型系统频频翻车?三大失败根源与解决方案全解析
人工智能
北极的树41 分钟前
谁说AI只会模仿,从Google AlphaEvolve项目看算法的自主创新
人工智能·算法·gemini
安思派Anspire1 小时前
用 LangGraph 构建第一个 AI 智能体完全指南(一)
人工智能
广州正荣1 小时前
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
人工智能·爬虫·科技
加油搞钱加油搞钱1 小时前
鹰盾加密器基于AI的视频个性化压缩技术深度解析:从智能分析到无损压缩实践
人工智能·音视频·视频加密·鹰盾加密·鹰盾播放器
Baihai_IDP1 小时前
OCR 识别质量如何影响 RAG 系统的性能?有何解决办法?
人工智能·llm·aigc
新智元1 小时前
20 人团队提前实现 DeepSeek 构想,AI 算力变天?直击大模型算力成本痛点
人工智能·openai