78-LLaMA-Factory微调实战-零代码训练-LoRA参数配置-训练曲线解读

文章目录

  • 【78.Python+AI】用LLaMA-Factory一条命令开始微调:零代码也能做模型训练
    • 导入语
    • [1 ~> 训练链路总览](#1 ~> 训练链路总览)
    • [2 ~> 环境搭建](#2 ~> 环境搭建)
      • [2.1 安装(conda隔离,避免污染主环境)](#2.1 安装(conda隔离,避免污染主环境))
      • [2.2 常见安装坑](#2.2 常见安装坑)
    • [3 ~> 数据集注册](#3 ~> 数据集注册)
      • [3.1 放置文件](#3.1 放置文件)
      • [3.2 在 dataset_info.json 中注册](#3.2 在 dataset_info.json 中注册)
    • [4 ~> 启动训练](#4 ~> 启动训练)
      • [4.1 方式一:WebUI(推荐新手)](#4.1 方式一:WebUI(推荐新手))
      • [4.2 方式二:命令行(适合远程服务器)](#4.2 方式二:命令行(适合远程服务器))
      • [4.3 参数推荐起点与调整逻辑](#4.3 参数推荐起点与调整逻辑)
    • [5 ~> 训练曲线解读](#5 ~> 训练曲线解读)
      • [5.1 三种典型的loss曲线](#5.1 三种典型的loss曲线)
      • [5.2 除了loss还要盯什么](#5.2 除了loss还要盯什么)
      • [5.3 训练中试一把](#5.3 训练中试一把)
    • [6 ~> 训练完成后的产出](#6 ~> 训练完成后的产出)
    • [思考 && 总结](#思考 && 总结)
    • 结尾

【78.Python+AI】用LLaMA-Factory一条命令开始微调:零代码也能做模型训练

📖 文章简介: 本文手把手教你用LLaMA-Factory完成第一次模型微调------这是目前最流行的零代码微调框架,支持100+开源模型,自带WebUI。文章覆盖完整链路:环境搭建(conda+CUDA避坑)、数据集放置与注册(dataset_info.json的正确写法)、LoRA关键参数配置(学习率/rank/epoch的推荐起点)、WebUI可视化训练操作,以及训练曲线解读(什么样的loss曲线算健康、什么情况说明过拟合)。配以Mermaid流程图展示从数据到模型的完整训练链路,适合刚准备好数据集、想用最短路径跑通第一次微调的开发者。


🎬 个人主页: 源码骑士

专栏传送门: 《Android开发基础》《python基础课程》

⭐️热衷从源码视角拆解技术底层原理,将复杂架构讲得通俗易懂


🎬 源码骑士的简介:

5年Android Framework系统开发经验,曾主导多项系统级性能优化专项

技术栈覆盖Android系统全链路(Binder/Handler/AMS/WMS/启动流程)及Java后端全家桶(Spring + MyBatis + Redis + Oracle)

累计产出原创技术文章100+篇,文章以流程图为特色,被读者评价为"看一篇胜过啃一周源码"


导入语

数据集洗好了,LoRA原理也懂了------但你打开transformers文档想手写训练脚本,迎面就是TrainingArguments、DataCollator、gradient_checkpointing一堆概念。

其实不用。LLaMA-Factory 把这一切封装成了一个WebUI:填几个参数、点一下开始,训练就跑起来了。这篇文章就带你走通从安装到出模型的全流程,顺便教会你看懂那条loss曲线到底在说什么。


1 ~> 训练链路总览

#mermaid-svg-L3AAbunr32n1rqLR{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-L3AAbunr32n1rqLR .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-L3AAbunr32n1rqLR .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-L3AAbunr32n1rqLR .error-icon{fill:#552222;}#mermaid-svg-L3AAbunr32n1rqLR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-L3AAbunr32n1rqLR .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-L3AAbunr32n1rqLR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-L3AAbunr32n1rqLR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-L3AAbunr32n1rqLR .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-L3AAbunr32n1rqLR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-L3AAbunr32n1rqLR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-L3AAbunr32n1rqLR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-L3AAbunr32n1rqLR .marker.cross{stroke:#333333;}#mermaid-svg-L3AAbunr32n1rqLR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-L3AAbunr32n1rqLR p{margin:0;}#mermaid-svg-L3AAbunr32n1rqLR .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-L3AAbunr32n1rqLR .cluster-label text{fill:#333;}#mermaid-svg-L3AAbunr32n1rqLR .cluster-label span{color:#333;}#mermaid-svg-L3AAbunr32n1rqLR .cluster-label span p{background-color:transparent;}#mermaid-svg-L3AAbunr32n1rqLR .label text,#mermaid-svg-L3AAbunr32n1rqLR span{fill:#333;color:#333;}#mermaid-svg-L3AAbunr32n1rqLR .node rect,#mermaid-svg-L3AAbunr32n1rqLR .node circle,#mermaid-svg-L3AAbunr32n1rqLR .node ellipse,#mermaid-svg-L3AAbunr32n1rqLR .node polygon,#mermaid-svg-L3AAbunr32n1rqLR .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-L3AAbunr32n1rqLR .rough-node .label text,#mermaid-svg-L3AAbunr32n1rqLR .node .label text,#mermaid-svg-L3AAbunr32n1rqLR .image-shape .label,#mermaid-svg-L3AAbunr32n1rqLR .icon-shape .label{text-anchor:middle;}#mermaid-svg-L3AAbunr32n1rqLR .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-L3AAbunr32n1rqLR .rough-node .label,#mermaid-svg-L3AAbunr32n1rqLR .node .label,#mermaid-svg-L3AAbunr32n1rqLR .image-shape .label,#mermaid-svg-L3AAbunr32n1rqLR .icon-shape .label{text-align:center;}#mermaid-svg-L3AAbunr32n1rqLR .node.clickable{cursor:pointer;}#mermaid-svg-L3AAbunr32n1rqLR .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-L3AAbunr32n1rqLR .arrowheadPath{fill:#333333;}#mermaid-svg-L3AAbunr32n1rqLR .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-L3AAbunr32n1rqLR .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-L3AAbunr32n1rqLR .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-L3AAbunr32n1rqLR .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-L3AAbunr32n1rqLR .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-L3AAbunr32n1rqLR .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-L3AAbunr32n1rqLR .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-L3AAbunr32n1rqLR .cluster text{fill:#333;}#mermaid-svg-L3AAbunr32n1rqLR .cluster span{color:#333;}#mermaid-svg-L3AAbunr32n1rqLR div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-L3AAbunr32n1rqLR .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-L3AAbunr32n1rqLR rect.text{fill:none;stroke-width:0;}#mermaid-svg-L3AAbunr32n1rqLR .icon-shape,#mermaid-svg-L3AAbunr32n1rqLR .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-L3AAbunr32n1rqLR .icon-shape p,#mermaid-svg-L3AAbunr32n1rqLR .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-L3AAbunr32n1rqLR .icon-shape .label rect,#mermaid-svg-L3AAbunr32n1rqLR .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-L3AAbunr32n1rqLR .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-L3AAbunr32n1rqLR .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-L3AAbunr32n1rqLR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 准备好的数据集

JSON文件
放入data目录

注册dataset_info.json
启动WebUI

llamafactory-cli webui
配置参数

模型/数据/LoRA/学习率
点击开始训练
观察loss曲线

与显存占用
导出LoRA适配器
合并权重或直接推理


2 ~> 环境搭建

2.1 安装(conda隔离,避免污染主环境)

bash 复制代码
# 创建独立环境
conda create -n llama python=3.10 -y
conda activate llama

# 安装PyTorch(按你的CUDA版本去官网选)
pip install torch --index-url https://download.pytorch.org/whl/cu121

# 安装LLaMA-Factory
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
pip install -e ".[torch,metrics]"

# 验证安装
llamafactory-cli version

2.2 常见安装坑

现象 解决
CUDA版本不匹配 torch.cuda.is_available() 返回False 重装对应CUDA版本的torch
flash-attn编译失败 卡在setup.py半天 可先不装,框架会自动用普通attention
网络拉不动模型 from_pretrained超时 设置 HF_ENDPOINT=https://hf-mirror.com

3 ~> 数据集注册

3.1 放置文件

bash 复制代码
LLaMA-Factory/
└─ data/
   ├─ dataset_info.json     # 数据集注册表
   └─ my_service_data.json  # 你的数据集文件

3.2 在 dataset_info.json 中注册

Alpaca格式:

json 复制代码
"my_service_data": {
  "file_name": "my_service_data.json",
  "columns": {
    "prompt": "instruction",
    "query": "input",
    "response": "output"
  }
}

ShareGPT格式:

json 复制代码
"my_service_data": {
  "file_name": "my_service_data.json",
  "formatting": "sharegpt",
  "columns": {
    "messages": "conversations"
  },
  "tags": {
    "role_tag": "from",
    "content_tag": "value",
    "user_tag": "human",
    "assistant_tag": "gpt"
  }
}

90%的"数据集加载失败"都是这里的字段名映射写错了------注册表的作用是告诉框架"你的JSON里哪个字段对应指令、哪个对应回答"。


4 ~> 启动训练

4.1 方式一:WebUI(推荐新手)

bash 复制代码
llamafactory-cli webui

浏览器打开 http://localhost:7860,依次配置:

bash 复制代码
模型名称: Qwen2-7B-Instruct
微调方法: lora
数据集: my_service_data
学习率: 1e-4
训练轮数: 3
LoRA秩: 16
量化等级(QLoRA): 4     ← 显存小于24G时选上

点击"开始",下方会实时显示loss曲线和训练日志。

4.2 方式二:命令行(适合远程服务器)

bash 复制代码
llamafactory-cli train \
    --stage sft \
    --model_name_or_path Qwen/Qwen2-7B-Instruct \
    --dataset my_service_data \
    --finetuning_type lora \
    --lora_rank 16 \
    --lora_target all \
    --learning_rate 1e-4 \
    --num_train_epochs 3.0 \
    --per_device_train_batch_size 4 \
    --gradient_accumulation_steps 4 \
    --quantization_bit 4 \
    --output_dir saves/qwen2-7b/lora/sft \
    --fp16

4.3 参数推荐起点与调整逻辑

参数 推荐起点 什么时候调
learning_rate 1e-4 loss不降→调大到2e-4;loss震荡→调小到5e-5
num_train_epochs 3 数据<500条→3~5;数据>5000条→2
lora_rank 16 效果不足→32;显存不够→8
batch_size × grad_accum 4×4=16 有效批量保持16~32,显存不够就调小batch、加大accum

5 ~> 训练曲线解读

5.1 三种典型的loss曲线

bash 复制代码
健康曲线:
loss
 2.0 ┤╮
 1.5 ┤╰╮
 1.0 ┤  ╰╮
 0.5 ┤    ╰╮╭─
 0.0 ┼────────────→ step
     快速下降后趋于平稳,最终稳定在一个非零值

问题曲线一:loss不降
 2.0 ┤──────────
     一条平线 → 学习率太小 / 数据没加载对(先检查这个!)

问题曲线二:loss降到接近0
 0.0 ┤____
     → 过拟合预警:模型在背答案,泛化能力差
     → 减少epoch、增大数据量、或加大dropout

5.2 除了loss还要盯什么

指标 健康表现 异常信号
显存占用 稳定在峰值以下 持续增长→可能OOM前兆
训练速度(it/s) 稳定 突然变慢→检查是否触发了swap
学习率曲线 按scheduler平滑衰减 一直恒定→scheduler没配置

5.3 训练中试一把

不要等到训练结束------每保存一个checkpoint就试一次:

bash 复制代码
llamafactory-cli chat \
    --model_name_or_path Qwen/Qwen2-7B-Instruct \
    --adapter_name_or_path saves/qwen2-7b/lora/sft/checkpoint-500

人工测试的黄金问题集: 从训练集抽5条(检验是否学会)+ 从业务中想5条没训过的(检验是否泛化)。训过的好、没训过的差→过拟合;两者都好→可以继续;两者都差→数据或参数有问题。


6 ~> 训练完成后的产出

bash 复制代码
saves/qwen2-7b/lora/sft/
├─ adapter_model.safetensors   # LoRA权重(几十MB,这才是核心产物)
├─ adapter_config.json         # LoRA配置
└─ checkpoint-*/               # 中间检查点

# 后续两条路:
# 1. 直接挂载适配器推理(灵活,可换适配器)
# 2. 合并进基座模型再导出(部署方便,见第83篇)

思考 && 总结

  1. LLaMA-Factory把微调的门槛降到了"会填表单": 但前提是数据集已经准备好------框架解决的是"怎么训",解决不了"用什么训"。
  2. dataset_info.json是新手第一大坑: 字段映射写错,loss就是一条平线------排查永远先查数据加载。
  3. 参数用推荐起点跑通,再基于loss曲线调: 不要训练前纠结参数,曲线的反馈比任何教程都准。
  4. loss降到接近0不是好事: 那是模型在背题。微调追求的是"学会模式",不是"记住答案"。
  5. 中间checkpoint就要测: 训练3小时才发现方向错了,和30分钟就发现,是完全不同的成本。

第一次微调的目标不是"训出完美模型",而是"跑通数据→训练→验证的完整闭环"。闭环通了,后面都是迭代优化的事。


结尾

各位小伙伴,本文的内容到这里就全部结束了,源码骑士在这里再次感谢您的阅读!

源码骑士 --- Android Framework & 全栈开发

👀 关注:跟博主一起从源码视角深耕底层原理,见证每一次成长

❤️ 点赞:让优质内容被更多人看见,让知识传递更有力量

收藏:把核心知识点存好,在需要时随时查、随时用

💬 评论:分享你的经验或疑问,评论区一起交流避坑

🔄 一键四连:不要忘记给博主"一键四连"哦!

🗡️ 寄语:技术之路难免有困惑,但同行的人会让前进更有方向

结语:恭喜,到这里你已经完成了从数据到模型的第一次微调闭环。下一篇深入QLoRA原理------搞清楚4-bit量化为什么能省75%显存而效果几乎无损。不要忘记给博主"一键四连"哦!

相关推荐
Black_Rock_br6 小时前
打通 PyTorch Monarch 与 ROCm:单 Controller 架构的异构算力实战
人工智能·pytorch·python·开源
其实防守也摸鱼6 小时前
Kimi K3深度测评:长文本之外的真实力
运维·开发语言·网络·人工智能·python·学习·安全
weixin_BYSJ19876 小时前
springboot3家政平台小程序--附源码00904
java·javascript·spring boot·python·django·flask·php
风痕天际6 小时前
Pytorch开发教程1——CUDA安装
人工智能·pytorch·python
geovindu6 小时前
python: Breadth First Search Algorithm and Depth First Search Algorithm
开发语言·后端·python·算法·搜索算法
程序员果子6 小时前
CrewAI :当 Agent 学会团队协作
人工智能·git·python·多智能体·agent框架
玉鸯6 小时前
向量检索不是记忆:Agent 记忆的三层进化
python·agent
大模型码小白6 小时前
Java 部署:Jenkins Pipeline 构建 Java 项目(自动化)
java·人工智能·python·机器学习
runafterhit7 小时前
python基础语法命令(C程序员刷leetcode)
c语言·python·leetcode
paeamecium7 小时前
【PAT甲级真题】- Kuchiguse (20)
数据结构·c++·python·算法·pat考试·pat