大模型法律微调实战:从数据准备到LoRA训练与验证
大模型法律微调实战:从数据准备到LoRA训练与验证
如果你手头有法律问答数据,想用开源大模型训练一个能回答法律问题的助手,本文给出可落地的LoRA微调流程。
适用环境:Linux服务器(Ubuntu 22.04)、单张24GB显存显卡、Python 3.10。
不涉及全参数微调,显存要求更低,适合零基础起步。
环境准备:安装依赖与下载基座模型
先创建虚拟环境并安装核心库。
以下命令在服务器终端执行:
python3 -m venv legal-ft
source legal-ft/bin/activate
pip install torch transformers datasets peft accelerate bitsandbytes
接着下载基座模型。
以Qwen2.5-7B-Instruct为例,用Hugging Face镜像加速:
export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download Qwen/Qwen2.5-7B-Instruct --local-dir ./qwen2.5-7b
如果服务器无法直连外网,提前在可联网机器下载后通过scp上传,目录结构保持一致。
数据格式:法律问答对怎么整理
微调数据需要整理成JSONL格式,每行一个样本,包含instruction(问题)和output(回答)。
示例:
{"instruction": "劳动合同到期不续签,用人单位需要支付经济补偿吗?", "output": "根据《劳动合同法》第四十六条,除用人单位维持或提高劳动合同约定条件续订而劳动者不同意外,固定期限劳动合同期满终止的,用人单位应当支付经济补偿。"}
建议准备500~2000条高质量问答,覆盖常见法律场景(劳动、婚姻、合同、侵权)。
数据要干净,避免错别字和无关内容。
用datasets库加载:
from datasets import load_dataset
ds = load_dataset('json', data_files='legal_data.jsonl', split='train')
训练配置:LoRA参数与启动命令
使用PEFT库的LoRA,只训练少量低秩矩阵。
创建train.py:
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from peft import LoraConfig, get_peft_model
from trl import SFTTrainer
model = AutoModelForCausalLM.from_pretrained('./qwen2.5-7b', device_map='auto')
tokenizer = AutoTokenizer.from_pretrained('./qwen2.5-7b')
lora_config = LoraConfig(r=8, lora_alpha=16, target_modules=['q_proj','v_proj'], lora_dropout=0.05, bias='none')
model = get_peft_model(model, lora_config)
training_args = TrainingArguments(
output_dir='./legal-lora',
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
num_train_epochs=3,
learning_rate=2e-4,
logging_steps=10,
save_strategy='epoch',
fp16=True
)
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=ds,
tokenizer=tokenizer,
dataset_text_field='instruction',
max_seq_length=512
)
trainer.train()
trainer.save_model('./legal-lora-final')
运行python train.py启动训练。
显存不足时,把per_device_train_batch_size降到1,或启用gradient_checkpointing=True。
避坑与验证:常见报错和效果检查
训练中容易遇到两个问题:一是CUDA out of memory,按上文降低batch size或使用4bit量化加载(load_in_4bit=True);
二是loss不下降,检查数据格式是否被正确解析,可先用print(ds[0])确认字段。
训练完成后,用以下脚本测试模型回答:
from peft import PeftModel
base = AutoModelForCausalLM.from_pretrained('./qwen2.5-7b', device_map='auto')
model = PeftModel.from_pretrained(base, './legal-lora-final')
inputs = tokenizer('劳动合同到期不续签,用人单位需要支付经济补偿吗?', return_tensors='pt')
out = model.generate(**inputs, max_new_tokens=200)
print(tokenizer.decode(out[0], skip_special_tokens=True))
观察回答是否引用了正确法条、是否出现胡编。
若回答重复或空洞,可增加数据量、降低学习率到1e-4,或减少训练轮次。
验证时建议保留20条未参与训练的问答做人工对比。
常见疑问
问:没有GPU能微调吗?
可以,但7B模型用CPU训练极慢,建议租用带GPU的云服务器,或改用更小的模型(如1.8B)并开启4bit量化。
问:数据里需要包含法条原文吗?
不强制,但回答中引用法条能提升可信度。建议在output中自然带上法条编号和关键内容。
问:训练后模型还是乱答怎么办?
先检查数据质量,再尝试增大r(如16)、增加数据量,或换用更强的基座模型。
整个流程在单卡24GB显存上约1~2小时可完成(取决于数据量),建议先在少量数据上跑通,再逐步扩大规模。