深度长文,手把手教你微调Qwen-3大模型,基于Python和Unsloth(下)

发布于 2025-6-3 09:21
浏览
0收藏

维持对话与推理的比例平衡

在准备好数据集后,通常即可开始模型训练,但我们仍需考虑模型的对话与推理比例(Chat-to-Reason Ratio)。较高的对话比例侧重对话流畅性和通用知识,而较高的推理比例则强调逻辑推理和问题解决能力。二者的平衡对构建既能进行自然对话又能处理复杂任务的多功能模型起着重要作用。

本文假设需要构建一个对话模型,因此设定对话部分占比70%,推理部分占比30%。实现方式如下:

import pandas as pd  

# 设定对话比例  
chat_percentage = 0.7  

# 按比例采样通用对话数据集  
non_reasoning_subset = pd.Series(non_reasoning_conversations)  
non_reasoning_subset = non_reasoning_subset.sample(  
    int(len(reasoning_conversations) * (1.0 - chat_percentage)),  
    random_state=2407,  
)

数据预处理的最后一步是合并数据集,代码如下:

data = pd.concat([  
    pd.Series(reasoning_conversations),  
    pd.Series(non_reasoning_subset)  
])  
data.name = "text"  

from datasets import Dataset  
combined_dataset = Dataset.from_pandas(pd.DataFrame(data))  
combined_dataset = combined_dataset.shuffle(seed=3407)

四、模型训练

在准备好结构化数据和带有LoRA适配器的模型后,即可开始训练。训练前需初始化超参数,这些参数会影响训练过程和模型精度。

我们使用​​SFTTrainer​​和预设超参数初始化训练器:

from trl import SFTTrainer, SFTConfig  

trainer = SFTTrainer(  
    model=model,  
    tokenizer=tokenizer,  
    train_dataset=combined_dataset,  # 结构化数据集  
    eval_dataset=None,  
    args=SFTConfig(  
        dataset_text_field="text",       # 用于训练的数据集字段  
        per_device_train_batch_size=2,   # 单设备训练批次大小  
        gradient_accumulation_steps=4,   # 梯度累积步数  
        warmup_steps=5,                  # 学习率预热步数  
        max_steps=30,                    # 总训练步数  
        learning_rate=2e-4,              # 学习率  
        logging_steps=1,                 # 日志记录频率  
        optim="adamw_8bit",              # 优化器  
        weight_decay=0.01,               # 权重衰减  
        lr_scheduler_type="linear",      # 学习率衰减策略  
        seed=3407,  
        report_to="none",                # 日志平台(可选wandb)  
    ),  
)

代码说明

  • ​SFTTrainer​​用于基于自定义数据集微调大语言模型,支持梯度累积、混合精度优化等技术,适用于指令调优、对话生成等任务。
  • 本例中未设置验证数据集(​​eval_dataset=None​​),可根据需求添加。

完成所有设置后,启动训练:

trainer_stats = trainer.train()

训练过程中,内核将输出每一步的训练损失:

训练LoRA适配的Qwen3模型

五、微调模型推理

训练完成后,需对微调模型进行推理以评估响应效果。推理方式分为禁用思考启用思考两种模式。

禁用思考模式

此模式下模型直接生成回答,适用于简单任务,计算效率更高:

messages = [  
    {"role": "user", "content": "Solve (x + 2)^2 = 0."}  
]  
text = tokenizer.apply_chat_template(  
    messages,  
    tokenize=False,  
    add_generation_prompt=True,  # 生成响应必需  
    enable_thinking=False,       # 禁用思考  
)  

from transformers import TextStreamer  
_ = model.generate(  
    **tokenizer(text, return_tensors="pt").to("cuda"),  
    max_new_tokens=256,         # 最大生成token数  
    temperature=0.7, top_p=0.8, top_k=20,  
    streamer=TextStreamer(tokenizer, skip_prompt=True),  
)

输出结果

<|im_start|> 要解这个方程(x + 2)²=0,我们可以对两边取平方根,得到x+2=0,然后两边减去2,解得x=-2。<|im_end|>

启用思考模式

此模式下模型会生成详细推理过程,适用于复杂任务:

messages = [  
    {"role": "user", "content": "Solve (x + 2)^2 = 0."}  
]  
text = tokenizer.apply_chat_template(  
    messages,  
    tokenize=False,  
    add_generation_prompt=True,  
    enable_thinking=True,        # 启用思考  
)  

_ = model.generate(  
    **tokenizer(text, return_tensors="pt").to("cuda"),  
    max_new_tokens=1024,        # 延长生成长度以容纳推理过程  
    temperature=0.6, top_p=0.95, top_k=20,  
    streamer=TextStreamer(tokenizer, skip_prompt=True),  
)

输出结果

用户让我解这个方程(x + 2)²=0。首先,我需要回忆一下如何解二次方程。可能的方法有几种,比如直接开平方、展开后用求根公式,或者因式分解。不过这个方程看起来已经是平方的形式了,所以直接开平方可能是最快捷的方法。  

首先,方程两边都是非负数,因为左边是一个平方,右边是0。所以开平方后,左边变成|x+2|,右边是0。绝对值等于0的情况只有一种,就是里面的表达式等于0,所以x+2=0,解得x=-2。  

不过,为了确保正确,我可以再检查一下。把x=-2代入原方程,左边就是(-2+2)²=0²=0,右边也是0,所以解是正确的。  

另外,从二次方程的性质来看,这个方程的判别式b²-4ac=0,说明有一个实根(重根),所以确实只有x=-2一个解。这样看来,结果是正确的。

保存微调模型

训练完成后,需保存微调模型及分词器。以下是将模型保存至本地的方法:

model.save_pretrained_merged(  
    "Qwen3-16bit-OpenMathReasoning-Finetuned-Merged",  
    tokenizer,  
    save_method="merged_16bit"  
)

若需将模型推送到Hugging Face Hub,可使用以下代码(需替换为个人访问令牌):

model.push_to_hub_merged(  
    "Qwen3-16bit-OpenMathReasoning-Finetuned-Merged",  
    tokenizer,  
    save_method="merged_16bit",  
    token="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"  
)

六、总结

本文分上、下篇,请完整阅读。主要内容包括:

  • Qwen-3的竞争力:在多项基准测试中超越DeepSeek-R1、Gemini-2.5-Pro等主流模型。
  • 微调核心目标:通过任务特定数据优化模型响应,使其更贴合垂直领域需求。
  • 主要工具链:使用unsloth、torch、transformers、trl等库实现高效微调。
  • 数据与训练流程:结构化数据集构建、LoRA适配器应用、SFTTrainer训练及推理验证。
  • 模型部署:合并LoRA参数后保存至本地或Hugging Face Hub,便于后续应用。

通过合理平衡对话与推理比例、选择高效工具链及优化训练流程,开发者可基于Qwen-3构建定制化AI助手,极大提升垂直领域任务的处理能力。

本文转载自​​​AI科技论谈​​​​​​,作者:AI科技论谈

1
收藏
回复
举报
回复
相关推荐