一、相关概念
用学习和做题练习 打比方:模型就是一个学生,权重 就是 脑子里记 的 知识。
前要
- 前向传播:做题
- 损失值 loss:扣分数
- 反向传播:分析错题,算出梯度
- 梯度:修改方向
- 学习率:每次改多大一步
- 权重震荡:步子太大来回横跳
- 过拟合:背会练习题,不会做新题
1. 前向传播
做题的过程。
给模型输入问题,模型跑一遍计算,输出答案。
输入 → 模型计算 → 输出预测结果。
只算输出,不修改模型任何参数 。
例子:给大模型一个指令,它生成一段回答,这就是一次前向传播。
2. 损失值 loss
"错题扣多少分",衡量你的答案和标准答案差多远。
- loss = 0:预测和标准答案完全一模一样,满分。
- loss越大:预测错得越离谱。
训练就是目标:想尽办法把loss往小压。
训练loss:训练集上的扣分;eval_loss:验证集(没见过的数据)上的扣分。
3. 反向传播
拿着错题分析,从后往前复盘,算出全部参数的梯度。
流程:
- 前向传播:模型做题得到输出
- 计算loss:看错多少
- 反向传播:从loss往回倒推,算出每一个权重的梯度(该怎么改)
👉反向传播只算梯度,还没有真正修改权重 。
真正更新权重,是优化器(AdamW)干的活。
QLoRA里,只有LoRA小适配器会算梯度;原始大模型主干冻结,不计算梯度,省大量显存。
4. 梯度 gradient (本质 N 维向量)
"错题分析,知道该往哪个方向改"。
做完题算出loss之后,要搞清楚:模型里面每个参数,是调大一点好,还是调小一点好,才能让loss变小 。
这个"往哪个方向改、改多大",就是梯度。
梯度是一个向量(矢量),而不是标量。
- 定义层面
在数学中,对于一个多元函数 f(x_1, x_2, ..., x_n) ,梯度定义为:
∇f=(∂f∂x1,∂f∂x2,...,∂f∂xn) \nabla f = \left( \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, ..., \frac{\partial f}{\partial x_n} \right) ∇f=(∂x1∂f,∂x2∂f,...,∂xn∂f)
它由各个参数方向的偏导数组成,既有大小,又有方向。
- 大小和方向
- 方向 :梯度指向函数值增长最快的方向(这也是为什么梯度下降法要取反方向------往负梯度方向走,函数值下降最快)
- 大小(模长) :表示函数在该点的变化率,即沿着最陡方向的"坡度"
∥∇f∥=(∂f∂x1)2+(∂f∂x2)2+...+(∂f∂xn)2 \|\nabla f\| = \sqrt{\left(\frac{\partial f}{\partial x_1}\right)^2 + \left(\frac{\partial f}{\partial x_2}\right)^2 + ... + \left(\frac{\partial f}{\partial x_n}\right)^2} ∥∇f∥=(∂x1∂f)2+(∂x2∂f)2+...+(∂xn∂f)2
- 在模型微调中
假设模型有 N 个参数(权重),那么梯度就是一个 N 维向量 :
g=∇L(θ)=(∂L∂θ1,∂L∂θ2,...,∂L∂θN) g = \nabla L(\theta) = \left( \frac{\partial L}{\partial \theta_1}, \frac{\partial L}{\partial \theta_2}, ..., \frac{\partial L}{\partial \theta_N} \right) g=∇L(θ)=(∂θ1∂L,∂θ2∂L,...,∂θN∂L)
5. 学习率 learning_rate
知道修改方向(梯度)之后,每一次下手改多少,就是学习率。
举个例子:
梯度告诉你:这个参数要减小才能降低loss。
- lr大:大刀阔斧改,一步改很多;学得快,但容易改过头。
- lr小:小心翼翼小步挪,走得慢,但比较稳。
LoRA/QLoRA为什么lr=2e‑4(0.0002),比全参微调高?
LoRA只是很小一部分参数,需要步子大一点才能学进去;全参微调几百万参数,步子要小。
梯度 + 学习率联合工作
新权重 = 旧权重 − 学习率 × 梯度
6. 权重震荡
学习率太大导致的现象。
学生改错改得太猛:
这次改多了,分数变好一点;下一轮又改过头,反而错得更厉害。
loss忽高忽低上下跳,无法平稳下降,这就叫权重震荡。
表现:loss抖动,不收敛;严重时loss直接变成NaN爆炸。
解决:降低学习率、开启max_grad_norm梯度裁剪。
7. 过拟合
死记硬背,不会举一反三, 学傻了。
区分两个集合:
- 训练集:平时做的练习题(模型见过)
- 验证集:考试卷子(模型从来没见过)
过拟合现象:
✅训练集loss越来越低(练习题几乎全对)
❌验证集loss反而升高(一到考试就拉胯,实际推理效果很差)
学生把练习题答案背下来了,没有学到真正规律,遇到新问题就废。
QLoRA微调非常容易过拟合,常见诱因:
- epoch跑太多,反复刷同一套数据
- 数据集太小
- 学习率太高
对抗手段:
- weight_decay权重衰减(相当于课后减负,不让权重变得极端)
- 不要把epoch调很大
- 使用
load_best_model_at_end拿验证集loss最好的权重,不用最后一轮 - 增加训练数据
8. 训练 数量单位: patch、forward、step、epoch
举例的前提:
-
一共 24 条训练数据
-
per_device_train_batch_size=2
-
gradient_accumulation_steps=3
1 个 Epoch(看完 24 条数据)
│
├── 共包含 4 个 Step(更新4次权重)
│ ├── Step 1: 累积 3 次 Forward(消耗 2 Patch + 2 Patch + 2 Patch = 6 条数据)→ 更新
│ ├── Step 2: 累积 3 次 Forward(消耗 6 条数据)→ 更新
│ ├── Step 3: 累积 3 次 Forward(消耗 6 条数据)→ 更新
│ └── Step 4: 累积 3 次 Forward(消耗 6 条数据)→ 更新
│
└── 总计 12 次 Forward(每次处理 2 条数据)
总结:
- patch
一条数据 在 概念上 对应 一个 patch; - forward
per_device_train_batch_size 决定 一个 forward 有几个 patch; step(更新权重的 次数 或者叫 步骤)
gradient_accumulation_steps 决定 一个 step 有几个 forward;- epoch
所有的 step 构成一次完成数据训练的 epoch。
完整 的 一次训练step流程(通俗版)
- 前向传播:拿一批样本喂模型,生成预测答案
- 算loss损失:对比标准答案,算出错多少分
- 反向传播:反向计算梯度,找出每个参数应该朝哪个方向修改
- 梯度累积(如果开了gradient_accumulation_steps):先攒梯度,不急着更新
- 权重更新 :攒够步数后,优化器AdamW:学习率 × 梯度,更新权重
- 进入下一轮循环
QLoRA注意:上面整套流程,主干大模型不更新,只有LoRA小权重被修改。
二、QLoRA 下 TrainingArguments 参数通俗解读
QLoRA核心:只训练少量LoRA适配器权重,主干模型冻结;下面参数大部分和普通SFT通用,但在QLoRA显存、收敛、保存上有特殊影响。
python
train_args = TrainingArguments(
output_dir=OUTPUT_ROOT, # 训练产物都放这里
logging_dir=os.path.join(OUTPUT_ROOT, "train_logs"), # 日志单独目录
per_device_train_batch_size=2, # 每卡每次 2 条样本
per_device_eval_batch_size=2, # 验证时同样 2 条
gradient_accumulation_steps=2, # 攒 2 步再更新,等效 batch=4
eval_accumulation_steps=2, # 验证也攒 2 步,省显存
learning_rate=2e-4, # 学习率
num_train_epochs=3, # 训练 3 轮
logging_steps=10, # 每 10 步打印日志
eval_strategy="epoch", # 每轮做一次验证
save_strategy="epoch", # 每轮保存检查点
save_total_limit=2, # 最多留 2 个检查点
load_best_model_at_end=True, # 结束自动加载验证集最好的那版
metric_for_best_model="eval_loss", # 用验证 loss 选最好
greater_is_better=False, # loss 越小越好
bf16=True, # bf16 混合精度
max_grad_norm=1.0, # 梯度裁剪上限,防爆炸
optim="adamw_torch", # 优化器
report_to="none", # 不接外部上报
weight_decay=0.01, # 权重衰减,防过拟合
ignore_data_skip=False
)
1. 路径输出类
1. output_dir
作用:模型checkpoint、LoRA权重、输出文件全部存这个文件夹。
QLoRA效果:保存的不是完整大模型,只是LoRA小适配器,体积很小,几MB~几百MB。
2. logging_dir
作用:训练loss、eval loss日志存到这个子文件夹,方便后面绘图看训练曲线。
2. Batch & 显存相关(QLoRA最关键,直接决定会不会OOM爆显存)
QLoRA主干模型是4/8bit量化冻结,占主要显存;显存压力主要来自梯度、优化器状态、batch大小(只针对LoRA小参数)。
3. per_device_train_batch_size=2
单块 GPU,一次同时跑多少条样本做前向 + 反向计算。这里 = 2,就是一张卡一次性喂进去 2 条数据。
一个 batch 在这里 就是 完成一次 2 条数据的训练,得到一个 梯度向量。
- 显存 :数字越大,同时处理的样本越多,显存吃的越多。显存不够就把这个值压到 1,是最常见操作。
- 训练震荡(loss 抖动)
这个数值太小,比如 = 1:每回只拿 1 条样本算梯度。单条样本的梯度噪声很大,loss 曲线上下蹦,参数更新晃来晃去。
数值太小时 可以 开大梯度累积gradient_accumulation_steps,凑等效 batch,来降低震荡 。靠多攒几步梯度,软件层面凑更大等效 batch,不增加显存开销- 实操建议:
不要盲目调大这个参数,很容易直接报显存溢出;想增大有效 batch 优先调梯度累积。
4. gradient_accumulation_steps=2 梯度累积
不马上更新权重,而是 分批算、攒梯度,攒够次数再更新权重;
用时间换大 batch 效果,不增加显存消耗。
4-1 没有 梯度积累
- 总共10 条训练数据
- 每批次 2 条(batch size = 2)
- 共 5 个批次(5 个 Step),即 1 个 epoch 有 5 步
梯度 产生的 规则是:每个 Forward 计算一次梯度,更新一次参数,而不是每条数据产生一个梯度。
具体过程:
Epoch 1:
Step 1: 数据 1,2 → 前向传播 → 计算 loss → 反向传播 → 梯度向量 g₁ → 更新参数
Step 2: 数据 3,4 → 前向传播 → 计算 loss → 反向传播 → 梯度向量 g₂ → 更新参数
Step 3: 数据 5,6 → 前向传播 → 计算 loss → 反向传播 → 梯度向量 g₃ → 更新参数
Step 4: 数据 7,8 → 前向传播 → 计算 loss → 反向传播 → 梯度向量 g₄ → 更新参数
Step 5: 数据 9,10 → 前向传播 → 计算 loss → 反向传播 → 梯度向量 g₅ → 更新参数
4-2 有 梯度积累
gradient_accumulation_steps=2
每完成 2 个 Forward 更新一次参数。
Epoch 1 (10条数据, batch_size=2, 共5个 Forward):
Batch 1: 数据 1,2 → 计算梯度 g₁ → 暂存,不更新 ❌
Batch 2: 数据 3,4 → 计算梯度 g₂ → 与 g₁ 累加 → 更新参数 ✅ (g₁ + g₂)
Batch 3: 数据 5,6 → 计算梯度 g₃ → 暂存,不更新 ❌
Batch 4: 数据 7,8 → 计算梯度 g₄ → 与 g₃ 累加 → 更新参数 ✅ (g₃ + g₄)
Batch 5: 数据 9,10 → 计算梯度 g₅ → 暂存,不更新 ❌ (epoch 结束,未攒够2个)
4-3 结论
不论 是否有 梯度积累, 每个 Forward 都会 得出 一个 梯度向量
QLoRA建议:显存不够就把这个数字调大,不要盲目调per_device_train_batch_size。
5. per_device_eval_batch_size=2
验证阶段,单张 GPU 每次同时处理多少条验证样本 。
该阶段下 只做前向、算 验证损失值 eval_loss ,不算梯度、不更新 LoRA 权重 。
所以 显存压力小。
什么时候开启
验证模式 eval ()?由
eval_strategy控制,就像上面的代码里写的eval_strategy="epoch"
- epoch:
【说明 】:1 个 epoch(一轮训练)的意思是 全部训练数据集,从头到尾完整过完一遍 。
每完整跑完 1 轮训练(1 个 epoch 结束),
暂停训练,
模型自动切换为 eval 验证模式,
加载全部验证数据集,按per_device_eval_batch_size分批喂入模型。
只跑前向传播,计算整个验证集平均 loss
验证完成,切回训练模式,继续下一轮 epoch 训练- steps
如果 eval_strategy="steps",可以设置每 N 次权重更新(N 个 step)就跑验证,不需要等全部数据集跑完。如果是"epoch",所以必须跑完整个数据集。- no:
全程不跑验证,不计算验证 loss。
6. eval_accumulation_steps=2
验证时也做累积。样本多、显存紧张时开启,避免验证阶段爆显存。
通俗易懂:
考试阅卷,一共 8 份卷子。
- 不开启 eval_accumulation_steps:把 8 份卷子全部堆桌上,一起算平均分,桌子要很大(显存占用高)。
eval_accumulation_steps=2:每次只拿 4 份卷子,算完这 4 份,收走,再拿下 4 份。桌子不用很大。
3. 学习率、轮次、优化器(QLoRA调参核心)
7. learning_rate=2e‑4
梯度告诉你往哪个方向走,学习率控制每一步迈多大。
大模型参数权重更新 = 学习率 × 梯度
e是科学计数法:2×10−42 \times 10^{-4}2×10−4
2e−4=2×10−4=0.00022e^{-4}=2\times10^{-4}= \boldsymbol{0.0002}2e−4=2×10−4=0.0002
简单记:e‑4 就是小数点后面3个0,再写数字 。
2e‑4 → 0.0002。
| 写法 | 数值 |
|---|---|
| 1e‑4 | 0.0001 |
| 2e‑4 | 0.0002 |
| 3e‑4 | 0.0003 |
| 2e‑5 | 0.00002 |
LoRA适配器的学习率。
⚠️重点:QLoRA/LoRA学习率远高于全参数微调。
- 全参数微调一般
2e‑5 ~ 5e‑5 - LoRA/QLoRA常用
1e‑4 ~ 3e‑4,你设置的2e‑4是很经典的值。
效果: - lr太大:LoRA权重震荡,模型乱回答,容易过拟合。
- lr太小:学不动,微调完和底座大模型几乎没区别。
8. num_train_epochs=3
把 全部训练数据集 完整跑3遍。
- epoch太少:没学会指令;
- epoch太多:LoRA过拟合,训练集loss很低,但实际推理效果变差。
QLoRA SFT常用 2‑5轮。数据集小尽量少epoch。
9. optim="adamw_torch"
梯度 告诉你朝哪走,学习率 决定一步多大,优化器AdamW,决定 走路的策略。
optim 是 TrainingArguments 里优化器选择参数 。
优化器:拿到梯度、学习率之后,具体怎么计算、怎么更新 LoRA 权重 的算法。
adamw_torch = 使用 PyTorch 原生自带的 AdamW 优化器,QLoRA 微调标准首选。
transformers里optim常见可选值:
| optim参数值 | 说明 | QLoRA是否推荐 |
|---|---|---|
adamw_torch |
PyTorch原生AdamW,官方标准,稳定效果好 | ✅首选,你现在用这个 |
adamw_hf |
HuggingFace自己实现的AdamW,老版本遗留,有历史bug | ❌不推荐 |
adafactor |
内存占用更低,适合显存极小机器;但收敛慢、微调效果普遍差 | ❌不推荐QLoRA,文档提示不要用 |
adamw_apex_fused |
apex融合版AdamW,速度更快;需要额外安装apex库,环境麻烦 | ⚠️追求速度可选,环境依赖重 |
sgd |
传统随机梯度下降,几乎不用在大模型微调,震荡严重 | ❌不推荐 |
重点对比:adamw_torch vs adafactor
- adamw_torch
- 显存占用更高一点;
- 收敛稳定,loss下降顺滑,LoRA微调效果最好;
- 不需要额外安装包,PyTorch自带。
- adafactor
- 省显存,不需要存二阶动量,低显存机器救急;
- 缺点:更新步长自适应,QLoRA微调经常学不到位,输出质量差;
只有你显存实在跑不动AdamW的时候才妥协使用。
10. weight_decay=0.01 权重衰减
权重衰减 就是 L2 正则化 ,只有optim="adamw_torch"时,才 配合 AdamW 优化器生效。
每次更新 LoRA 权重的时候,除了梯度带来的改动,还会额外把权重往 0 轻轻拽一下 ,不让 LoRA 矩阵的数值变得特别大。
核心作用: 罚过大权重,抑制 过拟合。
weight_decay = 0.01(默认常用值,QLoRA 标准)
平衡状态,大部分对话微调直接用。
调大,例如 0.05、0.1
往 0 拉扯的力度变强,更强抑制过拟合。
- 适合:数据集样本很少(几百条以内),极易背样本。
- 风险:数值太大,会压制模型学习新知识,学不进去微调数据。
调小,例如 0.0001 / 0
几乎不做约束。
- 适合:数据集数量巨大,不用担心过拟合。
- 风险:LoRA 权重容易暴涨,发生权重震荡、过拟合。
通俗:防止LoRA死记硬背训练集。
weight_decay=0= 关闭权重衰减
11. max_grad_norm=1.0 梯度裁剪
max_grad_norm=1.0:如果 梯度总力度 超过 1.0,就按比例把所有梯度全部缩小,强制上限为 1.0;没超过 1.0 就原样不动。
举例说明:
- patch 1:数据 1、2
前向→算 loss→backward,得到全局梯度向量 g₁
①计算 g₁的 L2 范数;
②如果范数>1.0:按比例整体缩小 g₁,方向不变;≤1.0 则 g₁不变;
③用处理后的 g₁去更新参数。 - patch 2:数据 3、4
前向→算 loss→backward,得到全新全局梯度向量 g₂
①算 g₂范数;
②超 1.0 就缩放,否则原样;
③更新参数。
核心作用:
防止梯度爆炸,loss突然飙升、loss变成NaN。QLoRA经常会出现梯度爆炸,这个参数建议一定要开。
举例: 训练中,某一批样本异常,会算出来巨大的梯度。
12. bf16=True
用 16 位半精度做计算,关键部分保留 32 位高精度,兼顾省显存、跑的快,尽量不损失训练效果 。
前提:显卡必须支持bf16(RTX30系及以后、A10/A100/H100;20系显卡不支持bf16,要用fp16)。
效果:减半梯度、优化器中间变量显存;加速训练;QLoRA强烈推荐开启。
如果显卡不支持bf16,直接OOM/报错,改成
fp16=True。
4. 日志、验证、保存策略
13. logging_steps=10
每跑10个训练step,打印一次loss、学习率到日志。方便观察loss下降是否正常。
14. eval_strategy="epoch"
每跑完一整个epoch,自动切换为 eval 验证模式,跑一遍 验证集,计算eval_loss。
可以选择:steps按步数验证。数据集大的时候按epoch验证更省时间。
15. save_strategy="epoch"
通俗:训练中途存下的模型快照 ,记录当前训练到什么程度、权重状态。
QLoRA场景只存LoRA适配器小权重,不存整个大模型,体积很小。
save_strategy="epoch"
每完整跑完1轮epoch,就写一份checkpoint快照到磁盘。
作用&价值:
- 防中断:训练断电、程序崩溃,不用从头重跑。读取最近的checkpoint,接着继续训练。
- 多版本留存 :
num_train_epochs=3,会产出3份快照:epoch1、epoch2、epoch3。可以事后挑效果最好那一份拿来推理。 - QLoRA下只保存LoRA适配器,文件不大,磁盘压力小。
对比另外两种常见策略:
save_strategy="steps":按step(权重更新次数)保存,比如每20个step存一次。数据集大、epoch耗时很久时用。save_strategy="no":不保存中间checkpoint,只保存训练结束最终模型;崩掉就要全部重来。
注意:checkpoint是训练过程快照,里面还包含优化器状态、训练步数;真正拿来推理可以导出单独的lora适配器文件。
16. save_total_limit=2
磁盘只保留最新2个checkpoint,旧的自动删除,避免磁盘被大量LoRA checkpoint占满。
举例说明:
前提:
- save_total_limit=2 (磁盘只保留最新2个模型快照)
- save_strategy="epoch" (训练中途存下的模型快照)
- num_train_epochs=3 (训练 3 遍)
具体过程:
- epoch1 跑完 → 存 checkpoint‑1,磁盘:
[ck1] - epoch2 跑完 → 存 checkpoint‑2,磁盘:
[ck1, ck2] - epoch3 跑完 → 存 checkpoint‑3;现在总数超过 2,自动删除最早的 ck1 ,磁盘保留:
[ck2, ck3]
17. load_best_model_at_end=True
训练全部结束后,自动读取 验证集指标最好 的那个 checkpoint 作为 最终模型,而不是最后一轮。
非常实用,避免最后一轮过拟合。
18. metric_for_best_model="eval_loss"
上面的 参数 load_best_model_at_end 是说 用好的;
而这个 参数 是说 怎么才算是 好的。
用验证集损失eval_loss,当作判断 "哪个模型是最好模型" 的评判标准。
eval_loss:验证集上面算出来的损失值;数值越小,模型泛化能力越好。
举例:
每跑完一个 epoch,都会在验证集跑一遍,算出eval_loss:
- epoch1:eval_loss=2.1
- epoch2:eval_loss=1.4 (比上一轮更小 → 当前最优)
- epoch3:eval_loss=1.6 (变大了,效果变差)
这个参数告诉程序:对比好坏就看 eval_loss,谁的 loss 最小,谁就是最佳模型。
配合
load_best_model_at_end=True一起用才会生效
19. greater_is_better=False
配合上一个参数metric_for_best_model="eval_loss"一起工作。
作用:告诉程序指标的 好坏逻辑
False:数值越小,模型越好(loss、损失值这类指标用这个)True:数值越大,模型越好(准确率、F1分数这类指标用这个)
举例演示
当前配置:
metric_for_best_model="eval_loss"
greater_is_better=False
- epoch1 eval_loss=2.1 → 当前最优
- epoch2 eval_loss=1.4 → 数值更小,更新为 最优
- epoch3 eval_loss=1.6 → 数值变大,不算更好,不更新最优
如果这里错误写成
True,程序会误以为loss越大效果越好,就会选loss=2.1当做最佳模型,完全搞错。
20. ignore_data_skip=False
训练中途断电、崩溃,用resume_from_checkpoint从保存的checkpoint恢复训练:
-
ignore_data_skip=False(默认):框架会记住上次训练到第几步,跳过已经训练完的样本,从上次中断那一条继续往下跑 。例子:总共1000步,跑到300步崩了;恢复后直接从301步继续,不再重复跑1‑300步。
-
ignore_data_skip=True:不跳过旧数据,强制从头重新跑数据集 。哪怕你加载断点权重,依旧从数据集第1条样本重新开始训练,相当于权重接着用,数据从头再来一遍。
如果没有checkpoint文件,
ignore_data_skip就完全无效;所以 该参数生效的前提是 参数 save_strategy="no" 不出现。
21. report_to="none"
**指定训练指标上报哪个可视化工具。
report_to="none"
只打印控制台文字,不生成events日志,没有曲线图,适合快速调试。report_to="tensorboard"
日志保存在本地磁盘,不需要联网、不需要注册账号,国内环境首选。report_to="wandb"
线上可视化平台,数据上传外网服务器,需要注册登录,国内经常网络报错。
TensorBoard 是什么
TensorBoard 是谷歌开发的训练可视化工具 ,专门读训练产生的日志文件,把数字变成图表,不是大模型,不是框架,是一个可视化面板程序。
transformers 的 Trainer 通过
report_to="tensorboard",自动把每一步的指标写入日志文件,给 TensorBoard 读取。
核心作用
训练的时候程序控制台只会刷一堆纯文本数字:
step 10 loss:2.12
step 20 loss:1.76
step 30 loss:1.41
...
盯着一堆数字,你很难看出来趋势。
TensorBoard 读取 events.out.tfevents.xxx 日志,在浏览器画出曲线图:
- loss损失曲线 (最重要)
- train_loss:训练集损失
- eval_loss:验证集损失
一眼观察:loss是否下降、有没有震荡、有没有过拟合。
- 学习率曲线:看学习率调度器是否正常生效(cosine、linear衰减)
- 还可以看梯度、样本直方图(QLoRA微调一般很少用)
report_to="tensorboard" 完整实操
python
train_args = TrainingArguments(
output_dir="./output",
logging_dir="./output/train_logs", # tensorboard日志就写进这个文件夹!重点
report_to="tensorboard", # 开启上报
logging_steps=10, # 每10步记录一次loss,数值不要太大
# ...其他参数
)
关键点:tensorboard 的事件日志文件,全部生成在
logging_dir下面,不是 output_dir。
依赖:必须先装库
bash
pip install tensorboard
-
训练启动后,日志长什么样
训练跑起来,
./output/train_logs里面会生成类似:events.out.tfevents.xxxx的日志文件,这就是绘图数据源。 -
启动 tensorboard 服务(终端执行)
方式1:直接指向logging_dir目录(推荐)
bash
tensorboard --logdir=./output/train_logs
方式2:如果你想对比多组实验,指向外层output
bash
tensorboard --logdir=./output
执行成功,终端输出:
Serving TensorBoard on localhost; to expose to the network, run with --bind_all
TensorBoard 2.x.x at http://localhost:6006 (Press CTRL+C to quit)
复制链接 http://localhost:6006,浏览器打开。
- 网页里面看loss曲线
- 左上角下拉框选择
Loss - 可以看到:
train/loss:训练损失eval/loss:验证损失(开启eval才会出现这条曲线)
- 左上角下拉框选择
怎么判断训练状态
- train loss 持续下降,eval loss同步下降 → 正常收敛
- train loss一直降,但eval loss开始抬头上翘 → 过拟合,该停训
常见踩坑:
-
看不到曲线,页面空白
- 检查
logging_dir路径,确认文件夹里面有events.out.tfevents.*文件; logging_steps不要设置太大,比如1000步记一次,曲线点很少。
- 检查
-
改了
report_to="tensorboard"但是没有生成events文件
没安装tensorboard库;或者你用了旧的checkpoint恢复训练,注意日志目录不要复用旧日志,容易混在一起。
- 远程服务器训练,本地浏览器看曲线
bash
# 服务器执行,开放对外访问
tensorboard --logdir=./output/train_logs --bind_all --port 6006
浏览器访问 服务器IP:6006
- 和
report_to="none"对比
none:不会生成events文件,只能看控制台打印文字loss,没有曲线图。
补充小技巧
如果你同时跑多次实验,每个实验给不同的logging_dir,全部放在一个总目录,tensorboard会自动在一张图上叠加多条loss曲线做对比。