本项目在局域网主机 HX-100(Ubuntu,RTX 3080 Ti 16GB 显存)上,以 /data/nvme2t/workspace/LLM-WS 为根目录,搭建了一套完整的小参数大模型微调工作区,覆盖「数据集下载 → 开源模型下载 → QLoRA 微调 → 效果对比评估 → OpenAI 兼容 API 部署」全链路。
微调效果的上限由数据决定。本项目选用 COIG-CQIA 作为统一中文指令微调数据集。
全称:Chinese Open Instruction Generalist — Quality is All You Need
来源:HuggingFace m-a-p/COIG-CQIA(BAAI 智源研究院 COIG 系列的高质量子集)
构建方式:从中文互联网(知乎、豆瓣、SegmentFault、小红书、wiki 等)采集真实问答与文章,经深度清洗、重构、人工审核构建,主打「质量至上」,贴合真实人类交互行为。
子集构成:包含 coig_pc(通用)、exam(考试)、zhihu、douban、segmentfault、logi(逻辑)、fitness 等多个子集,覆盖问答、写作、推理、考试、生活常识等任务。
hf-mirror.com 镜像拉取原始数据集(47 个文件)到 datasets/raw/coig-cqia;{instruction, input, output});datasets/processed/sft_train.json —— 1500 条训练集datasets/processed/sft_test.json —— 200 条留出测试集选取 6 个参数量 ≤4B 的开源模型,覆盖不同厂商、不同架构与不同训练定位,便于横向对比微调适配性。
| 模型 | 参数量 | 厂商/架构 | 定位与特点 | 许可证 |
|---|---|---|---|---|
| Qwen3-0.6B | 0.6B | 阿里 · Qwen3 | 最新一代小模型,原生支持 think/非 think 双模式 | Apache 2.0 |
| Qwen3-1.7B | 1.7B | 阿里 · Qwen3 | 同系更大容量,推理能力更强 | Apache 2.0 |
| Qwen2.5-1.5B-Instruct | 1.5B | 阿里 · Qwen2 | 成熟指令版,中文能力强、生态全 | Apache 2.0 |
| Qwen2.5-3B-Instruct | 3B | 阿里 · Qwen2 | 本组最大,中文理解与生成最均衡 | Apache 2.0 |
| SmolLM2-1.7B-Instruct | 1.7B | HuggingFace · Llama系 | 轻量英文优化模型,中文较弱 | Apache 2.0 |
| TinyLlama-1.1B-Chat | 1.1B | 社区 · Llama | 极简教学/实验模型,英文为主 | Apache 2.0 |
16GB 显存无法承载全参数微调(7B 全参需 40–60GB)。采用 QLoRA:将冻结的基座权重量化为 4bit NF4 加载,仅训练注入的 LoRA 低秩适配器(约占总参数 1–2%),显存需求下降约 4 倍,是单卡微调的现实最优解。配套使用 Unsloth 框架(手写 CUDA kernel,官方宣称 2× 提速、省 70% 显存)。
| 组件 | 版本/说明 |
|---|---|
| GPU / 驱动 | RTX 3080 Ti 16GB(Ampere sm_86),驱动 580,CUDA 13 |
| PyTorch | 2.6.0+cu124(经清华 PyPI 镜像安装,wheel 自带 CUDA runtime) |
| 微调框架 | Unsloth 2026.10.11(自动管理 TRL / PEFT / 编译优化) |
| 训练库 | trl、peft、transformers、bitsandbytes(4bit 量化)、accelerate |
| Python | 3.12,独立 venv(.venv/) |
| 精度 | bf16(Unsloth 检测本环境支持 bf16,训练用 bf16=True) |
load_in_4bit=True(NF4 + 双重量化)r=16, alpha=32, dropout=0q/k/v/o_proj + gate/up/down_proj(全注意力+MLP)max_seq_length=1024120 步(冒烟+对比规模)per_device=1, grad_accum=8(有效 batch=8)2e-4,warmup 5 步paged_adamw_8bit,gradient_checkpointing=unsloth训练数据经各模型 chat_template 渲染为「user→assistant」对话格式,仅对回答部分计算 loss。
| 模型 | 训练 loss(终) | 峰值显存 | 耗时 | LoRA 产物 |
|---|---|---|---|---|
| Qwen3-0.6B | 2.628 | 0.80 GB | 161 s | runs/qwen3-0.6b |
| Qwen3-1.7B | 2.295 | 1.66 GB | 328 s | runs/qwen3-1.7b |
| Qwen2.5-1.5B | 1.983 | 1.77 GB | 334 s | runs/qwen25-1.5b |
| Qwen2.5-3B | 1.864 | 2.68 GB | 535 s | runs/qwen25-3b |
| SmolLM2-1.7B | 1.497 | 1.30 GB | 349 s | runs/smollm2-1.7b |
| TinyLlama-1.1B | 1.615 | 1.03 GB | 274 s | runs/tinyllama-1.1b |
用同一批提示词、同样的解码参数,分别调用基座模型与微调模型,从「指令遵循、简洁度、能力保持」三维度对比。以下为 Qwen2.5-3B 实测。
| 评估维度 | 结果 |
|---|---|
| 指令遵循 / 简洁度 | ✅ 显著提升:微调后平均输出缩短约 25 字,去掉"当然可以!"等冗余铺垫,直接作答 |
| 逻辑推理保持 | ✅ 未退化:三段论推理题(Tom 会爬树吗)前后均正确 |
| 格式遵循 | ✅ 未退化:JSON 输出前后均能正确解析 |
| 事实正确性 | ✅ 未退化:常识题答案保持正确 |
| 非中文优化模型 | ⚠️ SmolLM2 / TinyLlama 微调后出现重复、语句不通——120 步小样本难以补救中文短板 |
为便于独立部署(不再依赖基座路径 + adapter),将 LoRA adapter 合并进基座,导出独立 fp16 模型:
# scripts/merge.py 核心步骤 model, tok = FastLanguageModel.from_pretrained(repo, load_in_4bit=True) model = PeftModel.from_pretrained(model, "runs/qwen25-3b") model = model.merge_and_unload() # LoRA 权重并入基座 model.save_pretrained(out, safe_serialization=True) # 产物:models_merged/qwen25-3b (2.3GB,独立可用)
采用 FastAPI + Transformers 自研轻量推理服务(无需 vLLM 重依赖),完整实现 OpenAI 协议:
| 接口 | 说明 | 验证 |
|---|---|---|
GET /v1/models | 模型列表 | ✅ |
POST /v1/chat/completions | 非流式对话,含 usage token 统计 | ✅ |
POST /v1/chat/completions(stream) | SSE 流式输出(chat.completion.chunk) | ✅ |
GET /health | 健康检查 | ✅ |
| OpenAI 官方 SDK | base_url 指向本服务,非流式+流式均通过 | ✅ |
http://${请替换为实际服务地址}:8000/v1(请替换为实际服务地址)qwen25-3b-sft;API Key:任意(当前未设鉴权)api,监听 0.0.0.0:8000# Python 调用(OpenAI SDK)
from openai import OpenAI
client = OpenAI(base_url="http://${请替换为实际服务地址}:8000/v1", api_key="none")
r = client.chat.completions.create(model="qwen25-3b-sft",
messages=[{"role":"user","content":"你的问题"}], max_tokens=512)
print(r.choices[0].message.content)
| 问题 | 根因 | 解决方案 |
|---|---|---|
| HF 模型下载 401 | 新版 huggingface_hub 默认走 xet 后端 | 设 HF_HUB_DISABLE_XET=1 |
| HF/ModelScope 单连接 KB 级 | 镜像限速 | snapshot_download 多线程叠加吞吐 |
| torch 官方源卡死 | download.pytorch.org 国内极慢 | 改用清华 PyPI 镜像(wheel 自带 CUDA) |
| fp16/bf16 报错 | Unsloth 检测本环境支持 bf16 | 训练改 bf16=True, fp16=False |
| 远程后台任务消失 | SSH 断开 & 进程被清 | 一律用 tmux 运行长任务 |
| 合并权重报错 | LoRA 未合并即保存基座 | 先 merge_and_unload() 再 save |