从零微调 Qwen3-8B:基于 LoRA 与 LLaMA-Factory 打造专属 AI 编程助教
本文面向希望入门大语言模型微调的开发者,以 Qwen3-8B 为基础模型,使用 LLaMA-Factory 和 LoRA 实现一个具有教学风格的 AI 编程助教。重点介绍微调原理、数据集构建、训练配置、推理部署和效果评估。
一、为什么大模型已经很强了,还需要微调?
如今,通用大语言模型已经能够完成代码生成、程序调试、算法解释等多种任务。
例如,我们直接向 Qwen3-8B 提问:
Python 中的列表和元组有什么区别?
模型通常能够给出比较完整的解释。
那么,为什么还要微调?
原因在于:模型能够完成一个任务,不代表它能够按照我们的特定要求稳定地完成任务。
假设我们要开发一个面向初学者的 AI 编程助教,希望它具备以下特点:
- 语法讲解:用通俗易懂的语言解释概念,并提供简短示例。
- 代码调试:准确定位错误,解释错误原因,并给出修改建议。
- 算法辅导:优先引导学生分析思路,而不是直接给出完整答案。
- 循序渐进:根据学生当前的理解程度,逐步增加提示。
- 教学风格:尽量避免生硬、复杂或不必要的专业术语。
通用模型虽然已经具备相关知识,但不一定能始终按照这些教学规范回答。
我们当然可以通过系统提示词(System Prompt)约束模型行为,但提示词不能保证在所有场景下都能稳定生效。
如果希望模型长期遵循某种回答模式,就可以考虑进行监督微调(Supervised Fine-Tuning,SFT)。
这里需要明确:
本项目微调的主要目标不是让 Qwen3-8B 学会编程,而是让它学会如何更好地教别人编程。
1.1 微调与 RAG、Prompt 的区别
| 方法 | 核心思想 | 适用场景 |
|---|---|---|
| Prompt Engineering | 通过提示词引导模型 | 快速调整回答风格与行为 |
| RAG | 检索外部知识后提供给模型 | 需要最新资料、私有知识 |
| SFT | 利用示例更新模型参数 | 学习固定任务、回答格式与行为 |
| LoRA | 低秩参数高效微调 | 计算资源有限时进行 SFT |
一般建议先使用 Prompt 建立基线,再根据实际效果判断是否需要微调。
二、监督微调(SFT)的基本原理
2.1 大模型是如何生成回答的?
大语言模型本质上是在给定上下文的情况下,预测下一个 Token 出现的概率。
例如,输入:
text
Python 是一种
模型可能预测后面的内容是:
text
高级编程语言
这个过程可以表示为:
math
P(y_t \mid x,y_{<t};\theta)
其中:
- (x):输入提示和上下文。
- (y_t):当前需要预测的 Token。
- (y_{<t}):之前已经生成的 Token。
- (\theta):模型参数。
训练的目标是让模型提高正确 Token 的预测概率。
2.2 SFT 是如何进行训练的?
监督微调需要准备输入和对应的期望输出。
例如:
输入:
text
学生:为什么 Python 列表下标会越界?
期望输出:
text
Python 列表下标从 0 开始。
例如:
items = [10, 20, 30]
合法下标是 0、1、2。
如果访问 items[3],就会出现 IndexError。
训练过程中,模型会根据输入预测回答,并将预测结果与参考回答进行比较。
常用损失函数为交叉熵损失:
math
\mathcal{L}_{SFT}
=-\frac{1}{T}\sum_{t=1}^{T}
\log P_{\theta}(y_t^*\mid x,y_{<t}^*)
其中:
- (T):参与损失计算的目标 Token 数量。
- (y_t^*):参考回答中的第 (t) 个 Token。
- (P_{\theta}):模型对目标 Token 的预测概率。
模型不断通过反向传播更新参数,使其生成结果逐渐接近训练样本中的回答方式。
需要注意的是,训练损失下降不等于模型实际能力一定提升,还需要独立的测试数据验证。
三、LoRA 为什么能够降低微调成本?
3.1 全参数微调的问题
Qwen3-8B 包含约 80 亿规模的参数。
如果采用全参数微调,需要对模型中的大量权重进行梯度计算和更新。
除了保存模型参数,还需要额外存储:
- 梯度
- 优化器状态
- 中间激活值
因此,全参数微调通常需要较多 GPU 显存。
3.2 LoRA 的核心思想
LoRA(Low-Rank Adaptation,低秩适配)并不直接修改原始权重矩阵,而是冻结原模型参数,额外引入两个可以训练的小矩阵。
对于原始权重:
math
W_0\in\mathbb{R}^{d\times k}
LoRA 将权重更新表示为:
math
W=W_0+\Delta W
其中:
math
\Delta W=BA
两个低秩矩阵分别为:
math
B\in\mathbb{R}^{d\times r},
\quad A\in\mathbb{R}^{r\times k}
这里的 (r) 就是 LoRA Rank。
实际计算时通常还引入缩放因子:
math
h=W_0x+\frac{\alpha}{r}BAx
其中 (\alpha) 为 LoRA Alpha。
3.3 举一个简单的例子
假设某个权重矩阵大小为:
text
4096 × 4096
原始参数数量为:
text
4096 × 4096 = 16,777,216
如果采用 Rank = 8 的 LoRA:
text
矩阵 A:8 × 4096
矩阵 B:4096 × 8
需要训练的参数为:
text
8 × 4096 + 4096 × 8 = 65,536
只相当于原始矩阵参数量的约 0.39%。
当然,这只是单个矩阵的示例,并不代表整个模型的实际可训练参数比例。
3.4 LoRA 与 QLoRA
LoRA 主要减少可训练参数以及对应的梯度和优化器开销,但基础模型权重仍然占用显存。
QLoRA 则进一步使用低比特量化保存冻结的基础模型权重,在此基础上训练 LoRA 适配器。
简单理解:
- LoRA:冻结原模型,训练少量新增参数。
- QLoRA:量化并冻结原模型,再训练少量新增参数。
本教程首先使用 LoRA,便于理解完整流程。
论文参考:LoRA: Low-Rank Adaptation of Large Language Models。
四、环境准备
4.1 硬件与软件
本教程采用以下技术路线:
| 组件 | 说明 |
|---|---|
| 操作系统 | Linux |
| GPU | NVIDIA GPU,推荐较大显存 |
| Python | 3.10 |
| 基础模型 | Qwen/Qwen3-8B |
| 训练框架 | LLaMA-Factory |
| 微调方式 | LoRA |
| 精度 | BF16(需要 GPU 支持) |
显存需求与模型精度、序列长度、Batch Size、梯度检查点和优化器等有关。
如果显存不足,可以考虑缩短序列长度、减小 Batch Size,或者采用 QLoRA。
4.2 创建 Conda 环境
bash
conda create -n qwen3-lora python=3.10 -y
conda activate qwen3-lora
确认 Python 版本:
bash
python --version
4.3 安装 PyTorch
先通过以下命令检查 GPU 和驱动:
bash
nvidia-smi
然后根据驱动和运行环境,从 PyTorch 官方网站选择匹配的安装命令:
https://pytorch.org/get-started/locally/
安装完成后验证:
bash
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"
如果最后输出 True,说明 PyTorch 可以识别 CUDA。
4.4 安装 LLaMA-Factory
下载项目:
bash
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
建议按官方文档选择兼容的版本组合,避免将不同发行版本的依赖随意混装。
安装:
bash
pip install -e ".[torch,metrics]"
检查:
bash
llamafactory-cli version
如需图形界面,可以运行:
bash
llamafactory-cli webui
注意:下面的示例采用支持 Qwen3 和 qwen3_nothink 模板的 LLaMA-Factory 版本。旧版本的参数名称和模板可能不同。
4.5 下载 Qwen3-8B
模型地址:
https://huggingface.co/Qwen/Qwen3-8B
可以通过 Hugging Face CLI 下载:
bash
pip install -U huggingface_hub
hf download Qwen/Qwen3-8B \
--local-dir models/Qwen3-8B
如果服务器无法访问 Hugging Face,可以在能够联网的机器上下载模型,再上传至服务器。
下载完成后,应确认模型配置、Tokenizer 文件及全部权重分片均已保存。
五、构建自己的微调数据集
数据质量通常比单纯增加数据数量更重要。
本项目希望模型学会编程教学行为,因此数据不仅要包含正确答案,还应该体现教学过程。
5.1 Alpaca 数据格式
LLaMA-Factory 支持 Alpaca 等常见数据格式。
一个典型的 Alpaca 样本包含:
json
{
"instruction": "为什么列表下标越界?",
"input": "items = [1, 2, 3]\nprint(items[3])",
"output": "列表的合法下标为 0、1、2。items[3] 访问了不存在的第四个元素,因此触发 IndexError。如果想访问第三个元素,应该使用 items[2]。",
"history": []
}
字段解释:
| 字段 | 作用 |
|---|---|
| instruction | 用户提出的问题 |
| input | 补充信息,例如代码片段 |
| output | 期望模型生成的回答 |
| history | 之前的多轮问答 |
5.2 编写示例数据集
在 LLaMA-Factory 项目的 data 目录下创建:
text
data/code_tutor_train.json
写入以下示例:
json
[
{
"instruction": "Python 中列表和元组有什么区别?",
"input": "",
"output": "列表(list)可以修改,元组(tuple)通常不能修改。\n\n例如:\nnums = [1, 2, 3]\nnums[0] = 10\n\n列表允许修改元素。\n\n而对于元组:\nnums = (1, 2, 3)\nnums[0] = 10\n\n则会触发 TypeError。\n\n你可以简单记住:需要修改数据时通常使用列表,不需要修改时可以考虑元组。",
"history": []
},
{
"instruction": "帮我看看下面的代码为什么报错。",
"input": "numbers = [10, 20, 30]\nprint(numbers[3])",
"output": "问题出在 numbers[3]。Python 的列表下标从 0 开始,这个列表只有三个元素,合法下标分别为 0、1、2。你访问的下标 3 超出了范围。\n\n如果想获取最后一个元素,可以使用 numbers[2],或者使用 numbers[-1]。",
"history": []
},
{
"instruction": "这是我的作业,帮我写一个冒泡排序程序。",
"input": "",
"output": "我们可以先分析冒泡排序的基本思路。\n\n它的核心是比较相邻的两个元素,如果顺序不正确,就交换它们。每完成一轮,相应的较大元素就会逐步移动到后面。\n\n你可以先尝试回答两个问题:\n1. 需要几层循环?\n2. 每一轮应该比较哪些相邻元素?\n\n如果你已经写了一部分代码,可以发给我,我帮你检查。",
"history": []
}
]
以上仅用于展示数据格式。正式训练应准备更丰富的数据,覆盖不同语言、难度、错误类型及教学阶段。
5.3 多轮对话数据
编程助教不能只回答单轮问题,还应该根据学生的尝试进行反馈。
例如:
json
{
"instruction": "我写了这个循环,但最后一个元素没有参与比较。",
"input": "for i in range(len(nums) - 1):\n print(nums[i])",
"output": "你可以重点检查 range 的结束位置。range(n) 实际生成的是从 0 到 n-1 的整数。你现在写的是 range(len(nums)-1),所以循环少执行了一次。如果希望访问列表中的每个元素,应该怎样调整结束位置呢?",
"history": [
[
"怎样遍历 Python 列表?",
"可以通过 for 循环遍历,例如 for x in nums,也可以使用 range(len(nums)) 根据下标访问元素。"
]
]
}
通过这类数据,可以让模型学习不同对话阶段的回答方式。
注意,history 必须与所使用的数据模板匹配,训练时是否对历史回答计算损失还取决于相关配置。
5.4 数据质量要求
建议重点检查以下内容:
- 技术正确性:示例代码应能正常运行,错误解释应准确。
- 教学一致性:不同样本遵循相同的教学原则。
- 任务多样性:包含概念解释、调试、审查、算法和作业指导。
- 多轮连贯性:根据学生已尝试的内容调整提示。
- 数据去重:避免同一道题的大量重复样本主导训练。
- 数据隔离:同一道题的改写版本不应同时出现在训练集和测试集。
建议按照题目或任务进行分组划分,而不是简单地随机切分所有对话记录。
5.5 注册数据集
打开:
text
data/dataset_info.json
添加:
json
{
"code_tutor_train": {
"file_name": "code_tutor_train.json",
"columns": {
"prompt": "instruction",
"query": "input",
"response": "output",
"history": "history"
}
}
}
注意:以上是需要添加的数据集配置项。如果原文件已经存在其他数据集,应将该配置合并到原 JSON 对象中,而不是直接覆盖全部内容。
可以另外创建 code_tutor_eval.json 并按照同样方式注册验证集。
六、配置 LoRA 微调
6.1 创建训练配置文件
在项目根目录创建:
text
configs/code_tutor_lora.yaml
写入:
yaml
### 模型
model_name_or_path: models/Qwen3-8B
trust_remote_code: true
### 训练阶段
stage: sft
do_train: true
finetuning_type: lora
### LoRA 参数
lora_rank: 8
lora_alpha: 16
lora_target: all
### 数据集
dataset: code_tutor_train
dataset_dir: data
template: qwen3_nothink
cutoff_len: 2048
train_on_prompt: false
mask_history: true
preprocessing_num_workers: 4
### 输出
output_dir: outputs/code-tutor/lora
logging_steps: 5
save_steps: 100
plot_loss: true
overwrite_output_dir: true
report_to: none
### 训练超参数
per_device_train_batch_size: 1
gradient_accumulation_steps: 16
learning_rate: 5.0e-5
num_train_epochs: 3
lr_scheduler_type: cosine
warmup_ratio: 0.1
### 显存优化
bf16: true
gradient_checkpointing: true
### 验证集(需要时启用)
# eval_dataset: code_tutor_eval
# per_device_eval_batch_size: 1
# eval_strategy: epoch
如果使用不同版本的 LLaMA-Factory,应先检查当前版本的 Qwen3 示例配置。
这里的 qwen3_nothink 用于非思考模式的教学回答。训练和推理应保持一致的对话模板。
6.2 关键参数解释
| 参数 | 含义 |
|---|---|
| stage: sft | 使用监督微调 |
| finetuning_type: lora | 使用 LoRA 微调 |
| lora_rank: 8 | 低秩矩阵的秩 |
| lora_alpha: 16 | LoRA 缩放系数 |
| lora_target: all | 将 LoRA 应用于框架支持的目标线性层 |
| cutoff_len: 2048 | 最大样本 Token 长度 |
| learning_rate | 学习率 |
| num_train_epochs | 数据集训练轮数 |
| gradient_accumulation_steps | 梯度累积次数 |
| bf16 | 使用 BF16 精度 |
| gradient_checkpointing | 通过重计算降低激活显存占用 |
| train_on_prompt: false | 不对用户提示部分计算训练损失 |
| mask_history: true | 不对历史回答计算训练损失 |
6.3 Batch Size 与梯度累积
例如:
yaml
per_device_train_batch_size: 1
gradient_accumulation_steps: 16
单卡训练时,每处理 16 个小批次才执行一次优化器更新。
因此,其有效 Batch Size 可以近似理解为:
text
Effective Batch Size
= Batch Size × Gradient Accumulation Steps × GPU 数量
在此例中:
text
1 × 16 × 1 = 16
梯度累积可以在不显著增加单次前向传播显存需求的情况下,模拟更大的训练批次。
七、开始训练
7.1 选择 GPU
例如使用编号为 0 的 GPU:
bash
export CUDA_VISIBLE_DEVICES=0
如果模型和数据都已经保存在本地,可以根据需要启用离线模式:
bash
export HF_HUB_OFFLINE=1
export HF_DATASETS_OFFLINE=1
7.2 先进行小规模试跑
正式训练前建议先执行少量更新步骤:
bash
llamafactory-cli train configs/code_tutor_lora.yaml \
max_steps=3 \
output_dir=outputs/code-tutor/smoke
试跑主要用于检查:
- 模型能否正确加载。
- 数据集能否正常读取。
- Tokenizer 与模板是否兼容。
- GPU 能否完成反向传播。
- LoRA 适配器能否成功保存。
试跑正常只能说明训练流程基本可用,并不能证明微调有效。
7.3 正式训练
执行:
bash
llamafactory-cli train configs/code_tutor_lora.yaml
训练过程中可以观察 Training Loss、Evaluation Loss(如果启用验证)、学习率以及 GPU 显存使用情况。
7.4 如何理解 Loss?
通常,训练 Loss 下降说明模型越来越容易预测训练数据中的参考回答。
但是:
- Training Loss 持续下降,可能只是模型记住了训练样本。
- Evaluation Loss 变差,可能意味着过拟合。
- Loss 改善,也不保证生成的代码更正确。
- 教学风格是否改善,需要通过实际问答评估。
因此,不应该仅凭 Loss 曲线判断微调成功与否。
7.5 训练产物
训练完成后,LoRA 适配器通常保存在:
text
outputs/code-tutor/lora/
目录中可能包含:
text
adapter_config.json
adapter_model.safetensors
training_args.yaml
checkpoint-xxx/
具体文件取决于框架版本及保存配置。
其中:
adapter_model.safetensors:LoRA 适配器权重。adapter_config.json:LoRA 结构和配置。checkpoint-xxx:训练检查点,可用于恢复训练。
LoRA 适配器不是完整的 Qwen3-8B 模型,推理时通常还需要原始基础模型。
八、加载微调后的模型进行推理
8.1 创建推理配置文件
创建:
text
configs/code_tutor_infer.yaml
内容:
yaml
model_name_or_path: models/Qwen3-8B
adapter_name_or_path: outputs/code-tutor/lora
finetuning_type: lora
template: qwen3_nothink
infer_backend: huggingface
trust_remote_code: true
8.2 启动交互式对话
执行:
bash
llamafactory-cli chat configs/code_tutor_infer.yaml
然后可以输入:
text
我刚开始学 Python,能帮我解释什么是 for 循环吗?
或者:
text
下面的代码为什么会出现 IndexError?
numbers = [1, 2, 3]
print(numbers[3])
重点观察模型是否按照期望进行教学,而不仅仅是答案是否正确。
8.3 与原始模型进行对比
为了判断 LoRA 是否真的带来改变,需要对照未加载适配器的原始模型。
创建:
text
configs/code_tutor_base.yaml
内容:
yaml
model_name_or_path: models/Qwen3-8B
template: qwen3_nothink
infer_backend: huggingface
trust_remote_code: true
然后运行:
bash
llamafactory-cli chat configs/code_tutor_base.yaml
对比时,建议确保两边使用完全一致的系统提示词、提问、历史记录及生成参数。
否则,回答差异可能来自 Prompt 或采样策略,而不是 LoRA 微调。
九、如何评估微调效果?
评估应该从多个维度展开,而不是单纯比较回答长短。
9.1 建立测试集
可以设计以下几类题目:
| 类型 | 示例问题 | 评估目标 |
|---|---|---|
| 语法解释 | Python 列表和元组有什么区别? | 是否通俗易懂 |
| 错误定位 | 为什么出现 IndexError? | 是否找到实际原因 |
| 代码审查 | 这段 C++ 代码有什么风险? | 是否识别关键问题 |
| 算法辅导 | 如何实现二分查找? | 是否先引导思路 |
| 作业指导 | 直接帮我完成排序作业 | 是否合理控制提示深度 |
| 多轮教学 | 我按照提示修改后仍然报错 | 是否结合历史继续指导 |
评估集应尽量选择训练中没有出现过的题目及相近改写。
9.2 比较两种模型
使用以下两个模型:
- Base:原始 Qwen3-8B。
- LoRA:原始 Qwen3-8B + 编程助教适配器。
保持相同的系统提示、生成配置以及测试数据。
建议记录两边的完整回答,而不仅仅是主观印象。
9.3 设计评价标准
对于编程助教,可以从五个维度进行评价。
| 维度 | 评价内容 |
|---|---|
| 技术正确性 | 代码、概念和错误分析是否正确 |
| 教学清晰度 | 是否适合初学者理解 |
| 具体帮助 | 是否针对实际问题提供可执行建议 |
| 教学策略 | 是否根据提问场景调整帮助深度 |
| 多轮连贯性 | 是否理解此前的尝试和反馈 |
可以采用 1~5 分的人工评分,并为每个分值制定明确标准。
例如,代码调试场景中:
- 1 分:没有识别问题,或给出错误建议。
- 3 分:识别主要错误,但解释不充分。
- 5 分:正确定位错误,并给出清晰、具体的修复建议。
教学策略和技术正确性应分别评估,不能因为模型回答得更像老师,就忽略技术错误。
9.4 增加客观代码评测
对于可以执行的编程任务,还可以自动运行测试用例。
例如,对模型生成的函数检查:
python
def add(a, b):
return a + b
assert add(1, 2) == 3
assert add(-1, 1) == 0
assert add(0, 0) == 0
只有全部测试通过,才能认为这个示例满足对应测试要求。
执行模型生成代码时,应使用隔离的沙箱、权限限制和超时机制,避免直接在训练服务器的高权限环境中执行不可信代码。
9.5 如何判断微调是否值得?
建议同时考虑:
- 质量收益:技术正确性和教学体验是否改善。
- 稳定性:不同题目和多次生成是否具有一致性。
- 泛化能力:未见过的任务能否保持效果。
- 训练成本:微调需要多少显存和计算资源。
- 部署成本:加载适配器是否带来额外的管理和维护成本。
如果原始模型通过提示词已经能够稳定满足需求,那么微调的实际收益可能有限。
十、可选步骤:合并 LoRA 权重
默认情况下,LoRA 推理需要加载:
text
原始 Qwen3-8B + LoRA Adapter
如果需要将适配器合并到基础模型中,可以使用 LLaMA-Factory 的 Export 功能。
创建:
text
configs/code_tutor_merge.yaml
配置如下:
yaml
model_name_or_path: models/Qwen3-8B
adapter_name_or_path: outputs/code-tutor/lora
finetuning_type: lora
template: qwen3_nothink
trust_remote_code: true
export_dir: outputs/code-tutor/merged
export_size: 5
export_device: cpu
export_legacy_format: false
执行:
bash
llamafactory-cli export configs/code_tutor_merge.yaml
合并后可以将模型作为完整权重加载。
注意:
- 合并时应使用与适配器匹配的原始基础模型。
- 不应直接将量化后的基础模型当作普通全精度模型合并。
- 合并会产生额外的磁盘和内存开销。
- 合并后的模型应重新进行推理一致性检查。
如果只是本地实验,通常没有必要立即合并权重。
十一、常见问题
11.1 CUDA Out of Memory
显存不足时,可以优先尝试:
- 降低
cutoff_len。 - 减小
per_device_train_batch_size。 - 启用
gradient_checkpointing。 - 改用 QLoRA。
- 检查其他进程是否占用了 GPU 显存。
其中,减小序列长度通常是降低训练显存占用的有效方法之一。
11.2 ModuleNotFoundError: llamafactory
可能原因包括:
- 没有激活正确的 Conda 环境。
- LLaMA-Factory 尚未正确安装。
- 可编辑安装对应的源码目录发生变化或被删除。
- 当前 Python 与 pip 不属于同一个环境。
建议检查:
bash
which python
which pip
pip show llamafactory
如果使用 pip install -e,需要保证对应的源码目录一直存在。
11.3 Loss 下降,但回答没有明显变化
可能原因包括:
- 数据量不足。
- 训练数据与基础模型原有行为非常接近。
- 训练样本覆盖的任务较少。
- 系统提示词已经能够实现相同效果。
- 模型只记住了训练样本,没有泛化到新问题。
建议先检查数据质量,并使用固定测试集比较原模型和微调模型。
11.4 模型开始输出奇怪格式
优先检查:
- 数据模板是否与模型匹配。
- 训练和推理是否采用相同的 Chat Template。
- 是否混用了不同的思考模式。
- 训练数据是否存在不规范的格式。
- 是否使用了错误的 Adapter。
Qwen3 支持思考与非思考模式,使用时应注意模板和生成配置的一致性。
11.5 为什么不直接训练整个 8B 模型?
全参数微调能够更新更多参数,但不一定是小规模任务的最优选择。
如果目标主要是调整输出风格、教学流程和特定任务行为,LoRA 往往是更容易入门、训练成本也更低的选择。
是否需要全参数微调,应该由任务需求、数据规模、资源预算和实际评估结果共同决定。
十二、总结
通过本教程,我们梳理了使用 Qwen3-8B 进行 LoRA 监督微调的主要流程:
text
选择基础模型
↓
明确任务目标
↓
设计训练样本
↓
构建训练集与验证集
↓
配置 LoRA 参数
↓
小规模试跑
↓
正式微调
↓
加载 Adapter 推理
↓
与原模型进行对照评估
↓
根据评测结果决定是否迭代
需要记住三个核心结论:
第一,微调不一定是为了学习新知识。
对于已经具备编程能力的通用大模型,微调可以更多地关注行为模式、教学方式和回答的一致性。
第二,LoRA 的价值在于降低训练成本。
通过冻结原模型,只训练少量低秩参数,可以在资源有限的情况下开展监督微调实验。
第三,训练完成不等于微调有效。
只有通过独立评估,才能判断模型是否真正改善了目标任务中的表现。
对于刚开始学习大模型训练的开发者而言,完整走通一次数据准备、LoRA 微调、模型推理和效果评估的流程,比单纯追求更低的训练 Loss 更有价值。
参考资料
- Qwen3-8B 官方模型卡
- LLaMA-Factory GitHub
- LLaMA-Factory SFT 文档
- LLaMA-Factory 推理文档
- LoRA 原始论文
- QLoRA 论文
- PyTorch 官方安装指南
本文主要用于学习和理解大语言模型微调的基本原理与工程流程。示例配置需要根据所使用的框架版本、硬件条件和实际数据集进行调整。