当前位置: 首页 > news >正文

使用 LoRA 高效微调 Qwen 模型:从入门到实战

概述

在自然语言处理(NLP)领域,预训练语言模型(PLM)如 GPT、BERT 等已成为各种任务的基石。然而,对这些包含数十亿甚至上千亿参数的巨型模型进行全量微调以适应特定任务或领域,对计算资源和时间的要求极为苛刻。参数高效微调(Parameter-Efficient Fine-Tuning, PEFT)技术应运而生,旨在仅训练模型的少量新增参数,即可达到接近全量微调的效果,从而显著降低资源消耗。LoRA(Low-Rank Adaptation) 是其中最为突出和实用的技术之一。

本文将带你深入了解 LoRA 的核心原理,并结合代码实例,展示如何运用 LoRA 对通义千问的模型 Qwen 进行高效微调,使其能够适应特定的对话场景或指令遵循任务。

开始
环境准备
加载模型与分词器
配置 LoRA 参数
应用 LoRA 到模型
准备训练数据
设置训练参数
开始训练
保存 LoRA 适配器
结束
加载微调模型进行推理
加载原始模型
加载 LoRA 适配器
模型评估模式
准备输入文本
生成回复
输出结果

Qwen 模型简介与代码解析

Qwen (Qwen) 是阿里巴巴开发的一系列大语言模型。Qwen3-0.6B 是其中较小规模的版本,适用于资源受限的场景。这些模型通过在大规模文本数据上进行预训练,学习了丰富的语言知识和模式,可以用于多种NLP任务,如文本生成、问答、对话等。

让我们从以下代码开始,这段代码是使用 Qwen 模型的基础:

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch# 加载预训练的 Qwen 分词器
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
# 加载预训练的 Qwen 模型
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B")
  • AutoTokenizer.from_pretrained: 自动加载与 Qwen 模型相匹配的分词器。分词器负责将原始文本转换成模型可以处理的数字 ID(Token IDs)序列。
  • AutoModelForCausalLM.from_pretrained: 加载 Qwen 预训练模型的权重。AutoModelForCausalLM 是 Hugging Face transformers 库中专门为因果语言建模(Causal Language Modeling)任务设计的模型类,这种任务非常适合生成文本,如对话回复生成。

LoRA 核心原理:以小博大

原始权重 W₀
参数冻结
低秩分解: ΔW ≈ A × B
A (d×r) 和 B (r×k) 矩阵
旁路结构: BAx + W₀x
只训练 A 和 B 参数
推理时合并权重: W_new = W₀ + ΔW

传统的模型微调需要更新模型中的所有参数,这导致训练成本高昂。LoRA 提出了一种巧妙的解决方案:

  1. 参数冻结 (Parameter Freezing): 在微调开始前,预训练模型 W_0 的原始参数被完全冻结(设置为 requires_grad=False),在整个微调过程中保持不变。
  2. 低秩分解 (Low-Rank Decomposition): LoRA 假设在特定任务上,模型权重需要的变化量 ΔW 具有"低秩"特性。这意味着 ΔW 可以通过两个更小的矩阵 AB 的乘积来近似表示:ΔW ≈ A * B
    • 假设原始权重矩阵 W_0 的形状是 (d, k)
    • 矩阵 A 的形状是 (d, r)
    • 矩阵 B 的形状是 (r, k)
    • 其中 r(称为 LoRA rank)远小于 dk (r << d, k)。例如,dk 可能是 4096,而 r 可能是 8 或 16。
  3. 旁路结构 (Bypass Structure): 在模型的选定层(如注意力层的 Query、Key、Value 矩阵)中,LoRA 添加一个并行的旁路。输入 x 会经过 BA 两个线性变换(B 在前),得到 BAx。这个结果与原始路径的输出 W_0x 相加,得到最终输出:Output = W_0x + BAx
  4. 高效训练 (Efficient Training): 训练过程中,只有矩阵 AB 中的参数是可训练的 (requires_grad=True)。原始模型参数 W_0 保持不变。由于 r 远小于原始矩阵的维度,需要训练的参数量 (d*r + r*k) 急剧减少,从而大幅降低了显存占用和计算时间。
  5. 推理 (Inference): 在推理阶段,为了保持原始模型结构不变并确保推理速度,可以将 ΔW(即 BA 矩阵)物理地加到原始权重 W_0 上,得到更新后的权重 W_new = W_0 + ΔW。之后,模型可以像以前一样进行前向计算,无需任何额外的旁路或计算。

实战:使用 LoRA 微调 Qwen

下面,我们将通过 Python 代码,结合 transformerspeft 库,实现对 Qwen 的 LoRA 微调。

1. 安装依赖

安装依赖: transformers torch peft datasets accelerate
导入必要的库
检查GPU可用性

首先,确保安装必要的库:

