PEFT 报 Target modules not found,LoRA 应该挂到哪一层
先读取真实模块名称,再区分 target_modules 的字符串正则与列表匹配。说明模型结构、层筛选和训练参数验收,避免套用其他模型的 q_proj 名称。
调用 get_peft_model() 时出现 Target modules ... not found in the base model,训练尚未开始。常见情况是复制了另一种模型的 q_proj、v_proj,或者把正则表达式放进了列表。
本文按 PEFT 0.17.0 的 LoRA 配置规则说明。模块名称属于模型实现,不能只根据“都是语言模型”判断。旧版本配置也应对照实际安装版本核查。
先看模型里到底有哪些模块
对已经加载的基础模型 model,列出名称与类型:
for name, module in model.named_modules():
print(name, type(module).__name__)
这里不会打印权重内容。检查的是将被注入适配器的子模块,不是 named_parameters() 中以 .weight 结尾的参数名。
有的注意力实现把 Q、K、V 合在 query_key_value,有的拆成 q_proj、k_proj、v_proj。某个名字在另一份模型中有效,不代表当前模型也存在。先找到真实目标,再确认其类型能被当前 LoRA 实现支持;名称匹配成功但层类型不受支持,是后续另一种错误。
包装器和模型版本还会改变完整路径。自定义架构、替换层或加载了不同模型类时,应检查实际对象,不能仅看配置文件写着哪一种模型家族。
字符串与列表不是同一种匹配
PEFT 0.17.0 中,target_modules 传字符串时按正则匹配完整模块名;传列表时,检查完整名称相等或模块路径以点加该项结尾。列表中的内容不作为逐项正则。
假设前一步已确认目标名称以 query_key_value 结尾,匹配这类模块可用:
from peft import LoraConfig, TaskType, get_peft_model
config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=8,
lora_alpha=16,
target_modules=["query_key_value"],
)
adapted = get_peft_model(model, config)
r 和 lora_alpha 在这里仅是示例配置,需要按实际训练方案确定。这个目标名只适用于已确认具有相应模块的模型。
若业务确实需要用正则筛选完整路径,使用单个字符串,并先观察它会匹配哪些名字:
import re
pattern = r".*\.1\..*query_key_value"
matched = [
name for name, _ in model.named_modules()
if re.fullmatch(pattern, name)
]
print(matched)
这里的模式示意“路径中某个点分数字为 1”的筛选,不保证等同于业务定义的第一层;真实路径里可能有多个数字层级。核对输出后,才把 pattern 作为字符串传给 target_modules。写成 [pattern] 会改成列表匹配,常常找不到任何目标。
不要为了消除错误扩大到所有层
target_modules="all-linear" 在该版本可选择线性层与 Conv1D;对 PreTrainedModel 会排除输出层。它会改变适配器覆盖范围、训练参数数量及保存结果,不能作为任何目标名错误的统一替代。
如果还配置了 layers_to_transform、layers_pattern、exclude_modules 或 modules_to_save,也要核对筛选与排除条件。目标名存在,但层筛选没有匹配到索引,仍可能无法注入。正则预览只是名称检查,不完整模拟这些额外规则。
已经保存的适配器配置还应与原基础模型匹配。不要随意改目标名后加载旧适配器,再用忽略缺失权重的方式声称加载成功;保留原配置和权重,必要时建立新的训练输出目录。
注入成功后检查哪些参数会训练
在注入前记录预期模块列表。成功构建 adapted 后,可用下面的诊断片段核对训练范围:
adapted.print_trainable_parameters()
for name, parameter in adapted.named_parameters():
if parameter.requires_grad:
print(name, tuple(parameter.shape))
确认预期 LoRA 参数存在,基础层与额外可训练模块的状态符合方案,再进行受控的前向与反向检查。只有错误消失还不够:匹配范围过窄、意外选中了另一组层,同样可能让模型能启动但训练目标变了。


