【Bug已解决】Adding a model 解决方案
【Bug已解决】Adding a model 解决方案一、现象长什么样当你按 Transformers 的添加新模型流程把一份第三方权重接进PreTrainedModel子类时常遇到这一类失败# 现象 A初始化权重全零 / 没被 Xavier 初始化 UserWarning: You are using the default init_weights which is not recommended. # 或者更糟forward 输出全是同一个常数因为权重没初始化 # 现象 Bload_weight 时 key 对不上 RuntimeError: Error(s) in loading state_dict for MyModel: Missing key(s) in state_dict: model.layers.0.self_attn.q_proj.weight. Unexpected key(s) in state_dict: transformer.h.0.attn.q_proj.weight. # 现象 Csave_pretrained 后再 from_pretrained 失败 KeyError: base_model_prefix # 或保存出的 config.json 缺关键字段导致二次加载崩溃 # 现象 DCI 的 slow 测试直接报错 ValueError: Could not find dummy objects for model my_model. # 官方 CI 要求提供 _dummy_xxx 输入否则集成测试跑不起来这些都不是模型数学写错而是集成骨架没搭全权重初始化、key 命名、base_model_prefix、dummy 测试对象缺一个就卡一个。二、背景把一个新模型Adding a model接进 transformers需要的不只是modeling_xxx.py里的网络代码还有一整套契约_init_weights/init_weights保证加载前权重被合理初始化。base_model_prefix告诉PreTrainedModel顶层容器叫什么如model、transformer所有get_input_embeddings、tie_weights、state_dict key 前缀都依赖它。权重 key 命名必须与 checkpoint 里的 key 完全一致前缀、层级。_tied_weights_keys/tie_weights词嵌入共享时声明。dummy 测试对象官方 CI 用_init_dummy_inputs等做无权重快速测试。漏掉其中任何一项都会在上文的现象里以不同形式炸出来。这些问题与 596特定模型 D_Nikud 的 Auto 注册是不同层面596 是Auto 体系认不认得你601 是模型自身骨架对不对。三、根因把常见失败归到四类根因没实现_init_weights或没调init_weights()。PreTrainedModel.__init__默认不会自动初始化子模块权重除非你覆盖了_init_weights并在__init__末尾调self.init_weights()。如果漏了权重保持nn.Linear的默认也可能被加载流程跳过→ 全零或常数forward 输出退化。base_model_prefix与权重 key 前缀不一致。 若你写base_model_prefix model但 checkpoint 的 key 是transformer.h.0...加载时所有 key 都Missing/Unexpected。反之保存时也会写出错误前缀二次加载即KeyError。tie_weights相关 key 未声明。 当lm_head.weight与embed_tokens.weight共享却没在_tied_weights_keys里声明保存 checkpoint 时可能重复保存或漏保存导致加载维度错乱。缺 dummy 测试对象。 官方 CI 的models/__init__.py测试会尝试无权重构造模型并跑 dummy 输入。若没提供_init_dummy_inputs或对应的ModelTesterCI 直接ValueError: Could not find dummy objects。四、最小可运行复现下面用纯 Python 模拟base_model_prefix 与 key 前缀不一致导致 load 失败的判定from typing import Dict, List class _PretendModel: def __init__(self, base_model_prefix: str): self.base_model_prefix base_model_prefix def expected_keys(self, layer_keys: List[str]) - List[str]: # 真实 transformers 会把 base_model_prefix 作为 state_dict 顶层前缀 return [f{self.base_model_prefix}.{k} for k in layer_keys] def load_state_dict(model, checkpoint_keys: List[str], model_keys: List[str]): missing [k for k in model_keys if k not in checkpoint_keys] unexpected [k for k in checkpoint_keys if k not in model_keys] return missing, unexpected # 情景 1prefix 不一致 model _PretendModel(base_model_prefixmodel) layer_keys [layers.0.self_attn.q_proj.weight] model_keys model.expected_keys(layer_keys) # [model.layers.0...q_proj.weight] checkpoint_keys [transformer.h.0.attn.q_proj.weight] # 错误前缀 missing, unexpected load_state_dict(model, checkpoint_keys, model_keys) print(missing:, missing) print(unexpected:, unexpected) assert missing and unexpected, 复现失败应当出现 key 不匹配 # 情景 2prefix 一致则正常 model2 _PretendModel(base_model_prefixtransformer) model_keys2 model2.expected_keys([h.0.attn.q_proj.weight]) ckpt2 [transformer.h.0.attn.q_proj.weight] m2, u2 load_state_dict(model2, ckpt2, model_keys2) print(prefix 一致时 missing/unexpected:, m2, u2) # [] [] assert not m2 and not u2运行后情景 1 报missing/unexpectedkey 前缀不符情景 2 正常正好对应现象 B 的Missing/Unexpected key(s)。五、解决方案第一层最小直接修复最直接补齐骨架三个关键点——_init_weights、base_model_prefix、key 命名对齐from transformers import PreTrainedModel, PretrainedConfig import torch.nn as nn import torch.nn.functional as F class MyConfig(PretrainedConfig): model_type my_model def __init__(self, hidden_size768, vocab_size32000, **kwargs): super().__init__(**kwargs) self.hidden_size hidden_size self.vocab_size vocab_size class MyModel(PreTrainedModel): config_class MyConfig base_model_prefix model # 关键 1与 checkpoint key 前缀一致 _tied_weights_keys [lm_head.weight, model.embed_tokens.weight] def __init__(self, config: MyConfig): super().__init__(config) self.embed_tokens nn.Embedding(config.vocab_size, config.hidden_size) self.layers nn.ModuleList([nn.Linear(config.hidden_size, config.hidden_size) for _ in range(2)]) self.lm_head nn.Linear(config.hidden_size, config.vocab_size, biasFalse) # 关键 2初始化权重 self.init_weights() # 会调用下面的 _init_weights def _init_weights(self, module): # 关键 3明确初始化避免全零 if isinstance(module, nn.Linear): module.weight.data.normal_(mean0.0, std0.02) if module.bias is not None: module.bias.data.zero_() def forward(self, input_ids): x self.embed_tokens(input_ids) for layer in self.layers: x F.relu(layer(x)) return self.lm_head(x) # 关键 4保存/加载 key 前缀一致 model MyModel(MyConfig()) model.save_pretrained(./my_ckpt) # 写出 model.* / lm_head.* m2 MyModel.from_pretrained(./my_ckpt) # 前缀对齐正常加载第一层让用户加载/保存/二次加载都正常且权重被正确初始化。六、解决方案第二层结构性改进把新模型骨架检查做成ModelScaffoldValidator在 CI 或加载前自动校验骨架完整性from dataclasses import dataclass from typing import List, Type dataclass class ModelScaffoldValidator: 校验一个新模型类是否满足 transformers 集成骨架契约。 required_attrs: List[str] None def __post_init__(self): self.required_attrs [ base_model_prefix, config_class, _init_weights, init_weights, ] def check(self, model_cls: Type) - List[str]: problems: List[str] [] for attr in self.required_attrs: if not hasattr(model_cls, attr): problems.append(f缺少 {attr}) # base_model_prefix 必须是非空字符串 prefix getattr(model_cls, base_model_prefix, None) if not isinstance(prefix, str) or not prefix: problems.append(base_model_prefix 必须是非空字符串) # 必须有 dummy 测试入口官方 CI 需要 if not hasattr(model_cls, _init_dummy_inputs) and \ not hasattr(model_cls, dummy_inputs): problems.append(缺少 dummy 测试对象CI slow 测试会失败) return problems def assert_ready(self, model_cls: Type): probs self.check(model_cls) if probs: raise RuntimeError(模型骨架不完整:\n \n.join(probs)) # 使用 from my_modeling import MyModel ModelScaffoldValidator().assert_ready(MyModel) # 不抛异常即骨架完整ModelScaffoldValidator把集成骨架从靠经验记忆变成可自动检查作者每次加模型先跑一遍缺什么一目了然。七、解决方案第三层断言 / CI 守护用 pytest 固化骨架契约任何一项缺失都红灯import pytest from transformers import PreTrainedModel from my_modeling import MyModel, MyConfig def test_has_base_model_prefix(): assert isinstance(MyModel.base_model_prefix, str) and MyModel.base_model_prefix, \ base_model_prefix 缺失或为空会导致 state_dict key 前缀错误 def test_init_weights_initializes(): m MyModel(MyConfig(hidden_size64, vocab_size100)) w m.layers[0].weight.data # 不应是全零初始化生效 assert w.abs().sum() 0, _init_weights 未生效权重可能全零 def test_save_load_roundtrip(): import tempfile, os m MyModel(MyConfig(hidden_size64, vocab_size100)) d tempfile.mkdtemp() m.save_pretrained(d) m2 MyModel.from_pretrained(d) # key 前缀应一致能正常加载 assert m2.base_model_prefix m.base_model_prefix def test_has_dummy_inputs_for_ci(): assert hasattr(MyModel, _init_dummy_inputs) or hasattr(MyModel, dummy_inputs), \ 缺少 dummy 测试对象官方 CI 的 slow 测试会 ValueErrorCI 跑pytest tests/test_model_scaffold.py以后只要有人加模型漏了base_model_prefix或_init_weights测试立刻拦截。八、排查清单当你Adding a model遇到加载/保存/CIT 失败按顺序查权重全零或输出常数 → 检查是否实现_init_weights并在__init__调self.init_weights()。Missing/Unexpected key→ 比对base_model_prefix与 checkpoint 真实 key 前缀必须逐字符一致。二次加载KeyError: base_model_prefix→ 保存前确认base_model_prefix已设且config_class正确。共享 embedding 维度错乱 → 在_tied_weights_keys声明lm_head.weight与embed_tokens.weight。CI slow 测试Could not find dummy objects→ 补_init_dummy_inputs或dummy_inputs。九、小结Adding a model 卡住的往往不是网络数学而是集成骨架契约_init_weights初始化、base_model_prefix与 key 前缀一致、_tied_weights_keys共享声明、dummy 测试对象。这四样缺一个就以一种具体现象炸出来。第一层补齐_init_weightsself.init_weights()、base_model_prefix对齐、key 命名一致立即能保存/加载/二次加载。第二层用ModelScaffoldValidator自动校验骨架完整性作者不再靠记忆。第三层pytest 断言prefix 非空、权重已初始化、save/load 往返、有 dummy 对象防止回归。记住加模型先搭骨架再填数学骨架四件套_init_weights/base_model_prefix/_tied_weights_keys/ dummy齐了集成基本不会翻车。

