llama-factory代码详解(一)--model_args.py
🎯 总目标
这段代码定义了一个叫 BaseModelArguments
的“数据容器”,专门用来收集训练或使用一个大模型(比如 LLM)时需要的各种配置参数。
你可以把它想象成一个“模型配置表单”,比如你要加载一个模型、设置它的行为、选择加速方式等,这些选项都通过这个类来统一管理。
一、核心概念:@dataclass
是什么?
✅ 一句话解释:
@dataclass
是 Python 的一个“懒人神器”,你只要告诉它有哪些字段(比如姓名、年龄),它就会自动帮你生成构造函数、打印方法等常用功能,不用你手写一堆代码。
比如:
@dataclass
class Person:name: strage: int
你就已经可以用了:
p = Person(name="小明", age=18)
print(p) # 输出:Person(name='小明', age=18)
Python 自动给你生成了 __init__
和 __repr__
方法!
二、字段详解:每个参数是干什么的?
现在我们来看这个 BaseModelArguments
类里的每一个字段,它们都是“模型相关的设置项”。
我们把它们分成几类来理解:
📦 1. 模型和适配器相关(从哪里加载模型)
字段名 | 含义 |
---|---|
model_name_or_path | 必填项! 你要用的主模型是哪个?可以是一个本地路径,也可以是 Hugging Face 或 ModelScope 上的模型名字,比如 "bert-base-uncased" 或 "Qwen/Qwen-7B" 。 |
adapter_name_or_path | 如果你用了 LoRA 微调技术,这里填适配器(adapter)的路径或名字。 支持多个,用逗号分隔,比如 "lora1,lora2" 。 |
adapter_folder | 存放多个 adapter 权重的文件夹路径。 |
cache_dir | 下载下来的模型文件存在哪个目录?避免每次重复下载。 |
📌 举个例子:
args = BaseModelArguments(model_name_or_path="Qwen/Qwen-7B",cache_dir="./models"
)
这表示:“我要用 Qwen-7B 模型,下载的文件存在 ./models 文件夹里。”
🧰 2. 分词器相关(文本怎么切分)
字段名 | 含义 |
---|---|
use_fast_tokenizer | 是否使用“快速分词器”?一般推荐 True ,更快更高效。 |
resize_vocab | 是否允许修改词汇表大小?比如你要加新的词进去。 |
split_special_tokens | 特殊标记(如 [CLS] , `< |
new_special_tokens | 你想添加哪些新的特殊词?比如 `< |
📌 举例:
new_special_tokens=" <|user|>,<|bot|> "
经过处理后会变成列表:['<|user|>', '<|bot|>']
(看后面的 __post_init__
)
🔁 3. 模型版本与加载优化
字段名 | 含义 |
---|---|
model_revision | 模型的哪个版本?比如 "main" (主干)、"v1.0" 或某个 commit ID。 |
low_cpu_mem_usage | 加载模型时是否节省内存?设为 True 可防止爆内存,尤其适合大模型。 |
trust_remote_code | 是否信任远程代码?有些模型需要自定义代码才能运行,打开这个才能加载。⚠️ 安全风险需注意! |
⚡ 4. 高性能训练/推理优化(加速技巧)
这些是让模型跑得更快、更省资源的技术选项。
字段名 | 含义 |
---|---|
rope_scaling | RoPE(旋转位置编码)的扩展方式,用于支持更长上下文(比如 32K 长文本)。 |
flash_attn | 是否启用 FlashAttention?一种大幅提升注意力计算速度的技术。默认 AUTO 表示自动判断。 |
shift_attn | 是否启用 S²-Attn(Shift Short Attention),LongLoRA 提出的技术,节省显存。 |
enable_liger_kernel | 是否启用 Liger Kernel,进一步优化训练速度。 |
use_unsloth | 是否使用 Unsloth 库优化 LoRA 微调,速度更快。 |
use_unsloth_gc | 是否使用 Unsloth 的梯度检查点技术(节省显存)。 |
upcast_layernorm / upcast_lmhead_output | 把某些层的计算提升到 float32,防止精度丢失,但会慢一点。 |
💡 这些都是“黑科技”,打开它们可以让模型训练或推理快很多!
🌀 5. 显存与训练控制
字段名 | 含义 |
---|---|
disable_gradient_checkpointing | 是否关闭梯度检查点?关闭后训练快但更吃显存。 |
use_reentrant_gc | 梯度检查点是否使用“可重入”模式?影响显存和稳定性。 |
📌 梯度检查点(Gradient Checkpointing)是一种“用时间换空间”的技术:减少显存占用,但训练稍慢。
🧠 6. 高级模型结构支持
字段名 | 含义 |
---|---|
mixture_of_depths | 是否使用 MoD(Mixture of Depths)?一种让模型动态跳过某些层的技术,加快推理。 |
moe_aux_loss_coef | 如果是 MoE(Mixture of Experts)模型,辅助损失的系数,用于平衡专家负载。 |
🧪 7. 推理与调试设置
字段名 | 含义 |
---|---|
infer_backend | 推理时用哪个后端?比如 HF(Hugging Face)、vLLM 等。 |
offload_folder | 当显存不够时,把部分权重“卸载”到硬盘的目录。 |
use_cache | 推理时是否缓存 Key-Value(KV Cache)?开启后生成文本更快。 |
infer_dtype | 推理时使用什么数据类型?float16 快但精度低,bfloat16 更稳,auto 自动选择。 |
print_param_status | 调试用:打印模型参数的状态(比如哪些被冻结、哪些可训练),方便查错。 |
🔐 8. 登录认证相关
字段名 | 含义 |
---|---|
hf_hub_token | 登录 Hugging Face 的 token,用于下载私有模型。 |
ms_hub_token | 登录 ModelScope(魔搭)的 token。 |
om_hub_token | 登录 OpenModel(或其他平台)的 token。 |
三、field()
是干嘛的?
你看到每个字段后面都有个 field(...)
,这是 dataclass
提供的工具,用来给字段加“额外信息”。
default=None,
metadata={"help": "这里是说明文字"}
default
: 默认值。如果不传这个参数,就用这个值。metadata
: 元数据,主要是给人看的帮助文档,比如你在命令行工具中看到的提示语就来自这里。
📌 举例:
model_name_or_path: Optional[str] = field(default=None,metadata={"help": "Path to the model..."}
)
意思就是:
“这个字段叫
model_name_or_path
,类型是字符串或空,默认是空,它的作用是:输入模型路径或名字。”
四、__post_init__
:初始化后的检查
def __post_init__(self):if self.model_name_or_path is None:raise ValueError("Please provide `model_name_or_path`.")...
这是 @dataclass
提供的一个特殊方法:在所有字段初始化完成后自动执行。
它做了几件事:
- 强制检查:必须提供
model_name_or_path
,否则报错。 - 数据清洗:
- 把
adapter_name_or_path
按逗号拆成列表,并去掉空格。 - 把
new_special_tokens
也拆成列表。
原始输入可能是
"lora1, lora2, lora3"
→ 处理后变成['lora1', 'lora2', 'lora3']
- 把
📌 举个例子:
args = BaseModelArguments(model_name_or_path="qwen",adapter_name_or_path="lora1, lora2 ",new_special_tokens=" <|user|> , <|bot|> "
)
结果:
args.adapter_name_or_path
→['lora1', 'lora2']
args.new_special_tokens
→['<|user|>', '<|bot|>']
✅ 总结:这张“配置表”是干啥的?
这个 BaseModelArguments
类就像一个模型启动说明书,告诉程序:
- 用哪个模型?
- 怎么加载更省内存?
- 是否启用各种加速技术(FlashAttention、Unsloth、Liger Kernel)?
- 如何处理分词?
- 是否合并多个 LoRA?
- 推理用什么后端和精度?
它通常会被用在命令行解析中(比如配合 HfArgumentParser
),让用户可以通过命令行输入这些参数,比如:
python train.py \--model_name_or_path Qwen/Qwen-7B \--adapter_name_or_path ./lora1,./lora2 \--use_fast_tokenizer True \--flash_attn auto
然后程序自动把这些参数变成一个 BaseModelArguments
对象,方便后续使用。
🎁 打个比方
想象你要组装一台电脑:
model_name_or_path
就是 CPUadapter_name_or_path
是外接显卡flash_attn
是超频开关low_cpu_mem_usage
是节能模式__post_init__
就是开机自检:检查电源有没有插、内存条有没有装而
@dataclass
就是那个帮你写好“组装说明书”的工具,不用你手动画电路图。
✅ 一句话总结:
@dataclass
让你用最简洁的方式定义一个“纯数据类”,而BaseModelArguments
就是一个专门用来配置大模型各种选项的“超级表单”,包含了加载、训练、推理、优化等方方面面的设置。