pip install transformers torch peft datasets accelerate
# 如果需要 8-bit 量化以进一步节省显存,可安装 bitsandbytes
# pip install bitsandbytes

2. 加载模型和分词器

定义模型名称: Qwen/Qwen3-0.6B
加载分词器: AutoTokenizer.from_pretrained
加载模型: AutoModelForCausalLM.from_pretrained
设置数据类型和设备映射
from transformers import AutoModelForCausalLM, AutoTokenizer
import torchmodel_name = "Qwen/Qwen3-0.6B"
tokenizer = AutoTokenizer.from_pretrained(model_name)# 使用 float16 精度和 device_map 可以在 GPU 上更有效地管理显存
model = AutoModelForCausalLM.from_pretrained(model_name,torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,device_map="auto" # 自动将模型放到 GPU 或 CPU
)

3. 配置并应用 LoRA

定义 LoRA 配置
设置任务类型: CAUSAL_LM
设置 LoRA 秩: r=16
设置目标模块: q_proj, k_proj, v_proj, o_proj
设置 lora_alpha=32, lora_dropout=0.1
应用 LoRA: get_peft_model
打印可训练参数信息
from peft import LoraConfig, get_peft_model, TaskType# 定义 LoRA 配置
peft_config = LoraConfig(task_type=TaskType.CAUSAL_LM,      # 指定任务类型为因果语言建模,用于 Qweninference_mode=False,              # 设置为 False 表示处于训练模式r=16,                              # LoRA 的秩,是关键超参数,控制低秩分解的大小target_modules=["q_proj", "k_proj", "v_proj", "o_proj"], # 指定需要应用 LoRA 的模块。对于 Qwen 模型,通常是这些投影层lora_alpha=32,                     # LoRA 缩放因子,通常设置为 r 的倍数lora_dropout=0.1,                  # LoRA 旁路中的 Dropout 概率,防止过拟合
)# 将 LoRA 配置应用到模型上
model = get_peft_model(model, peft_config)# 打印可训练参数信息,确认 LoRA 已成功应用
model.print_trainable_parameters()
# 输出类似: trainable params: 1,XXX,XXX || all params: XX,XXX,XXX || trainable: X.XX%

4. 准备训练数据集

准备指令-响应数据
定义 token 化函数
创建 Dataset 对象
应用 token 化映射
移除不需要的列
数据集格式: input_ids, labels

你需要一个指令-响应对数据集。对于 Qwen 模型,格式通常包含系统提示、用户输入和助手响应。

  • 数据格式示例(字符串):<|system|>\nYou are a helpful assistant.<|end|>\n<|user|>\nExplain quantum computing in simple terms.<|end|>\n<|assistant|>\nQuantum computing uses quantum bits (qubits) that can be 0, 1, or both at once (superposition). This allows them to perform many calculations simultaneously, potentially solving certain problems much faster than classical computers.\n<|end|>
  • 你需要将其转换为 token_ids 序列。
  • 使用 tokenizer 对完整对话文本进行编码。
  • 确保序列长度不超过模型的最大上下文长度(可通过 tokenizer.model_max_length 查看)。
from datasets import Dataset# 示例数据
raw_data = [{"text": "<|system|>\nYou are a helpful assistant.<|end|>\n<|user|>\nExplain quantum computing in simple terms.<|end|>\n<|assistant|>\nQuantum computing uses quantum bits (qubits) that can be 0, 1, or both at once (superposition). This allows them to perform many calculations simultaneously, potentially solving certain problems much faster than classical computers.\n<|end|>"},# ... 更多指令-响应数据
]def tokenize_function(examples):# 将完整对话字符串转换为 token IDsoutputs = tokenizer(examples["text"],truncation=True,padding=False, # 在 PEFT 中通常不 padding,数据集会动态处理max_length=1024, # 根据需要调整return_tensors=None, # 返回普通列表)# 对于因果语言建模,labels 与 input_ids 相同# 在训练时,模型会预测 input_ids 中的下一个 tokenreturn {"input_ids": outputs["input_ids"], "labels": outputs["input_ids"]}# 创建 HuggingFace Dataset 对象
dataset = Dataset.from_list(raw_data)
tokenized_dataset = dataset.map(tokenize_function, batched=True)# 移除不需要的列,保留 input_ids 和 labels
tokenized_dataset = tokenized_dataset.remove_columns(["text"])

5. 设置训练参数与启动训练

在这里插入图片描述

