基于 ms-swift 与 Qwen2.5 实现语音控制机器人意图识别模型的 LoRA 微调

基于 ms-swift 与 Qwen2.5 实现语音控制机器人意图识别模型的 LoRA 微调

本文基于 ms-swift 微调框架与 Qwen2.5-1.5B-Instruct 模型,使用 amazon_massive_intent_zh-CN 语音控制数据集,通过 LoRA(Low-Rank Adaptation)完成指令微调。覆盖环境搭建、数据准备、模型下载、LoRA 训练全流程,最终在 8GB 显存的 RTX 4060 Ti 上完成训练。


一、核心概念:什么是 LoRA 微调?

大语言模型(LLM)拥有强大的通用能力,但在特定领域任务上,往往需要"微调"来适配。LoRA(Low-Rank Adaptation) 是一种参数高效微调方法:

概念 说明 对比
全量微调 更新模型所有参数 显存需求大,1.5B 模型约需 12GB+
LoRA 微调 冻结原始权重,仅训练低秩分解矩阵 仅训练 0.6% 参数,显存需求降低 70%+
Prompt Tuning 在输入端添加可学习 token 不修改模型权重,能力有限

LoRA 的核心思想: 不直接修改原始权重矩阵 WWW,而是学习一个低秩增量 ΔW=BA\Delta W = BAΔW=BA,其中 B∈Rd×rB \in \mathbb{R}^{d \times r}B∈Rd×r,A∈Rr×kA \in \mathbb{R}^{r \times k}A∈Rr×k,r≪min⁡(d,k)r \ll \min(d, k)r≪min(d,k)。推理时 W′=W+ΔWW' = W + \Delta WW′=W+ΔW,不增加推理延迟。

本次微调目标: 让 Qwen2.5-1.5B-Instruct 学会理解语音控制机器人的自然语言指令(如设置闹钟、调节音量、播放音乐等),并给出恰当的回复。


二、系统架构

核心组件:

组件 版本 职责
ms-swift 3.12.6 ModelScope 微调框架,封装训练流程
transformers 4.48.0 HuggingFace 模型加载与推理
peft 0.18.1 LoRA 适配器实现
trl 0.17.0 基于 transformers 的训练工具
torch 2.6.0+cu124 GPU 加速计算

三、环境准备

3.1 硬件环境

配置 规格
GPU NVIDIA RTX 4060 Ti 8GB
CUDA 12.4
显存占用 训练峰值 ~3.91 GiB

3.2 软件环境

使用 plate_ocr conda 环境,关键依赖如下:

bash 复制代码
# 核心依赖
pip install ms-swift==3.* transformers==4.48.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

# PyTorch(已有)
torch==2.6.0+cu124

# 模型下载
pip install modelscope -i https://pypi.tuna.tsinghua.edu.cn/simple

踩坑记录: ms-swift 4.x 要求 transformers>=5.0,与 torch 2.6.0 存在兼容性问题。解决方案是降级到 ms-swift 3.12.6 + transformers 4.48.0,同时卸载不需要的 torchvision(文本微调不涉及视觉功能)。

3.3 下载基座模型

从 ModelScope 下载 Qwen2.5-1.5B-Instruct(约 2.88GB):

python 复制代码
from modelscope import snapshot_download

model_dir = snapshot_download(
    'Qwen/Qwen2.5-1.5B-Instruct',
    cache_dir='./models'
)
print(f"模型下载完成,路径: {model_dir}")

四、步骤详解

步骤 1:训练数据准备

使用 amazon_massive_intent_zh-CN 数据集,这是语音控制机器人的意图识别数据集,采用 messages 格式:

json 复制代码
{
    "messages": [
        {"role": "system", "content": "你是一个语音控制机器人"},
        {"role": "user", "content": "星期五早上九点叫醒我"},
        {"role": "assistant", "content": "已为你设置星期五上午九点的闹钟,到时候会准时提醒你。"}
    ]
}

数据集特点:

属性 说明
样本数 100 条
格式 messages(system / user / assistant 三轮对话)
角色设定 "你是一个语音控制机器人"
意图类型 闹钟设置、音量控制、音乐播放、天气查询、定时器、灯光控制等
平均 token 长度 35.5 ± 3.8

数据示例(部分意图类型):


步骤 2:LoRA 训练参数配置

通过 swift sft 命令行配置训练参数:

bash 复制代码
swift sft ^
    --model models\Qwen\Qwen2___5-1___5B-Instruct ^
    --train_type lora ^
    --dataset amazon_massive_intent_zh-CN\Mytrain.jsonl ^
    --num_train_epochs 3 ^
    --per_device_train_batch_size 2 ^
    --learning_rate 1e-4 ^
    --lora_rank 8 ^
    --lora_alpha 32 ^
    --output_dir output

关键参数说明:

参数 说明
train_type lora 使用 LoRA 微调,而非全量训练
lora_rank 8 低秩矩阵的秩,越大表达能力越强但参数越多
lora_alpha 32 缩放系数,通常设为 rank 的 2~4 倍
learning_rate 1e-4 LoRA 学习率,比全量微调大 10 倍
per_device_train_batch_size 2 单卡 batch size,受 8GB 显存限制
num_train_epochs 3 训练轮数

