ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

SwanLab 大模型微调可视化实战:2 个场景跑通 loss 曲线与调参决策

SwanLab 大模型微调可视化实战:2 个场景跑通 loss 曲线与调参决策

SwanLab 大模型微调可视化实战:2 个场景跑通 loss 曲线与调参决策

【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调(全参数/Lora)、部署国内外开源大模型(LLM)/多模态大模型(MLLM)教程项目地址: https://gitcode.com/datawhalechina/self-llm

你刚跑完一次大模型微调,关掉终端后却说不清它到底学到了什么:loss 降没降、该不该再训一个 epoch、学习率调没调对,全凭感觉。SwanLab 是一款开源的 AI 训练跟踪与可视化工具,能自动记录超参数、实时画出 loss 曲线,还支持把模型生成结果存进面板做主观评测。本文基于 self-llm 仓库的两个真实案例,带你 2 个场景跑通微调加可视化的完整流程,并学会依据曲线做调参与早停决策。

项目定位:让训练过程可追踪、可比对

self-llm 是《开源大模型食用指南》教程仓库,覆盖从部署到 LoRA/全参微调的完整路径,SwanLab 在其中承担"实验看板"的角色。核心能力包括:

  • 全程追踪:超参数、train loss、learning rate、梯度范数自动入档
  • 曲线对比:多条实验的指标可叠加到同一张图
  • 文本记录:用 swanlab.Text 把每轮推理输出存进面板,供肉眼验收
  • 框架集成:与 Transformers Trainer 通过 report_to="swanlab" 或 SwanLabCallback 两行接入

快速上手:两行代码接入可视化

装好环境

# 清华源加速,降低下载超时概率 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple # 版本组合来自仓库医学微调案例,已验证可复现 pip install swanlab==0.5.7 modelscope==1.22.0 "transformers>=4.50.0" datasets==3.2.0 accelerate peft==0.11.1

硬件与环境要求:

  • 显存:LoRA 微调 24GB 起步(如 24GB 的 4090);1.7B 级全参微调建议 32GB
  • Python 3.8–3.11,已装好 PyTorch 与 CUDA
  • 首次使用云端面板需在 swanlab.cn 注册账号并复制 API Key,训练启动时会提示粘贴;不配也能在本地目录记录日志

跑通最小示例

接入只需两行:TrainingArguments 里加 report_to,Trainer 里加 callback。

