Chapter 03
快速上手:Llama-3 8B QLoRA
Axolotl 的哲学是"一切都在 YAML 里"。本章用 30 行 YAML 训出一个 Llama-3 8B QLoRA。
3.1最小 YAML
# my_qlora.yml
base_model: meta-llama/Meta-Llama-3-8B
load_in_4bit: true
adapter: qlora
lora_r: 16
lora_alpha: 32
lora_dropout: 0.05
lora_target_modules:
- q_proj
- k_proj
- v_proj
- o_proj
- gate_proj
- up_proj
- down_proj
datasets:
- path: tatsu-lab/alpaca
type: alpaca
dataset_prepared_path: ./prepared
val_set_size: 0.02
sequence_len: 2048
sample_packing: true
micro_batch_size: 2
gradient_accumulation_steps: 8
num_epochs: 2
learning_rate: 2e-4
optimizer: adamw_bnb_8bit
lr_scheduler: cosine
warmup_ratio: 0.03
bf16: auto
flash_attention: true
gradient_checkpointing: true
output_dir: ./out
logging_steps: 10
save_steps: 200
save_total_limit: 3
3.2三个命令
# 1) 预处理数据(可选,train 也会自动跑)
axolotl preprocess my_qlora.yml
# 2) 训练
axolotl train my_qlora.yml
# 3) 推理验证
axolotl inference my_qlora.yml --lora_model_dir ./out
3.3YAML 字段速读
| 字段 | 含义 |
|---|---|
base_model | HF 模型 ID 或本地路径 |
load_in_4bit / load_in_8bit | 开 4bit / 8bit 量化加载 |
adapter | lora / qlora / "" 全参 |
lora_target_modules | 替换哪些 Linear |
datasets | list[dict],每个有 path + type |
val_set_size | 从 train 切出 valid 比例 |
sequence_len | 截断 |
sample_packing | 多样本打包 |
micro_batch_size / gradient_accumulation_steps | 有效 batch = 两者乘积 × GPU 数 |
optimizer | adamw_torch / adamw_bnb_8bit / paged_adamw_8bit / ... |
flash_attention | true 开 flash-attn-2 |
3.4多卡
accelerate launch -m axolotl.cli.train my_qlora.yml
# 或
axolotl train my_qlora.yml --num-processes 8
多机加 accelerate config 时配置 NCCL / IB / master 地址。
3.5训练过程中看什么
tail -f ./out/training.log
# wandb 集成
wandb_project: my-axolotl-run
wandb_name: llama3-qlora-v1
观察:
- train_loss:典型 SFT 从 2.5 → 0.8;
- eval_loss:跟着降不发散;
- tokens/s/GPU:A100 80G 上 ~4-6k。
3.6常见踩坑
| 现象 | 处理 |
|---|---|
| "Datasets must have 'type'" | 每个 dataset dict 必须有 type 字段 |
| OOM | 开 gradient_checkpointing;降 micro_batch_size |
| 训 1 epoch 后 NaN | lr 太大;QLoRA 用 2e-4 偏上限 |
| tokenizer 报 chat_template missing | 显式 chat_template: llama3 |
3.7入口背后:axolotl train 调用栈
"一行命令"背后真实路径(来源 src/axolotl/cli/main.py + src/axolotl/train.py):
| 步 | 位置 | 做什么 |
|---|---|---|
| 1 | cli/main.py:41 cli() | Click @group dispatcher;初始化 env / dotenv / CUDA alloc |
| 2 | cli/main.py:98–137 train() | 多卡时自动 accelerate launch / torchrun 重新拉子进程 |
| 3 | src/axolotl/train.py | 子进程入口;YAML → AxolotlInputConfig(Pydantic 校验) |
| 4 | train.py:54–100 setup_model_and_tokenizer() | 加 model / tokenizer / processor / PEFT config |
| 5 | loaders/model.py:72 ModelLoader | pre-config patches → 量化 → 注意力实现 → load → post-model patches |
| 6 | utils/data/wrappers.py:119 | 按 dataset.type 通过 prompt_strategies.load() 选 strategy |
| 7 | core/builders/causal.py:53 或 rl.py:24 | 按 rl 字段选 HFCausalTrainerBuilder 或 HFRLTrainerBuilder |
| 8 | builder.build() | 构造 AxolotlTrainer(8 mixin)或 AxolotlDPOTrainer / AxolotlGRPOTrainer... |
| 9 | trainer.train() | 调到 HF Trainer.train(),forward / loss 被 mixin patch |
3.8Builder pattern:两条路
看 core/builders/,Axolotl 不是只有一个 Trainer。两条 builder:
| Builder | 位置 | 触发条件 |
|---|---|---|
HFCausalTrainerBuilder | causal.py:53 | YAML 不写 rl(标准 SFT / pretrain) |
HFRLTrainerBuilder | rl.py:24 | YAML 写 rl: dpo/kto/orpo/grpo/simpo/ipo/ebft |
父类 TrainerBuilderBase(base.py:56–76)三件事:(cfg, model, tokenizer, processor=None) 注入、模型 tag、RNG 初始化、trainer patch 管理。
3.9这章你需要带走的
- Axolotl 的核心是一份 YAML +
axolotl train; - 必填字段:base_model / datasets / adapter / sequence_len;
- 多卡用 accelerate launch;
- 训完用
axolotl inference直接验证。