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

debain12.9使用unsloth微调Qwen2.5模型

debain12.9使用unsloth微调Qwen2.5模型

  • 基础环境准备
  • 下载模型
  • 微调脚本

基础环境准备

基础环境安装

以Qwen2.5-0.5B为例

下载模型

source ai/bin/activate
modelscope download --model 'unsloth/Qwen2.5-0.5B' --local_dir 'unsloth/Qwen2.5-0.5B'

微调脚本

from unsloth import FastLanguageModel
import torch

max_seq_length = 2048 # Choose any! We auto support RoPE Scaling internally!
dtype = None # None for auto detection. Float16 for Tesla T4, V100, Bfloat16 for Ampere+
load_in_4bit = True # Use 4bit quantization to reduce memory usage. Can be False.

# 加载模型
print('加载模型...')
model, tokenizer = FastLanguageModel.from_pretrained(
  model_name = "./unsloth/Qwen2.5-0.5B", # 加载本地模型,也可以自动下载huggingface模型(写huggingface模型id即可,不过需要科学上网或使用hf-mirror下载)
  max_seq_length = max_seq_length,
  dtype = dtype,
  load_in_4bit = load_in_4bit
)

# 添加LoRA适配器,因此我们只需要更新所有参数的1%到10%!
print('添加LoRA适配器...')
model = FastLanguageModel.get_peft_model(
    model,
    # LoRA 的秩(Rank),即低秩矩阵的维度大小。
    # 常用 8、16、32、64、128,越大表示适配能力越强,但参数量和显存占用也会增加。
    # 建议从较小的值(如 8)开始测试,逐步增加直到性能满意。
    r = 16,
    # 指定要对模型中哪些模块应用 LoRA 适配。
    # `q_proj`, `k_proj`, `v_proj`, `o_proj`:Transformer 自注意力机制中的查询(Query)、键(Key)、值(Value)和输出(Output)投影层。
    # `gate_proj`, `up_proj`, `down_proj`:Feed-Forward 网络(FFN)中的门控、上行、下行投影层。
    # 默认选择所有注意力层和 FFN 层,可以缩小范围(如仅 `q_proj`, `v_proj`)以进一步减少参数量。
    target_modules = [
      "q_proj",
      "k_proj",
      "v_proj",
      "o_proj",
      "gate_proj",
      "up_proj",
      "down_proj",
    ],
    # LoRA 的缩放因子,控制适配层对原始权重的调整幅度。
    # 最终更新量 = LoRA 输出结果 × (`lora_alpha / r`)。
    # 通常设置 `lora_alpha = r` 或为其倍数。例如 `r=8, alpha=16` 或 `r=16, alpha=32`。
    lora_alpha = 16,
    # 在 LoRA 适配层中应用 Dropout 的比例。
    # 设为 `0` 可最大化内存利用率,仅在过拟合风险较高时设为非零值(如 `0.1`)。
    lora_dropout = 0,
    # 是否对模型的偏置项(Bias)进行训练。
    # **可选值**:
    # - `"none"`:不训练任何偏置(推荐,节省显存)。
    # - `"all"`:训练所有偏置。
    # - `"lora_only"`:仅训练 LoRA 层的偏置。
    bias = "none",
    # [NEW] "unsloth" uses 30% less VRAM, fits 2x larger batch sizes!
    use_gradient_checkpointing = "unsloth", # True or "unsloth" for very long context
    random_state = 3407,
    # 是否使用 **Rank-Stabilized LoRA(RS-LoRA)**,一种改进的 LoRA 变体,通过调整初始化方式提升稳定性。
    # 默认关闭,除非显存充足且追求更稳定训练。
    use_rslora = False,
    # 配置 **LoftQ(LoRA with Fine-Tuned Quantization)**,用于在量化(如 4-bit)模型上应用 LoRA。
    # 默认无需设置,仅在使用量化微调时需要配置。
    loftq_config = None, # And LoftQ
)

# 定义变量
alpaca_prompt = """下面是描述任务的说明,并配有提供更多上下文的输入。编写适当完成请求的响应。

### 指令:
{}

### 输入:
{}

### 回答:
{}"""

# 微调前推理
print('微调前推理...')
question = "业务对象功能简介?"
FastLanguageModel.for_inference(model)
inputs = tokenizer([alpaca_prompt.format(question, question, "")], return_tensors="pt").to("cuda")
from transformers import TextStreamer
text_streamer = TextStreamer(tokenizer)
_ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 256)

# 数据加载
print('加载数据...')
EOS_TOKEN = tokenizer.eos_token # Must add EOS_TOKEN
def formatting_prompts_func(examples):
    instructions = examples["instruction"]
    inputs       = examples["input"]
    outputs      = examples["output"]
    texts = []
    for instruction, input, output in zip(instructions, inputs, outputs):
        # Must add EOS_TOKEN, otherwise your generation will go on forever!
        text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN
        texts.append(text)
    return { "text" : texts, }
pass

# huggingface
from datasets import load_dataset
# 加载本地数据集,也可以自动下载huggingface数据集(写huggingface数据集id即可,不过需要科学上网或使用hf-mirror下载)
# split可以控制加载指定数据区域,0:200,即前两百条数据
dataset = load_dataset("json", data_files="./qwen_ibps_qa.json", split = "train[0:200]")
dataset = dataset.map(formatting_prompts_func, batched = True,)