相关新闻

超声波测距模块HC-SR04原理、代码实现与工程实践全解析

超声波测距模块HC-SR04原理、代码实现与工程实践全解析

最近在做一个智能小车项目,需要实现自动避障功能,超声波测距模块就成了我的首选方案。但在实际调试过程中,发现网上很多教程要么代码不完整,要么对原理和误差处理讲得不够透彻,导致新手很容易卡在数据不准或模块不响应…

2026/8/8 8:11:20 阅读更多 →
基于Python与Vosk的《我的世界》本地语音控制自动化方案

基于Python与Vosk的《我的世界》本地语音控制自动化方案

1. 先搞清楚“语音控制MC外挂”到底能做什么,不能做什么 看到“语音控制MC外挂”这个标题,很多人第一反应可能是“用嘴玩游戏”或者“解放双手的神器”。但作为一个在游戏开发和自动化脚本领域折腾过不少项目的人,我得先泼点冷水&#xff1a…

2026/8/8 8:11:20 阅读更多 →
C#单件模式实战:从线程安全到Lazy<T>的最佳实践

C#单件模式实战:从线程安全到Lazy<T>的最佳实践

1. 单件模式:为什么它既是基石,又是“坑王”?在C#开发里,尤其是做上位机、工业控制或者需要长期运行的服务端应用时,你肯定遇到过这样的场景:整个系统只需要一个配置管理器、一个日志记录器,或者…

