视觉塔冻结、投影层冻结、语言模型不冻结:LlamaFactory 多模态的三个默认值
本文所有事实以
hiyouga/LlamaFactory官方仓库 2026-08-09 的内容为准。我们没有安装、训练或部署过任何模型,文中所有默认值都是从源码field(default=...)里读出来的。
在 src/llamafactory/hparams/finetuning_args.py 里,有三个名字长得几乎一样的布尔开关,默认值却不是一边倒:freeze_vision_tower 默认 True、freeze_multi_modal_projector 默认 True、freeze_language_model 默认 False。两个冻结,一个不冻结。
这篇只做一件事:把这三个默认值的确切字段名、所在的参数层、以及仓库里另一组同样以 freeze_ 开头但完全不是一回事的字段,讲到你不会搜串为止。至于”你的任务里该不该改它们”,这篇一句建议都不会给——原因写在最后一节。
先把三个字段的写法钉住
| 参数 | 默认值 | 字面含义 |
|---|---|---|
freeze_vision_tower | True | 视觉塔默认冻结 |
freeze_multi_modal_projector | True | 多模态投影层默认冻结 |
freeze_language_model | False | 语言模型默认不冻结 |
三个字段的写法上没有任何花样:都是布尔,都有默认值。容易读错的是方向——字段名都以 freeze_ 开头,前两个的默认值 True 落在”冻”这一侧,第三个的默认值 False 落在”不冻”这一侧。也就是说同一个命名前缀下,默认值并不是齐刷刷一个方向,读的时候得把字段名和取值配在一起看,不能只扫一眼前缀就下结论。
这里要卡死一句话:默认值不是推荐值。 源码里的 default 只回答”你什么都不写时它是什么”,不回答”你应该写什么”。这两件事在参数文档里经常被混着读,是本篇最想拆开的一层。
它们坐在哪一层
LlamaFactory 把超参按职责拆到了 src/llamafactory/hparams/ 下的多个文件里:data_args.py、model_args.py、finetuning_args.py、generating_args.py、evaluation_args.py、training_args.py、megatron_bridge_args.py,加上 parser.py 和 __init__.py。
换句话说,这个仓库把超参按数据、模型、微调、生成、评测、训练、Megatron 桥接拆成了 7 个 *_args.py,外加一个 parser.py 和 __init__.py。这层结构本身值得先记一遍:同一次训练里你要填的参数,源头分散在好几个文件,靠”我记得这个参数是干什么的”去猜它在哪个文件,命中率不高。
上面这三个冻结开关在 finetuning_args.py 里,和 stage(默认 "sft")、finetuning_type(默认 "lora")、LoRA 那一批参数是同一个文件的邻居。同一个文件里还有三个训练控制字段:compute_accuracy 默认 False、disable_shuffling 默认 False、early_stopping_steps 默认 None。这三个和多模态没有直接关系,列出来是为了让你知道搜到这一段时上下文长什么样,不至于把相邻的字段当成同一组。
而你做多模态任务时同样躲不掉的另一批参数——图像和视频的像素预算、抽帧率——不在这个文件里,它们在 model_args.py。这个分层本身就是一条能省时间的信息:当你按名字搜某个多模态参数搜不到时,先确认自己翻的是哪一个 *_args.py,而不是怀疑这个参数不存在。
别把两组 freeze_ 搞混
同一个 finetuning_args.py 里还有另外三个字段,前缀完全一样:
| 参数 | 默认值 |
|---|---|
freeze_trainable_layers | 2 |
freeze_trainable_modules | "all" |
freeze_extra_modules | None |
这一组和多模态那三个开关是两组不同的字段:这一组的名字对应的是 freeze-tuning 这种微调方式的配置项,取值也不是布尔(一个是整数 2,一个是字符串 "all",一个默认为空);多模态那三个是清一色的布尔开关。
实际会踩的坑很朴素:按 freeze_ 这个前缀去翻这个文件,这六个字段的名字长得一样近,光看前缀分不出谁是谁。分辨方法是看类型和取值——布尔的那三个是多模态那组,带数字 2 和字符串 "all" 的那三个是另一组。
至于这两组字段在运行时如何联合生效、谁覆盖谁,我们没有读过那段逻辑,这里不做任何推断。
和默认的 stage / finetuning_type 连起来读
finetuning_args.py 里 stage 默认是 "sft",finetuning_type 默认是 "lora"。所以你什么都不写时,这个文件给出的默认组合是:SFT 阶段、LoRA 方式、视觉塔冻结、投影层冻结、语言模型不冻结。
同一文件里 LoRA 那几个默认值是:lora_rank 默认 8、lora_target 默认 "all"、additional_target 默认 None、lora_alpha 默认 None、lora_dropout 默认 0.0。
lora_target 的默认值是 "all",多模态三个开关里又有两个默认 True——这两套字段用的是完全不同的命名体系,它们在代码里怎么交互,卡在我们这一侧的边界就是:没读过实现,不推断。能写的只有一句客观描述:这几个值就是各自源码里的默认值,仅此而已。
为什么要把输入侧那几行一起看
model_args.py 里与多模态输入直接相关的几行是这样的:
| 参数 | 默认值 |
|---|---|
image_max_pixels | 768 * 768 |
image_min_pixels | 32 * 32 |
video_max_pixels | 256 * 256 |
video_min_pixels | 16 * 16 |
video_fps | 2.0 |
video_maxlen | 128 |
use_audio_in_video | False |
audio_sampling_rate | 16000 |
image_do_pan_and_scan | False |
crop_to_patches | False |
这篇引这几行不是为了凑一张表,而是因为从字段名的字面含义看,它们和三个冻结开关分属同一件事的两端:一边是名字里带 freeze_ 的权重侧开关,一边是名字里带 image_ / video_ / audio_ 的输入侧规格。你在配一次多模态任务时两边都要填,但它们分别写在两个文件里。至于这两侧在运行时具体怎么互相影响,我们没读过实现,不做推断。
从默认值里能直接读出来的数字关系也就两条:图像单张的最大像素预算(768 * 768)是视频单帧(256 * 256)的 9 倍;视频默认按 2.0 fps 抽帧、最多取 128 帧。音频那侧默认采样率是 16000,而 use_audio_in_video 默认 False。这些是读数,不是结论,我们不据此推导任何”所以你该怎么配”。
怎么核对你手上那一份
版本会漂,所以核对动作比记住数字更重要。三步:
- 跑
llamafactory-cli train -h,看你安装的这个版本实际暴露出来的参数名和默认值; - 打开
src/llamafactory/hparams/finetuning_args.py,把freeze_vision_tower、freeze_multi_modal_projector、freeze_language_model这三个名字逐个搜一遍,看各自的field(default=...); - 回头看你要用的那份示例 YAML,确认里面有没有显式写这几个字段。
第三步不能省,因为这个仓库里确实存在”源码默认值”和”官方示例里的值”不一样的先例:model_args.py 里 trust_remote_code 的源码默认值是 False,而 examples/ 下的示例 YAML(train_lora/qwen3_lora_sft.yaml、inference/qwen3_lora_sft.yaml、merge_lora/qwen3_lora_sft.yaml)里都显式写了 trust_remote_code: true。两处不一致,以你手上仓库的当前状态为准——我们不推断哪一处”才是对的”,也不由此评价什么。
这个先例对本篇的用处只有一条:核对多模态那三个冻结开关时,别只看源码默认值就下结论,也去看一眼你实际要跑的那份 YAML 里写没写。
反过来说,什么情况下问题不在这三个字段上?如果你 -h 的输出里根本没有 freeze_vision_tower 这个名字,那说明你手上的版本和本文核对的这一版对不上,先去确认版本,而不是去改配置;如果你的 YAML 里压根没出现过任何 freeze_ 字段、行为却和预期不一样,那问题多半在别的层——比如数据侧或模型加载侧的参数——继续在这三个开关上纠缠是浪费时间。
那到底该不该改
不给建议,这是本篇的立场,说清楚理由:我们没有安装、没有训练、没有跑过任何一次多模态微调,官方也没有给出一套”什么场景该冻哪一部分”的通用值。在这种前提下写”建议解冻视觉塔""保持默认更好”,都是编的。
这篇能给你的确定信息只有三条:这三个字段的确切名字与默认值;它们在 finetuning_args.py,而输入侧参数在 model_args.py;仓库里还有另一组 freeze_ 开头的字段容易搜串,靠取值类型区分。改成多少取决于你的数据和硬件,官方没给通用值。
关于 template 为什么必须训练推理两侧对齐、dataset_info.json 的字段怎么填、README 那张标着 * estimated 的显存表怎么读,我们各有专门篇目讲,这篇只负责把这三个默认值钉死。
本文依据 LlamaFactory 官方仓库(github.com/hiyouga/LlamaFactory)的 README、data/README.md、examples/ 下的配置与 src/llamafactory/hparams/ 的参数定义整理,核对日 2026-08-09。本文内容为仓库源码与文档口径,我们没有安装、训练或部署过任何模型,文中显存数字均为官方标注的估算值(README 原文标 * estimated)而非实测占用。参数与默认值随版本变动,请以 llamafactory-cli train -h 的实际输出为准。安全相关做法请结合自身环境评估,本文不构成安全方案建议。