Qwen3-8B 本地 QLoRA 微调项目复盘
从 Ollama 基线评测、SFT 数据构造、LLaMA-Factory 安装、训练与推理,
到 BASE/LoRA 对比、自动化评测、故障排查与经验总结
|
项目项 |
实际内容 |
|
操作系统 |
Windows + PowerShell |
|
硬件 |
NVIDIA GeForce RTX 3060 Laptop GPU,约 6GB 显存 |
|
基座模型 |
Qwen3-8B |
|
本地推理 |
Ollama |
|
微调框架 |
LLaMA-Factory 0.9.6.dev0 |
|
训练方式 |
4-bit QLoRA(SFT + LoRA) |
|
辅助模型 |
BGE-M3(已验证 embedding,但未进入本次 RAG 流程) |
|
项目性质 |
以学习完整微调闭环为主,不以生产级效果为目标 |
一、项目摘要
本项目从已经部署好的 Ollama 与 Qwen3-8B 出发,先建立基座模型 baseline,再将人工理想答案转换成 Alpaca 格式的 SFT 数据,随后在 Windows 环境中安装并配置 LLaMA-Factory,使用 4-bit QLoRA 在 RTX 3060 Laptop GPU 上完成训练,生成 LoRA Adapter,并开展 BASE 与 LoRA 的推理对比。过程中系统处理了 PowerShell 语法、中文编码、GitHub 下载、虚拟环境、CUDA、Hugging Face SSL/超时、版本依赖、离线加载、推理参数、自动评分逻辑、端口和进程等问题。
最终最大的收获不是“训练出了一个明显更强的模型”,而是完整掌握了微调项目的工程闭环,并通过实验认识到:小样本微调不一定提升效果,训练 loss 下降也不等于泛化能力提升;数据定义、训练/测试隔离、推理配置和评估方法,往往比单纯增加 epoch 更重要。
二、项目目标与总体路线
本地模型部署与 API 验证
→ 建立 Qwen3-8B baseline
→ 人工评分并定位问题
→ 构造 Alpaca SFT 数据
→ 安装并配置 LLaMA-Factory
→ 4-bit QLoRA 训练
→ 生成并加载 LoRA Adapter
→ BASE / LoRA 独立测试
→ 自动化评测与人工复核
→ 分析结果、问题与下一轮改进方向
本项目的明确边界:
- 目标是学习微调完整流程,而不是用少量 toy data 训练生产级模型。
- 坚持使用 Qwen3-8B,以理解 8B 模型在 6GB 级显存上的 QLoRA 实践。
- Ollama 中已有的 qwen3:8b 只用于推理;训练需要 Hugging Face 格式的 Qwen/Qwen3-8B 权重。
- BGE-M3 负责向量化和检索,本次只完成接口验证,没有继续实现 RAG。
三、阶段一:验证 Ollama、Qwen3-8B 与 BGE-M3
3.1 初始环境
ollama list
qwen3:8b
bge-m3:latest
模型分工被明确为:Qwen3-8B 负责生成,BGE-M3 负责 embedding,Ollama 负责本地推理服务。这里建立了第一个关键认知:推理模型文件与训练权重不是同一种用途,Ollama 量化模型不能直接交给 LLaMA-Factory 训练。
3.2 PowerShell 中 curl 命令失败
|
现象 |
根因 |
解决方式 |
|
使用 Linux 风格反斜杠换行后,-d 被识别为新命令 |
PowerShell 的续行符不是 \,而是反引号 ` |
改用 PowerShell 反引号,或直接使用单行命令 |
|
curl 的行为与预期不一致 |
某些 PowerShell 中 curl 是 Invoke-WebRequest 的别名 |
使用 curl.exe,或优先采用 Invoke-RestMethod |
|
Ollama 返回 invalid character 'm' looking for beginning of object key string |
命令行引号被 PowerShell 处理后,发送的内容不再是合法 JSON |
用哈希表构造对象,再 ConvertTo-Json |
$body = @{
model = "qwen3:8b"
messages = @(
@{
role = "user"
content = "用三句话解释什么是大模型微调。"
}
)
stream = $false
} | ConvertTo-Json -Depth 10
3.3 中文乱码与 UTF-8 处理
API 已连通后,模型却把中文识别成乱码或问号,回复与问题无关。根因是 PowerShell 控制台、字符串、HTTP Body 的编码链路不一致。
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
$utf8Body = [System.Text.Encoding]::UTF8.GetBytes($body)
Invoke-RestMethod `
-Uri "http://localhost:11434/api/chat" `
-Method Post `
-ContentType "application/json; charset=utf-8" `
-Body $utf8Body
处理完成后,Qwen3-8B 能正确接收中文问题并返回正常中文回答。
3.4 Qwen3 思考模式
Qwen3 可能输出较长的 thinking 内容,既占用 token,也会干扰严格 JSON/标签任务。初期通过在用户输入后加入 /no_think,并在 system prompt 中要求不输出思考过程,减少无关输出。后续进一步认识到,推理模板与 max_new_tokens 同样会影响答案完整性。
图 1:Ollama API 调通后,中文编码与思考输出仍需处理
四、阶段二:建立基座模型 Baseline
4.1 为什么先做 baseline
微调前先回答一个问题:基座模型在目标任务上到底差在哪里。没有 baseline,微调后就无法证明效果是否提升,也无法区分问题究竟来自知识不足、格式不稳定、风格不匹配,还是 prompt 与推理参数。
4.2 初始评测集
|
任务类别 |
示例目标 |
主要评估点 |
|
客户反馈转 JSON |
抽取 problem、emotion、suggestion |
JSON 合法性、字段完整性、不得添加解释 |
|
客服回复 |
专业、友好、长度适当 |
语气、事实一致性、简洁度 |
|
商品问题抽取 |
商品名、问题、处理诉求 |
字段准确、不得自行推断 |
|
用户意图分类 |
退款/换货/咨询/投诉 |
只能输出标签、分类正确 |
|
种草文案改写 |
自然、不夸张的小红书风格 |
自然度、模板感、营销味 |
创建目录与核心文件:
llm-finetune-step1/
├─ data/eval.jsonl
├─ outputs/qwen3_8b_baseline.jsonl
├─ outputs/review.csv
├─ run_baseline.py
└─ make_review_csv.py
4.3 批量推理脚本
run_baseline.py 使用 requests 调用 Ollama /api/chat,固定 temperature=0.2、stream=false,通过 system prompt 强调 JSON、单标签等格式要求,并把 instruction、ideal、prediction 保存为 JSONL。
4.4 人工评分
2 = 完全符合要求
1 = 基本正确,但格式、语气或细节有问题
0 = 明显不符合要求
评分表包含 id、score、issue、instruction、ideal、prediction。初始结果说明 Qwen3-8B 已具备基本任务能力,但在客服回复长度、文案自然度、结构化格式稳定性等方面仍有改进空间。
图 2:第一版 baseline 批量运行结果
五、阶段三:构造 SFT 训练数据
将评测数据中的 instruction 与人工编写的 ideal 转换成 Alpaca 格式。训练目标必须使用人工理想答案,不能直接用基座模型 prediction,否则模型只会模仿原有错误。
{
"instruction": "用户任务",
"input": "",
"output": "人工理想答案",
"system": "你是一个严谨的中文任务助手……"
}
第一轮数据仅约 5 条,属于 toy dataset。其价值是验证“数据准备—注册—训练—推理—评估”的闭环,不能期待形成稳定泛化能力。
六、阶段四:安装 LLaMA-Factory 与环境配置
6.1 GitHub clone 连接被重置
|
尝试 |
结果 |
后续处理 |
|
git clone --depth 1 |
Recv failure: Connection was reset |
确认属于网络问题,不是命令错误 |
|
增加 --single-branch --filter=blob:none |
仍可能不稳定 |
改为下载 GitHub ZIP |
|
Invoke-WebRequest 下载 main.zip |
下载成功 |
解压后自动识别实际根目录 |
6.2 ZIP 解压目录名不一致
原先假定目录名为 LLaMA-Factory-main,实际名称不同,Rename-Item 报路径不存在。解决方法是不要继续猜目录名,而是让 PowerShell 自动找到解压后的第一个文件夹。
$src = Get-ChildItem .\lf_tmp -Directory | Select-Object -First 1
Move-Item $src.FullName .\LLaMA-Factory
6.3 虚拟环境重复创建导致 Permission denied
在 (.venv) 已激活时再次执行 python -m venv .venv,系统无法覆盖正在使用的环境。处理方式是停止重复创建,直接继续使用当前虚拟环境。
6.4 CUDA 与 GPU 验证
python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'no cuda')"
True
NVIDIA GeForce RTX 3060 Laptop GPU
6.5 LLaMA-Factory 安装验证
pip install -e .
llamafactory-cli version
Welcome to LLaMA Factory, version 0.9.6.dev0

图 3:LLaMA-Factory 安装完成,CUDA 可用,RTX 3060 Laptop GPU 被识别
七、阶段五:注册自定义数据集
把 sft_alpaca.json 复制到 LLaMA-Factory/data,命名为 beauty_sft_alpaca.json,并在 data/dataset_info.json 中注册。
"beauty_sft": {
"file_name": "beauty_sft_alpaca.json",
"formatting": "alpaca",
"columns": {
"prompt": "instruction",
"query": "input",
"response": "output",
"system": "system"
}
}
为避免手工编辑大型 JSON 文件导致漏逗号、括号错误,使用 Python 脚本读取、增加节点并重新 dump。重要认识:仅把文件放进 data 目录并不够,LLaMA-Factory 必须在 dataset_info.json 中知道数据名称、文件名和字段映射。
八、阶段六:第一次 4-bit QLoRA 微调
8.1 为什么选择 QLoRA
Qwen3-8B 参数量较大,而 RTX 3060 Laptop GPU 显存约 6GB,无法进行全参数训练。因此使用 4-bit 量化基座模型,只训练 LoRA 适配器参数,在较低显存下完成 SFT。
8.2 训练配置关键参数
|
参数 |
示例值 |
作用 |
|
model_name_or_path |
Qwen/Qwen3-8B |
训练使用的 Hugging Face 基座权重 |
|
stage |
sft |
监督微调 |
|
finetuning_type |
lora |
仅训练 LoRA 参数 |
|
quantization_bit |
4 |
4-bit QLoRA,降低显存 |
|
template |
qwen3_nothink |
采用 Qwen3 非思考模板 |
|
lora_rank / alpha |
8 / 16 |
控制适配器容量与缩放 |
|
batch size |
1 |
适应小显存 |
|
gradient_accumulation_steps |
8 |
增大有效 batch size |
|
learning_rate |
1e-4 |
LoRA 常用量级 |
|
num_train_epochs |
约 5~8 |
第一轮为流程验证,允许过拟合 |
|
fp16 |
true |
降低显存并加速 |
8.3 Hugging Face SSL 与联网问题
首次下载模型时遇到 CERTIFICATE_VERIFY_FAILED、连接重置或超时。尝试安装 certifi、python-certifi-win32、huggingface_hub 等证书相关包后,曾误把 transformers 升级到与 LLaMA-Factory 不兼容的 5.x,随后按框架要求降回兼容版本。模型最终成功下载到 Hugging Face 本地缓存。
离线复用时设置:
$env:HF_HUB_OFFLINE = "1"
$env:TRANSFORMERS_OFFLINE = "1"
另一种更确定的做法,是把 model_name_or_path 改成缓存 snapshots 下实际 snapshot 的绝对路径,避免框架再次尝试联网检查更新。
九、阶段七:训练完成与 LoRA 推理
第一次训练成功后,saves/qwen3-8b/lora/beauty_sft 下生成 adapter_config.json、adapter_model.safetensors、trainer_state.json、trainer_log.jsonl、训练参数等文件。该目录是 LoRA Adapter,不是完整 8B 模型。
9.1 推理配置
model_name_or_path: Qwen/Qwen3-8B
adapter_name_or_path: saves/qwen3-8b/lora/beauty_sft
finetuning_type: lora
template: qwen3_nothink
quantization_bit: 4
9.2 光标闪烁并非卡死
llamafactory-cli chat 加载完模型后显示 User:,光标持续闪烁,这是交互式聊天正在等待输入。clear 用于清空历史,exit 用于退出。模型加载阶段没有频繁输出也不代表程序卡住。

图 4:QLoRA 训练环境确认与 LLaMA-Factory 版本信息
十、阶段八:第一次 BASE / LoRA A/B 测试
10.1 为什么要使用未见测试集
训练样本上的表现只能说明模型记住了数据,不能证明泛化。为此另建未参与训练的测试问题,在相同推理参数下分别运行 BASE 与 LoRA。
10.2 自动化的必要性
手工启动 BASE、逐条提问、复制答案、退出,再启动 LoRA 重复操作非常繁琐,因此先写 PowerShell 一键脚本,后又改为 Python v3 自动化脚本,负责启动 LLaMA-Factory API、轮询就绪、批量请求、保存输出、关闭服务并评分。
10.3 API 显示 gpt-3.5-turbo 的误解
OpenAI 兼容接口默认对外模型名可能显示为 gpt-3.5-turbo,但底层实际加载仍由 YAML 的 Qwen3-8B 决定,并未调用 OpenAI。可以设置 API_MODEL_NAME 修改展示名称。
10.4 第一版自动评分 0/10 的根因
|
问题 |
表现 |
修复 |
|
中文响应编码错误 |
内容显示为 ç¨äº… 等乱码 |
显式按 UTF-8 解码并统一文件读写编码 |
|
空 think 标签误判 |
<think>\n\n</think> 也被判失败 |
评分前用正则删除 think 块,再评估正文 |
|
输出截断 |
JSON 或回答在中间停止 |
提高 max_new_tokens,并减少 thinking 占用 |
|
评分规则不匹配 |
所有题机械给相同分数 |
为实际测试 ID 配置规则,并保留人工复核 |
10.5 脚本看起来“不动”
模型服务日志被重定向到文件后,主窗口只显示“正在加载模型”,容易被误认为卡死。实际是在把 8B 4-bit 权重从硬盘加载到内存和显存。排查方法包括查看日志尾部、检查端口、检查 GPU 占用,以及让脚本打印轮询状态。
10.6 清理端口误碰 PID 0
根据端口查询进程时匹配到 PID 0,Windows 不允许终止系统空闲进程。修复为:只有 PID 大于 0 且确实占用目标端口时才 Stop-Process,并避免用过宽的字符串匹配。
十一、第一次实验结果与判断
第一次微调完成了训练闭环,但 BASE 与 LoRA 的独立测试没有表现出可靠、可测量的提升。部分答案不完整主要由推理 max_new_tokens 较小、thinking 内容占用额度等因素造成,而非训练本身失败。
|
观察 |
判断 |
|
训练 loss 能下降 |
说明优化器确实在学习训练数据 |
|
训练样本很少 |
容易记忆与过拟合,难以提升未见样本 |
|
BASE 已具备较强能力 |
少量泛化样本未必能进一步改善 |
|
LoRA 输出有时更冗长或偏离 |
微调可能破坏原有指令遵循或放大数据偏差 |
|
自动评分曾给出错误结论 |
评估脚本本身也必须验证 |
十二、阶段九:重新设计第二轮训练
第二轮不再混合过多任务,而是把目标收敛到更明确的结构化抽取场景,并扩大训练样本,同时使用独立的 15 条未见测试集进行对比。
12.1 数据设计原则
- 训练集和测试集严格隔离,测试问题不得出现在训练数据中。
- 字段定义统一,尤其是 problem、emotion、suggestion 的语义边界。
- 理想答案不凭空补充用户没有表达的诉求。
- 统一 JSON 字段顺序、标签集合和空值规则。
- 尽量避免同时训练 JSON、客服话术、分类、文案等差异很大的任务。
12.2 第二轮训练观察
训练日志显示 LoRA 可训练参数只占总参数的一小部分;通过 batch size=1 和梯度累积形成较大的有效 batch。loss 在训练过程中总体下降,说明训练正常。由于用户希望停止耗时任务,第二轮未完整跑完全部计划步数,但保留了中间 checkpoint(如 checkpoint-10)用于推理与测试。
十三、第二轮测试与评估问题
13.1 离线加载
即使模型已缓存,Hugging Face Hub 默认仍可能联网检查。再次超时后设置 HF_HUB_OFFLINE=1 与 TRANSFORMERS_OFFLINE=1,或直接使用 snapshot 本地路径。
13.2 自动评分规则未覆盖新 ID
第二轮报告出现 BASE 15/30、LoRA 15/30,但每条理由都是“未配置该题的专用评分规则”。这说明分数只是评分脚本的默认值,没有实际比较模型能力。最终必须回到原始回答做人工复核。
13.3 人工复核发现的主要问题
|
问题类型 |
典型表现 |
数据/评估改进 |
|
JSON 外有额外内容 |
带解释、Markdown 或 think 标签 |
训练中增加严格格式样本;评估时先验证可解析性 |
|
suggestion 自行猜测 |
用户没提出退换货,模型却补充退货 |
明确“未表达则输出空字符串/未提及” |
|
处理诉求偏离原意 |
把投诉改写成退款或换货 |
标签与字段定义必须更细致 |
|
情绪标签不稳定 |
同类文本出现不满、焦虑、生气等混用 |
限定枚举集合并建立标注规范 |
|
回答截断 |
JSON 末尾缺失 |
增加 max_new_tokens,关闭 thinking,必要时设置停止规则 |
十四、磁盘占用突然增加约 80GB 的原因
LoRA Adapter 本身通常不大,磁盘快速增长主要来自多项叠加,而不是 adapter 变成了 80GB。
|
来源 |
说明 |
|
Hugging Face 模型缓存 |
Qwen3-8B 的训练权重、分片、快照和可能的重复/未完成下载 |
|
Ollama 模型 |
已有 qwen3:8b 与 bge-m3 的量化模型占用 |
|
PyTorch / CUDA 依赖 |
虚拟环境、wheel、pip 缓存体积较大 |
|
训练 checkpoint |
多次保存会重复保存 adapter、优化状态和训练状态 |
|
临时 ZIP / 解压目录 |
LLaMA-Factory.zip、lf_tmp、失败目录 |
|
Windows pagefile |
大模型加载时系统可能扩展页面文件,占用系统盘 |
可安全清理的典型对象:
- pip cache purge 清理 pip 下载缓存。
- Hugging Face 缓存中的 .incomplete、失败下载和不再使用的旧 snapshot。
- LLaMA-Factory.zip、lf_tmp、失败的解压目录。
- 确认不需要后删除旧 checkpoint,仅保留最终或最佳 checkpoint。
- 不要盲目删除当前模型 snapshot、正在使用的 .venv、训练数据和 Adapter。
十五、项目实际产物
|
类别 |
典型文件/目录 |
用途 |
|
Baseline |
data/eval.jsonl |
基座评测问题与理想答案 |
|
Baseline 输出 |
outputs/qwen3_8b_baseline.jsonl |
基座模型批量预测 |
|
人工评分 |
outputs/review.csv |
记录分数和问题类型 |
|
第一轮训练集 |
data/sft_alpaca.json / beauty_sft_alpaca.json |
Alpaca SFT 数据 |
|
数据注册 |
data/dataset_info.json |
LLaMA-Factory 数据集映射 |
|
训练配置 |
examples/train_lora/qwen3_8b_beauty_lora_sft.yaml |
第一轮 QLoRA 参数 |
|
推理配置 |
自定义 inference YAML |
加载 BASE 或 LoRA |
|
LoRA 结果 |
saves/qwen3-8b/lora/beauty_sft |
Adapter 与训练日志 |
|
第二轮 checkpoint |
checkpoint-10 等 |
中途停止后用于验证 |
|
自动化工具 |
PowerShell / Python 批量评测脚本 |
启动服务、请求、保存与评分 |
十六、已经完成与尚未完成
16.1 已完成
- Ollama 本地 API 调用与 UTF-8 中文传输。
- Qwen3-8B baseline 建立、批量推理和人工评分。
- Alpaca SFT 数据构造与 LLaMA-Factory 注册。
- Windows 下 LLaMA-Factory、PyTorch、CUDA、bitsandbytes 环境配置。
- Qwen3-8B 4-bit QLoRA 训练并生成 Adapter。
- LoRA 交互推理与本地缓存离线加载。
- BASE/LoRA 独立测试与自动化脚本。
- 训练日志、loss、可训练参数、有效 batch 等基本分析。
- 多类工程问题的定位和修复。
16.2 尚未完成
- 第二轮没有完成全部计划训练步数,只使用了中间 checkpoint。
- 没有把 LoRA 合并为完整模型。
- 没有转换为 GGUF,也没有把最终 Adapter 稳定接回 Ollama。
- 没有实现 BGE-M3 + 向量库 + Qwen 的 RAG。
- 没有形成数百到数千条高质量、严格标注的生产级训练集。
- 没有建立成熟的自动指标体系,例如 JSON Schema 通过率、字段级 F1、标签准确率和人工盲评。
十七、核心经验与教训
- 微调前必须先做 baseline。否则即使 loss 下降,也不知道模型是否真正变好。
- 训练集和测试集必须严格隔离。训练样本表现好只代表记忆,不能代表泛化。
- 任务应尽量收敛。少量数据同时覆盖多种完全不同的任务,会让学习信号互相干扰。
- 强基座模型不一定需要微调。若主要缺少私有知识,应优先考虑 RAG;若主要是格式、风格、流程稳定性问题,才更适合 SFT/LoRA。
- 数据质量比增加 epoch 更重要。标签边界、空值规则、字段定义和理想答案一致性直接决定模型学到什么。
- 训练 loss 下降不等于业务效果提升。必须用未见数据和业务指标验证。
- 微调可能破坏基座能力。数据过少、偏差过大或学习率不合适,可能导致回答更死板、更冗长或更容易猜测。
- 推理配置会显著影响结论。template、thinking、max_new_tokens、temperature、stop tokens 都可能造成截断或格式污染。
- 自动评分也会出错。乱码、ID 不匹配、默认分数、空 think 标签等都曾制造错误结论,因此评分程序本身也要测试。
- Windows 工程细节不可忽视。PowerShell 引号、续行符、编码、路径、端口、进程与缓存往往比训练参数更容易卡住新手。
十八、面试可用的项目表述
我在 Windows 和 RTX 3060 Laptop GPU 上完成了一个 Qwen3-8B 的本地 QLoRA 微调实验。项目先通过 Ollama 建立 baseline,用 Python 批量调用模型并人工标注问题;随后把理想答案转换成 Alpaca SFT 数据,在 LLaMA-Factory 中注册数据集并用 4-bit QLoRA 训练 LoRA Adapter。训练后我分别加载 BASE 与 LoRA,用未见测试集进行 A/B 对比,并编写自动化脚本完成服务启动、批量推理、结果保存和评分。实验中处理了 PowerShell JSON 与 UTF-8 编码、GitHub 下载、CUDA 和 bitsandbytes、Hugging Face SSL/离线缓存、Transformers 版本冲突、推理输出截断、API 模型名误导以及自动评分规则错误等问题。最终结果表明,小样本 LoRA 并未稳定优于基座模型,说明 loss 下降不等于泛化提升,后续应优先改进数据定义、扩大高质量样本,并采用 JSON Schema 通过率、字段准确率和人工盲评等更可靠指标。
十九、面试中应能解释的问题
- 为什么 Ollama 里的 qwen3:8b 不能直接用于 LLaMA-Factory 训练?
- LoRA 与 QLoRA 的区别是什么,为什么 6GB 显存选择 4-bit QLoRA?
- lora_rank、lora_alpha、gradient_accumulation_steps、cutoff_len 分别有什么作用?
- 为什么要先做 baseline,为什么训练集和测试集必须隔离?
- 为什么 loss 下降但测试效果可能不提升?
- 如何判断任务应做微调还是 RAG?BGE-M3 在 RAG 中承担什么角色?
- 如何检测 JSON 输出质量?为什么只看文本相似度不够?
- Hugging Face 已有缓存为什么还会联网,如何离线加载?
- 为什么 API 显示 gpt-3.5-turbo,但实际仍是 Qwen3-8B?
- 自动评分出现 0/10 或固定 1 分时,如何验证评分逻辑是否可信?
二十、下一轮正确的改进方向
- 只选择一个清晰任务,例如客户反馈结构化抽取,不再混入文案、客服回复和分类。
- 制定标注规范:字段含义、允许标签、空值策略、不得推断规则、JSON 字段顺序。
- 准备至少数百条高质量训练样本,并设置训练集、验证集和独立测试集。
- 增加困难样本、边界样本和反例,避免模型只记住固定句式。
- 训练时保存并比较多个 checkpoint,不默认最后一步最好。
- 固定 BASE 与 LoRA 的推理参数,关闭 thinking,适当提高 max_new_tokens。
- 采用结构化指标:JSON 可解析率、Schema 通过率、字段级 precision/recall/F1、标签准确率、额外文本率。
- 进行人工盲评,避免评审者提前知道答案来自 BASE 还是 LoRA。
- 确认 LoRA 确有稳定提升后,再考虑合并模型、导出 GGUF、接入 Ollama 或部署 API。
- 若目标是补充私有知识而非格式和风格,转向 BGE-M3 + 向量库 + Qwen3-8B 的 RAG 路线。
二十一、故障排查速查表
|
故障/现象 |
优先检查 |
推荐处理 |
|
PowerShell -d 无法识别 |
是否使用了 Linux 的 \ |
用反引号或 Invoke-RestMethod |
|
invalid character 'm' |
JSON 引号是否被吃掉 |
ConvertTo-Json 后发送 UTF-8 bytes |
|
中文乱码 |
控制台、HTTP、文件编码 |
统一 UTF-8 / utf-8-sig |
|
git clone connection reset |
网络与 GitHub 连接 |
浅克隆失败后改 ZIP |
|
Rename-Item 路径不存在 |
解压后的真实目录名 |
Get-ChildItem 自动发现目录 |
|
venv Permission denied |
环境是否已经激活 |
不要覆盖正在使用的 .venv |
|
torch.cuda.is_available=False |
PyTorch 是否为 CUDA 版 |
重装匹配的 CUDA wheel |
|
SSL CERTIFICATE_VERIFY_FAILED |
证书链、代理、网络 |
修复证书或先完成缓存下载 |
|
Transformers 版本冲突 |
pip show 与框架约束 |
降级到 LLaMA-Factory 兼容范围 |
|
模型已缓存仍联网 |
Hub 默认检查更新 |
设置 HF_HUB_OFFLINE 和本地 snapshot 路径 |
|
chat 光标闪烁 |
是否已出现 User: |
直接输入问题,不要误判卡死 |
|
回答中途结束 |
max_new_tokens 与 thinking |
提高上限并使用 nothink 模板 |
|
API 名称是 GPT-3.5 |
兼容接口默认名称 |
检查 YAML;设置 API_MODEL_NAME |
|
自动评分全 0 或固定分 |
编码、题目 ID、默认规则 |
查看原始输出并人工抽样 |
|
磁盘增加几十 GB |
HF 缓存、checkpoint、pip、pagefile |
分类核对后清理,不盲删模型 |
二十二、结论
本项目已经完成了一个真实、可复现的大模型微调学习闭环:从基座评测、训练数据构造、框架安装和 QLoRA 训练,到 Adapter 推理、独立测试、自动化脚本与结果分析。过程中遇到的大量问题并非“模型算法”本身,而是操作系统、编码、网络、依赖、缓存、推理和评估工程问题;能够逐一定位并修复,本身就是 LLM 工程能力的重要组成部分。
从实验结论看,当前小样本 LoRA 没有稳定优于 Qwen3-8B 基座模型。这不是项目失败,而是一次有价值的负结果:它证明了微调不是“跑完训练就会变强”,也说明可靠评估比漂亮的 loss 曲线更重要。下一轮应以单一任务、严格标注、更多高质量样本、固定推理参数和结构化指标为核心,再决定是否值得合并和部署。
更多推荐
所有评论(0)