llama-factory微调Qwen3 14B_qwen3-14b
Qwen3-14b-QLoRA 配置详解
概述
本文档详细介绍了Qwen3-14b-QLoRA微调配置的每个模块,包括各配置项的作用、原理和设置理由。该配置针对四卡GPU环境下的14B参数模型进行了优化,使用QLoRA技术实现高效的参数微调。
没这个配置也可以租个gpu服务器啥的,花不了多少钱。
开了cpu卸载后内存占用:CPU Virtual Memory: used = 51.92 GB
训练脚本自取
我用夸克网盘分享了「Qwen3-14b-QLoRA.zip」- https://pan.quark.cn/s/55de54b222ac
数据集我从AI-MO/NuminaMath-CoT中随机选了200条,然后整成以下格式:
[ { \"source\": \"olympiads\", \"problem\": \"Let \\\\( n \\\\) be a positive integer. Given \\\\(\\\\left(1+x+x^{2}\\\\right)^{n}=a_{0}+a_{1} x+a_{2} x^{2}+\\\\cdots+a_{2n} x^{2n} \\\\), find the value of \\\\( a_{0}+a_{3}+a_{6}+a_{9}+\\\\cdots \\\\).\", \"solution\": \"\\n1. **Recalling the given information**:\\n We are given that for a positive integer \\\\( n \\\\),\\n \\\\[\\n (1 + x + x^2)^n = a_0 + a_1 x + a_2 x^2 + \\\\cdots + a_{2n} x^{2n}.\\n \\\\]\\n\\n2. **Introducing the roots of unity**:\\n Let \\\\(\\\\omega = e^{2\\\\pi i / 3} = \\\\frac{-1 + i \\\\sqrt{3}}{2}\\\\), which is a primitive cube root of unity. This implies:\\n \\\\[\\n \\\\omega^3 = 1, \\\\quad \\\\omega^2 + \\\\omega + 1 = 0.\\n \\\\]\\n\\n3. **Substituting \\\\(x = \\\\omega\\\\)**:\\n Substitute \\\\(x = \\\\omega\\\\) in the expansion. Therefore, we have:\\n \\\\[\\n (1 + \\\\omega + \\\\omega^2)^n = a_0 + a_1 \\\\omega + a_2 \\\\omega^2 + a_3 \\\\omega^3 + a_4 \\\\omega^4 + \\\\cdots + a_{2n} \\\\omega^{2n}.\\n \\\\]\\n\\n4. **Simplification using properties of \\\\(\\\\omega\\\\)**:\\n Given \\\\(\\\\omega^2 + \\\\omega + 1 = 0\\\\), we find:\\n \\\\[\\n 1 + \\\\omega + \\\\omega^2 = 0.\\n \\\\]\\n Hence:\\n \\\\[\\n (1 + \\\\omega + \\\\omega^2)^n = 0^n = 0.\\n \\\\]\\n Therefore:\\n \\\\[\\n 0 = a_0 + a_1 \\\\omega + a_2 \\\\omega^2 + a_3 + a_4 \\\\omega + \\\\cdots + a_{2n} \\\\omega^{2n}.\\n \\\\]\\n\\n5. **Defining group sums \\\\(S_1, S_2, S_3\\\\)**:\\n Let the sums of the coefficients in specific groupings be:\\n \\\\[\\n S_1 = a_0 + a_3 + a_6 + \\\\cdots,\\n \\\\]\\n \\\\[\\n S_2 = a_1 + a_4 + a_7 + \\\\cdots,\\n \\\\]\\n \\\\[\\n S_3 = a_2 + a_5 + a_8 + \\\\cdots.\\n \\\\]\\n\\n6. **Setting up the system of equations**:\\n From the substitution of \\\\(x = \\\\omega\\\\) we have:\\n \\\\[\\n 0 = S_1 + S_2 \\\\omega + S_3 \\\\omega^2.\\n \\\\]\\n Since \\\\(\\\\omega^2 + \\\\omega + 1 = 0\\\\), we can rewrite the above as:\\n \\\\[\\n S_1 + \\\\omega S_2 + \\\\omega^2 S_3 = 0.\\n \\\\]\\n Additionally, using the properties of \\\\(\\\\omega\\\\), particularly conjugation and the cubic nature, achieve:\\n \\\\[\\n \\\\omega^2(S_2 - S_3) = 0 \\\\Rightarrow S_2 = S_3.\\n \\\\]\\n\\n7. **Establish equality among sums**:\\n Now we obtain:\\n \\\\[\\n S_1 + \\\\omega S_2 + \\\\omega^2 S_2 = 0,\\n \\\\]\\n \\\\[\\n S_1 + S_2(\\\\omega + \\\\omega^2) = 0,\\n \\\\]\\n And thus \\\\(\\\\omega + \\\\omega^2 = -1\\\\), which simplifies further to \\\\(S_1 = S_2 = S_3\\\\).\\n\\n8. **Simplification with \\\\(x = 1\\\\)**:\\n Substitute \\\\(x = 1\\\\) in the expansion results:\\n \\\\[\\n (1 + 1 + 1)^n = 3^n = a_0 + a_1 + a_2 + \\\\cdots + a_{2n}.\\n \\\\]\\n Hence:\\n \\\\[\\n S_1 + S_2 + S_3 = 3^n.\\n \\\\]\\n\\n9. **Conclusion**:\\n Since \\\\(S_1 = S_2 = S_3\\\\), we can write:\\n \\\\[\\n 3S_1 = 3^n \\\\Rightarrow S_1 = 3^{n-1}.\\n \\\\]\\n Hence, the value of \\\\(a_0 + a_3 + a_6 + a_9 + \\\\cdots\\\\) is \\\\(3^{n-1}\\\\).\\n\\n\\\\[\\n\\\\boxed{3^{n-1}}\\n\\\\]\", \"messages\": [ { \"content\": \"Let \\\\( n \\\\) be a positive integer. Given \\\\(\\\\left(1+x+x^{2}\\\\right)^{n}=a_{0}+a_{1} x+a_{2} x^{2}+\\\\cdots+a_{2n} x^{2n} \\\\), find the value of \\\\( a_{0}+a_{3}+a_{6}+a_{9}+\\\\cdots \\\\).\", \"role\": \"user\" }, { \"content\": \"\\n1. **Recalling the given information**:\\n We are given that for a positive integer \\\\( n \\\\),\\n \\\\[\\n (1 + x + x^2)^n = a_0 + a_1 x + a_2 x^2 + \\\\cdots + a_{2n} x^{2n}.\\n \\\\]\\n\\n2. **Introducing the roots of unity**:\\n Let \\\\(\\\\omega = e^{2\\\\pi i / 3} = \\\\frac{-1 + i \\\\sqrt{3}}{2}\\\\), which is a primitive cube root of unity. This implies:\\n \\\\[\\n \\\\omega^3 = 1, \\\\quad \\\\omega^2 + \\\\omega + 1 = 0.\\n \\\\]\\n\\n3. **Substituting \\\\(x = \\\\omega\\\\)**:\\n Substitute \\\\(x = \\\\omega\\\\) in the expansion. Therefore, we have:\\n \\\\[\\n (1 + \\\\omega + \\\\omega^2)^n = a_0 + a_1 \\\\omega + a_2 \\\\omega^2 + a_3 \\\\omega^3 + a_4 \\\\omega^4 + \\\\cdots + a_{2n} \\\\omega^{2n}.\\n \\\\]\\n\\n4. **Simplification using properties of \\\\(\\\\omega\\\\)**:\\n Given \\\\(\\\\omega^2 + \\\\omega + 1 = 0\\\\), we find:\\n \\\\[\\n 1 + \\\\omega + \\\\omega^2 = 0.\\n \\\\]\\n Hence:\\n \\\\[\\n (1 + \\\\omega + \\\\omega^2)^n = 0^n = 0.\\n \\\\]\\n Therefore:\\n \\\\[\\n 0 = a_0 + a_1 \\\\omega + a_2 \\\\omega^2 + a_3 + a_4 \\\\omega + \\\\cdots + a_{2n} \\\\omega^{2n}.\\n \\\\]\\n\\n5. **Defining group sums \\\\(S_1, S_2, S_3\\\\)**:\\n Let the sums of the coefficients in specific groupings be:\\n \\\\[\\n S_1 = a_0 + a_3 + a_6 + \\\\cdots,\\n \\\\]\\n \\\\[\\n S_2 = a_1 + a_4 + a_7 + \\\\cdots,\\n \\\\]\\n \\\\[\\n S_3 = a_2 + a_5 + a_8 + \\\\cdots.\\n \\\\]\\n\\n6. **Setting up the system of equations**:\\n From the substitution of \\\\(x = \\\\omega\\\\) we have:\\n \\\\[\\n 0 = S_1 + S_2 \\\\omega + S_3 \\\\omega^2.\\n \\\\]\\n Since \\\\(\\\\omega^2 + \\\\omega + 1 = 0\\\\), we can rewrite the above as:\\n \\\\[\\n S_1 + \\\\omega S_2 + \\\\omega^2 S_3 = 0.\\n \\\\]\\n Additionally, using the properties of \\\\(\\\\omega\\\\), particularly conjugation and the cubic nature, achieve:\\n \\\\[\\n \\\\omega^2(S_2 - S_3) = 0 \\\\Rightarrow S_2 = S_3.\\n \\\\]\\n\\n7. **Establish equality among sums**:\\n Now we obtain:\\n \\\\[\\n S_1 + \\\\omega S_2 + \\\\omega^2 S_2 = 0,\\n \\\\]\\n \\\\[\\n S_1 + S_2(\\\\omega + \\\\omega^2) = 0,\\n \\\\]\\n And thus \\\\(\\\\omega + \\\\omega^2 = -1\\\\), which simplifies further to \\\\(S_1 = S_2 = S_3\\\\).\\n\\n8. **Simplification with \\\\(x = 1\\\\)**:\\n Substitute \\\\(x = 1\\\\) in the expansion results:\\n \\\\[\\n (1 + 1 + 1)^n = 3^n = a_0 + a_1 + a_2 + \\\\cdots + a_{2n}.\\n \\\\]\\n Hence:\\n \\\\[\\n S_1 + S_2 + S_3 = 3^n.\\n \\\\]\\n\\n9. **Conclusion**:\\n Since \\\\(S_1 = S_2 = S_3\\\\), we can write:\\n \\\\[\\n 3S_1 = 3^n \\\\Rightarrow S_1 = 3^{n-1}.\\n \\\\]\\n Hence, the value of \\\\(a_0 + a_3 + a_6 + a_9 + \\\\cdots\\\\) is \\\\(3^{n-1}\\\\).\\n\\n\\\\[\\n\\\\boxed{3^{n-1}}\\n\\\\]\", \"role\": \"assistant\" } ] }, ......]
配置环境说明
硬件配置
- GPU: 4×Tesla T10 (16GB显存/卡)
- 总显存: 64GB
- CUDA版本: 12.9
- 驱动版本: 575.51.03
软件环境
- Python环境: vllm虚拟环境
- 训练框架: LLaMA-Factory
- 深度学习库: DeepSpeed + Transformers + BitsAndBytes
- 模型: Qwen3-14B (约14B参数)
显存占用分析
训练过程中的显存使用情况
根据实际训练监控数据,四卡训练Qwen3-14B模型的显存占用情况如下:
+-----------------------------------------------------------------------------------------+| NVIDIA-SMI 575.51.03 Driver Version: 575.51.03 CUDA Version: 12.9 ||-----------------------------------------+------------------------+----------------------+| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC || Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. || | | MIG M. ||=========================================+========================+======================|| 0 Tesla T10Off | 00000000:05:00.0 Off | Off || N/A 74C P0 133W / 150W | 15642MiB / 16384MiB | 100% Default || | | N/A |+-----------------------------------------+------------------------+----------------------+| 1 Tesla T10Off | 00000000:06:00.0 Off | Off || N/A 59C P0 132W / 150W | 15712MiB / 16384MiB | 100% Default || | | N/A |+-----------------------------------------+------------------------+----------------------+| 2 Tesla T10Off | 00000000:09:00.0 Off | Off || N/A 62C P0 103W / 150W | 13116MiB / 16384MiB | 100% Default || | | N/A |+-----------------------------------------+------------------------+----------------------+| 3 Tesla T10Off | 00000000:0A:00.0 Off | Off || N/A 50C P0 124W / 150W | 14590MiB / 16384MiB | 100% Default || | | N/A |+-----------------------------------------+------------------------+----------------------+
显存占用详细分析
平均显存使用率: 90.1%
总显存使用: 58.94 GB / 64 GB
显存占用优化效果
1. QLoRA技术的显存节省
- 传统全量微调: 约需要 80-100GB 显存
- QLoRA微调: 实际使用 59GB 显存
- 节省显存: 约 30-40%
2. 各项优化技术的贡献
- 4位量化: 减少约 60-70% 的模型权重显存
- ZeRO-3分片: 将参数分片到4张卡,每卡负担1/4
- CPU卸载: 优化器状态和部分参数卸载到CPU
- 梯度检查点: 减少约 30-50% 的激活显存
- 激活检查点: 额外减少 20-30% 的激活显存
3. 显存分配详细分析
每GPU显存分配估算 (以GPU 0为例):├── 模型权重 (4bit量化) : ~4,000 MB├── LoRA适配器 : ~200 MB├── 优化器状态 (部分CPU卸载) : ~3,000 MB├── 梯度缓存 : ~2,000 MB├── 激活值 : ~4,000 MB├── 中间计算缓存 : ~1,500 MB├── DeepSpeed运行时开销 : ~800 MB└── 其他系统开销 : ~142 MB ───────────────────────────────── 总计 : ~15,642 MB
性能表现
1. 训练效率指标
- GPU利用率: 100% (所有GPU满负载运行)
- 训练速度: 约 2-3 steps/秒 (取决于序列长度)
- 温度控制: 50-74°C (在安全范围内)
- 功耗: 103-133W (Tesla T10额定150W)
2. 内存效率对比
配置优化建议
基于实际显存使用情况,提供以下优化建议:
1. 显存充足时的调整
- 可以适当增加
per_device_train_batch_size到 3-4 - 可以增加
cutoff_len到 4096 - 可以使用
lora_rank24-32
2. 显存紧张时的调整
- 减少
per_device_train_batch_size到 1 - 启用更激进的CPU卸载
- 减少
cutoff_len到 1024 - 降低
lora_rank到 8-12
3. 监控要点
- 定期检查显存使用率,避免超过95%
- 监控GPU温度,保持在75°C以下
- 观察训练速度,确保资源充分利用
1. 模型配置模块 (Model Configuration)
1.1 基础模型配置
model_name_or_path: /home/amazcuter/.cache/modelscope/hub/models/Qwen/Qwen3-14Badapter_name_or_path: nullcache_dir: nullmodel_revision: main
详细说明:
-
model_name_or_path: 指定预训练模型路径
- 作用: 加载Qwen3-14B基座模型
- 为什么这样设置: 使用本地缓存路径可以避免重复下载,提高训练启动速度
-
adapter_name_or_path: LoRA适配器路径
- 作用: 如果从现有的LoRA适配器继续训练,可以指定路径
- 为什么设置为null: 从头开始训练新的LoRA适配器
-
cache_dir: 缓存目录
- 作用: 指定模型缓存存储位置
- 为什么设置为null: 使用默认缓存位置
1.2 分词器配置
use_fast_tokenizer: trueresize_vocab: falsesplit_special_tokens: false
详细说明:
-
use_fast_tokenizer: 使用快速分词器
- 作用: 提高文本预处理速度
- 为什么设置为true: Fast tokenizer基于Rust实现,速度比Python版本快数倍
-
resize_vocab: 词汇表大小调整
- 作用: 是否调整词汇表大小以适应新的特殊token
- 为什么设置为false: Qwen3模型的词汇表已经足够完整,无需调整
-
split_special_tokens: 分割特殊token
- 作用: 是否将特殊token进一步分割
- 为什么设置为false: 保持特殊token的完整性
1.3 内存优化配置
low_cpu_mem_usage: trueflash_attn: autoshift_attn: falsegradient_checkpointing: truedisable_gradient_checkpointing: false
详细说明:
-
low_cpu_mem_usage: 低CPU内存使用
- 作用: 减少模型加载时的CPU内存占用
- 为什么设置为true: 14B模型较大,需要减少CPU内存压力
-
flash_attn: Flash Attention
- 作用: 使用Flash Attention优化attention计算
- 为什么设置为auto: 自动检测并使用Flash Attention,提高训练效率
-
gradient_checkpointing: 梯度检查点
- 作用: 通过重新计算来换取内存空间
- 为什么设置为true: 14B模型需要大量显存,使用梯度检查点可以显著减少显存占用
1.4 其他优化配置
rope_scaling: nullmixture_of_depths: nulluse_unsloth: falsemoe_aux_loss_coef: nullupcast_layernorm: falseupcast_lmhead_output: false
详细说明:
-
rope_scaling: RoPE位置编码缩放
- 作用: 用于处理超长序列的位置编码
- 为什么设置为null: 使用默认的序列长度,无需特殊缩放
-
use_unsloth: 使用Unsloth加速
- 作用: 使用Unsloth库进行训练加速
- 为什么设置为false: 确保兼容性,使用标准训练方式
2. 训练方法配置模块 (Training Method Configuration)
2.1 训练阶段和类型
stage: sftdo_train: truefinetuning_type: lora
详细说明:
-
stage: 训练阶段
- 作用: 指定训练类型为监督微调(Supervised Fine-tuning)
- 为什么选择sft: 使用有监督的数据进行指令微调,提高模型的指令遵循能力
-
finetuning_type: 微调类型
- 作用: 指定使用LoRA微调方法
- 为什么选择lora: LoRA只训练少量参数,显著减少显存需求和训练时间
2.2 LoRA配置
lora_target: alllora_rank: 16lora_alpha: 32lora_dropout: 0.1loraplus_lr_ratio: 1.0use_rslora: falseuse_dora: false
详细说明:
-
lora_target: LoRA目标层
- 作用: 指定在哪些层应用LoRA
- 为什么设置为all: 对所有线性层应用LoRA,获得更好的微调效果
-
lora_rank: LoRA秩
- 作用: 控制LoRA矩阵的秩,影响参数量和表达能力
- 为什么设置为16: 在参数效率和表达能力之间取得平衡,16是经验证的有效值
-
lora_alpha: LoRA缩放因子
- 作用: 控制LoRA输出的缩放程度
- 为什么设置为32: 通常设置为rank的2倍,保证训练稳定性
-
lora_dropout: LoRA dropout
- 作用: 在LoRA层中应用dropout防止过拟合
- 为什么设置为0.1: 适中的dropout率,既防止过拟合又不影响收敛
2.3 量化配置
quantization_bit: 4quantization_method: bitsandbytespure_bf16: false
详细说明:
-
quantization_bit: 量化位数
- 作用: 使用4位量化压缩模型权重
- 为什么设置为4: 4位量化可以将显存占用减少到原来的1/4,同时保持较好的性能
-
quantization_method: 量化方法
- 作用: 指定使用BitsAndBytes库进行量化
- 为什么选择bitsandbytes: 该库专门为transformers模型优化,支持4位量化和QLoRA
2.4 其他训练方法参数
create_new_adapter: falseuse_badam: falsebadam_mode: layerbadam_switch_mode: ascendingbadam_switch_interval: 50badam_update_ratio: 0.05pissa_init: falsepissa_iter: 16pissa_convert: falsefreeze_trainable_layers: 2freeze_extra_modules: null
详细说明:
-
create_new_adapter: 创建新适配器
- 作用: 是否创建新的adapter而不是修改现有的
- 为什么设置为false: 直接训练LoRA适配器,不需要额外的adapter层
-
freeze_trainable_layers: 冻结可训练层数
- 作用: 冻结模型底层的若干层,只训练高层
- 为什么设置为2: 冻结底层2层,保留底层特征表示,只微调高层语义
3. 数据集配置模块 (Dataset Configuration)
3.1 数据集基本配置
dataset: math_traintemplate: chatmlcutoff_len: 2048train_on_prompt: falsemask_history: true
详细说明:
-
dataset: 数据集名称
- 作用: 指定使用的数据集
- 为什么选择math_train: 使用数学问题数据集,提高模型的数学推理能力
-
template: 对话模板
- 作用: 指定对话格式模板
- 为什么选择chatml: ChatML格式是标准的对话格式,便于模型理解对话结构
-
cutoff_len: 截断长度
- 作用: 限制输入序列的最大长度
- 为什么设置为2048: 平衡内存占用和序列完整性,2048是常用的序列长度
-
train_on_prompt: 训练提示词
- 作用: 是否在提示词部分计算损失
- 为什么设置为false: 只在回答部分计算损失,避免学习用户输入
-
mask_history: 掩码历史
- 作用: 是否掩码对话历史部分
- 为什么设置为true: 只关注当前轮次的回答,提高训练效率
3.2 数据处理配置
overwrite_cache: truepreprocessing_num_workers: 4max_samples: 200eval_dataset: nullval_size: 0.1
详细说明:
-
overwrite_cache: 覆盖缓存
- 作用: 是否重新处理数据集并覆盖缓存
- 为什么设置为true: 确保使用最新的数据处理结果
-
preprocessing_num_workers: 预处理工作进程数
- 作用: 并行处理数据集的进程数量
- 为什么设置为4: 充分利用多核CPU进行数据预处理,加快数据加载速度
-
max_samples: 最大样本数
- 作用: 限制训练使用的样本数量
- 为什么设置为200: 用于快速验证配置,实际训练可以增加这个值
-
val_size: 验证集比例
- 作用: 从训练集中划分验证集的比例
- 为什么设置为0.1: 10%的验证集足以监控训练效果
4. 输出配置模块 (Output Configuration)
4.1 输出路径和日志
output_dir: ./saves/qwen3-14b/lora/sftlogging_steps: 5save_steps: 200plot_loss: trueoverwrite_output_dir: false
详细说明:
-
output_dir: 输出目录
- 作用: 指定模型保存路径
- 为什么这样设置: 清晰的目录结构,便于管理不同的实验
-
logging_steps: 日志记录步数
- 作用: 每隔多少步记录一次训练日志
- 为什么设置为5: 频繁记录日志,便于监控训练过程
-
save_steps: 保存步数
- 作用: 每隔多少步保存一次模型检查点
- 为什么设置为200: 适中的保存频率,既保证训练安全又不过度占用存储
-
plot_loss: 绘制损失曲线
- 作用: 是否生成损失曲线图
- 为什么设置为true: 便于可视化训练过程,监控收敛情况
5. 训练参数配置模块 (Training Parameters Configuration)
5.1 批次大小和梯度累积
per_device_train_batch_size: 2gradient_accumulation_steps: 4per_device_eval_batch_size: 2
详细说明:
-
per_device_train_batch_size: 每设备训练批次大小
- 作用: 每个GPU上的批次大小
- 为什么设置为2: 14B模型较大,设置较小的批次大小以适应显存限制
-
gradient_accumulation_steps: 梯度累积步数
- 作用: 累积多少步的梯度后再进行一次参数更新
- 为什么设置为4: 有效批次大小 = 2×4×4(GPU数) = 32,合理的有效批次大小
-
计算有效批次大小: 2(per_device) × 4(accumulation) × 4(GPUs) = 32
5.2 学习率配置
learning_rate: 3.0e-5lr_scheduler_type: cosinewarmup_ratio: 0.1
详细说明:
-
learning_rate: 学习率
- 作用: 控制参数更新的步长
- 为什么设置为3.0e-5: 对于大模型微调,这是一个安全且有效的学习率
-
lr_scheduler_type: 学习率调度器类型
- 作用: 控制学习率在训练过程中的变化
- 为什么选择cosine: 余弦退火调度器能够平滑地降低学习率,有助于收敛
-
warmup_ratio: 预热比例
- 作用: 训练初期学习率逐渐升高的比例
- 为什么设置为0.1: 10%的预热期有助于训练稳定性
5.3 训练轮次和精度
num_train_epochs: 20.0bf16: falsefp16: truepure_bf16: false
详细说明:
-
num_train_epochs: 训练轮次
- 作用: 完整遍历数据集的次数
- 为什么设置为20: 对于小数据集,多轮训练能够充分学习
-
fp16: 半精度训练
- 作用: 使用16位浮点数进行训练
- 为什么设置为true: 减少显存占用,提高训练速度,同时保持数值稳定性
-
bf16: Brain Float 16
- 作用: 使用bfloat16数据类型
- 为什么设置为false: 与fp16互斥,选择fp16以获得更好的兼容性
5.4 其他训练参数
ddp_timeout: 180000000include_num_input_tokens_seen: true
详细说明:
-
ddp_timeout: 分布式训练超时时间
- 作用: 设置分布式训练的超时限制
- 为什么设置为180000000: 大模型训练时间较长,设置较长的超时时间
-
include_num_input_tokens_seen: 包含已见token数量
- 作用: 在日志中记录已处理的token数量
- 为什么设置为true: 便于监控训练进度
6. 评估配置模块 (Evaluation Configuration)
eval_strategy: stepseval_steps: 200eval_on_start: false
详细说明:
-
eval_strategy: 评估策略
- 作用: 指定何时进行评估
- 为什么选择steps: 基于步数进行评估,更加灵活
-
eval_steps: 评估步数
- 作用: 每隔多少步进行一次评估
- 为什么设置为200: 与保存步数一致,便于监控模型性能
-
eval_on_start: 训练开始时评估
- 作用: 是否在训练开始前进行评估
- 为什么设置为false: 节省时间,直接开始训练
7. 保存配置模块 (Save Configuration)
save_strategy: stepssave_only_model: falsesave_safetensors: true
详细说明:
-
save_strategy: 保存策略
- 作用: 指定何时保存模型
- 为什么选择steps: 基于步数保存,与评估策略一致
-
save_only_model: 仅保存模型
- 作用: 是否只保存模型权重,不保存优化器状态
- 为什么设置为false: 保存完整的训练状态,便于断点续训
-
save_safetensors: 使用SafeTensors格式
- 作用: 使用更安全的模型保存格式
- 为什么设置为true: SafeTensors格式更安全,加载速度更快
8. DeepSpeed配置模块 (DeepSpeed Configuration)
8.1 DeepSpeed配置引用
deepspeed: ./configs/ds_config_zero3.json
详细说明:
- deepspeed: DeepSpeed配置文件路径
- 作用: 指定DeepSpeed的详细配置
- 为什么使用DeepSpeed: 支持大模型训练,提供内存优化和分布式训练功能
8.2 DeepSpeed ZeRO-3详细配置
8.2.1 精度配置
\"fp16\": { \"enabled\": true, \"loss_scale\": 0, \"initial_scale_power\": 16, \"loss_scale_window\": 1000, \"hysteresis\": 2, \"min_loss_scale\": 1}
详细说明:
-
enabled: 启用fp16训练
- 作用: 使用半精度浮点数训练
- 为什么设置为true: 减少显存占用,提高训练速度
-
loss_scale: 损失缩放
- 作用: 防止梯度下溢
- 为什么设置为0: 使用动态损失缩放,自动调整
-
initial_scale_power: 初始缩放幂次
- 作用: 初始损失缩放的幂次(2^16)
- 为什么设置为16: 提供足够的梯度精度
8.2.2 优化器配置
\"optimizer\": { \"type\": \"AdamW\", \"params\": { \"lr\": \"auto\", \"betas\": \"auto\", \"eps\": \"auto\", \"weight_decay\": \"auto\" }}
详细说明:
-
type: 优化器类型
- 作用: 指定使用AdamW优化器
- 为什么选择AdamW: AdamW对大模型训练效果好,有内置权重衰减
-
params: 参数设置为auto
- 作用: 自动从HuggingFace配置中获取参数
- 为什么设置为auto: 保持与主配置文件的一致性
8.2.3 ZeRO-3优化配置
\"zero_optimization\": { \"stage\": 3, \"overlap_comm\": true, \"contiguous_gradients\": true, \"sub_group_size\": 1e9, \"reduce_bucket_size\": \"auto\", \"stage3_prefetch_bucket_size\": \"auto\", \"stage3_param_persistence_threshold\": \"auto\", \"stage3_max_live_parameters\": 1e9, \"stage3_max_reuse_distance\": 1e9, \"stage3_gather_16bit_weights_on_model_save\": true, \"round_robin_gradients\": true, \"offload_optimizer\": { \"device\": \"cpu\", \"pin_memory\": true }, \"offload_param\": { \"device\": \"cpu\", \"pin_memory\": true }}
详细说明:
-
stage: ZeRO阶段
- 作用: 指定使用ZeRO-3,分片参数、梯度和优化器状态
- 为什么选择3: 最大程度减少显存占用,适合大模型训练
-
overlap_comm: 重叠通信
- 作用: 计算和通信重叠执行
- 为什么设置为true: 提高训练效率,减少通信开销
-
offload_optimizer/offload_param: CPU卸载
- 作用: 将优化器状态和参数卸载到CPU内存
- 为什么启用: 进一步减少GPU显存占用,支持更大模型训练
-
pin_memory: 内存锁定
- 作用: 锁定CPU内存,加快CPU-GPU数据传输
- 为什么设置为true: 提高数据传输效率
8.2.4 激活检查点配置
\"activation_checkpointing\": { \"partition_activations\": true, \"cpu_checkpointing\": true, \"contiguous_memory_optimization\": false, \"number_checkpoints\": 4, \"synchronize_checkpoint_boundary\": false, \"profile\": false}
详细说明:
-
partition_activations: 分区激活
- 作用: 将激活值分区存储
- 为什么设置为true: 进一步减少显存占用
-
cpu_checkpointing: CPU检查点
- 作用: 将激活检查点存储在CPU内存中
- 为什么设置为true: 最大化显存节省
-
number_checkpoints: 检查点数量
- 作用: 每层的检查点数量
- 为什么设置为4: 在内存和重计算开销之间取得平衡
9. 数据集配置文件 (Dataset Info Configuration)
9.1 数据集信息
{ \"math_train\": { \"file_name\": \"small_dataset.json\", \"file_sha1\": \"\", \"formatting\": \"sharegpt\", \"columns\": { \"messages\": \"messages\" }, \"tags\": { \"role_tag\": \"role\", \"content_tag\": \"content\", \"user_tag\": \"user\", \"assistant_tag\": \"assistant\" } }}
详细说明:
-
formatting: 数据格式
- 作用: 指定数据集格式为ShareGPT格式
- 为什么选择sharegpt: 标准的对话数据格式,支持多轮对话
-
columns: 列映射
- 作用: 指定数据中的消息列名
- 为什么这样设置: 与数据集的实际结构保持一致
-
tags: 标签配置
- 作用: 定义角色和内容的标签名称
- 为什么这样设置: 符合ChatML格式的标准定义
9.2 数据集样本格式
{ \"messages\": [ { \"content\": \"问题内容\", \"role\": \"user\" }, { \"content\": \"回答内容\", \"role\": \"assistant\" } ]}
详细说明:
-
messages: 消息列表
- 作用: 包含完整的对话轮次
- 为什么这样设计: 支持多轮对话,便于模型学习对话结构
-
role: 角色标识
- 作用: 区分用户和助手的消息
- 为什么使用user/assistant: 标准的对话角色定义
10. 启动脚本配置 (Launch Script Configuration)
10.1 环境配置
source ~/vllm/bin/activateexport CUDA_VISIBLE_DEVICES=0,1,2,3export PYTHONPATH=\"$PWD:$PYTHONPATH\"
详细说明:
-
虚拟环境: 激活指定的Python环境
- 作用: 确保使用正确的依赖包
- 为什么这样设置: 避免包冲突,确保环境一致性
-
CUDA_VISIBLE_DEVICES: 指定GPU设备
- 作用: 使用四张GPU进行训练
- 为什么选择0,1,2,3: 充分利用四卡资源,提高训练效率
-
PYTHONPATH: Python路径
- 作用: 添加当前目录到Python路径
- 为什么这样设置: 确保能够正确导入本地模块
10.2 启动命令
$HOME/vllm/bin/llamafactory-cli train train_config.yaml
详细说明:
-
llamafactory-cli: 使用LLaMA-Factory的命令行工具
- 作用: 启动训练任务
- 为什么选择这个工具: 专门为大模型微调设计,支持多种微调方法
-
train: 训练子命令
- 作用: 指定执行训练任务
-
train_config.yaml: 配置文件
- 作用: 指定训练的详细配置
- 为什么使用YAML: 配置文件格式清晰,易于阅读和修改
11. 配置优化建议
11.1 性能优化建议
-
显存优化:
- 使用ZeRO-3 + CPU卸载
- 启用梯度检查点
- 使用4位量化
- 适当减少batch size
-
训练效率优化:
- 使用Flash Attention
- 启用通信重叠
- 使用fast tokenizer
- 合理设置预处理工作进程数
-
收敛性优化:
- 使用余弦学习率调度
- 添加学习率预热
- 适当的dropout设置
- 合理的LoRA配置
11.2 实际使用建议
-
数据集大小调整:
- 实际训练时增加max_samples
- 根据数据集大小调整训练轮次
- 适当调整验证集比例
-
硬件配置调整:
- 根据实际GPU数量调整batch size
- 根据显存大小调整序列长度
- 根据CPU核心数调整并行工作进程
-
监控和调试:
- 使用GPU监控脚本实时监控资源使用
- 适当调整日志记录频率
- 定期检查训练损失和评估指标
12. 常见问题和解决方案
12.1 显存不足问题
- 问题: CUDA out of memory
- 解决方案:
- 减少per_device_train_batch_size
- 增加gradient_accumulation_steps
- 启用CPU卸载
- 使用更小的LoRA rank
12.2 训练速度慢问题
- 问题: 训练速度过慢
- 解决方案:
- 启用Flash Attention
- 增加预处理工作进程数
- 使用更快的存储设备
- 优化数据加载配置
12.3 收敛问题
- 问题: 损失不收敛或收敛慢
- 解决方案:
- 调整学习率
- 检查数据质量
- 调整LoRA配置
- 增加训练轮次
结论
本配置文件经过精心设计,针对四卡GPU环境下的Qwen3-14B模型微调进行了优化。通过合理的参数设置,实现了显存效率和训练效果的平衡。用户可以根据自己的硬件配置和训练需求,对相应的参数进行调整。
配置的核心思想是:
- 使用QLoRA技术减少显存占用
- 使用DeepSpeed ZeRO-3实现大模型训练
- 通过合理的超参数设置保证训练效果
- 使用多种优化技术提高训练效率
建议用户在使用前先进行小规模测试,确认配置的有效性,然后再进行大规模训练。


