LlamaFactory 工程指南:从 Makefile 命令到 v0/v1 双架构与训练参数解析全景
本文基于仓库中的开发者指南文档 .ai/CLAUDE.md 展开,系统梳理 LlamaFactory 的日常工程命令(风格检查、测试、构建)、由 USE_V1 环境变量控制的 v0/v1 双架构、llamafactory-cli 入口到 YAML 训练配置的完整调用链,以及新增模型支持与分布式训练的关键模块。读完后,你可以独立完成项目的本地开发、单测调试、代码风格合规检查,并能理解从一行 train 命令到多阶段训练器路由的全部底层机制。
一、文档定位:.ai/CLAUDE.md 是什么
.ai/CLAUDE.md 是一份面向 AI 编码助手(Claude Code)的仓库协作指南,其内容与根目录 CLAUDE.md 保持一致。它虽然篇幅不长,却浓缩了 LlamaFactory 仓库最核心的工程约定:
- Commands:
make快捷命令与 pytest 调用规范; - Architecture:v0/v1 两套并行架构的依赖方向与代码位置;
- Entry Points / Training Flow:CLI 入口与 v0 训练调用链;
- Configuration System:YAML/JSON 配置到四个类型化 dataclass 的解析机制;
- Key Modules:核心模块职责速查表;
- Adding a New Model / Distributed / Testing / Code Style:新增模型步骤、分布式后端、测试与代码风格规范。
把它当作一份"工程宪法"来读:任何对仓库的贡献(包括 AI 辅助生成)都应以其中的命令、架构与风格约定为准绳。
二、开发命令:Makefile 目标与 uv 优先策略
文档列出的全部命令如下,均与 Makefile 中的实际目标一一对应:
# Code style (auto-fix)
make style
# Code quality check (no modifications)
make quality
# Run all tests
make test
# Run a single test file
WANDB_DISABLED=true pytest -vv --import-mode=importlib tests/path/to/test_file.py
# Run tests matching a pattern
WANDB_DISABLED=true pytest -vv --import-mode=importlib tests/ -k "test_name"
# License header check
make license
# Build package
make build
对照 Makefile 的实现,可以看到几个值得注意的工程细节:
- uv 优先的运行时策略:Makefile 通过
RUN := $(shell command -v uv >/dev/null 2>&1 && echo "uv run" || echo "")(Makefile)动态探测uv是否存在。有uv时用uv run/uvx,无uv时回退到普通python -m build/ruff。这与文档"Commands automatically useuv run/uvxifuvis available"的描述一致,也解释了为什么贡献者不需要统一包管理器也能执行相同命令。 - 锁定的 Ruff 版本:
ruff_version := 0.15.5(Makefile)保证团队内 lint 行为一致;quality与style的区别在于后者会追加--fix并执行ruff format,即make quality只检查、make style自动修复。 - license 检查的目录范围:
check_dirs := scripts src tests tests_v1(Makefile),make license实际执行python3 tests/check_license.py(检查脚本),覆盖这四个目录,确保新文件包含 Apache 2.0 许可头。 - 测试范围:
make test等价于WANDB_DISABLED=true ... pytest -vv --import-mode=importlib tests/ tests_v1/(Makefile),同时跑 v0 与 v1 两套测试;单独运行测试文件时必须自行带上WANDB_DISABLED=true前缀,避免 wandb 在 CI/本地环境中产生干扰。
三、双架构:USE_V1 环境变量控制的 v0 与 v1
文档最重要的架构声明是:LlamaFactory 存在两套并行架构,由 USE_V1 环境变量切换:
- v0(默认):模块依赖方向为
api, webui > chat, eval, train > data, model > hparams > extras,代码位于src/llamafactory/主体; - v1(实验性,
USE_V1=1):依赖方向为trainers > core > accelerator, plugins, config > utils,代码位于 src/llamafactory/v1/。
文档明确指出"Most active development happens in v0",即 v1 是实验性重构分支,日常开发以 v0 为准。
从源码可以精确印证这一分叉点——src/llamafactory/cli.py 的 main() 只有十来行:
def main():
from .extras.misc import is_env_enabled
if is_env_enabled("USE_V1"):
from .v1 import launcher
else:
from . import launcher
launcher.launch()
即 USE_V1 为真时加载 src/llamafactory/v1/launcher.py,否则加载 v0 的 src/llamafactory/launcher.py,两套入口各自独立演化,互不干扰。v1 的目录结构也印证了文档描述的层级:trainers/(SFT/DPO/RM 训练器)、core/(数据引擎、模型引擎、基础训练器与渲染)、plugins/(数据、模型、采样器、训练器插件)、config/、accelerator/、utils/。
四、CLI 入口:llamafactory-cli 与子命令分派
pyproject.toml 中声明了两个完全等价的命令行入口:
[project.scripts]
llamafactory-cli = "llamafactory.cli:main"
lmf = "llamafactory.cli:main"
两者都指向 cli.py 的 main()。v0 的 launch()(src/llamafactory/launcher.py)按 sys.argv[1] 的子命令分派,文档列出的可用子命令为:train、chat、api、export、webchat、webui、env、version、help。对照源码的分派逻辑,各子命令去向如下:
| 子命令 | 分派目标 | 说明 |
|---|---|---|
train |
llamafactory/train/tuner.py::run_exp() |
训练主入口(多卡时先转 torchrun) |
api |
llamafactory/api/app.py::run_api() |
启动 OpenAI 风格 API 服务 |
chat |
llamafactory/chat/chat_model.py::run_chat() |
CLI 交互式对话 |
export |
llamafactory/train/tuner.py::export_model() |
合并 LoRA、量化、导出模型 |
webchat |
llamafactory/webui/interface.py::run_web_demo() |
Web 对话界面 |
webui |
llamafactory/webui/interface.py::run_web_ui() |
LlamaBoard 训练管理界面 |
env / version |
print_env() / 版本横幅 |
环境信息 / 版本信息 |
help |
打印 USAGE 帮助块 | 用法提示 |
五、v0 训练调用链:从 YAML 到六种训练阶段
文档给出的 v0 训练流程图:
run_exp() [tuner.py]
→ read_args() → parse YAML/JSON config
→ get_train_args() → produces typed argument dataclasses
→ routes to: run_sft / run_dpo / run_ppo / run_rm / run_pt / run_kto
→ optional: export_model()
这条调用链在 src/llamafactory/train/tuner.py 中可以得到逐行印证:
def run_exp(args=None, callbacks=None) -> None:
args = read_args(args) # ① 读取命令行 / YAML 配置
if "-h" in args or "--help" in args:
get_train_args(args) # 仅打印帮助
ray_args = get_ray_args(args) # ② Ray 分支判定
if ray_args.use_ray:
_ray_training_function(ray_args, config={"args": args, "callbacks": callbacks})
else:
_training_function(config={"args": args, "callbacks": callbacks}) # ③ 常规训练
三个环节的源码级细节:
read_args()(配置解析):定义于 src/llamafactory/hparams/parser.py。当第一个命令行参数以.yaml/.yml结尾时,用OmegaConf加载该文件,并允许后续 CLI 参数覆盖文件配置(OmegaConf.merge(dict_config, override_config))。因此llamafactory-cli train xxx.yaml learning_rate=5e-5这类"文件 + 行内覆盖"的写法是合法的。get_train_args()(类型化参数):将合并后的字典送入HfArgumentParser,产出训练参数 dataclass 元组(详见下节)。_training_function()(阶段路由):先挂载回调(LogCallback、ReporterCallback、可选的 SwanLab/早停/Profiler 回调,见 tuner.py),再按finetuning_args.stage路由到run_pt / run_sft / run_rm / run_ppo / run_dpo / run_kto(tuner.py);若启用了 HyperParallel、Megatron Bridge 或 mcore-adapter(MCA)后端,则在pt/sft(MCA 还包括dpo)阶段优先走对应的专用 runner(tuner.py)。
文档中的示例命令 llamafactory-cli train examples/train_lora/llama3_lora_sft.yaml 是写法模板;当前仓库 examples/train_lora/ 下实际可用的对应示例文件为 qwen3_lora_sft.yaml,可按同一方式执行:
llamafactory-cli train examples/train_lora/qwen3_lora_sft.yaml
export 子命令同样落在 tuner.py 的 export_model() 中,完成 tokenizer 修复、模型加载、LoRA 合并、dtype 转换、分片保存,最后还会写出 Ollama 用的 Modelfile(tuner.py)。
六、配置系统:YAML 到四个类型化 dataclass
文档声明"所有训练参数都是 YAML/JSON 配置文件",解析位于 src/llamafactory/hparams/parser.py,产出四个核心 dataclass:
ModelArguments—— 模型/分词器选择、量化;DataArguments—— 数据集、模板、预处理;FinetuningArguments—— LoRA rank/target、训练方法(sft/dpo/ppo/rm/pt/kto);TrainingArguments—— 继承自 HuggingFaceTrainingArguments。
从源码看,parser.py 实际上还定义了 GeneratingArguments(生成参数)与 RayArguments(Ray 集群参数),训练参数元组为(parser.py):
_TRAIN_ARGS = [
ModelArguments,
DataArguments,
TrainingArguments,
FinetuningArguments,
GeneratingArguments,
]
此外,parser.py 按运行模式维护了三套参数组合:常规训练(_TRAIN_ARGS)、启用 mcore-adapter 时以 McaTrainingArguments 替换标准训练参数(parser.py)、以及推理/导出与评测各自的参数组合(_INFER_ARGS、_EVAL_ARGS)。这种"同一套 dataclass、按场景组装"的设计,是 LlamaFactory 用一份 YAML 同时支撑训练、导出、推理、评测的基础。各参数类分别定义在 hparams/model_args.py、hparams/data_args.py、hparams/finetuning_args.py、hparams/training_args.py 与 hparams/generating_args.py 中,pyproject.toml 声明 requires-python = ">=3.11.0",与文档"Python 3.11+ syntax"的要求对应。
七、核心模块速查:职责边界一览
文档的 Key Modules 表给出了各模块职责,结合仓库文件结构整理如下(路径均相对仓库根目录):
| 模块 | 职责 |
|---|---|
| src/llamafactory/model/loader.py | 加载模型 + 分词器;应用量化、LoRA、补丁 |
| src/llamafactory/model/patcher.py | 模型专属的兼容性补丁 |
| src/llamafactory/data/template.py | 提示词模板;TEMPLATES 字典将模型家族映射到对应格式 |
| src/llamafactory/data/mm_plugin.py | 多模态(图像/视频/音频)数据处理 |
| src/llamafactory/data/processor/ | 分阶段数据处理器(supervised、pairwise、pretrain、feedback 等) |
| src/llamafactory/train/sft/ | SFT 训练器;dpo/kto/ppo/rm/pt 各阶段遵循相同目录结构 |
| src/llamafactory/chat/ | 推理引擎:hf_engine、vllm_engine、sglang_engine 等 |
| src/llamafactory/extras/constants.py | 跨项目使用的枚举与常量 |
几个值得留意的结构约定:train/ 下每个训练阶段(sft、dpo、kto、ppo、rm、pt,以及后端的 hyper_parallel、mca、megatron_bridge)都采用 workflow.py + trainer.py 的双文件模式——workflow.py 负责数据、模型装配,trainer.py 负责自定义损失/指标;data/processor/ 则按监督方式拆分(supervised.py、pairwise.py、pretrain.py、feedback.py、unsupervised.py),新增训练范式时按此模式扩展即可。
八、新增模型支持:三步接入流程
文档给出的标准流程,也是维护 100+ LLM/VLM 支持的落地方式:
- 添加提示词模板:在 src/llamafactory/data/template.py 的
TEMPLATES字典中注册新模型家族的对话格式; - 添加模型补丁:若该模型存在与 transformers 版本的兼容性问题(如权重命名、
lm_head结构差异),在 src/llamafactory/model/patcher.py 中补充针对性修复; - 添加多模态支持(如需要):在 src/llamafactory/data/mm_plugin.py 中实现该模型的图像/视频/音频 token 处理插件。
配套地,新模型的数据集声明应写入 data/dataset_info.json,多模态演示数据格式可参考 data/mllm_demo.json;模板与多模态插件的行为均有对应测试覆盖(tests/data/test_template.py、tests/data/test_mm_plugin.py),新增接入后跑通这两个测试文件是基本的自证手段。
九、分布式训练:torchrun 自动升级与三种扩展后端
文档声明"多卡自动使用 torchrun,另有 Ray / HyperParallel FSDP2 / Megatron-core 三种后端"。源码印证了"自动"的触发条件——src/llamafactory/launcher.py:
command = sys.argv.pop(1) if len(sys.argv) > 1 else "help"
if is_env_enabled("USE_MCA") or is_env_enabled("USE_MEGATRON_BRIDGE"): # force use torchrun
os.environ["FORCE_TORCHRUN"] = "1"
if command == "train" and (
is_env_enabled("FORCE_TORCHRUN") or (get_device_count() > 1 and not use_ray() and not use_kt())
):
# launch distributed training
也就是说,train 子命令在满足以下任一条件时会以 torchrun 子进程方式重启自身:显式设置了 FORCE_TORCHRUN、启用了 MCA/Megatron Bridge(强制)、或多卡且未使用 Ray/KTransformers。torchrun 的节点参数全部来自环境变量:NNODES、NODE_RANK、NPROC_PER_NODE、MASTER_ADDR、MASTER_PORT(默认取可用端口),并支持 RDZV_ID 等弹性启动参数(launcher.py)。
三种扩展后端在 tuner.py 中的落点:
- Ray:
use_ray时走_ray_training_function(),自动初始化 Ray、按集群资源创建 placement group、按节点 IP 排序分配 worker(tuner.py),示例配置见 examples/train_lora/qwen3_lora_sft_ray.yaml; - HyperParallel(FSDP2):
finetuning_args.use_hyper_parallel时路由到 src/llamafactory/train/hyper_parallel/,要求安装hyper_parallel包; - Megatron 系:
use_mca路由到 src/llamafactory/train/mca/(mcore-adapter,支持 pt/sft/dpo),use_megatron_bridge路由到 src/llamafactory/train/megatron_bridge/,对应示例分别为 examples/megatron/ 与 examples/megatron_bridge/llama3_sft.yaml。
十、测试体系:v0/v1 双目录与 pytest 约定
文档对测试的约定与仓库实际结构完全一致:
tests/—— v0 测试;tests_v1/—— v1 测试(与Makefile的make test同时执行两者对应);- 多数训练测试需要 GPU 硬件:例如 tests/model/ 下的
test_lora.py、test_full.py、test_freeze.py均依赖真实模型加载; - pytest 标记:
@pytest.mark.slow、@pytest.mark.runs_on(['cuda'])用于筛选设备/耗时测试; - 必须设置
WANDB_DISABLED=true:防止测试进程尝试连接 wandb。
单文件/按名称筛选的规范命令(与文档一致):
WANDB_DISABLED=true pytest -vv --import-mode=importlib tests/data/test_template.py
WANDB_DISABLED=true pytest -vv --import-mode=importlib tests/ -k "test_lora"
其中 --import-mode=importlib 是必需项——项目测试文件存在同名模块(如各 test_supervised.py),importlib 模式可避免包根路径冲突。端到端训练验证可参考 tests/e2e/test_train.py。
十一、代码风格:Ruff 规则与许可头要求
文档的四条风格约定在 pyproject.toml 中都能找到对应配置:
- Ruff 负责 lint 与格式化:
line-length = 119、target-version = "py311",pydocstyle 约定为google(对应文档"Google-style docstrings");选中的规则集为C/E/F/I/W/UP/D/PT009/RUF022,即复杂度、错误、pyflakes、isort、警告、pyupgrade、文档字符串、pytest assert 与__all__排序; - Python 3.11+ 语法:
target-version = "py311"且项目要求requires-python = ">=3.11.0"; - 字符串双引号:
[tool.ruff.format] quote-style = "double",make style会自动统一; - Apache 2.0 许可头:所有新文件必须包含许可头,由
make license(即 tests/check_license.py)对scripts src tests tests_v1四个目录强制检查。
完整的提交前检查顺序可以概括为:make style(自动修复)→ make quality(只检查,CI 语义)→ make license → make test → make build 验证打包。
十二、小结
.ai/CLAUDE.md 用不到一百行定义了 LlamaFactory 的工程契约:命令层面由 Makefile + uv 提供一致的 style/quality/test/license/build 入口;架构层面 v0(api, webui > chat, eval, train > data, model > hparams > extras)承担主开发线,v1(src/llamafactory/v1/)以 USE_V1 环境变量隔离演进;运行层面一切训练行为收敛于 llamafactory-cli train <config.yaml>,经 read_args() → get_train_args() → 阶段路由进入六种训练流程,并可无缝切换到 Ray、HyperParallel FSDP2 或 Megatron 后端。掌握这份指南,即可在 LlamaFactory 仓库中以与上游维护者一致的规范开展开发、测试与模型接入工作。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00