# 设置微调参数
print('设置微调参数...')
from trl import SFTTrainer
from transformers import TrainingArguments
from unsloth import is_bfloat16_supported
trainer = SFTTrainer(
    # 要微调的预训练模型(如 LLaMA、GPT-2)
    model = model,
    # 与模型匹配的分词器
    tokenizer = tokenizer,
    # 训练数据集(需是 HuggingFace Dataset 格式)
    train_dataset = dataset,
    # 数据集中包含训练文本的字段名(例如每行数据的 "text" 列)
    dataset_text_field = "text",
    # 输入序列的最大长度
    max_seq_length = max_seq_length,
    # 预处理数据集时使用的进程数(加速数据处理)
    dataset_num_proc = 2,
    # 是否将多个短序列打包成一个序列(True 可加速训练)
    packing = False,
    args = TrainingArguments(
        # 每个GPU的批次大小(根据显存调整)
        per_device_train_batch_size = 2,
        # 梯度累积步数(等效批次大小 = batch_size * steps)
        gradient_accumulation_steps = 4,
        # 学习率预热步数(避免初始不稳定)
        warmup_steps = 5,
        # num_train_epochs = 1, # Set this for 1 full training run.
        # 最大训练步数(覆盖 `num_train_epochs`)
        max_steps = 100,
        # 初始学习率(常用 1e-5 到 2e-4)
        learning_rate = 2e-4,
        # 使用 FP16 混合精度(NVIDIA GPU)
        fp16 = not is_bfloat16_supported(),
        # 使用 BF16 混合精度(AMD/TPU 或更新 NVIDIA GPU)
        bf16 = is_bfloat16_supported(),
        # 每隔多少步记录日志(损失、学习率等)
        logging_steps = 10,
        # 使用 8-bit AdamW 优化器(节省显存)
        optim = "adamw_8bit",
        # 权重衰减系数(防止过拟合)
        weight_decay = 0.01,
        # 学习率调度策略(如线性衰减)
        # - **`linear`**:线性衰减到 0,经典策略。
        # - 其他选项:`cosine`(余弦衰减)、`constant`(恒定学习率)等。
        lr_scheduler_type = "linear",
        # 随机种子(确保实验可复现)
        seed = 3407,
        # 模型和日志保存路径
        output_dir = "outputs",
         # 禁用第三方日志服务(如 WandB)
        report_to = "none", # Use this for WandB etc
    ),
)

# 模型微调训练
print('开始微调训练...')
trainer.train()

# 微调后推理
print('微调后推理...')
question = "业务对象功能简介"
FastLanguageModel.for_inference(model)  # Unsloth has 2x faster inference!
inputs = tokenizer([alpaca_prompt.format(question, question, "")], return_tensors="pt").to("cuda")
from transformers import TextStreamer
text_streamer = TextStreamer(tokenizer)
_ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 256)

# 保存到本地
print('保存到本地...')
new_model_local = "./unsloth/Qwen2.5-0.5B-001"
print('保存tokenizer...')
tokenizer.save_pretrained(new_model_local)
print('合并并保存merged_16bit...')
model.save_pretrained_merged(new_model_local, tokenizer, save_method = "merged_16bit")
print('合并并保存lora...')
model.save_pretrained_merged(new_model_local, tokenizer, save_method = "lora")

# 注意llama.cpp的安装喔,GGUF量化模型必须有这个工具!
# Save to 16bit GGUF
print('保存16bit GGUF...')
model.save_pretrained_gguf(new_model_local, tokenizer, quantization_method = "f16")
# Save to 8bit Q8_0
print('保存Q8_0 GGUF...')
model.save_pretrained_gguf(new_model_local, tokenizer)
# Save to q4_k_m GGUF
print('保存Q4_K_M GGUF...')
model.save_pretrained_gguf(new_model_local, tokenizer, quantization_method = "q4_k_m")

享受微调吧

相关文章:

  • Ubuntu20.04搭建gerrit code review
  • nnMamba:基于状态空间模型的3D生物医学图像分割、分类和地标检测
  • 深度学习算法实战——情感语音合成(主页有源码)
  • LeetCode 2523. Closest Prime Numbers in Range(2025/3/7每日一题)
  • OSI七大模型 --- 发送邮件
  • 操作系统 2.4-内核级线程基本实现原理
  • 小程序和页面生命周期详解
  • 游戏元宇宙崛起:AI代理IP驱动虚拟世界“无限可能”​
  • web3区块链
  • 火绒终端安全管理系统V2.0--纵深防御体系(分层防御)之规则拦截层
  • 深度学习笔记——循环神经网络RNN
  • 2025年Q2(桥门式)起重机司机考试题库
  • 换元积分法的数学本质与几何可视化——一场关于变量代换的数学探秘
  • 深度学习驱动的智能化革命:技术演进与跨行业实践
  • React + React-intl @3.xx + TypeScript
  • DeepSeek系列模型技术报告的阅读笔记
  • 前馈神经网络 - 参数学习(梯度下降法 - 多分类任务)
  • [LeetCode力扣hot100]-堆
  • 笔记本电脑外接固态移动硬盘可以用于深度学习吗
  • echarts的geo3d绘制地图添加定位点和点击事件,发现当有一个散点的时候无法点击
  • 企业网站的首页设计/seo刷排名公司
  • 宣传网站建设方案模板/百度推广一天费用200
  • 重庆二级站seo整站优化排名/seo关键词优化排名
  • 黄江做网站/教育培训网站官网
  • 营销网站建设制作设计/百度手机助手网页
  • c 网站登录验证码怎么做/知识搜索引擎