from transformers import Trainer, TrainingArguments# 定义训练参数
training_args = TrainingArguments(output_dir="./qwen_lora_finetuned_output",  # 模型保存目录overwrite_output_dir=True,               # 覆盖输出目录num_train_epochs=1,                      # 训练轮数 - 示例中设置为1以加快训练per_device_train_batch_size=1,           # 训练批次大小 - 根据显存调整gradient_accumulation_steps=8,           # 梯度累积步数,模拟更大的批次warmup_steps=100,                        # 预热步数logging_steps=10,                        # 日志记录频率save_steps=500,                          # 模型保存频率learning_rate=5e-5,                      # 学习率 - 对于Qwen可以尝试更小的学习率fp16=torch.cuda.is_available(),          # 如果有 GPU,使用混合精度训练logging_dir='./logs',                    # 日志目录remove_unused_columns=False,             # 保留我们添加的列push_to_hub=False,                       # 是否推送到 Hugging Face Hub
)# 创建训练器
trainer = Trainer(model=model,args=training_args,train_dataset=tokenized_dataset,         # 传入处理好的数据集tokenizer=tokenizer,                     # 传入分词器
)# 开始训练
trainer.train()

6. 保存与使用微调后的模型

训练完成后,只保存 LoRA 的适配器权重:

# 保存 LoRA 适配器
peft_model_path = "./qwen_lora_finetuned_output"
model.save_pretrained(peft_model_path)
tokenizer.save_pretrained(peft_model_path) # 同时保存分词器
print(f"LoRA adapters saved to {peft_model_path}")

加载并使用微调后的模型进行推理:

加载原始模型
加载 LoRA 适配器: PeftModel.from_pretrained
模型设置为评估模式
准备输入文本: 系统提示+用户输入
编码输入文本为 token IDs
模型生成回复
解码生成结果
输出最终响应
from peft import PeftModel
from transformers import pipeline# 1. 加载原始 Qwen 模型和分词器
base_model = AutoModelForCausalLM.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)# 2. 加载并应用 LoRA 适配器
model = PeftModel.from_pretrained(base_model, peft_model_path)# 3. 设置模型为评估模式
model.eval()# 4. 准备输入文本 - 对于Qwen,使用适当的格式
input_text = "<|system|>\nYou are a helpful assistant.<|end|>\n<|user|>\nWhat is 2+2?<|end|>\n<|assistant|>"
input_ids = tokenizer.encode(input_text, return_tensors='pt')# 5. 生成回复
with torch.no_grad():output = model.generate(input_ids,max_new_tokens=50, # 控制生成新token的数量num_return_sequences=1,pad_token_id=tokenizer.eos_token_id, # 用 EOS token 作为 paddingdo_sample=True, # 是否采样top_k=50, # Top-K 采样top_p=0.95, # Nucleus 采样temperature=0.7 # 采样温度)# 6. 解码并打印结果
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print("Generated Response:", generated_text[len(input_text):]) # 只打印新生成的部分

总结

本文详细介绍了 LoRA 技术的原理,并演示了如何将其应用于 Qwen 模型的微调。通过 LoRA,我们能够显著减少需要训练的参数量,降低对计算资源的需求,同时保持模型的性能。这种高效的方法为在资源受限的环境下应用和部署大型语言模型提供了可能。希望这篇博客能帮助你理解并实践 LoRA,开启高效的模型微调之旅。

http://www.dtcms.com/a/594199.html

相关文章:

  • 如何做网站的维护和推广专业做网站照片
  • 惠州企业网站seo公司html5网站地址
  • 欧芯LKS32MC07
  • 创建大型网站专业网站制作哪里好
  • 算法215. 数组中的第K个最大元素
  • 巩义网站推广优化网站开发的软件环境
  • K8s资源控制器的实战
  • ppt超链接网站怎么做创建网站的六个步骤
  • Spring AI Alibaba脉络:企业级智能体框架
  • 网站建设一年多少钱贵阳小程序定制开发
  • 阿里云虚拟主机做淘客网站网页设计实训总结模板
  • 时序数据分析:Python爬取新浪财经频道新闻并绘制趋势图
  • 福州网站建设流程深圳公共资源交易中心
  • 东莞网站公司哪家好当下 如何做网站赚钱
  • 5.会话列表测试用例
  • 咨询公司网站设计电商网站商品中心设计方案
  • 电子商务网站版面布局天津北京网站建设公司哪家好
  • Java基础——集合进阶8
  • README查看会议信息
  • 云校网站建设网站优化排名易下拉系统
  • 基础算法精讲 09|递归|操作型|计算型
  • OpenCSG 2025年10月月报:战略合作、学术突破、H200上新与社会责任
  • Lua基本语法
  • 关于网站建设的请示范文东莞网站优化一般多少钱
  • CI/CD 全流程指南:从概念到落地的持续交付实践
  • 软件生产的“高速公路网”:深入浅出理解CI/CD的核心流程
  • 网站列表设计东城企业网站建设
  • 医学类数据集目标检测分割分类数据集汇总介绍
  • 2017网站建设傻瓜式网站开发
  • 开发环境搭建之JDK11+maven3.9.8+tomcat9安装