Gemma 4 模型微调(Fine-Tuning)学习笔记
来源:Datawhale AI 学习营 Day3-7
Notebook:gemma4_emotion_lora_modelscope_single_gpu.ipynb
日期:2026-06-11
ipynb文件下载地址
一、什么是微调
微调 = 在已训练好的通用模型基础上,用专精数据再训练,使其成为领域"专家"。
- 预训练 = 学会通识
- 微调 = 专精特训
二、Notebook 逐 Cell 详解
Notebook 共 21 个 Cell,分为 16 个逻辑步骤。下面逐一说明代码逻辑与输出含义。
0. 前提
需要执行以下命令(删除旧 torchvision):
bash
pip uninstall torchvision
Cell 1:安装依赖
python
!uv pip install -U vllm modelscope transformers accelerate datasets trl peft scikit-learn pandas tqdm torchvision \
--no-cache -i https://mirrors.cloud.tencent.com/pypi/simple/ \
--extra-index-url https://wheels.vllm.ai/rocm/
| 包名 | 作用 |
|---|---|
modelscope |
从阿里魔搭下载模型和数据集 |
transformers |
加载 Gemma 模型和 tokenizer |
datasets |
从本地 parquet 加载数据 |
trl |
提供 SFTTrainer 做指令微调 |
peft |
配置 LoRA 微调 |
scikit-learn |
计算 accuracy、F1、混淆矩阵 |
vllm |
推理加速引擎(用于后续对话) |
AMD ROCm 环境:使用腾讯云 pip 源 + ROCm wheels 源。
Cell 2:导入依赖与全局配置
python
MODELSCOPE_MODEL_ID = "google/gemma-4-E4B-it"
OUTPUT_DIR = "./gemma4-it-emotion-lora-ms-single-gpu"
TRAIN_LIMIT = 4000 # 先用小数据跑通
VALIDATION_LIMIT = 400
TEST_LIMIT = 400
MODEL_DTYPE = torch.bfloat16
SYSTEM_PROMPT = """You are an emotion classification assistant.
Read the user's text and answer with exactly one label.
Only choose from: sadness, joy, love, anger, fear, surprise.
Return only the label and nothing else."""
关键参数说明:
TRAIN_LIMIT=4000:只用全量 16000 条中的 4000 条训练,快速验证流程MODEL_DTYPE=torch.bfloat16:使用 BF16 精度节省显存。若显卡不支持,改torch.float16SYSTEM_PROMPT:告诉模型只输出 6 个情绪标签之一,不做多余解释
输出:
torch version: 2.10.0+git8514f05
torch.cuda.is_available(): True
torch.cuda.device_count(): 1
current device: 0
device name: AMD Radeon Graphics
torch.cuda.is_available()返回True--- 即使是在 AMD ROCm 上,PyTorch 统一使用cuda接口AMD Radeon Graphics--- 确认 ROCm 正确识别了 AMD GPU
Cell 3:固定随机种子
python
def setup_seed(seed: int = 42):
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
set_seed(seed)
if torch.cuda.is_available():
torch.cuda.manual_seed_all(seed)
确保数据 shuffle、LoRA 初始化、训练过程可复现。
Cell 4:从魔搭下载 Gemma 模型
python
model_dir = snapshot_download(
MODELSCOPE_MODEL_ID,
cache_dir="./models",
)
LOCAL_MODEL_DIR = model_dir
输出:
Downloading model from ModelScope...
ModelScope model id: google/gemma-4-E4B-it
Downloading Model from https://www.modelscope.cn to directory: ./models/google/gemma-4-E4B-it
Downloaded model dir: ./models/google/gemma-4-E4B-it
与 Hugging Face 版本的差异:
- 不需要
HF_TOKEN,完全脱离 HF Hub- 从魔搭(国内)下载,速度快、无需科学上网
- 下载后使用本地路径加载,后续离线可用
Cell 5:加载 emotion 数据集
python
dataset_dir = dataset_snapshot_download(
MODELSCOPE_DATASET_ID, # "AI-ModelScope/emotion"
cache_dir="./datasets",
)
# 从本地 parquet 文件加载
raw_dataset = load_dataset("parquet", data_files={...})
# 将 label 字段从 int64 显式转为 ClassLabel
raw_dataset[split] = raw_dataset[split].cast_column(
"label", ClassLabel(names=["sadness","joy","love","anger","fear","surprise"])
)
输出:
Raw dataset: DatasetDict({
train: Dataset({ features: ['text', 'label'], num_rows: 16000 })
validation: Dataset({ features: ['text', 'label'], num_rows: 2000 })
test: Dataset({ features: ['text', 'label'], num_rows: 2000 })
})
Subset:
train: 4000 validation: 400 test: 400
label_names: ['sadness', 'joy', 'love', 'anger', 'fear', 'surprise']
example: {'text': 'while cycling in the country', 'label': 4}
数据集结构:
text:英文句子label:整数索引(0→sadness, 1→joy, 2→love, 3→anger, 4→fear, 5→surprise)- 代码里
dataset_snapshot_download拉取的是 raw parquet 文件,绕过MsDataset桥接层,避免as_dataset()版本兼容报错
Cell 6:构造 Prompt-Completion 格式
python
def to_prompt_completion(example):
text = example["text"]
label = label_names[example["label"]]
user_content = f"Classify the emotion of this text:\n\n{text}"
return {
"prompt": [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_content},
],
"completion": [
{"role": "assistant", "content": label},
],
}
转换原理 :原始分类数据(text → label)被转为聊天模型的对话格式(messages 列表),Gemma 4 的 tokenizer 自带 chat_template.jinja,会自动将 messages 渲染为模型期望的输入格式。
输出示例:
{'prompt': [
{'role': 'system', 'content': 'You are an emotion classification assistant...'},
{'role': 'user', 'content': 'Classify the emotion of this text:\n\nwhile cycling in the country'}
],
'completion': [{'role': 'assistant', 'content': 'fear'}]}
Cell 7:加载 Tokenizer 和基础模型
python
tokenizer = AutoTokenizer.from_pretrained(LOCAL_MODEL_DIR, use_fast=True)
base_model = AutoModelForCausalLM.from_pretrained(
LOCAL_MODEL_DIR,
torch_dtype=MODEL_DTYPE, # torch.bfloat16
low_cpu_mem_usage=True,
)
base_model.to(device) # 移到 GPU
base_model.config.use_cache = False # 训练时关闭 cache
输出:
pad_token: <pad>
eos_token: <eos>
chat_template probe output:
<bos><|turn>system
You are a helpful assistant.<turn|>
<|turn>user
Hello<turn|>
<|turn>model
Loading base model from: ./models/google/gemma-4-E4B-it
Using device: cuda
HIP version: 7.2.53211
Base model device: cuda:0
关键点:
chat_template自检成功,输出 Gemma 4 的对话模板格式use_cache=False:训练时需关闭 KV CacheHIP version: 7.2.53211:确认是 AMD ROCm 的 HIP 后端
Cell 8:推理辅助函数
python
def extract_label(raw_text: str) -> str:
# 先尝试正则匹配 6 个合法标签
match = LABEL_PATTERN.search(raw_text.strip().lower())
if match:
return match.group(1)
# 兜底:取第一个 token
tokens = raw_text.split()
return tokens[0].strip(".,!?:;\"'()[]{}") if tokens else "INVALID"
def generate_label(model, tokenizer, user_text, system_prompt, max_new_tokens=4):
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"Classify the emotion of this text:\n\n{user_text}"},
]
inputs = tokenizer.apply_chat_template(messages, tokenize=True, ...)
outputs = model.generate(**inputs, max_new_tokens=max_new_tokens, do_sample=False)
raw_pred = tokenizer.decode(outputs[0][input_len:], skip_special_tokens=True)
return extract_label(raw_pred)
# 验证
predict_emotion("I feel so happy and excited today!")
# 输出: 'joy'
设计要点:
max_new_tokens=4:情绪标签很短,限制生成长度节省时间do_sample=False:贪婪解码,保证结果确定性extract_label先正则匹配,未匹配则取第一个 token,仍不合法则标INVALID- 测试
"I feel so happy"返回joy,说明基础模型具备基本的情绪分类能力
Cell 9:评估函数
python
def evaluate_model(model, tokenizer, split="test", limit=EVAL_LIMIT):
for ex in tqdm(raw_source):
true_label = label_names[ex["label"]]
raw_pred_label = generate_label(model, tokenizer, ex["text"])
pred_label = raw_pred_label if raw_pred_label in VALID_LABELS else "INVALID"
# 累积 y_true, y_pred, rows
metrics = {
"accuracy": accuracy_score(y_true, y_pred),
"macro_f1": f1_score(y_true, y_pred, average="macro"),
"invalid_predictions": sum(1 for p in y_pred if p == "INVALID"),
"evaluated_examples": len(y_true),
}
return metrics, report, pd.DataFrame(rows)
def confusion_matrix_df(pred_df):
return pd.DataFrame(
confusion_matrix(pred_df["true_label"], pred_df["pred_label"],
labels=ALL_EVAL_LABELS), # ["sadness",...,"INVALID"]
index=ALL_EVAL_LABELS, columns=ALL_EVAL_LABELS,
)
评估维度:
- accuracy:正确预测比例
- macro_f1:每个类别 F1 的简单平均,对样本不均衡更公平
- invalid_predictions:模型输出非 6 类标签的次数
- confusion_matrix:行=真实标签,列=预测标签,对角线=正确数
Cell 10:微调前评估(基线)
python
pre_metrics, pre_report, pre_preds = evaluate_model(base_model, tokenizer, split="test", limit=EVAL_LIMIT)
pre_metrics
输出:
python
{'accuracy': 0.625,
'macro_f1': 0.4824237718715574,
'invalid_predictions': 2,
'evaluated_examples': 400}
分析:
- 准确率 62.5% --- 比随机猜测(1/6 ≈ 16.7%)好,但对情绪分类任务远远不够
- macro F1 仅 0.482 --- 说明模型在少数类别(love、surprise)上表现很差
- 2 个 INVALID --- 基础模型偶尔不按格式输出
Cell 11:微调前分类报告
python
pd.DataFrame(pre_report).transpose()
输出(核心行):
precision recall f1-score support
sadness 0.551 0.851 0.669 114
joy 0.772 0.710 0.740 162
love 0.375 0.231 0.286 26
anger 0.625 0.319 0.423 47
fear 0.667 0.333 0.444 36
surprise 0.333 0.333 0.333 15
分析:
joy样本最多(162),表现相对好(F1=0.740)love样本少(26),recall 仅 0.231 --- 模型经常把 love 误判为 joysurprise样本最少(15),F1 仅 0.333- 整体趋势:样本量越大的类别,效果越好
Cell 12:微调前混淆矩阵
sadness joy love anger fear surprise INVALID
sadness 97 10 1 2 2 1 1
joy 25 115 7 6 2 6 1
love 7 13 6 0 0 0 0
anger 26 3 1 15 2 0 0
fear 16 4 0 1 12 3 0
surprise 5 4 1 0 0 5 0
解读:
- 行 = 真实标签,列 = 模型预测
- 对角线 = 猜对的数量
- 第 1 行(sadness):97 条猜对,但 25 条被误判为 joy --- 两类别语义接近
anger→sadness误判 26 条(47 条中超过一半被误判为 sadness)love仅 6/26 猜对,其余被分到 sadness/joy
Cell 13:配置 LoRA
python
lora_config = LoraConfig(
r=16, # LoRA 秩,越大表达能力越强,显存开销越大
lora_alpha=32, # 缩放系数,通常为 r 的 2 倍
lora_dropout=0.05, # Dropout 防过拟合
bias="none", # 不训练 bias
task_type="CAUSAL_LM",
target_modules="all-linear", # 所有线性层都加 LoRA
)
参数解析:
r=16:LoRA 的核心超参数。rank 越大,可训练参数越多,但显存也越大。16 是常见起点lora_alpha=32:权重缩放系数,实际缩放 =alpha / r。32/16=2,即 LoRA 权重乘以 2target_modules="all-linear":给模型中所有线性层加 LoRA(包括 Q/K/V/O、MLP 等),适合首次跑通
Cell 14:定义训练参数(SFTConfig)
python
training_args = SFTConfig(
output_dir=OUTPUT_DIR,
per_device_train_batch_size=4, # 每张卡 batch size
gradient_accumulation_steps=4, # 梯度累积步数
# 等效 batch size = 4 × 4 = 16
learning_rate=1e-4,
weight_decay=0.01,
lr_scheduler_type="linear", # 线性学习率衰减
warmup_steps=50, # warmup 步数
num_train_epochs=1, # 只训练 1 轮
logging_steps=5, # 每 5 步打印一次 loss
eval_strategy="steps",
eval_steps=25, # 每 25 步评估一次
gradient_checkpointing=True, # 节省显存(以时间换空间)
bf16=BF16,
fp16=FP16,
max_length=256, # 最大序列长度
completion_only_loss=True, # 只计算 assistant 部分的 loss(排除 system/user)
optim="adamw_torch", # 使用 PyTorch 原生 AdamW,避免 bitsandbytes 在 ROCm 的兼容问题
)
关键参数解释:
completion_only_loss=True:训练时只对 assistant 回复部分计算 loss,system 和 user 部分不参与。这确保模型只学习"如何输出标签",不记忆 prompt 模板per_device_batch=4 + grad_accum=4:等效 batch=16。显存不够时可降为1+4或2+2gradient_checkpointing=True:不存中间激活值,需要时重算。节省约 30-50% 显存,减慢约 20% 速度optim="adamw_torch":AMD ROCm 下bitsandbytes的 8-bit 优化器兼容性不稳定,使用原生 PyTorch 实现更可靠
Cell 15:开始 LoRA 微调
python
trainer = SFTTrainer(
model=base_model,
train_dataset=sft_dataset["train"],
eval_dataset=sft_dataset["validation"],
peft_config=lora_config,
args=training_args,
processing_class=tokenizer,
)
train_result = trainer.train()
(A) 参数统计输出:
Trainable LoRA parameters: 50,499,584
Total parameters: 7,991,600,416
Trainable ratio: 0.6319%
分析:
- 总参数约 79.9 亿(Gemma-4-E4B 规模)
- LoRA 可训练参数仅 5049 万 ,占 0.63%
- 训练如此少的参数就能显著提升效果,正是 LoRA 的核心价值
(B) 训练进度输出:
[250/250 16:52, Epoch 1/1]
训练 250 步,耗时约 17 分钟(含评估时间)
© 训练日志表(每 25 步记录一次):
| Step | Training Loss | Validation Loss | Mean Token Acc |
|---|---|---|---|
| 25 | 0.577 | 0.405 | 0.846 |
| 50 | 0.339 | 0.302 | 0.899 |
| 75 | 0.205 | 0.228 | 0.930 |
| 100 | 0.154 | 0.182 | 0.940 |
| 125 | 0.151 | 0.158 | 0.944 |
| 150 | 0.123 | 0.152 | 0.944 |
| 175 | 0.117 | 0.134 | 0.950 |
| 200 | 0.110 | 0.113 | 0.952 |
| 225 | 0.111 | 0.095 | 0.964 |
| 250 | 0.103 | 0.089 | 0.963 |
趋势解读:
- Training Loss 从 0.577 降至 0.103,持续下降说明模型在学习
- Validation Loss 从 0.405 降至 0.089,同步下降(没有过拟合)
- Mean Token Accuracy 从 84.6% 升至 96.3%,表示下一个 token 预测准确度持续提升
- 验证 loss 仅在 Step 100-150 区间有轻微波动后继续下降,训练过程健康
(D) 最终训练指标:
TrainOutput(global_step=250, training_loss=0.3145,
metrics={
'train_runtime': 1016.15s, # 约 17 分钟
'train_samples_per_second': 3.936,
'train_steps_per_second': 0.246,
})
Cell 16:保存 LoRA Adapter
python
trainer.model.save_pretrained(OUTPUT_DIR)
tokenizer.save_pretrained(OUTPUT_DIR)
输出:
Saved adapter and tokenizer to: ./gemma4-it-emotion-lora-ms-single-gpu
保存的文件结构:
gemma4-it-emotion-lora-ms-single-gpu/
├── adapter_model.safetensors # LoRA 权重(仅 ~20MB,而非 15GB)
├── adapter_config.json # LoRA 配置(r=16, alpha=32...)
├── tokenizer.json # Tokenizer 文件
├── tokenizer_config.json
├── chat_template.jinja
├── special_tokens_map.json
├── train_metrics.json # 训练指标记录
└── checkpoint-*/ # 训练中间 checkpoint
保存的是 LoRA adapter 而非完整模型。adapter 文件仅几十 MB,后续可以合并回原模型或单独加载推理。
Cell 17:微调后评估
python
ft_model = trainer.model
post_metrics, post_report, post_preds = evaluate_model(ft_model, tokenizer, split="test", limit=EVAL_LIMIT)
post_metrics
输出:
python
{'accuracy': 0.915,
'macro_f1': 0.8644926299207644,
'invalid_predictions': 0,
'evaluated_examples': 400}
对比基线(Cell 10):
| 指标 | 微调前 | 微调后 | 提升 |
|---|---|---|---|
| accuracy | 0.625 | 0.915 | +46.4% |
| macro_f1 | 0.482 | 0.864 | +79.3% |
| invalid | 2 | 0 | 完全消除 |
分析:仅用 4000 条数据 + 1 epoch + LoRA(训练 0.63% 参数),准确率从 62.5% 提升到 91.5%。
Cell 18:微调后分类报告
precision recall f1-score support
sadness 0.923 0.947 0.935 114
joy 0.933 0.951 0.942 162
love 0.731 0.731 0.731 26
anger 1.000 0.872 0.932 47
fear 0.872 0.944 0.907 36
surprise 0.833 0.667 0.741 15
macro avg 0.882 0.852 0.864 400
对比 Cell 11:
| 类别 | 微调前 F1 | 微调后 F1 | 提升 |
|---|---|---|---|
| sadness | 0.669 | 0.935 | +39.8% |
| joy | 0.740 | 0.942 | +27.3% |
| love | 0.286 | 0.731 | +155.6% |
| anger | 0.423 | 0.932 | +120.3% |
| fear | 0.444 | 0.907 | +104.3% |
| surprise | 0.333 | 0.741 | +122.5% |
结论:
- 所有 6 个类别的 F1 都大幅提升
- 样本少的类别(love、anger、fear、surprise)提升尤其显著(+100%+),说明 LoRA 微调有效克服了数据不平衡问题
- anger 的 precision 达到 1.000,模型从未将其他类别误判为 anger
Cell 19:微调后混淆矩阵
sadness joy love anger fear surprise INVALID
sadness 108 3 1 0 2 0 0
joy 2 154 6 0 0 0 0
love 2 5 19 0 0 0 0
anger 5 1 0 41 0 0 0
fear 0 0 0 0 34 2 0
surprise 0 2 0 0 3 10 0
对比 Cell 12:
- 对角线数字显著增大(正确预测增多)
sadness→sadness:97 → 108anger→sadness错误:26 → 5(大幅减少)INVALID列为全 0 ------ 模型不再输出非 6 类的非法标签anger列几乎无值(除了对角线41)------ anger 被误判为其他类的情况极少love仍有 5 条被误判为 joy(两者语义确实接近)
Cell 20:微调前后对比表
python
comparison_df = pd.DataFrame([
{"stage": "pre_finetuning", **pre_metrics},
{"stage": "post_finetuning", **post_metrics},
])
输出:
stage accuracy macro_f1 invalid_predictions evaluated_examples
0 pre_finetuning 0.625 0.482424 2 400
1 post_finetuning 0.915 0.864493 0 400
一键对比,微调效果一目了然。
Cell 21:逐条预测对比(前 20 条展示)
预训练错误的句子,微调后大部分都纠正了。
典型案例:
| 文本 | 真实标签 | 微调前预测 | 微调后预测 |
|---|---|---|---|
| "i feel is that the most likeable characters are..." | joy | sadness ❌ | joy ✅ |
| "im feeling and if ive liked being pregnant" | love | joy ❌ | love ✅ |
| "i used to be able to hang around talk with the..." | anger | sadness ❌ | anger ✅ |
| "i feel agitated and annoyed more than worried..." | fear | anger ❌ | fear ✅ |
| "im feeling really bitter about this one" | anger | sadness ❌ | anger ✅ |
少数微调后反而错误的案例(如第 20 条):"i feel i can only hope im not alone in these tough times..." 真实标签为 sadness,微调后预测为 joy。说明模型在某些模棱两可的样本上仍不够精准,可以:
- 增加训练数据量
- 增加训练 epoch
- 调整 LoRA rank
三、核心概念
1. 数据集
AI-ModelScope/emotion(dair-ai/emotion 的魔搭镜像):
- 英文情绪分类,6 类标签
- 训练/验证/测试:16000 / 2000 / 2000
- 字段:
text(句子)、label(0-5 整数)
2. LoRA 参数详解
| 参数 | 值 | 含义 |
|---|---|---|
r |
16 | LoRA 矩阵的秩,越大参数越多 |
lora_alpha |
32 | 缩放系数,alpha/r=2 |
lora_dropout |
0.05 | 随机丢弃比例,防过拟合 |
target_modules |
all-linear | 给所有线性层加 LoRA |
| 可训练参数 | 5049 万 | 占总参 79.9 亿的 0.63% |
3. 训练配置关键参数
| 参数 | 值 | 作用 |
|---|---|---|
per_device_train_batch_size |
4 | 每张卡 batch 大小 |
gradient_accumulation_steps |
4 | 梯度累积步数(等效 batch=16) |
learning_rate |
1e-4 | AdamW 学习率 |
num_train_epochs |
1 | 训练轮数 |
max_length |
256 | 序列最大长度 |
completion_only_loss |
True | 只算 assistant 部分 loss |
gradient_checkpointing |
True | 梯度检查点省显存 |
optim |
adamw_torch | 原生 AdamW(不用 bitsandbytes) |
4. 评估指标
| 指标 | 公式/含义 |
|---|---|
| Accuracy | 正确数 / 总数 |
| Precision(精确率) | 预测为该类中真正是该类的比例 |
| Recall(召回率) | 真是该类中被找出来的比例 |
| F1 Score | 2 × P × R / (P + R),综合评分 |
| Macro F1 | 各类别 F1 的算术平均(不均衡数据更公平) |
| Invalid | 模型输出非法标签的次数 |
四、Notebook 完整流程总结
Cell 1: 安装依赖 pip install modelscope transformers trl peft ...
Cell 2: 全局配置 设置模型 ID、数据量、精度、System Prompt
Cell 3: 固定种子 42
Cell 4: 下载模型 ModelScope → ./models/google/gemma-4-E4B-it
Cell 5: 加载数据集 魔搭 emotion → parquet → DatasetDict
Cell 6: 格式转换 分类数据 → messages 对话格式
Cell 7: 加载模型 AutoTokenizer + AutoModelForCausalLM
Cell 8: 推理函数 generate_label + extract_label
Cell 9: 评估函数 accuracy / F1 / 混淆矩阵
Cell 10: 微调前评估 基线 accuracy=0.625
Cell 11: 基线分类报告 love 最差 (F1=0.286)
Cell 12: 基线混淆矩阵 anger→sadness 误判 26 条
Cell 13: LoRA 配置 r=16, alpha=32, all-linear
Cell 14: 训练配置 batch=4, lr=1e-4, epoch=1
Cell 15: ⭐ 开始训练 17 分钟,250 步,loss 0.103→0.089
Cell 16: 保存 adapter 仅 ~20MB
Cell 17: 微调后评估 提升至 accuracy=0.915
Cell 18: 微调后报告 所有类别 F1 > 0.73
Cell 19: 微调后矩阵 对角线显著增大
Cell 20: 对比表格 pre vs post 一目了然
Cell 21: 逐条对比 微调前错误→微调后纠正
五、AMD 云平台实操指南
云平台机制
使用 AMD Radeon Cloud 云平台时:
- 实例默认有
Destroy Instance按钮,必要时销毁 - 销毁后模型文件、安装的库全部丢失
- 持久化存储路径:
/network-workspace(跨实例不丢,限 20GB)
常见问题
| 问题 | 原因 | 解决 |
|---|---|---|
| 显存不够 | vLLM 对话占用显存 | 先 Ctrl+C 停掉 vLLM 再跑微调 |
| 文件"丢失" | 云平台不同实例存储独立 | 文件放 /network-workspace 或下载到本地 |
| 库装完重启没了 | 销毁后环境重建 | 用 Notebook 自动安装 |
| 训练卡住 | 正在计算中 | 看单元格 [*]=运行中 / [√]=完成 |
| LoRA 参数为 0 | target_modules 不匹配 |
检查 target_modules="all-linear" |
安全退出流程
- 下载 LoRA adapter、CSV、训练指标、截图到本地
- 回到网页 Profile → Active Instance → Destroy Instance
六、学完能做什么?
"同一通用模型 + 不同专业数据 = 不同领域的专家"
替换数据集即可迁移到不同任务:
1. 情感/意图分类
- 数据:一句话 → 一个标签
- 数据格式:
{"text": "...", "label": 0}
2. 信息提取
- 数据:非结构化文本 → 结构化字段
- 将 prompt 改为:
Extract the date, location, and person from this text:\n\n{text}
3. 格式转换
- 数据:自由文本 → 固定格式(JSON、Markdown)
- 将 completion 改为目标格式
4. 客服风格化
- 数据:用户问题 → 品牌话术回复
- 保持对话格式不变,替换训练数据即可
5. 领域问答
- 数据:领域 QA 对
- 微调后的模型在特定领域表现显著优于通用模型