模型训练

内容纲要

一、LoRA微调

1. 什么是LoRA微调

LoRA微调的全程是Low-Rank Adaptation,这种方法通过引入低秩矩阵分解,可以通过仅训练少量参数实现大模型的适配。

2. 全参数微调的缺陷

2.1 训练成本高

全参数微调,需要更新千亿甚至万亿级别的参数,会消耗大量计算资源,为了调整海量参数时不跑偏,还需要准备相当规模的数据集,费时费力。

2.2 训练时间长

全参数微调训练时间会比较长,有些场合需要快速迭代,跟不上业务的节奏

2.3 灾难性遗忘

全参数微调需要根据新任务,调整和重构预训练模型的所有参数,有可能导致原有的知识表征被破坏,导致新任务上表现虽好,但是旧任务上的表现急剧下降,这就是大模型的灾难性遗忘。

3 LoRA微调怎样避免这些问题?

需要训练一个巨大的参数矩阵$W{M*N}$,为了避免灾难性遗忘,训练的时候,我们不能调整原始矩阵,而是要调整一个同样大小的矩阵$ΔW{MN}$,使得推理时可以用$W_{MN}+αΔW{M*N}$代替原来的$W{M*N}$。

此时训练的参数量仍未M*N,如何改善?机器学习里的PCA使用过一个思路:矩阵分解。很多算法都使用类似的方法降低计算量(潜在语义分析LSA,推荐系统里的协同过滤)

Lora微调不是真正地训练一个巨大的矩阵$ΔW{M*N}$,而是训练两个小型矩阵$A{Mr}$和$B_{rN}$,使得$A{Mr}B{rN}≈ΔW_{MN}$,只要这两个结果足够近似,在工程上就是可行的。

如果r远小于M 、N,就可以极大地压缩参数量。假设M=300000,N=500000,那么$ΔW{MN}$的总参数量为MN=1500亿。如果取r=16,那么$A{Mr}$的参数量为Mk=480万,同理$B{rN}$的参数量为kN=800万,总参数量为1280万,仅为$ΔW{M*N}$总参数量的0.000085,即不到万分之一。

4 实际做法

  • 每个transformer都添加低秩旁路
  • 矩阵A高斯初始化
  • 矩阵B初始化为全0矩阵

二、获取基座模型

1、搜索想要的模型:

huggingface
modelscope

2、 使用–local_dir指定本地存储位置

modelscope download --model Qwen/Qwen2.5-3B-Instruct-GPTQ-Int4 --local_dir /workspace/deepseekDistllation/models/Qwen/Qwen2.5-3B-Instruct-GPTQ-Int4

三、 使用训练工具LLaMA-Factory

1、 LLaMA-Factory简介

实际工作中,会用一些工具提升工作效率。LLaMA-Factory 是一个封装比较完善的LLM微调工具,可以仅使用命令行与web UI 微调大模型,对微调工作提供了各种支持。
1、支持的模型:
LLaMA、LLaVA、Mistral、Mixtral-MoE、Qwen、Qwen2-VL、DeepSeek、Yi、Gemma、ChatGLM、Phi 等等100+。
2、集成方法:
(增量)预训练、(多模态)指令监督微调、奖励模型训练、PPO 训练、DPO 训练、KTO 训练、ORPO 训练等等。
3、多种精度:
16 bit全参数微调、冻结微调、LoRA 微调和基于 AQLM/AWQ/GPTQ/LLM.int8/HQQ/EETQ 的 2/3/4/5/6/8 比特 QLoRA 微调。
4、先进算法:
GaLore、BAdam、APOLLO、Adam-mini、DoRA、LongLoRA、LLaMA Pro、Mixture-of-Depths、LoRA+、LoftQ 和 PiSSA。
5、git地址:
https://github.com/hiyouga/LLaMA-Factory

2 环境搭建

2.1 创建虚拟环境
conda create --name llamafactory-3.11 python==3.11
conda activate llamafactory-3.11
2.2 拉代码安装
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git

cd LLaMA-Factory

pip install -e ".[torch,metrics]"

如果报错:No matching distribution found for setuptools>=61.0

pip install -r requirements.txt -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
pip install --no-build-isolation --no-index --find-links=./ --no-deps -e ".[torch,metrics]"
2.3 追加两个包
pip install auto_gptq optimum

3 LLaMA-Factory的使用

3.1 使用webui

在Anaconda Prompt中输入以下命令

conda activate llamafactory-3.11
llamafactory-cli webui

如果报错:argument of type ‘bool’ is not iterable

pip install pydantic==2.10.6

本地操作系统,启动后在浏览器上输入 http://localhost:7860,进入webui页面

3.2 使用命令行训练
llamafactory-cli train \
    --stage sft \
    --do_train True \
    --model_name_or_path /workspace/deepseekDistllation/models/Qwen/Qwen2.5-3B-Instruct-GPTQ-Int4 \
    --preprocessing_num_workers 16 \
    --finetuning_type lora \
    --template qwen \
    --flash_attn auto \
    --dataset_dir /workspace/deepseekDistllation/data/chatData \
    --dataset chat-train \
    --cutoff_len 6000 \
    --learning_rate 0.0001 \
    --num_train_epochs 1.0 \
    --max_samples 100000 \
    --per_device_train_batch_size 2 \
    --gradient_accumulation_steps 2 \
    --lr_scheduler_type cosine \
    --max_grad_norm 1.0 \
    --logging_steps 5 \
    --save_steps 100 \
    --warmup_steps 10 \
    --packing False \
    --report_to none \
    --output_dir /workspace/deepseekDistllation/models/lora/Qwen2.5-3B-instruct-GPTQ-Int4/train_2025-04-22-07-55-05 \
    --bf16 True \
    --plot_loss True \
    --trust_remote_code True \
    --ddp_timeout 180000000 \
    --include_num_input_tokens_seen True \
    --optim adamw_torch \
    --quantization_bit 4 \
    --quantization_method bitsandbytes \
    --double_quantization True \
    --lora_rank 16 \
    --lora_alpha 16 \
    --lora_dropout 0 \
    --lora_target all