2026/8/8 8:11:20 阅读更多 →

最新新闻

STM32 ADC 注入通道实战:给紧急采样开一条 VIP 通道

STM32 ADC 注入通道实战:给紧急采样开一条 VIP 通道

我早年做过一个电机驱动板,母线电流用 ADC 规则通道连续采,在后台画波形、算 RMS。一切正常,直到有次负载卡死,电流"唰"地窜上去。我代码里明明写了"电流超阈值就关 PWM",结果 MOS 管还是冒了烟。…

2026/8/8 9:15:49 阅读更多 →
2026年西宁做城市生命线安全工程建设的公司有哪些?

2026年西宁做城市生命线安全工程建设的公司有哪些?

青藏高原东麓、湟水河谷两岸,西宁这座城市最要紧的家底大多埋在地下。两千多米的海拔让冬季格外漫长,集中供热一开就是大半年,燃气管线顺着老城街巷铺进千家万户,河谷地形又让排水防涝在每年汛期成为绕不开的考题。老城区管网服役…

2026/8/8 9:15:49 阅读更多 →
成都GEO优化常见问题,蜀航云创

成都GEO优化常见问题,蜀航云创

随着成都实体经济数字化进程加快,不管是实体商家、产业园区、生产工厂还是政企单位,GEO(地理位置信息)优化已经成为引流获客、精细化运营的核心环节。但不少成都企业在做GEO优化的过程中踩了不少坑,钱花了却没拿到预期…

