18.人工智能实战:LoRA 微调后效果不升反降?从数据清洗到训练参数的完整排查方案

人工智能实战:LoRA 微调后效果不升反降?从数据清洗到训练参数的完整排查方案


一、问题场景:训练跑通了,但模型变笨了

很多团队在做大模型应用时,都会遇到这样的问题:

text 复制代码
通用模型能用,但不够贴合业务。

于是开始尝试 LoRA 微调。

第一版训练通常很顺利:

text 复制代码
数据准备好了
训练脚本跑起来了
loss 也下降了
模型也成功保存了

但一测试发现:

text 复制代码
1. 模型回答变啰嗦
2. 原本会的问题不会了
3. 业务问题没有明显提升
4. 输出格式更不稳定
5. 有些答案明显过拟合训练样本

这就是 LoRA 微调里非常常见的问题:

text 复制代码
训练成功 ≠ 效果变好。

这篇文章解决的问题是:

text 复制代码
LoRA 微调后效果不升反降,如何从数据、参数、评测、合并、推理五个方面系统排查。

二、LoRA 适合解决什么问题?

LoRA 不是万能的。

适合:

text 复制代码
1. 固定输出风格
2. 特定格式生成
3. 领域术语表达
4. 指令遵循增强
5. 小范围业务适配

不适合:

text 复制代码
1. 给模型注入大量新知识
2. 替代 RAG
3. 修复基础推理能力
4. 让小模型突然具备大模型能力

如果你的目标是:

text 复制代码
让模型记住公司所有制度

更适合:

text 复制代码
RAG

如果你的目标是:

text 复制代码
让模型按照固定格式输出审批意见

LoRA 更合适。


三、问题根因:大多数 LoRA 失败不是算法问题

LoRA 效果差,常见原因是:

text 复制代码
1. 数据质量差
2. 数据量太少或太重复
3. 指令格式不统一
4. 学习率过高
5. 训练轮数过多
6. 没有评测集
7. 推理时 prompt 和训练格式不一致

其中最常见的是:

text 复制代码
数据问题。

不是代码问题。


四、准备训练数据

推荐 JSONL 格式:

json 复制代码
{"instruction": "请根据用户问题生成客服回复", "input": "用户说退款不到账怎么办?", "output": "您好,退款到账时间通常为1-3个工作日,请您先确认原支付渠道。"}
{"instruction": "请根据用户问题生成客服回复", "input": "用户说订单物流不更新怎么办?", "output": "您好,物流信息可能存在延迟,建议您等待24小时后再次查看。"}

每条样本必须包含:

text 复制代码
instruction
input
output

不要混乱。


五、数据清洗脚本

python 复制代码
import json

def clean_jsonl(input_path: str, output_path: str):
    seen = set()
    cleaned = []

    with open(input_path, "r", encoding="utf-8") as f:
        for line in f:
            item = json.loads(line)

            instruction = item.get("instruction", "").strip()
            user_input = item.get("input", "").strip()
            output = item.get("output", "").strip()

            if not instruction or not output:
                continue

            key = instruction + user_input + output

            if key in seen:
                continue

            seen.add(key)

            if len(output) < 5:
                continue

            cleaned.append({
                "instruction": instruction,
                "input": user_input,
                "output": output
            })

    with open(output_path, "w", encoding="utf-8") as f:
        for item in cleaned:
            f.write(json.dumps(item, ensure_ascii=False) + "\n")

    print("cleaned:", len(cleaned))


clean_jsonl("train_raw.jsonl", "train_clean.jsonl")

清洗重点:

text 复制代码
1. 去空样本
2. 去重复样本
3. 去过短输出
4. 统一字段格式

六、训练前必须拆分评测集

错误做法:

text 复制代码
所有数据都拿去训练

正确做法:

text 复制代码
train 90%
eval 10%

示例:

python 复制代码
import json
import random

def split_dataset(path: str):
    with open(path, "r", encoding="utf-8") as f:
        data = [json.loads(line) for line in f]

    random.shuffle(data)

    split = int(len(data) * 0.9)

    train = data[:split]
    eval_data = data[split:]

    for name, items in [("train.jsonl", train), ("eval.jsonl", eval_data)]:
        with open(name, "w", encoding="utf-8") as f:
            for item in items:
                f.write(json.dumps(item, ensure_ascii=False) + "\n")

    print("train:", len(train), "eval:", len(eval_data))


split_dataset("train_clean.jsonl")

七、训练参数建议

LoRA 常见参数:

text 复制代码
r:8 / 16 / 32
lora_alpha:16 / 32
learning_rate:1e-4 ~ 2e-4
epochs:2~3
batch_size:根据显存

保守起步:

text 复制代码
r=8
lora_alpha=16
learning_rate=1e-4
epochs=2

如果数据很少,不要训练太多轮。

否则很容易过拟合。


八、使用 PEFT 加载 LoRA

安装:

bash 复制代码
pip install peft transformers accelerate

示例:

python 复制代码
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig, get_peft_model

model_name = "Qwen/Qwen2.5-0.5B-Instruct"

tokenizer = AutoTokenizer.from_pretrained(
    model_name,
    trust_remote_code=True
)

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    device_map="auto",
    trust_remote_code=True
)

