ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

LLaMA-Factory 微调实战:从环境配置到模型部署闭环指南

LLaMA-Factory 微调实战:从环境配置到模型部署闭环指南 简介本资源为开源大模型微调框架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 不是一个“开箱即用”的二进制包而是一套面向微调工程师的命令行工作流框架——它把数据准备、参数配置、训练启动、模型导出全封装成 YAMLCLI但所有环节都依赖你亲手校准路径、显存、精度和 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.0tag对应d6b5c3a。执行git clone --branch v0.9.0 --single-branch https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory为什么必须指定 tagmaster分支在 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-depsLLaMA-Factory 依赖明确见pyproject.toml但若系统已装transformers4.40.0pip 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 torch2.3.0cu121 torchvision0.18.0cu121 --extra-index-url https://download.pytorch.org/whl/cu121 pip install transformers4.41.2 datasets2.19.1 peft0.11.1 bitsandbytes0.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中packagesfind_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/PPOLLaMA-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_projLoRA 作用的线性层Qwen2 架构中q_proj和v_proj是最关键的梯度通道比o_proj更敏感--fp16启用半精度若 GPU 不支持如 T4改用--bf16需 Ampere 架构或--fp32显存翻倍。运行后终端应输出Step 1/10: loss2.145,Step 5/10: loss1.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.jsonJSON 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.JSONcolumns映射 JSON 字段到模板变量。prompt: instruction表示用instruction字段值填充{prompt}若你的数据字段叫instruct这里必须写prompt: instruct否则{prompt}渲染为空字符串format必须包含所有{xxx}变量且变量名与columns键一致。漏掉{query}会导致输入为空loss 瞬间飙升system_format若数据无 system 字段如 Alpaca此字段为 fallback默认值若设为null则训练时无 system promptrole_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 samples3.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_size2A10 单卡 24Gqwen2-7b LoRA fp16下bs4易 OOMbs2保底可用gradient_accumulation_steps4补偿小 batch等效 global batch size 2 * 4 * num_gpusmax_steps100初次训练建议 ≤200 步避免过拟合用--save_steps 50保存中间 checkpointlora_rank64Rank 越高LoRA 矩阵越大显存占用越接近 fullr64在效果和显存间平衡lora_alpha16alpha/ratio控制 LoRA 更新强度alpha16对应 ratio0.2516/64是 Qwen2 的经验值提示不要盲目复制网上 YAML很多博客贴的llama3_lora.yaml用lora_target: q_proj,k_proj,v_proj,o_proj但在 LLaMA-3 架构中k_proj梯度极小加入反而降低收敛速度。Qwen2 推荐q_proj,v_projLlama3 推荐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:$PYTHONPATHLinux/macOS根治法删掉src/目录外的llamafactory/文件夹有人误把src/llamafactory复制到项目根目录确保src/是唯一 source tree。4.2 现象ValueError: Expected all tensors to be on the same deviceGPU 显存未满但报错原因bitsandbytes的Linear4bit层未被device_mapauto正确分配部分参数留在 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编码为1unk 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: Cant load tokenizer for models/qwen2-7b但config.json和tokenizer.model都存在原因tokenizer.model是 sentencepiece 模型但 Qwen2 实际使用tokenizer.jsonHugging 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_smoothing0.1该参数触发了不兼容路径。解决在 YAML 中显式关闭label_smoothing: 0.0或升级 PyTorch 至2.3.0已修复此问题临时方案改用--bf16BFloat16 对 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 modelllamafactory-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 cpuCPU 合并更稳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_mapauto) tokenizer AutoTokenizer.from_pretrained(saves/qwen2_lora_merged) inputs tokenizer(你好, return_tensorspt).to(model.device) print(tokenizer.decode(model.generate(**inputs, max_new_tokens20)[0])) # 应输出连贯中文回复而非乱码或截断5.2 封装为 Gradio Web UI一行命令启动LLaMA-Factory 自带webui.py但需先安装gradio并配置web_demo.yamlpip install gradio4.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.yamltemplate: 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转 GGUFllamafactory-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_m3.8 GB12.3★★★★☆细节保留好q5_k_m4.6 GB9.1★★★★★最佳平衡q8_07.2 GB5.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只能靠版本锁死。希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进