Chapter 10

实战:训一个 Hermes 风格对话模型

📌 commit ab1a0d8NousResearch Hermes 配方复刻

NousResearch Hermes 系列是英文社区最受欢迎的对话模型之一,base 用 Llama-3 / Qwen2.5,数据用 Hermes 自家清洗的 SFT mix。本章复现一个简化版。

10.1Hermes 配方关键点

  1. base:Llama-3.1-8B / Qwen2.5-7B;
  2. chat 格式:ChatML(<|im_start|>...<|im_end|>);
  3. 数据:Hermes 系自家 1M+ 条 SFT,覆盖通用 / 推理 / function call / 角色扮演;
  4. 训练:全参微调 3 epoch;
  5. 对齐:可选 + DPO(用 Hermes preference data)。

10.2SFT 阶段 YAML

# hermes_sft.yml
base_model: meta-llama/Meta-Llama-3.1-8B
tokenizer_type: AutoTokenizer
chat_template: chatml                       # ★ Hermes 用 ChatML

datasets:
  - path: teknium/OpenHermes-2.5            # Hermes 公开数据
    type: chat_template
    chat_template: chatml
    field_messages: conversations
    message_field_role: from
    message_field_content: value
    roles:
      user: [human, user]
      assistant: [gpt, assistant]
      system: [system]

dataset_prepared_path: ./prepared_hermes
val_set_size: 0.005

sequence_len: 8192
sample_packing: true
pad_to_sequence_len: true

adapter: lora                                # 显存够可改 ""(全参)
lora_r: 64
lora_alpha: 128
lora_target_modules:
  - q_proj
  - k_proj
  - v_proj
  - o_proj
  - gate_proj
  - up_proj
  - down_proj
lora_modules_to_save:                        # ChatML 加了新 special token,必须训
  - embed_tokens
  - lm_head

micro_batch_size: 2
gradient_accumulation_steps: 8
num_epochs: 3
learning_rate: 1e-4
optimizer: adamw_torch_fused
lr_scheduler: cosine
warmup_ratio: 0.03
weight_decay: 0.0
max_grad_norm: 1.0

bf16: auto
tf32: true
flash_attention: true
gradient_checkpointing: true
deepspeed: deepspeed_configs/zero2.json

output_dir: ./out_hermes_sft
logging_steps: 10
save_steps: 500
save_total_limit: 3
evaluation_strategy: steps
eval_steps: 500

wandb_project: hermes-clone
wandb_name: llama3.1-8b-sft

10.3启动 SFT(8 卡)

accelerate launch -m axolotl.cli.train hermes_sft.yml --num-processes 8

时间预算:OpenHermes-2.5 约 1M 样本,8×A100-80GB、3 epoch ≈ 36-48 小时。

10.4DPO 阶段(可选)

# hermes_dpo.yml
base_model: ./out_hermes_sft                 # 用 SFT 结果起步
rl: dpo
rl_beta: 0.1

datasets:
  - path: argilla/distilabel-capybara-dpo-7k-binarized
    type: chatml.argilla                      # 数据格式跟 base 一致
    split: train

sequence_len: 4096
adapter: lora
lora_r: 32
lora_target_modules: [q_proj,k_proj,v_proj,o_proj]

micro_batch_size: 1
gradient_accumulation_steps: 8
num_epochs: 1
learning_rate: 5e-7
optimizer: adamw_torch
lr_scheduler: cosine
warmup_ratio: 0.03

bf16: auto
flash_attention: true
gradient_checkpointing: true
deepspeed: deepspeed_configs/zero2.json

output_dir: ./out_hermes_dpo

时间预算:~8 小时 8×A100。

10.5合并 + 评估

# 合并 LoRA
axolotl merge-lora hermes_dpo.yml --lora_model_dir ./out_hermes_dpo

# 用 lm-eval-harness 评估
lm_eval --model hf \
        --model_args pretrained=./out_hermes_dpo/merged \
        --tasks mmlu,arc_easy,hellaswag,truthfulqa \
        --batch_size 8

10.6推理 / 部署

# 单机测试
axolotl inference hermes_dpo.yml --lora_model_dir ./out_hermes_dpo

# 生产用 vLLM
vllm serve ./out_hermes_dpo/merged --port 8000

10.7成本

阶段耗时云成本 ($20/h 8 卡)
SFT 3 epoch(OpenHermes-2.5)~40 h~$800
DPO 1 epoch(7k pairs)~8 h~$160
合并 + 评估~3 h~$60
~51 h~$1,020

10.8性能加速三件套:multipack / Liger / cut_cross_entropy

Hermes 流水训得快的关键不是硬件,是这三个开关组合:

特性YAML 字段原理 / 收益
Sample Packing (multipack) sample_packing: true + pad_to_sequence_len: true 多条短样本拼到 seq_len,省 padding 浪费;典型 +30-50% 训练速度
Liger Kernels plugins: [axolotl.integrations.liger.LigerPlugin] Triton fused RMSNorm / RoPE / SwiGLU / 交叉熵;峰值显存 -60% + 速度 +20%
Cut Cross Entropy plugins: [axolotl.integrations.cut_cross_entropy.CutCrossEntropyPlugin]分块计算 lm_head logits + CE,避免 batch × seq × vocab 张量;省 70% 峰值显存
三连组合 都开 实测 Llama-3-8B SFT 提速 2-3×,OOM 边界往后挪一档

10.9sample_packing 的两条实现路径

sample_packing 时 Axolotl 内部会按"是否开 flash_attn"挑路径(来源 monkeypatch/multipack/):

配置实际走的实现
sample_packing + flash_attention Flash-attn 自带的 cu_seqlens(最快,无 mask 开销)
sample_packing + 不开 flash_attention用 4D block-diag attention mask;速度慢一档,但任何 attention backend 都能跑
neat_packing(旧名) v2025 之前的名字;现在统一叫 sample_packing

"为什么我开了 sample_packing 没看到提速?"答:没配 flash-attn,packing 的 mask 开销吃掉了打包的收益。

10.10新优化器:Muon / Adam-mini / BAdam

2025-Q4 之后 Axolotl 跟进了一波新优化器。来源 schemas/enums.py CustomOptimizers

optimizer 值含义
adamw_torch(默认) HF 标准
adamw_bnb_8bit BNB 8-bit Adam(QLoRA 必配)
paged_adamw_8bit QLoRA paged 优化器
adamw_torch_fused PyTorch 2.x fused 算子
muon 2025-04 引入,Newton-Schulz 风格二阶,2D 权重适用
distributed_muon FSDP2 友好版 Muon(2025-12 加入)
adam_mini 2024-Q4 论文;省一半优化器状态
badam 块坐标 Adam,省更多
galore_adamw / apollo_adamw低秩梯度优化

"长训练省显存"首选 Muon;"小模型快收敛"留 adamw_bnb_8bit。

10.11这章你需要带走的