import swanlab from transformers import TrainingArguments, Trainer from swanlab.integration.transformers import SwanLabCallback args = TrainingArguments( output_dir="./output", num_train_epochs=1, report_to="swanlab", # 让 Trainer 自动上报指标 ) trainer = Trainer( model=model, args=args, train_dataset=train_dataset, callbacks=[SwanLabCallback()], # 自动记录 loss、学习率等 ) trainer.train() swanlab.finish()

loss 收敛曲线 这类曲线,训练全程自动更新,无需手写任何 logging 代码。

实战:把一次真实微调跑通

场景 1:Qwen3-1.7B 医学问答全参微调

数据准备:仓库案例使用 delicate_medical_r1_data 数据集(2000 余条医学问答,含 question/think/answer 三列),目标是让模型学会输出带 think 思考过程的回答。随机打乱后按 9:1 拆分为 train.jsonl 与 val.jsonl。

关键代码:模型经 modelscope 下载后加载,训练前缀部分在 labels 里填 -100,只对回答部分计算损失:

from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer tokenizer = AutoTokenizer.from_pretrained(model_dir, use_fast=False, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained( model_dir, device_map="auto", torch_dtype=torch.bfloat16) model.enable_input_require_grads() # 开启梯度检查点时需要 # 关键:指令前缀对应位置填 -100,损失只计算回答部分 labels = [-100] * len(instruction["input_ids"]) + response["input_ids"]

训练参数与 SwanLab 项目名(完整 process_func 见仓库源码,约 40 行):

os.environ["SWANLAB_PROJECT"] = "qwen3-sft-medical" # SwanLab 项目名 args = TrainingArguments( output_dir="./output/Qwen3-1.7B", per_device_train_batch_size=1, # 32GB 显存全参,保守取值 gradient_accumulation_steps=4, # 等效 batch size = 4 eval_strategy="steps", eval_steps=100, num_train_epochs=2, learning_rate=1e-4, gradient_checkpointing=True, # 以算力换显存 report_to="swanlab", run_name="qwen3-1.7B", )

输出解读:训练结束前,把验证集前 3 条的推理结果作为文本记入面板,与 loss 曲线互相印证:

swanlab.log({"Prediction": [swanlab.Text(response_text)]}) # 记录生成文本 swanlab.finish()

面板里同时挂了三样东西:train/eval loss 两条曲线、学习率调度、以及带 think 标签的医学问答生成文本,训练结束即可肉眼验收。

场景 2:Phi-4 LoRA 微调医疗实体识别

数据准备:few_shot_ner_sft 数据集的 cmeee 子集取前 5000 条,每条中文医疗文本带 9 类实体标注(dis 疾病、sym 临床表现、bod 身体部位、dru 药物等),完整数据加载与 prompt 拼接逻辑见仓库 NER 教程。

关键代码:LoRA 只训练低秩旁路参数,冻结原权重,显存占用显著低于全参:

config = LoraConfig( task_type=TaskType.CAUSAL_LM, target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"], r=64, # LoRA 秩 lora_alpha=16, lora_dropout=0.1, ) model = get_peft_model(model, config) args = TrainingArguments( per_device_train_batch_size=4, gradient_accumulation_steps=4, num_train_epochs=1, learning_rate=1e-4, gradient_checkpointing=True, report_to="none", # 指标改由 SwanLabCallback 上报 ) swanlab_callback = SwanLabCallback( project="Phi-4-NER-fintune", experiment_name="phi-4", config={"lora_rank": 64, "lora_alpha": 16}, # 超参一并入档 )

输出解读:训练面板自动画出 4 张图,训练损失在 120 步内从 3.4 降到 0.33 附近,梯度范数稳定在 0.5 以下,学习率曲线呈线性衰减。

更关键的是面板里的 Prediction 文本区:基座模型对"由于迷走神经、舌咽神经核及舌下神经核受损伤,可发生呼吸肌及吞咽肌痉挛"这类句子,只识别出 1 个实体;微调后的 Phi-4 输出了"迷走神经""舌咽神经""呼吸肌""吞咽肌"(bod 身体部位)与"痉挛"(sym 临床表现)等多个正确实体,效果可直接肉眼对比。

用数据说话:看曲线决定何时停训

两个案例的关键指标放在一起(均取自 SwanLab 面板读数):

实验配置关键读数结论
Qwen3-1.7B 全参2 epoch,lr=1e-4step 500:train loss 1.2042 / eval loss 1.1426;第 2 个 epoch 后 train loss 跌破 0.6,eval loss 从 1.12 反弹到 1.2 附近典型过拟合,2000 条数据全参只训 1 个 epoch 足够
Phi-4 LoRA NER1 epoch,120 步train loss 3.4 → 0.3287,grad norm 峰值 0.3958单 epoch 收敛平稳,无过拟合迹象

怎么依据曲线做决策:

  • 判断过拟合:看两条曲线的"剪刀口"。eval loss 比 train loss 持续高出 0.3 以上且掉头向上,就停训,回取分离前的 checkpoint。
  • 控制训练量:小数据(千条级)配全参微调,1 个 epoch 通常是上限,多训只会变差。
  • 验证调度:面板里的 learning rate 曲线能直接核对你的调度策略(linear/cosine)是否生效;loss 震荡时优先换调度、加大 warmup。
  • 别只看数字:每 epoch 记录 3–5 条模型输出(swanlab.Text),loss 低不代表回答对。

避坑手册:五个高频问题

  • 现象:CUDA out of memory。原因:batch 过大或显存不足(1.7B 全参约需 32GB)。解法:batch_size 降到 1,加 gradient_checkpointing=True,或改用 LoRA/4bit 量化。
  • 现象:警告use_cache=True is incompatible with gradient checkpointing。原因:Trainer 与梯度检查点默认行为冲突,transformers 会自动关闭缓存。解法:训练阶段属正常提示,可忽略;纯推理时需手动model.config.use_cache=True。
  • 现象:loss 大幅震荡不收敛。原因:学习率偏大或缺少 warmup。解法:lr 降到 5e-5,增加 warmup_steps(如 100)后重跑。
  • 现象:train loss 一路降、eval loss 反升。原因:过拟合(见"用数据说话"一节)。解法:减少 epoch,LoRA 场景把 lora_dropout 提到 0.2 或降低 r。
  • 现象:SwanLab 云端看不到实验数据。原因:API Key 未配置或未登录。解法:日志始终保存在本地 ./swanlog,可用swanlab watch ./swanlog离线查看,下次启动时再完成登录。

小结与进阶

  • 接入 SwanLab 只需 report_to="swanlab" 加一个 callback,两行代码,别手写 logging
  • 停训依据两条曲线的分离程度:eval loss 反超即停,取最佳 checkpoint
  • 用 swanlab.Text 每轮记几条推理输出,比单看 loss 更可靠
  • 超参数写进 SwanLabCallback 的 config,下次复现直接对照面板
  • 训练前先定好判停规则,而不是训完再找理由

进阶方向:GRPO 强化学习微调(仓库提供 Qwen3-8B 完整 Notebook)、EvalScope 并发压测、QLoRA 4bit 量化进一步压显存。

仓库内相关案例:

  • 医学问答全参微调:09-Qwen3-1.7B-医学推理式对话微调 及 SwanLab 可视化记录.md
  • 法律问答 LoRA 微调:05-Qwen2.5-Coder-7B-Instruct Lora 微调 SwanLab 可视化记录版.md
  • 医疗 NER LoRA 微调:05-Phi-4-Lora 微调 命名实体识别.md
  • GRPO 强化学习:10-Qwen3-8B GRPO微调及通过swanlab可视化.md

执行git clone https://gitcode.com/datawhalechina/self-llm获取全部案例,挑一个场景今天就跑起来。

【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调(全参数/Lora)、部署国内外开源大模型(LLM)/多模态大模型(MLLM)教程项目地址: https://gitcode.com/datawhalechina/self-llm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表