四、训练过程

1 指定基座模型

模型名称:Qwen2.5-3B-Instruct-GPTQ-Int4
模型路径:/workspace/deepseekDistllation/models/Qwen/Qwen2.5-3B-Instruct-GPTQ-Int4

2 指定数据集

数据路径:/workspace/deepseekDistllation/data/chatData
数据集:chat-train

3 指定训练的基本性质

微调方法:LoRA
量化等级:4
训练阶段:Supervised fine-tuning

4 指定重要参数

学习率:1e-4 或者 5e-5
截断长度:6000
训练轮数:1.0
批处理大小:1
梯度累计:2
预热步数:10
LoRA的秩:8
LoRA缩放系数:16
LoRA随机丢弃:0.1

5 指定训练完成后的模型存储位置

/workspace/deepseekDistllation/models/lora/Qwen2.5-3B-instruct-GPTQ-Int4/

6 点击开始按钮,开始训练

五、检查训练效果

1 加载基座模型

CUDA_VISIBLE_DEVICES=0 API_PORT=8000 llamafactory-cli api \
    --model_name_or_path /workspace/deepseekDistllation/models/Qwen/Qwen2.5-3B-Instruct-GPTQ-Int4

2 加载基座模型+LoRA

CUDA_VISIBLE_DEVICES=0 API_PORT=8000 llamafactory-cli api \
    --model_name_or_path /workspace/deepseekDistllation/models/Qwen/Qwen2.5-3B-Instruct-GPTQ-Int4 \
    --adapter_name_or_path /workspace/deepseekDistllation/models/lora/Qwen2.5-3B-instruct-GPTQ-Int4/train_2025-03-20-20-41-50/checkpoint-1250 \
    --finetuning_type lora

3 使用代码访问服务

可以用代码访问部署好的api server

def callServer(input):
    port = 8000
    client = OpenAI(
        api_key="0",
        base_url="http://localhost:{}/v1".format(os.environ.get("API_PORT", port)),
    )
    messages = []
    messages.append({"role": "user", "content": input})
    result = client.chat.completions.create(messages=messages, model="test",max_tokens=6000)
    return result.choices[0].message.content

if __name__ == "__main__":
    input = "对于「初三女生在搀扶跌倒老奶奶后反被冤枉,但仍选择资助她千元」的新闻事件,你有什么看法?"
    a = time.time()
    result = callServer(input)
    b = time.time()
    print("输出长度:"+str(len(result))+"字  耗时:"+str(b-a)+"秒  输出速度:"+str(len(result)/(b-a))+"字/秒")
    print(result)

访问时,可以观察显卡的实时状态,windows在命令行里启动nvidia-smi -l 1,linux 使用 watch -n 1 nvidia-smi

六、主要参数

LLaMA-Factory训练过程中用到的参数非常多,按照重要程度整理如下:

1 极重要,本次训练模型和数据路径

参数名称 说明
模型名称 基座模型的名称
模型路径 基座模型的路径
检查点路径 开始的checkpoint路径,如果不需要可以为空
数据路径 数据存放的目录
数据集 dataset_info.json中记录的哪一个数据集
输出目录 训练好的模型的路径,windows下默认在 C:\Users\foxba\saves\Qwen2.5-3B-Instruct-GPTQ-Int4\LoRA\
训练参数目录 C:\Users\foxba\config\
对话模板 和使用的基座模型一致

2 极重要,决定本次训练的基本性质

参数名称 说明
微调方法 full–全参数训练 <br />freeze–冻结一部分参数<br />LoRA–使用LoRA微调
训练阶段 属于哪个训练阶段<br />Supervised Fine-Tuning:进一步做有监督训练<br />Reward Modeling:奖励建模,用于强化学习<br />PPO:强化学习算法之一,用于增强多次迭代中的稳定性<br />DPO:强化学习算法之一,用于避免策略和价值函数之间的相互影响,提高学习效率<br />KTO:知识转移方法,可以强化学习效率和最终效果<br />Pre-Training:预训练<br />本次实验选Supervised Fine-Tuning
量化等级 none:不做量化<br />8:8位量化<br />4:4位量化

3 重要,决定本次训练的整体效果

参数名称 说明
学习率 0.1 一般只用于探索,没人会真的用<br />0.01 从头训练的标准模型初始学习率<br />0.001 已经快接近优化目标时做细致调整时采用<br />0.0001 模型接近收敛时做微调<br />0.00005 预训练阶段的最后微调
截断长度 本次实验选6000
训练轮数 学习的特性较简单 ,1轮即可,如果数据集太小,不应选择太多轮数,可以考虑数据增强。
批处理大小 根据显存的情况调整
梯度累计 批处理大小*梯度累计决定了梯度更新的频率
预热步数 建议使用,防止参数剧烈震荡
LoRA的秩 学到信息的丰富程度
LoRA缩放系数 LoRA的重要程度
LoRA随机丢弃 随机丢弃LoRA层权重的概率,是一种正则化方法,方式模型过度依赖LoRA

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部