大模型微调实战手册 (SWIFT + Qwen2)
本手册详细记录了在 Windows 环境下,使用 RTX 4060 (8GB 显存) 成功微调 Qwen2-1.5B 模型的全过程、命令详解及常见问题处理。
1. 环境搭建 (Installation)
在开始微调之前,需要配置好 Python 环境及相关的 AI 库。建议使用 Python 3.10+ 环境。
第一步:创建并激活虚拟环境
bash
# 创建虚拟环境
python -m venv .venv
# 激活虚拟环境 (Windows PowerShell)
.\.venv\Scripts\Activate.ps1
第二步:安装核心依赖包
perl
# 1. 安装 ModelScope SWIFT 框架 (核心工具)
pip install ms-swift -U
# 2. 安装 PyTorch (根据你的 CUDA 版本选择,这里以 CUDA 12.1 为例)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
# 3. 安装量化与加速工具 (8G 显存必备)
pip install bitsandbytes # 提供 4-bit 量化支持
pip install accelerate # 显存优化与加速
pip install peft # LoRA 核心库
pip install transformers -U # 确保 Transformers 库是最新的
第三步:验证安装
bash
# 检查 SWIFT 是否安装成功
swift --version
2. 快速开始流程
第一步:准备数据集 my_data.jsonl
数据集应包含多种提问方式,以增强模型的泛化能力。
json
{"instruction": "这件衬衫多少钱?", "output": "这件衬衫的价格是19.9美元。"}
{"instruction": "衬衫单价是多少?", "output": "这件衬衫的价格是19.9美元。"}
{"instruction": "Shirt price please.", "output": "这件衬衫的价格是19.9美元。"}
第二步:执行微调 (SFT)
lua
swift sft `
--model qwen/Qwen2-1.5B-Instruct `
--train_type lora `
--dataset "d:\ACode\demo\my_data.jsonl" `
--quant_bits 4 `
--max_length 256 `
--per_device_train_batch_size 1 `
--gradient_accumulation_steps 4 `
--learning_rate 1e-4 `
--num_train_epochs 5 `
--lora_rank 8 `
--lora_alpha 32 `
--logging_steps 1 `
--output_dir "d:\ACode\demo\output"
第三步:推理测试 (Inference)
arduino
swift infer --adapters "D:\ACode\demo\output\v0-xxxxxxxx-xxxxxx\checkpoint-65"
第四步:合并导出 (Export)
r
swift export `
--adapters "D:\ACode\demo\output\v0-xxxxxxxx-xxxxxx\checkpoint-65" `
--merge_lora true
3. 合并后的模型使用 (Usage)
合并(Merged)后的模型已经将 LoRA 权重融入了底座模型,它现在是一个完整的、独立的 模型文件夹(通常位于 checkpoint-xxx/merged 目录下)。
方法一:使用 SWIFT 推理 (最简单)
合并后的模型不再需要 --adapters 参数,直接作为普通模型加载即可:
bash
# 这里的 --model 指向合并后的完整目录
swift infer --model "D:\ACode\demo\output\v0-xxx\checkpoint-65\merged"
方法二:使用原生 Transformers 库 (Python 代码)
你可以像使用任何 HuggingFace/ModelScope 模型一样加载它:
ini
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
model_path = "D:/ACode/demo/output/v0-xxx/checkpoint-65/merged"
# 加载分词器和模型
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.bfloat16, device_map="auto", trust_remote_code=True)
# 进行对话测试
inputs = tokenizer("这件衬衫多少钱?", return_tensors="pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens=128)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
方法三:第三方工具部署 (部署神器)
因为合并后的模型结构与原始 Qwen2 完全一致,你可以直接将其导入:
- LM Studio / Ollama:将合并后的目录导入或转换为 GGUF 格式即可使用。
- API 服务 :使用
vLLM或FastChat快速搭建自己的 API 服务器。
4. 核心命令参数详解
swift sft (有监督微调)
| 参数名 | 解释 | 建议值 |
|---|---|---|
--model |
指定底座模型 ID 或路径 | qwen/Qwen2-1.5B-Instruct |
--train_type |
训练方法 | lora (轻量化插件式微调) |
--quant_bits |
量化位数 | 4 (8G 显存必选,显著降低占用) |
--max_length |
单条数据最大长度 | 256 (根据任务复杂度调整) |
--per_device_train_batch_size |
单卡批大小 | 1 (显存小时设为 1) |
--gradient_accumulation_steps |
梯度累积步数 | 4 (模拟更大的 Batch Size) |
--learning_rate |
学习率 | 1e-4 (LoRA 训练常用值) |
--num_train_epochs |
训练总轮数 | 5 (视任务复杂度而定) |
--lora_rank |
LoRA 的秩 | 8 或 16 (越大表达力越强) |
--logging_steps |
日志打印频率 | 1 (每一小步都显示,方便监控) |
swift infer (模型推理)
| 参数名 | 解释 | 说明 |
|---|---|---|
--adapters |
指向训练好的 checkpoint 文件夹 | 必须包含 adapter_config.json |
--stream |
是否开启流式输出 | true (像 ChatGPT 一样弹出文字) |
--quant_bits |
推理量化位数 | 0 (1.5B 模型推理时不量化更稳定) |
swift export (导出合并)
| 参数名 | 解释 | 说明 |
|---|---|---|
--merge_lora |
是否将 LoRA 权重合并入主模型 | true (生成可独立使用的模型) |
4. 常见问题 (FAQ)
Q: 为什么命令执行后 output 文件夹里没有东西?
A : SWIFT 在启动阶段需要进行模型下载、加载和 4-bit 量化,这通常需要 30-60 秒。在量化完成并开始第一个训练步之前,不会写入日志。
Q: 遇到 ambiguous option 错误怎么办?
A : 这是 SWIFT v3 的参数名歧义。例如使用 --merge_lora true 而不是模糊的 --merge。
Q: 8GB 显存如何进一步优化?
A:
- 减小
--max_length(例如设为 128)。 - 确保开启
--gradient_checkpointing true。 - 关闭浏览器等占用 GPU 资源的后台程序。
5. 目录结构参考
bash
demo/
├── my_data.jsonl # 原始数据集
├── output/ # 训练输出目录
│ └── v0-xxx-xxx/ # 某次训练的任务文件夹
│ ├── checkpoint-65/ # 训练生成的权重
│ └── logging.jsonl # 训练日志
└── .venv/ # Python 虚拟环境