LoRA 的数学原理:

  • 原始权重 W∈Rd×kW \in \mathbb{R}^{d \times k}W∈Rd×k 被冻结,不参与梯度更新
  • 仅训练 A∈Rr×kA \in \mathbb{R}^{r \times k}A∈Rr×k 和 B∈Rd×rB \in \mathbb{R}^{d \times r}B∈Rd×r,其中 r=8≪min⁡(d,k)r=8 \ll \min(d,k)r=8≪min(d,k)
  • 缩放因子 αr=328=4\frac{\alpha}{r} = \frac{32}{8} = 4rα=832=4,控制 LoRA 增量的影响幅度

步骤 3:LoRA 目标模块选择

ms-swift 自动为 Qwen2.5 的以下模块注入 LoRA 适配器:

python 复制代码
target_modules = {
    'q_proj',    # 注意力 - 查询矩阵
    'k_proj',    # 注意力 - 键矩阵
    'v_proj',    # 注意力 - 值矩阵
    'o_proj',    # 注意力 - 输出投影
    'gate_proj', # MLP - 门控投影
    'up_proj',   # MLP - 上投影
    'down_proj'  # MLP - 下投影
}

为什么选择这些模块?

  • 注意力层(q/k/v/o_proj):控制模型"关注什么",对指令遵循能力影响最大
  • MLP 层(gate/up/down_proj):控制模型的"知识存储",对回复内容生成至关重要

参数量统计:

指标 数值
模型总参数 1552.95M
可训练参数 9.23M(0.59%
缓冲区参数 0.0001M

步骤 4:训练过程监控

训练共 18 步(100 样本 × 3 epoch ÷ batch_size 2 ÷ gradient_accumulation 8 ≈ 18 步),总耗时约 42 秒。

训练日志关键指标:

Step Loss Token Acc 学习率 显存
1 19.07 48.96% 9.92e-05 3.59 GiB
5 14.71 57.77% 8.21e-05 3.91 GiB
10 9.08 63.43% 4.13e-05 3.91 GiB
15 7.89 69.17% 6.70e-06 3.91 GiB
18 --- 69.85% --- 3.91 GiB

训练趋势分析:

  • Loss 持续下降:19.07 → 7.89,模型在学习指令-回复的映射关系
  • Token Acc 稳步提升:48.96% → 69.85%,模型生成的 token 越来越准确
  • 学习率衰减:采用余弦退火策略,从 1e-4 衰减到接近 0
  • 显存稳定:峰值 3.91 GiB,远低于 8GB 上限

步骤 5:训练产物

训练完成后,输出目录结构如下:

核心产物是 adapter_model.safetensors------仅 37MB 的 LoRA 权重文件,配合原始基座模型即可还原微调后的完整模型。


五、训练结果展示

5.1 训练曲线

训练结束后,ms-swift 自动生成以下可视化图表:

曲线 趋势 说明
train_loss 19.07 → 7.89 损失持续下降,模型在学习
train_token_acc 48.9% → 69.9% 生成准确率稳步提升
train_learning_rate 1e-4 → ~0 余弦退火衰减
train_grad_norm 41.4 → 18.8 梯度范数下降,训练趋于稳定

5.2 最终训练指标

复制代码
train_runtime: 41.87s
train_samples_per_second: 7.164
train_steps_per_second: 0.43
train_loss: 10.54
token_acc: 69.85%
memory(GiB): 3.91
train_speed(s/it): 2.32

5.3 模型推理验证

微调后的模型可通过以下方式加载并推理:

python 复制代码
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer

# 加载基座模型
base_model = AutoModelForCausalLM.from_pretrained(
    "models\\Qwen\\Qwen2___5-1___5B-Instruct"
)
# 叠加 LoRA 适配器
model = PeftModel.from_pretrained(
    base_model,
    "output\\v0-20260622-215722\\checkpoint-18"
)
tokenizer = AutoTokenizer.from_pretrained(
    "models\\Qwen\\Qwen2___5-1___5B-Instruct"
)

# 推理测试
inputs = tokenizer(
    "你是一个语音控制机器人\n用户: 帮我设个半小时后的闹钟\n助手:",
    return_tensors="pt"
)
outputs = model.generate(**inputs, max_new_tokens=50)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
# 预期输出: "已为你设置30分钟后的闹钟,时间到会提醒你。"

六、核心技术点总结

技术点 实现方式 作用
LoRA 低秩分解 rank=8, alpha=32 仅训练 0.59% 参数,大幅降低显存需求
目标模块选择 注意力层 + MLP 层共 7 个模块 兼顾指令遵循与知识记忆
梯度累积 accumulation_steps=8 等效 batch_size=16,稳定训练
余弦退火 学习率从 1e-4 衰减到 ~0 前期快速学习,后期精细收敛
bf16 混合精度 torch.bfloat16 减少显存占用,加速训练
messages 格式 system/user/assistant 三轮 统一对话微调的数据格式
适配器保存 safetensors 格式 仅保存 37MB LoRA 权重,便于部署

七、延伸思考

  1. 更多训练数据:当前仅 100 条样本,增加到 1000+ 条可显著提升模型泛化能力
  2. 更多训练轮数:3 个 epoch 对 100 条数据仍显不足,可增加到 10~20 个 epoch
  3. 权重合并(merge) :使用 swift export --merge_lora 将 LoRA 权重合并回基座模型,便于部署
  4. 模型量化:合并后可进一步做 GPTQ/AWQ 量化,在 CPU 或低显存 GPU 上推理
  5. 评估指标:添加验证集,监控 eval_loss 防止过拟合
  6. QLoRA:结合 4-bit 量化 + LoRA,进一步降低显存到 2GB 以下,实现在更小的 GPU 上微调大模型