2026/8/8 9:15:49 阅读更多 →
5个高效场景深度解析:如何用智能工具自动获取百度网盘提取码

5个高效场景深度解析:如何用智能工具自动获取百度网盘提取码

5个高效场景深度解析:如何用智能工具自动获取百度网盘提取码 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 面对海量百度网盘加密资源,传统…

2026/8/8 9:15:49 阅读更多 →
揭秘行业乱象与正规军突围之路,专业全国加盟网站建设服务商助您快速获客

揭秘行业乱象与正规军突围之路,专业全国加盟网站建设服务商助您快速获客

在这个流量红利逐渐见顶,竞争日益白热化的商业时代,越来越多的品牌方开始意识到一个残酷的真相:仅仅依靠线下门店的地推或者传统的线上广告投放,已经很难支撑起一家连锁企业的高速扩张了。尤其是对于那些拥有成熟商业模式、产品力强但缺渠道缺流量的品牌来说,拥有一套高效…

2026/8/8 9:15:49 阅读更多 →
基于超局部模型与ESO的PMSM无模型预测电流控制详解

基于超局部模型与ESO的PMSM无模型预测电流控制详解

大家好,我是专注于工业控制与电机驱动领域的技术博主。在实际的永磁同步电机(PMSM)高性能控制项目中,你是否遇到过这样的困境:传统的模型预测控制(MPC)高度依赖精确的电机数学模型,一…

2026/8/8 9:14:48 阅读更多 →

日新闻

AI多智能体时代来临,读懂MCP与A2A架构,抢占企业数字化新风口

AI多智能体时代来临,读懂MCP与A2A架构,抢占企业数字化新风口

当下AI应用飞速普及,无数企业下场搭建智能体系统,可落地阶段难题接踵而至:上下文无限堆积频繁爆栈、AI工具调用准确率低下、Token成本居高不下、企业数据权限混乱暗藏安全隐患……很多团队卡在架构搭建环节,空有前沿技术概念&…

2026/8/8 0:00:07 阅读更多 →
PHP二维码生成终极指南:用chillerlan/php-qrcode打造专业级二维码

PHP二维码生成终极指南:用chillerlan/php-qrcode打造专业级二维码

PHP二维码生成终极指南:用chillerlan/php-qrcode打造专业级二维码 【免费下载链接】php-qrcode A PHP QR Code generator and reader with a user-friendly API. 项目地址: https://gitcode.com/gh_mirrors/ph/php-qrcode 在当今数字时代,二维码已…

2026/8/8 0:00:08 阅读更多 →
UniApp微信小程序隐私保护组件开发:从原理到实战

UniApp微信小程序隐私保护组件开发:从原理到实战

1. 项目缘起:为什么我们需要一个隐私保护通用组件?最近在维护一个基于uniapp开发的微信小程序矩阵时,我遇到了一个非常棘手的问题。随着平台对用户隐私保护的要求越来越严格,几乎每一个新版本发布,或者在某些特定机型&…

2026/8/8 0:00:08 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/6 22:02:27 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/8 8:58:26 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/7 23:24:08 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/7 17:02:37 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/7 23:54:54 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/7 17:02:36 阅读更多 →