config = LoraConfig(
    r=8,
    lora_alpha=16,
    target_modules=["q_proj", "v_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

model = get_peft_model(model, config)

model.print_trainable_parameters()

九、训练格式必须和推理格式一致

训练时格式:

text 复制代码
### 指令:
{instruction}

### 输入:
{input}

### 回答:
{output}

那么推理时也要保持:

python 复制代码
def build_prompt(instruction: str, user_input: str):
    return f"""
### 指令:
{instruction}

### 输入:
{user_input}

### 回答:
"""

如果训练和推理格式不一致,效果会明显下降。


十、评测不能只看 loss

loss 下降不代表业务效果提升。

必须准备固定测试问题:

python 复制代码
eval_questions = [
    "用户说退款一直没到账怎么办?",
    "用户投诉物流不更新怎么回复?",
    "用户要求人工客服怎么处理?"
]

对比:

text 复制代码
base model 输出
LoRA model 输出

评估维度:

text 复制代码
1. 是否符合业务语气
2. 是否包含关键信息
3. 是否编造规则
4. 是否格式稳定
5. 是否比原模型更好

十一、推理加载 LoRA

python 复制代码
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel

base_model = "Qwen/Qwen2.5-0.5B-Instruct"
lora_path = "./lora-output"

tokenizer = AutoTokenizer.from_pretrained(base_model, trust_remote_code=True)

model = AutoModelForCausalLM.from_pretrained(
    base_model,
    device_map="auto",
    trust_remote_code=True
)

model = PeftModel.from_pretrained(model, lora_path)
model.eval()

推理:

python 复制代码
import torch

prompt = build_prompt(
    "请根据用户问题生成客服回复",
    "用户说退款一直没到账怎么办?"
)

inputs = tokenizer(prompt, return_tensors="pt").to(model.device)

with torch.inference_mode():
    outputs = model.generate(
        **inputs,
        max_new_tokens=256,
        temperature=0.3
    )

print(tokenizer.decode(outputs[0], skip_special_tokens=True))

十二、踩坑记录

坑 1:用低质量数据训练

LoRA 会放大数据问题。

垃圾数据越多,模型越不稳定。


坑 2:训练轮数过多

数据量少时,epochs 太多会过拟合。

表现为:

text 复制代码
模型总是输出训练集里的固定句式。

坑 3:学习率过高

学习率过高会破坏原模型能力。

建议从:

text 复制代码
1e-4

开始。


坑 4:target_modules 随便填

不同模型结构不同。

不要照抄别人的 target_modules。


坑 5:不做基线对比

必须比较:

text 复制代码
base model vs LoRA model

否则你不知道是否真的提升。


十三、适合收藏的 LoRA 排查 Checklist

text 复制代码
目标:
[ ] 是否明确 LoRA 要解决的问题
[ ] 是否不把 LoRA 当知识库
[ ] 是否适合用微调解决

数据:
[ ] 是否去重
[ ] 是否清洗
[ ] 是否统一格式
[ ] 是否拆分评测集
[ ] 是否覆盖真实业务问题

训练:
[ ] 学习率是否合理
[ ] epoch 是否过多
[ ] r / alpha 是否保守
[ ] target_modules 是否正确

评测:
[ ] 是否和 base model 对比
[ ] 是否有固定测试集
[ ] 是否人工评估业务效果
[ ] 是否检查幻觉和格式

上线:
[ ] 推理 prompt 是否和训练一致
[ ] 是否保留回滚方案
[ ] 是否灰度测试

十四、经验总结

LoRA 微调不是"把数据扔进去训练一下"。

真正决定效果的是:

text 复制代码
1. 数据质量
2. 任务边界
3. 训练格式
4. 参数控制
5. 评测体系

一句话总结:

text 复制代码
LoRA 不是让模型学更多知识,而是让模型更稳定地执行某类任务。

十五、优化建议

后续可以继续做:

text 复制代码
1. 增加高质量人工标注数据
2. 构建自动评测集
3. 对 badcase 做定向补充
4. 尝试不同 r 和 learning_rate
5. 使用 DPO 优化偏好输出
6. 将 LoRA 与 RAG 结合
7. 灰度上线对比真实用户反馈

最后一句经验:

text 复制代码
微调最怕的不是训练失败,而是训练成功后你以为它变好了。
相关推荐
davedeveloper1 小时前
ReAct 论文深度解读:让大模型学会“边想边做“
人工智能
2601_956414141 小时前
2026年5月PCB厂家推荐:TOP5榜产品应对5G基站散热挑战
大数据·人工智能·5g
生成论实验室1 小时前
《源·觉·知·行·事·物:生成论视域下的统一认知语法》导论:在破碎的世界寻找统一语法
人工智能·科技·算法·架构·创业创新
zhutier-1 小时前
国科大交叉学院二次选拔笔试2025 AI方向基础知识整理存档
人工智能
嵌入式老牛2 小时前
液晶段码(米/日字格)识别—预处理
人工智能·opencv·计算机视觉
comcoo2 小时前
本地 AI 智能体 OpenClaw 部署实操教程
人工智能·openclaw安装包·龙虾ai·open claw部署
@不误正业2 小时前
第13章-开源鸿蒙是否适合做端侧AI操作系统
人工智能·开源·harmonyos
冬奇Lab2 小时前
RAG 系列(六):向量数据库——存储与检索的基础设施
数据库·人工智能·llm
Agent手记2 小时前
首件检验流程繁琐,耗时久还容易出现合规漏洞怎么办?——基于实在Agent的AI+超自动化全流程闭环实战
网络·人工智能·ai·自动化