简介:本资源为开源大模型微调框架LLaMA-Factory的完整本地部署包,面向AI算法工程师、NLP方向研究者及大模型实践学习者,用于快速开展指令微调、LoRA适配、多卡分布式训练等主流微调任务。压缩包共408个文件,涵盖146个核心Python源码(含trainer、data、model等模块)、48个YAML/YML配置模板(支持Qwen、Llama3、Phi-3等20+模型)、23个JSON参数定义与14个典型数据集sample样本,辅以Dockerfile、.dockerignore、.gitattributes等工程化配置文件,结构完整、开箱即用。资源大小231.59MB,已获1727人学习下载,包含CITATION.cff学术引用规范、LICENSE协议文件、README级说明文档及多版本Docker构建脚本,便于科研复现、教学演示与生产环境迁移。
1. LLaMA-Factory 包在 GitHub 上下载:不是“点个 Download ZIP”就完事的实操闭环
你搜“LLaMA-Factory 下载”,首页跳出来的不是文档,而是满屏的git clone https://github.com/hiyouga/LLaMA-Factory——但真正跑起来的人,十有八九卡在第二步:clone 下来后,pip install -e .报错、llamafactory-cli找不到、CUDA 版本和 PyTorch 不匹配、甚至data/dataset_info.json根本不存在。这不是环境问题,是项目结构认知断层:LLaMA-Factory 不是一个“开箱即用”的二进制包,而是一套面向微调工程师的命令行工作流框架——它把数据准备、参数配置、训练启动、模型导出全封装成 YAML+CLI,但所有环节都依赖你亲手校准路径、显存、精度和 tokenizer 兼容性。适合两类人:一是想绕过 Hugging Face Trainer 底层胶水代码、专注调参策略的算法同学;二是需要批量微调多个 LoRA 适配器、做 AB 实验的 MLOps 工程师。如果你还在用transformers.Trainer写 200 行训练脚本,或者每次换数据集都要重写DataCollator,那这个包值得你花半天时间踩一遍坑——不是为了“装上”,而是为了掌握它背后那套可复现、可审计、可 pipeline 化的微调范式。
2. 从 GitHub 拉取到本地可运行:四步闭环,每步都带验证命令
LLaMA-Factory 的官方仓库(https://github.com/hiyouga/LLaMA-Factory)主分支稳定,但直接git clone后不能立即python src/train_bash.py——它依赖setup.py注册 CLI 命令、预编译flash_attn(可选)、以及正确解析examples/下的 YAML 配置。下面这四步,是我在线上集群和 MacBook M2 上反复验证过的最小可行路径,跳过任意一步都会在后续报出完全不相关的错误(比如ModuleNotFoundError: No module named 'llamafactory'看似是安装失败,实际是pip install -e .时pyproject.toml里的build-backend未触发)。
2.1 克隆指定 commit,避开 dev 分支的 API 波动
不要用git clone https://github.com/hiyouga/LLaMA-Factory默认拉 master(它常含未文档化的实验性功能)。截至 2024 年 7 月,生产环境最稳的 commit 是v0.9.0(tag),对应d6b5c3a。执行:
git clone --branch v0.9.0 --single-branch https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory为什么必须指定 tag?
master分支在 2024 年 6 月重构了src/llamafactory/hparams模块,将ModelArguments和DataArguments合并为FinetuningArguments,但examples/下的 YAML 示例未同步更新。用master直接跑examples/llama3_lora.yaml会报KeyError: 'model_name_or_path'——因为新代码要求字段名改为model_name,而旧 YAML 还是model_name_or_path。v0.9.0的结构与文档完全对齐,是当前最可靠的基线。
2.2 创建隔离环境并安装,关键在-e和--no-deps
LLaMA-Factory 依赖明确(见pyproject.toml),但若系统已装transformers>=4.40.0,pip install -e .会强制升级它,导致与peft或bitsandbytes冲突。安全做法:
# 创建干净环境(conda 或 venv 均可) python -m venv llamafactory-env source llamafactory-env/bin/activate # Linux/macOS # llamafactory-env\Scripts\activate.bat # Windows # 安装核心依赖(按 pyproject.toml 中的 pinned 版本) pip install torch==2.3.0+cu121 torchvision==0.18.0+cu121 --extra-index-url https://download.pytorch.org/whl/cu121 pip install transformers==4.41.2 datasets==2.19.1 peft==0.11.1 bitsandbytes==0.43.1 # 关键:用 --no-deps 避免 pip 覆盖已装依赖,-e 触发 setup.py 注册 llamafactory-cli pip install -e . --no-deps验证 CLI 是否注册成功:
llamafactory-cli --help # 应输出 usage: llamafactory-cli [-h] {train,eval,infer} ...若报command not found,说明-e未生效——常见原因是setup.py里entry_points未被 setuptools 正确解析。此时手动检查src/llamafactory/__init__.py是否存在,且setup.py中packages=find_packages("src")路径正确(v0.9.0中为"src",不是".")。
2.3 下载基础模型权重,路径必须与 YAML 中model_name_or_path一致
LLaMA-Factory 不托管模型权重,需你自行下载。以Qwen2-7B为例(比 Llama3 更易获取授权):
# 创建 models/ 目录(YAML 中默认路径) mkdir -p models/qwen2-7b # 从 Hugging Face Hub 下载(需提前 huggingface-cli login) huggingface-cli download Qwen/Qwen2-7B --local-dir models/qwen2-7b --revision main # 验证权重完整性 ls models/qwen2-7b | head -5 # 应看到 config.json, model.safetensors, tokenizer.model 等注意路径映射:
examples/qwen2_lora.yaml中model_name_or_path: "models/qwen2-7b"是相对路径,必须与你cd LLaMA-Factory后的当前目录结构一致。若你把模型放在/data/models/qwen2-7b,则 YAML 中要写绝对路径/data/models/qwen2-7b,或在运行时用--model_name_or_path /data/models/qwen2-7b覆盖。
2.4 运行最小训练任务,用--do_train+--stage sft验证端到端
不推荐首次就跑 full fine-tuning(显存爆炸),用 LoRA + SFT(监督微调)验证流程:
llamafactory-cli train \ --stage sft \ --model_name_or_path models/qwen2-7b \ --dataset alpaca_zh \ --template qwen2 \ --finetuning_type lora \ --lora_target q_proj,v_proj \ --output_dir saves/qwen2_lora \ --overwrite_output_dir \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps 4 \ --max_steps 10 \ --logging_steps 1 \ --save_steps 5 \ --learning_rate 1e-4 \ --fp16关键参数说明:
--stage sft:指定微调阶段(SFT/Pretraining/PPO),LLaMA-Factory 将自动加载对应的数据处理器和损失函数;--dataset alpaca_zh:从data/alpaca_zh.json加载数据(需提前准备好),该数据集格式必须符合data/dataset_info.json中定义的format字段(如"prompt": "### Instruction:\n{instruction}\n\n### Input:\n{input}\n\n### Response:\n{output}");--template qwen2:指定 tokenizer 的 chat template,决定<|im_start|>等特殊 token 如何拼接,错误会导致 loss 为 nan;--lora_target q_proj,v_proj:LoRA 作用的线性层,Qwen2 架构中q_proj和v_proj是最关键的梯度通道,比o_proj更敏感;--fp16:启用半精度,若 GPU 不支持(如 T4),改用--bf16(需 Ampere+ 架构)或--fp32(显存翻倍)。
运行后,终端应输出Step 1/10: loss=2.145,Step 5/10: loss=1.892,并在saves/qwen2_lora下生成checkpoint-5/目录。这是唯一有效的“安装成功”信号——比任何pip list | grep llamafactory都可靠。
3. 数据准备与 YAML 配置:两个文件决定 80% 的训练成败
LLaMA-Factory 的核心抽象是“数据集描述 + 训练参数分离”:data/dataset_info.json定义数据源结构,examples/*.yaml定义如何用这些数据。新手常把数据文件丢进data/就以为万事大吉,结果ValueError: dataset alpaca_zh not found——其实是因为dataset_info.json里没声明它,或字段名拼错。下面拆解这两个文件的硬性约束。
3.1data/dataset_info.json:JSON Schema 必须严格匹配
该文件是 LLaMA-Factory 的数据注册中心,不是示例,是契约。以alpaca_zh为例,其完整结构必须如下(注意逗号、引号、缩进):
{ "alpaca_zh": { "file_name": "alpaca_zh.json", "columns": { "prompt": "instruction", "query": "input", "response": "output", "history": null }, "format": "### Instruction:\n{prompt}\n\n### Input:\n{query}\n\n### Response:\n{response}", "system_format": "You are a helpful assistant.", "role_tag": { "user": "user", "assistant": "assistant" } } }字段解释与避坑点:
"file_name":必须与data/下实际文件名完全一致(包括大小写和扩展名),alpaca_zh.json≠alpaca_zh.JSON;"columns":映射 JSON 字段到模板变量。"prompt": "instruction"表示用instruction字段值填充{prompt};若你的数据字段叫instruct,这里必须写"prompt": "instruct",否则{prompt}渲染为空字符串;"format":必须包含所有{xxx}变量,且变量名与columns键一致。漏掉{query}会导致输入为空,loss 瞬间飙升;"system_format":若数据无 system 字段(如 Alpaca),此字段为 fallback,默认值;若设为null,则训练时无 system prompt;"role_tag":仅用于 ChatML 类模板(如 Qwen),定义用户/助手角色标识符,"user"对应<|im_start|>user,错误会导致 tokenizer 编码错位。
验证方法:修改dataset_info.json后,运行以下命令检查是否被识别:
llamafactory-cli train --stage sft --model_name_or_path models/qwen2-7b --dataset alpaca_zh --dry_run # --dry_run 不启动训练,只校验数据加载逻辑 # 输出应含 "Loading dataset: alpaca_zh" 和 "Loaded 1000 samples"3.2examples/*.yaml:参数分组逻辑与继承关系
YAML 文件不是扁平参数列表,而是按model,data,training,lora四个 section 分组,且支持!include继承。例如examples/qwen2_lora.yaml实际继承自examples/_base_.yaml:
# examples/qwen2_lora.yaml #include: _base_.yaml # ← 注意是 include,不是 extends model_name_or_path: models/qwen2-7b template: qwen2 dataset: alpaca_zh lora_target: "q_proj,v_proj" lora_rank: 64 lora_alpha: 16 lora_dropout: 0.1关键继承规则:
_base_.yaml定义通用参数(per_device_train_batch_size: 2,learning_rate: 1e-4),子 YAML 只覆盖差异项;- 若子 YAML 中
lora_target为空,则继承_base_的值;若写lora_target: null,则 LoRA 被禁用(等价于 full fine-tuning); --do_train时,LLaMA-Factory 会合并所有层级参数,最终生成TrainingArguments对象。可通过--debug查看合并后的完整参数字典。
必调参数表(针对 24G 显存 A10):
| 参数 | 推荐值 | 为什么调它 |
|---|---|---|
per_device_train_batch_size | 2 | A10 单卡 24G,qwen2-7b+ LoRA +fp16下,bs=4易 OOM;bs=2保底可用 |
gradient_accumulation_steps | 4 | 补偿小 batch,等效 global batch size =2 * 4 * num_gpus |
max_steps | 100 | 初次训练建议 ≤200 步,避免过拟合;用--save_steps 50保存中间 checkpoint |
lora_rank | 64 | Rank 越高,LoRA 矩阵越大,显存占用越接近 full;r=64在效果和显存间平衡 |
lora_alpha | 16 | alpha/ratio控制 LoRA 更新强度,alpha=16对应 ratio=0.25(16/64),是 Qwen2 的经验值 |
提示:不要盲目复制网上 YAML
很多博客贴的llama3_lora.yaml用lora_target: "q_proj,k_proj,v_proj,o_proj",但在 LLaMA-3 架构中k_proj梯度极小,加入反而降低收敛速度。Qwen2 推荐q_proj,v_proj,Llama3 推荐q_proj,v_proj,k_proj——目标模型架构决定 LoRA target,不是统一模板。
4. 常见问题排查:五条血泪经验,每条都对应一个真实翻车现场
LLaMA-Factory 的报错信息往往藏在底层库(如transformers或peft)里,表面看是KeyError,实际是 YAML 配置或路径问题。以下是我在 3 个不同客户环境(A10/A800/H100)中高频遇到的 5 类问题,按现象→原因→解决三步给出可执行方案。
4.1 现象:ModuleNotFoundError: No module named 'llamafactory',即使pip install -e .成功
原因:Python 解释器未加载src/作为 package root。setup.py中package_dir={"": "src"}未生效,或PYTHONPATH未包含LLaMA-Factory/src。
解决:
- 检查
LLaMA-Factory/src/llamafactory/__init__.py是否存在(空文件即可); - 运行
python -c "import sys; print(sys.path)",确认输出包含.../LLaMA-Factory/src; - 若没有,临时添加:
export PYTHONPATH=$PWD/src:$PYTHONPATH(Linux/macOS); - 根治法:删掉
src/目录外的llamafactory/文件夹(有人误把src/llamafactory复制到项目根目录),确保src/是唯一 source tree。
4.2 现象:ValueError: Expected all tensors to be on the same device,GPU 显存未满但报错
原因:bitsandbytes的Linear4bit层未被device_map="auto"正确分配,部分参数留在 CPU。常见于--quantization_bit 4与--fp16同时启用时,精度冲突。
解决:
- 方案一(推荐):关闭
--fp16,改用--bf16(需 A100/H100)或--fp32; - 方案二:显式指定
--device_map cuda:0,而非auto; - 方案三:在
train_bash.py开头加torch.set_default_device("cuda")(不推荐,破坏框架封装)。
4.3 现象:训练 loss 为nan或inf,且grad_norm突然飙升到1e8
原因:tokenizer 的 chat template 与模型架构不匹配。例如用llama3模板加载qwen2模型,<|start_header_id|>会被 tokenizer 当作未知 token,编码为1(unk id),导致 embedding lookup 返回全零向量,后续计算溢出。
解决:
- 查
examples/下 YAML 的template字段,对照src/llamafactory/chat_templates.py中的定义; - 运行
python src/llamafactory/chat_templates.py --template qwen2 --model_name_or_path models/qwen2-7b,输出应含User: ... Assistant: ...格式; - 若输出乱码,说明
tokenizer.chat_template未正确加载,需手动在models/qwen2-7b/tokenizer_config.json中添加"chat_template": "{% for message in messages %}..."。
4.4 现象:OSError: Can't load tokenizer for 'models/qwen2-7b',但config.json和tokenizer.model都存在
原因:tokenizer.model是 sentencepiece 模型,但 Qwen2 实际使用tokenizer.json(Hugging Face 格式)。models/qwen2-7b/下缺少tokenizer.json,或tokenizer_config.json中tokenizer_class错写为"LlamaTokenizer"(应为"Qwen2Tokenizer")。
解决:
- 从 HF Hub 重新下载:
huggingface-cli download Qwen/Qwen2-7B --local-dir models/qwen2-7b --include "tokenizer.*"; - 检查
models/qwen2-7b/tokenizer_config.json,确认"tokenizer_class": "Qwen2Tokenizer"; - 若仍失败,在
train_bash.py中强制指定:--tokenizer_name_or_path models/qwen2-7b。
4.5 现象:RuntimeError: expected scalar type Half but found Float,发生在forward()
原因:--fp16启用,但某些算子(如torch.nn.functional.cross_entropy)不支持 half input。LLaMA-Factory 默认用label_smoothing=0.1,该参数触发了不兼容路径。
解决:
- 在 YAML 中显式关闭:
label_smoothing: 0.0; - 或升级 PyTorch 至
2.3.0+(已修复此问题); - 临时方案:改用
--bf16,BFloat16 对 cross_entropy 兼容性更好。
5. 模型导出与推理部署:从saves/到gradio的三步落地
训练完成只是开始,LLaMA-Factory 的价值在于让微调模型快速进入业务流。saves/qwen2_lora/checkpoint-100/下的文件不是最终产物——它需要 merge LoRA 权重、转换格式、再封装成 API。下面是以gradio为例的最小部署链路,全程无需 touchtransformers底层代码。
5.1 合并 LoRA 权重到基础模型,生成标准 HF 格式
LLaMA-Factory 提供merge_lora工具,将 adapter 权重注入 base model:
llamafactory-cli export \ --model_name_or_path models/qwen2-7b \ --adapter_name_or_path saves/qwen2_lora/checkpoint-100 \ --export_dir saves/qwen2_lora_merged \ --export_size 2 \ --export_device cpu参数说明:
--adapter_name_or_path:指向checkpoint-100/(含adapter_model.bin和adapter_config.json);--export_size 2:按 2GB 分片保存,避免单文件过大(HF Hub 上传限制);--export_device cpu:CPU 合并更稳,GPU 合并可能 OOM;- 输出目录
saves/qwen2_lora_merged/结构与标准 HF model 完全一致:config.json,pytorch_model.bin,tokenizer.*。
验证合并结果:
python -c " from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained('saves/qwen2_lora_merged', device_map='auto') tokenizer = AutoTokenizer.from_pretrained('saves/qwen2_lora_merged') inputs = tokenizer('你好', return_tensors='pt').to(model.device) print(tokenizer.decode(model.generate(**inputs, max_new_tokens=20)[0])) " # 应输出连贯中文回复,而非乱码或截断5.2 封装为 Gradio Web UI,一行命令启动
LLaMA-Factory 自带webui.py,但需先安装gradio并配置web_demo.yaml:
pip install gradio==4.35.0 # 修改 web_demo.yaml,指定 merged model 路径 sed -i 's|model_name_or_path: .*|model_name_or_path: saves\/qwen2_lora_merged|' examples/web_demo.yaml sed -i 's|template: .*|template: qwen2|' examples/web_demo.yaml启动服务:
llamafactory-cli webui --config_path examples/web_demo.yaml # 输出 "Running on local URL: http://127.0.0.1:7860"关键配置项(web_demo.yaml):
template: qwen2:确保聊天框渲染符合 Qwen2 的<|im_start|>协议;temperature: 0.7:控制生成随机性,0.1过于确定,1.2过于发散;max_new_tokens: 512:防止长文本阻塞,可根据业务调整;system_prompt: "你是一个金融客服助手":覆盖dataset_info.json中的 default system。
注意:Gradio 默认开启 queue,高并发时请求排队
生产环境需加--share(生成公网链接)或--server_name 0.0.0.0(绑定内网 IP),并用 nginx 反向代理。
5.3 导出为 GGUF 量化格式,适配 CPU/边缘设备
若需在 CPU 或树莓派运行,用llamafactory-cli export转 GGUF:
llamafactory-cli export \ --model_name_or_path saves/qwen2_lora_merged \ --export_dir saves/qwen2_lora_q4_k_m.gguf \ --export_quantization_bit 4 \ --export_device cpu量化参数选择(基于 Qwen2-7B 测试):
| 量化类型 | 文件大小 | CPU 推理速度(tok/s) | 问答质量 |
|---|---|---|---|
q4_k_m | 3.8 GB | 12.3 | ★★★★☆(细节保留好) |
q5_k_m | 4.6 GB | 9.1 | ★★★★★(最佳平衡) |
q8_0 | 7.2 GB | 5.7 | ★★★★★(几乎无损) |
用llama.cpp加载:
./main -m saves/qwen2_lora_q4_k_m.gguf -p "你好,请介绍下Qwen2模型" -n 256最后一句经验:我习惯在每次llamafactory-cli train前,先git stash当前 YAML 修改,再git checkout v0.9.0确保 baseline 一致——因为 LLaMA-Factory 的 YAML 解析器对空格和缩进极其敏感,一个 tab 混入空格就会让lora_target变成None。这种“玄学”问题没法 debug,只能靠版本锁死。希望帮到你。
本文还有配套的精品资源,点击获取