From dd2032d9baf7528f41d245e6b6773bcdc8dae771 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 30 Oct 2026 08:49:12 +0100 Subject: [PATCH 1/7] [modular] WIP: error when inherited code silently uses a redefined modular class --- .../models/aya_vision/modular_aya_vision.py | 14 ++ .../models/mixtral/modular_mixtral.py | 15 ++ utils/fix_modular_inherited_overrides.py | 166 ++++++++++++++++++ utils/modular_model_converter.py | 84 +++++++++ 4 files changed, 279 insertions(+) create mode 100644 utils/fix_modular_inherited_overrides.py diff --git a/src/transformers/models/aya_vision/modular_aya_vision.py b/src/transformers/models/aya_vision/modular_aya_vision.py index 030e7f49cc71..72cdb0c75199 100644 --- a/src/transformers/models/aya_vision/modular_aya_vision.py +++ b/src/transformers/models/aya_vision/modular_aya_vision.py @@ -31,6 +31,7 @@ from ...utils import TransformersKwargs, auto_docstring, logging from ...utils.generic import can_return_tuple, merge_with_config_defaults from .configuration_aya_vision import AyaVisionConfig +from ..auto import AutoModel logger = logging.get_logger(__name__) @@ -199,6 +200,13 @@ def forward( attentions=outputs.attentions, image_hidden_states=image_features if mm_encoder_outputs.get("image") is not None else None, ) + def __init__(self, config: AyaVisionConfig): + super().__init__(config) + self.vision_tower = AutoModel.from_config(config.vision_config) + + self.multi_modal_projector = AyaVisionMultiModalProjector(config) + self.language_model = AutoModel.from_config(config.text_config) + self.post_init() class AyaVisionForConditionalGeneration(LlavaForConditionalGeneration): @@ -265,5 +273,11 @@ def forward( **kwargs, ) + def __init__(self, config: AyaVisionConfig): + super().__init__(config) + self.model = AyaVisionModel(config) + self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False) + self.post_init() + __all__ = ["AyaVisionForConditionalGeneration", "AyaVisionPreTrainedModel", "AyaVisionModel"] diff --git a/src/transformers/models/mixtral/modular_mixtral.py b/src/transformers/models/mixtral/modular_mixtral.py index c50416758569..bfc32630179c 100644 --- a/src/transformers/models/mixtral/modular_mixtral.py +++ b/src/transformers/models/mixtral/modular_mixtral.py @@ -318,6 +318,21 @@ def forward( last_hidden_state=hidden_states, past_key_values=past_key_values, ) + def __init__(self, config: MixtralConfig): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + + self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx) + self.layers = nn.ModuleList( + [MixtralDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = MixtralRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = MixtralRotaryEmbedding(config=config) + self.gradient_checkpointing = False + + # Initialize weights and apply final processing + self.post_init() class MixtralForCausalLM(MistralForCausalLM): diff --git a/utils/fix_modular_inherited_overrides.py b/utils/fix_modular_inherited_overrides.py new file mode 100644 index 000000000000..a67229729f82 --- /dev/null +++ b/utils/fix_modular_inherited_overrides.py @@ -0,0 +1,166 @@ +"""Make modular files explicit: copy generated members whose inherited version would use the parent's classes.""" + +import builtins +import json +import subprocess +import sys + +import libcst as cst + +sys.path.insert(0, "utils") +import modular_model_converter as mmc # noqa: E402 + + +captured = {} +mmc.check_inherited_code_uses_parent_definitions = lambda mapper, files: captured.update(mapper=mapper, files={k: dict(v) for k, v in files.items()}) + + +def top_level_names(module): + out = [] + for node in module.body: + if isinstance(node, (cst.ClassDef, cst.FunctionDef)): + out.append(node.name.value) + else: + out.append(None) + return out + + +def import_lines_for(module, name): + """Return an import statement code importing `name` if `module` imports it at top level.""" + for node in module.body: + stmts = [node] + if isinstance(node, cst.If): # `if is_torch_available():` blocks + stmts = list(node.body.body) + for stmt in stmts: + if not m_simple(stmt): + continue + imp = stmt.body[0] + if isinstance(imp, cst.ImportFrom) and not isinstance(imp.names, cst.ImportStar): + for alias in imp.names: + asname = alias.asname.name.value if alias.asname else None + real = mmc.get_full_attribute_name(alias.name) + if (asname or real) == name: + mod = cst.Module(body=[]).code_for_node(imp.module) if imp.module else "" + dots = "." * len(imp.relative) + return f"from {dots}{mod} import {real}" + (f" as {asname}" if asname else "") + if isinstance(imp, cst.Import): + for alias in imp.names: + asname = alias.asname.name.value if alias.asname else None + real = mmc.get_full_attribute_name(alias.name) + if (asname or real.split(".")[0]) == name: + return f"import {real}" + (f" as {asname}" if asname else "") + return None + + +def m_simple(stmt): + return isinstance(stmt, cst.SimpleStatementLine) and len(stmt.body) == 1 + + +class Inserter(cst.CSTTransformer): + def __init__(self, members): # {class_name: {key: stmt}} + self.members = members + + def leave_ClassDef(self, original, updated): + todo = dict(self.members.get(updated.name.value, {})) + if not todo: + return updated + body = [] + for stmt in updated.body.body: + key = mmc._statement_key(stmt) + if key in todo: + body.append(todo.pop(key)) + elif m_simple(stmt) and isinstance(stmt.body[0], cst.Pass): + continue + else: + body.append(stmt) + body.extend(todo.values()) + return updated.with_changes(body=updated.body.with_changes(body=body)) + + +class Renamer(cst.CSTTransformer): + def __init__(self, mapping): + self.mapping = mapping + + def leave_Name(self, original, updated): + return updated.with_changes(value=self.mapping.get(updated.value, updated.value)) + + +def undefined_names(path): + out = subprocess.run( + ["ruff", "check", "--select", "F821", "--output-format", "json", "--no-cache", path], + capture_output=True, + text=True, + ).stdout + return sorted({d["message"].split("`")[1] for d in json.loads(out or "[]")}) + + +def fix(path): + captured.clear() + mmc.convert_modular_file(path) + mapper, files = captured["mapper"], captured["files"] + mismatches = mmc.find_inherited_code_mismatches(mapper, files) + if not mismatches: + return 0, [] + generated = {name: entry["node"] for body in files.values() for name, entry in body.items()} + members = {} + for class_name, key, _, _ in mismatches: + if key is None: + continue + stmt = next(s for s in generated[class_name].body.body if mmc._statement_key(s) == key) + members.setdefault(class_name, {})[key] = stmt + source = open(path).read() + module = cst.parse_module(source).visit(Inserter(members)) + open(path, "w").write(module.code) + + # Resolve names the copied code uses but the modular file does not define + renamed_to_original, import_for = {}, {} + for file, original in mapper.model_specific_modules.items(): + renamed = original.visit(mapper.renamers[file]) + rel = "..%s.%s" % tuple(file.split(".")[-2:]) + for o, r in zip(top_level_names(original), top_level_names(renamed)): + if r is not None and r not in renamed_to_original: + renamed_to_original[r] = (o, f"from {rel} import {o}") + for name in undefined_names(path): + if name not in import_for and name not in renamed_to_original: + line = import_lines_for(renamed, name) + if line is not None: + import_for[name] = line + missing, rename, imports = [], {}, [] + for name in undefined_names(path): + if name in renamed_to_original: + original_name, line = renamed_to_original[name] + rename[name] = original_name + imports.append(line) + elif name in import_for: + imports.append(import_for[name]) + elif not hasattr(builtins, name): + missing.append(name) + module = cst.parse_module(open(path).read()) + if rename: + module = module.visit(Renamer(rename)) + if imports: + idx = max( + i + for i, node in enumerate(module.body) + if m_simple(node) and isinstance(node.body[0], (cst.Import, cst.ImportFrom)) + ) + new_nodes = [cst.parse_statement(line) for line in sorted(set(imports))] + module = module.with_changes(body=[*module.body[: idx + 1], *new_nodes, *module.body[idx + 1 :]]) + code = module.code + open(path, "w").write(code) + return len(mismatches), missing + + +if __name__ == "__main__": + import time + + paths = sys.argv[1:] + t0 = time.time() + for i, path in enumerate(paths, 1): + try: + n, missing = fix(path) + status = f"fixed {n}" + (f" | UNRESOLVED {missing}" if missing else "") if n else "clean" + except Exception as e: + status = f"CRASH {type(e).__name__}: {e}"[:200] + el = time.time() - t0 + print(f"[{i}/{len(paths)}] {path.split('/')[-1]} {status} | elapsed {el:.0f}s | eta ~{el / i * (len(paths) - i):.0f}s", flush=True) diff --git a/utils/modular_model_converter.py b/utils/modular_model_converter.py index 2e8aa5782a67..a921ce3f6dae 100644 --- a/utils/modular_model_converter.py +++ b/utils/modular_model_converter.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import argparse +import ast import glob import importlib import multiprocessing as mp @@ -1626,12 +1627,17 @@ def leave_Module(self, node): # 1. for each modeling file found in the imports, rename it with the new model name, visit it, and update dependencies self.visited_modules = {} self.renamers = {} + # Top-level classes/functions of each renamed modeling file, before the modular definitions are merged in + self.renamed_original_nodes = {} name_prefixes = self.infer_new_model_name() for file, module in self.model_specific_modules.items(): file_model_name = file.split(".")[-2] new_name = name_prefixes[file] renamer = ReplaceNameTransformer(file_model_name, new_name, self.model_name) renamed_module = module.visit(renamer) + self.renamed_original_nodes[file] = { + node.name.value: node for node in renamed_module.body if isinstance(node, (cst.ClassDef, cst.FunctionDef)) + } self.visited_modules[file] = ModelFileMapper.visit_and_merge_dependencies( renamed_module, self.classes, @@ -1969,6 +1975,82 @@ class node based on the inherited classes if needed. Also returns any new import return nodes_to_add, file_type, new_imports +def _normalized_code(node: cst.CSTNode) -> str: + """Code of `node` without docstrings, so that only behavior is compared.""" + tree = ast.parse(cst.Module(body=[node]).code) + for sub in ast.walk(tree): + body = getattr(sub, "body", None) + if ( + isinstance(body, list) + and body + and isinstance(body[0], ast.Expr) + and isinstance(body[0].value, ast.Constant) + and isinstance(body[0].value.value, str) + ): + sub.body = body[1:] or [ast.Pass()] + return ast.dump(tree) + + +def _statement_key(node: cst.CSTNode) -> str | None: + if isinstance(node, (cst.FunctionDef, cst.ClassDef)): + return node.name.value + target = get_assign_target(node) + return target.value if isinstance(target, cst.Name) else None + + +def _names_in(node: cst.CSTNode) -> set[str]: + return {name.value for name in m.findall(node, m.Name())} + + +def find_inherited_code_mismatches( + modular_mapper: "ModularFileMapper", files: dict[str, dict] +) -> list[tuple[str, str, str, str]]: + """ + Inheriting in a modular file must mean the same thing as inheriting in Python. If `MixtralDecoderLayer(LlamaDecoderLayer)` + does not override `__init__`, Python builds `LlamaMLP`, but the generated file builds `MixtralMLP` because of the + renaming. If the modular file redefines `MixtralMLP` with different code, the modular and generated files disagree. + Returns `(class_name, member, used_name, parent_class)` for each such case. + """ + generated = {name: entry["node"] for body in files.values() for name, entry in body.items()} + modular_defined = set(modular_mapper.classes) | set(modular_mapper.functions) + mismatches = [] + for class_name, modular_node in modular_mapper.classes.items(): + bases = [ + k.value.value + for k in modular_node.bases + if m.matches(k.value, m.Name()) and k.value.value in modular_mapper.model_specific_imported_objects + ] + if len(bases) != 1 or class_name not in generated: + continue + originals = modular_mapper.renamed_original_nodes[modular_mapper.model_specific_imported_objects[bases[0]]] + modular_statements = {_statement_key(node): node for node in modular_node.body.body} + for statement in generated[class_name].body.body: + key = _statement_key(statement) + inherited_names = _names_in(statement) + if key is not None and key in modular_statements: + inherited_names -= _names_in(modular_statements[key]) + for name in sorted(inherited_names & modular_defined - {class_name}): + if name not in originals or name not in generated: + continue + if _normalized_code(originals[name]) != _normalized_code(generated[name]): + mismatches.append((class_name, key, name, bases[0])) + return mismatches + + +def check_inherited_code_uses_parent_definitions(modular_mapper: "ModularFileMapper", files: dict[str, dict]): + mismatches = find_inherited_code_mismatches(modular_mapper, files) + if mismatches: + errors = [ + f"`{class_name}.{member}` is inherited from `{parent}` but uses `{name}`, which the modular file redefines: " + f"Python inheritance would use `{parent}`'s version. Override `{member}` in `{class_name}`." + for class_name, member, name, parent in mismatches + ] + raise ValueError( + f"Modular file for `{modular_mapper.model_name}` does not behave like the generated code:\n- " + + "\n- ".join(errors) + ) + + def create_modules( modular_mapper: ModularFileMapper, file_path: str | None = None, @@ -2012,6 +2094,8 @@ def create_modules( current_file_indices[file_type] += 1 files[file_type][dependency] = {"insert_idx": idx, "node": node} + check_inherited_code_uses_parent_definitions(modular_mapper, files) + # Add the __all__ statement to files at the end for file_type, node in modular_mapper.all_all_to_add.items(): idx = current_file_indices[file_type] From 739b7c4fd90cabdbd318bf5333673a8a0bf8ca77 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 30 Oct 2026 10:56:24 +0100 Subject: [PATCH 2/7] [modular] make inherited code use parent definitions explicitly in 182 modular files; allowlist 53 to fix --- .../models/aimv2/modular_aimv2.py | 8 +- .../models/apertus/modular_apertus.py | 15 +- src/transformers/models/aria/modular_aria.py | 9 ++ .../audioflamingo3/modular_audioflamingo3.py | 1 + src/transformers/models/axk1/modular_axk1.py | 18 ++- src/transformers/models/axk2/modular_axk2.py | 17 ++- .../models/aya_vision/modular_aya_vision.py | 23 ++- .../bailing_hybrid/modular_bailing_hybrid.py | 21 ++- .../models/bamba/modular_bamba.py | 47 +++++- src/transformers/models/beam/modular_beam.py | 19 +++ src/transformers/models/beit/modular_beit.py | 5 + .../models/bitnet/modular_bitnet.py | 7 +- .../models/canary/modular_canary.py | 1 + .../models/cohere/modular_cohere.py | 1 + .../models/cohere2/modular_cohere2.py | 9 +- .../models/cohere2_moe/modular_cohere2_moe.py | 8 + .../cohere2_vision/modular_cohere2_vision.py | 111 ++++++++++++++ .../models/cohere_asr/modular_cohere_asr.py | 3 + .../cohere_compass/modular_cohere_compass.py | 5 + .../modular_conditional_detr.py | 10 +- .../cosmos3_edge/modular_cosmos3_edge.py | 6 + src/transformers/models/cwm/modular_cwm.py | 9 +- .../models/data2vec/modular_data2vec_audio.py | 17 ++- .../models/deepseek_v2/modular_deepseek_v2.py | 12 +- .../models/deepseek_v3/modular_deepseek_v3.py | 15 +- .../models/deepseek_v4/modular_deepseek_v4.py | 5 +- .../models/deepseek_vl/modular_deepseek_vl.py | 4 + .../modular_deepseek_vl_hybrid.py | 12 ++ .../modular_deformable_detr.py | 4 + src/transformers/models/deit/modular_deit.py | 4 +- .../models/diffllama/modular_diffllama.py | 11 +- .../models/dinov2/modular_dinov2.py | 48 +++++- .../modular_dinov2_with_registers.py | 5 +- src/transformers/models/doge/modular_doge.py | 6 + .../models/dots1/modular_dots1.py | 22 ++- src/transformers/models/dpt/modular_dpt.py | 19 +++ .../modular_embedding_gemma2.py | 113 +++++++++++++- src/transformers/models/eomt/modular_eomt.py | 4 +- .../models/ernie/modular_ernie.py | 40 +++++ .../models/ernie4_5/modular_ernie4_5.py | 49 ++++++- .../ernie4_5_moe/modular_ernie4_5_moe.py | 51 ++++++- src/transformers/models/esmc/modular_esmc.py | 2 + .../models/evolla/modular_evolla.py | 96 +++++++++++- .../models/exaone4/modular_exaone4.py | 14 +- .../models/exaone4_5/modular_exaone4_5.py | 54 ++++++- .../models/exaone_moe/modular_exaone_moe.py | 13 +- .../models/falcon_h1/modular_falcon_h1.py | 4 + .../models/fast_vlm/modular_fast_vlm.py | 6 + .../models/florence2/modular_florence2.py | 6 + .../fun_asr_nano/modular_fun_asr_nano.py | 43 ++++++ .../models/gemma2/modular_gemma2.py | 4 + .../models/gemma3/modular_gemma3.py | 13 ++ .../models/gemma3n/modular_gemma3n.py | 8 +- .../models/gemma4/modular_gemma4.py | 12 ++ .../gemma4_unified/modular_gemma4_unified.py | 31 +++- src/transformers/models/glm/modular_glm.py | 48 +++++- .../models/glm46v/modular_glm46v.py | 4 +- .../models/glm4v/modular_glm4v.py | 118 ++++++++++++++- .../models/glm_ocr/modular_glm_ocr.py | 20 ++- .../models/glmasr/modular_glmasr.py | 4 + .../models/glmga/modular_glmga.py | 19 ++- .../models/got_ocr2/modular_got_ocr2.py | 36 +++++ .../models/gpt_oss/modular_gpt_oss.py | 12 +- .../models/granite/modular_granite.py | 4 + .../modular_granite4_vision.py | 8 + .../modular_granite_speech5.py | 11 +- .../models/granite_swa/modular_granite_swa.py | 4 +- .../granitemoe_swa/modular_granitemoe_swa.py | 4 +- src/transformers/models/gte/modular_gte.py | 11 +- .../models/helium/modular_helium.py | 64 +++++++- .../modular_higgs_audio_v2_tokenizer.py | 41 ++++++ .../models/hrm_text/modular_hrm_text.py | 10 ++ .../models/hubert/modular_hubert.py | 17 ++- .../modular_hunyuan_v1_dense.py | 16 +- .../hunyuan_v1_moe/modular_hunyuan_v1_moe.py | 7 +- .../models/hunyuan_vl/modular_hunyuan_vl.py | 5 + .../models/hy_v4/modular_hy_v4.py | 29 +++- .../models/hyperclovax/modular_hyperclovax.py | 11 +- .../models/inkling/modular_inkling.py | 4 + .../models/internvl/modular_internvl.py | 9 ++ .../models/jamba/modular_jamba.py | 1 + .../models/janus/modular_janus.py | 5 + .../modular_jina_embeddings_v3.py | 29 +++- .../models/kimi_k25/modular_kimi_k25.py | 6 + .../models/kimi_linear/modular_kimi_linear.py | 8 + .../models/kolibri1/modular_kolibri1.py | 18 ++- .../modular_kyutai_speech_to_text.py | 1 + .../models/laguna/modular_laguna.py | 22 +++ src/transformers/models/lasr/modular_lasr.py | 9 ++ src/transformers/models/lfm2/modular_lfm2.py | 12 +- .../models/lfm2_moe/modular_lfm2_moe.py | 9 +- .../models/lfm2_vl/modular_lfm2_vl.py | 6 + .../models/lighton_ocr/modular_lighton_ocr.py | 4 + .../modular_llava_next_video.py | 12 ++ .../modular_llava_onevision.py | 12 +- .../models/lw_detr/modular_lw_detr.py | 37 +++++ .../mimo_v2_flash/modular_mimo_v2_flash.py | 23 ++- .../models/minicpm3/modular_minicpm3.py | 15 ++ .../models/minicpm_ocr/modular_minicpm_ocr.py | 20 ++- .../models/minicpmv4_7/modular_minicpmv4_7.py | 10 ++ .../models/minimax/modular_minimax.py | 10 ++ .../minimax_m3_vl/modular_minimax_m3_vl.py | 51 ++++++- .../models/ministral/modular_ministral.py | 14 +- .../models/ministral3/modular_ministral3.py | 10 +- .../models/mistral/modular_mistral.py | 4 +- .../models/mistral3/modular_mistral3.py | 9 ++ .../models/mistral4/modular_mistral4.py | 4 +- .../mistral_large4/modular_mistral_large4.py | 18 ++- .../models/mixtral/modular_mixtral.py | 21 +-- src/transformers/models/mlcd/modular_mlcd.py | 4 + .../models/molmo2/modular_molmo2.py | 8 + .../modular_moonshine_streaming.py | 44 +++++- .../modular_moss_transcribe_diarize.py | 8 + .../muse_glimmer/modular_muse_glimmer.py | 85 ++++++++++- .../modular_muse_glimmer_assistant.py | 5 + .../models/muse_spark/modular_muse_spark.py | 17 ++- .../models/nanochat/modular_nanochat.py | 16 ++ .../modular_nemotron3_5_transcribe.py | 1 + .../modular_nemotron_asr_streaming.py | 45 ++++++ .../models/nemotron_h/modular_nemotron_h.py | 4 + src/transformers/models/olmo/modular_olmo.py | 7 +- .../models/olmo2/modular_olmo2.py | 9 +- .../models/olmo3/modular_olmo3.py | 13 +- .../models/olmo_hybrid/modular_olmo_hybrid.py | 5 +- .../modular_openai_privacy_filter.py | 17 +++ .../models/ovis2/modular_ovis2.py | 1 + .../models/pe_audio/modular_pe_audio.py | 8 + .../pe_audio_video/modular_pe_audio_video.py | 2 + .../perception_lm/modular_perception_lm.py | 4 + src/transformers/models/phi/modular_phi.py | 2 + src/transformers/models/phi3/modular_phi3.py | 4 + .../models/phimoe/modular_phimoe.py | 20 +++ .../models/pixio/modular_pixio.py | 18 ++- .../models/plbart/modular_plbart.py | 4 + .../modular_pp_doclayout_v3.py | 4 + .../pp_formulanet/modular_pp_formulanet.py | 6 + .../models/pp_lcnet_v3/modular_pp_lcnet_v3.py | 4 +- .../models/pp_lcnet_v4/modular_pp_lcnet_v4.py | 11 +- .../modular_pp_ocrv5_mobile_det.py | 5 +- .../modular_pp_ocrv5_server_rec.py | 1 + .../modular_pp_ocrv6_medium_det.py | 4 +- .../modular_pp_ocrv6_small_det.py | 4 +- .../modular_pp_ocrv6_tiny_rec.py | 4 + .../modular_prompt_depth_anything.py | 21 ++- .../models/qianfan_ocr/modular_qianfan_ocr.py | 15 ++ .../models/qwen2/modular_qwen2.py | 16 +- .../models/qwen2_5_vl/modular_qwen2_5_vl.py | 51 ++++++- .../models/qwen2_moe/modular_qwen2_moe.py | 11 ++ .../models/qwen3_5/modular_qwen3_5.py | 17 ++- .../models/qwen3_5_moe/modular_qwen3_5_moe.py | 111 +++++++++++++- .../models/qwen3_moe/modular_qwen3_moe.py | 27 +++- .../models/qwen3_next/modular_qwen3_next.py | 5 + .../models/qwen3_vl/modular_qwen3_vl.py | 124 +++++++++++++++- .../models/qwen4_exp/modular_qwen4_exp.py | 56 ++++++- .../models/radio/modular_radio.py | 4 +- .../models/roberta/modular_roberta.py | 2 + src/transformers/models/sam2/modular_sam2.py | 11 +- .../modular_sam3_tracker_video.py | 22 +++ .../models/sapiens2/modular_sapiens2.py | 8 + .../models/seed_oss/modular_seed_oss.py | 12 +- src/transformers/models/sew/modular_sew.py | 9 +- .../models/slanet/modular_slanet.py | 4 + .../models/smollm3/modular_smollm3.py | 14 +- .../models/starcoder2/modular_starcoder2.py | 4 +- .../models/step3p7/modular_step3p7.py | 42 +++++- .../models/t5gemma2/modular_t5gemma2.py | 20 ++- .../models/tipsv2_dpt/modular_tipsv2_dpt.py | 8 +- .../models/ultrabert/modular_ultrabert.py | 35 ++++- .../models/ultravbert/modular_ultravbert.py | 138 +++++++++++++++++- .../models/unispeech/modular_unispeech.py | 9 +- .../unispeech_sat/modular_unispeech_sat.py | 18 ++- .../video_llama_3/modular_video_llama_3.py | 46 +++++- .../models/videoprism/modular_videoprism.py | 9 ++ .../models/vipllava/modular_vipllava.py | 9 ++ .../models/vit_msn/modular_vit_msn.py | 1 + .../modular_voxtral_realtime.py | 3 + .../wav2vec2_bert/modular_wav2vec2_bert.py | 6 + .../modular_wav2vec2_conformer.py | 7 + .../models/wavlm/modular_wavlm.py | 13 +- .../models/xcodec2/modular_xcodec2.py | 14 +- .../xlm_roberta_xl/modular_xlm_roberta_xl.py | 34 ++++- .../models/youtu/modular_youtu.py | 12 +- .../models/zamba2/modular_zamba2.py | 4 +- src/transformers/models/zaya/modular_zaya.py | 6 + utils/fix_modular_inherited_overrides.py | 53 ++++++- utils/modular_model_converter.py | 65 ++++++++- 186 files changed, 3296 insertions(+), 210 deletions(-) diff --git a/src/transformers/models/aimv2/modular_aimv2.py b/src/transformers/models/aimv2/modular_aimv2.py index a46e87b53e66..02728d50ecff 100644 --- a/src/transformers/models/aimv2/modular_aimv2.py +++ b/src/transformers/models/aimv2/modular_aimv2.py @@ -136,6 +136,10 @@ class Aimv2Config(SiglipConfig): projection_dim: int = 512 logit_scale_init_value: float = 2.6592 max_logit_scale: float = 100.0 + sub_configs_defaults = { + "vision_config": Aimv2VisionConfig, + "text_config": Aimv2TextConfig, + } class Aimv2Output(SiglipOutput): @@ -229,7 +233,9 @@ def forward( class Aimv2Encoder(SiglipEncoder): - pass + def __init__(self, config: Aimv2Config): + super().__init__(config) + self.layers = nn.ModuleList([Aimv2EncoderLayer(config) for _ in range(config.num_hidden_layers)]) class Aimv2AttentionPoolingHead(nn.Module): diff --git a/src/transformers/models/apertus/modular_apertus.py b/src/transformers/models/apertus/modular_apertus.py index 03ae896f8b07..332d3f6da5e3 100644 --- a/src/transformers/models/apertus/modular_apertus.py +++ b/src/transformers/models/apertus/modular_apertus.py @@ -189,6 +189,10 @@ def __init__(self, config: ApertusConfig, layer_idx: int): del self.input_layernorm del self.post_attention_layernorm + self.self_attn = ApertusAttention(config=config, layer_idx=layer_idx) + + self.mlp = ApertusMLP(config) + def forward( self, hidden_states: torch.Tensor, @@ -221,11 +225,18 @@ def forward( class ApertusPreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": ApertusDecoderLayer, + "attentions": ApertusAttention, + } class ApertusModel(LlamaModel): - pass + def __init__(self, config: ApertusConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [ApertusDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) class ApertusForCausalLM(LlamaForCausalLM): diff --git a/src/transformers/models/aria/modular_aria.py b/src/transformers/models/aria/modular_aria.py index 6003a518dae0..4c10024cb3f2 100644 --- a/src/transformers/models/aria/modular_aria.py +++ b/src/transformers/models/aria/modular_aria.py @@ -751,6 +751,10 @@ class AriaPreTrainedModel(LlamaPreTrainedModel): _can_compile_fullgraph = False # MoE models don't work with torch.compile (dynamic slicing) _supports_attention_backend = True input_modalities = ("image", "text") + _can_record_outputs = { + "hidden_states": AriaTextDecoderLayer, + "attentions": AriaTextAttention, + } @torch.no_grad() def _init_weights(self, module): @@ -767,6 +771,7 @@ def __init__(self, config: AriaTextConfig): ) self.gradient_checkpointing = False self.post_init() + self.norm = AriaTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) class AriaTextForCausalLM(AriaTextPreTrainedModel, DeepseekV2ForCausalLM): @@ -903,6 +908,10 @@ def forward( class AriaForConditionalGeneration(LlavaForConditionalGeneration): _tied_weights_keys = {"lm_head.weight": "model.language_model.embed_tokens.weight"} + def __init__(self, config: AriaConfig): + super().__init__(config) + self.model = AriaModel(config) + @auto_docstring def get_image_features( self, diff --git a/src/transformers/models/audioflamingo3/modular_audioflamingo3.py b/src/transformers/models/audioflamingo3/modular_audioflamingo3.py index f1a2e5d0107a..616cdd0ab608 100644 --- a/src/transformers/models/audioflamingo3/modular_audioflamingo3.py +++ b/src/transformers/models/audioflamingo3/modular_audioflamingo3.py @@ -188,6 +188,7 @@ class AudioFlamingo3Model(VoxtralModel): def __init__(self, config: AudioFlamingo3Config): super().__init__(config) + self.multi_modal_projector = AudioFlamingo3MultiModalProjector(config) @can_return_tuple @auto_docstring( diff --git a/src/transformers/models/axk1/modular_axk1.py b/src/transformers/models/axk1/modular_axk1.py index 76c301e7684b..d9e4e7bc1bb1 100644 --- a/src/transformers/models/axk1/modular_axk1.py +++ b/src/transformers/models/axk1/modular_axk1.py @@ -33,6 +33,7 @@ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import Unpack from ...utils import auto_docstring, logging +from ...utils.output_capturing import OutputRecorder from ..deepseek_v3.configuration_deepseek_v3 import DeepseekV3Config from ..deepseek_v3.modeling_deepseek_v3 import ( DeepseekV3Attention, @@ -242,11 +243,20 @@ def forward( class AXK1DecoderLayer(Glm4MoeLiteDecoderLayer): - pass + def __init__(self, config: AXK1Config, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = AXK1Attention(config, layer_idx) + + self.mlp = AXK1MoE(config) if config.mlp_layer_types[layer_idx] == "sparse" else AXK1MLP(config) class AXK1PreTrainedModel(DeepseekV3PreTrainedModel): _keys_to_ignore_on_load_unexpected = ["inv_freq"] + _can_record_outputs = { + "hidden_states": AXK1DecoderLayer, + "attentions": AXK1Attention, + "router_logits": OutputRecorder(AXK1TopkRouter, index=0), + } @torch.no_grad() def _init_weights(self, module): @@ -260,7 +270,11 @@ def _init_weights(self, module): class AXK1Model(DeepseekV3Model): - pass + def __init__(self, config: AXK1Config): + super().__init__(config) + self.layers = nn.ModuleList( + [AXK1DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) class AXK1ForCausalLM(DeepseekV3ForCausalLM): diff --git a/src/transformers/models/axk2/modular_axk2.py b/src/transformers/models/axk2/modular_axk2.py index d18dd84f4d7d..5aea07485e05 100644 --- a/src/transformers/models/axk2/modular_axk2.py +++ b/src/transformers/models/axk2/modular_axk2.py @@ -28,6 +28,7 @@ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import Unpack from ...utils import auto_docstring, logging +from ...utils.output_capturing import OutputRecorder from ..clip.modeling_clip import CLIPMLP from ..deepseek_v3.modeling_deepseek_v3 import ( DeepseekV3RMSNorm, @@ -261,7 +262,9 @@ class AXK2Experts(DeepseekV32Experts): class AXK2MoE(DeepseekV32MoE): - pass + def __init__(self, config: AXK2Config): + super().__init__(config) + self.gate = AXK2TopkRouter(config) class AXK2Attention(DeepseekV32Attention): @@ -407,10 +410,16 @@ def __init__(self, config: AXK2Config, layer_idx: int): if config.mlp_layer_types[layer_idx] == "sparse" else AXK2RMSNorm(config.hidden_size, eps=config.rms_norm_eps) ) + self.self_attn = AXK2Attention(config, layer_idx) class AXK2PreTrainedModel(DeepseekV32PreTrainedModel): _keys_to_ignore_on_load_unexpected = ["inv_freq"] + _can_record_outputs = { + "hidden_states": AXK2DecoderLayer, + "attentions": AXK2Attention, + "router_logits": OutputRecorder(AXK2TopkRouter, index=0), + } @torch.no_grad() def _init_weights(self, module): @@ -424,7 +433,11 @@ def _init_weights(self, module): class AXK2Model(DeepseekV32Model): - pass + def __init__(self, config: AXK2Config): + super().__init__(config) + self.layers = nn.ModuleList( + [AXK2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) class AXK2ForCausalLM(DeepseekV32ForCausalLM): diff --git a/src/transformers/models/aya_vision/modular_aya_vision.py b/src/transformers/models/aya_vision/modular_aya_vision.py index 72cdb0c75199..c17c87f42b39 100644 --- a/src/transformers/models/aya_vision/modular_aya_vision.py +++ b/src/transformers/models/aya_vision/modular_aya_vision.py @@ -31,7 +31,6 @@ from ...utils import TransformersKwargs, auto_docstring, logging from ...utils.generic import can_return_tuple, merge_with_config_defaults from .configuration_aya_vision import AyaVisionConfig -from ..auto import AutoModel logger = logging.get_logger(__name__) @@ -100,6 +99,11 @@ class AyaVisionModelOutputWithPast(LlavaModelOutputWithPast): class AyaVisionModel(LlavaModel): + def __init__(self, config: AyaVisionConfig): + super().__init__(config) + + self.multi_modal_projector = AyaVisionMultiModalProjector(config) + # Unlike LLaVA, the model doesn't have to deal with Pixtral-style image states @merge_with_config_defaults @can_return_tuple @@ -200,16 +204,13 @@ def forward( attentions=outputs.attentions, image_hidden_states=image_features if mm_encoder_outputs.get("image") is not None else None, ) - def __init__(self, config: AyaVisionConfig): - super().__init__(config) - self.vision_tower = AutoModel.from_config(config.vision_config) - - self.multi_modal_projector = AyaVisionMultiModalProjector(config) - self.language_model = AutoModel.from_config(config.text_config) - self.post_init() class AyaVisionForConditionalGeneration(LlavaForConditionalGeneration): + def __init__(self, config: AyaVisionConfig): + super().__init__(config) + self.model = AyaVisionModel(config) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -273,11 +274,5 @@ def forward( **kwargs, ) - def __init__(self, config: AyaVisionConfig): - super().__init__(config) - self.model = AyaVisionModel(config) - self.lm_head = nn.Linear(config.text_config.hidden_size, config.text_config.vocab_size, bias=False) - self.post_init() - __all__ = ["AyaVisionForConditionalGeneration", "AyaVisionPreTrainedModel", "AyaVisionModel"] diff --git a/src/transformers/models/bailing_hybrid/modular_bailing_hybrid.py b/src/transformers/models/bailing_hybrid/modular_bailing_hybrid.py index e58f0fdcfebd..501dbc2d0091 100644 --- a/src/transformers/models/bailing_hybrid/modular_bailing_hybrid.py +++ b/src/transformers/models/bailing_hybrid/modular_bailing_hybrid.py @@ -402,7 +402,14 @@ class BailingHybridMoE(DeepseekV3MoE): class BailingHybridDecoderLayer(KimiLinearDecoderLayer): - pass + def __init__(self, config: BailingHybridConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = ( + # CODEPATH: TODO: remove this once the mlinter rule is relaxed + BailingHybridAttention(config, layer_idx) + if config.layer_types[layer_idx] == "full_attention" + else BailingHybridDeltaAttention(config, layer_idx) + ) @auto_docstring @@ -441,12 +448,22 @@ def _init_weights(self, module): @auto_docstring class BailingHybridModel(Qwen3NextModel): - pass + def __init__(self, config: BailingHybridConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [BailingHybridDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = BailingHybridRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = BailingHybridRotaryEmbedding(config=config) class BailingHybridForCausalLM(DeepseekV3ForCausalLM, GenerationMixin): _tied_weights_keys = {} + def __init__(self, config: BailingHybridConfig): + super().__init__(config) + self.model = BailingHybridModel(config) + __all__ = [ "BailingHybridConfig", diff --git a/src/transformers/models/bamba/modular_bamba.py b/src/transformers/models/bamba/modular_bamba.py index 4ae3cb144a36..ff745ef24264 100644 --- a/src/transformers/models/bamba/modular_bamba.py +++ b/src/transformers/models/bamba/modular_bamba.py @@ -18,6 +18,8 @@ # limitations under the License. """PyTorch Bamba model.""" +from collections.abc import Callable + import torch from torch import nn @@ -25,12 +27,12 @@ from ...cache_utils import Cache, DynamicCache from ...masking_utils import create_causal_mask, create_recurrent_attention_mask from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast -from ...modeling_utils import PreTrainedModel, slice_logits_to_keep +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel, slice_logits_to_keep from ...processing_utils import Unpack from ...utils import auto_docstring, can_return_tuple, logging from ...utils.generic import TransformersKwargs, merge_with_config_defaults, no_inherit_decorator from ...utils.output_capturing import capture_outputs -from ..jamba.modeling_jamba import JambaAttentionDecoderLayer +from ..jamba.modeling_jamba import JambaAttentionDecoderLayer, eager_attention_forward from ..llama.modeling_llama import ( LlamaAttention, LlamaForCausalLM, @@ -112,7 +114,45 @@ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1): @no_inherit_decorator class BambaAttention(LlamaAttention): - pass + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, + attention_mask: torch.Tensor | None = None, + past_key_values: Cache | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) + key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights class BambaRMSNormGated(MambaRMSNormGated): @@ -356,6 +396,7 @@ def __init__(self, config: BambaConfig): # Initialize weights and apply final processing self.post_init() + self.model = BambaModel(config) @can_return_tuple @auto_docstring diff --git a/src/transformers/models/beam/modular_beam.py b/src/transformers/models/beam/modular_beam.py index 9a8171bcaa7b..0192589228ca 100644 --- a/src/transformers/models/beam/modular_beam.py +++ b/src/transformers/models/beam/modular_beam.py @@ -181,6 +181,8 @@ def __init__(self, config: BeamConfig, layer_idx: int): self.gate_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=False) # One gate bias per head, broadcast over `head_dim`. self.gate_bias = nn.Parameter(torch.zeros(config.num_attention_heads)) + self.q_norm = BeamRMSNorm(self.head_dim, eps=config.rms_norm_eps) # unlike olmo, only on the head dim! + self.k_norm = BeamRMSNorm(self.head_dim, eps=config.rms_norm_eps) # thus post q_norm does not need reshape def forward( self, @@ -288,6 +290,8 @@ class BeamMoE(Qwen3MoeSparseMoeBlock): def __init__(self, config: BeamConfig): super().__init__(config) self.routed_scaling_factor = config.routed_scaling_factor + self.experts = BeamExperts(config) + self.gate = BeamTopKRouter(config) def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: batch_size, sequence_length, hidden_dim = hidden_states.shape @@ -305,6 +309,9 @@ def __init__(self, config: BeamConfig, layer_idx: int): self.post_feedforward_layernorm = BeamRMSNorm(config.hidden_size, config.rms_norm_eps) self.attn_residual_add_idx = 2 * (layer_idx + 1) self.mlp_residual_add_idx = self.attn_residual_add_idx + 1 + self.self_attn = BeamAttention(config, layer_idx) + + self.mlp = BeamMoE(config) if config.mlp_layer_types[layer_idx] == "sparse" else BeamMLP(config) def forward( self, @@ -372,6 +379,14 @@ def _init_weights(self, module): class BeamModel(Qwen3MoeModel): + def __init__(self, config: BeamConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [BeamDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = BeamRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = BeamRotaryEmbedding(config=config) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -441,6 +456,10 @@ def forward( class BeamForCausalLM(DeepseekV3ForCausalLM): + def __init__(self, config: BeamConfig): + super().__init__(config) + self.model = BeamModel(config) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/beit/modular_beit.py b/src/transformers/models/beit/modular_beit.py index 4e3b6f996434..ebfaf62c9ae1 100644 --- a/src/transformers/models/beit/modular_beit.py +++ b/src/transformers/models/beit/modular_beit.py @@ -223,6 +223,7 @@ def __init__(self, config: BeitConfig, drop_path_rate: float = 0.0): nn.Parameter(init_values * torch.ones(config.hidden_size), requires_grad=True) if init_values > 0 else 1.0 ) self.relative_position_bias = BeitRelativePositionBias(config) if config.use_relative_position_bias else None + self.attention = BeitAttention(config) def forward( self, @@ -271,6 +272,10 @@ class BeitPreTrainedModel(ViTPreTrainedModel): _keys_to_ignore_on_load_unexpected = [r".*relative_position_index.*"] _supports_flash_attn = False _supports_flex_attn = False + _can_record_outputs = { + "hidden_states": BeitLayer, + "attentions": BeitAttention, + } def _init_weights(self, module): """Initialize the weights""" diff --git a/src/transformers/models/bitnet/modular_bitnet.py b/src/transformers/models/bitnet/modular_bitnet.py index 7f3a248766b2..a20d2123ec1f 100644 --- a/src/transformers/models/bitnet/modular_bitnet.py +++ b/src/transformers/models/bitnet/modular_bitnet.py @@ -100,7 +100,12 @@ def forward( class BitNetDecoderLayer(LlamaDecoderLayer): - pass + def __init__(self, config: BitNetConfig, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = BitNetAttention(config=config, layer_idx=layer_idx) + + self.mlp = BitNetMLP(config) class BitNetModel(LlamaModel): diff --git a/src/transformers/models/canary/modular_canary.py b/src/transformers/models/canary/modular_canary.py index 76335990b5e2..d9f7990e6ed0 100644 --- a/src/transformers/models/canary/modular_canary.py +++ b/src/transformers/models/canary/modular_canary.py @@ -282,6 +282,7 @@ class CanaryForConditionalGeneration(CohereAsrForConditionalGeneration): def __init__(self, config: CanaryConfig): super().__init__(config) self.proj_out = nn.Linear(config.decoder_config.hidden_size, config.decoder_config.vocab_size, bias=True) + self.model = CanaryModel(config) __all__ = [ diff --git a/src/transformers/models/cohere/modular_cohere.py b/src/transformers/models/cohere/modular_cohere.py index e5a162b28394..c32f96ae5cd2 100644 --- a/src/transformers/models/cohere/modular_cohere.py +++ b/src/transformers/models/cohere/modular_cohere.py @@ -247,6 +247,7 @@ def __init__(self, config: CohereConfig): [CohereDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] ) self.norm = CohereLayerNorm(hidden_size=(config.hidden_size), eps=config.layer_norm_eps) + self.rotary_emb = CohereRotaryEmbedding(config=config) class CohereForCausalLM(LlamaForCausalLM): diff --git a/src/transformers/models/cohere2/modular_cohere2.py b/src/transformers/models/cohere2/modular_cohere2.py index 9fd81c926971..62521d016014 100644 --- a/src/transformers/models/cohere2/modular_cohere2.py +++ b/src/transformers/models/cohere2/modular_cohere2.py @@ -213,6 +213,7 @@ def forward( class Cohere2DecoderLayer(CohereDecoderLayer): def __init__(self, config: Cohere2Config, layer_idx: int): super().__init__(config, layer_idx) + self.self_attn = Cohere2Attention(config=config, layer_idx=layer_idx) def forward( self, @@ -252,6 +253,10 @@ def __init__(self, config: Cohere2Config): super().__init__(config) self.norm = Cohere2LayerNorm(hidden_size=(config.hidden_size), eps=config.layer_norm_eps) self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx) + self.layers = nn.ModuleList( + [Cohere2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = Cohere2RotaryEmbedding(config) def forward( self, @@ -312,7 +317,9 @@ def forward( class Cohere2ForCausalLM(CohereForCausalLM): - pass + def __init__(self, config: Cohere2Config): + super().__init__(config) + self.model = Cohere2Model(config) __all__ = ["Cohere2Config", "Cohere2ForCausalLM", "Cohere2Model", "Cohere2PreTrainedModel"] diff --git a/src/transformers/models/cohere2_moe/modular_cohere2_moe.py b/src/transformers/models/cohere2_moe/modular_cohere2_moe.py index 1c7b5d26a19e..ad1beab893a0 100644 --- a/src/transformers/models/cohere2_moe/modular_cohere2_moe.py +++ b/src/transformers/models/cohere2_moe/modular_cohere2_moe.py @@ -187,6 +187,7 @@ def __init__(self, config: Cohere2MoeConfig, layer_idx: int): if config.mlp_layer_types[layer_idx] == "dense" else Cohere2MoeSparseMoeBlock(config) ) + self.self_attn = Cohere2MoeAttention(config=config, layer_idx=layer_idx) class Cohere2MoeRotaryEmbedding(Cohere2RotaryEmbedding): @@ -219,6 +220,9 @@ def __init__(self, config: Cohere2MoeConfig): if config.rms_norm_eps is not None else Cohere2MoeLayerNorm(hidden_size=config.hidden_size, eps=config.layer_norm_eps) ) + self.layers = nn.ModuleList( + [Cohere2MoeDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) def forward( self, @@ -281,6 +285,10 @@ def forward( class Cohere2MoeForCausalLM(Cohere2ForCausalLM): _fsdp_plan = {"lm_head": "keep_full_weight"} + def __init__(self, config: Cohere2MoeConfig): + super().__init__(config) + self.model = Cohere2MoeModel(config) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/cohere2_vision/modular_cohere2_vision.py b/src/transformers/models/cohere2_vision/modular_cohere2_vision.py index 9ea41cdf8aef..f39869225d5a 100644 --- a/src/transformers/models/cohere2_vision/modular_cohere2_vision.py +++ b/src/transformers/models/cohere2_vision/modular_cohere2_vision.py @@ -18,6 +18,7 @@ import numpy as np import torch from torch import nn +from torchvision.transforms.v2 import functional as tvF from transformers.models.aya_vision.modeling_aya_vision import ( AyaVisionCausalLMOutputWithPast, @@ -29,6 +30,7 @@ from transformers.models.got_ocr2.image_processing_got_ocr2 import GotOcr2ImageProcessor from ...cache_utils import Cache +from ...image_utils import PILImageResampling, SizeDict from ...modeling_flash_attention_utils import FlashAttentionKwargs from ...modeling_outputs import BaseModelOutputWithPooling from ...modeling_utils import slice_logits_to_keep @@ -92,6 +94,11 @@ class Cohere2VisionPreTrainedModel(AyaVisionPreTrainedModel): class Cohere2VisionModel(AyaVisionModel): + def __init__(self, config: Cohere2VisionConfig): + super().__init__(config) + + self.multi_modal_projector = Cohere2VisionMultiModalProjector(config) + @can_return_tuple @auto_docstring( custom_intro="Obtains image last hidden states from the vision tower and apply multimodal projection." @@ -160,6 +167,10 @@ def forward( class Cohere2VisionForConditionalGeneration(AyaVisionForConditionalGeneration): + def __init__(self, config: Cohere2VisionConfig): + super().__init__(config) + self.model = Cohere2VisionModel(config) + @auto_docstring def get_image_features( self, pixel_values: torch.FloatTensor, **kwargs: Unpack[TransformersKwargs] @@ -327,6 +338,106 @@ class Cohere2VisionImageProcessor(GotOcr2ImageProcessor): patch_size = 16 valid_kwargs = Cohere2VisionImageProcessorKwargs + def crop_image_to_patches( + self, + images: "torch.Tensor", + min_patches: int, + max_patches: int, + use_thumbnail: bool = True, + patch_size: SizeDict | None = None, + resample: "PILImageResampling | tvF.InterpolationMode | int | None" = None, + ): + """ + Crop the images to patches and return a list of cropped images. + The number of patches and their grid arrangement are determined by the original image size, + the target patch size and the minimum and maximum number of patches. + The aspect ratio of the patches grid is chosen to be the closest to the original image aspect ratio. + + Args: + images (`torch.Tensor`): + The images to be cropped. + min_patches (`int`): + The minimum number of patches to be extracted from the image. + max_patches (`int`): + The maximum number of patches to be extracted from the image. + use_thumbnail (`bool`, *optional*, defaults to `True`): + Whether to add a thumbnail image to the list of cropped patches. + patch_size (`SizeDict`, *optional*): + The size of the output patches. + resample (`PILImageResampling | tvF.InterpolationMode | int | None`, *optional*): + Resampling filter to use when resizing. + """ + patch_size_height, patch_size_width = patch_size.height, patch_size.width + original_height, original_width = images.shape[-2:] + # find the closest aspect ratio to the target + num_columns, num_rows = get_optimal_tiled_canvas( + (original_height, original_width), (patch_size_height, patch_size_width), min_patches, max_patches + ) + + # calculate the target width and height + target_width = patch_size_width * num_columns + target_height = patch_size_height * num_rows + num_blocks = num_columns * num_rows + + # resize the image so that each patch is of patch_size + resized_image = self.resize(images, SizeDict(height=target_height, width=target_width), resample=resample) + # split the image into patches + processed_images = [] + for i in range(num_blocks): + column = i % num_columns + row = i // num_columns + box = ( + column * patch_size_width, + row * patch_size_height, + (column + 1) * patch_size_width, + (row + 1) * patch_size_height, + ) + # split the image + patch_image = resized_image[..., box[1] : box[3], box[0] : box[2]] + processed_images.append(patch_image) + + if use_thumbnail and len(processed_images) != 1: + thumbnail_img = self.resize(images, patch_size, resample=resample) + processed_images.append(thumbnail_img) + + processed_images = torch.stack(processed_images, dim=0).transpose(0, 1).contiguous() + + return processed_images + + def get_number_of_image_patches(self, height: int, width: int, images_kwargs: dict | None = None) -> int: + """ + A utility that returns number patches for a given image size. + + Args: + height (`int`): + Height of the input image. + width (`int`): + Width of the input image. + images_kwargs (`dict`, *optional*) + Any kwargs to override defaults of the image processor. + Returns: + `int`: Number of patches per image. + """ + images_kwargs = images_kwargs or {} + min_patches = images_kwargs.get("min_patches", self.min_patches) + max_patches = images_kwargs.get("max_patches", self.max_patches) + patch_size = images_kwargs.get("patch_size", self.size) + crop_to_patches = images_kwargs.get("crop_to_patches", self.crop_to_patches) + + num_patches = 1 + if crop_to_patches and max_patches > 1: + if isinstance(patch_size, dict): + patch_height, patch_width = patch_size["height"], patch_size["width"] + else: + patch_height, patch_width = patch_size.height, patch_size.width + num_columns, num_rows = get_optimal_tiled_canvas( + (height, width), (patch_height, patch_width), min_patches, max_patches + ) + if num_columns * num_rows > 1: + num_patches += num_columns * num_rows + + return num_patches + __all__ = [ "Cohere2VisionForConditionalGeneration", diff --git a/src/transformers/models/cohere_asr/modular_cohere_asr.py b/src/transformers/models/cohere_asr/modular_cohere_asr.py index ce220de11f21..9c4e7c14d932 100644 --- a/src/transformers/models/cohere_asr/modular_cohere_asr.py +++ b/src/transformers/models/cohere_asr/modular_cohere_asr.py @@ -267,6 +267,7 @@ def __init__(self, config: CohereAsrConfig): self.embedding_layernorm = nn.LayerNorm(config.hidden_size) self.proj = nn.Linear(config.encoder_config.hidden_size, config.hidden_size, bias=True) self.post_init() + self.layers = nn.ModuleList([CohereAsrDecoderLayer(config, idx) for idx in range(config.num_hidden_layers)]) def forward( self, @@ -348,6 +349,7 @@ class CohereAsrModel(MoonshineModel): def __init__(self, config: CohereAsrConfig): super().__init__(config) self.encoder = AutoModel.from_config(config.encoder_config) + self.decoder = CohereAsrDecoder(config) @can_return_tuple @auto_docstring @@ -427,6 +429,7 @@ def __init__(self, config: CohereAsrConfig): super().__init__(config) self.proj_out = nn.Linear(config.hidden_size, config.vocab_size, bias=True) self.post_init() + self.model = CohereAsrModel(config) @can_return_tuple @auto_docstring diff --git a/src/transformers/models/cohere_compass/modular_cohere_compass.py b/src/transformers/models/cohere_compass/modular_cohere_compass.py index 36d1a0317724..d4b5e4e4ca27 100644 --- a/src/transformers/models/cohere_compass/modular_cohere_compass.py +++ b/src/transformers/models/cohere_compass/modular_cohere_compass.py @@ -130,6 +130,10 @@ class CohereCompassConfig(Qwen3VLConfig): video_token_id: int = 255032 vision_start_token_id: int = 255028 vision_end_token_id: int = 255029 + sub_configs_defaults = { + "vision_config": CohereCompassVisionConfig, + "text_config": CohereCompassTextConfig, + } # Overwritten to show type as cohere_compass for internal compatibility @@ -300,6 +304,7 @@ def forward( class CohereCompassDecoderLayer(Cohere2DecoderLayer): def __init__(self, config: CohereCompassTextConfig, layer_idx: int): super().__init__(config, layer_idx) + self.self_attn = CohereCompassAttention(config=config, layer_idx=layer_idx) @auto_docstring diff --git a/src/transformers/models/conditional_detr/modular_conditional_detr.py b/src/transformers/models/conditional_detr/modular_conditional_detr.py index f04cc4ae26f3..c8c4595c7b9a 100644 --- a/src/transformers/models/conditional_detr/modular_conditional_detr.py +++ b/src/transformers/models/conditional_detr/modular_conditional_detr.py @@ -889,6 +889,7 @@ def __init__(self, config: ConditionalDetrConfig): # Initialize weights and apply final processing self.post_init() + self.decoder = ConditionalDetrDecoder(config) @auto_docstring @can_return_tuple @@ -1025,6 +1026,9 @@ def __init__(self, config: ConditionalDetrConfig): super().__init__(config) self.class_labels_classifier = nn.Linear(config.d_model, config.num_labels) + # CONDITIONAL_DETR encoder-decoder model + self.model = ConditionalDetrModel(config) + # taken from https://github.com/Atten4Vis/conditionalDETR/blob/master/models/conditional_detr.py def _set_aux_loss(self, outputs_class, outputs_coord): return [{"logits": a, "pred_boxes": b} for a, b in zip(outputs_class[:-1], outputs_coord[:-1])] @@ -1147,7 +1151,11 @@ def forward( class ConditionalDetrForSegmentation(DetrForSegmentation): - pass + def __init__(self, config: ConditionalDetrConfig): + super().__init__(config) + + # object detection model + self.conditional_detr = ConditionalDetrForObjectDetection(config) __all__ = [ diff --git a/src/transformers/models/cosmos3_edge/modular_cosmos3_edge.py b/src/transformers/models/cosmos3_edge/modular_cosmos3_edge.py index d17de33fb4ce..64ce27761a0e 100644 --- a/src/transformers/models/cosmos3_edge/modular_cosmos3_edge.py +++ b/src/transformers/models/cosmos3_edge/modular_cosmos3_edge.py @@ -568,6 +568,7 @@ def __init__(self, config: Cosmos3EdgeConfig): super().__init__(self) self.visual = Cosmos3EdgeVisionModel._from_config(config.vision_config) self.projector = Cosmos3EdgePatchMerger(config) + self.language_model = Cosmos3EdgeTextModel._from_config(config.text_config) def get_image_features( self, @@ -623,6 +624,10 @@ class Cosmos3EdgeForConditionalGeneration(Qwen2VLForConditionalGeneration, Cosmo _tied_weights_keys = {} accepts_loss_kwargs = False + def __init__(self, config: Cosmos3EdgeConfig): + super().__init__(config) + self.model = Cosmos3EdgeModel(config) + def _prepare_position_ids_for_generation(self, inputs_tensor, model_kwargs): # Qwen2-VL exposes four axes (text plus three visual axes). Edge's interleaved M-RoPE consumes the three # visual axes directly, so start from the common 2D text positions rather than Qwen2-VL's four-axis helper. @@ -834,6 +839,7 @@ class Cosmos3EdgeVideoProcessor(Glm4vVideoProcessor): num_frames = None max_duration = None max_image_size = None + valid_kwargs = Cosmos3EdgeVideoProcessorInitKwargs def __init__(self, **kwargs: Unpack[Cosmos3EdgeVideoProcessorInitKwargs]): if kwargs.get("temporal_patch_size", self.temporal_patch_size) != 1: diff --git a/src/transformers/models/cwm/modular_cwm.py b/src/transformers/models/cwm/modular_cwm.py index d38968bae114..9f7514e21f0f 100644 --- a/src/transformers/models/cwm/modular_cwm.py +++ b/src/transformers/models/cwm/modular_cwm.py @@ -109,7 +109,10 @@ def __init__(self, config: CwmConfig, layer_idx: int): class CwmPreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": CwmDecoderLayer, + "attentions": CwmAttention, + } class CwmModelOutputWithPast(BaseModelOutputWithPast): @@ -185,7 +188,9 @@ def forward( class CwmForCausalLM(LlamaForCausalLM): - pass + def __init__(self, config: CwmConfig): + super().__init__(config) + self.model = CwmModel(config) __all__ = [ diff --git a/src/transformers/models/data2vec/modular_data2vec_audio.py b/src/transformers/models/data2vec/modular_data2vec_audio.py index 53c184d20566..208a7ace56fb 100644 --- a/src/transformers/models/data2vec/modular_data2vec_audio.py +++ b/src/transformers/models/data2vec/modular_data2vec_audio.py @@ -128,7 +128,9 @@ class Data2VecAudioFeatureProjection(Wav2Vec2FeatureProjection): class Data2VecAudioEncoder(Wav2Vec2Encoder): - pass + def __init__(self, config): + super().__init__(config) + self.pos_conv_embed = Data2VecAudioPositionalConvEmbedding(config) class Data2VecAudioAdapter(Wav2Vec2Adapter): @@ -251,15 +253,22 @@ def forward(self, **super_kwargs): class Data2VecAudioForSequenceClassification(Wav2Vec2ForSequenceClassification): - pass + def __init__(self, config: Data2VecAudioConfig): + super().__init__(config) + self.data2vec_audio = Data2VecAudioModel(config) class Data2VecAudioForAudioFrameClassification(Wav2Vec2ForAudioFrameClassification): - pass + def __init__(self, config: Data2VecAudioConfig): + super().__init__(config) + self.data2vec_audio = Data2VecAudioModel(config) class Data2VecAudioForXVector(Wav2Vec2ForXVector): - pass + def __init__(self, config: Data2VecAudioConfig): + super().__init__(config) + + self.data2vec_audio = Data2VecAudioModel(config) __all__ = [ diff --git a/src/transformers/models/deepseek_v2/modular_deepseek_v2.py b/src/transformers/models/deepseek_v2/modular_deepseek_v2.py index c5b940242b56..cbce36b62d80 100644 --- a/src/transformers/models/deepseek_v2/modular_deepseek_v2.py +++ b/src/transformers/models/deepseek_v2/modular_deepseek_v2.py @@ -408,10 +408,20 @@ def _init_weights(self, module): class DeepseekV2Model(OlmoeModel): - pass + def __init__(self, config: DeepseekV2Config): + super().__init__(config) + self.layers = nn.ModuleList( + [DeepseekV2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = DeepseekV2RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = DeepseekV2RotaryEmbedding(config=config) class DeepseekV2ForCausalLM(LlamaForCausalLM): + def __init__(self, config: DeepseekV2Config): + super().__init__(config) + self.model = DeepseekV2Model(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/deepseek_v3/modular_deepseek_v3.py b/src/transformers/models/deepseek_v3/modular_deepseek_v3.py index 1bd72a52a592..b55144d8e160 100644 --- a/src/transformers/models/deepseek_v3/modular_deepseek_v3.py +++ b/src/transformers/models/deepseek_v3/modular_deepseek_v3.py @@ -132,6 +132,14 @@ class DeepseekV3MoE(DeepseekV2Moe): A mixed expert module containing shared experts. """ + def __init__(self, config: DeepseekV3Config): + super().__init__(config) + self.experts = DeepseekV3Experts(config) + self.gate = DeepseekV3TopkRouter(config) + self.shared_experts = DeepseekV3MLP( + config=config, intermediate_size=config.moe_intermediate_size * config.n_shared_experts + ) + class DeepseekV3Attention(DeepseekV2Attention): """Multi-headed Latent Attention (MLA) from Deepseek V2, with support for rope interleave.""" @@ -232,7 +240,12 @@ def _init_weights(self, module): class DeepseekV3Model(DeepseekV2Model): - pass + def __init__(self, config: DeepseekV3Config): + super().__init__(config) + self.layers = nn.ModuleList( + [DeepseekV3DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = DeepseekV3RotaryEmbedding(config=config) class DeepseekV3ForCausalLM(DeepseekV2ForCausalLM): diff --git a/src/transformers/models/deepseek_v4/modular_deepseek_v4.py b/src/transformers/models/deepseek_v4/modular_deepseek_v4.py index 8916807600c3..c8920292abe0 100644 --- a/src/transformers/models/deepseek_v4/modular_deepseek_v4.py +++ b/src/transformers/models/deepseek_v4/modular_deepseek_v4.py @@ -1187,6 +1187,7 @@ def __init__(self, config: DeepseekV4Config): self.rotary_emb = DeepseekV4RotaryEmbedding(config) self.hc_head = DeepseekV4HyperHead(config) self.post_init() + self.norm = DeepseekV4RMSNorm(config.hidden_size, eps=config.rms_norm_eps) @merge_with_config_defaults @capture_outputs @@ -1246,7 +1247,9 @@ def forward( class DeepseekV4ForCausalLM(MixtralForCausalLM): - pass + def __init__(self, config: DeepseekV4Config): + super().__init__(config) + self.model = DeepseekV4Model(config) __all__ = [ diff --git a/src/transformers/models/deepseek_vl/modular_deepseek_vl.py b/src/transformers/models/deepseek_vl/modular_deepseek_vl.py index bfb901793287..002faf755fa2 100644 --- a/src/transformers/models/deepseek_vl/modular_deepseek_vl.py +++ b/src/transformers/models/deepseek_vl/modular_deepseek_vl.py @@ -122,6 +122,10 @@ def __init__(self, config: DeepseekVLConfig): class DeepseekVLForConditionalGeneration(JanusForConditionalGeneration): output_modalities = ("text",) + def __init__(self, config: DeepseekVLConfig): + super().__init__(config) + self.model = DeepseekVLModel(config) + def prepare_embeddings_for_image_generation(self): raise AttributeError("Not needed for DeepseekVL") diff --git a/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py b/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py index bc150c8b042f..94dc8d860886 100644 --- a/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py +++ b/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py @@ -30,6 +30,7 @@ from ...image_utils import ( OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, + ImageInput, PILImageResampling, SizeDict, ) @@ -221,6 +222,7 @@ def __init__(self, config: DeepseekVLHybridConfig): self.high_res_vision_alpha = nn.Parameter(torch.zeros(1)) super().__init__(config) + self.aligner = DeepseekVLHybridAligner(config) def get_low_res_image_features(self, pixel_values: torch.FloatTensor, **kwargs: Unpack[TransformersKwargs]): return self.vision_model(pixel_values, return_dict=True, **kwargs) @@ -336,6 +338,10 @@ def forward( class DeepseekVLHybridForConditionalGeneration(DeepseekVLForConditionalGeneration): + def __init__(self, config: DeepseekVLHybridConfig): + super().__init__(config) + self.model = DeepseekVLHybridModel(config) + @can_return_tuple @auto_docstring(custom_args=DEEPSEEK_VL_COMMON_CUSTOM_ARGS) def forward( @@ -417,6 +423,7 @@ class DeepseekVLHybridImageProcessorPil(DeepseekVLImageProcessorPil): high_res_size = {"height": 1024, "width": 1024} high_res_resample = PILImageResampling.BICUBIC model_input_names = ["pixel_values", "high_res_pixel_values"] + valid_kwargs = DeepseekVLHybridImageProcessorKwargs def __init__(self, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]): PilBackend.__init__(self, **kwargs) @@ -521,6 +528,10 @@ def _preprocess( tensor_type=return_tensors, ) + @auto_docstring + def preprocess(self, images: ImageInput, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]) -> BatchFeature: + return super().preprocess(images, **kwargs) + class DeepseekVLHybridImageProcessor(DeepseekVLImageProcessor): high_res_image_mean = OPENAI_CLIP_MEAN @@ -528,6 +539,7 @@ class DeepseekVLHybridImageProcessor(DeepseekVLImageProcessor): high_res_size = {"height": 1024, "width": 1024} high_res_resample = PILImageResampling.BICUBIC model_input_names = ["pixel_values", "high_res_pixel_values"] + valid_kwargs = DeepseekVLHybridImageProcessorKwargs def __init__(self, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]): TorchvisionBackend.__init__(self, **kwargs) diff --git a/src/transformers/models/deformable_detr/modular_deformable_detr.py b/src/transformers/models/deformable_detr/modular_deformable_detr.py index cf6b1282074f..ca563b22c0c4 100644 --- a/src/transformers/models/deformable_detr/modular_deformable_detr.py +++ b/src/transformers/models/deformable_detr/modular_deformable_detr.py @@ -759,6 +759,10 @@ class DeformableDetrEncoder(DetrEncoder): "attentions": OutputRecorder(DeformableDetrMultiscaleDeformableAttention, layer_name="self_attn", index=1), } + def __init__(self, config: DeformableDetrConfig): + super().__init__(config) + self.layers = nn.ModuleList([DeformableDetrEncoderLayer(config) for _ in range(config.encoder_layers)]) + @merge_with_config_defaults @capture_outputs def forward( diff --git a/src/transformers/models/deit/modular_deit.py b/src/transformers/models/deit/modular_deit.py index ad4570c244a5..a3f4e15ee77b 100644 --- a/src/transformers/models/deit/modular_deit.py +++ b/src/transformers/models/deit/modular_deit.py @@ -145,7 +145,9 @@ def _init_weights(self, module: nn.Linear | nn.Conv2d | nn.LayerNorm) -> None: class DeiTModel(ViTModel): - pass + def __init__(self, config: DeiTConfig, add_pooling_layer: bool = True, use_mask_token: bool = False): + super().__init__(config, add_pooling_layer, use_mask_token) + self.embeddings = DeiTEmbeddings(config, use_mask_token=use_mask_token) class DeiTForMaskedImageModeling(ViTForMaskedImageModeling): diff --git a/src/transformers/models/diffllama/modular_diffllama.py b/src/transformers/models/diffllama/modular_diffllama.py index 3d8c8ff34acc..d743866f3806 100644 --- a/src/transformers/models/diffllama/modular_diffllama.py +++ b/src/transformers/models/diffllama/modular_diffllama.py @@ -170,8 +170,15 @@ def __init__(self, config: DiffLlamaConfig, layer_idx: int): self.self_attn = DiffLlamaAttention(config=config, layer_idx=layer_idx) + self.mlp = DiffLlamaMLP(config) + class DiffLlamaPreTrainedModel(LlamaPreTrainedModel): + _can_record_outputs = { + "hidden_states": DiffLlamaDecoderLayer, + "attentions": DiffLlamaAttention, + } + @torch.no_grad() def _init_weights(self, module): PreTrainedModel._init_weights(self, module) @@ -187,7 +194,9 @@ class DiffLlamaModel(LlamaModel): class DiffLlamaForCausalLM(GemmaForCausalLM): - pass + def __init__(self, config: DiffLlamaConfig): + super().__init__(config) + self.model = DiffLlamaModel(config) class DiffLlamaForSequenceClassification(LlamaForSequenceClassification): diff --git a/src/transformers/models/dinov2/modular_dinov2.py b/src/transformers/models/dinov2/modular_dinov2.py index a2cf436cd991..71cafef6badd 100644 --- a/src/transformers/models/dinov2/modular_dinov2.py +++ b/src/transformers/models/dinov2/modular_dinov2.py @@ -13,6 +13,8 @@ # limitations under the License. """PyTorch DINOv2 model.""" +from collections.abc import Callable + import torch from torch import nn @@ -22,6 +24,7 @@ from ...masking_utils import create_bidirectional_mask from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import BackboneOutput, BaseModelOutput, BaseModelOutputWithPooling, ImageClassifierOutput +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, torch_int from ...utils.generic import can_return_tuple, merge_with_config_defaults @@ -63,6 +66,7 @@ def __init__(self, config: Dinov2Config) -> None: torch.randn(1, self.patch_embeddings.num_patches + 1, config.hidden_size) ) self.config = config + self.patch_embeddings = Dinov2PatchEmbeddings(config) def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor: """ @@ -104,7 +108,38 @@ def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: class Dinov2Attention(ViTAttention): - pass + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) + key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + + return attn_output, attn_weights class Dinov2LayerScale(nn.Module): @@ -178,10 +213,21 @@ def forward( @auto_docstring class Dinov2PreTrainedModel(ViTPreTrainedModel): config: Dinov2Config + _can_record_outputs = { + "hidden_states": Dinov2Layer, + "attentions": Dinov2Attention, + } @torch.no_grad() def _init_weights(self, module) -> None: + """Initialize the weights""" super()._init_weights(module) + if isinstance(module, Dinov2Embeddings): + if module.position_embeddings is not None: + init.trunc_normal_(module.position_embeddings, mean=0.0, std=self.config.initializer_range) + init.trunc_normal_(module.cls_token, mean=0.0, std=self.config.initializer_range) + if module.mask_token is not None: + init.zeros_(module.mask_token) if isinstance(module, (nn.Linear, nn.Conv2d)): init.trunc_normal_(module.weight, mean=0.0, std=self.config.initializer_range) if module.bias is not None: diff --git a/src/transformers/models/dinov2_with_registers/modular_dinov2_with_registers.py b/src/transformers/models/dinov2_with_registers/modular_dinov2_with_registers.py index 0997bd47e2af..4ee4d4788023 100644 --- a/src/transformers/models/dinov2_with_registers/modular_dinov2_with_registers.py +++ b/src/transformers/models/dinov2_with_registers/modular_dinov2_with_registers.py @@ -204,7 +204,9 @@ class Dinov2WithRegistersEncoder(Dinov2Encoder): class Dinov2WithRegistersModel(Dinov2Model): - pass + def __init__(self, config: Dinov2WithRegistersConfig): + super().__init__(config) + self.embeddings = Dinov2WithRegistersEmbeddings(config) class Dinov2WithRegistersForImageClassification(Dinov2ForImageClassification): @@ -224,6 +226,7 @@ class Dinov2WithRegistersBackbone(Dinov2Backbone): def __init__(self, config: Dinov2WithRegistersConfig): super().__init__(config) self.num_register_tokens = config.num_register_tokens + self.embeddings = Dinov2WithRegistersEmbeddings(config) def forward( self, diff --git a/src/transformers/models/doge/modular_doge.py b/src/transformers/models/doge/modular_doge.py index 18f3b6d8146c..c610234e09e7 100644 --- a/src/transformers/models/doge/modular_doge.py +++ b/src/transformers/models/doge/modular_doge.py @@ -453,6 +453,12 @@ def _init_weights(self, module): class DogeModel(MixtralModel): + def __init__(self, config: DogeConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [DogeDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/dots1/modular_dots1.py b/src/transformers/models/dots1/modular_dots1.py index ea3a83ec51ed..4a328f5bede0 100644 --- a/src/transformers/models/dots1/modular_dots1.py +++ b/src/transformers/models/dots1/modular_dots1.py @@ -13,6 +13,7 @@ # limitations under the License. import torch from huggingface_hub.dataclasses import strict +from torch import nn from ...cache_utils import Cache, DynamicCache from ...configuration_utils import PreTrainedConfig @@ -21,6 +22,7 @@ from ...modeling_rope_utils import RopeParameters from ...processing_utils import Unpack from ...utils import auto_docstring, logging +from ...utils.output_capturing import OutputRecorder from ..deepseek_v3.modeling_deepseek_v3 import ( DeepseekV3DecoderLayer, DeepseekV3ForCausalLM, @@ -169,14 +171,28 @@ class Dots1MoE(DeepseekV3MoE): class Dots1DecoderLayer(DeepseekV3DecoderLayer): - pass + def __init__(self, config: Dots1Config, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = Dots1Attention(config=config, layer_idx=layer_idx) class Dots1PreTrainedModel(DeepseekV3PreTrainedModel): _keys_to_ignore_on_load_unexpected = None + _can_record_outputs = { + "hidden_states": Dots1DecoderLayer, + "attentions": Dots1Attention, + "router_logits": OutputRecorder(Dots1TopkRouter, index=0), + } class Dots1Model(Qwen3Model): + def __init__(self, config: Dots1Config): + super().__init__(config) + self.layers = nn.ModuleList( + [Dots1DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -239,6 +255,10 @@ def forward( class Dots1ForCausalLM(DeepseekV3ForCausalLM): + def __init__(self, config: Dots1Config): + super().__init__(config) + self.model = Dots1Model(config) + def forward( self, **super_kwargs: Unpack[TransformersKwargs], diff --git a/src/transformers/models/dpt/modular_dpt.py b/src/transformers/models/dpt/modular_dpt.py index dc024ecf2e4c..1e1985e3500b 100644 --- a/src/transformers/models/dpt/modular_dpt.py +++ b/src/transformers/models/dpt/modular_dpt.py @@ -38,6 +38,9 @@ from torchvision.transforms.v2 import functional as tvF +from ...image_utils import ImageInput +from ...processing_utils import Unpack + def get_resize_output_image_size( input_image: "torch.Tensor", @@ -119,6 +122,9 @@ class DPTImageProcessor(BeitImageProcessor): valid_kwargs = DPTImageProcessorKwargs + def __init__(self, **kwargs: Unpack[DPTImageProcessorKwargs]): + super().__init__(**kwargs) + def resize( self, image: "torch.Tensor", @@ -286,5 +292,18 @@ def post_process_depth_estimation( return results + @auto_docstring + def preprocess( + self, + images: ImageInput, + segmentation_maps: ImageInput | None = None, + **kwargs: Unpack[DPTImageProcessorKwargs], + ) -> BatchFeature: + r""" + segmentation_maps (`ImageInput`, *optional*): + The segmentation maps to preprocess. + """ + return super().preprocess(images, segmentation_maps, **kwargs) + __all__ = ["DPTImageProcessor"] diff --git a/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py b/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py index 07d97a2d6bfd..68ff150e8170 100644 --- a/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py +++ b/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py @@ -24,13 +24,14 @@ from ...activations import ACT2FN from ...audio_utils import AudioInput, is_valid_audio from ...configuration_utils import PreTrainedConfig, SubConfigSpec +from ...image_processing_utils import BatchFeature from ...image_utils import ImageInput, make_nested_list_of_images from ...integrations import use_kernelized_func from ...masking_utils import create_bidirectional_mask, create_bidirectional_sliding_window_mask from ...modeling_flash_attention_utils import FlashAttentionKwargs from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel -from ...processing_utils import ProcessingKwargs, ProcessorMixin, Unpack +from ...processing_utils import MultiModalData, ProcessingKwargs, ProcessorMixin, Unpack from ...tokenization_utils_base import PreTokenizedInput, TextInput from ...utils import ( TransformersKwargs, @@ -372,6 +373,11 @@ def __init__(self, config: EmbeddingGemma2TextConfig, layer_idx: int): super().__init__(config, layer_idx) self.layer_scalar = nn.Buffer(torch.ones(1)) self.ple_block = EmbeddingGemma2TextPLEBlock(config) + self.self_attn = EmbeddingGemma2Attention(config=config, layer_idx=layer_idx) + self.input_layernorm = EmbeddingGemma2RMSNorm(self.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = EmbeddingGemma2RMSNorm(self.hidden_size, eps=config.rms_norm_eps) + self.pre_feedforward_layernorm = EmbeddingGemma2RMSNorm(self.hidden_size, eps=config.rms_norm_eps) + self.post_feedforward_layernorm = EmbeddingGemma2RMSNorm(self.hidden_size, eps=config.rms_norm_eps) def forward( self, @@ -466,6 +472,8 @@ def __init__(self, config: EmbeddingGemma2TextConfig): # Projecting per token is equivalent to projecting after mean pooling self.embedding_projection = nn.Linear(config.hidden_size, config.embedding_dim, bias=False) + self.norm = EmbeddingGemma2RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = EmbeddingGemma2RotaryEmbedding(config) def forward( self, @@ -574,6 +582,16 @@ def __init__(self, config: EmbeddingGemma2Config): # Drop inherited `vocab_size_per_layer_input` (no token-identity PLE in EmbeddingGemma 2) del self.vocab_size_per_layer_input self.post_init() + self.embed_vision = ( + EmbeddingGemma2MultimodalEmbedder(config.vision_config, config.text_config) + if config.vision_config is not None + else None + ) + self.embed_audio = ( + EmbeddingGemma2MultimodalEmbedder(config.audio_config, config.text_config) + if config.audio_config is not None + else None + ) @can_return_tuple @auto_docstring(custom_intro="Projects the last hidden state from the vision model into language model space.") @@ -782,6 +800,9 @@ class EmbeddingGemma2VideoProcessor(Gemma4VideoProcessor): valid_kwargs = EmbeddingGemma2VideoProcessorKwargs + def __init__(self, **kwargs: Unpack[EmbeddingGemma2VideoProcessorKwargs]): + super().__init__(**kwargs) + def sample_frames( self, metadata: VideoMetadata, @@ -839,6 +860,14 @@ def sample_frames( return indices + @auto_docstring + def preprocess( + self, + videos: VideoInput, + **kwargs: Unpack[EmbeddingGemma2VideoProcessorKwargs], + ) -> BatchFeature: + return super().preprocess(videos, **kwargs) + class EmbeddingGemma2ProcessorKwargs(Gemma4ProcessorKwargs): _defaults = { @@ -1011,6 +1040,88 @@ def replace_video_token(self, video_inputs: dict, video_idx: int, **kwargs) -> s [f"{t} {self.boi_token}{self.video_token * num_soft_tokens}{self.eoi_token}" for t in timestamp_str] ) + def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, audio_lengths=None, **kwargs): + """ + Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. + + Args: + image_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (height, width) per each image. + video_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (num_frames, height, width) per each video. + audio_lengths (`list[int]`, *optional*): + The lengths of audio inputs in number of samples. Used to dynamically + compute per-audio token counts. + + Returns: + `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided + input modalities, along with other useful data. + """ + + images_kwargs = EmbeddingGemma2ProcessorKwargs._defaults.get("images_kwargs", {}) + images_kwargs.update(kwargs) + patch_size = images_kwargs.get("patch_size", None) or self.image_processor.patch_size + pooling_kernel_size = ( + images_kwargs.get("pooling_kernel_size", None) or self.image_processor.pooling_kernel_size + ) + max_soft_tokens = images_kwargs.get("max_soft_tokens", None) or self.image_processor.max_soft_tokens + + max_patches = max_soft_tokens * pooling_kernel_size**2 + + vision_data = {} + if image_sizes is not None: + num_image_tokens = [] + for image_size in image_sizes: + target_h, target_w = get_aspect_ratio_preserving_size( + height=image_size[0], + width=image_size[1], + patch_size=patch_size, + max_patches=max_patches, + pooling_kernel_size=pooling_kernel_size, + ) + patch_height = target_h // patch_size + patch_width = target_w // patch_size + num_image_tokens.append(patch_height * patch_width // pooling_kernel_size**2) + + num_image_patches = [1] * len(image_sizes) + vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) + + if video_sizes is not None: + videos_kwargs = EmbeddingGemma2ProcessorKwargs._defaults.get("videos_kwargs", {}) + videos_kwargs.update(kwargs) + patch_size = videos_kwargs.get("patch_size", None) or self.video_processor.patch_size + pooling_kernel_size = ( + videos_kwargs.get("pooling_kernel_size", None) or self.video_processor.pooling_kernel_size + ) + max_soft_tokens = videos_kwargs.get("max_soft_tokens", None) or self.video_processor.max_soft_tokens + + max_patches = max_soft_tokens * pooling_kernel_size**2 + + num_video_tokens = [] + for num_frames, height, width in video_sizes: + target_h, target_w = get_aspect_ratio_preserving_size( + height=height, + width=width, + patch_size=patch_size, + max_patches=max_patches, + pooling_kernel_size=pooling_kernel_size, + ) + patch_height = target_h // patch_size + patch_width = target_w // patch_size + num_video_tokens.append(num_frames * (patch_height * patch_width // pooling_kernel_size**2)) + vision_data.update({"num_video_tokens": num_video_tokens}) + + if audio_lengths is not None: + # Dynamically compute per-audio token counts from sample lengths. + # audio_lengths are in number of samples; assume default sampling rate. + sampling_rate = getattr(self.feature_extractor, "sampling_rate", 16_000) + num_audio_tokens = [ + self._compute_audio_num_tokens(np.zeros(length), sampling_rate) for length in audio_lengths + ] + vision_data.update({"num_audio_tokens": num_audio_tokens}) + + return MultiModalData(**vision_data) + __all__ = [ "EmbeddingGemma2Config", diff --git a/src/transformers/models/eomt/modular_eomt.py b/src/transformers/models/eomt/modular_eomt.py index 24d54d05f590..efe3767ddacd 100644 --- a/src/transformers/models/eomt/modular_eomt.py +++ b/src/transformers/models/eomt/modular_eomt.py @@ -227,7 +227,9 @@ class EomtLayerScale(Dinov2LayerScale): class EomtLayer(Dinov2Layer): - pass + def __init__(self, config: EomtConfig) -> None: + super().__init__(config) + self.attention = EomtAttention(config) class EomtLayerNorm2d(nn.LayerNorm): diff --git a/src/transformers/models/ernie/modular_ernie.py b/src/transformers/models/ernie/modular_ernie.py index 5503c38f2854..e128037d7beb 100644 --- a/src/transformers/models/ernie/modular_ernie.py +++ b/src/transformers/models/ernie/modular_ernie.py @@ -277,6 +277,11 @@ class ErnieForPreTraining(BertForPreTraining): "cls.predictions.decoder.weight": "ernie.embeddings.word_embeddings.weight", } + def __init__(self, config: ErnieConfig): + super().__init__(config) + + self.ernie = ErnieModel(config) + @can_return_tuple @auto_docstring def forward( @@ -355,6 +360,11 @@ def forward( class ErnieForCausalLM(BertLMHeadModel): + def __init__(self, config: ErnieConfig): + super().__init__(config) + + self.ernie = ErnieModel(config, add_pooling_layer=False) + @can_return_tuple @auto_docstring def forward( @@ -426,6 +436,11 @@ class ErnieForMaskedLM(BertForMaskedLM): "cls.predictions.decoder.weight": "ernie.embeddings.word_embeddings.weight", } + def __init__(self, config: ErnieConfig): + super().__init__(config) + + self.ernie = ErnieModel(config, add_pooling_layer=False) + @can_return_tuple @auto_docstring def forward( @@ -478,6 +493,11 @@ def forward( class ErnieForNextSentencePrediction(BertForNextSentencePrediction): + def __init__(self, config: ErnieConfig): + super().__init__(config) + + self.ernie = ErnieModel(config) + @can_return_tuple @auto_docstring def forward( @@ -552,6 +572,11 @@ def forward( class ErnieForSequenceClassification(BertForSequenceClassification): + def __init__(self, config: ErnieConfig): + super().__init__(config) + + self.ernie = ErnieModel(config) + @can_return_tuple @auto_docstring def forward( @@ -620,6 +645,11 @@ def forward( class ErnieForMultipleChoice(BertForMultipleChoice): + def __init__(self, config: ErnieConfig): + super().__init__(config) + + self.ernie = ErnieModel(config) + @can_return_tuple @auto_docstring def forward( @@ -707,6 +737,11 @@ def forward( class ErnieForTokenClassification(BertForTokenClassification): + def __init__(self, config: ErnieConfig): + super().__init__(config) + + self.ernie = ErnieModel(config, add_pooling_layer=False) + @can_return_tuple @auto_docstring def forward( @@ -757,6 +792,11 @@ def forward( class ErnieForQuestionAnswering(BertForQuestionAnswering): + def __init__(self, config: ErnieConfig): + super().__init__(config) + + self.ernie = ErnieModel(config, add_pooling_layer=False) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/ernie4_5/modular_ernie4_5.py b/src/transformers/models/ernie4_5/modular_ernie4_5.py index a02ed12ec434..c6ed5bf1b819 100644 --- a/src/transformers/models/ernie4_5/modular_ernie4_5.py +++ b/src/transformers/models/ernie4_5/modular_ernie4_5.py @@ -13,13 +13,18 @@ # limitations under the License. """PyTorch Ernie 4.5 model""" +from collections.abc import Callable + import torch from torch import nn +from ...cache_utils import Cache from ...modeling_rope_utils import dynamic_rope_update -from ...utils import auto_docstring, can_return_tuple +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple from ...utils.generic import no_inherit_decorator -from ..glm.modeling_glm import rotate_half +from ..glm.modeling_glm import eager_attention_forward, rotate_half from ..llama.modeling_llama import ( LlamaAttention, LlamaForCausalLM, @@ -97,6 +102,46 @@ def __init__(self, config: Ernie4_5Config, layer_idx: int): self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.use_bias) self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.use_bias) + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, + attention_mask: torch.Tensor | None = None, + past_key_values: Cache | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) + key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + class Ernie4_5ForCausalLM(LlamaForCausalLM): @can_return_tuple diff --git a/src/transformers/models/ernie4_5_moe/modular_ernie4_5_moe.py b/src/transformers/models/ernie4_5_moe/modular_ernie4_5_moe.py index 09cef9eae63c..ca30ee399b48 100644 --- a/src/transformers/models/ernie4_5_moe/modular_ernie4_5_moe.py +++ b/src/transformers/models/ernie4_5_moe/modular_ernie4_5_moe.py @@ -13,6 +13,8 @@ # limitations under the License. """PyTorch Ernie 4.5 MoE model.""" +from collections.abc import Callable + import torch import torch.nn.functional as F from torch import nn @@ -21,12 +23,17 @@ from ...cache_utils import Cache, DynamicCache from ...masking_utils import create_causal_mask from ...modeling_outputs import MoeModelOutputWithPast -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging from ...utils.generic import maybe_autocast, merge_with_config_defaults, no_inherit_decorator from ...utils.output_capturing import OutputRecorder, capture_outputs -from ..ernie4_5.modeling_ernie4_5 import Ernie4_5RotaryEmbedding, apply_rotary_pos_emb, rotate_half # noqa: F401 +from ..ernie4_5.modeling_ernie4_5 import ( # noqa: F401 + Ernie4_5RotaryEmbedding, + apply_rotary_pos_emb, + eager_attention_forward, + rotate_half, +) from ..llama.modeling_llama import LlamaAttention, LlamaRMSNorm from ..mixtral.modeling_mixtral import ( MixtralExperts, @@ -69,6 +76,46 @@ def __init__(self, config: Ernie4_5_MoeConfig, layer_idx: int): self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.use_bias) self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.use_bias) + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, + attention_mask: torch.Tensor | None = None, + past_key_values: Cache | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) + key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + class Ernie4_5_MoeStatics(nn.Module): """ diff --git a/src/transformers/models/esmc/modular_esmc.py b/src/transformers/models/esmc/modular_esmc.py index 99b6541aee88..0e0e7de563d5 100644 --- a/src/transformers/models/esmc/modular_esmc.py +++ b/src/transformers/models/esmc/modular_esmc.py @@ -198,6 +198,8 @@ def __init__(self, config: EsmcConfig, layer_idx: int | None = None): # ESM3 residual scaling to stabilise deep networks; every released checkpoint uses it. self.scaling_factor = math.sqrt(config.num_hidden_layers / 36) + self.self_attn = EsmcAttention(config=config, layer_idx=layer_idx) + def forward( self, hidden_states: torch.Tensor, diff --git a/src/transformers/models/evolla/modular_evolla.py b/src/transformers/models/evolla/modular_evolla.py index d49b5be36212..6c5e9864221b 100644 --- a/src/transformers/models/evolla/modular_evolla.py +++ b/src/transformers/models/evolla/modular_evolla.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from collections.abc import Callable from dataclasses import dataclass import torch @@ -27,7 +28,7 @@ CausalLMOutputWithPast, ModelOutput, ) -from ...modeling_utils import PreTrainedModel, slice_logits_to_keep +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel, slice_logits_to_keep from ...processing_utils import Unpack from ...utils import ( TransformersKwargs, @@ -48,6 +49,7 @@ EsmRotaryEmbedding, EsmSelfAttention, EsmSelfOutput, + apply_rotary_pos_emb, ) from ..llama.modeling_llama import ( LlamaAttention, @@ -115,7 +117,53 @@ def compute_default_rope_parameters(config: SaProtConfig, device=None, **kwargs) class EvollaSaProtSelfAttention(EsmSelfAttention): - pass + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.FloatTensor | None = None, + encoder_hidden_states: torch.FloatTensor | None = None, + encoder_attention_mask: torch.FloatTensor | None = None, + position_embeddings: torch.Tensor | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.attention_head_size) + + query_layer = self.query(hidden_states).view(hidden_shape).transpose(1, 2) + + is_cross_attention = encoder_hidden_states is not None + current_states = encoder_hidden_states if is_cross_attention else hidden_states + attention_mask = encoder_attention_mask if is_cross_attention else attention_mask + key_layer = self.key(current_states).view(hidden_shape).transpose(1, 2) + value_layer = self.value(current_states).view(hidden_shape).transpose(1, 2) + + # Matt: Our BERT model (which this code was derived from) scales attention logits down by sqrt(head_dim). + # EVOLLA_SA_PROT scales the query down by the same factor instead. Modulo numerical stability these are equivalent, + # but not when rotary embeddings get involved. Therefore, we scale the query here to match the original + # EVOLLA_SA_PROT code and fix rotary embeddings. + query_layer = query_layer * self.attention_head_size**-0.5 + + if self.position_embedding_type == "rotary": + cos, sin = position_embeddings + query_layer, key_layer = apply_rotary_pos_emb(query_layer, key_layer, cos, sin, unsqueeze_dim=1) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + attn_output, attn_weights = attention_interface( + self, + query_layer, + key_layer, + value_layer, + attention_mask, + dropout=0.0 if not self.training else self.dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return attn_output, attn_weights class EvollaSaProtSelfOutput(EsmSelfOutput): @@ -621,7 +669,45 @@ class EvollaMLP(LlamaMLP): class EvollaAttention(LlamaAttention): - pass + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, + attention_mask: torch.Tensor | None = None, + past_key_values: Cache | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) + key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights class EvollaDecoderLayer(LlamaDecoderLayer): @@ -697,6 +783,10 @@ class EvollaPreTrainedModel(LlamaPreTrainedModel): "EvollaSequenceCompressorResampler", "EvollaSequenceAlignerCrossAttention", ] + _can_record_outputs = { + "hidden_states": EvollaDecoderLayer, + "attentions": EvollaAttention, + } @torch.no_grad() def _init_weights(self, module): diff --git a/src/transformers/models/exaone4/modular_exaone4.py b/src/transformers/models/exaone4/modular_exaone4.py index 577e36e6cc56..da0975bf6750 100644 --- a/src/transformers/models/exaone4/modular_exaone4.py +++ b/src/transformers/models/exaone4/modular_exaone4.py @@ -227,12 +227,20 @@ class Exaone4MLP(Olmo2MLP): class Exaone4DecoderLayer(Olmo2DecoderLayer): - pass + def __init__(self, config: Exaone4Config, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = Exaone4Attention(config=config, layer_idx=layer_idx) + self.post_attention_layernorm = Exaone4RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_feedforward_layernorm = Exaone4RMSNorm(config.hidden_size, eps=config.rms_norm_eps) class Exaone4PreTrainedModel(LlamaPreTrainedModel): config: Exaone4Config _no_split_modules = ["Exaone4DecoderLayer"] + _can_record_outputs = { + "hidden_states": Exaone4DecoderLayer, + "attentions": Exaone4Attention, + } class Exaone4Model(Exaone4PreTrainedModel, LlamaModel): @@ -313,6 +321,10 @@ def forward( class Exaone4ForCausalLM(LlamaForCausalLM): + def __init__(self, config: Exaone4Config): + super().__init__(config) + self.model = Exaone4Model(config) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/exaone4_5/modular_exaone4_5.py b/src/transformers/models/exaone4_5/modular_exaone4_5.py index c727d40af28d..0061900d9bb0 100644 --- a/src/transformers/models/exaone4_5/modular_exaone4_5.py +++ b/src/transformers/models/exaone4_5/modular_exaone4_5.py @@ -24,7 +24,7 @@ from ...configuration_utils import PreTrainedConfig, SubConfigSpec from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling, CausalLMOutputWithPast from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, slice_logits_to_keep -from ...processing_utils import ProcessingKwargs, Unpack +from ...processing_utils import MultiModalData, ProcessingKwargs, Unpack from ...utils import TransformersKwargs, auto_docstring from ...utils.generic import get_max_seqlen, is_flash_attention_requested from ..auto import AutoConfig, AutoModel @@ -189,7 +189,9 @@ class Exaone4_5_MLP(Qwen2_5_VLMLP): class Exaone4_5_VisionBlock(Qwen2_5_VLVisionBlock): - pass + def __init__(self, config, attn_implementation: str = "sdpa") -> None: + super().__init__(config, attn_implementation) + self.attn = Exaone4_5_VisionAttention(config=config) class Exaone4_5_PreTrainedModel(Exaone4PreTrainedModel): @@ -200,6 +202,10 @@ class Exaone4_5_PreTrainedModel(Exaone4PreTrainedModel): class Exaone4_5_VisionModel(Exaone4_5_PreTrainedModel, Qwen2_5_VisionTransformerPretrainedModel): config: Exaone4_5_VisionConfig + _can_record_outputs = { + "hidden_states": Exaone4_5_VisionBlock, + "attentions": Exaone4_5_VisionAttention, + } def __init__(self, config: Exaone4_5_VisionConfig, *inputs, **kwargs): super().__init__(config, *inputs, **kwargs) @@ -327,6 +333,10 @@ class Exaone4_5_ForConditionalGeneration(Exaone4_5_PreTrainedModel, Qwen2_5_VLFo input_modalities = ("image", "video", "text") + def __init__(self, config: Exaone4_5_Config): + super().__init__(config) + self.model = Exaone4_5_Model(config) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -424,10 +434,50 @@ class Exaone4_5_ProcessorKwargs(ProcessingKwargs, total=False): class Exaone4_5_Processor(Qwen2VLProcessor): + valid_processor_kwargs = Exaone4_5_ProcessorKwargs + @property def model_input_names(self): return super().model_input_names + def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): + """ + Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. + Args: + image_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (height, width) per each image. + video_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (num_frames, height, width) per each video. + Returns: + `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided + input modalities, along with other useful data. + """ + + vision_data = {} + if image_sizes is not None: + images_kwargs = Exaone4_5_ProcessorKwargs._defaults.get("images_kwargs", {}) + images_kwargs.update(kwargs) + merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size + + num_image_patches = [ + self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) + for image_size in image_sizes + ] + num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] + vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) + + if video_sizes is not None: + videos_kwargs = Exaone4_5_ProcessorKwargs._defaults.get("videos_kwargs", {}) + videos_kwargs.update(kwargs) + merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size + num_video_patches = [ + self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes + ] + num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] + vision_data["num_video_tokens"] = num_video_tokens + + return MultiModalData(**vision_data) + __all__ = [ "Exaone4_5_Config", diff --git a/src/transformers/models/exaone_moe/modular_exaone_moe.py b/src/transformers/models/exaone_moe/modular_exaone_moe.py index 523c5065f0db..be362edef9f5 100644 --- a/src/transformers/models/exaone_moe/modular_exaone_moe.py +++ b/src/transformers/models/exaone_moe/modular_exaone_moe.py @@ -16,6 +16,7 @@ import torch from huggingface_hub.dataclasses import strict +from torch import nn from ... import initialization as init from ...modeling_outputs import MoeCausalLMOutputWithPast @@ -167,6 +168,7 @@ def __init__(self, config): self.shared_experts = ExaoneMoeMLP( config=config, intermediate_size=config.moe_intermediate_size * config.num_shared_experts ) + self.gate = ExaoneMoeTopkRouter(config) class ExaoneMoeDecoderLayer(OlmoeDecoderLayer): @@ -175,6 +177,7 @@ def __init__(self, config: ExaoneMoeConfig, layer_idx: int): self.mlp = ( ExaoneMoeSparseMoEBlock(config) if config.mlp_layer_types[layer_idx] == "sparse" else ExaoneMoeMLP(config) ) + self.self_attn = ExaoneMoeAttention(config=config, layer_idx=layer_idx) class ExaoneMoePreTrainedModel(Exaone4PreTrainedModel): @@ -201,10 +204,18 @@ def _init_weights(self, module): class ExaoneMoeModel(Dots1Model): - pass + def __init__(self, config: ExaoneMoeConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [ExaoneMoeDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) class ExaoneMoeForCausalLM(DeepseekV3ForCausalLM): + def __init__(self, config: ExaoneMoeConfig): + super().__init__(config) + self.model = ExaoneMoeModel(config) + def forward( self, **super_kwargs: Unpack[TransformersKwargs], diff --git a/src/transformers/models/falcon_h1/modular_falcon_h1.py b/src/transformers/models/falcon_h1/modular_falcon_h1.py index bc321b2bfa09..13efc01ecd96 100644 --- a/src/transformers/models/falcon_h1/modular_falcon_h1.py +++ b/src/transformers/models/falcon_h1/modular_falcon_h1.py @@ -597,6 +597,10 @@ def forward( class FalconH1ForCausalLM(LlamaForCausalLM): + def __init__(self, config: FalconH1Config): + super().__init__(config) + self.model = FalconH1Model(config) + @staticmethod def create_masks_for_generate(config, inputs_embeds, attention_mask, past_key_values, position_ids=None, **_): # Every FalconH1 decoder layer is hybrid (attention + mamba in the same block), so the layer-type diff --git a/src/transformers/models/fast_vlm/modular_fast_vlm.py b/src/transformers/models/fast_vlm/modular_fast_vlm.py index 1a1561111590..031ccbd549b2 100644 --- a/src/transformers/models/fast_vlm/modular_fast_vlm.py +++ b/src/transformers/models/fast_vlm/modular_fast_vlm.py @@ -132,6 +132,8 @@ class FastVlmModel(LlavaModel): def __init__(self, config: FastVlmConfig): super().__init__(config) + self.multi_modal_projector = FastVlmMultiModalProjector(config) + @merge_with_config_defaults @can_return_tuple @auto_docstring( @@ -236,6 +238,10 @@ class FastVlmCausalLMOutputWithPast(LlavaCausalLMOutputWithPast): """ ) class FastVlmForConditionalGeneration(LlavaForConditionalGeneration): + def __init__(self, config: FastVlmConfig): + super().__init__(config) + self.model = FastVlmModel(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/florence2/modular_florence2.py b/src/transformers/models/florence2/modular_florence2.py index 46f7c6d34717..620fb7f3b781 100644 --- a/src/transformers/models/florence2/modular_florence2.py +++ b/src/transformers/models/florence2/modular_florence2.py @@ -1363,6 +1363,8 @@ def __init__(self, config: Florence2Config): super().__init__(config) self.vision_tower = Florence2VisionBackbone(config=config.vision_config) + self.multi_modal_projector = Florence2MultiModalProjector(config) + def get_encoder(self, modality=None): if modality is None: return self.language_model.get_encoder() @@ -1461,6 +1463,10 @@ class Florence2ForConditionalGeneration(LlavaForConditionalGeneration): "lm_head.weight": "model.language_model.shared.weight", } + def __init__(self, config: Florence2Config): + super().__init__(config) + self.model = Florence2Model(config) + @auto_docstring def get_image_features( self, pixel_values: torch.Tensor, **kwargs: Unpack[TransformersKwargs] diff --git a/src/transformers/models/fun_asr_nano/modular_fun_asr_nano.py b/src/transformers/models/fun_asr_nano/modular_fun_asr_nano.py index 323885340c7f..40c4ec544371 100644 --- a/src/transformers/models/fun_asr_nano/modular_fun_asr_nano.py +++ b/src/transformers/models/fun_asr_nano/modular_fun_asr_nano.py @@ -29,6 +29,7 @@ from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import ProcessingKwargs, Unpack, prepare_keyword_inputs, prepare_prompt_input +from ...tokenization_utils_base import TextInput from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, is_torch_available, logging from ...utils.generic import merge_with_config_defaults, no_inherit_decorator from ...utils.output_capturing import capture_outputs @@ -185,6 +186,38 @@ def decode(self, *args, strip_prefix=False, **kwargs): def batch_decode(self, *args, **kwargs): raise AttributeError("Not needed") + @auto_docstring + def __call__( + self, + text: TextInput | list[TextInput], + audio: AudioInput | None = None, + output_labels: bool | None = False, + **kwargs: Unpack[FunAsrNanoProcessorKwargs], + ) -> BatchFeature: + r""" + output_labels (bool, *optional*, default=False): + Whether to return labels for training. + + Returns: + [`BatchFeature`]: A dictionary with tokenized text (`input_ids`, `attention_mask`) and + audio features (`input_features`, `input_features_mask`). + """ + # Check only if passed explicitly as another value since by default we'll use `pt` + if "return_tensors" in kwargs and kwargs["return_tensors"] != "pt": + raise ValueError(f"{self.__class__.__name__} only supports `return_tensors='pt'`.") + + if output_labels: + kwargs["return_mm_token_type_ids"] = True + model_inputs = super().__call__(audio=audio, text=text, **kwargs) + + if output_labels: + mm_token_type_ids = model_inputs.pop("mm_token_type_ids") + labels = model_inputs["input_ids"].clone() + labels[mm_token_type_ids != 0] = -100 # audio positions + labels[labels == self.tokenizer.pad_token_id] = -100 + model_inputs["labels"] = labels + return BatchFeature(data=model_inputs, tensor_type="pt") + @auto_docstring class FunAsrNanoPreTrainedModel(AudioFlamingo3PreTrainedModel): @@ -324,6 +357,8 @@ def __init__( nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) if add_norm else nn.Identity() ) + self.mlp = FunAsrNanoMLP(config) + def forward( self, hidden_states: torch.Tensor, @@ -460,6 +495,10 @@ def forward( """ ) class FunAsrNanoModel(AudioFlamingo3Model): + def __init__(self, config: FunAsrNanoConfig): + super().__init__(config) + self.multi_modal_projector = FunAsrNanoMultiModalProjector(config) + @can_return_tuple @auto_docstring( custom_intro="This method is used to get the audio embeddings from input features, meaning inferring the audio encoder and the adaptor." @@ -507,6 +546,10 @@ def get_audio_features( """ ) class FunAsrNanoForConditionalGeneration(Qwen3ASRForConditionalGeneration): + def __init__(self, config: FunAsrNanoConfig): + super().__init__(config) + self.model = FunAsrNanoModel(config) + def forward(self, **super_kwargs): r""" input_features_mask (`torch.Tensor` of shape `(batch_size, feature_sequence_length)`): diff --git a/src/transformers/models/gemma2/modular_gemma2.py b/src/transformers/models/gemma2/modular_gemma2.py index 7f72d6cb8370..9510af27cdb3 100644 --- a/src/transformers/models/gemma2/modular_gemma2.py +++ b/src/transformers/models/gemma2/modular_gemma2.py @@ -309,6 +309,10 @@ def forward( class Gemma2PreTrainedModel(GemmaPreTrainedModel): _supports_sdpa = False # sdpa does not support softcapping + _can_record_outputs = { + "hidden_states": Gemma2DecoderLayer, + "attentions": Gemma2Attention, + } class Gemma2Model(GemmaModel): diff --git a/src/transformers/models/gemma3/modular_gemma3.py b/src/transformers/models/gemma3/modular_gemma3.py index 8af2e09748d6..024cd624fad5 100644 --- a/src/transformers/models/gemma3/modular_gemma3.py +++ b/src/transformers/models/gemma3/modular_gemma3.py @@ -421,6 +421,10 @@ class Gemma3PreTrainedModel(Gemma2PreTrainedModel): input_modalities = ("image", "text") _no_split_modules = ["Gemma3DecoderLayer"] _supports_sdpa = True + _can_record_outputs = { + "hidden_states": Gemma3DecoderLayer, + "attentions": Gemma3Attention, + } @torch.no_grad() def _init_weights(self, module): @@ -466,6 +470,10 @@ def __init__(self, config: Gemma3TextConfig): self.embed_tokens = Gemma3TextScaledWordEmbedding( config.vocab_size, config.hidden_size, self.padding_idx, embed_scale=self.config.hidden_size**0.5 ) + self.layers = nn.ModuleList( + [Gemma3DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = Gemma3RotaryEmbedding(config) def forward( self, @@ -659,6 +667,7 @@ class Gemma3Model(PaliGemmaModel): def __init__(self, config: Gemma3Config): super().__init__(config) del self.text_config_dtype + self.multi_modal_projector = Gemma3MultiModalProjector(config) @can_return_tuple @auto_docstring(custom_intro="Projects the last hidden state from the vision model into language model space.") @@ -755,6 +764,10 @@ def forward( class Gemma3ForConditionalGeneration(PaliGemmaForConditionalGeneration): + def __init__(self, config: Gemma3Config): + super().__init__(config) + self.model = Gemma3Model(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/gemma3n/modular_gemma3n.py b/src/transformers/models/gemma3n/modular_gemma3n.py index ca38fe77dd2f..f0c73433543b 100644 --- a/src/transformers/models/gemma3n/modular_gemma3n.py +++ b/src/transformers/models/gemma3n/modular_gemma3n.py @@ -1994,7 +1994,9 @@ def forward( @auto_docstring(custom_intro="The base Gemma 3n language model with a language modeling head.") class Gemma3nForCausalLM(Gemma3ForCausalLM): - pass + def __init__(self, config: Gemma3nTextConfig): + super().__init__(config) + self.model = Gemma3nTextModel(config) class Gemma3nMultimodalEmbedder(nn.Module): @@ -2312,6 +2314,10 @@ def get_audio_features( class Gemma3nForConditionalGeneration(PaliGemmaForConditionalGeneration): accepts_loss_kwargs = False + def __init__(self, config: Gemma3nConfig): + super().__init__(config) + self.model = Gemma3nModel(config) + def get_per_layer_input_embeddings(self): return self.model.get_per_layer_input_embeddings() diff --git a/src/transformers/models/gemma4/modular_gemma4.py b/src/transformers/models/gemma4/modular_gemma4.py index 4a63e27e578e..6f3d6815bffa 100644 --- a/src/transformers/models/gemma4/modular_gemma4.py +++ b/src/transformers/models/gemma4/modular_gemma4.py @@ -885,6 +885,10 @@ def __init__(self, config: Gemma4VisionConfig, layer_idx: int): super().__init__(self, config, layer_idx) self.self_attn = Gemma4VisionAttention(config=config, layer_idx=layer_idx) self.mlp = Gemma4VisionMLP(config) + self.input_layernorm = Gemma4RMSNorm(self.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = Gemma4RMSNorm(self.hidden_size, eps=config.rms_norm_eps) + self.pre_feedforward_layernorm = Gemma4RMSNorm(self.hidden_size, eps=config.rms_norm_eps) + self.post_feedforward_layernorm = Gemma4RMSNorm(self.hidden_size, eps=config.rms_norm_eps) def forward( self, @@ -1533,6 +1537,10 @@ def forward( class Gemma4ForCausalLM(Gemma3ForCausalLM): base_model_prefix = "model" + def __init__(self, config: Gemma4TextConfig): + super().__init__(config) + self.model = Gemma4TextModel(config) + @can_return_tuple @auto_docstring def forward( @@ -2208,6 +2216,10 @@ def get_audio_features( class Gemma4ForConditionalGeneration(Gemma3nForConditionalGeneration): base_model_prefix = "model" + def __init__(self, config: Gemma4Config): + super().__init__(config) + self.model = Gemma4Model(config) + def get_per_layer_input_embeddings(self): return self.model.get_per_layer_input_embeddings() diff --git a/src/transformers/models/gemma4_unified/modular_gemma4_unified.py b/src/transformers/models/gemma4_unified/modular_gemma4_unified.py index 0c0819b435db..372ee451fee8 100644 --- a/src/transformers/models/gemma4_unified/modular_gemma4_unified.py +++ b/src/transformers/models/gemma4_unified/modular_gemma4_unified.py @@ -14,7 +14,7 @@ import math from collections import UserDict from dataclasses import dataclass -from typing import Literal +from typing import Any, Literal import torch from huggingface_hub.dataclasses import strict @@ -23,7 +23,7 @@ from ... import initialization as init from ...cache_utils import Cache, DynamicCache -from ...configuration_utils import PreTrainedConfig +from ...configuration_utils import PreTrainedConfig, SubConfigSpec from ...image_processing_utils import BatchFeature from ...image_utils import PILImageResampling from ...masking_utils import create_causal_mask, create_masks_for_generate, create_sliding_window_causal_mask @@ -524,7 +524,15 @@ def model_patch_size(self, value): @auto_docstring(checkpoint="google/gemma-4-12B-it") @strict class Gemma4UnifiedConfig(Gemma4Config): - pass + sub_configs_defaults = { + "text_config": Gemma4UnifiedTextConfig, + "vision_config": SubConfigSpec(config_class=Gemma4UnifiedVisionConfig, optional=True), + "audio_config": SubConfigSpec(config_class=Gemma4UnifiedAudioConfig, optional=True), + } + + text_config: Gemma4UnifiedTextConfig | dict[str, Any] | None = None + vision_config: Gemma4UnifiedVisionConfig | dict[str, Any] | None = None + audio_config: Gemma4UnifiedAudioConfig | dict[str, Any] | None = None @auto_docstring @@ -623,6 +631,11 @@ def __init__(self, config: Gemma4UnifiedTextConfig | Gemma4UnifiedVisionConfig, self.self_attn = Gemma4UnifiedTextAttention(config=config, layer_idx=layer_idx) self.mlp = Gemma4UnifiedTextMLP(config, layer_idx) self.layer_scalar = nn.Buffer(torch.ones(1)) + self.input_layernorm = Gemma4UnifiedRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = Gemma4UnifiedRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + self.pre_feedforward_layernorm = Gemma4UnifiedRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_feedforward_layernorm = Gemma4UnifiedRMSNorm(config.hidden_size, eps=config.rms_norm_eps) def forward( self, @@ -714,6 +727,10 @@ def __init__(self, config: Gemma4UnifiedTextConfig): ) self.norm = Gemma4UnifiedRMSNorm(config.hidden_size, eps=config.rms_norm_eps) self.unique_layer_types = set(self.config.layer_types) + self.layers = nn.ModuleList( + [Gemma4UnifiedTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = Gemma4UnifiedTextRotaryEmbedding(config=config) def forward( self, @@ -788,6 +805,10 @@ def forward( class Gemma4UnifiedForCausalLM(Gemma4ForCausalLM): + def __init__(self, config: Gemma4UnifiedTextConfig): + super().__init__(config) + self.model = Gemma4UnifiedTextModel(config) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -1230,6 +1251,10 @@ def forward( class Gemma4UnifiedForConditionalGeneration(Gemma4ForConditionalGeneration): + def __init__(self, config: Gemma4UnifiedConfig): + super().__init__(config) + self.model = Gemma4UnifiedModel(config) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/glm/modular_glm.py b/src/transformers/models/glm/modular_glm.py index 26bc5f967b48..daa736120abb 100644 --- a/src/transformers/models/glm/modular_glm.py +++ b/src/transformers/models/glm/modular_glm.py @@ -13,10 +13,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +from collections.abc import Callable + import torch import torch.nn as nn -from ...utils import logging +from ...cache_utils import Cache +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, logging from ...utils.generic import no_inherit_decorator from ..llama.modeling_llama import ( LlamaAttention, @@ -24,6 +29,7 @@ LlamaForSequenceClassification, LlamaForTokenClassification, LlamaRotaryEmbedding, + eager_attention_forward, ) from ..phi3.modeling_phi3 import Phi3MLP from .configuration_glm import GlmConfig @@ -113,6 +119,46 @@ def __init__(self, config: GlmConfig, layer_idx: int | None = None): super().__init__(config, layer_idx) self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=False) + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, + attention_mask: torch.Tensor | None = None, + past_key_values: Cache | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) + key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + class GlmForCausalLM(LlamaForCausalLM): pass diff --git a/src/transformers/models/glm46v/modular_glm46v.py b/src/transformers/models/glm46v/modular_glm46v.py index b06240de964d..f35a8c2844b5 100644 --- a/src/transformers/models/glm46v/modular_glm46v.py +++ b/src/transformers/models/glm46v/modular_glm46v.py @@ -85,7 +85,9 @@ def __init__(self, config: Glm46VConfig): class Glm46VForConditionalGeneration(Glm4vForConditionalGeneration): - pass + def __init__(self, config: Glm46VConfig): + super().__init__(config) + self.model = Glm46VModel(config) class Glm46VProcessor(Glm4vProcessor): diff --git a/src/transformers/models/glm4v/modular_glm4v.py b/src/transformers/models/glm4v/modular_glm4v.py index 76a4acf8a21c..422d426fe99f 100644 --- a/src/transformers/models/glm4v/modular_glm4v.py +++ b/src/transformers/models/glm4v/modular_glm4v.py @@ -30,14 +30,14 @@ from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling from ...modeling_rope_utils import RopeParameters from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, slice_logits_to_keep -from ...processing_utils import Unpack +from ...processing_utils import MultiModalData, Unpack from ...utils import ( TransformersKwargs, auto_docstring, logging, torch_compilable_check, ) -from ...utils.generic import merge_with_config_defaults +from ...utils.generic import get_max_seqlen, is_flash_attention_requested, merge_with_config_defaults from ...utils.output_capturing import capture_outputs from ...vision_utils import get_vision_attention_seqlens, get_vision_position_ids from ..glm4.modeling_glm4 import Glm4MLP, Glm4RMSNorm, eager_attention_forward @@ -53,6 +53,7 @@ Qwen2_5_VLVisionAttention, Qwen2_5_VLVisionBlock, Qwen2_5_VLVisionRotaryEmbedding, + apply_rotary_pos_emb_vision, ) from ..qwen2_vl.modeling_qwen2_vl import Qwen2VLModel from ..qwen2_vl.processing_qwen2_vl import ( @@ -346,6 +347,74 @@ def __init__(self, config: Glm4vVisionConfig) -> None: self.qkv = nn.Linear(config.hidden_size, config.hidden_size * 3, bias=config.attention_bias) self.proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False) + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, + max_seqlen: int | None = None, + **kwargs, + ) -> torch.Tensor: + seq_length = hidden_states.shape[0] + query_states, key_states, value_states = ( + self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0) + ) + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb_vision(query_states, key_states, cos, sin) + + query_states = query_states.transpose(0, 1).unsqueeze(0) + key_states = key_states.transpose(0, 1).unsqueeze(0) + value_states = value_states.transpose(0, 1).unsqueeze(0) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + if is_flash_attention_requested(self.config): + # Flash Attention: Use cu_seqlens for variable length attention + max_seqlen = get_max_seqlen(cu_seqlens, self.config, kwargs={"max_seqlen": max_seqlen}) + attn_output, _ = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + cu_seq_lens_q=cu_seqlens, + cu_seq_lens_k=cu_seqlens, + max_length_q=max_seqlen, + max_length_k=max_seqlen, + is_causal=False, + **kwargs, + ) + else: + # Other implementations: Process each chunk separately + lengths = cu_seqlens[1:] - cu_seqlens[:-1] + splits = [ + torch.split(tensor, lengths.tolist(), dim=2) for tensor in (query_states, key_states, value_states) + ] + + attn_outputs = [ + attention_interface( + self, + q, + k, + v, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + is_causal=False, + **kwargs, + )[0] + for q, k, v in zip(*splits) + ] + attn_output = torch.cat(attn_outputs, dim=1) + + attn_output = attn_output.reshape(seq_length, -1).contiguous() + attn_output = self.proj(attn_output) + return attn_output + class Glm4vVisionBlock(Qwen2_5_VLVisionBlock): def __init__(self, config) -> None: @@ -757,6 +826,7 @@ class Glm4vModel(Qwen2VLModel): def __init__(self, config: Glm4vConfig): super().__init__(config) self.visual = Glm4vVisionModel._from_config(config.vision_config) + self.language_model = Glm4vTextModel._from_config(config.text_config) def get_video_features( self, @@ -938,6 +1008,10 @@ class Glm4vCausalLMOutputWithPast(Qwen2_5_VLCausalLMOutputWithPast): class Glm4vForConditionalGeneration(Qwen2_5_VLForConditionalGeneration): + def __init__(self, config: Glm4vConfig): + super().__init__(config) + self.model = Glm4vModel(config) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -1090,6 +1164,8 @@ class Glm4vProcessorKwargs(Qwen2VLProcessorKwargs): class Glm4vProcessor(Qwen2VLProcessor): + valid_processor_kwargs = Glm4vProcessorKwargs + def __init__(self, image_processor=None, tokenizer=None, video_processor=None, chat_template=None, **kwargs): super().__init__(image_processor, tokenizer, video_processor, chat_template=chat_template) self.image_token = "<|image|>" if not hasattr(tokenizer, "image_token") else tokenizer.image_token @@ -1152,6 +1228,44 @@ def create_mm_token_type_ids(self, input_ids: list) -> list[list[int]]: def replace_frame_token_id(self, timestamp_sec, num_image_tokens: int = 1): return f"<|begin_of_image|>{self.image_token * num_image_tokens}<|end_of_image|>{int(timestamp_sec)}" + def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): + """ + Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. + Args: + image_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (height, width) per each image. + video_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (num_frames, height, width) per each video. + Returns: + `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided + input modalities, along with other useful data. + """ + + vision_data = {} + if image_sizes is not None: + images_kwargs = Glm4vProcessorKwargs._defaults.get("images_kwargs", {}) + images_kwargs.update(kwargs) + merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size + + num_image_patches = [ + self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) + for image_size in image_sizes + ] + num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] + vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) + + if video_sizes is not None: + videos_kwargs = Glm4vProcessorKwargs._defaults.get("videos_kwargs", {}) + videos_kwargs.update(kwargs) + merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size + num_video_patches = [ + self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes + ] + num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] + vision_data["num_video_tokens"] = num_video_tokens + + return MultiModalData(**vision_data) + __all__ = [ "Glm4vConfig", diff --git a/src/transformers/models/glm_ocr/modular_glm_ocr.py b/src/transformers/models/glm_ocr/modular_glm_ocr.py index a61d071f3e30..89bdd796ac9c 100644 --- a/src/transformers/models/glm_ocr/modular_glm_ocr.py +++ b/src/transformers/models/glm_ocr/modular_glm_ocr.py @@ -123,6 +123,10 @@ class GlmOcrConfig(Glm4vConfig): image_end_token_id: int = 59257 video_start_token_id: int = 59258 video_end_token_id: int = 59259 + sub_configs_defaults = { + "vision_config": GlmOcrVisionConfig, + "text_config": GlmOcrTextConfig, + } class GlmOcrTextAttention(Glm4vTextAttention, nn.Module): @@ -135,7 +139,9 @@ def __init__(self, config: GlmOcrTextConfig, layer_idx: int | None = None): class GlmOcrTextDecoderLayer(Glm4vTextDecoderLayer): - pass + def __init__(self, config: GlmOcrTextConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = GlmOcrTextAttention(config, layer_idx) class GlmOcrPreTrainedModel(Glm4vPreTrainedModel): @@ -230,6 +236,7 @@ class GlmOcrVisionBlock(Glm4vVisionBlock): def __init__(self, config) -> None: super().__init__() self.mlp = GlmOcrVisionMlp(config, bias=config.attention_bias) + self.attn = GlmOcrVisionAttention(config) class GlmOcrVisionPatchMerger(Glm4vVisionPatchMerger): @@ -237,6 +244,11 @@ class GlmOcrVisionPatchMerger(Glm4vVisionPatchMerger): class GlmOcrVisionModel(Glm4vVisionModel): + _can_record_outputs = { + "hidden_states": GlmOcrVisionBlock, + "attentions": GlmOcrVisionAttention, + } + def __init__(self, config: GlmOcrVisionConfig) -> None: super().__init__(config) del self.embeddings @@ -247,6 +259,8 @@ def __init__(self, config: GlmOcrVisionConfig) -> None: hidden_act=config.hidden_act, ) + self.blocks = nn.ModuleList([GlmOcrVisionBlock(config) for _ in range(config.depth)]) + def forward( self, hidden_states: torch.Tensor, @@ -299,7 +313,9 @@ class GlmOcrTextModel(Glm4vTextModel): class GlmOcrModel(Glm4vModel): - pass + def __init__(self, config: GlmOcrConfig): + super().__init__(config) + self.visual = GlmOcrVisionModel._from_config(config.vision_config) class GlmOcrForConditionalGeneration(Glm4vForConditionalGeneration): diff --git a/src/transformers/models/glmasr/modular_glmasr.py b/src/transformers/models/glmasr/modular_glmasr.py index 4120f094d745..e13241b9c02c 100644 --- a/src/transformers/models/glmasr/modular_glmasr.py +++ b/src/transformers/models/glmasr/modular_glmasr.py @@ -340,6 +340,10 @@ def __init__(self, config: GlmAsrConfig): """ ) class GlmAsrModel(AudioFlamingo3Model): + def __init__(self, config: GlmAsrConfig): + super().__init__(config) + self.multi_modal_projector = GlmAsrMultiModalProjector(config) + @can_return_tuple @auto_docstring( custom_intro="Compute audio embeddings from log-mel input features using the audio encoder and multi-modal projector." diff --git a/src/transformers/models/glmga/modular_glmga.py b/src/transformers/models/glmga/modular_glmga.py index 1f407bb18f26..89aeece1d0e4 100644 --- a/src/transformers/models/glmga/modular_glmga.py +++ b/src/transformers/models/glmga/modular_glmga.py @@ -22,12 +22,13 @@ from ...image_transforms import group_images_by_shape, reorder_images from ...image_utils import ( ChannelDimension, + ImageInput, PILImageResampling, SizeDict, get_image_size, ) -from ...processing_utils import ImagesKwargs, VideosKwargs -from ...utils import TensorType +from ...processing_utils import ImagesKwargs, Unpack, VideosKwargs +from ...utils import TensorType, auto_docstring from ...video_utils import VideoMetadata, group_videos_by_shape, reorder_videos from ..glm4v.video_processing_glm4v import smart_resize from ..glm46v.configuration_glm46v import Glm46VConfig @@ -86,6 +87,7 @@ class GlmgaImageProcessorKwargs(ImagesKwargs, total=False): class GlmgaImageProcessor(Glm46VImageProcessor): patch_expand_factor = 1 + valid_kwargs = GlmgaImageProcessorKwargs def _preprocess( self, @@ -152,9 +154,14 @@ def _preprocess( data={"pixel_values": pixel_values, "image_grid_thw": image_grid_thw}, tensor_type=return_tensors ) + @auto_docstring + def preprocess(self, images: ImageInput, **kwargs: Unpack[GlmgaImageProcessorKwargs]) -> BatchFeature: + return super().preprocess(images, **kwargs) + class GlmgaImageProcessorPil(Glm46VImageProcessorPil): patch_expand_factor = 1 + valid_kwargs = GlmgaImageProcessorKwargs def _preprocess( self, @@ -215,6 +222,10 @@ def _preprocess( data={"pixel_values": pixel_values, "image_grid_thw": image_grid_thw}, tensor_type=return_tensors ) + @auto_docstring + def preprocess(self, images: ImageInput, **kwargs: Unpack[GlmgaImageProcessorKwargs]) -> BatchFeature: + return super().preprocess(images, **kwargs) + class GlmgaVideoProcessorInitKwargs(VideosKwargs, total=False): r""" @@ -246,6 +257,10 @@ class GlmgaVideoProcessor(Glm46VVideoProcessor): fps = 2 patch_expand_factor = 1 max_frames = 640 + valid_kwargs = GlmgaVideoProcessorInitKwargs + + def __init__(self, **kwargs: Unpack[GlmgaVideoProcessorInitKwargs]): + super().__init__(**kwargs) def sample_frames( self, diff --git a/src/transformers/models/got_ocr2/modular_got_ocr2.py b/src/transformers/models/got_ocr2/modular_got_ocr2.py index 7f0b58ac2993..d984165d5c72 100644 --- a/src/transformers/models/got_ocr2/modular_got_ocr2.py +++ b/src/transformers/models/got_ocr2/modular_got_ocr2.py @@ -26,6 +26,8 @@ from ...modeling_utils import PreTrainedModel, slice_logits_to_keep from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging +from ...utils.generic import merge_with_config_defaults +from ...utils.output_capturing import capture_outputs from ..auto import AutoConfig from ..llava.modeling_llava import ( LlavaCausalLMOutputWithPast, @@ -183,6 +185,34 @@ class GotOcr2PreTrainedModel(SamPreTrainedModel): class GotOcr2VisionEncoder(SamVisionEncoder, GotOcr2PreTrainedModel): input_modalities = ("image",) config: GotOcr2VisionConfig + _can_record_outputs = {"hidden_states": GotOcr2VisionLayer, "attentions": GotOcr2VisionAttention} + + def __init__(self, config: GotOcr2VisionConfig): + super().__init__(config) + for i in range(config.num_hidden_layers): + layer = GotOcr2VisionLayer( + config, + window_size=config.window_size if i not in config.global_attn_indexes else 0, + ) + self.layers.append(layer) + + @merge_with_config_defaults + @capture_outputs(tie_last_hidden_states=False) + def forward( + self, pixel_values: torch.FloatTensor | None = None, **kwargs: Unpack[TransformersKwargs] + ) -> tuple | GotOcr2VisionEncoderOutput: + if pixel_values is None: + raise ValueError("You have to specify pixel_values") + + hidden_states = self.patch_embed(pixel_values) + if self.pos_embed is not None: + hidden_states = hidden_states + self.pos_embed + for layer_module in self.layers: + hidden_states = layer_module(hidden_states) + hidden_states = self.neck(hidden_states) + return GotOcr2VisionEncoderOutput( + last_hidden_state=hidden_states, + ) class GotOcr2MultiModalProjector(nn.Module): @@ -236,6 +266,8 @@ def __init__(self, config: GotOcr2Config): super().__init__(config) self.vision_tower = GotOcr2VisionEncoder(config.vision_config) + self.multi_modal_projector = GotOcr2MultiModalProjector(config) + @can_return_tuple @auto_docstring( custom_intro="Obtains image last hidden states from the vision tower and apply multimodal projection." @@ -307,6 +339,10 @@ def forward( class GotOcr2ForConditionalGeneration(LlavaForConditionalGeneration): + def __init__(self, config: GotOcr2Config): + super().__init__(config) + self.model = GotOcr2Model(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/gpt_oss/modular_gpt_oss.py b/src/transformers/models/gpt_oss/modular_gpt_oss.py index 75e49d4bf25c..d5c2e4e959f5 100644 --- a/src/transformers/models/gpt_oss/modular_gpt_oss.py +++ b/src/transformers/models/gpt_oss/modular_gpt_oss.py @@ -339,6 +339,14 @@ def _init_weights(self, module): class GptOssModel(MixtralModel): + def __init__(self, config: GptOssConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [GptOssDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = GptOssRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = GptOssRotaryEmbedding(config=config) + @merge_with_config_defaults @capture_outputs @auto_docstring @@ -400,7 +408,9 @@ def forward( class GptOssForCausalLM(MixtralForCausalLM): - pass + def __init__(self, config: GptOssConfig): + super().__init__(config) + self.model = GptOssModel(config) class GptOssForSequenceClassification(MixtralForSequenceClassification): diff --git a/src/transformers/models/granite/modular_granite.py b/src/transformers/models/granite/modular_granite.py index 778f2d2b7953..f731c14529b0 100644 --- a/src/transformers/models/granite/modular_granite.py +++ b/src/transformers/models/granite/modular_granite.py @@ -179,6 +179,10 @@ def forward( class GraniteForCausalLM(LlamaForCausalLM): + def __init__(self, config: GraniteConfig): + super().__init__(config) + self.model = GraniteModel(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/granite4_vision/modular_granite4_vision.py b/src/transformers/models/granite4_vision/modular_granite4_vision.py index f1e3d2d49c31..056e4bd2c621 100644 --- a/src/transformers/models/granite4_vision/modular_granite4_vision.py +++ b/src/transformers/models/granite4_vision/modular_granite4_vision.py @@ -360,8 +360,12 @@ class Granite4VisionPreTrainedModel(LlavaNextPreTrainedModel): "attentions": Granite4VisionTextAttention, } + @torch.no_grad() def _init_weights(self, module): super()._init_weights(module) + if isinstance(module, Granite4VisionModel): + embed_std = 1 / math.sqrt(self.config.text_config.hidden_size) + init.normal_(module.image_newline, mean=0.0, std=embed_std) if isinstance(module, Granite4VisionWindowQFormerDownsampler): embed_std = 1 / math.sqrt(module.query.shape[-1]) init.normal_(module.query, mean=0.0, std=embed_std) @@ -696,6 +700,10 @@ def forward( class Granite4VisionForConditionalGeneration(LlavaNextForConditionalGeneration): + def __init__(self, config: Granite4VisionConfig): + super().__init__(config) + self.model = Granite4VisionModel(config) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/granite_speech5/modular_granite_speech5.py b/src/transformers/models/granite_speech5/modular_granite_speech5.py index 524242911026..f56c0d61b2a9 100644 --- a/src/transformers/models/granite_speech5/modular_granite_speech5.py +++ b/src/transformers/models/granite_speech5/modular_granite_speech5.py @@ -141,6 +141,9 @@ class GraniteSpeech5CTCConfig(ParakeetCTCConfig): pad_token_id: int | None = 0 # controls the tying of `ctc_head` to the encoder's (self-conditioning) CTC head `out` tie_word_embeddings: bool = True + sub_configs_defaults = { + "encoder_config": GraniteSpeech5EncoderConfig, + } def validate_architecture(self): if self.encoder_config.vocab_size != self.vocab_size: @@ -260,7 +263,13 @@ def downsample_attention_mask(attention_mask: torch.Tensor) -> torch.Tensor: return attention_mask[:, : 2 * half_length].reshape(attention_mask.shape[0], half_length, 2).all(dim=2) -class GraniteSpeech5EncoderBlock(GradientCheckpointingLayer, ParakeetEncoderBlock): ... +class GraniteSpeech5EncoderBlock(GradientCheckpointingLayer, ParakeetEncoderBlock): + ... + + def __init__(self, config: GraniteSpeech5EncoderConfig, layer_idx: int | None = None): + super().__init__(config, layer_idx) + self.self_attn = GraniteSpeech5EncoderAttention(config, layer_idx) + self.conv = GraniteSpeech5EncoderConvolutionModule(config) class GraniteSpeech5EncoderSubsamplingBlock(GraniteSpeech5EncoderBlock): diff --git a/src/transformers/models/granite_swa/modular_granite_swa.py b/src/transformers/models/granite_swa/modular_granite_swa.py index 496a11098235..172def4a61d5 100644 --- a/src/transformers/models/granite_swa/modular_granite_swa.py +++ b/src/transformers/models/granite_swa/modular_granite_swa.py @@ -333,7 +333,9 @@ def forward( class GraniteSWAForCausalLM(GraniteForCausalLM): - pass + def __init__(self, config: GraniteSWAConfig): + super().__init__(config) + self.model = GraniteSWAModel(config) __all__ = ["GraniteSWAConfig", "GraniteSWAForCausalLM", "GraniteSWAModel", "GraniteSWAPreTrainedModel"] diff --git a/src/transformers/models/granitemoe_swa/modular_granitemoe_swa.py b/src/transformers/models/granitemoe_swa/modular_granitemoe_swa.py index f810c65492d2..9fd43af2b24c 100644 --- a/src/transformers/models/granitemoe_swa/modular_granitemoe_swa.py +++ b/src/transformers/models/granitemoe_swa/modular_granitemoe_swa.py @@ -242,7 +242,9 @@ def forward( class GraniteMoeSWAForCausalLM(GraniteMoeSharedForCausalLM): - pass + def __init__(self, config: GraniteMoeSWAConfig): + super().__init__(config) + self.model = GraniteMoeSWAModel(config) __all__ = [ diff --git a/src/transformers/models/gte/modular_gte.py b/src/transformers/models/gte/modular_gte.py index ac3a961e27c3..c7ec586ac83a 100644 --- a/src/transformers/models/gte/modular_gte.py +++ b/src/transformers/models/gte/modular_gte.py @@ -136,7 +136,9 @@ def forward(self, x: torch.Tensor) -> torch.Tensor: class GteLayer(JinaEmbeddingsV3Layer): - pass + def __init__(self, config: GteConfig): + super().__init__(config) + self.mlp = GteMLP(config) class GtePooler(JinaEmbeddingsV3Pooler): @@ -168,6 +170,8 @@ def __init__(self, config: GteConfig, add_pooling_layer=False): """ super().__init__(config, add_pooling_layer=add_pooling_layer) + self.embeddings = GteEmbeddings(config) + class GteLMHead(JinaEmbeddingsV3LMHead): def __init__(self, config: GteConfig): @@ -242,7 +246,10 @@ def __init__(self, config: GteConfig): class GteForTokenClassification(BertForTokenClassification): - pass + def __init__(self, config: GteConfig): + super().__init__(config) + + self.gte = GteModel(config, add_pooling_layer=False) __all__ = [ diff --git a/src/transformers/models/helium/modular_helium.py b/src/transformers/models/helium/modular_helium.py index c14e30e98596..c0927665031e 100644 --- a/src/transformers/models/helium/modular_helium.py +++ b/src/transformers/models/helium/modular_helium.py @@ -13,13 +13,22 @@ # See the License for the specific language governing permissions and # limitations under the License. import math +from collections.abc import Callable import torch import torch.nn as nn -from ...utils import logging +from ...cache_utils import Cache +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS +from ...processing_utils import Unpack +from ...utils import TransformersKwargs, logging from ...utils.generic import no_inherit_decorator -from ..gemma.modeling_gemma import GemmaForCausalLM, GemmaForSequenceClassification, GemmaForTokenClassification +from ..gemma.modeling_gemma import ( + GemmaForCausalLM, + GemmaForSequenceClassification, + GemmaForTokenClassification, + eager_attention_forward, +) from ..granite.modeling_granite import GraniteAttention from ..llama.modeling_llama import LlamaDecoderLayer, LlamaMLP, LlamaModel, LlamaPreTrainedModel, LlamaRotaryEmbedding from .configuration_helium import HeliumConfig @@ -98,6 +107,46 @@ def __init__(self, config: HeliumConfig, layer_idx: int | None = None): self.o_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False) self.scaling = 1 / math.sqrt(self.head_dim) + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, + attention_mask: torch.Tensor | None = None, + past_key_values: Cache | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) + key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + class HeliumDecoderLayer(LlamaDecoderLayer): def __init__(self, config: HeliumConfig, layer_idx: int | None = None): @@ -107,9 +156,14 @@ def __init__(self, config: HeliumConfig, layer_idx: int | None = None): self.input_layernorm = HeliumRMSNorm(config.hidden_size, eps=config.rms_norm_eps) self.post_attention_layernorm = HeliumRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.self_attn = HeliumAttention(config=config, layer_idx=layer_idx) + class HeliumPreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": HeliumDecoderLayer, + "attentions": HeliumAttention, + } class HeliumModel(HeliumPreTrainedModel, LlamaModel): @@ -126,7 +180,9 @@ def __init__(self, config: HeliumConfig): class HeliumForCausalLM(GemmaForCausalLM): - pass + def __init__(self, config: HeliumConfig): + super().__init__(config) + self.model = HeliumModel(config) class HeliumForSequenceClassification(GemmaForSequenceClassification): diff --git a/src/transformers/models/higgs_audio_v2_tokenizer/modular_higgs_audio_v2_tokenizer.py b/src/transformers/models/higgs_audio_v2_tokenizer/modular_higgs_audio_v2_tokenizer.py index 370319faa595..ffeddcfb99c7 100644 --- a/src/transformers/models/higgs_audio_v2_tokenizer/modular_higgs_audio_v2_tokenizer.py +++ b/src/transformers/models/higgs_audio_v2_tokenizer/modular_higgs_audio_v2_tokenizer.py @@ -13,12 +13,15 @@ # limitations under the License. +import math + import torch import torch.nn as nn import torch.nn.functional as F import torchaudio from huggingface_hub.dataclasses import strict +from ... import initialization as init from ...configuration_utils import SubConfigSpec from ...utils import auto_docstring from ...utils.import_utils import requires @@ -107,6 +110,44 @@ class HiggsAudioV2TokenizerPreTrainedModel(XcodecPreTrainedModel): _no_split_modules = ["HiggsAudioV2TokenizerResidualVectorQuantization"] _keys_to_ignore_on_load_unexpected = ["semantic_model.masked_spec_embed"] + @torch.no_grad() + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, nn.Linear): + init.normal_(module.weight, mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + init.zeros_(module.bias) + elif isinstance(module, (nn.LayerNorm, nn.GroupNorm)): + init.zeros_(module.bias) + init.ones_(module.weight) + elif isinstance(module, nn.Conv1d): + init.kaiming_normal_(module.weight) + if module.bias is not None: + k = math.sqrt(module.groups / (module.in_channels * module.kernel_size[0])) + init.uniform_(module.bias, a=-k, b=k) + elif module.__class__.__name__ == "Snake1d": + init.ones_(module.alpha) + elif isinstance(module, nn.ConvTranspose1d): + module.reset_parameters() + elif isinstance(module, nn.Embedding): + init.normal_(module.weight, mean=0.0, std=0.02) + elif isinstance(module, HiggsAudioV2TokenizerModel): + # The conv1d are not handled correctly, as `self.acoustic_encoder/decoder` are initialized from a PreTrainedModel, + # but then only the submodules are used (which are not PreTrainedModels...) -> here we reinit them as in DacModel + for submodule in module.acoustic_encoder.modules(): + if isinstance(submodule, nn.Conv1d): + init.trunc_normal_(submodule.weight, std=0.02) + init.constant_(submodule.bias, 0) + for submodule in module.acoustic_decoder.modules(): + if isinstance(submodule, nn.Conv1d): + init.trunc_normal_(submodule.weight, std=0.02) + init.constant_(submodule.bias, 0) + elif isinstance(module, HiggsAudioV2TokenizerEuclideanCodebook): + init.copy_(module.inited, torch.Tensor([True])) + init.zeros_(module.cluster_size) + init.zeros_(module.embed) + init.zeros_(module.embed_avg) + class HiggsAudioV2TokenizerEuclideanCodebook(XcodecEuclideanCodebook): ... diff --git a/src/transformers/models/hrm_text/modular_hrm_text.py b/src/transformers/models/hrm_text/modular_hrm_text.py index 337c07a302e1..9d82d6dc7b35 100644 --- a/src/transformers/models/hrm_text/modular_hrm_text.py +++ b/src/transformers/models/hrm_text/modular_hrm_text.py @@ -217,6 +217,8 @@ def __init__(self, config: HrmTextConfig, layer_idx: int): self.input_layernorm = HrmTextRMSNorm(eps=config.rms_norm_eps) self.post_attention_layernorm = HrmTextRMSNorm(eps=config.rms_norm_eps) + self.self_attn = HrmTextAttention(config=config, layer_idx=layer_idx) + class HrmTextStack(nn.Module): """A single transformer stack — used twice inside, once as H module and once as L module""" @@ -252,6 +254,10 @@ def forward( @auto_docstring class HrmTextPreTrainedModel(LlamaPreTrainedModel): config: HrmTextConfig + _can_record_outputs = { + "hidden_states": HrmTextDecoderLayer, + "attentions": HrmTextAttention, + } def _check_and_adjust_attn_implementation( self, attn_implementation: str | None, is_init_check: bool = False, allow_all_kernels: bool = False @@ -406,6 +412,10 @@ def forward( @auto_docstring class HrmTextForCausalLM(LlamaForCausalLM): + def __init__(self, config: HrmTextConfig): + super().__init__(config) + self.model = HrmTextModel(config) + @staticmethod def create_masks_for_generate( config: PreTrainedConfig, diff --git a/src/transformers/models/hubert/modular_hubert.py b/src/transformers/models/hubert/modular_hubert.py index b7963222f926..2d14c2add00c 100644 --- a/src/transformers/models/hubert/modular_hubert.py +++ b/src/transformers/models/hubert/modular_hubert.py @@ -115,11 +115,15 @@ def forward(self, hidden_states): class HubertEncoder(Wav2Vec2Encoder): - pass + def __init__(self, config): + super().__init__(config) + self.pos_conv_embed = HubertPositionalConvEmbedding(config) class HubertEncoderStableLayerNorm(Wav2Vec2EncoderStableLayerNorm): - pass + def __init__(self, config): + super().__init__(config) + self.pos_conv_embed = HubertPositionalConvEmbedding(config) @auto_docstring @@ -288,11 +292,16 @@ def forward( class HubertForCTC(Wav2Vec2ForCTC): - pass + def __init__(self, config: HubertConfig, target_lang: str | None = None): + super().__init__(config, target_lang) + + self.hubert = HubertModel(config) class HubertForSequenceClassification(Wav2Vec2ForSequenceClassification): - pass + def __init__(self, config: HubertConfig): + super().__init__(config) + self.hubert = HubertModel(config) __all__ = ["HubertForCTC", "HubertForSequenceClassification", "HubertModel", "HubertPreTrainedModel"] diff --git a/src/transformers/models/hunyuan_v1_dense/modular_hunyuan_v1_dense.py b/src/transformers/models/hunyuan_v1_dense/modular_hunyuan_v1_dense.py index 146e54b11d45..da4d0891a79d 100644 --- a/src/transformers/models/hunyuan_v1_dense/modular_hunyuan_v1_dense.py +++ b/src/transformers/models/hunyuan_v1_dense/modular_hunyuan_v1_dense.py @@ -113,9 +113,16 @@ def __init__(self, config: HunYuanDenseV1Config, layer_idx: int): super().__init__(config, layer_idx) self.layer_idx = layer_idx + self.self_attn = HunYuanDenseV1Attention(config=config, layer_idx=layer_idx) + + self.mlp = HunYuanDenseV1MLP(config) + class HunYuanDenseV1PreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": HunYuanDenseV1DecoderLayer, + "attentions": HunYuanDenseV1Attention, + } class HunYuanDenseV1RotaryEmbedding(LlamaRotaryEmbedding): @@ -164,7 +171,12 @@ def compute_ntk_alpha_rope_parameters(config: HunYuanDenseV1Config, **kwargs) -> class HunYuanDenseV1Model(LlamaModel): - pass + def __init__(self, config: HunYuanDenseV1Config): + super().__init__(config) + self.layers = nn.ModuleList( + [HunYuanDenseV1DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = HunYuanDenseV1RotaryEmbedding(config=config) class HunYuanDenseV1ForCausalLM(LlamaForCausalLM): diff --git a/src/transformers/models/hunyuan_v1_moe/modular_hunyuan_v1_moe.py b/src/transformers/models/hunyuan_v1_moe/modular_hunyuan_v1_moe.py index 07b779f1815b..8a0517b31edb 100644 --- a/src/transformers/models/hunyuan_v1_moe/modular_hunyuan_v1_moe.py +++ b/src/transformers/models/hunyuan_v1_moe/modular_hunyuan_v1_moe.py @@ -179,7 +179,12 @@ class HunYuanMoEV1RotaryEmbedding(HunYuanDenseV1RotaryEmbedding): class HunYuanMoEV1Model(DeepseekV2Model): - pass + def __init__(self, config: HunYuanMoEV1Config): + super().__init__(config) + self.layers = nn.ModuleList( + [HunYuanMoEV1DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = HunYuanMoEV1RotaryEmbedding(config=config) class HunYuanMoEV1ForCausalLM(DeepseekV2ForCausalLM): diff --git a/src/transformers/models/hunyuan_vl/modular_hunyuan_vl.py b/src/transformers/models/hunyuan_vl/modular_hunyuan_vl.py index 7ae8b421fbdf..e7ba9a674951 100644 --- a/src/transformers/models/hunyuan_vl/modular_hunyuan_vl.py +++ b/src/transformers/models/hunyuan_vl/modular_hunyuan_vl.py @@ -298,6 +298,10 @@ class HunYuanVLConfig(Qwen2VLConfig): vision_start_token_id = AttributeError() vision_end_token_id = AttributeError() video_token_id = AttributeError() + sub_configs_defaults = { + "vision_config": HunYuanVLVisionConfig, + "text_config": HunYuanVLTextConfig, + } def __post_init__(self, **kwargs): # When loading legacy "flat" Tencent checkpoints (where text fields live at the top level instead of inside a @@ -1057,6 +1061,7 @@ def __init__(self, config: HunYuanVLConfig): super().__init__(config) self.vision_tower = HunYuanVLVisionTransformer(config.vision_config) del self.visual + self.language_model = HunYuanVLTextModel._from_config(config.text_config) def get_vision_position_ids( self, diff --git a/src/transformers/models/hy_v4/modular_hy_v4.py b/src/transformers/models/hy_v4/modular_hy_v4.py index 8f8b3655b1fb..1bcb74bc5b59 100644 --- a/src/transformers/models/hy_v4/modular_hy_v4.py +++ b/src/transformers/models/hy_v4/modular_hy_v4.py @@ -31,6 +31,7 @@ from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring from ...utils.generic import maybe_autocast +from ...utils.output_capturing import OutputRecorder from ..deepseek_v4.modeling_deepseek_v4 import ( DeepseekV4DecoderLayer, DeepseekV4HyperConnection, @@ -265,6 +266,7 @@ def __init__(self, config: HYV4Config, layer_idx: int): self.gate_projection_size = self.v_head_dim self.gate_proj = nn.Linear(config.hidden_size, self.num_heads * self.gate_projection_size, bias=False) self.sinks = nn.Parameter(torch.full((self.num_heads,), config.learnable_sink_init)) + self.indexer = None if self.skip_topk else HYV4Indexer(config, layer_idx) def forward( self, @@ -368,7 +370,9 @@ class HYV4Experts(Glm5NextTextExperts): class HYV4MoE(Glm4MoeLiteMoE): - pass + def __init__(self, config: HYV4Config): + super().__init__(config) + self.experts = HYV4Experts(config) class HYV4HyperConnection(DeepseekV4HyperConnection): @@ -384,6 +388,7 @@ def __init__(self, config: HYV4Config): concatenated_weights_size = 2 * self.hc_mult # noqa: F841 self.hc_post_magnitude = config.hc_magnitude self.scale = nn.Parameter(torch.empty(2)) + self.input_norm = HYV4UnweightedRMSNorm(eps=config.rms_norm_eps) def forward(self, hidden_streams: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]: """Independent HC implementation with forced fp32 application""" @@ -408,6 +413,10 @@ def forward(self, hidden_streams: torch.Tensor) -> tuple[torch.Tensor, torch.Ten class HYV4HyperHead(DeepseekV4HyperHead): + def __init__(self, config: HYV4Config): + super().__init__(config) + self.input_norm = HYV4UnweightedRMSNorm(eps=config.rms_norm_eps) + def forward(self, x: torch.Tensor) -> torch.Tensor: # Key difference is to force fp32 in any case device_type = x.device.type @@ -426,6 +435,11 @@ class HYV4DecoderLayer(DeepseekV4DecoderLayer): def __init__(self, config: HYV4Config, layer_idx: int): super().__init__(self, config, layer_idx) self.mlp = HYV4MoE(config) if config.mlp_layer_types[layer_idx] == "sparse" else HYV4MLP(config) + self.self_attn = HYV4Attention(config, layer_idx) + self.input_layernorm = HYV4RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = HYV4RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.attn_hc = HYV4HyperConnection(config) + self.ffn_hc = HYV4HyperConnection(config) def forward( self, @@ -485,6 +499,11 @@ class HYV4PreTrainedModel(Glm4MoeLitePreTrainedModel): "k_norm", "sinks", ] + _can_record_outputs = { + "hidden_states": HYV4DecoderLayer, + "attentions": HYV4Attention, + "router_logits": OutputRecorder(HYV4TopkRouter, index=0), + } @torch.no_grad() def _init_weights(self, module): @@ -517,6 +536,10 @@ class HYV4Model(Glm4MoeLiteModel): def __init__(self, config: HYV4Config): super().__init__(config) self.hc_head = HYV4HyperHead(config) + self.layers = nn.ModuleList( + [HYV4DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = HYV4RotaryEmbedding(config=config) def forward( self, @@ -597,6 +620,10 @@ class HYV4ForCausalLM(Glm4MoeLiteForCausalLM): "lm_head", ] + def __init__(self, config: HYV4Config): + super().__init__(config) + self.model = HYV4Model(config) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/hyperclovax/modular_hyperclovax.py b/src/transformers/models/hyperclovax/modular_hyperclovax.py index 17b7388704b9..f51746ee6752 100644 --- a/src/transformers/models/hyperclovax/modular_hyperclovax.py +++ b/src/transformers/models/hyperclovax/modular_hyperclovax.py @@ -159,12 +159,19 @@ def forward( @auto_docstring class HyperCLOVAXPreTrainedModel(GranitePreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": HyperCLOVAXDecoderLayer, + "attentions": HyperCLOVAXAttention, + } @auto_docstring class HyperCLOVAXModel(GraniteModel): - pass + def __init__(self, config: HyperCLOVAXConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [HyperCLOVAXDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) @auto_docstring diff --git a/src/transformers/models/inkling/modular_inkling.py b/src/transformers/models/inkling/modular_inkling.py index 4368fc2ec103..8dfa8c530b16 100644 --- a/src/transformers/models/inkling/modular_inkling.py +++ b/src/transformers/models/inkling/modular_inkling.py @@ -850,6 +850,10 @@ class InklingForCausalLM(Gemma3ForCausalLM): _tp_plan = {"lm_head": "rowwise_split_input"} _fsdp_plan = {"lm_head": "keep_full_weight"} + def __init__(self, config: InklingTextConfig): + super().__init__(config) + self.model = InklingTextModel(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/internvl/modular_internvl.py b/src/transformers/models/internvl/modular_internvl.py index 345db5bc8e7b..a4b07c0dd228 100644 --- a/src/transformers/models/internvl/modular_internvl.py +++ b/src/transformers/models/internvl/modular_internvl.py @@ -450,6 +450,11 @@ class InternVLModelOutputWithPast(LlavaModelOutputWithPast): class InternVLModel(LlavaModel): + def __init__(self, config: InternVLConfig): + super().__init__(config) + + self.multi_modal_projector = InternVLMultiModalProjector(config) + def pixel_shuffle(self, vision_features: torch.Tensor, scale_factor: float = 0.5): """Perform pixel shuffle downsampling on vision features. @@ -599,6 +604,10 @@ class InternVLCausalLMOutputWithPast(LlavaCausalLMOutputWithPast): class InternVLForConditionalGeneration(LlavaForConditionalGeneration): + def __init__(self, config: InternVLConfig): + super().__init__(config) + self.model = InternVLModel(config) + def forward(**super_kwargs): r""" Example: diff --git a/src/transformers/models/jamba/modular_jamba.py b/src/transformers/models/jamba/modular_jamba.py index fe83043e3476..2d0fb8cc1162 100644 --- a/src/transformers/models/jamba/modular_jamba.py +++ b/src/transformers/models/jamba/modular_jamba.py @@ -527,6 +527,7 @@ class JambaForCausalLM(MixtralForCausalLM): def __init__(self, config: JambaConfig): super().__init__(config) self.num_experts = config.num_experts + self.model = JambaModel(config) def forward( self, diff --git a/src/transformers/models/janus/modular_janus.py b/src/transformers/models/janus/modular_janus.py index 801c6308113e..8d9f1e49c4be 100644 --- a/src/transformers/models/janus/modular_janus.py +++ b/src/transformers/models/janus/modular_janus.py @@ -356,6 +356,8 @@ def __init__(self, config: JanusVisionConfig): super().__init__(config) self.encoder = JanusVisionEncoder(config) + self.embeddings = JanusVisionEmbeddings(config) + def forward( self, pixel_values: torch.FloatTensor | None = None, @@ -633,6 +635,9 @@ def __init__(self, config: JanusVQVAEConfig): # Initialize the VQVAE model. self.post_init() + self.encoder = JanusVQVAEEncoder(config) + self.quantize = JanusVQVAEVectorQuantizer(config) + def decode(self, image_tokens: torch.LongTensor) -> torch.FloatTensor: """ Decodes quantized token IDs into pixel values. diff --git a/src/transformers/models/jina_embeddings_v3/modular_jina_embeddings_v3.py b/src/transformers/models/jina_embeddings_v3/modular_jina_embeddings_v3.py index 710628f6795d..83f87aa27a16 100644 --- a/src/transformers/models/jina_embeddings_v3/modular_jina_embeddings_v3.py +++ b/src/transformers/models/jina_embeddings_v3/modular_jina_embeddings_v3.py @@ -20,6 +20,7 @@ from torch import nn from torch.nn import CrossEntropyLoss +from ... import initialization as init from ...integrations import use_kernelized_func from ...masking_utils import create_bidirectional_mask from ...modeling_outputs import ( @@ -199,6 +200,7 @@ def __init__(self, config: JinaEmbeddingsV3Config): del self.use_parallel_residual del self.input_layernorm del self.attention + self.mlp = JinaEmbeddingsV3MLP(config) def forward( self, @@ -234,6 +236,16 @@ class JinaEmbeddingsV3PreTrainedModel(XLMRobertaPreTrainedModel): "attentions": JinaEmbeddingsV3Attention, } + @torch.no_grad() + def _init_weights(self, module): + """Initialize the weights""" + super()._init_weights(module) + if isinstance(module, JinaEmbeddingsV3LMHead): + init.zeros_(module.bias) + elif isinstance(module, JinaEmbeddingsV3Embeddings): + init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1))) + init.zeros_(module.token_type_ids) + @auto_docstring class JinaEmbeddingsV3Model(XLMRobertaModel): @@ -246,6 +258,8 @@ def __init__(self, config: JinaEmbeddingsV3Config, add_pooling_layer=True): # Initialize weights and apply final processing self.post_init() + self.embeddings = JinaEmbeddingsV3Embeddings(config) + @merge_with_config_defaults @capture_outputs @auto_docstring @@ -373,15 +387,24 @@ def forward( class JinaEmbeddingsV3ForSequenceClassification(XLMRobertaForSequenceClassification): - pass + def __init__(self, config: JinaEmbeddingsV3Config): + super().__init__(config) + + self.roberta = JinaEmbeddingsV3Model(config, add_pooling_layer=False) class JinaEmbeddingsV3ForTokenClassification(XLMRobertaForTokenClassification): - pass + def __init__(self, config: JinaEmbeddingsV3Config): + super().__init__(config) + + self.roberta = JinaEmbeddingsV3Model(config, add_pooling_layer=False) class JinaEmbeddingsV3ForQuestionAnswering(XLMRobertaForQuestionAnswering): - pass + def __init__(self, config: JinaEmbeddingsV3Config): + super().__init__(config) + + self.roberta = JinaEmbeddingsV3Model(config, add_pooling_layer=False) __all__ = [ diff --git a/src/transformers/models/kimi_k25/modular_kimi_k25.py b/src/transformers/models/kimi_k25/modular_kimi_k25.py index 961986d81b8b..e991df9f5dde 100644 --- a/src/transformers/models/kimi_k25/modular_kimi_k25.py +++ b/src/transformers/models/kimi_k25/modular_kimi_k25.py @@ -619,6 +619,10 @@ def forward( @auto_docstring class Kimi_K25ForConditionalGeneration(Glm4vForConditionalGeneration): + def __init__(self, config: Kimi_K25Config): + super().__init__(config) + self.model = Kimi_K25Model(config) + @can_return_tuple @auto_docstring def forward( @@ -728,6 +732,8 @@ class Kimi_K25ProcessorKwargs(ProcessingKwargs, total=False): @auto_docstring class Kimi_K25Processor(Qwen2VLProcessor): + valid_processor_kwargs = Kimi_K25ProcessorKwargs + def __init__( self, image_processor=None, diff --git a/src/transformers/models/kimi_linear/modular_kimi_linear.py b/src/transformers/models/kimi_linear/modular_kimi_linear.py index d026563d5604..0e9f887c2035 100644 --- a/src/transformers/models/kimi_linear/modular_kimi_linear.py +++ b/src/transformers/models/kimi_linear/modular_kimi_linear.py @@ -336,6 +336,10 @@ class KimiLinearModel(Qwen3NextModel): def __init__(self, config: KimiLinearConfig): super().__init__(config) del self.rotary_emb + self.layers = nn.ModuleList( + [KimiLinearDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = KimiLinearRMSNorm(config.hidden_size, eps=config.rms_norm_eps) def forward( self, @@ -399,6 +403,10 @@ def forward( class KimiLinearForCausalLM(DeepseekV3ForCausalLM, GenerationMixin): _tied_weights_keys = {} + def __init__(self, config: KimiLinearConfig): + super().__init__(config) + self.model = KimiLinearModel(config) + __all__ = [ "KimiLinearConfig", diff --git a/src/transformers/models/kolibri1/modular_kolibri1.py b/src/transformers/models/kolibri1/modular_kolibri1.py index a38d096da0e0..c9da8b5a194f 100644 --- a/src/transformers/models/kolibri1/modular_kolibri1.py +++ b/src/transformers/models/kolibri1/modular_kolibri1.py @@ -20,6 +20,7 @@ from ... import initialization as init from ...configuration_utils import PreTrainedConfig from ...utils import auto_docstring, is_torch_greater_or_equal +from ...utils.output_capturing import OutputRecorder from ..deepseek_v3.modeling_deepseek_v3 import DeepseekV3ForCausalLM, DeepseekV3MoE from ..exaone4.modeling_exaone4 import Exaone4Attention from ..glm4.modeling_glm4 import Glm4DecoderLayer @@ -145,16 +146,23 @@ def __init__(self, config: Kolibri1Config): super().__init__(config) self.gate = Kolibri1TopKRouter(config) self.shared_experts = Kolibri1MLP(config, intermediate_size=config.shared_expert_intermediate_size) + self.experts = Kolibri1Experts(config) class Kolibri1DecoderLayer(Glm4DecoderLayer): def __init__(self, config: Kolibri1Config, layer_idx: int): super().__init__(config, layer_idx) self.mlp = Kolibri1SparseMoeBlock(config) + self.self_attn = Kolibri1Attention(config=config, layer_idx=layer_idx) class Kolibri1PreTrainedModel(Qwen3MoePreTrainedModel): _keep_in_fp32_modules_strict = ["e_score_correction_bias"] + _can_record_outputs = { + "router_logits": OutputRecorder(Kolibri1TopKRouter, index=0), + "hidden_states": Kolibri1DecoderLayer, + "attentions": Kolibri1Attention, + } @torch.no_grad() def _init_weights(self, module): @@ -164,10 +172,18 @@ def _init_weights(self, module): class Kolibri1Model(Qwen2MoeModel): - pass + def __init__(self, config: Kolibri1Config): + super().__init__(config) + self.layers = nn.ModuleList( + [Kolibri1DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) class Kolibri1ForCausalLM(DeepseekV3ForCausalLM): + def __init__(self, config: Kolibri1Config): + super().__init__(config) + self.model = Kolibri1Model(config) + def forward(self, **super_kwargs): r""" Example: diff --git a/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py b/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py index 6f7ca85d46a1..28f5cbf8afca 100644 --- a/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py +++ b/src/transformers/models/kyutai_speech_to_text/modular_kyutai_speech_to_text.py @@ -270,6 +270,7 @@ def __init__(self, config: KyutaiSpeechToTextConfig): # yet the codec_model needs a generation config to initialize it's cache for streaming inference # we therefore initialize a generation config for the codec model self.codec_model.generation_config = GenerationConfig.from_model_config(config.codec_config) + self.model = KyutaiSpeechToTextModel(config) def forward(self, **super_kwargs): r""" diff --git a/src/transformers/models/laguna/modular_laguna.py b/src/transformers/models/laguna/modular_laguna.py index 84c2543bc47d..3d0e7794f725 100644 --- a/src/transformers/models/laguna/modular_laguna.py +++ b/src/transformers/models/laguna/modular_laguna.py @@ -32,6 +32,7 @@ from ...processing_utils import Unpack from ...utils import auto_docstring, logging from ...utils.generic import TransformersKwargs, no_inherit_decorator +from ...utils.output_capturing import OutputRecorder from ..afmoe.modeling_afmoe import AfmoeAttention from ..gemma3.modeling_gemma3 import Gemma3RotaryEmbedding from ..glm4_moe_lite.modeling_glm4_moe_lite import Glm4MoeLiteDecoderLayer @@ -255,6 +256,7 @@ def __init__(self, config: LagunaConfig): super().__init__(config) self.shared_experts = LagunaMLP(config, intermediate_size=config.shared_expert_intermediate_size) self.routed_scaling_factor = config.moe_routed_scaling_factor + self.gate = LagunaTopKRouter(config) def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: batch_size, sequence_length, hidden_dim = hidden_states.shape @@ -290,6 +292,9 @@ def __init__(self, config: LagunaConfig, layer_idx: int, num_heads: int): g_proj_dim = self.num_heads if self.gate_per_head else self.num_heads * self.head_dim self.g_proj = nn.Linear(config.hidden_size, g_proj_dim, bias=False) + self.q_norm = LagunaRMSNorm(self.head_dim, eps=config.rms_norm_eps) + self.k_norm = LagunaRMSNorm(self.head_dim, eps=config.rms_norm_eps) + def forward( self, hidden_states: torch.Tensor, @@ -358,6 +363,12 @@ def __init__(self, config: LagunaConfig, layer_idx: int): class LagunaPreTrainedModel(Qwen2MoePreTrainedModel): + _can_record_outputs = { + "router_logits": OutputRecorder(LagunaTopKRouter, index=0), + "hidden_states": LagunaDecoderLayer, + "attentions": LagunaAttention, + } + @torch.no_grad() def _init_weights(self, module): super()._init_weights(module) @@ -374,6 +385,13 @@ def _init_weights(self, module): class LagunaModel(LlamaModel): + def __init__(self, config: LagunaConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [LagunaDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = LagunaRotaryEmbedding(config=config) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -438,6 +456,10 @@ def forward( class LagunaForCausalLM(Qwen2MoeForCausalLM): + def __init__(self, config: LagunaConfig): + super().__init__(config) + self.model = LagunaModel(config) + def forward(self, **super_kwargs): r""" labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): diff --git a/src/transformers/models/lasr/modular_lasr.py b/src/transformers/models/lasr/modular_lasr.py index 26568363b871..88ee838fe9e5 100644 --- a/src/transformers/models/lasr/modular_lasr.py +++ b/src/transformers/models/lasr/modular_lasr.py @@ -301,6 +301,9 @@ class LasrCTCConfig(ParakeetCTCConfig): vocab_size: int = 512 pad_token_id: int = 0 + sub_configs_defaults = { + "encoder_config": LasrEncoderConfig, + } @property def inputs_to_logits_ratio(self): @@ -399,6 +402,8 @@ def __init__(self, config: LasrEncoderConfig, layer_idx: int): self.norm_conv = nn.LayerNorm(config.hidden_size, config.layer_norm_eps, bias=False) self.norm_feed_forward2 = nn.LayerNorm(config.hidden_size, config.layer_norm_eps, bias=False) self.norm_out = nn.LayerNorm(config.hidden_size, config.layer_norm_eps, bias=False) + self.self_attn = LasrEncoderAttention(config, layer_idx) + self.conv = LasrEncoderConvolutionModule(config) def forward( self, @@ -439,6 +444,10 @@ def forward( class LasrPreTrainedModel(ParakeetPreTrainedModel): # padding is incompatible with flex attention as the resulting mask cannot be used to apply padding _supports_flex_attn = False + _can_record_outputs = { + "hidden_states": LasrEncoderBlock, + "attentions": LasrEncoderAttention, + } def _init_weights(self, module): raise AttributeError("Normal super call") diff --git a/src/transformers/models/lfm2/modular_lfm2.py b/src/transformers/models/lfm2/modular_lfm2.py index fdf264606e19..4278c903f6e3 100644 --- a/src/transformers/models/lfm2/modular_lfm2.py +++ b/src/transformers/models/lfm2/modular_lfm2.py @@ -238,7 +238,10 @@ def forward( class Lfm2PreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": Lfm2DecoderLayer, + "attentions": Lfm2Attention, + } class Lfm2Model(LlamaModel): @@ -246,6 +249,9 @@ def __init__(self, config: Lfm2Config): super().__init__(config) self.embedding_norm = Lfm2RMSNorm(config.hidden_size, eps=config.norm_eps) del self.norm + self.layers = nn.ModuleList( + [Lfm2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) def forward( self, @@ -307,7 +313,9 @@ def forward( class Lfm2ForCausalLM(LlamaForCausalLM): - pass + def __init__(self, config: Lfm2Config): + super().__init__(config) + self.model = Lfm2Model(config) __all__ = ["Lfm2ForCausalLM", "Lfm2Model", "Lfm2PreTrainedModel"] diff --git a/src/transformers/models/lfm2_moe/modular_lfm2_moe.py b/src/transformers/models/lfm2_moe/modular_lfm2_moe.py index 69cd4ab5519b..c0405326aa82 100644 --- a/src/transformers/models/lfm2_moe/modular_lfm2_moe.py +++ b/src/transformers/models/lfm2_moe/modular_lfm2_moe.py @@ -94,6 +94,8 @@ def __init__(self, config): self.use_expert_bias = config.use_expert_bias if self.use_expert_bias: self.expert_bias = nn.Buffer(torch.zeros(config.num_experts, dtype=torch.float32)) + self.experts = Lfm2MoeExperts(config) + self.gate = Lfm2MoeTopKRouter(config) def forward(self, hidden_states: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]: batch_size, sequence_length, hidden_dim = hidden_states.shape @@ -149,6 +151,9 @@ def __init__(self, config: Lfm2MoeConfig): self.embedding_norm = Lfm2MoeRMSNorm(config.hidden_size, eps=config.norm_eps) del self.norm del self.rotary_emb + self.layers = nn.ModuleList( + [Lfm2MoeDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) def forward( self, @@ -210,7 +215,9 @@ def forward( class Lfm2MoeForCausalLM(DeepseekV2ForCausalLM): - pass + def __init__(self, config: Lfm2MoeConfig): + super().__init__(config) + self.model = Lfm2MoeModel(config) __all__ = ["Lfm2MoeForCausalLM", "Lfm2MoeModel", "Lfm2MoePreTrainedModel"] diff --git a/src/transformers/models/lfm2_vl/modular_lfm2_vl.py b/src/transformers/models/lfm2_vl/modular_lfm2_vl.py index 8943de4723e3..742703620065 100644 --- a/src/transformers/models/lfm2_vl/modular_lfm2_vl.py +++ b/src/transformers/models/lfm2_vl/modular_lfm2_vl.py @@ -91,6 +91,8 @@ class Lfm2VlModel(LlavaModel): def __init__(self, config: Lfm2VlConfig): super().__init__(config) + self.multi_modal_projector = Lfm2VlMultiModalProjector(config) + @can_return_tuple @auto_docstring( custom_intro="Obtains image last hidden states from the vision tower and apply multimodal projection." @@ -236,6 +238,10 @@ def forward( class Lfm2VlForConditionalGeneration(LlavaForConditionalGeneration): + def __init__(self, config: Lfm2VlConfig): + super().__init__(config) + self.model = Lfm2VlModel(config) + @auto_docstring def get_image_features( self, diff --git a/src/transformers/models/lighton_ocr/modular_lighton_ocr.py b/src/transformers/models/lighton_ocr/modular_lighton_ocr.py index e9b1f2527baa..3c189b73a1ea 100644 --- a/src/transformers/models/lighton_ocr/modular_lighton_ocr.py +++ b/src/transformers/models/lighton_ocr/modular_lighton_ocr.py @@ -297,6 +297,10 @@ def forward( class LightOnOcrForConditionalGeneration(Mistral3ForConditionalGeneration): + def __init__(self, config: LightOnOcrConfig): + super().__init__(config) + self.model = LightOnOcrModel(config) + @auto_docstring def get_image_features( self, pixel_values: torch.FloatTensor, image_sizes: torch.Tensor, **kwargs: Unpack[TransformersKwargs] diff --git a/src/transformers/models/llava_next_video/modular_llava_next_video.py b/src/transformers/models/llava_next_video/modular_llava_next_video.py index a6e876455ef9..4719418df7b7 100644 --- a/src/transformers/models/llava_next_video/modular_llava_next_video.py +++ b/src/transformers/models/llava_next_video/modular_llava_next_video.py @@ -19,6 +19,7 @@ from huggingface_hub.dataclasses import strict from torch import nn +from ... import initialization as init from ...cache_utils import Cache from ...configuration_utils import PreTrainedConfig, SubConfigSpec from ...modeling_flash_attention_utils import FlashAttentionKwargs @@ -212,6 +213,13 @@ class LlavaNextVideoPreTrainedModel(LlavaNextPreTrainedModel): "attentions": "LlamaAttention", } + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + if isinstance(module, LlavaNextVideoModel): + embed_std = 1 / math.sqrt(self.config.text_config.hidden_size) + init.normal_(module.image_newline, mean=0.0, std=embed_std) + class LlavaNextVideoModel(LlavaNextModel): def __init__(self, config: LlavaNextVideoConfig, **super_kwargs): @@ -471,6 +479,10 @@ def forward( class LlavaNextVideoForConditionalGeneration(LlavaNextForConditionalGeneration): + def __init__(self, config: LlavaNextVideoConfig): + super().__init__(config) + self.model = LlavaNextVideoModel(config) + @merge_with_config_defaults @can_return_tuple @auto_docstring diff --git a/src/transformers/models/llava_onevision/modular_llava_onevision.py b/src/transformers/models/llava_onevision/modular_llava_onevision.py index 8ee8719d3f09..ce7dba233223 100644 --- a/src/transformers/models/llava_onevision/modular_llava_onevision.py +++ b/src/transformers/models/llava_onevision/modular_llava_onevision.py @@ -19,6 +19,7 @@ import torchvision.transforms.v2.functional as tvF from torch import nn +from ... import initialization as init from ...cache_utils import Cache from ...image_processing_backends import PilBackend, TorchvisionBackend from ...image_processing_utils import BatchFeature @@ -395,7 +396,12 @@ class LlavaOnevisionCausalLMOutputWithPast(LlavaNextVideoCausalLMOutputWithPast) class LlavaOnevisionPreTrainedModel(LlavaNextVideoPreTrainedModel): - pass + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + if isinstance(module, LlavaOnevisionModel): + embed_std = 1 / math.sqrt(self.config.text_config.hidden_size) + init.normal_(module.image_newline, mean=0.0, std=embed_std) class LlavaOnevisionModel(LlavaNextVideoModel): @@ -706,6 +712,10 @@ def forward( class LlavaOnevisionForConditionalGeneration(LlavaNextVideoForConditionalGeneration): + def __init__(self, config: LlavaOnevisionConfig): + super().__init__(config) + self.model = LlavaOnevisionModel(config) + @merge_with_config_defaults @can_return_tuple @auto_docstring diff --git a/src/transformers/models/lw_detr/modular_lw_detr.py b/src/transformers/models/lw_detr/modular_lw_detr.py index 8405417144d4..d02c628eecb9 100644 --- a/src/transformers/models/lw_detr/modular_lw_detr.py +++ b/src/transformers/models/lw_detr/modular_lw_detr.py @@ -240,6 +240,39 @@ def __init__(self, config: LwDetrViTConfig): self.k_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=False) self.num_key_value_groups = 1 + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) + key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + + return attn_output, attn_weights + class LwDetrViTMlp(VitDetMlp): pass @@ -349,6 +382,10 @@ def forward( @auto_docstring() class LwDetrViTBackbone(VitDetBackbone): + def __init__(self, config: LwDetrViTConfig): + super().__init__(config) + self.encoder = LwDetrViTEncoder(config) + def forward(self, pixel_values: torch.Tensor, **kwargs: Unpack[TransformersKwargs]) -> BackboneOutput: r""" Examples: diff --git a/src/transformers/models/mimo_v2_flash/modular_mimo_v2_flash.py b/src/transformers/models/mimo_v2_flash/modular_mimo_v2_flash.py index 6e11f34ecce8..d014399399c4 100644 --- a/src/transformers/models/mimo_v2_flash/modular_mimo_v2_flash.py +++ b/src/transformers/models/mimo_v2_flash/modular_mimo_v2_flash.py @@ -26,6 +26,7 @@ from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring from ...utils.generic import no_inherit_decorator +from ...utils.output_capturing import OutputRecorder from ..deepseek_v3.modeling_deepseek_v3 import ( DeepseekV3Experts, DeepseekV3ForCausalLM, @@ -301,7 +302,11 @@ def forward( class MiMoV2FlashDecoderLayer(Glm4MoeLiteDecoderLayer): - pass + def __init__(self, config: MiMoV2FlashConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = MiMoV2FlashAttention(config, layer_idx) + + self.mlp = MiMoV2FlashMoE(config) if config.mlp_layer_types[layer_idx] == "sparse" else MiMoV2FlashMLP(config) @auto_docstring @@ -311,6 +316,11 @@ class MiMoV2FlashPreTrainedModel(DeepseekV3PreTrainedModel): _supports_flex_attn = False # asymmetric head dim + not being a power of 2 _compatible_flash_implementations = ["flash_attention_4"] _keys_to_ignore_on_load_unexpected = [r"^model\.mtp\."] + _can_record_outputs = { + "hidden_states": MiMoV2FlashDecoderLayer, + "attentions": MiMoV2FlashAttention, + "router_logits": OutputRecorder(MiMoV2FlashTopkRouter, index=0), + } @torch.no_grad() def _init_weights(self, module): @@ -330,11 +340,18 @@ def _init_weights(self, module): @auto_docstring class MiMoV2FlashModel(LagunaModel): - pass + def __init__(self, config: MiMoV2FlashConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [MiMoV2FlashDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = MiMoV2FlashRotaryEmbedding(config=config) class MiMoV2FlashForCausalLM(DeepseekV3ForCausalLM): - pass + def __init__(self, config: MiMoV2FlashConfig): + super().__init__(config) + self.model = MiMoV2FlashModel(config) __all__ = [ diff --git a/src/transformers/models/minicpm3/modular_minicpm3.py b/src/transformers/models/minicpm3/modular_minicpm3.py index 7630cdfe82f2..d0044d782aa8 100644 --- a/src/transformers/models/minicpm3/modular_minicpm3.py +++ b/src/transformers/models/minicpm3/modular_minicpm3.py @@ -17,6 +17,7 @@ import torch from huggingface_hub.dataclasses import strict +from torch import nn from ... import initialization as init from ...cache_utils import Cache @@ -224,6 +225,8 @@ def __init__(self, config: MiniCPM3Config, layer_idx: int): # (Llama adds the branch directly). Precompute the constant once instead of per forward. self.residual_scale = config.scale_depth / math.sqrt(config.num_hidden_layers) + self.self_attn = MiniCPM3Attention(config=config, layer_idx=layer_idx) + def forward( self, hidden_states: torch.Tensor, @@ -255,6 +258,11 @@ def forward( class MiniCPM3PreTrainedModel(LlamaPreTrainedModel): + _can_record_outputs = { + "hidden_states": MiniCPM3DecoderLayer, + "attentions": MiniCPM3Attention, + } + @torch.no_grad() def _init_weights(self, module): PreTrainedModel._init_weights(self, module) @@ -270,10 +278,17 @@ def __init__(self, config: MiniCPM3Config): self.embed_tokens = MiniCPM3ScaledWordEmbedding( config.vocab_size, config.hidden_size, self.padding_idx, embed_scale=config.scale_emb ) + self.layers = nn.ModuleList( + [MiniCPM3DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) @auto_docstring class MiniCPM3ForCausalLM(LlamaForCausalLM): + def __init__(self, config: MiniCPM3Config): + super().__init__(config) + self.model = MiniCPM3Model(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/minicpm_ocr/modular_minicpm_ocr.py b/src/transformers/models/minicpm_ocr/modular_minicpm_ocr.py index a530881f3772..6c2ef54fc543 100644 --- a/src/transformers/models/minicpm_ocr/modular_minicpm_ocr.py +++ b/src/transformers/models/minicpm_ocr/modular_minicpm_ocr.py @@ -18,10 +18,13 @@ from huggingface_hub.dataclasses import strict from PIL.Image import Resampling as PILImageResampling +from ...configuration_utils import SubConfigSpec from ...feature_extraction_utils import BatchFeature from ...image_transforms import divide_to_patches, group_images_by_shape, reorder_images -from ...image_utils import SizeDict +from ...image_utils import ImageInput, SizeDict +from ...processing_utils import Unpack from ...utils import TensorType, auto_docstring, is_cv2_available, logging, requires_backends +from ..auto import AutoConfig from ..minicpmv4_6.configuration_minicpmv4_6 import MiniCPMV4_6Config, MiniCPMV4_6VisionConfig from ..minicpmv4_6.image_processing_minicpmv4_6 import MiniCPMV4_6ImageProcessor, MiniCPMV4_6ImageProcessorKwargs from ..minicpmv4_6.modeling_minicpmv4_6 import MiniCPMV4_6ForConditionalGeneration, MiniCPMV4_6Model @@ -120,6 +123,10 @@ class MiniCPMOcrConfig(MiniCPMV4_6Config): downsample_mode: str = "4x" drop_vision_last_layer = AttributeError() image_size = AttributeError() + sub_configs_defaults = { + "text_config": SubConfigSpec(config_class=AutoConfig, model_type="qwen3_5_text"), + "vision_config": MiniCPMOcrVisionConfig, + } class MiniCPMOcrImageProcessorKwargs(MiniCPMV4_6ImageProcessorKwargs, total=False): @@ -154,6 +161,9 @@ class MiniCPMOcrImageProcessor(MiniCPMV4_6ImageProcessor): small_image_upsize = "always" valid_kwargs = MiniCPMOcrImageProcessorKwargs + def __init__(self, **kwargs: Unpack[MiniCPMOcrImageProcessorKwargs]): + super().__init__(**kwargs) + def _resolve_tile_size( self, image: "torch.Tensor", @@ -309,6 +319,14 @@ def _preprocess( skip_tensor_conversion=["grids", "num_patches_per_image"], ) + @auto_docstring + def preprocess( + self, + images: ImageInput, + **kwargs: Unpack[MiniCPMOcrImageProcessorKwargs], + ) -> BatchFeature: + return super().preprocess(images, **kwargs) + class MiniCPMOcrVideoProcessorKwargs(MiniCPMV4_6VideoProcessorKwargs, total=False): r""" diff --git a/src/transformers/models/minicpmv4_7/modular_minicpmv4_7.py b/src/transformers/models/minicpmv4_7/modular_minicpmv4_7.py index 51486d66bc0c..3f47cd10ed2e 100644 --- a/src/transformers/models/minicpmv4_7/modular_minicpmv4_7.py +++ b/src/transformers/models/minicpmv4_7/modular_minicpmv4_7.py @@ -19,6 +19,7 @@ from huggingface_hub.dataclasses import strict from ...cache_utils import Cache +from ...configuration_utils import SubConfigSpec from ...image_utils import ImageInput, make_flat_list_of_images from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling, CausalLMOutputWithPast from ...modeling_utils import slice_logits_to_keep @@ -26,6 +27,7 @@ from ...tokenization_utils_base import PreTokenizedInput, TextInput from ...utils import TransformersKwargs, auto_docstring, logging from ...video_utils import VideoInput, make_batched_videos +from ..auto import AutoConfig from ..minicpmv4_6.configuration_minicpmv4_6 import MiniCPMV4_6Config, MiniCPMV4_6VisionConfig from ..minicpmv4_6.modeling_minicpmv4_6 import ( MiniCPMV4_6ForConditionalGeneration, @@ -83,6 +85,10 @@ class MiniCPMV4_7Config(MiniCPMV4_6Config): slice_end_id: int | None = None newline_id: int | None = None drop_vision_last_layer = AttributeError() + sub_configs_defaults = { + "text_config": SubConfigSpec(config_class=AutoConfig, model_type="qwen3_5_text"), + "vision_config": MiniCPMV4_7VisionConfig, + } class MiniCPMV4_7Model(MiniCPMV4_6Model): @@ -599,6 +605,10 @@ def forward( class MiniCPMV4_7ForConditionalGeneration(MiniCPMV4_6ForConditionalGeneration): + def __init__(self, config: MiniCPMV4_7Config): + super().__init__(config) + self.model = MiniCPMV4_7Model(config) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/minimax/modular_minimax.py b/src/transformers/models/minimax/modular_minimax.py index 37c41a63c126..03114a7716c8 100644 --- a/src/transformers/models/minimax/modular_minimax.py +++ b/src/transformers/models/minimax/modular_minimax.py @@ -434,6 +434,12 @@ def _init_weights(self, module): class MiniMaxModel(MixtralModel): + def __init__(self, config: MiniMaxConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [MiniMaxDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + @merge_with_config_defaults @capture_outputs def forward( @@ -503,6 +509,10 @@ def forward( class MiniMaxForCausalLM(MixtralForCausalLM): + def __init__(self, config: MiniMaxConfig): + super().__init__(config) + self.model = MiniMaxModel(config) + def forward(self, **super_kwargs): r""" Example: diff --git a/src/transformers/models/minimax_m3_vl/modular_minimax_m3_vl.py b/src/transformers/models/minimax_m3_vl/modular_minimax_m3_vl.py index d75071683ca8..2dc75e717faa 100644 --- a/src/transformers/models/minimax_m3_vl/modular_minimax_m3_vl.py +++ b/src/transformers/models/minimax_m3_vl/modular_minimax_m3_vl.py @@ -29,11 +29,11 @@ from ...modeling_outputs import BaseModelOutputWithPooling, MoeModelOutputWithPast from ...modeling_rope_utils import RopeParameters from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel, slice_logits_to_keep -from ...processing_utils import Unpack +from ...processing_utils import MultiModalData, Unpack from ...utils import TransformersKwargs, auto_docstring, logging, torch_compilable_check from ...utils.generic import can_return_tuple, merge_with_config_defaults from ...utils.import_utils import is_torchdynamo_compiling -from ...utils.output_capturing import capture_outputs +from ...utils.output_capturing import OutputRecorder, capture_outputs from ...vision_utils import get_vision_position_ids from ..clip.modeling_clip import CLIPMLP, CLIPAttention, CLIPEncoderLayer from ..deepseek_v4.modeling_deepseek_v4 import DeepseekV4Experts @@ -627,6 +627,11 @@ class MiniMaxM3VLPreTrainedModel(MiniMaxM2PreTrainedModel): _can_compile_fullgraph = True _supports_attention_backend = True _compatible_flash_implementations = ["MiniMaxAI/msa"] + _can_record_outputs = { + "router_logits": OutputRecorder(MiniMaxM3VLTopKRouter, index=0), + "hidden_states": MiniMaxM3VLDecoderLayer, + "attentions": MiniMaxM3VLAttention, + } @torch.no_grad() def _init_weights(self, module): @@ -1130,6 +1135,10 @@ def forward( class MiniMaxM3SparseForConditionalGeneration(LlavaForConditionalGeneration): config: MiniMaxM3VLConfig + def __init__(self, config: MiniMaxM3VLConfig): + super().__init__(config) + self.model = MiniMaxM3VLModel(config) + def get_image_features(self, pixel_values, image_grid_thw, **kwargs): return self.model.get_image_features(pixel_values, image_grid_thw, **kwargs) @@ -1290,6 +1299,44 @@ def replace_video_token(self, video_inputs: dict, video_idx: int, **kwargs) -> s chunk += self.VISION_START_TOKEN + self.VIDEO_TOKEN * frame_seqlen + self.VISION_END_TOKEN return chunk + def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): + """ + Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. + Args: + image_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (height, width) per each image. + video_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (num_frames, height, width) per each video. + Returns: + `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided + input modalities, along with other useful data. + """ + + vision_data = {} + if image_sizes is not None: + images_kwargs = MiniMaxM3VLProcessorKwargs._defaults.get("images_kwargs", {}) + images_kwargs.update(kwargs) + merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size + + num_image_patches = [ + self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) + for image_size in image_sizes + ] + num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] + vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) + + if video_sizes is not None: + videos_kwargs = MiniMaxM3VLProcessorKwargs._defaults.get("videos_kwargs", {}) + videos_kwargs.update(kwargs) + merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size + num_video_patches = [ + self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes + ] + num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] + vision_data["num_video_tokens"] = num_video_tokens + + return MultiModalData(**vision_data) + __all__ = [ "MiniMaxM3VLConfig", diff --git a/src/transformers/models/ministral/modular_ministral.py b/src/transformers/models/ministral/modular_ministral.py index 5e3950c71274..ab2bcdd226ca 100644 --- a/src/transformers/models/ministral/modular_ministral.py +++ b/src/transformers/models/ministral/modular_ministral.py @@ -94,11 +94,17 @@ class MinistralRMSNorm(Qwen2RMSNorm): class MinistralDecoderLayer(Qwen2DecoderLayer): - pass + def __init__(self, config: MinistralConfig, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = MinistralAttention(config=config, layer_idx=layer_idx) class MinistralPreTrainedModel(Qwen2PreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": MinistralDecoderLayer, + "attentions": MinistralAttention, + } class MinistralRotaryEmbedding(Qwen2RotaryEmbedding): @@ -175,7 +181,9 @@ def forward( class MinistralForCausalLM(Qwen2ForCausalLM): - pass + def __init__(self, config: MinistralConfig): + super().__init__(config) + self.model = MinistralModel(config) class MinistralForSequenceClassification(Qwen2ForSequenceClassification): diff --git a/src/transformers/models/ministral3/modular_ministral3.py b/src/transformers/models/ministral3/modular_ministral3.py index 0a925f5d404d..717bd4e8afc0 100644 --- a/src/transformers/models/ministral3/modular_ministral3.py +++ b/src/transformers/models/ministral3/modular_ministral3.py @@ -21,6 +21,7 @@ apply_rotary_pos_emb, eager_attention_forward, ) +from .configuration_ministral3 import Ministral3Config logger = logging.get_logger(__name__) @@ -81,12 +82,17 @@ def forward( class Ministral3DecoderLayer(MistralDecoderLayer): - pass + def __init__(self, config: Ministral3Config, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = Ministral3Attention(config=config, layer_idx=layer_idx) @auto_docstring class Ministral3PreTrainedModel(MistralPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": Ministral3DecoderLayer, + "attentions": Ministral3Attention, + } @auto_docstring diff --git a/src/transformers/models/mistral/modular_mistral.py b/src/transformers/models/mistral/modular_mistral.py index c4e8061a77c1..a9bef77ab5ec 100644 --- a/src/transformers/models/mistral/modular_mistral.py +++ b/src/transformers/models/mistral/modular_mistral.py @@ -164,7 +164,9 @@ def forward( class MistralForCausalLM(LlamaForCausalLM): - pass + def __init__(self, config: MistralConfig): + super().__init__(config) + self.model = MistralModel(config) class MistralForTokenClassification(LlamaForTokenClassification): diff --git a/src/transformers/models/mistral3/modular_mistral3.py b/src/transformers/models/mistral3/modular_mistral3.py index 7b189afe09f7..94e1607817cf 100644 --- a/src/transformers/models/mistral3/modular_mistral3.py +++ b/src/transformers/models/mistral3/modular_mistral3.py @@ -121,6 +121,11 @@ class Mistral3PreTrainedModel(LlavaPreTrainedModel): class Mistral3Model(LlavaModel): + def __init__(self, config: Mistral3Config): + super().__init__(config) + + self.multi_modal_projector = Mistral3MultiModalProjector(config) + @merge_with_config_defaults @can_return_tuple @auto_docstring( @@ -221,6 +226,10 @@ def forward( class Mistral3ForConditionalGeneration(LlavaForConditionalGeneration): + def __init__(self, config: Mistral3Config): + super().__init__(config) + self.model = Mistral3Model(config) + @merge_with_config_defaults @can_return_tuple @auto_docstring diff --git a/src/transformers/models/mistral4/modular_mistral4.py b/src/transformers/models/mistral4/modular_mistral4.py index 1a54faf2a548..026fa555e941 100644 --- a/src/transformers/models/mistral4/modular_mistral4.py +++ b/src/transformers/models/mistral4/modular_mistral4.py @@ -98,7 +98,9 @@ class Mistral4Experts(DeepseekV3Experts): class Mistral4MoE(DeepseekV3MoE): - pass + def __init__(self, config: Mistral4Config): + super().__init__(config) + self.gate = Mistral4TopkRouter(config) class Mistral4Attention(DeepseekV3Attention): diff --git a/src/transformers/models/mistral_large4/modular_mistral_large4.py b/src/transformers/models/mistral_large4/modular_mistral_large4.py index 194897707a9a..120441317c6b 100644 --- a/src/transformers/models/mistral_large4/modular_mistral_large4.py +++ b/src/transformers/models/mistral_large4/modular_mistral_large4.py @@ -30,7 +30,7 @@ from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, can_return_tuple from ...utils.generic import merge_with_config_defaults -from ...utils.output_capturing import capture_outputs +from ...utils.output_capturing import OutputRecorder, capture_outputs from ..auto import AutoConfig from ..deepseek_v32.modeling_deepseek_v32 import DeepseekV32Indexer, eager_attention_forward from ..glm_moe_dsa.configuration_glm_moe_dsa import GlmMoeDsaConfig @@ -399,6 +399,7 @@ def __init__(self, config: MistralLarge4TextConfig, layer_idx: int): self.kv_a_layernorm = ( MistralLarge4RMSNorm(config.kv_lora_rank, eps=config.rms_norm_eps) if not self.is_kv_shared_layer else None ) + self.indexer = None if self.skip_topk else MistralLarge4TextIndexer(config, layer_idx) # trf-ignore: TRF043 def forward( @@ -544,7 +545,9 @@ class MistralLarge4TextExperts(Mistral4Experts): class MistralLarge4TextMoE(Mistral4MoE): - pass + def __init__(self, config: MistralLarge4TextConfig): + super().__init__(config) + self.gate = MistralLarge4TextTopkRouter(config) class MistralLarge4TextDecoderLayer(GlmMoeDsaDecoderLayer): @@ -552,6 +555,7 @@ def __init__(self, config: MistralLarge4TextConfig, layer_idx: int): super().__init__(config, layer_idx) self.input_layernorm = MistralLarge4RMSNorm(config.hidden_size, eps=config.rms_norm_eps) self.post_attention_layernorm = MistralLarge4RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.self_attn = MistralLarge4TextAttention(config, layer_idx) def forward( self, @@ -596,6 +600,11 @@ class MistralLarge4PreTrainedModel(GlmMoeDsaPreTrainedModel): _keep_in_fp32_modules_strict = ["rotary_emb", "mlp.gate.weight"] # The checkpoint ships a multi-token-prediction draft head that this model does not implement yet # TODO _keys_to_ignore_on_load_unexpected = [r"mtp_dspark\..*"] + _can_record_outputs = { + "hidden_states": MistralLarge4TextDecoderLayer, + "attentions": MistralLarge4TextAttention, + "router_logits": OutputRecorder(MistralLarge4TextTopkRouter, index=0), + } @torch.no_grad() def _init_weights(self, module): @@ -617,6 +626,10 @@ class MistralLarge4TextModel(MistralLarge4PreTrainedModel, GlmMoeDsaModel): def __init__(self, config: MistralLarge4TextConfig): super().__init__(config) self.norm = MistralLarge4RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.layers = nn.ModuleList( + [MistralLarge4TextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = MistralLarge4TextRotaryEmbedding(config=config) @merge_with_config_defaults @capture_outputs @@ -776,6 +789,7 @@ class MistralLarge4ForConditionalGeneration(Mistral3ForConditionalGeneration): def __init__(self, config: MistralLarge4Config): super().__init__(config) self.final_logit_softcapping = self.config.get_text_config().final_logit_softcapping + self.model = MistralLarge4Model(config) @merge_with_config_defaults @can_return_tuple diff --git a/src/transformers/models/mixtral/modular_mixtral.py b/src/transformers/models/mixtral/modular_mixtral.py index bfc32630179c..74061854ce67 100644 --- a/src/transformers/models/mixtral/modular_mixtral.py +++ b/src/transformers/models/mixtral/modular_mixtral.py @@ -265,6 +265,12 @@ def _init_weights(self, module): class MixtralModel(MistralModel): + def __init__(self, config: MixtralConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [MixtralDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -318,21 +324,6 @@ def forward( last_hidden_state=hidden_states, past_key_values=past_key_values, ) - def __init__(self, config: MixtralConfig): - super().__init__(config) - self.padding_idx = config.pad_token_id - self.vocab_size = config.vocab_size - - self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx) - self.layers = nn.ModuleList( - [MixtralDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] - ) - self.norm = MixtralRMSNorm(config.hidden_size, eps=config.rms_norm_eps) - self.rotary_emb = MixtralRotaryEmbedding(config=config) - self.gradient_checkpointing = False - - # Initialize weights and apply final processing - self.post_init() class MixtralForCausalLM(MistralForCausalLM): diff --git a/src/transformers/models/mlcd/modular_mlcd.py b/src/transformers/models/mlcd/modular_mlcd.py index c8c9852b367b..52579eff9010 100644 --- a/src/transformers/models/mlcd/modular_mlcd.py +++ b/src/transformers/models/mlcd/modular_mlcd.py @@ -220,6 +220,7 @@ class MLCDEncoder(CLIPEncoder): def __init__(self, config: MLCDVisionConfig): """Overwrite dummy `MLCDConfig` to `MLCDVisionConfig`.""" super().__init__(config) + self.layers = nn.ModuleList([MLCDEncoderLayer(config) for _ in range(config.num_hidden_layers)]) def forward( self, @@ -309,6 +310,9 @@ def __init__(self, config: MLCDVisionConfig): self.vision_rotary_embedding = MLCDRotaryEmbedding(config) self.class_pos_emb = nn.Parameter(torch.randn(1, config.hidden_size // config.num_attention_heads // 2)) + self.embeddings = MLCDVisionEmbeddings(config) + self.encoder = MLCDEncoder(config) + def forward( self, pixel_values: torch.FloatTensor | None = None, diff --git a/src/transformers/models/molmo2/modular_molmo2.py b/src/transformers/models/molmo2/modular_molmo2.py index 2c28d93bae93..2ec1f109f25f 100644 --- a/src/transformers/models/molmo2/modular_molmo2.py +++ b/src/transformers/models/molmo2/modular_molmo2.py @@ -1199,6 +1199,10 @@ def __init__(self, config: Molmo2TextConfig, layer_idx: int): super().__init__(config, layer_idx) self.norm_after = config.norm_after + self.self_attn = Molmo2Attention(config=config, layer_idx=layer_idx) + + self.mlp = Molmo2MLP(config) + def forward( self, hidden_states: torch.Tensor, @@ -1242,6 +1246,10 @@ def forward( class Molmo2PreTrainedModel(LlamaPreTrainedModel): config: Molmo2Config input_modalities = ("image", "video", "text") + _can_record_outputs = { + "hidden_states": Molmo2DecoderLayer, + "attentions": Molmo2Attention, + } def _init_weights(self, module): PreTrainedModel._init_weights(self, module) diff --git a/src/transformers/models/moonshine_streaming/modular_moonshine_streaming.py b/src/transformers/models/moonshine_streaming/modular_moonshine_streaming.py index 1f874d099e6d..cd1be7dbf22a 100644 --- a/src/transformers/models/moonshine_streaming/modular_moonshine_streaming.py +++ b/src/transformers/models/moonshine_streaming/modular_moonshine_streaming.py @@ -28,6 +28,7 @@ ) from ...modeling_utils import ALL_ATTENTION_FUNCTIONS from ...processing_utils import ProcessingKwargs, Unpack +from ...tokenization_utils_base import AudioInput, PreTokenizedInput, TextInput from ...utils import TransformersKwargs, auto_docstring, logging from ...utils.generic import merge_with_config_defaults from ...utils.output_capturing import OutputRecorder, capture_outputs @@ -57,7 +58,41 @@ class MoonshineStreamingProcessorKwargs(ProcessingKwargs, total=False): } -class MoonshineStreamingProcessor(Wav2Vec2Processor): ... +class MoonshineStreamingProcessor(Wav2Vec2Processor): + ... + + @auto_docstring + def __call__( + self, + audio: AudioInput | None = None, + text: str | list[str] | TextInput | PreTokenizedInput | None = None, + **kwargs: Unpack[MoonshineStreamingProcessorKwargs], + ): + r""" + Returns: + This method returns the results of each `call` method. If both are used, the output is a dictionary containing the results of both. + """ + if audio is None and text is None: + raise ValueError("You need to specify either an `audio` or `text` input to process.") + + output_kwargs = self._merge_kwargs( + MoonshineStreamingProcessorKwargs, + tokenizer_init_kwargs=self.tokenizer.init_kwargs, + **kwargs, + ) + + if audio is not None: + inputs = self.feature_extractor(audio, **output_kwargs["audio_kwargs"]) + if text is not None: + encodings = self.tokenizer(text, **output_kwargs["text_kwargs"]) + + if text is None: + return inputs + elif audio is None: + return encodings + else: + inputs["labels"] = encodings["input_ids"] + return inputs @auto_docstring( @@ -409,7 +444,12 @@ def __init__(self, config: MoonshineStreamingConfig): self.decoder = MoonshineStreamingDecoder(config) -class MoonshineStreamingForConditionalGeneration(MoonshineForConditionalGeneration): ... +class MoonshineStreamingForConditionalGeneration(MoonshineForConditionalGeneration): + ... + + def __init__(self, config: MoonshineStreamingConfig): + super().__init__(config) + self.model = MoonshineStreamingModel(config) __all__ = [ diff --git a/src/transformers/models/moss_transcribe_diarize/modular_moss_transcribe_diarize.py b/src/transformers/models/moss_transcribe_diarize/modular_moss_transcribe_diarize.py index 683aa5b56279..43947904196d 100644 --- a/src/transformers/models/moss_transcribe_diarize/modular_moss_transcribe_diarize.py +++ b/src/transformers/models/moss_transcribe_diarize/modular_moss_transcribe_diarize.py @@ -663,6 +663,10 @@ class MossTranscribeDiarizeCausalLMOutputWithPast(AudioFlamingo3CausalLMOutputWi """ ) class MossTranscribeDiarizeModel(AudioFlamingo3Model): + def __init__(self, config: MossTranscribeDiarizeConfig): + super().__init__(config) + self.multi_modal_projector = MossTranscribeDiarizeMultiModalProjector(config) + @can_return_tuple @auto_docstring( custom_intro="Extract MOSS audio embeddings from log-mel features, reassembling multi-chunk audio per sample." @@ -771,6 +775,10 @@ class MossTranscribeDiarizeForConditionalGeneration(AudioFlamingo3ForConditional _tied_weights_keys = {"lm_head.weight": "model.language_model.embed_tokens.weight"} _tp_plan = {"lm_head": "colwise_gather_output"} + def __init__(self, config: MossTranscribeDiarizeConfig): + super().__init__(config) + self.model = MossTranscribeDiarizeModel(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/muse_glimmer/modular_muse_glimmer.py b/src/transformers/models/muse_glimmer/modular_muse_glimmer.py index d420a0f7e6db..060dff383c05 100644 --- a/src/transformers/models/muse_glimmer/modular_muse_glimmer.py +++ b/src/transformers/models/muse_glimmer/modular_muse_glimmer.py @@ -28,14 +28,14 @@ from ...image_processing_backends import TorchvisionBackend from ...image_processing_utils import BatchFeature from ...image_transforms import group_images_by_shape, reorder_images -from ...image_utils import PILImageResampling, SizeDict +from ...image_utils import ImageInput, PILImageResampling, SizeDict from ...masking_utils import create_causal_mask, create_sliding_window_causal_mask from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, slice_logits_to_keep from ...processing_utils import Unpack, VideosKwargs from ...utils import TensorType, TransformersKwargs, auto_docstring, logging from ...utils.constants import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD -from ...utils.generic import merge_with_config_defaults +from ...utils.generic import get_max_seqlen, is_flash_attention_requested, merge_with_config_defaults from ...utils.output_capturing import capture_outputs from ...video_processing_utils import BaseVideoProcessor from ...video_utils import VideoMetadata, group_videos_by_shape, reorder_videos @@ -66,6 +66,7 @@ Kimi_K25VisionAttention, Kimi_K25VisionEncoderLayer, Kimi_K25VisionMLP, + apply_rotary_pos_emb_vision, ) from ..llama.modeling_llama import eager_attention_forward from ..paddleocr_vl.modeling_paddleocr_vl import PaddleOCRVisionEmbeddings @@ -132,6 +133,7 @@ class MuseGlimmerImageProcessor(Glm4vImageProcessor): size = None merge_size = 2 max_image_tokens = 4096 + valid_kwargs = MuseGlimmerImageProcessorKwargs def _validate_preprocess_kwargs(self, **kwargs): # MuseGlimmer uses aspect_ratio_preserving_resize driven by patch_size, @@ -285,6 +287,10 @@ def get_number_of_image_patches(self, height: int, width: int, images_kwargs=Non grid_h, grid_w = resized_height // patch_size, resized_width // patch_size return grid_h * grid_w + @auto_docstring + def preprocess(self, images: ImageInput, **kwargs: Unpack[MuseGlimmerImageProcessorKwargs]) -> BatchFeature: + return super().preprocess(images, **kwargs) + class MuseGlimmerVideoProcessorInitKwargs(VideosKwargs, total=False): """ @@ -874,7 +880,75 @@ def forward( class MuseGlimmerVisionAttention(Kimi_K25VisionAttention): - pass + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, + max_seqlen: int | None = None, + **kwargs, + ) -> torch.Tensor: + seq_length = hidden_states.shape[0] + + query_states = self.q_proj(hidden_states).reshape(1, seq_length, -1, self.head_dim) + key_states = self.k_proj(hidden_states).reshape(1, seq_length, -1, self.head_dim) + value_states = self.v_proj(hidden_states).reshape(1, seq_length, -1, self.head_dim) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb_vision(query_states, key_states, cos, sin) + + query_states = query_states.transpose(2, 1) + key_states = key_states.transpose(2, 1) + value_states = value_states.transpose(2, 1) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + if is_flash_attention_requested(self.config): + # Flash Attention: Use cu_seqlens for variable length attention + max_seqlen = get_max_seqlen(cu_seqlens, self.config, kwargs={"max_seqlen": max_seqlen}) + attn_output, _ = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + cu_seq_lens_q=cu_seqlens, + cu_seq_lens_k=cu_seqlens, + max_length_q=max_seqlen, + max_length_k=max_seqlen, + is_causal=False, + **kwargs, + ) + else: + # Other implementations: Process each chunk separately + lengths = cu_seqlens[1:] - cu_seqlens[:-1] + splits = [ + torch.split(tensor, lengths.tolist(), dim=2) for tensor in (query_states, key_states, value_states) + ] + + attn_outputs = [ + attention_interface( + self, + q, + k, + v, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + is_causal=False, + **kwargs, + )[0] + for q, k, v in zip(*splits) + ] + attn_output = torch.cat(attn_outputs, dim=1) + + attn_output = attn_output.reshape(seq_length, -1).contiguous() + attn_output = self.proj(attn_output) + return attn_output class MuseGlimmerVisionMLP(Kimi_K25VisionMLP): @@ -1075,6 +1149,7 @@ def __init__(self, config: MuseGlimmerConfig): self.vision_adapter = MuseGlimmerVisionAdapter(config) self.vision_projection = nn.Linear(config.projector_hidden_size, config.text_config.hidden_size, bias=False) self.perception_emb_norm = MuseGlimmerRMSNorm(eps=config.text_config.rms_norm_eps, with_scale=False) + self.vision_tower = MuseGlimmerVisionModel._from_config(config.vision_config) def get_image_features( self, @@ -1099,6 +1174,10 @@ class MuseGlimmerForConditionalGeneration(Kimi_K25ForConditionalGeneration): input_modalities = ("image", "video", "text") _tp_plan = {"lm_head": "colwise_gather_output"} + def __init__(self, config: MuseGlimmerConfig): + super().__init__(config) + self.model = MuseGlimmerModel(config) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/muse_glimmer_assistant/modular_muse_glimmer_assistant.py b/src/transformers/models/muse_glimmer_assistant/modular_muse_glimmer_assistant.py index 2ea51fe16e80..c7892c479e41 100644 --- a/src/transformers/models/muse_glimmer_assistant/modular_muse_glimmer_assistant.py +++ b/src/transformers/models/muse_glimmer_assistant/modular_muse_glimmer_assistant.py @@ -139,6 +139,7 @@ def __init__(self, config: MuseGlimmerAssistantConfig, layer_idx: int): super().__init__(config, layer_idx) self.input_layernorm = MuseGlimmerAssistantRMSNorm(config.hidden_size, eps=config.rms_norm_eps) del self.post_feedforward_layernorm + self.self_attn = MuseGlimmerAssistantAttention(config=config, layer_idx=layer_idx) def forward( self, @@ -170,6 +171,10 @@ def forward( class MuseGlimmerAssistantPreTrainedModel(Exaone4PreTrainedModel): main_input_name = "noise_embeds" + _can_record_outputs = { + "hidden_states": MuseGlimmerAssistantDecoderLayer, + "attentions": MuseGlimmerAssistantAttention, + } class MuseGlimmerAssistantContextProjection(nn.Module): diff --git a/src/transformers/models/muse_spark/modular_muse_spark.py b/src/transformers/models/muse_spark/modular_muse_spark.py index 3937febe3879..bbb8c04ecd72 100644 --- a/src/transformers/models/muse_spark/modular_muse_spark.py +++ b/src/transformers/models/muse_spark/modular_muse_spark.py @@ -470,6 +470,9 @@ def __init__(self, config: MuseSparkTextConfig, layer_idx: int): self.post_attention_residual_gate = MuseSparkResidualGate(config) self.post_feedforward_layernorm = MuseSparkTextInputScaledRMSNorm(config.hidden_size, eps=config.post_norm_eps) self.post_feedforward_residual_gate = MuseSparkResidualGate(config) + self.self_attn = MuseSparkTextAttention(config=config, layer_idx=layer_idx) + self.input_layernorm = MuseSparkTextCenteredRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.pre_feedforward_layernorm = MuseSparkTextCenteredRMSNorm(config.hidden_size, eps=config.rms_norm_eps) def forward( self, @@ -531,6 +534,12 @@ class MuseSparkTextModel(MuseGlimmerTextModel): "router_logits": OutputRecorder(MuseSparkTopkRouter, index=0), } + def __init__(self, config: MuseSparkTextConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [MuseSparkTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + @merge_with_config_defaults @capture_outputs @auto_docstring @@ -618,7 +627,9 @@ def forward( class MuseSparkVisionModel(MuseGlimmerVisionModel): - pass + def __init__(self, config: MuseSparkVisionConfig): + super().__init__(config) + self.patch_embedder = MuseSparkVisionPatchEmbedder(config) class MuseSparkAudioConv1dPaddingCache(VoxtralRealtimeConv1dPaddingCache): @@ -955,6 +966,10 @@ class MuseSparkForConditionalGeneration(MuseGlimmerForConditionalGeneration): # as it requires a custom tp plan _tied_weights_keys = AttributeError() + def __init__(self, config: MuseSparkConfig): + super().__init__(config) + self.model = MuseSparkModel(config) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/nanochat/modular_nanochat.py b/src/transformers/models/nanochat/modular_nanochat.py index e386ddea9f13..774e7c199846 100644 --- a/src/transformers/models/nanochat/modular_nanochat.py +++ b/src/transformers/models/nanochat/modular_nanochat.py @@ -123,9 +123,18 @@ def __init__(self, config: NanoChatConfig, layer_idx: int): self.input_layernorm = NanoChatRMSNorm(eps=config.rms_norm_eps) self.post_attention_layernorm = NanoChatRMSNorm(eps=config.rms_norm_eps) + self.self_attn = NanoChatAttention(config=config, layer_idx=layer_idx) + + self.mlp = NanoChatMLP(config) + @auto_docstring class NanoChatPreTrainedModel(LlamaPreTrainedModel): + _can_record_outputs = { + "hidden_states": NanoChatDecoderLayer, + "attentions": NanoChatAttention, + } + def _init_weights(self, module: nn.Module) -> None: PreTrainedModel._init_weights(self, module) if isinstance(module, NanoChatAttention): @@ -142,6 +151,9 @@ def __init__(self, config: NanoChatConfig): super().__init__(config) self.norm = NanoChatRMSNorm(eps=config.rms_norm_eps) + self.layers = nn.ModuleList( + [NanoChatDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) def forward( self, @@ -202,6 +214,10 @@ class NanoChatForCausalLM(Gemma2ForCausalLM): _fsdp_plan = {"lm_head": "keep_full_weight"} + def __init__(self, config: NanoChatConfig): + super().__init__(config) + self.model = NanoChatModel(config) + def forward(self, **super_kwargs) -> CausalLMOutputWithPast: r""" Example: diff --git a/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py b/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py index 35eada815c4f..75c85410b7a6 100644 --- a/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py +++ b/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py @@ -723,6 +723,7 @@ def __init__(self, config: Nemotron3_5TranscribeConfig): config.word_timestamp_config.hidden_size, config.word_timestamp_config.vocab_size, kernel_size=1 ) self.post_init() + self.model = Nemotron3_5TranscribeModel(config) @auto_docstring def get_audio_features(self, input_features, input_features_mask, **kwargs): diff --git a/src/transformers/models/nemotron_asr_streaming/modular_nemotron_asr_streaming.py b/src/transformers/models/nemotron_asr_streaming/modular_nemotron_asr_streaming.py index ce6b2c70bd4f..43ee8465dadb 100644 --- a/src/transformers/models/nemotron_asr_streaming/modular_nemotron_asr_streaming.py +++ b/src/transformers/models/nemotron_asr_streaming/modular_nemotron_asr_streaming.py @@ -21,6 +21,7 @@ from huggingface_hub.dataclasses import strict from torch import nn +from ... import initialization as init from ...cache_utils import Cache, DynamicCache from ...feature_extraction_utils import BatchFeature from ...masking_utils import create_bidirectional_mask @@ -165,6 +166,7 @@ class NemotronAsrStreamingConfig(ParakeetRNNTConfig): vocab_size: int = 1025 pad_token_id: int = 0 blank_token_id: int = 1024 + sub_configs_defaults = {"encoder_config": NemotronAsrStreamingEncoderConfig} class NemotronAsrStreamingFeatureExtractor(ParakeetFeatureExtractor): @@ -782,6 +784,7 @@ class NemotronAsrStreamingEncoderBlock(ParakeetEncoderBlock): def __init__(self, config: NemotronAsrStreamingEncoderConfig, layer_idx: int | None = None): super().__init__(config, layer_idx) self.conv = NemotronAsrStreamingEncoderConvolutionModule(config, layer_idx=layer_idx) + self.self_attn = NemotronAsrStreamingEncoderAttention(config, layer_idx) def forward( self, @@ -825,6 +828,10 @@ class NemotronAsrStreamingPreTrainedModel(ParakeetPreTrainedModel): config: NemotronAsrStreamingConfig # flex attention is incompatible as this model uses a float attention mask (relative position bias) across the board _supports_flex_attn = False + _can_record_outputs = { + "hidden_states": NemotronAsrStreamingEncoderBlock, + "attentions": NemotronAsrStreamingEncoderAttention, + } def _get_subsampling_output_length(self, input_lengths: torch.Tensor): encoder_config = getattr(self.config, "encoder_config", self.config) @@ -844,6 +851,18 @@ def _get_subsampling_output_length(self, input_lengths: torch.Tensor): return lengths.to(dtype=torch.int) + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + std = getattr(self.config, "initializer_range", 0.02) + + if isinstance(module, NemotronAsrStreamingEncoderAttention): + init.normal_(module.bias_u, mean=0.0, std=std) + init.normal_(module.bias_v, mean=0.0, std=std) + elif isinstance(module, NemotronAsrStreamingEncoderRelPositionalEncoding): + buffer_value = module.compute_default_relative_positional_parameters(module.config) + init.copy_(module.inv_freq, buffer_value) + def chunked_limited_mask_function(left_ctx: int, right_ctx: int) -> Callable: """ @@ -867,6 +886,15 @@ def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool: """ ) class NemotronAsrStreamingEncoder(ParakeetEncoder): + def __init__(self, config: NemotronAsrStreamingEncoderConfig): + super().__init__(config) + self.subsampling = NemotronAsrStreamingEncoderSubsamplingConv2D(config) + self.encode_positions = NemotronAsrStreamingEncoderRelPositionalEncoding(config) + + self.layers = nn.ModuleList( + [NemotronAsrStreamingEncoderBlock(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + @auto_docstring @merge_with_config_defaults @capture_outputs @@ -1040,6 +1068,8 @@ class NemotronAsrStreamingForRNNT( def __init__(self, config: NemotronAsrStreamingConfig): super().__init__(config) + self.decoder = NemotronAsrStreamingRNNTDecoder(config) + self.joint = NemotronAsrStreamingRNNTJointNetwork(config) @auto_docstring @can_return_tuple @@ -1118,6 +1148,21 @@ def forward( padding_cache=encoder_outputs.padding_cache, ) + @can_return_tuple + def get_audio_features( + self, + input_features: torch.Tensor, + attention_mask: torch.Tensor | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> NemotronAsrStreamingEncoderModelOutput: + encoder_outputs = self.encoder( + input_features=input_features, + attention_mask=attention_mask, + **kwargs, + ) + encoder_outputs.pooler_output = self.encoder_projector(encoder_outputs.last_hidden_state) + return encoder_outputs + __all__ = [ "NemotronAsrStreamingConfig", diff --git a/src/transformers/models/nemotron_h/modular_nemotron_h.py b/src/transformers/models/nemotron_h/modular_nemotron_h.py index 947b7bc1ae30..1df46ad3c041 100644 --- a/src/transformers/models/nemotron_h/modular_nemotron_h.py +++ b/src/transformers/models/nemotron_h/modular_nemotron_h.py @@ -462,6 +462,10 @@ def forward( class NemotronHForCausalLM(ZambaForCausalLM): _tied_weights_keys = {} + def __init__(self, config: NemotronHConfig): + super().__init__(config) + self.model = NemotronHModel(config) + @staticmethod def create_masks_for_generate(config, inputs_embeds, attention_mask, past_key_values, position_ids=None, **_): # Nemotron-H layer_types include non-attention block types (moe / mlp) that the default dispatch diff --git a/src/transformers/models/olmo/modular_olmo.py b/src/transformers/models/olmo/modular_olmo.py index 46f0af9b1e01..c6dd93bbfb72 100644 --- a/src/transformers/models/olmo/modular_olmo.py +++ b/src/transformers/models/olmo/modular_olmo.py @@ -165,6 +165,8 @@ def __init__(self, config: OlmoConfig, layer_idx: int): self.post_attention_layernorm = OlmoLayerNorm(config.hidden_size) self.self_attn = OlmoAttention(config=config, layer_idx=layer_idx) + self.mlp = OlmoMLP(config) + class OlmoModel(LlamaModel): def __init__(self, config: OlmoConfig): @@ -173,10 +175,13 @@ def __init__(self, config: OlmoConfig): [OlmoDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] ) self.norm = OlmoLayerNorm(config.hidden_size) + self.rotary_emb = OlmoRotaryEmbedding(config=config) class OlmoForCausalLM(LlamaForCausalLM): - pass + def __init__(self, config: OlmoConfig): + super().__init__(config) + self.model = OlmoModel(config) class OlmoForSequenceClassification(LlamaForSequenceClassification): diff --git a/src/transformers/models/olmo2/modular_olmo2.py b/src/transformers/models/olmo2/modular_olmo2.py index 4f8dcffeaae0..5ce647a0a182 100644 --- a/src/transformers/models/olmo2/modular_olmo2.py +++ b/src/transformers/models/olmo2/modular_olmo2.py @@ -204,7 +204,10 @@ def forward( class Olmo2PreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": Olmo2DecoderLayer, + "attentions": Olmo2Attention, + } # The OLMo2 model is identical to the OLMo model, except RMSNorm is used instead of @@ -220,7 +223,9 @@ def __init__(self, config: Olmo2Config): # The heads now only need to redefine the model inside to the correct `RobertaModel` class Olmo2ForCausalLM(OlmoForCausalLM): - pass + def __init__(self, config: Olmo2Config): + super().__init__(config) + self.model = Olmo2Model(config) class Olmo2ForSequenceClassification(OlmoForSequenceClassification): diff --git a/src/transformers/models/olmo3/modular_olmo3.py b/src/transformers/models/olmo3/modular_olmo3.py index 015a3461a073..2db23479a2c0 100644 --- a/src/transformers/models/olmo3/modular_olmo3.py +++ b/src/transformers/models/olmo3/modular_olmo3.py @@ -181,7 +181,9 @@ def forward( class Olmo3DecoderLayer(Olmo2DecoderLayer): - pass + def __init__(self, config: Olmo3Config, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = Olmo3Attention(config=config, layer_idx=layer_idx) class Olmo3RotaryEmbedding(Gemma3RotaryEmbedding): @@ -207,6 +209,11 @@ def forward(self, x, position_ids, layer_type): class Olmo3PreTrainedModel(Olmo2PreTrainedModel): + _can_record_outputs = { + "hidden_states": Olmo3DecoderLayer, + "attentions": Olmo3Attention, + } + def _init_weights(self, module): PreTrainedModel._init_weights(module) if isinstance(module, Olmo3RotaryEmbedding): @@ -294,7 +301,9 @@ def forward( class Olmo3ForCausalLM(Olmo2ForCausalLM): - pass + def __init__(self, config: Olmo3Config): + super().__init__(config) + self.model = Olmo3Model(config) class Olmo3ForSequenceClassification(Olmo2ForSequenceClassification): diff --git a/src/transformers/models/olmo_hybrid/modular_olmo_hybrid.py b/src/transformers/models/olmo_hybrid/modular_olmo_hybrid.py index 304c9c079589..6ee8d85251a6 100644 --- a/src/transformers/models/olmo_hybrid/modular_olmo_hybrid.py +++ b/src/transformers/models/olmo_hybrid/modular_olmo_hybrid.py @@ -545,6 +545,7 @@ def __init__(self, config: OlmoHybridConfig): else None ) self.post_init() + self.norm = OlmoHybridRMSNorm(config.hidden_size, eps=config.rms_norm_eps) @merge_with_config_defaults @capture_outputs @@ -613,7 +614,9 @@ def forward( class OlmoHybridForCausalLM(Olmo3ForCausalLM): - pass + def __init__(self, config: OlmoHybridConfig): + super().__init__(config) + self.model = OlmoHybridModel(config) __all__ = [ diff --git a/src/transformers/models/openai_privacy_filter/modular_openai_privacy_filter.py b/src/transformers/models/openai_privacy_filter/modular_openai_privacy_filter.py index 2d3c6194e402..9f3ce9735da7 100644 --- a/src/transformers/models/openai_privacy_filter/modular_openai_privacy_filter.py +++ b/src/transformers/models/openai_privacy_filter/modular_openai_privacy_filter.py @@ -20,6 +20,7 @@ from torch import nn from torch.nn import functional as F +from ... import initialization as init from ...configuration_utils import PreTrainedConfig from ...integrations import use_experts_implementation from ...masking_utils import create_bidirectional_sliding_window_mask @@ -297,6 +298,7 @@ class OpenAIPrivacyFilterEncoderLayer(GptOssDecoderLayer): def __init__(self, config: OpenAIPrivacyFilterConfig): super().__init__(config) self.self_attn = OpenAIPrivacyFilterAttention(config) + self.mlp = OpenAIPrivacyFilterMLP(config) def forward( self, @@ -350,6 +352,21 @@ def get_correct_experts_implementation(self, requested_experts: str | None) -> s requested_experts = "eager" if requested_experts is None else requested_experts return PreTrainedModel.get_correct_experts_implementation(self, requested_experts) + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + std = self.config.initializer_range + if isinstance(module, OpenAIPrivacyFilterExperts): + init.normal_(module.gate_up_proj, mean=0.0, std=std) + init.zeros_(module.gate_up_proj_bias) + init.normal_(module.down_proj, mean=0.0, std=std) + init.zeros_(module.down_proj_bias) + elif isinstance(module, OpenAIPrivacyFilterAttention): + init.normal_(module.sinks, mean=0.0, std=std) + elif isinstance(module, OpenAIPrivacyFilterTopKRouter): + init.normal_(module.weight, mean=0.0, std=std) + init.normal_(module.bias, mean=0.0, std=std) + @auto_docstring class OpenAIPrivacyFilterModel(GptOssModel): diff --git a/src/transformers/models/ovis2/modular_ovis2.py b/src/transformers/models/ovis2/modular_ovis2.py index 45fabca73f14..9b5c6d15aa3c 100644 --- a/src/transformers/models/ovis2/modular_ovis2.py +++ b/src/transformers/models/ovis2/modular_ovis2.py @@ -364,6 +364,7 @@ class Ovis2ForConditionalGeneration(LlavaForConditionalGeneration, GenerationMix def __init__(self, config: Ovis2Config): super().__init__(config) self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + self.model = Ovis2Model(config) @auto_docstring def get_image_features( diff --git a/src/transformers/models/pe_audio/modular_pe_audio.py b/src/transformers/models/pe_audio/modular_pe_audio.py index cafa6b2d0d33..36727eddd244 100644 --- a/src/transformers/models/pe_audio/modular_pe_audio.py +++ b/src/transformers/models/pe_audio/modular_pe_audio.py @@ -43,6 +43,10 @@ def __init__(self, config: PreTrainedConfig, stride: int = 1, stride_index: int class PeAudioDacEncoder(DacEncoder): def __init__(self, config: PreTrainedConfig): super().__init__(config) + # Create EncoderBlocks that double channels as they downsample by `stride` + for stride_index, stride in enumerate(config.downsampling_ratios): + stride_index = stride_index + 1 + self.block += [PeAudioDacEncoderBlock(config, stride=stride, stride_index=stride_index)] class PeAudioEncoderEmbedder(nn.Module): @@ -121,6 +125,10 @@ class PeAudioEncoderOutput(BaseModelOutputWithPooling): class PeAudioEncoder(PeAudioVideoEncoder): base_model_prefix = "audio_model.audio_encoder" + def __init__(self, config: PeAudioEncoderConfig): + super().__init__(config) + self.embedder = PeAudioEncoderEmbedder(config) + @merge_with_config_defaults @capture_outputs @auto_docstring diff --git a/src/transformers/models/pe_audio_video/modular_pe_audio_video.py b/src/transformers/models/pe_audio_video/modular_pe_audio_video.py index 3a1b63f0acea..8299f78f5b6e 100644 --- a/src/transformers/models/pe_audio_video/modular_pe_audio_video.py +++ b/src/transformers/models/pe_audio_video/modular_pe_audio_video.py @@ -283,6 +283,8 @@ def __init__(self, config, layer_idx): super().__init__(config, layer_idx) del self.attention_type + self.self_attn = PeAudioVideoEncoderAttention(config=config, layer_idx=layer_idx) + class PeAudioVideoEncoderRMSNorm(Qwen3RMSNorm): ... diff --git a/src/transformers/models/perception_lm/modular_perception_lm.py b/src/transformers/models/perception_lm/modular_perception_lm.py index 138c628ca933..b3a53dea0d05 100644 --- a/src/transformers/models/perception_lm/modular_perception_lm.py +++ b/src/transformers/models/perception_lm/modular_perception_lm.py @@ -275,6 +275,10 @@ def forward( @auto_docstring class PerceptionLMForConditionalGeneration(LlavaForConditionalGeneration): + def __init__(self, config: PerceptionLMConfig): + super().__init__(config) + self.model = PerceptionLMModel(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/phi/modular_phi.py b/src/transformers/models/phi/modular_phi.py index 42f355e76a85..129e75f9766f 100644 --- a/src/transformers/models/phi/modular_phi.py +++ b/src/transformers/models/phi/modular_phi.py @@ -193,6 +193,7 @@ def __init__(self, config: PhiConfig): self.embed_dropout = nn.Dropout(config.embd_pdrop) self.final_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) del self.norm + self.rotary_emb = PhiRotaryEmbedding(config=config) @merge_with_config_defaults @capture_outputs @@ -256,6 +257,7 @@ class PhiForCausalLM(LlamaForCausalLM): def __init__(self, config: PhiConfig): super().__init__(config) self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=True) + self.model = PhiModel(config) class PhiForSequenceClassification(LlamaForSequenceClassification): diff --git a/src/transformers/models/phi3/modular_phi3.py b/src/transformers/models/phi3/modular_phi3.py index 45bf7eacdde2..61fc5b1ec1c5 100644 --- a/src/transformers/models/phi3/modular_phi3.py +++ b/src/transformers/models/phi3/modular_phi3.py @@ -205,6 +205,10 @@ def forward( class Phi3PreTrainedModel(MistralPreTrainedModel): _version = "0.0.5" + _can_record_outputs = { + "hidden_states": Phi3DecoderLayer, + "attentions": Phi3Attention, + } class Phi3ForCausalLM(MistralForCausalLM): diff --git a/src/transformers/models/phimoe/modular_phimoe.py b/src/transformers/models/phimoe/modular_phimoe.py index 3a5b37ae1808..f6d78397d3c5 100644 --- a/src/transformers/models/phimoe/modular_phimoe.py +++ b/src/transformers/models/phimoe/modular_phimoe.py @@ -19,6 +19,7 @@ import torch from torch import nn +from ... import initialization as init from ...modeling_layers import ( GenericForSequenceClassification, ) @@ -329,6 +330,10 @@ def __init__(self, config: PhimoeConfig, layer_idx: int): config.hidden_size, eps=config.rms_norm_eps, elementwise_affine=True ) + self.self_attn = PhimoeAttention(config, layer_idx) + + self.mlp = PhimoeSparseMoeBlock(config) + class PhimoePreTrainedModel(MixtralPreTrainedModel): _can_record_outputs = { @@ -337,17 +342,32 @@ class PhimoePreTrainedModel(MixtralPreTrainedModel): "attentions": PhimoeAttention, } + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + std = self.config.initializer_range + if isinstance(module, PhimoeExperts): + init.normal_(module.gate_up_proj, mean=0.0, std=std) + init.normal_(module.down_proj, mean=0.0, std=std) + elif isinstance(module, PhimoeTopKRouter): + init.normal_(module.weight, mean=0.0, std=std) + class PhimoeModel(MixtralModel): def __init__(self, config: PhimoeConfig): super().__init__(config) self.norm = nn.LayerNorm(config.hidden_size, eps=config.rms_norm_eps, elementwise_affine=True) + self.layers = nn.ModuleList( + [PhimoeDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = PhimoeRotaryEmbedding(config=config) class PhimoeForCausalLM(MixtralForCausalLM): def __init__(self, config: PhimoeConfig): super().__init__(config) self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=self.config.lm_head_bias) + self.model = PhimoeModel(config) # Copied from transformers.models.phi3.modeling_phi3.Phi3ForCausalLM.prepare_inputs_for_generation def prepare_inputs_for_generation( diff --git a/src/transformers/models/pixio/modular_pixio.py b/src/transformers/models/pixio/modular_pixio.py index 01702b4fd4b1..5d64c2a2332a 100644 --- a/src/transformers/models/pixio/modular_pixio.py +++ b/src/transformers/models/pixio/modular_pixio.py @@ -17,6 +17,7 @@ from huggingface_hub.dataclasses import strict from torch import nn +from ... import initialization as init from ...backbone_utils import BackboneMixin, filter_output_hidden_states from ...masking_utils import create_bidirectional_mask from ...modeling_outputs import BackboneOutput, BaseModelOutput, BaseModelOutputWithPooling @@ -163,6 +164,7 @@ class PixioLayer(ViTLayer): def __init__(self, config: PixioConfig): super().__init__(config) self.drop_path = PixioDropPath(config.drop_path_rate) if config.drop_path_rate > 0.0 else nn.Identity() + self.mlp = PixioMLP(config) def forward( self, @@ -186,7 +188,21 @@ def forward( class PixioPreTrainedModel(ViTPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": PixioLayer, + "attentions": PixioAttention, + } + + @torch.no_grad() + def _init_weights(self, module): + """Initialize the weights""" + super()._init_weights(module) + if isinstance(module, PixioEmbeddings): + if module.position_embeddings is not None: + init.trunc_normal_(module.position_embeddings, mean=0.0, std=self.config.initializer_range) + init.trunc_normal_(module.cls_token, mean=0.0, std=self.config.initializer_range) + if module.mask_token is not None: + init.zeros_(module.mask_token) @auto_docstring diff --git a/src/transformers/models/plbart/modular_plbart.py b/src/transformers/models/plbart/modular_plbart.py index 9b53aa22e5f5..79c33db9d26a 100644 --- a/src/transformers/models/plbart/modular_plbart.py +++ b/src/transformers/models/plbart/modular_plbart.py @@ -324,6 +324,10 @@ class PLBartClassificationHead(BartClassificationHead): class PLBartForSequenceClassification(BigBirdPegasusForSequenceClassification): + def __init__(self, config: PLBartConfig, **kwargs): + super().__init__(config, **kwargs) + self.model = PLBartModel(config) + def forward(**super_kwargs): r""" decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*): diff --git a/src/transformers/models/pp_doclayout_v3/modular_pp_doclayout_v3.py b/src/transformers/models/pp_doclayout_v3/modular_pp_doclayout_v3.py index e7f174029e6f..806492c10cfe 100644 --- a/src/transformers/models/pp_doclayout_v3/modular_pp_doclayout_v3.py +++ b/src/transformers/models/pp_doclayout_v3/modular_pp_doclayout_v3.py @@ -1015,6 +1015,9 @@ def __init__(self, config: PPDocLayoutV3Config): config.d_model, config.d_model, config.num_prototypes, num_layers=3 ) + # Create encoder + self.encoder = PPDocLayoutV3HybridEncoder(config) + @auto_docstring @can_return_tuple def forward( @@ -1329,6 +1332,7 @@ def __init__(self, config: PPDocLayoutV3Config): self.num_queries = config.num_queries self.post_init() + self.model = PPDocLayoutV3Model(config) @auto_docstring @can_return_tuple diff --git a/src/transformers/models/pp_formulanet/modular_pp_formulanet.py b/src/transformers/models/pp_formulanet/modular_pp_formulanet.py index e56b1d35bdf4..0b69c16ac977 100644 --- a/src/transformers/models/pp_formulanet/modular_pp_formulanet.py +++ b/src/transformers/models/pp_formulanet/modular_pp_formulanet.py @@ -143,6 +143,8 @@ class PPFormulaNetProcessor(NougatProcessor): [`~PPFormulaNetProcessor.__call__`] and [`~PPFormulaNetProcessor.decode`] for more information. """ + valid_processor_kwargs = PPFormulaNetProcessorKwargs + def __init__(self, image_processor, tokenizer): super().__init__(image_processor, tokenizer) @@ -423,6 +425,10 @@ def forward( class PPFormulaNetForConditionalGeneration(Florence2ForConditionalGeneration): _tied_weights_keys = {} + def __init__(self, config: PPFormulaNetConfig): + super().__init__(config) + self.model = PPFormulaNetModel(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/pp_lcnet_v3/modular_pp_lcnet_v3.py b/src/transformers/models/pp_lcnet_v3/modular_pp_lcnet_v3.py index 353c0ffced0d..ca4d0bb0e736 100644 --- a/src/transformers/models/pp_lcnet_v3/modular_pp_lcnet_v3.py +++ b/src/transformers/models/pp_lcnet_v3/modular_pp_lcnet_v3.py @@ -243,7 +243,9 @@ def _init_weights(self, module): class PPLCNetV3Backbone(PPLCNetBackbone): - pass + def __init__(self, config: PPLCNetV3Config): + super().__init__(config) + self.encoder = PPLCNetV3Encoder(config) class PPLCNetV3Encoder(PPLCNetEncoder): diff --git a/src/transformers/models/pp_lcnet_v4/modular_pp_lcnet_v4.py b/src/transformers/models/pp_lcnet_v4/modular_pp_lcnet_v4.py index d6e2cfcb6fa3..e3230342dc5d 100644 --- a/src/transformers/models/pp_lcnet_v4/modular_pp_lcnet_v4.py +++ b/src/transformers/models/pp_lcnet_v4/modular_pp_lcnet_v4.py @@ -251,7 +251,9 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: class PPLCNetV4PreTrainedModel(PPLCNetPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": PPLCNetV4Block, + } class PPLCNetV4Encoder(PPLCNetEncoder): @@ -261,10 +263,15 @@ def __init__(self, config: PPLCNetV4Config): # stem self.convolution = PPLCNetV4LargeStem(config) if config.stem_type == "large" else PPLCNetV4SmallStem(config) + for stage_index in range(len(config.block_configs)): + block = PPLCNetV4Block(config, stage_index) + self.blocks.append(block) class PPLCNetV4Backbone(PPLCNetBackbone): - pass + def __init__(self, config: PPLCNetV4Config): + super().__init__(config) + self.encoder = PPLCNetV4Encoder(config) __all__ = [ diff --git a/src/transformers/models/pp_ocrv5_mobile_det/modular_pp_ocrv5_mobile_det.py b/src/transformers/models/pp_ocrv5_mobile_det/modular_pp_ocrv5_mobile_det.py index 6dc885a6aab6..10c6409d309b 100644 --- a/src/transformers/models/pp_ocrv5_mobile_det/modular_pp_ocrv5_mobile_det.py +++ b/src/transformers/models/pp_ocrv5_mobile_det/modular_pp_ocrv5_mobile_det.py @@ -261,7 +261,10 @@ def forward( """ ) class PPOCRV5MobileDetForObjectDetection(PPOCRV5ServerDetForObjectDetection): - pass + def __init__(self, config: PPOCRV5MobileDetConfig): + super().__init__(config) + self.model = PPOCRV5MobileDetModel(config) + self.head = PPOCRV5MobileDetHead(config) __all__ = [ diff --git a/src/transformers/models/pp_ocrv5_server_rec/modular_pp_ocrv5_server_rec.py b/src/transformers/models/pp_ocrv5_server_rec/modular_pp_ocrv5_server_rec.py index 4412ef459dab..694813bf4f65 100644 --- a/src/transformers/models/pp_ocrv5_server_rec/modular_pp_ocrv5_server_rec.py +++ b/src/transformers/models/pp_ocrv5_server_rec/modular_pp_ocrv5_server_rec.py @@ -262,6 +262,7 @@ def __init__(self, config): in_features=self.embed_dim, hidden_features=int(self.embed_dim * config.mlp_ratio), ) + self.self_attn = PPOCRV5ServerRecAttention(config) def forward( self, diff --git a/src/transformers/models/pp_ocrv6_medium_det/modular_pp_ocrv6_medium_det.py b/src/transformers/models/pp_ocrv6_medium_det/modular_pp_ocrv6_medium_det.py index c1c54ee4d1e0..fa42b14db6bf 100644 --- a/src/transformers/models/pp_ocrv6_medium_det/modular_pp_ocrv6_medium_det.py +++ b/src/transformers/models/pp_ocrv6_medium_det/modular_pp_ocrv6_medium_det.py @@ -127,7 +127,9 @@ def __init__(self, config): @auto_docstring(custom_intro="PPOCRV6MediumDet model for text detection tasks.") class PPOCRV6MediumDetForObjectDetection(PPOCRV5ServerDetForObjectDetection): - pass + def __init__(self, config: PPOCRV6MediumDetConfig): + super().__init__(config) + self.head = PPOCRV6MediumDetHead(config) __all__ = [ diff --git a/src/transformers/models/pp_ocrv6_small_det/modular_pp_ocrv6_small_det.py b/src/transformers/models/pp_ocrv6_small_det/modular_pp_ocrv6_small_det.py index fe29e238ef71..9ac518311439 100644 --- a/src/transformers/models/pp_ocrv6_small_det/modular_pp_ocrv6_small_det.py +++ b/src/transformers/models/pp_ocrv6_small_det/modular_pp_ocrv6_small_det.py @@ -160,7 +160,9 @@ def __init__(self, config: PPOCRV6SmallDetConfig): @auto_docstring(custom_intro="PPOCR6SmallRec model for text recognition tasks.") class PPOCRV6SmallDetForObjectDetection(PPOCRV5ServerDetForObjectDetection): - pass + def __init__(self, config: PPOCRV6SmallDetConfig): + super().__init__(config) + self.head = PPOCRV6SmallDetHead(config) __all__ = [ diff --git a/src/transformers/models/pp_ocrv6_tiny_rec/modular_pp_ocrv6_tiny_rec.py b/src/transformers/models/pp_ocrv6_tiny_rec/modular_pp_ocrv6_tiny_rec.py index f9c722cafdf4..274542aef87d 100644 --- a/src/transformers/models/pp_ocrv6_tiny_rec/modular_pp_ocrv6_tiny_rec.py +++ b/src/transformers/models/pp_ocrv6_tiny_rec/modular_pp_ocrv6_tiny_rec.py @@ -110,6 +110,10 @@ def forward(self, hidden_states: torch.FloatTensor, **kwargs: Unpack[Transformer @auto_docstring(custom_intro="PPOCR6TinyRec model for text recognition tasks.") class PPOCRV6TinyRecForTextRecognition(PPOCRV6SmallRecForTextRecognition): + def __init__(self, config: PPOCRV6TinyRecConfig): + super().__init__(config) + self.head = PPOCRV6TinyRecHead(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/prompt_depth_anything/modular_prompt_depth_anything.py b/src/transformers/models/prompt_depth_anything/modular_prompt_depth_anything.py index 4ed16b2c77db..b47462bc9dbb 100644 --- a/src/transformers/models/prompt_depth_anything/modular_prompt_depth_anything.py +++ b/src/transformers/models/prompt_depth_anything/modular_prompt_depth_anything.py @@ -112,6 +112,11 @@ def forward(self, hidden_state, residual=None, size=None, prompt_depth=None): class PromptDepthAnythingFeatureFusionStage(DepthAnythingFeatureFusionStage): + def __init__(self, config: PromptDepthAnythingConfig): + super().__init__(config) + for _ in range(len(config.neck_hidden_sizes)): + self.layers.append(PromptDepthAnythingFeatureFusionLayer(config)) + def forward(self, hidden_states, size=None, prompt_depth=None): # reversing the hidden_states, we start from the last hidden_states = hidden_states[::-1] @@ -189,10 +194,19 @@ def forward(self, hidden_state): class PromptDepthAnythingReassembleStage(DepthAnythingReassembleStage): - pass + def __init__(self, config): + super().__init__(config) + for channels, factor in zip(config.neck_hidden_sizes, config.reassemble_factors): + self.layers.append(PromptDepthAnythingReassembleLayer(config, channels=channels, factor=factor)) class PromptDepthAnythingNeck(DepthAnythingNeck): + def __init__(self, config): + super().__init__(config) + + # fusion + self.fusion_stage = PromptDepthAnythingFeatureFusionStage(config) + def forward( self, hidden_states: list[torch.Tensor], @@ -228,6 +242,11 @@ def forward( """ ) class PromptDepthAnythingForDepthEstimation(DepthAnythingForDepthEstimation): + def __init__(self, config: PromptDepthAnythingConfig): + super().__init__(config) + self.neck = PromptDepthAnythingNeck(config) + self.head = PromptDepthAnythingDepthEstimationHead(config) + @merge_with_config_defaults @capture_outputs @auto_docstring diff --git a/src/transformers/models/qianfan_ocr/modular_qianfan_ocr.py b/src/transformers/models/qianfan_ocr/modular_qianfan_ocr.py index fb7a9b82bf17..47ae95d8fd67 100644 --- a/src/transformers/models/qianfan_ocr/modular_qianfan_ocr.py +++ b/src/transformers/models/qianfan_ocr/modular_qianfan_ocr.py @@ -19,6 +19,7 @@ import torch.nn as nn from huggingface_hub.dataclasses import strict +from ... import initialization as init from ...configuration_utils import SubConfigSpec from ...image_utils import ImageInput from ...modeling_outputs import BaseModelOutputWithPooling @@ -183,6 +184,20 @@ class QianfanOCRVisionPreTrainedModel(InternVLVisionPreTrainedModel): "attentions": QianfanOCRVisionAttention, } + @torch.no_grad() + def _init_weights(self, module): + """Initialize the weights""" + super()._init_weights(module) + if isinstance(module, QianfanOCRVisionEmbeddings): + init.zeros_(module.cls_token) + if module.mask_token is not None: + init.zeros_(module.mask_token) + if module.position_embeddings is not None: + init.zeros_(module.position_embeddings) + elif isinstance(module, QianfanOCRVisionLayer): + init.constant_(module.lambda_1, self.config.layer_scale_init_value) + init.constant_(module.lambda_2, self.config.layer_scale_init_value) + @auto_docstring class QianfanOCRVisionModel(InternVLVisionModel): diff --git a/src/transformers/models/qwen2/modular_qwen2.py b/src/transformers/models/qwen2/modular_qwen2.py index bcc1496d3acf..d8c08b75e00c 100644 --- a/src/transformers/models/qwen2/modular_qwen2.py +++ b/src/transformers/models/qwen2/modular_qwen2.py @@ -99,11 +99,19 @@ def forward( class Qwen2DecoderLayer(LlamaDecoderLayer): - pass + def __init__(self, config: Qwen2Config, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = Qwen2Attention(config=config, layer_idx=layer_idx) + + self.mlp = Qwen2MLP(config) class Qwen2PreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": Qwen2DecoderLayer, + "attentions": Qwen2Attention, + } class Qwen2Model(MistralModel): @@ -178,7 +186,9 @@ def forward( class Qwen2ForCausalLM(LlamaForCausalLM): - pass + def __init__(self, config: Qwen2Config): + super().__init__(config) + self.model = Qwen2Model(config) class Qwen2ForSequenceClassification(LlamaForSequenceClassification): diff --git a/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py b/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py index 63fc84eaac0e..20844d3b165f 100644 --- a/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py +++ b/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py @@ -30,7 +30,7 @@ from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import BaseModelOutputWithPooling from ...modeling_utils import slice_logits_to_keep -from ...processing_utils import ProcessingKwargs, Unpack +from ...processing_utils import MultiModalData, ProcessingKwargs, Unpack from ...utils import auto_docstring, logging from ...utils.generic import get_max_seqlen, merge_with_config_defaults from ...utils.output_capturing import capture_outputs @@ -101,7 +101,10 @@ class Qwen2_5_VLTextConfig(Qwen2VLTextConfig): class Qwen2_5_VLConfig(Qwen2VLConfig): - pass + sub_configs_defaults = { + "vision_config": Qwen2_5_VLVisionConfig, + "text_config": Qwen2_5_VLTextConfig, + } class Qwen2_5_VLRMSNorm(LlamaRMSNorm): @@ -577,6 +580,10 @@ class Qwen2_5_VLForConditionalGeneration(Qwen2VLForConditionalGeneration): # Reference: fix gemma3 grad acc #37208 accepts_loss_kwargs = False + def __init__(self, config: Qwen2_5_VLConfig): + super().__init__(config) + self.model = Qwen2_5_VLModel(config) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -686,6 +693,8 @@ class Qwen2_5_VLProcessorKwargs(ProcessingKwargs, total=False): class Qwen2_5_VLProcessor(Qwen2VLProcessor): + valid_processor_kwargs = Qwen2_5_VLProcessorKwargs + def _process_videos(self, videos: VideoInput, **kwargs): processed_data, video_replacements = super()._process_videos(videos, **kwargs) video_grid_thw = processed_data["video_grid_thw"] @@ -708,6 +717,44 @@ def _process_videos(self, videos: VideoInput, **kwargs): def model_input_names(self): return super().model_input_names + ["second_per_grid_ts", "mm_token_type_ids"] + def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): + """ + Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. + Args: + image_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (height, width) per each image. + video_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (num_frames, height, width) per each video. + Returns: + `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided + input modalities, along with other useful data. + """ + + vision_data = {} + if image_sizes is not None: + images_kwargs = Qwen2_5_VLProcessorKwargs._defaults.get("images_kwargs", {}) + images_kwargs.update(kwargs) + merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size + + num_image_patches = [ + self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) + for image_size in image_sizes + ] + num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] + vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) + + if video_sizes is not None: + videos_kwargs = Qwen2_5_VLProcessorKwargs._defaults.get("videos_kwargs", {}) + videos_kwargs.update(kwargs) + merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size + num_video_patches = [ + self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes + ] + num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] + vision_data["num_video_tokens"] = num_video_tokens + + return MultiModalData(**vision_data) + __all__ = [ "Qwen2_5_VLConfig", diff --git a/src/transformers/models/qwen2_moe/modular_qwen2_moe.py b/src/transformers/models/qwen2_moe/modular_qwen2_moe.py index 613ed9f1c721..6e36cb6eea7a 100644 --- a/src/transformers/models/qwen2_moe/modular_qwen2_moe.py +++ b/src/transformers/models/qwen2_moe/modular_qwen2_moe.py @@ -22,6 +22,7 @@ import torch.nn.functional as F from torch import nn +from ... import initialization as init from ...activations import ACT2FN from ...cache_utils import Cache, DynamicCache from ...generation import GenerationMixin @@ -153,6 +154,16 @@ class Qwen2MoePreTrainedModel(MixtralPreTrainedModel): "attentions": Qwen2MoeAttention, } + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + std = self.config.initializer_range + if isinstance(module, Qwen2MoeExperts): + init.normal_(module.gate_up_proj, mean=0.0, std=std) + init.normal_(module.down_proj, mean=0.0, std=std) + elif isinstance(module, Qwen2MoeTopKRouter): + init.normal_(module.weight, mean=0.0, std=std) + @auto_docstring class Qwen2MoeModel(MixtralModel): diff --git a/src/transformers/models/qwen3_5/modular_qwen3_5.py b/src/transformers/models/qwen3_5/modular_qwen3_5.py index 171cbb6b71da..36e788b14978 100644 --- a/src/transformers/models/qwen3_5/modular_qwen3_5.py +++ b/src/transformers/models/qwen3_5/modular_qwen3_5.py @@ -176,6 +176,10 @@ class Qwen3_5Config(Qwen3VLConfig): video_token_id: int = 248057 vision_start_token_id: int = 248053 vision_end_token_id: int = 248054 + sub_configs_defaults = { + "vision_config": Qwen3_5VisionConfig, + "text_config": Qwen3_5TextConfig, + } class Qwen3_5VisionRotaryEmbedding(Qwen3VLVisionRotaryEmbedding): @@ -340,7 +344,10 @@ def forward( class Qwen3_5Attention(Qwen3NextAttention): - pass + def __init__(self, config: Qwen3_5Config, layer_idx: int): + super().__init__(config, layer_idx) + self.q_norm = Qwen3_5RMSNorm(self.head_dim, eps=config.rms_norm_eps) # unlike olmo, only on the head dim! + self.k_norm = Qwen3_5RMSNorm(self.head_dim, eps=config.rms_norm_eps) # thus post q_norm does not need reshape class Qwen3_5MLP(Qwen3NextMLP): @@ -501,6 +508,10 @@ class Qwen3_5TextModel(Qwen3NextModel): def __init__(self, config: Qwen3_5TextConfig): super().__init__(config) self.rotary_emb = Qwen3_5TextRotaryEmbedding(config=config) + self.layers = nn.ModuleList( + [Qwen3_5DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = Qwen3_5RMSNorm(config.hidden_size, eps=config.rms_norm_eps) def forward( self, @@ -644,6 +655,10 @@ class Qwen3_5ForTokenClassification(GenericForTokenClassification, Qwen3_5PreTra class Qwen3_5ForConditionalGeneration(Qwen3VLForConditionalGeneration): input_modalities = ("image", "video", "text") + def __init__(self, config: Qwen3_5Config): + super().__init__(config) + self.model = Qwen3_5Model(config) + def get_video_features(self, **super_kwargs) -> tuple | BaseModelOutputWithPooling: return super().get_video_features(**super_kwargs) diff --git a/src/transformers/models/qwen3_5_moe/modular_qwen3_5_moe.py b/src/transformers/models/qwen3_5_moe/modular_qwen3_5_moe.py index 8ab0d69010a8..8db666dbe4ed 100644 --- a/src/transformers/models/qwen3_5_moe/modular_qwen3_5_moe.py +++ b/src/transformers/models/qwen3_5_moe/modular_qwen3_5_moe.py @@ -15,15 +15,19 @@ import torch from huggingface_hub.dataclasses import strict +from torch import nn from ... import initialization as init -from ...cache_utils import Cache +from ...cache_utils import Cache, DynamicCache from ...integrations import use_kernel_forward_from_hub, use_kernelized_func +from ...masking_utils import create_causal_mask, create_recurrent_attention_mask from ...modeling_layers import GradientCheckpointingLayer -from ...modeling_outputs import BaseModelOutputWithPooling +from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, logging, no_inherit_decorator +from ...utils.generic import merge_with_config_defaults +from ...utils.output_capturing import OutputRecorder, capture_outputs from ..qwen3_5.configuration_qwen3_5 import Qwen3_5VisionConfig from ..qwen3_5.modeling_qwen3_5 import ( Qwen3_5GatedDeltaNet, @@ -157,6 +161,10 @@ class Qwen3_5MoeConfig(Qwen3VLConfig): video_token_id: int = 248057 vision_start_token_id: int = 248053 vision_end_token_id: int = 248054 + sub_configs_defaults = { + "vision_config": Qwen3_5MoeVisionConfig, + "text_config": Qwen3_5MoeTextConfig, + } class Qwen3_5MoeVisionRotaryEmbedding(Qwen3_5VisionRotaryEmbedding): @@ -177,7 +185,12 @@ class Qwen3_5MoeGatedDeltaNet(Qwen3_5GatedDeltaNet): @no_inherit_decorator class Qwen3_5MoeAttention(Qwen3NextAttention): - pass + def __init__(self, config: Qwen3_5MoeConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.q_norm = Qwen3_5MoeRMSNorm(self.head_dim, eps=config.rms_norm_eps) # unlike olmo, only on the head dim! + self.k_norm = Qwen3_5MoeRMSNorm( + self.head_dim, eps=config.rms_norm_eps + ) # thus post q_norm does not need reshape class Qwen3_5MoeMLP(Qwen3_5MLP): @@ -194,7 +207,10 @@ class Qwen3_5MoeTopKRouter(Qwen3VLMoeTextTopKRouter): class Qwen3_5MoeSparseMoeBlock(Qwen3NextSparseMoeBlock): - pass + def __init__(self, config): + super().__init__(config) + self.gate = Qwen3_5MoeTopKRouter(config) + self.shared_expert = Qwen3_5MoeMLP(config, intermediate_size=config.shared_expert_intermediate_size) @use_kernel_forward_from_hub("RMSNormZeroCentered") @@ -218,6 +234,11 @@ def __init__(self, config: Qwen3_5MoeTextConfig, layer_idx: int): class Qwen3_5MoePreTrainedModel(Qwen3NextPreTrainedModel): _no_split_modules = ["Qwen3_5MoeDecoderLayer", "Qwen3_5MoeVisionBlock"] + _can_record_outputs = { + "router_logits": OutputRecorder(Qwen3_5MoeTopKRouter, index=0), + "hidden_states": Qwen3_5MoeDecoderLayer, + "attentions": Qwen3_5MoeAttention, + } def _init_weights(self, module): PreTrainedModel._init_weights(self, module) @@ -251,7 +272,83 @@ class Qwen3_5MoeCausalLMOutputWithPast(Qwen3VLMoeCausalLMOutputWithPast): class Qwen3_5MoeTextModel(Qwen3_5TextModel): - pass + def __init__(self, config: Qwen3_5MoeTextConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [Qwen3_5MoeDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + + @merge_with_config_defaults + @capture_outputs + @auto_docstring + def forward( + self, + input_ids: torch.LongTensor | None = None, + attention_mask: torch.Tensor | None = None, + position_ids: torch.LongTensor | None = None, + past_key_values: Cache | None = None, + inputs_embeds: torch.FloatTensor | None = None, + use_cache: bool | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> BaseModelOutputWithPast: + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError("You must specify exactly one of input_ids or inputs_embeds") + + if inputs_embeds is None: + inputs_embeds = self.embed_tokens(input_ids) + + if use_cache and past_key_values is None: + past_key_values = DynamicCache(config=self.config) + + # the hard coded `4` is for text, temporal, height and width. + if position_ids is None: + past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0 + position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens + position_ids = position_ids.view(1, 1, -1).expand(4, inputs_embeds.shape[0], -1) + elif position_ids.ndim == 2: + position_ids = position_ids[None, ...].expand(4, position_ids.shape[0], -1) + + if position_ids.ndim == 3 and position_ids.shape[0] == 4: + text_position_ids = position_ids[0] + position_ids = position_ids[1:] + else: + text_position_ids = None + + if not isinstance(causal_mask_mapping := attention_mask, dict): + # Prepare mask arguments + mask_kwargs = { + "config": self.config, + "inputs_embeds": inputs_embeds, + "attention_mask": attention_mask, + "past_key_values": past_key_values, + "position_ids": text_position_ids, + } + # Create the masks + causal_mask_mapping = { + "full_attention": create_causal_mask(**mask_kwargs), + "linear_attention": create_recurrent_attention_mask(**mask_kwargs), + } + + hidden_states = inputs_embeds + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for i, decoder_layer in enumerate(self.layers[: self.config.num_hidden_layers]): + hidden_states = decoder_layer( + hidden_states, + position_embeddings=position_embeddings, + attention_mask=causal_mask_mapping[self.config.layer_types[i]], + position_ids=text_position_ids, + past_key_values=past_key_values, + use_cache=use_cache, + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + + return Qwen3_5MoeModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) class Qwen3_5MoeModel(Qwen3_5Model): @@ -354,6 +451,10 @@ class Qwen3_5MoeForConditionalGeneration(Qwen3VLMoeForConditionalGeneration): _fsdp_plan = {"lm_head": "keep_full_weight"} + def __init__(self, config: Qwen3_5MoeConfig): + super().__init__(config) + self.model = Qwen3_5MoeModel(config) + def forward(self, **super_kwargs): r""" Example: diff --git a/src/transformers/models/qwen3_moe/modular_qwen3_moe.py b/src/transformers/models/qwen3_moe/modular_qwen3_moe.py index 65fb6c0f0e9e..233815a8a050 100644 --- a/src/transformers/models/qwen3_moe/modular_qwen3_moe.py +++ b/src/transformers/models/qwen3_moe/modular_qwen3_moe.py @@ -16,6 +16,7 @@ import torch from torch import nn +from ... import initialization as init from ...cache_utils import Cache from ...modeling_outputs import MoeCausalLMOutputWithPast, MoeModelOutputWithPast from ...modeling_utils import slice_logits_to_keep @@ -80,7 +81,15 @@ class Qwen3MoeRMSNorm(LlamaRMSNorm): class Qwen3MoeDecoderLayer(Qwen2MoeDecoderLayer): - pass + def __init__(self, config: Qwen3MoeConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = Qwen3MoeAttention(config, layer_idx) + if (layer_idx not in config.mlp_only_layers) and ( + config.num_experts > 0 and (layer_idx + 1) % config.decoder_sparse_step == 0 + ): + self.mlp = Qwen3MoeSparseMoeBlock(config) + else: + self.mlp = Qwen3MoeMLP(config, intermediate_size=config.intermediate_size) class Qwen3MoePreTrainedModel(MixtralPreTrainedModel): @@ -90,9 +99,23 @@ class Qwen3MoePreTrainedModel(MixtralPreTrainedModel): "attentions": Qwen3MoeAttention, } + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + std = self.config.initializer_range + if isinstance(module, Qwen3MoeExperts): + init.normal_(module.gate_up_proj, mean=0.0, std=std) + init.normal_(module.down_proj, mean=0.0, std=std) + elif isinstance(module, Qwen3MoeTopKRouter): + init.normal_(module.weight, mean=0.0, std=std) + class Qwen3MoeModel(MixtralModel): - pass + def __init__(self, config: Qwen3MoeConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [Qwen3MoeDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) class Qwen3MoeForCausalLM(MixtralForCausalLM): diff --git a/src/transformers/models/qwen3_next/modular_qwen3_next.py b/src/transformers/models/qwen3_next/modular_qwen3_next.py index 41c2801da2cb..3ac55c1cb370 100644 --- a/src/transformers/models/qwen3_next/modular_qwen3_next.py +++ b/src/transformers/models/qwen3_next/modular_qwen3_next.py @@ -109,6 +109,10 @@ def __init__(self, config: Qwen3NextConfig, layer_idx: int): config.hidden_size, config.num_attention_heads * self.head_dim * 2, bias=config.attention_bias ) del self.sliding_window + self.q_norm = Qwen3NextRMSNorm(self.head_dim, eps=config.rms_norm_eps) # unlike olmo, only on the head dim! + self.k_norm = Qwen3NextRMSNorm( + self.head_dim, eps=config.rms_norm_eps + ) # thus post q_norm does not need reshape def forward( self, @@ -807,6 +811,7 @@ class Qwen3NextForCausalLM(MixtralForCausalLM): def __init__(self, config: Qwen3NextConfig): super().__init__(config) self.num_experts = config.num_experts + self.model = Qwen3NextModel(config) def forward( self, diff --git a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py index 583ecc8e6cf2..3df1c9f06695 100644 --- a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py +++ b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py @@ -30,9 +30,11 @@ from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling from ...modeling_rope_utils import RopeParameters from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, slice_logits_to_keep -from ...processing_utils import ProcessingKwargs, Unpack, VideosKwargs +from ...processing_utils import MultiModalData, ProcessingKwargs, Unpack, VideosKwargs from ...utils import auto_docstring, is_torchvision_available, logging from ...utils.generic import ( + get_max_seqlen, + is_flash_attention_requested, merge_with_config_defaults, ) from ...utils.output_capturing import capture_outputs @@ -51,6 +53,7 @@ Qwen2_5_VLRotaryEmbedding, Qwen2_5_VLVisionBlock, Qwen2_5_VLVisionRotaryEmbedding, + apply_rotary_pos_emb_vision, ) from ..qwen2_vl.modeling_qwen2_vl import ( PatchEmbed, @@ -261,6 +264,74 @@ def __init__(self, config: Qwen3VLVisionConfig) -> None: super().__init__() self.dim = config.hidden_size + def forward( + self, + hidden_states: torch.Tensor, + cu_seqlens: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, + max_seqlen: int | None = None, + **kwargs, + ) -> torch.Tensor: + seq_length = hidden_states.shape[0] + query_states, key_states, value_states = ( + self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0) + ) + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb_vision(query_states, key_states, cos, sin) + + query_states = query_states.transpose(0, 1).unsqueeze(0) + key_states = key_states.transpose(0, 1).unsqueeze(0) + value_states = value_states.transpose(0, 1).unsqueeze(0) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + if is_flash_attention_requested(self.config): + # Flash Attention: Use cu_seqlens for variable length attention + max_seqlen = get_max_seqlen(cu_seqlens, self.config, kwargs={"max_seqlen": max_seqlen}) + attn_output, _ = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + cu_seq_lens_q=cu_seqlens, + cu_seq_lens_k=cu_seqlens, + max_length_q=max_seqlen, + max_length_k=max_seqlen, + is_causal=False, + **kwargs, + ) + else: + # Other implementations: Process each chunk separately + lengths = cu_seqlens[1:] - cu_seqlens[:-1] + splits = [ + torch.split(tensor, lengths.tolist(), dim=2) for tensor in (query_states, key_states, value_states) + ] + + attn_outputs = [ + attention_interface( + self, + q, + k, + v, + attention_mask=None, + scaling=self.scaling, + dropout=0.0 if not self.training else self.attention_dropout, + is_causal=False, + **kwargs, + )[0] + for q, k, v in zip(*splits) + ] + attn_output = torch.cat(attn_outputs, dim=1) + + attn_output = attn_output.reshape(seq_length, -1).contiguous() + attn_output = self.proj(attn_output) + return attn_output + class Qwen3VLVisionBlock(Qwen2_5_VLVisionBlock): def __init__(self, config, attn_implementation: str = "sdpa") -> None: @@ -344,6 +415,8 @@ def __init__(self, config: Qwen3VLTextConfig, layer_idx: int): super().__init__(config, layer_idx) del self.attention_type + self.self_attn = Qwen3VLTextAttention(config=config, layer_idx=layer_idx) + def forward( self, hidden_states: torch.Tensor, @@ -496,6 +569,10 @@ class Qwen3VLTextModel(Qwen3VLPreTrainedModel, Qwen3Model): def __init__(self, config: Qwen3VLTextConfig): super().__init__(config) del self.has_sliding_layers + self.layers = nn.ModuleList( + [Qwen3VLTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = Qwen3VLTextRotaryEmbedding(config=config) def _deepstack_process( self, hidden_states: torch.Tensor, visual_pos_masks: torch.Tensor, visual_embeds: torch.Tensor @@ -785,6 +862,10 @@ class Qwen3VLCausalLMOutputWithPast(Qwen2_5_VLCausalLMOutputWithPast): class Qwen3VLForConditionalGeneration(Qwen2_5_VLForConditionalGeneration): + def __init__(self, config: Qwen3VLConfig): + super().__init__(config) + self.model = Qwen3VLModel(config) + @auto_docstring def get_image_features(self, **super_kwargs) -> tuple | BaseModelOutputWithDeepstackFeatures: return super().get_image_features(**super_kwargs) @@ -896,6 +977,8 @@ class Qwen3VLProcessorKwargs(ProcessingKwargs, total=False): class Qwen3VLProcessor(Qwen2VLProcessor): + valid_processor_kwargs = Qwen3VLProcessorKwargs + def __init__(self, image_processor=None, tokenizer=None, video_processor=None, chat_template=None, **kwargs): super().__init__(image_processor, tokenizer, video_processor, chat_template, **kwargs) self.vision_start_token = ( @@ -956,6 +1039,44 @@ def _calculate_timestamps(self, indices: list[int] | np.ndarray, video_fps: floa ] return timestamps + def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): + """ + Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. + Args: + image_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (height, width) per each image. + video_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (num_frames, height, width) per each video. + Returns: + `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided + input modalities, along with other useful data. + """ + + vision_data = {} + if image_sizes is not None: + images_kwargs = Qwen3VLProcessorKwargs._defaults.get("images_kwargs", {}) + images_kwargs.update(kwargs) + merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size + + num_image_patches = [ + self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) + for image_size in image_sizes + ] + num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] + vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) + + if video_sizes is not None: + videos_kwargs = Qwen3VLProcessorKwargs._defaults.get("videos_kwargs", {}) + videos_kwargs.update(kwargs) + merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size + num_video_patches = [ + self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes + ] + num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] + vision_data["num_video_tokens"] = num_video_tokens + + return MultiModalData(**vision_data) + class Qwen3VLVideoProcessorInitKwargs(VideosKwargs, total=False): r""" @@ -1005,6 +1126,7 @@ class Qwen3VLVideoProcessor(Qwen2VLVideoProcessor): fps = 2 cap_pixels_per_frame = None max_video_tokens = 768 + valid_kwargs = Qwen3VLVideoProcessorInitKwargs def __init__(self, **kwargs: Unpack[Qwen3VLVideoProcessorInitKwargs]): BaseVideoProcessor.__init__(self, **kwargs) diff --git a/src/transformers/models/qwen4_exp/modular_qwen4_exp.py b/src/transformers/models/qwen4_exp/modular_qwen4_exp.py index b6656a4d332d..0c880ac870f0 100644 --- a/src/transformers/models/qwen4_exp/modular_qwen4_exp.py +++ b/src/transformers/models/qwen4_exp/modular_qwen4_exp.py @@ -14,6 +14,7 @@ """PyTorch Qwen4-Exp model.""" import math +from collections.abc import Callable import torch import torch.nn.functional as F @@ -27,7 +28,7 @@ from ...masking_utils import create_causal_mask, create_recurrent_attention_mask from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling -from ...modeling_utils import PreTrainedModel +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, logging from ...utils.generic import merge_with_config_defaults, no_inherit_decorator @@ -40,6 +41,7 @@ apply_mask_to_padding_states, causal_conv1d_fn, causal_conv1d_update, + eager_attention_forward, rotate_half, torch_chunk_gated_delta_rule, torch_recurrent_gated_delta_rule, @@ -289,6 +291,10 @@ class Qwen4ExpConfig(Qwen3_5MoeConfig): model_type = "qwen4_exp" base_model_fsdp_plan = None + sub_configs_defaults = { + "vision_config": Qwen4ExpVisionConfig, + "text_config": Qwen4ExpTextConfig, + } class Qwen4ExpTextRotaryEmbedding(Qwen3_5TextRotaryEmbedding): @@ -498,15 +504,45 @@ def forward( # The cos/sin are the full positions here due to the indexer, so we need to slice to get current positions position_embeddings = (x[:, -hidden_states.shape[1] :, :] for x in position_embeddings) + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) - return super().forward( - hidden_states=hidden_states, - position_embeddings=position_embeddings, - attention_mask=attention_mask, - past_key_values=past_key_values, + query_states, gate = torch.chunk( + self.q_proj(hidden_states).view(*input_shape, -1, self.head_dim * 2), 2, dim=-1 + ) + gate = gate.reshape(*input_shape, -1) + + query_states = self.q_norm(query_states.view(hidden_shape)).transpose(1, 2) + key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) + + if past_key_values is not None: + key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, **kwargs, ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = attn_output * torch.sigmoid(gate) + + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + class Qwen4ExpTextMLP(Qwen3NextMLP): pass @@ -1037,6 +1073,10 @@ def forward( class Qwen4ExpForCausalLM(Qwen3_5MoeForCausalLM): config: Qwen4ExpTextConfig + def __init__(self, config: Qwen4ExpTextConfig): + super().__init__(config) + self.model = Qwen4ExpTextModel(config) + @auto_docstring class Qwen4ExpVisionModel(Qwen3_5MoeVisionModel): @@ -1140,7 +1180,9 @@ def forward( @auto_docstring class Qwen4ExpForConditionalGeneration(Qwen3_5MoeForConditionalGeneration): - pass + def __init__(self, config: Qwen4ExpConfig): + super().__init__(config) + self.model = Qwen4ExpModel(config) __all__ = [ diff --git a/src/transformers/models/radio/modular_radio.py b/src/transformers/models/radio/modular_radio.py index f5e8ffcc7667..8d6cf29c247b 100644 --- a/src/transformers/models/radio/modular_radio.py +++ b/src/transformers/models/radio/modular_radio.py @@ -246,7 +246,9 @@ def forward( class RadioLayer(Dinov2Layer): - pass + def __init__(self, config: RadioConfig) -> None: + super().__init__(config) + self.attention = RadioAttention(config) @auto_docstring diff --git a/src/transformers/models/roberta/modular_roberta.py b/src/transformers/models/roberta/modular_roberta.py index 4bb19815d66f..b1b1c2bd4c15 100644 --- a/src/transformers/models/roberta/modular_roberta.py +++ b/src/transformers/models/roberta/modular_roberta.py @@ -178,6 +178,8 @@ class RobertaModel(BertModel): def __init__(self, config: RobertaConfig, add_pooling_layer=True): super().__init__(self, config) + self.embeddings = RobertaEmbeddings(config) + @auto_docstring( custom_intro=""" diff --git a/src/transformers/models/sam2/modular_sam2.py b/src/transformers/models/sam2/modular_sam2.py index 2b9abe9afafb..ac82ea7ff792 100644 --- a/src/transformers/models/sam2/modular_sam2.py +++ b/src/transformers/models/sam2/modular_sam2.py @@ -44,7 +44,7 @@ is_flash_attention_requested, merge_with_config_defaults, ) -from ...utils.output_capturing import capture_outputs +from ...utils.output_capturing import OutputRecorder, capture_outputs from ..auto import AutoModel from ..detr.modeling_detr import DetrSinePositionEmbedding from ..sam.image_processing_sam import SamImageProcessor @@ -955,7 +955,13 @@ def __init__(self, config: Sam2MaskDecoderConfig, skip_first_layer_pe: bool = Fa class Sam2TwoWayTransformer(SamTwoWayTransformer): - pass + def __init__(self, config: Sam2MaskDecoderConfig): + super().__init__(config) + + for i in range(self.num_hidden_layers): + self.layers.append(Sam2TwoWayAttentionBlock(config, skip_first_layer_pe=(i == 0))) + + self.final_attn_token_to_image = Sam2Attention(config) class Sam2LayerNorm(SamLayerNorm): @@ -1153,6 +1159,7 @@ def forward( ) class Sam2Model(SamModel): _tied_weights_keys = {} + _can_record_outputs = {"mask_decoder_attentions": OutputRecorder(Sam2TwoWayAttentionBlock, index=2)} def __init__(self, config: Sam2Config): PreTrainedModel.__init__(self, config) diff --git a/src/transformers/models/sam3_tracker_video/modular_sam3_tracker_video.py b/src/transformers/models/sam3_tracker_video/modular_sam3_tracker_video.py index 7b1f1f2e7187..e634430583e8 100644 --- a/src/transformers/models/sam3_tracker_video/modular_sam3_tracker_video.py +++ b/src/transformers/models/sam3_tracker_video/modular_sam3_tracker_video.py @@ -16,6 +16,7 @@ import torch from huggingface_hub.dataclasses import strict +from ... import initialization as init from ...configuration_utils import PreTrainedConfig, SubConfigSpec from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging @@ -335,6 +336,27 @@ class Sam3TrackerVideoSegmentationOutput(Sam2VideoSegmentationOutput): class Sam3TrackerVideoPreTrainedModel(Sam2VideoPreTrainedModel): base_model_prefix = "tracker_model" + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + if isinstance(module, Sam3TrackerVideoModel): + if module.no_memory_positional_encoding is not None: + init.zeros_(module.no_memory_positional_encoding) + if module.memory_temporal_positional_encoding is not None: + init.zeros_(module.memory_temporal_positional_encoding) + if module.no_object_pointer is not None: + init.zeros_(module.no_object_pointer) + if module.occlusion_spatial_embedding_parameter is not None: + init.zeros_(module.occlusion_spatial_embedding_parameter) + if isinstance(module, Sam3TrackerVideoMemoryFuserCXBlock): + if module.scale is not None: + init.zeros_(module.scale) + elif isinstance(module, Sam3TrackerVideoPositionalEmbedding): + init.normal_(module.positional_embedding, std=module.scale) + elif isinstance(module, Sam3TrackerVideoMemoryAttention): + position_ids = module.precompute_positions(module.config) + init.copy_(module.position_ids, position_ids) + class Sam3TrackerVideoVisionRotaryEmbedding(Sam2VideoVisionRotaryEmbedding): def __init__(self, config: Sam3TrackerVideoConfig, device=None): diff --git a/src/transformers/models/sapiens2/modular_sapiens2.py b/src/transformers/models/sapiens2/modular_sapiens2.py index c83910762ec8..892687498a12 100644 --- a/src/transformers/models/sapiens2/modular_sapiens2.py +++ b/src/transformers/models/sapiens2/modular_sapiens2.py @@ -1594,6 +1594,10 @@ class Sapiens2PreTrainedModel(DINOv3ViTPreTrainedModel): _keys_to_ignore_on_load_unexpected = [r"periods"] # mask_token is only used for masked image modeling pretraining and is absent in most checkpoints. _keys_to_ignore_on_load_missing = [r"mask_token"] + _can_record_outputs = { + "hidden_states": Sapiens2Layer, + "attentions": Sapiens2Attention, + } @torch.no_grad() def _init_weights(self, module) -> None: @@ -1633,6 +1637,8 @@ class Sapiens2Model(DINOv3ViTModel): def __init__(self, config: Sapiens2Config): super().__init__(config) self.norm = Sapiens2RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.embeddings = Sapiens2Embeddings(config) + self.model = Sapiens2Encoder(config) def forward( self, @@ -1672,6 +1678,8 @@ class Sapiens2Backbone(DINOv3ViTBackbone): def __init__(self, config: Sapiens2Config): super().__init__(config) self.norm = Sapiens2RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.embeddings = Sapiens2Embeddings(config) + self.model = Sapiens2Encoder(config) def forward( self, diff --git a/src/transformers/models/seed_oss/modular_seed_oss.py b/src/transformers/models/seed_oss/modular_seed_oss.py index a00810a8ce75..58888e034163 100644 --- a/src/transformers/models/seed_oss/modular_seed_oss.py +++ b/src/transformers/models/seed_oss/modular_seed_oss.py @@ -138,11 +138,19 @@ def forward( class SeedOssDecoderLayer(LlamaDecoderLayer): - pass + def __init__(self, config: SeedOssConfig, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = SeedOssAttention(config=config, layer_idx=layer_idx) + + self.mlp = SeedOssMLP(config) class SeedOssPreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": SeedOssDecoderLayer, + "attentions": SeedOssAttention, + } class SeedOssModel(LlamaModel): diff --git a/src/transformers/models/sew/modular_sew.py b/src/transformers/models/sew/modular_sew.py index 7398ca9dc0e5..a01679281d78 100644 --- a/src/transformers/models/sew/modular_sew.py +++ b/src/transformers/models/sew/modular_sew.py @@ -389,11 +389,16 @@ def forward( class SEWForCTC(Wav2Vec2ForCTC): - pass + def __init__(self, config: SEWConfig, target_lang: str | None = None): + super().__init__(config, target_lang) + + self.sew = SEWModel(config) class SEWForSequenceClassification(Wav2Vec2ForSequenceClassification): - pass + def __init__(self, config: SEWConfig): + super().__init__(config) + self.sew = SEWModel(config) __all__ = ["SEWForCTC", "SEWForSequenceClassification", "SEWModel", "SEWPreTrainedModel"] diff --git a/src/transformers/models/slanet/modular_slanet.py b/src/transformers/models/slanet/modular_slanet.py index bc9d764dd526..fb784b27f149 100644 --- a/src/transformers/models/slanet/modular_slanet.py +++ b/src/transformers/models/slanet/modular_slanet.py @@ -350,6 +350,10 @@ def forward( class SLANetForTableRecognition(SLANeXtForTableRecognition): _keys_to_ignore_on_load_missing = ["num_batches_tracked"] + def __init__(self, config: SLANetConfig): + super().__init__(config) + self.backbone = SLANetBackbone(config=config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/smollm3/modular_smollm3.py b/src/transformers/models/smollm3/modular_smollm3.py index f75017ad2645..67b7bc55ede7 100644 --- a/src/transformers/models/smollm3/modular_smollm3.py +++ b/src/transformers/models/smollm3/modular_smollm3.py @@ -190,11 +190,17 @@ def forward( class SmolLM3DecoderLayer(LlamaDecoderLayer): - pass + def __init__(self, config: SmolLM3Config, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = SmolLM3Attention(config=config, layer_idx=layer_idx) class SmolLM3PreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": SmolLM3DecoderLayer, + "attentions": SmolLM3Attention, + } class SmolLM3Model(Qwen2Model): @@ -202,7 +208,9 @@ class SmolLM3Model(Qwen2Model): class SmolLM3ForCausalLM(LlamaForCausalLM): - pass + def __init__(self, config: SmolLM3Config): + super().__init__(config) + self.model = SmolLM3Model(config) class SmolLM3ForSequenceClassification(LlamaForSequenceClassification): diff --git a/src/transformers/models/starcoder2/modular_starcoder2.py b/src/transformers/models/starcoder2/modular_starcoder2.py index 2855e98c5ecd..016b52dd3a0d 100644 --- a/src/transformers/models/starcoder2/modular_starcoder2.py +++ b/src/transformers/models/starcoder2/modular_starcoder2.py @@ -200,7 +200,9 @@ def forward( class Starcoder2ForCausalLM(MistralForCausalLM): - pass + def __init__(self, config: Starcoder2Config): + super().__init__(config) + self.model = Starcoder2Model(config) class Starcoder2ForSequenceClassification(MistralForSequenceClassification): diff --git a/src/transformers/models/step3p7/modular_step3p7.py b/src/transformers/models/step3p7/modular_step3p7.py index 38d878b881e4..c19642464170 100644 --- a/src/transformers/models/step3p7/modular_step3p7.py +++ b/src/transformers/models/step3p7/modular_step3p7.py @@ -598,7 +598,40 @@ class Step3p7VisionMLP(MiniMaxM3VLVisionMLP): class Step3p7VisionAttention(MiniMaxM3VLVisionAttention): - pass + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: torch.Tensor | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor | None]: + """Input shape: Batch x Time x Channel""" + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + queries = self.q_proj(hidden_states).view(hidden_shape) + keys = self.k_proj(hidden_states).view(hidden_shape) + values = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + cos, sin = position_embeddings + queries, keys = apply_rotary_pos_emb_vision(queries, keys, cos, sin) + queries, keys = queries.transpose(1, 2), keys.transpose(1, 2) + + attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( + self.config._attn_implementation, eager_attention_forward + ) + attn_output, attn_weights = attention_interface( + self, + queries, + keys, + values, + attention_mask, + scaling=self.scale, + dropout=0.0 if not self.training else self.dropout, + **kwargs, + ) + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + return self.out_proj(attn_output), attn_weights class Step3p7VisionEncoderLayer(GradientCheckpointingLayer): @@ -827,6 +860,9 @@ def __init__(self, config: Step3p7TextConfig, layer_idx: int): super().__init__(config, layer_idx, num_heads) self.scaling = config.query_pre_attn_scalar**-0.5 + self.q_norm = Step3p7RMSNorm(self.head_dim, eps=config.rms_norm_eps) + self.k_norm = Step3p7RMSNorm(self.head_dim, eps=config.rms_norm_eps) + def forward( self, hidden_states: torch.Tensor, @@ -1053,6 +1089,10 @@ class Step3p7ForConditionalGeneration(DeepseekOcr2ForConditionalGeneration): input_modalities = ("image", "text") config: Step3p7Config + def __init__(self, config: Step3p7Config): + super().__init__(config) + self.model = Step3p7Model(config) + @auto_docstring class Step3p7Processor(ProcessorMixin): diff --git a/src/transformers/models/t5gemma2/modular_t5gemma2.py b/src/transformers/models/t5gemma2/modular_t5gemma2.py index a3be4eea53d0..3af699452a17 100644 --- a/src/transformers/models/t5gemma2/modular_t5gemma2.py +++ b/src/transformers/models/t5gemma2/modular_t5gemma2.py @@ -22,7 +22,7 @@ from ... import initialization as init from ...cache_utils import DynamicCache, EncoderDecoderCache, StaticCache -from ...configuration_utils import PreTrainedConfig +from ...configuration_utils import PreTrainedConfig, SubConfigSpec from ...generation import GenerationConfig, GenerationMixin, GenerationMode from ...masking_utils import create_bidirectional_mask from ...modeling_flash_attention_utils import FlashAttentionKwargs @@ -47,7 +47,7 @@ ) from ...utils.generic import merge_with_config_defaults from ...utils.output_capturing import OutputRecorder, capture_outputs -from ..auto import AutoModel +from ..auto import AutoConfig, AutoModel from ..gemma3.configuration_gemma3 import Gemma3Config, Gemma3TextConfig from ..gemma3.modeling_gemma3 import ( Gemma3Attention, @@ -103,6 +103,10 @@ def __post_init__(self, **kwargs): @strict class T5Gemma2EncoderConfig(Gemma3Config): model_type = "t5gemma2_encoder" + sub_configs_defaults = { + "text_config": T5Gemma2TextConfig, + "vision_config": SubConfigSpec(config_class=AutoConfig, model_type="siglip_vision_model"), + } @auto_docstring(checkpoint="google/t5gemma-2-270m-270m") @@ -347,7 +351,15 @@ def inner_mask(batch_idx: int, head_idx: int, q_idx: int, kv_idx: int) -> bool: class T5Gemma2EncoderLayer(T5GemmaEncoderLayer): - pass + def __init__(self, config, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = T5Gemma2SelfAttention( + config=config, + layer_idx=layer_idx, + ) + + self.mlp = T5Gemma2MLP(config) class T5Gemma2DecoderLayer(T5GemmaEncoderLayer): @@ -362,6 +374,8 @@ def __init__(self, config, layer_idx: int): layer_idx=layer_idx, ) + self.mlp = T5Gemma2MLP(config) + def forward( self, hidden_states: torch.Tensor, diff --git a/src/transformers/models/tipsv2_dpt/modular_tipsv2_dpt.py b/src/transformers/models/tipsv2_dpt/modular_tipsv2_dpt.py index d7fc12b90eec..eae2fd281761 100644 --- a/src/transformers/models/tipsv2_dpt/modular_tipsv2_dpt.py +++ b/src/transformers/models/tipsv2_dpt/modular_tipsv2_dpt.py @@ -354,7 +354,13 @@ def __init__(self, config: Tipsv2DptConfig): class Tipsv2DptNeck(DepthAnythingNeck): - pass + def __init__(self, config): + super().__init__(config) + + self.reassemble_stage = Tipsv2DptReassembleStage(config) + + # fusion + self.fusion_stage = Tipsv2DptFeatureFusionStage(config) class Tipsv2DptDecoder(nn.Module): diff --git a/src/transformers/models/ultrabert/modular_ultrabert.py b/src/transformers/models/ultrabert/modular_ultrabert.py index 9733325a7d4f..3d069b31cb0b 100644 --- a/src/transformers/models/ultrabert/modular_ultrabert.py +++ b/src/transformers/models/ultrabert/modular_ultrabert.py @@ -18,11 +18,13 @@ import torch from torch import nn +from ... import initialization as init from ...activations import ACT2FN from ...configuration_utils import strict from ...masking_utils import create_bidirectional_mask, create_bidirectional_sliding_window_mask from ...modeling_layers import GenericForQuestionAnswering from ...modeling_outputs import BaseModelOutput +from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS from ...modeling_utils import ALL_ATTENTION_FUNCTIONS from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring @@ -169,14 +171,39 @@ class UltrabertMLP(EuroBertMLP): class UltrabertDecoderLayer(EuroBertDecoderLayer): - pass + def __init__(self, config: UltrabertConfig, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = UltrabertAttention(config=config, layer_idx=layer_idx) + self.input_layernorm = UltrabertRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = UltrabertRMSNorm(config.hidden_size, eps=config.rms_norm_eps) class UltrabertPreTrainedModel(Olmo3PreTrainedModel): config: UltrabertConfig + _can_record_outputs = { + "hidden_states": UltrabertDecoderLayer, + "attentions": UltrabertAttention, + } + + def _init_weights(self, module): + super()._init_weights(module) + if isinstance(module, UltrabertRotaryEmbedding): + for layer_type in module.layer_types: + rope_init_fn = module.compute_default_rope_parameters + if module.rope_type[layer_type] != "default": + rope_init_fn = ROPE_INIT_FUNCTIONS[module.rope_type[layer_type]] + curr_inv_freq, _ = rope_init_fn(module.config, layer_type=layer_type) + init.copy_(getattr(module, f"{layer_type}_inv_freq"), curr_inv_freq) + init.copy_(getattr(module, f"{layer_type}_original_inv_freq"), curr_inv_freq) class UltrabertModel(EuroBertModel): + def __init__(self, config: UltrabertConfig): + super().__init__(config) + self.norm = UltrabertRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = UltrabertRotaryEmbedding(config=config) + @merge_with_config_defaults @capture_outputs @auto_docstring @@ -244,6 +271,8 @@ def __init__(self, config: UltrabertConfig): self.decoder = nn.Identity() self.sparse_prediction = False self.sparse_pred_ignore_index = -100 + self.model = UltrabertModel(config) + self.head = UltrabertPredictionHead(config) def get_output_embeddings(self): # UltraBERT doesn't normally tie embeddings, so output embeddings differ from input embeddings @@ -259,12 +288,16 @@ def __init__(self, config: UltrabertConfig): super().__init__(config) self.head = nn.Identity() + self.model = UltrabertModel(config) + class UltrabertForTokenClassification(ModernBertForTokenClassification): def __init__(self, config: UltrabertConfig): super().__init__(config) self.head = nn.Identity() + self.model = UltrabertModel(config) + class UltrabertForQuestionAnswering(GenericForQuestionAnswering, UltrabertPreTrainedModel): pass diff --git a/src/transformers/models/ultravbert/modular_ultravbert.py b/src/transformers/models/ultravbert/modular_ultravbert.py index 5947cc707bce..492d047eb4d6 100644 --- a/src/transformers/models/ultravbert/modular_ultravbert.py +++ b/src/transformers/models/ultravbert/modular_ultravbert.py @@ -18,15 +18,17 @@ import torch import torch.nn as nn from huggingface_hub.dataclasses import strict +from torch.nn import CrossEntropyLoss from torchvision.transforms.v2 import functional as tvF +from ... import initialization as init from ...activations import ACT2FN from ...configuration_utils import SubConfigSpec from ...image_processing_utils import BatchFeature from ...image_transforms import group_images_by_shape, reorder_images from ...image_utils import ImageInput, PILImageResampling, SizeDict from ...processing_utils import Unpack -from ...utils import TensorType, auto_docstring +from ...utils import TensorType, TransformersKwargs, auto_docstring from ...utils.generic import can_return_tuple from ..auto import AutoConfig from ..idefics3.image_processing_idefics3 import ( @@ -307,19 +309,101 @@ def forward(self, image_hidden_states): class UltraVBertPreTrainedModel(ModernVBertPreTrainedModel): _keys_to_ignore_on_load_unexpected = [r"vision_model\.head\."] + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + + def init_weight(module: nn.Module, std: float): + cutoff_factor = getattr(self.config, "initializer_cutoff_factor", 2.0) + init.trunc_normal_( + module.weight, + mean=0.0, + std=std, + a=-cutoff_factor * std, + b=cutoff_factor * std, + ) + + if isinstance(module, (nn.Linear, nn.Conv2d)): + if module.bias is not None: + init.zeros_(module.bias) + + if isinstance(module, UltraVBertConnector): + out_std = self.config.initializer_range / math.sqrt(2.0 * self.config.text_config.num_hidden_layers) + init_weight(module.modality_projection, out_std) + elif isinstance(module, UltraVBertForMaskedLM): + out_std = self.config.initializer_range / math.sqrt(2.0 * self.config.text_config.num_hidden_layers) + init_weight(module.lm_head, out_std) + elif isinstance( + module, + ( + UltraVBertForSequenceClassification, + UltraVBertForTokenClassification, + ), + ): + final_out_std = self.config.initializer_range / math.sqrt(self.config.text_config.hidden_size) + init_weight(module.classifier, final_out_std) + @auto_docstring class UltraVBertModel(ModernVBertModel): + def __init__(self, config: UltraVBertConfig): + super().__init__(config) + + # init components + self.connector = UltraVBertConnector(config) + @can_return_tuple @auto_docstring(checkpoint="athrael-soju/UltraVBERT") - def forward(self, **super_kwargs): + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: torch.Tensor | None = None, + position_ids: torch.LongTensor | None = None, + inputs_embeds: torch.FloatTensor | None = None, + pixel_values: torch.FloatTensor | None = None, + pixel_attention_mask: torch.BoolTensor | None = None, + image_hidden_states: torch.FloatTensor | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple | UltraVBertBaseModelOutput: r""" pixel_attention_mask (`torch.BoolTensor` of shape `(batch_size, num_images, image_size, image_size)`, *optional*): Mask over the real pixels of each image tile. image_hidden_states (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`): The hidden states of the image encoder after modality projection. """ - return super().forward(**super_kwargs) + + if inputs_embeds is None: + inputs_embeds = self.text_model.get_input_embeddings()(input_ids).to(input_ids.device) + + # Images processing + if pixel_values is not None: + image_hidden_states = self.get_image_features( + pixel_values=pixel_values, pixel_attention_mask=pixel_attention_mask + ).pooler_output + + # Merge image and text embeddings + if image_hidden_states is not None: + image_hidden_states = torch.cat(image_hidden_states, dim=0) + image_hidden_states = image_hidden_states.to(dtype=inputs_embeds.dtype, device=inputs_embeds.device) + special_image_mask = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, image_features=image_hidden_states + ) + inputs_embeds = inputs_embeds.masked_scatter(special_image_mask, image_hidden_states) + + # Language model pass + outputs = self.text_model( + inputs_embeds=inputs_embeds, + attention_mask=attention_mask, + position_ids=position_ids, + **kwargs, + ) + + return UltraVBertBaseModelOutput( + last_hidden_state=outputs.last_hidden_state, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + image_hidden_states=image_hidden_states, + ) class UltraVBertPredictionHead(nn.Module): @@ -342,16 +426,56 @@ def __init__(self, config: UltraVBertConfig): super().__init__(config) self.lm_head = nn.Linear(config.text_config.hidden_size, self.vocab_size, bias=False) + self.model = UltraVBertModel(config) + self.projection_head = UltraVBertPredictionHead(config.text_config) + @can_return_tuple @auto_docstring(checkpoint="athrael-soju/UltraVBERT") - def forward(self, **super_kwargs): + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: torch.Tensor | None = None, + position_ids: torch.LongTensor | None = None, + inputs_embeds: torch.FloatTensor | None = None, + pixel_values: torch.FloatTensor | None = None, + pixel_attention_mask: torch.BoolTensor | None = None, + image_hidden_states: torch.FloatTensor | None = None, + labels: torch.LongTensor | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple | UltraVBertMaskedLMOutput: r""" pixel_attention_mask (`torch.BoolTensor` of shape `(batch_size, num_images, image_size, image_size)`, *optional*): Mask over the real pixels of each image tile. image_hidden_states (`torch.FloatTensor` of shape `(batch_size, num_channels, image_size, image_size)`): The hidden states of the image encoder after modality projection. """ - return super().forward(**super_kwargs) + + outputs = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + inputs_embeds=inputs_embeds, + pixel_values=pixel_values, + pixel_attention_mask=pixel_attention_mask, + image_hidden_states=image_hidden_states, + **kwargs, + ) + hidden_states = outputs[0] + + logits = self.lm_head(self.projection_head(hidden_states)) + + loss = None + if labels is not None: + criterion = CrossEntropyLoss() + loss = criterion(logits.view(-1, self.vocab_size), labels.view(-1)) + + return UltraVBertMaskedLMOutput( + loss=loss, + logits=logits, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + image_hidden_states=outputs.image_hidden_states, + ) class UltraVBertForSequenceClassification(ModernVBertForSequenceClassification): @@ -359,6 +483,8 @@ def __init__(self, config: UltraVBertConfig): super().__init__(config) self.head = nn.Identity() + self.model = UltraVBertModel(config) + @can_return_tuple @auto_docstring(checkpoint="athrael-soju/UltraVBERT") def forward(self, **super_kwargs): @@ -376,6 +502,8 @@ def __init__(self, config: UltraVBertConfig): super().__init__(config) self.head = nn.Identity() + self.model = UltraVBertModel(config) + @can_return_tuple @auto_docstring(checkpoint="athrael-soju/UltraVBERT") def forward(self, **super_kwargs): diff --git a/src/transformers/models/unispeech/modular_unispeech.py b/src/transformers/models/unispeech/modular_unispeech.py index 2ab92c96f40b..5b5e80477601 100644 --- a/src/transformers/models/unispeech/modular_unispeech.py +++ b/src/transformers/models/unispeech/modular_unispeech.py @@ -396,11 +396,16 @@ def forward( class UniSpeechForCTC(Wav2Vec2ForCTC): - pass + def __init__(self, config: UniSpeechConfig, target_lang: str | None = None): + super().__init__(config, target_lang) + + self.unispeech = UniSpeechModel(config) class UniSpeechForSequenceClassification(Wav2Vec2ForSequenceClassification): - pass + def __init__(self, config: UniSpeechConfig): + super().__init__(config) + self.unispeech = UniSpeechModel(config) __all__ = [ diff --git a/src/transformers/models/unispeech_sat/modular_unispeech_sat.py b/src/transformers/models/unispeech_sat/modular_unispeech_sat.py index 5c8a82b0027d..40d043a0f046 100644 --- a/src/transformers/models/unispeech_sat/modular_unispeech_sat.py +++ b/src/transformers/models/unispeech_sat/modular_unispeech_sat.py @@ -399,19 +399,29 @@ def forward( class UniSpeechSatForCTC(Wav2Vec2ForCTC): - pass + def __init__(self, config: UniSpeechSatConfig, target_lang: str | None = None): + super().__init__(config, target_lang) + + self.unispeech_sat = UniSpeechSatModel(config) class UniSpeechSatForSequenceClassification(Wav2Vec2ForSequenceClassification): - pass + def __init__(self, config: UniSpeechSatConfig): + super().__init__(config) + self.unispeech_sat = UniSpeechSatModel(config) class UniSpeechSatForAudioFrameClassification(Wav2Vec2ForAudioFrameClassification): - pass + def __init__(self, config: UniSpeechSatConfig): + super().__init__(config) + self.unispeech_sat = UniSpeechSatModel(config) class UniSpeechSatForXVector(Wav2Vec2ForXVector): - pass + def __init__(self, config: UniSpeechSatConfig): + super().__init__(config) + + self.unispeech_sat = UniSpeechSatModel(config) __all__ = [ diff --git a/src/transformers/models/video_llama_3/modular_video_llama_3.py b/src/transformers/models/video_llama_3/modular_video_llama_3.py index 1a81387390cc..a6fb76a0bb01 100644 --- a/src/transformers/models/video_llama_3/modular_video_llama_3.py +++ b/src/transformers/models/video_llama_3/modular_video_llama_3.py @@ -34,7 +34,7 @@ ) from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, ModelOutput from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel -from ...processing_utils import ProcessorMixin, Unpack, VideosKwargs +from ...processing_utils import MultiModalData, ProcessorMixin, Unpack, VideosKwargs from ...utils import TensorType, auto_docstring, can_return_tuple, logging from ...utils.generic import ( get_max_seqlen, @@ -618,6 +618,7 @@ class VideoLlama3ForConditionalGeneration(Qwen2VLForConditionalGeneration): def __init__(self, config: VideoLlama3Config): super().__init__(config) # just to add type hint on config + self.model = VideoLlama3Model(config) def forward( self, @@ -700,6 +701,8 @@ class VideoLlama3ProcessorKwargs(Qwen2VLProcessorKwargs): class VideoLlama3Processor(Qwen3VLProcessor): + valid_processor_kwargs = VideoLlama3ProcessorKwargs + def __init__(self, image_processor=None, tokenizer=None, video_processor=None, chat_template=None, **kwargs): self.image_token = "<|image_pad|>" if not hasattr(tokenizer, "image_token") else tokenizer.image_token self.video_token = "<|video_pad|>" if not hasattr(tokenizer, "video_token") else tokenizer.video_token @@ -747,6 +750,44 @@ def model_input_names(self): def _calculate_timestamps(self): raise AttributeError("VideoLlama doesn't need this method") + def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): + """ + Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. + Args: + image_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (height, width) per each image. + video_sizes (`list[list[int]]`, *optional*): + The input sizes formatted as (num_frames, height, width) per each video. + Returns: + `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided + input modalities, along with other useful data. + """ + + vision_data = {} + if image_sizes is not None: + images_kwargs = VideoLlama3ProcessorKwargs._defaults.get("images_kwargs", {}) + images_kwargs.update(kwargs) + merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size + + num_image_patches = [ + self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) + for image_size in image_sizes + ] + num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] + vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) + + if video_sizes is not None: + videos_kwargs = VideoLlama3ProcessorKwargs._defaults.get("videos_kwargs", {}) + videos_kwargs.update(kwargs) + merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size + num_video_patches = [ + self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes + ] + num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] + vision_data["num_video_tokens"] = num_video_tokens + + return MultiModalData(**vision_data) + class VideoLlama3ImageProcessorKwargs(Qwen2VLImageProcessorKwargs): r""" @@ -957,6 +998,9 @@ class VideoLlama3VideoProcessor(Qwen2VLVideoProcessor): valid_kwargs = VideoLlama3VideoProcessorInitKwargs model_input_names = ["pixel_values_videos", "video_grid_thw", "video_merge_sizes", "video_compression_mask"] + def __init__(self, **kwargs: Unpack[VideoLlama3VideoProcessorInitKwargs]): + super().__init__(**kwargs) + def _get_compression_mask( self, pixel_values_videos: torch.FloatTensor, diff --git a/src/transformers/models/videoprism/modular_videoprism.py b/src/transformers/models/videoprism/modular_videoprism.py index 653087f20e82..883e6740142d 100644 --- a/src/transformers/models/videoprism/modular_videoprism.py +++ b/src/transformers/models/videoprism/modular_videoprism.py @@ -137,6 +137,10 @@ class VideoPrismConfig(SiglipConfig): """ initializer_factor = AttributeError() + sub_configs_defaults = { + "vision_config": VideoPrismVisionConfig, + "text_config": VideoPrismTextConfig, + } class VideoPrismTokenizer(T5Tokenizer): @@ -290,6 +294,7 @@ def __init__(self, config: VideoPrismVisionConfig): del self.cls_token del self.image_size self.position_embeddings = nn.Parameter(torch.zeros(1, num_patches, config.hidden_size)) # noqa: F821 + self.patch_embeddings = VideoPrismTubeletEmbeddings(config) def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: int) -> torch.Tensor: """ @@ -515,6 +520,10 @@ class VideoPrismPreTrainedModel(VivitPreTrainedModel): # sdpa is disabled because it does not support attention capping _supports_sdpa = False _input_embed_layer = AttributeError() + _can_record_outputs = { + "hidden_states": VideoPrismLayer, + "attentions": VideoPrismAttention, + } @torch.no_grad() def _init_weights(self, module): diff --git a/src/transformers/models/vipllava/modular_vipllava.py b/src/transformers/models/vipllava/modular_vipllava.py index aa3f41378208..0eb96378a36c 100644 --- a/src/transformers/models/vipllava/modular_vipllava.py +++ b/src/transformers/models/vipllava/modular_vipllava.py @@ -73,6 +73,11 @@ class VipLlavaPreTrainedModel(LlavaPreTrainedModel): class VipLlavaModel(LlavaModel): + def __init__(self, config: VipLlavaConfig): + super().__init__(config) + + self.multi_modal_projector = VipLlavaMultiModalProjector(config) + @can_return_tuple @auto_docstring( custom_intro="Obtains image last hidden states from the vision tower and apply multimodal projection." @@ -179,6 +184,10 @@ def forward( class VipLlavaForConditionalGeneration(LlavaForConditionalGeneration): + def __init__(self, config: VipLlavaConfig): + super().__init__(config) + self.model = VipLlavaModel(config) + @auto_docstring def get_image_features( self, diff --git a/src/transformers/models/vit_msn/modular_vit_msn.py b/src/transformers/models/vit_msn/modular_vit_msn.py index a6f622be1c5a..812323d42798 100644 --- a/src/transformers/models/vit_msn/modular_vit_msn.py +++ b/src/transformers/models/vit_msn/modular_vit_msn.py @@ -87,6 +87,7 @@ def __init__(self, config: ViTMSNConfig, use_mask_token: bool = False) -> None: """ super().__init__(config) del self.pooler + self.embeddings = ViTMSNEmbeddings(config, use_mask_token=use_mask_token) @merge_with_config_defaults @capture_outputs(tie_last_hidden_states=False) diff --git a/src/transformers/models/voxtral_realtime/modular_voxtral_realtime.py b/src/transformers/models/voxtral_realtime/modular_voxtral_realtime.py index 00b9636d7e38..e06e7fc4b0fd 100644 --- a/src/transformers/models/voxtral_realtime/modular_voxtral_realtime.py +++ b/src/transformers/models/voxtral_realtime/modular_voxtral_realtime.py @@ -458,6 +458,9 @@ def __init__(self, config: VoxtralRealtimeTextConfig): super().__init__(config) self.norm = VoxtralRealtimeRMSNorm(config.hidden_size, eps=config.rms_norm_eps) self.rotary_emb = VoxtralRealtimeRotaryEmbedding(config=config) + self.layers = nn.ModuleList( + [VoxtralRealtimeTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) class VoxtralRealtimeTimeEmbedding(nn.Module): diff --git a/src/transformers/models/wav2vec2_bert/modular_wav2vec2_bert.py b/src/transformers/models/wav2vec2_bert/modular_wav2vec2_bert.py index e59fa87f542c..27886f17cf86 100644 --- a/src/transformers/models/wav2vec2_bert/modular_wav2vec2_bert.py +++ b/src/transformers/models/wav2vec2_bert/modular_wav2vec2_bert.py @@ -736,6 +736,8 @@ def __init__(self, config: Wav2Vec2BertConfig, target_lang: str | None = None): """ super().__init__(config) + self.wav2vec2_bert = Wav2Vec2BertModel(config) + def freeze_feature_encoder(self): raise AttributeError("Not needed for Wav2Vec2Bert") @@ -796,6 +798,7 @@ def forward( class Wav2Vec2BertForSequenceClassification(Wav2Vec2ForSequenceClassification): def __init__(self, config: Wav2Vec2BertConfig): super().__init__(config) + self.wav2vec2_bert = Wav2Vec2BertModel(config) def freeze_feature_encoder(self): raise AttributeError("Not needed for Wav2Vec2Bert") @@ -868,6 +871,7 @@ def forward( class Wav2Vec2BertForAudioFrameClassification(Wav2Vec2ConformerForAudioFrameClassification): def __init__(self, config: Wav2Vec2BertConfig): super().__init__(config) + self.wav2vec2_bert = Wav2Vec2BertModel(config) def freeze_feature_encoder(self): raise AttributeError("Not needed for Wav2Vec2Bert") @@ -924,6 +928,8 @@ class Wav2Vec2BertForXVector(Wav2Vec2ConformerForXVector): def __init__(self, config: Wav2Vec2BertConfig): super().__init__(config) + self.wav2vec2_bert = Wav2Vec2BertModel(config) + def freeze_feature_encoder(self): raise AttributeError("Not needed for Wav2Vec2Bert") diff --git a/src/transformers/models/wav2vec2_conformer/modular_wav2vec2_conformer.py b/src/transformers/models/wav2vec2_conformer/modular_wav2vec2_conformer.py index 52bd1fc41e96..f01b82e1f0f7 100644 --- a/src/transformers/models/wav2vec2_conformer/modular_wav2vec2_conformer.py +++ b/src/transformers/models/wav2vec2_conformer/modular_wav2vec2_conformer.py @@ -677,6 +677,7 @@ def __init__(self, config: Wav2Vec2ConformerConfig): class Wav2Vec2ConformerForPreTraining(Wav2Vec2ForPreTraining): def __init__(self, config: Wav2Vec2ConformerConfig): super().__init__(config) + self.wav2vec2_conformer = Wav2Vec2ConformerModel(config) class Wav2Vec2ConformerForCTC(Wav2Vec2ForCTC): @@ -689,6 +690,8 @@ def __init__(self, config: Wav2Vec2ConformerConfig, target_lang: str | None = No """ super().__init__(config) + self.wav2vec2_conformer = Wav2Vec2ConformerModel(config) + def tie_weights(self): raise AttributeError("Not needed for Wav2Vec2Conformer") @@ -699,17 +702,21 @@ def freeze_base_model(self): class Wav2Vec2ConformerForSequenceClassification(Wav2Vec2ForSequenceClassification): def __init__(self, config: Wav2Vec2ConformerConfig): super().__init__(config) + self.wav2vec2_conformer = Wav2Vec2ConformerModel(config) class Wav2Vec2ConformerForAudioFrameClassification(Wav2Vec2ForAudioFrameClassification): def __init__(self, config: Wav2Vec2ConformerConfig): super().__init__(config) + self.wav2vec2_conformer = Wav2Vec2ConformerModel(config) class Wav2Vec2ConformerForXVector(Wav2Vec2ForXVector): def __init__(self, config: Wav2Vec2ConformerConfig): super().__init__(config) + self.wav2vec2_conformer = Wav2Vec2ConformerModel(config) + __all__ = [ "Wav2Vec2ConformerForAudioFrameClassification", diff --git a/src/transformers/models/wavlm/modular_wavlm.py b/src/transformers/models/wavlm/modular_wavlm.py index b6af149d030d..86ac236934d2 100644 --- a/src/transformers/models/wavlm/modular_wavlm.py +++ b/src/transformers/models/wavlm/modular_wavlm.py @@ -12,6 +12,7 @@ from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, logging +from ...utils.output_capturing import OutputRecorder from ..wav2vec2.modeling_wav2vec2 import ( Wav2Vec2FeatureProjection, Wav2Vec2FeedForward, @@ -468,6 +469,10 @@ class WavLMPreTrainedModel(PreTrainedModel, Wav2Vec2PreTrainedModel): _supports_flash_attn = False _supports_sdpa = False _supports_flex_attn = False + _can_record_outputs = { + "hidden_states": [WavLMEncoderLayer, WavLMEncoderLayerStableLayerNorm], + "attentions": OutputRecorder(WavLMAttention, index=1, layer_name="encoder"), + } @torch.no_grad() def _init_weights(self, module): @@ -516,7 +521,13 @@ def load_adapter(self): class WavLMModel(Wav2Vec2Model): - pass + def __init__(self, config: WavLMConfig): + super().__init__(config) + + if config.do_stable_layer_norm: + self.encoder = WavLMEncoderStableLayerNorm(config) + else: + self.encoder = WavLMEncoder(config) class WavLMForCTC(Wav2Vec2ForCTC): diff --git a/src/transformers/models/xcodec2/modular_xcodec2.py b/src/transformers/models/xcodec2/modular_xcodec2.py index fe1755315fe1..7ab040cb1950 100644 --- a/src/transformers/models/xcodec2/modular_xcodec2.py +++ b/src/transformers/models/xcodec2/modular_xcodec2.py @@ -235,7 +235,12 @@ def forward( class Xcodec2DecoderLayer(LlamaDecoderLayer): - pass + def __init__(self, config: Xcodec2Config, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = Xcodec2Attention(config=config, layer_idx=layer_idx) + + self.mlp = Xcodec2MLP(config) class Xcodec2SnakeBeta(Qwen2_5OmniSnakeBeta): @@ -303,6 +308,9 @@ def __init__(self, config: Xcodec2Config, stride: int = 1, stride_index: int = 1 super().__init__(config, stride, stride_index) dimension = config.encoder_hidden_size * 2**stride_index self.snake1 = Xcodec2AntiAliasedActivation1d(activation=Xcodec2SnakeBeta(dimension // 2)) + self.res_unit1 = Xcodec2ResidualUnit(dimension // 2, dilation=1) + self.res_unit2 = Xcodec2ResidualUnit(dimension // 2, dilation=3) + self.res_unit3 = Xcodec2ResidualUnit(dimension // 2, dilation=9) class Xcodec2Encoder(DacEncoder): @@ -310,6 +318,10 @@ def __init__(self, config: Xcodec2Config): super().__init__(config) d_model = config.encoder_hidden_size * 2 ** len(config.downsampling_ratios) self.snake1 = Xcodec2AntiAliasedActivation1d(activation=Xcodec2SnakeBeta(d_model)) + # Create EncoderBlocks that double channels as they downsample by `stride` + for stride_index, stride in enumerate(config.downsampling_ratios): + stride_index = stride_index + 1 + self.block += [Xcodec2EncoderBlock(config, stride=stride, stride_index=stride_index)] class Xcodec2ResNetBlock(nn.Module): diff --git a/src/transformers/models/xlm_roberta_xl/modular_xlm_roberta_xl.py b/src/transformers/models/xlm_roberta_xl/modular_xlm_roberta_xl.py index 6af8d3d672a9..c56366fb1060 100644 --- a/src/transformers/models/xlm_roberta_xl/modular_xlm_roberta_xl.py +++ b/src/transformers/models/xlm_roberta_xl/modular_xlm_roberta_xl.py @@ -23,6 +23,7 @@ import torch.nn as nn from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss +from ... import initialization as init from ...activations import gelu from ...cache_utils import Cache from ...generation import GenerationMixin @@ -138,6 +139,7 @@ def __init__(self, config, is_causal=False, layer_idx=None, is_cross_attention=F del self.LayerNorm self.self_attn_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.output = XLMRobertaXLSelfOutput(config) def forward( self, @@ -176,6 +178,17 @@ class XLMRobertaXLLayer(BertLayer): def __init__(self, config, layer_idx=None): super().__init__(config, layer_idx) self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.attention = XLMRobertaXLAttention(config, is_causal=config.is_decoder, layer_idx=layer_idx) + if self.add_cross_attention: + if not self.is_decoder: + raise ValueError(f"{self} should be used as a decoder model if cross attention is added") + self.crossattention = XLMRobertaXLAttention( + config, + is_causal=False, + layer_idx=layer_idx, + is_cross_attention=True, + ) + self.output = XLMRobertaXLOutput(config) def feed_forward_chunk(self, attention_output): intermediate_output = self.LayerNorm(attention_output) @@ -223,10 +236,29 @@ def forward( @auto_docstring class XLMRobertaXLPreTrainedModel(RobertaPreTrainedModel): base_model_prefix = "roberta" + _can_record_outputs = { + "hidden_states": XLMRobertaXLLayer, + "attentions": XLMRobertaXLSelfAttention, + "cross_attentions": XLMRobertaXLCrossAttention, + } + + @torch.no_grad() + def _init_weights(self, module): + """Initialize the weights""" + super()._init_weights(module) + if isinstance(module, XLMRobertaXLLMHead): + init.zeros_(module.bias) + elif isinstance(module, XLMRobertaXLEmbeddings): + init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1))) + init.zeros_(module.token_type_ids) class XLMRobertaXLModel(BertModel): - pass + def __init__(self, config: XLMRobertaXLConfig, add_pooling_layer=True): + super().__init__(config, add_pooling_layer) + + self.embeddings = XLMRobertaXLEmbeddings(config) + self.encoder = XLMRobertaXLEncoder(config) class XLMRobertaXLLMHead(nn.Module): diff --git a/src/transformers/models/youtu/modular_youtu.py b/src/transformers/models/youtu/modular_youtu.py index c5ba1f03da53..c8e592f86494 100644 --- a/src/transformers/models/youtu/modular_youtu.py +++ b/src/transformers/models/youtu/modular_youtu.py @@ -123,10 +123,20 @@ class YoutuAttention(DeepseekV3Attention): class YoutuDecoderLayer(LlamaDecoderLayer): - pass + def __init__(self, config: YoutuConfig, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = YoutuAttention(config=config, layer_idx=layer_idx) + + self.mlp = YoutuMLP(config) class YoutuPreTrainedModel(LlamaPreTrainedModel, PreTrainedModel): + _can_record_outputs = { + "hidden_states": YoutuDecoderLayer, + "attentions": YoutuAttention, + } + @torch.no_grad() def _init_weights(self, module): PreTrainedModel._init_weights(self, module) diff --git a/src/transformers/models/zamba2/modular_zamba2.py b/src/transformers/models/zamba2/modular_zamba2.py index a9a79e4017a7..76c1c941801d 100644 --- a/src/transformers/models/zamba2/modular_zamba2.py +++ b/src/transformers/models/zamba2/modular_zamba2.py @@ -581,7 +581,9 @@ def forward( class Zamba2ForCausalLM(ZambaForCausalLM): - pass + def __init__(self, config: Zamba2Config): + super().__init__(config) + self.model = Zamba2Model(config) class Zamba2ForSequenceClassification(ZambaForSequenceClassification): diff --git a/src/transformers/models/zaya/modular_zaya.py b/src/transformers/models/zaya/modular_zaya.py index 1a97ba735e67..9f2a75ab8096 100644 --- a/src/transformers/models/zaya/modular_zaya.py +++ b/src/transformers/models/zaya/modular_zaya.py @@ -368,6 +368,8 @@ def __init__(self, config: ZayaConfig, layer_idx: int): self.post_attention_residual_scale = ZayaResidualScaling(config.hidden_size) self.post_mlp_residual_scale = ZayaResidualScaling(config.hidden_size) + self.self_attn = ZayaAttention(config=config, layer_idx=layer_idx) + def forward( self, hidden_states: torch.Tensor, @@ -573,6 +575,9 @@ def __init__(self, config: ZayaConfig): super().__init__(config) self.input_hidden_states_scale = nn.Parameter(torch.ones(config.hidden_size)) self.input_hidden_states_bias = nn.Parameter(torch.zeros(config.hidden_size)) + self.layers = nn.ModuleList( + [ZayaDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) def forward( self, @@ -664,6 +669,7 @@ class ZayaForCausalLM(AfmoeForCausalLM, ZayaPreTrainedModel): def __init__(self, config: ZayaConfig, **kwargs): super().__init__(config, **kwargs) self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=self.config.lm_head_bias) + self.model = ZayaModel(config) @staticmethod def create_masks_for_generate(config, inputs_embeds, attention_mask, past_key_values, position_ids=None, **_): diff --git a/utils/fix_modular_inherited_overrides.py b/utils/fix_modular_inherited_overrides.py index a67229729f82..e90dee078b94 100644 --- a/utils/fix_modular_inherited_overrides.py +++ b/utils/fix_modular_inherited_overrides.py @@ -6,6 +6,7 @@ import sys import libcst as cst +from libcst import matchers as m sys.path.insert(0, "utils") import modular_model_converter as mmc # noqa: E402 @@ -66,6 +67,8 @@ def leave_ClassDef(self, original, updated): return updated body = [] for stmt in updated.body.body: + if isinstance(stmt, cst.BaseSmallStatement): + stmt = cst.SimpleStatementLine(body=[stmt]) key = mmc._statement_key(stmt) if key in todo: body.append(todo.pop(key)) @@ -73,7 +76,12 @@ def leave_ClassDef(self, original, updated): continue else: body.append(stmt) - body.extend(todo.values()) + first_method = next((i for i, s in enumerate(body) if isinstance(s, cst.FunctionDef)), len(body)) + early = [s for k, s in todo.items() if not isinstance(s, cst.FunctionDef) or k == "__init__"] + late = [s for k, s in todo.items() if isinstance(s, cst.FunctionDef) and k != "__init__"] + body = body[:first_method] + early + body[first_method:] + late + if isinstance(updated.body, cst.SimpleStatementSuite): # one-line `class A(B): pass` + return updated.with_changes(body=cst.IndentedBlock(body=body)) return updated.with_changes(body=updated.body.with_changes(body=body)) @@ -85,6 +93,29 @@ def leave_Name(self, original, updated): return updated.with_changes(value=self.mapping.get(updated.value, updated.value)) +def super_init_call(func: cst.FunctionDef) -> cst.SimpleStatementLine: + p = func.params + args = [cst.Arg(cst.Name(x.name.value)) for x in [*p.posonly_params, *p.params] if x.name.value != "self"] + if isinstance(p.star_arg, cst.Param): + args.append(cst.Arg(cst.Name(p.star_arg.name.value), star="*")) + args += [cst.Arg(cst.Name(x.name.value), keyword=cst.Name(x.name.value)) for x in p.kwonly_params] + if p.star_kwarg is not None: + args.append(cst.Arg(cst.Name(p.star_kwarg.name.value), star="**")) + return cst.parse_statement(f"super().__init__({cst.Module(body=[]).code_for_node(cst.Call(func=cst.Name('f'), args=args))[2:-1]})") + + +def minimal_init(generated: cst.FunctionDef, names: set[str], modular_class: cst.ClassDef) -> cst.FunctionDef: + """`super().__init__(...)` (or the existing modular `__init__`) + only the statements using the redefined names. + The converter replaces same-target `self.x = ...` assignments in place, so the generated code does not change.""" + needed = [s for s in generated.body.body if mmc._names_in(s) & names] + existing = next( + (s for s in modular_class.body.body if isinstance(s, cst.FunctionDef) and s.name.value == "__init__"), None + ) + if existing is not None: + return existing.with_changes(body=existing.body.with_changes(body=[*existing.body.body, *needed])) + return generated.with_changes(body=generated.body.with_changes(body=[super_init_call(generated), *needed])) + + def undefined_names(path): out = subprocess.run( ["ruff", "check", "--select", "F821", "--output-format", "json", "--no-cache", path], @@ -102,15 +133,21 @@ def fix(path): if not mismatches: return 0, [] generated = {name: entry["node"] for body in files.values() for name, entry in body.items()} - members = {} - for class_name, key, _, _ in mismatches: - if key is None: - continue + flagged = {} + for class_name, key, name, _ in mismatches: + if key is not None: + flagged.setdefault((class_name, key), set()).add(name) + members, manual = {}, [] + for (class_name, key), names in flagged.items(): stmt = next(s for s in generated[class_name].body.body if mmc._statement_key(s) == key) + if isinstance(stmt, cst.FunctionDef) and key == "__init__": + stmt = minimal_init(stmt, names, mapper.classes[class_name]) + elif isinstance(stmt, cst.FunctionDef) and m.findall(stmt, m.Call(func=m.Attribute(value=m.Call(func=m.Name("super"))))): + manual.append(f"{class_name}.{key}") members.setdefault(class_name, {})[key] = stmt source = open(path).read() - module = cst.parse_module(source).visit(Inserter(members)) - open(path, "w").write(module.code) + code = cst.parse_module(source).visit(Inserter(members)).code + open(path, "w").write(code) # Resolve names the copied code uses but the modular file does not define renamed_to_original, import_for = {}, {} @@ -148,7 +185,7 @@ def fix(path): module = module.with_changes(body=[*module.body[: idx + 1], *new_nodes, *module.body[idx + 1 :]]) code = module.code open(path, "w").write(code) - return len(mismatches), missing + return len(mismatches), missing + [f"super() in {x}" for x in manual] if __name__ == "__main__": diff --git a/utils/modular_model_converter.py b/utils/modular_model_converter.py index a921ce3f6dae..ee346255e3dc 100644 --- a/utils/modular_model_converter.py +++ b/utils/modular_model_converter.py @@ -1636,7 +1636,9 @@ def leave_Module(self, node): renamer = ReplaceNameTransformer(file_model_name, new_name, self.model_name) renamed_module = module.visit(renamer) self.renamed_original_nodes[file] = { - node.name.value: node for node in renamed_module.body if isinstance(node, (cst.ClassDef, cst.FunctionDef)) + node.name.value: node + for node in renamed_module.body + if isinstance(node, (cst.ClassDef, cst.FunctionDef)) } self.visited_modules[file] = ModelFileMapper.visit_and_merge_dependencies( renamed_module, @@ -2037,7 +2039,68 @@ def find_inherited_code_mismatches( return mismatches +# Modular files whose inherited code still silently uses classes they redefine. Do not add to this list: override +# the inherited method instead (see `check_inherited_code_uses_parent_definitions`). +INHERITANCE_MISMATCH_ALLOWLIST = { + "altclip", + "chinese_clip", + "clipseg", + "colmodernvbert", + "d_fine", + "deepseek_ocr2", + "deepseek_v32", + "deimv2", + "edgetam", + "edgetam_video", + "ernie4_5_vl_moe", + "eurobert", + "falcon_mamba", + "flex_olmo", + "flint", + "gemma", + "glm4_moe", + "glm4_moe_lite", + "glm4v_moe", + "glm5_next", + "glm_image", + "glm_moe_dsa", + "gradium_phonon_tts", + "granite_speech_plus", + "granitemoehybrid", + "granitemoeshared", + "higgs_audio_v2", + "instructblipvideo", + "jais2", + "mellum", + "metaclip_2", + "minimax_m2", + "moonshine", + "nomic_bert", + "owlv2", + "paddleocr_vl", + "pocket_tts", + "pp_doclayout_v2", + "qwen2_5_omni", + "qwen3_asr", + "qwen3_omni_moe", + "qwen3_vl_moe", + "rf_detr", + "rt_detr_v2", + "sam_hq", + "siglip2", + "smolvlm", + "solar_open", + "timesfm2_5", + "tipsv2", + "unlimited_ocr", + "vaultgemma", + "videomt", +} + + def check_inherited_code_uses_parent_definitions(modular_mapper: "ModularFileMapper", files: dict[str, dict]): + if modular_mapper.model_name in INHERITANCE_MISMATCH_ALLOWLIST: + return mismatches = find_inherited_code_mismatches(modular_mapper, files) if mismatches: errors = [ From 07b89b1c34c1d9ff169af981115d3d1e575024b1 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 30 Oct 2026 11:09:34 +0100 Subject: [PATCH 3/7] [modular] only check redefined classes, not functions; keep post_init last --- src/transformers/models/aria/modular_aria.py | 2 +- .../models/bamba/modular_bamba.py | 48 +-------- .../cohere2_vision/modular_cohere2_vision.py | 102 ------------------ .../models/cohere_asr/modular_cohere_asr.py | 4 +- .../modular_conditional_detr.py | 2 +- .../models/deepseek_v4/modular_deepseek_v4.py | 2 +- .../models/dinov2/modular_dinov2.py | 36 +------ .../modular_embedding_gemma2.py | 2 +- .../models/ernie4_5/modular_ernie4_5.py | 49 +-------- .../ernie4_5_moe/modular_ernie4_5_moe.py | 51 +-------- .../models/evolla/modular_evolla.py | 92 +--------------- src/transformers/models/glm/modular_glm.py | 48 +-------- .../models/glm4v/modular_glm4v.py | 71 +----------- .../models/helium/modular_helium.py | 53 +-------- .../models/janus/modular_janus.py | 6 +- .../modular_jina_embeddings_v3.py | 4 +- .../models/lw_detr/modular_lw_detr.py | 33 ------ .../muse_glimmer/modular_muse_glimmer.py | 73 +------------ .../modular_nemotron3_5_transcribe.py | 2 +- .../models/olmo_hybrid/modular_olmo_hybrid.py | 2 +- .../modular_pp_doclayout_v3.py | 2 +- .../models/qwen3_vl/modular_qwen3_vl.py | 71 ------------ .../models/qwen4_exp/modular_qwen4_exp.py | 44 ++------ .../models/step3p7/modular_step3p7.py | 35 +----- utils/fix_modular_inherited_overrides.py | 4 +- utils/modular_model_converter.py | 3 +- 26 files changed, 44 insertions(+), 797 deletions(-) diff --git a/src/transformers/models/aria/modular_aria.py b/src/transformers/models/aria/modular_aria.py index 4c10024cb3f2..6e035ff53333 100644 --- a/src/transformers/models/aria/modular_aria.py +++ b/src/transformers/models/aria/modular_aria.py @@ -770,8 +770,8 @@ def __init__(self, config: AriaTextConfig): [AriaTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] ) self.gradient_checkpointing = False - self.post_init() self.norm = AriaTextRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_init() class AriaTextForCausalLM(AriaTextPreTrainedModel, DeepseekV2ForCausalLM): diff --git a/src/transformers/models/bamba/modular_bamba.py b/src/transformers/models/bamba/modular_bamba.py index ff745ef24264..24f2971f6ad2 100644 --- a/src/transformers/models/bamba/modular_bamba.py +++ b/src/transformers/models/bamba/modular_bamba.py @@ -18,8 +18,6 @@ # limitations under the License. """PyTorch Bamba model.""" -from collections.abc import Callable - import torch from torch import nn @@ -27,12 +25,12 @@ from ...cache_utils import Cache, DynamicCache from ...masking_utils import create_causal_mask, create_recurrent_attention_mask from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast -from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel, slice_logits_to_keep +from ...modeling_utils import PreTrainedModel, slice_logits_to_keep from ...processing_utils import Unpack from ...utils import auto_docstring, can_return_tuple, logging from ...utils.generic import TransformersKwargs, merge_with_config_defaults, no_inherit_decorator from ...utils.output_capturing import capture_outputs -from ..jamba.modeling_jamba import JambaAttentionDecoderLayer, eager_attention_forward +from ..jamba.modeling_jamba import JambaAttentionDecoderLayer from ..llama.modeling_llama import ( LlamaAttention, LlamaForCausalLM, @@ -114,45 +112,7 @@ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1): @no_inherit_decorator class BambaAttention(LlamaAttention): - def forward( - self, - hidden_states: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, - attention_mask: torch.Tensor | None = None, - past_key_values: Cache | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor, torch.Tensor]: - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - - query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) - key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) - value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) - - if past_key_values is not None: - key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - attn_output, attn_weights = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask, - dropout=0.0 if not self.training else self.attention_dropout, - scaling=self.scaling, - **kwargs, - ) - - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attn_output = self.o_proj(attn_output) - return attn_output, attn_weights + pass class BambaRMSNormGated(MambaRMSNormGated): @@ -393,10 +353,10 @@ class BambaForCausalLM(LlamaForCausalLM): def __init__(self, config: BambaConfig): super().__init__(config) self.z_loss_coefficient = config.z_loss_coefficient + self.model = BambaModel(config) # Initialize weights and apply final processing self.post_init() - self.model = BambaModel(config) @can_return_tuple @auto_docstring diff --git a/src/transformers/models/cohere2_vision/modular_cohere2_vision.py b/src/transformers/models/cohere2_vision/modular_cohere2_vision.py index f39869225d5a..3fc2d0874356 100644 --- a/src/transformers/models/cohere2_vision/modular_cohere2_vision.py +++ b/src/transformers/models/cohere2_vision/modular_cohere2_vision.py @@ -18,7 +18,6 @@ import numpy as np import torch from torch import nn -from torchvision.transforms.v2 import functional as tvF from transformers.models.aya_vision.modeling_aya_vision import ( AyaVisionCausalLMOutputWithPast, @@ -30,7 +29,6 @@ from transformers.models.got_ocr2.image_processing_got_ocr2 import GotOcr2ImageProcessor from ...cache_utils import Cache -from ...image_utils import PILImageResampling, SizeDict from ...modeling_flash_attention_utils import FlashAttentionKwargs from ...modeling_outputs import BaseModelOutputWithPooling from ...modeling_utils import slice_logits_to_keep @@ -338,106 +336,6 @@ class Cohere2VisionImageProcessor(GotOcr2ImageProcessor): patch_size = 16 valid_kwargs = Cohere2VisionImageProcessorKwargs - def crop_image_to_patches( - self, - images: "torch.Tensor", - min_patches: int, - max_patches: int, - use_thumbnail: bool = True, - patch_size: SizeDict | None = None, - resample: "PILImageResampling | tvF.InterpolationMode | int | None" = None, - ): - """ - Crop the images to patches and return a list of cropped images. - The number of patches and their grid arrangement are determined by the original image size, - the target patch size and the minimum and maximum number of patches. - The aspect ratio of the patches grid is chosen to be the closest to the original image aspect ratio. - - Args: - images (`torch.Tensor`): - The images to be cropped. - min_patches (`int`): - The minimum number of patches to be extracted from the image. - max_patches (`int`): - The maximum number of patches to be extracted from the image. - use_thumbnail (`bool`, *optional*, defaults to `True`): - Whether to add a thumbnail image to the list of cropped patches. - patch_size (`SizeDict`, *optional*): - The size of the output patches. - resample (`PILImageResampling | tvF.InterpolationMode | int | None`, *optional*): - Resampling filter to use when resizing. - """ - patch_size_height, patch_size_width = patch_size.height, patch_size.width - original_height, original_width = images.shape[-2:] - # find the closest aspect ratio to the target - num_columns, num_rows = get_optimal_tiled_canvas( - (original_height, original_width), (patch_size_height, patch_size_width), min_patches, max_patches - ) - - # calculate the target width and height - target_width = patch_size_width * num_columns - target_height = patch_size_height * num_rows - num_blocks = num_columns * num_rows - - # resize the image so that each patch is of patch_size - resized_image = self.resize(images, SizeDict(height=target_height, width=target_width), resample=resample) - # split the image into patches - processed_images = [] - for i in range(num_blocks): - column = i % num_columns - row = i // num_columns - box = ( - column * patch_size_width, - row * patch_size_height, - (column + 1) * patch_size_width, - (row + 1) * patch_size_height, - ) - # split the image - patch_image = resized_image[..., box[1] : box[3], box[0] : box[2]] - processed_images.append(patch_image) - - if use_thumbnail and len(processed_images) != 1: - thumbnail_img = self.resize(images, patch_size, resample=resample) - processed_images.append(thumbnail_img) - - processed_images = torch.stack(processed_images, dim=0).transpose(0, 1).contiguous() - - return processed_images - - def get_number_of_image_patches(self, height: int, width: int, images_kwargs: dict | None = None) -> int: - """ - A utility that returns number patches for a given image size. - - Args: - height (`int`): - Height of the input image. - width (`int`): - Width of the input image. - images_kwargs (`dict`, *optional*) - Any kwargs to override defaults of the image processor. - Returns: - `int`: Number of patches per image. - """ - images_kwargs = images_kwargs or {} - min_patches = images_kwargs.get("min_patches", self.min_patches) - max_patches = images_kwargs.get("max_patches", self.max_patches) - patch_size = images_kwargs.get("patch_size", self.size) - crop_to_patches = images_kwargs.get("crop_to_patches", self.crop_to_patches) - - num_patches = 1 - if crop_to_patches and max_patches > 1: - if isinstance(patch_size, dict): - patch_height, patch_width = patch_size["height"], patch_size["width"] - else: - patch_height, patch_width = patch_size.height, patch_size.width - num_columns, num_rows = get_optimal_tiled_canvas( - (height, width), (patch_height, patch_width), min_patches, max_patches - ) - if num_columns * num_rows > 1: - num_patches += num_columns * num_rows - - return num_patches - __all__ = [ "Cohere2VisionForConditionalGeneration", diff --git a/src/transformers/models/cohere_asr/modular_cohere_asr.py b/src/transformers/models/cohere_asr/modular_cohere_asr.py index 9c4e7c14d932..6eae59a6cee7 100644 --- a/src/transformers/models/cohere_asr/modular_cohere_asr.py +++ b/src/transformers/models/cohere_asr/modular_cohere_asr.py @@ -266,8 +266,8 @@ def __init__(self, config: CohereAsrConfig): self.pos_emb = nn.Embedding(config.max_position_embeddings, config.hidden_size) self.embedding_layernorm = nn.LayerNorm(config.hidden_size) self.proj = nn.Linear(config.encoder_config.hidden_size, config.hidden_size, bias=True) - self.post_init() self.layers = nn.ModuleList([CohereAsrDecoderLayer(config, idx) for idx in range(config.num_hidden_layers)]) + self.post_init() def forward( self, @@ -428,8 +428,8 @@ class CohereAsrForConditionalGeneration(MoonshineForConditionalGeneration): def __init__(self, config: CohereAsrConfig): super().__init__(config) self.proj_out = nn.Linear(config.hidden_size, config.vocab_size, bias=True) - self.post_init() self.model = CohereAsrModel(config) + self.post_init() @can_return_tuple @auto_docstring diff --git a/src/transformers/models/conditional_detr/modular_conditional_detr.py b/src/transformers/models/conditional_detr/modular_conditional_detr.py index c8c4595c7b9a..c2c033399b3f 100644 --- a/src/transformers/models/conditional_detr/modular_conditional_detr.py +++ b/src/transformers/models/conditional_detr/modular_conditional_detr.py @@ -886,10 +886,10 @@ class ConditionalDetrModel(DetrModel): def __init__(self, config: ConditionalDetrConfig): super().__init__(config) self.query_position_embeddings = nn.Embedding(config.num_queries, config.d_model) + self.decoder = ConditionalDetrDecoder(config) # Initialize weights and apply final processing self.post_init() - self.decoder = ConditionalDetrDecoder(config) @auto_docstring @can_return_tuple diff --git a/src/transformers/models/deepseek_v4/modular_deepseek_v4.py b/src/transformers/models/deepseek_v4/modular_deepseek_v4.py index c8920292abe0..b9d3e1b0178c 100644 --- a/src/transformers/models/deepseek_v4/modular_deepseek_v4.py +++ b/src/transformers/models/deepseek_v4/modular_deepseek_v4.py @@ -1186,8 +1186,8 @@ def __init__(self, config: DeepseekV4Config): ) self.rotary_emb = DeepseekV4RotaryEmbedding(config) self.hc_head = DeepseekV4HyperHead(config) - self.post_init() self.norm = DeepseekV4RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_init() @merge_with_config_defaults @capture_outputs diff --git a/src/transformers/models/dinov2/modular_dinov2.py b/src/transformers/models/dinov2/modular_dinov2.py index 71cafef6badd..5b8f48e2fc41 100644 --- a/src/transformers/models/dinov2/modular_dinov2.py +++ b/src/transformers/models/dinov2/modular_dinov2.py @@ -13,8 +13,6 @@ # limitations under the License. """PyTorch DINOv2 model.""" -from collections.abc import Callable - import torch from torch import nn @@ -24,7 +22,6 @@ from ...masking_utils import create_bidirectional_mask from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import BackboneOutput, BaseModelOutput, BaseModelOutputWithPooling, ImageClassifierOutput -from ...modeling_utils import ALL_ATTENTION_FUNCTIONS from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, torch_int from ...utils.generic import can_return_tuple, merge_with_config_defaults @@ -108,38 +105,7 @@ def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: class Dinov2Attention(ViTAttention): - def forward( - self, - hidden_states: torch.Tensor, - attention_mask: torch.Tensor | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor, torch.Tensor]: - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - - query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) - key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) - value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - attn_output, attn_weights = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask, - dropout=0.0 if not self.training else self.attention_dropout, - scaling=self.scaling, - **kwargs, - ) - - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attn_output = self.o_proj(attn_output) - - return attn_output, attn_weights + pass class Dinov2LayerScale(nn.Module): diff --git a/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py b/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py index 68ff150e8170..e7650359b379 100644 --- a/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py +++ b/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py @@ -581,7 +581,6 @@ def __init__(self, config: EmbeddingGemma2Config): super().__init__(config) # Drop inherited `vocab_size_per_layer_input` (no token-identity PLE in EmbeddingGemma 2) del self.vocab_size_per_layer_input - self.post_init() self.embed_vision = ( EmbeddingGemma2MultimodalEmbedder(config.vision_config, config.text_config) if config.vision_config is not None @@ -592,6 +591,7 @@ def __init__(self, config: EmbeddingGemma2Config): if config.audio_config is not None else None ) + self.post_init() @can_return_tuple @auto_docstring(custom_intro="Projects the last hidden state from the vision model into language model space.") diff --git a/src/transformers/models/ernie4_5/modular_ernie4_5.py b/src/transformers/models/ernie4_5/modular_ernie4_5.py index c6ed5bf1b819..a02ed12ec434 100644 --- a/src/transformers/models/ernie4_5/modular_ernie4_5.py +++ b/src/transformers/models/ernie4_5/modular_ernie4_5.py @@ -13,18 +13,13 @@ # limitations under the License. """PyTorch Ernie 4.5 model""" -from collections.abc import Callable - import torch from torch import nn -from ...cache_utils import Cache from ...modeling_rope_utils import dynamic_rope_update -from ...modeling_utils import ALL_ATTENTION_FUNCTIONS -from ...processing_utils import Unpack -from ...utils import TransformersKwargs, auto_docstring, can_return_tuple +from ...utils import auto_docstring, can_return_tuple from ...utils.generic import no_inherit_decorator -from ..glm.modeling_glm import eager_attention_forward, rotate_half +from ..glm.modeling_glm import rotate_half from ..llama.modeling_llama import ( LlamaAttention, LlamaForCausalLM, @@ -102,46 +97,6 @@ def __init__(self, config: Ernie4_5Config, layer_idx: int): self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.use_bias) self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.use_bias) - def forward( - self, - hidden_states: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, - attention_mask: torch.Tensor | None = None, - past_key_values: Cache | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor, torch.Tensor]: - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - - query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) - key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) - value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) - - if past_key_values is not None: - key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - attn_output, attn_weights = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask, - dropout=0.0 if not self.training else self.attention_dropout, - scaling=self.scaling, - **kwargs, - ) - - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attn_output = self.o_proj(attn_output) - return attn_output, attn_weights - class Ernie4_5ForCausalLM(LlamaForCausalLM): @can_return_tuple diff --git a/src/transformers/models/ernie4_5_moe/modular_ernie4_5_moe.py b/src/transformers/models/ernie4_5_moe/modular_ernie4_5_moe.py index ca30ee399b48..09cef9eae63c 100644 --- a/src/transformers/models/ernie4_5_moe/modular_ernie4_5_moe.py +++ b/src/transformers/models/ernie4_5_moe/modular_ernie4_5_moe.py @@ -13,8 +13,6 @@ # limitations under the License. """PyTorch Ernie 4.5 MoE model.""" -from collections.abc import Callable - import torch import torch.nn.functional as F from torch import nn @@ -23,17 +21,12 @@ from ...cache_utils import Cache, DynamicCache from ...masking_utils import create_causal_mask from ...modeling_outputs import MoeModelOutputWithPast -from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging from ...utils.generic import maybe_autocast, merge_with_config_defaults, no_inherit_decorator from ...utils.output_capturing import OutputRecorder, capture_outputs -from ..ernie4_5.modeling_ernie4_5 import ( # noqa: F401 - Ernie4_5RotaryEmbedding, - apply_rotary_pos_emb, - eager_attention_forward, - rotate_half, -) +from ..ernie4_5.modeling_ernie4_5 import Ernie4_5RotaryEmbedding, apply_rotary_pos_emb, rotate_half # noqa: F401 from ..llama.modeling_llama import LlamaAttention, LlamaRMSNorm from ..mixtral.modeling_mixtral import ( MixtralExperts, @@ -76,46 +69,6 @@ def __init__(self, config: Ernie4_5_MoeConfig, layer_idx: int): self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.use_bias) self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.use_bias) - def forward( - self, - hidden_states: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, - attention_mask: torch.Tensor | None = None, - past_key_values: Cache | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor, torch.Tensor]: - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - - query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) - key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) - value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) - - if past_key_values is not None: - key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - attn_output, attn_weights = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask, - dropout=0.0 if not self.training else self.attention_dropout, - scaling=self.scaling, - **kwargs, - ) - - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attn_output = self.o_proj(attn_output) - return attn_output, attn_weights - class Ernie4_5_MoeStatics(nn.Module): """ diff --git a/src/transformers/models/evolla/modular_evolla.py b/src/transformers/models/evolla/modular_evolla.py index 6c5e9864221b..52ad10547ce6 100644 --- a/src/transformers/models/evolla/modular_evolla.py +++ b/src/transformers/models/evolla/modular_evolla.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from collections.abc import Callable from dataclasses import dataclass import torch @@ -28,7 +27,7 @@ CausalLMOutputWithPast, ModelOutput, ) -from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel, slice_logits_to_keep +from ...modeling_utils import PreTrainedModel, slice_logits_to_keep from ...processing_utils import Unpack from ...utils import ( TransformersKwargs, @@ -49,7 +48,6 @@ EsmRotaryEmbedding, EsmSelfAttention, EsmSelfOutput, - apply_rotary_pos_emb, ) from ..llama.modeling_llama import ( LlamaAttention, @@ -117,53 +115,7 @@ def compute_default_rope_parameters(config: SaProtConfig, device=None, **kwargs) class EvollaSaProtSelfAttention(EsmSelfAttention): - def forward( - self, - hidden_states: torch.Tensor, - attention_mask: torch.FloatTensor | None = None, - encoder_hidden_states: torch.FloatTensor | None = None, - encoder_attention_mask: torch.FloatTensor | None = None, - position_embeddings: torch.Tensor | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor]: - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.attention_head_size) - - query_layer = self.query(hidden_states).view(hidden_shape).transpose(1, 2) - - is_cross_attention = encoder_hidden_states is not None - current_states = encoder_hidden_states if is_cross_attention else hidden_states - attention_mask = encoder_attention_mask if is_cross_attention else attention_mask - key_layer = self.key(current_states).view(hidden_shape).transpose(1, 2) - value_layer = self.value(current_states).view(hidden_shape).transpose(1, 2) - - # Matt: Our BERT model (which this code was derived from) scales attention logits down by sqrt(head_dim). - # EVOLLA_SA_PROT scales the query down by the same factor instead. Modulo numerical stability these are equivalent, - # but not when rotary embeddings get involved. Therefore, we scale the query here to match the original - # EVOLLA_SA_PROT code and fix rotary embeddings. - query_layer = query_layer * self.attention_head_size**-0.5 - - if self.position_embedding_type == "rotary": - cos, sin = position_embeddings - query_layer, key_layer = apply_rotary_pos_emb(query_layer, key_layer, cos, sin, unsqueeze_dim=1) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - attn_output, attn_weights = attention_interface( - self, - query_layer, - key_layer, - value_layer, - attention_mask, - dropout=0.0 if not self.training else self.dropout, - scaling=self.scaling, - **kwargs, - ) - - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - return attn_output, attn_weights + pass class EvollaSaProtSelfOutput(EsmSelfOutput): @@ -669,45 +621,7 @@ class EvollaMLP(LlamaMLP): class EvollaAttention(LlamaAttention): - def forward( - self, - hidden_states: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, - attention_mask: torch.Tensor | None = None, - past_key_values: Cache | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor, torch.Tensor]: - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - - query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) - key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) - value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) - - if past_key_values is not None: - key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - attn_output, attn_weights = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask, - dropout=0.0 if not self.training else self.attention_dropout, - scaling=self.scaling, - **kwargs, - ) - - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attn_output = self.o_proj(attn_output) - return attn_output, attn_weights + pass class EvollaDecoderLayer(LlamaDecoderLayer): diff --git a/src/transformers/models/glm/modular_glm.py b/src/transformers/models/glm/modular_glm.py index daa736120abb..26bc5f967b48 100644 --- a/src/transformers/models/glm/modular_glm.py +++ b/src/transformers/models/glm/modular_glm.py @@ -13,15 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -from collections.abc import Callable - import torch import torch.nn as nn -from ...cache_utils import Cache -from ...modeling_utils import ALL_ATTENTION_FUNCTIONS -from ...processing_utils import Unpack -from ...utils import TransformersKwargs, logging +from ...utils import logging from ...utils.generic import no_inherit_decorator from ..llama.modeling_llama import ( LlamaAttention, @@ -29,7 +24,6 @@ LlamaForSequenceClassification, LlamaForTokenClassification, LlamaRotaryEmbedding, - eager_attention_forward, ) from ..phi3.modeling_phi3 import Phi3MLP from .configuration_glm import GlmConfig @@ -119,46 +113,6 @@ def __init__(self, config: GlmConfig, layer_idx: int | None = None): super().__init__(config, layer_idx) self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=False) - def forward( - self, - hidden_states: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, - attention_mask: torch.Tensor | None = None, - past_key_values: Cache | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor, torch.Tensor]: - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - - query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) - key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) - value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) - - if past_key_values is not None: - key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - attn_output, attn_weights = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask, - dropout=0.0 if not self.training else self.attention_dropout, - scaling=self.scaling, - **kwargs, - ) - - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attn_output = self.o_proj(attn_output) - return attn_output, attn_weights - class GlmForCausalLM(LlamaForCausalLM): pass diff --git a/src/transformers/models/glm4v/modular_glm4v.py b/src/transformers/models/glm4v/modular_glm4v.py index 422d426fe99f..a4ec5207a6b4 100644 --- a/src/transformers/models/glm4v/modular_glm4v.py +++ b/src/transformers/models/glm4v/modular_glm4v.py @@ -37,7 +37,7 @@ logging, torch_compilable_check, ) -from ...utils.generic import get_max_seqlen, is_flash_attention_requested, merge_with_config_defaults +from ...utils.generic import merge_with_config_defaults from ...utils.output_capturing import capture_outputs from ...vision_utils import get_vision_attention_seqlens, get_vision_position_ids from ..glm4.modeling_glm4 import Glm4MLP, Glm4RMSNorm, eager_attention_forward @@ -53,7 +53,6 @@ Qwen2_5_VLVisionAttention, Qwen2_5_VLVisionBlock, Qwen2_5_VLVisionRotaryEmbedding, - apply_rotary_pos_emb_vision, ) from ..qwen2_vl.modeling_qwen2_vl import Qwen2VLModel from ..qwen2_vl.processing_qwen2_vl import ( @@ -347,74 +346,6 @@ def __init__(self, config: Glm4vVisionConfig) -> None: self.qkv = nn.Linear(config.hidden_size, config.hidden_size * 3, bias=config.attention_bias) self.proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False) - def forward( - self, - hidden_states: torch.Tensor, - cu_seqlens: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, - max_seqlen: int | None = None, - **kwargs, - ) -> torch.Tensor: - seq_length = hidden_states.shape[0] - query_states, key_states, value_states = ( - self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0) - ) - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb_vision(query_states, key_states, cos, sin) - - query_states = query_states.transpose(0, 1).unsqueeze(0) - key_states = key_states.transpose(0, 1).unsqueeze(0) - value_states = value_states.transpose(0, 1).unsqueeze(0) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - if is_flash_attention_requested(self.config): - # Flash Attention: Use cu_seqlens for variable length attention - max_seqlen = get_max_seqlen(cu_seqlens, self.config, kwargs={"max_seqlen": max_seqlen}) - attn_output, _ = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask=None, - scaling=self.scaling, - dropout=0.0 if not self.training else self.attention_dropout, - cu_seq_lens_q=cu_seqlens, - cu_seq_lens_k=cu_seqlens, - max_length_q=max_seqlen, - max_length_k=max_seqlen, - is_causal=False, - **kwargs, - ) - else: - # Other implementations: Process each chunk separately - lengths = cu_seqlens[1:] - cu_seqlens[:-1] - splits = [ - torch.split(tensor, lengths.tolist(), dim=2) for tensor in (query_states, key_states, value_states) - ] - - attn_outputs = [ - attention_interface( - self, - q, - k, - v, - attention_mask=None, - scaling=self.scaling, - dropout=0.0 if not self.training else self.attention_dropout, - is_causal=False, - **kwargs, - )[0] - for q, k, v in zip(*splits) - ] - attn_output = torch.cat(attn_outputs, dim=1) - - attn_output = attn_output.reshape(seq_length, -1).contiguous() - attn_output = self.proj(attn_output) - return attn_output - class Glm4vVisionBlock(Qwen2_5_VLVisionBlock): def __init__(self, config) -> None: diff --git a/src/transformers/models/helium/modular_helium.py b/src/transformers/models/helium/modular_helium.py index c0927665031e..5504f086b060 100644 --- a/src/transformers/models/helium/modular_helium.py +++ b/src/transformers/models/helium/modular_helium.py @@ -13,22 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. import math -from collections.abc import Callable import torch import torch.nn as nn -from ...cache_utils import Cache -from ...modeling_utils import ALL_ATTENTION_FUNCTIONS -from ...processing_utils import Unpack -from ...utils import TransformersKwargs, logging +from ...utils import logging from ...utils.generic import no_inherit_decorator -from ..gemma.modeling_gemma import ( - GemmaForCausalLM, - GemmaForSequenceClassification, - GemmaForTokenClassification, - eager_attention_forward, -) +from ..gemma.modeling_gemma import GemmaForCausalLM, GemmaForSequenceClassification, GemmaForTokenClassification from ..granite.modeling_granite import GraniteAttention from ..llama.modeling_llama import LlamaDecoderLayer, LlamaMLP, LlamaModel, LlamaPreTrainedModel, LlamaRotaryEmbedding from .configuration_helium import HeliumConfig @@ -107,46 +98,6 @@ def __init__(self, config: HeliumConfig, layer_idx: int | None = None): self.o_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False) self.scaling = 1 / math.sqrt(self.head_dim) - def forward( - self, - hidden_states: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, - attention_mask: torch.Tensor | None = None, - past_key_values: Cache | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor, torch.Tensor]: - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - - query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) - key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) - value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) - - if past_key_values is not None: - key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - attn_output, attn_weights = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask, - dropout=0.0 if not self.training else self.attention_dropout, - scaling=self.scaling, - **kwargs, - ) - - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attn_output = self.o_proj(attn_output) - return attn_output, attn_weights - class HeliumDecoderLayer(LlamaDecoderLayer): def __init__(self, config: HeliumConfig, layer_idx: int | None = None): diff --git a/src/transformers/models/janus/modular_janus.py b/src/transformers/models/janus/modular_janus.py index 8d9f1e49c4be..29e302af977e 100644 --- a/src/transformers/models/janus/modular_janus.py +++ b/src/transformers/models/janus/modular_janus.py @@ -632,12 +632,12 @@ def __init__(self, config: JanusVQVAEConfig): self.decoder = JanusVQVAEDecoder(config) self.gradient_checkpointing = False - # Initialize the VQVAE model. - self.post_init() - self.encoder = JanusVQVAEEncoder(config) self.quantize = JanusVQVAEVectorQuantizer(config) + # Initialize the VQVAE model. + self.post_init() + def decode(self, image_tokens: torch.LongTensor) -> torch.FloatTensor: """ Decodes quantized token IDs into pixel values. diff --git a/src/transformers/models/jina_embeddings_v3/modular_jina_embeddings_v3.py b/src/transformers/models/jina_embeddings_v3/modular_jina_embeddings_v3.py index 83f87aa27a16..1fd5407370ab 100644 --- a/src/transformers/models/jina_embeddings_v3/modular_jina_embeddings_v3.py +++ b/src/transformers/models/jina_embeddings_v3/modular_jina_embeddings_v3.py @@ -255,11 +255,11 @@ def __init__(self, config: JinaEmbeddingsV3Config, add_pooling_layer=True): self.layers = nn.ModuleList([JinaEmbeddingsV3Layer(config) for _ in range(config.num_hidden_layers)]) del self.encoder + self.embeddings = JinaEmbeddingsV3Embeddings(config) + # Initialize weights and apply final processing self.post_init() - self.embeddings = JinaEmbeddingsV3Embeddings(config) - @merge_with_config_defaults @capture_outputs @auto_docstring diff --git a/src/transformers/models/lw_detr/modular_lw_detr.py b/src/transformers/models/lw_detr/modular_lw_detr.py index d02c628eecb9..0ae2e415f285 100644 --- a/src/transformers/models/lw_detr/modular_lw_detr.py +++ b/src/transformers/models/lw_detr/modular_lw_detr.py @@ -240,39 +240,6 @@ def __init__(self, config: LwDetrViTConfig): self.k_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=False) self.num_key_value_groups = 1 - def forward( - self, - hidden_states: torch.Tensor, - attention_mask: torch.Tensor | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor, torch.Tensor]: - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - - query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) - key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) - value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - attn_output, attn_weights = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask, - dropout=0.0 if not self.training else self.attention_dropout, - scaling=self.scaling, - **kwargs, - ) - - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attn_output = self.o_proj(attn_output) - - return attn_output, attn_weights - class LwDetrViTMlp(VitDetMlp): pass diff --git a/src/transformers/models/muse_glimmer/modular_muse_glimmer.py b/src/transformers/models/muse_glimmer/modular_muse_glimmer.py index 060dff383c05..08bc613d8bea 100644 --- a/src/transformers/models/muse_glimmer/modular_muse_glimmer.py +++ b/src/transformers/models/muse_glimmer/modular_muse_glimmer.py @@ -35,7 +35,7 @@ from ...processing_utils import Unpack, VideosKwargs from ...utils import TensorType, TransformersKwargs, auto_docstring, logging from ...utils.constants import IMAGENET_STANDARD_MEAN, IMAGENET_STANDARD_STD -from ...utils.generic import get_max_seqlen, is_flash_attention_requested, merge_with_config_defaults +from ...utils.generic import merge_with_config_defaults from ...utils.output_capturing import capture_outputs from ...video_processing_utils import BaseVideoProcessor from ...video_utils import VideoMetadata, group_videos_by_shape, reorder_videos @@ -66,7 +66,6 @@ Kimi_K25VisionAttention, Kimi_K25VisionEncoderLayer, Kimi_K25VisionMLP, - apply_rotary_pos_emb_vision, ) from ..llama.modeling_llama import eager_attention_forward from ..paddleocr_vl.modeling_paddleocr_vl import PaddleOCRVisionEmbeddings @@ -880,75 +879,7 @@ def forward( class MuseGlimmerVisionAttention(Kimi_K25VisionAttention): - def forward( - self, - hidden_states: torch.Tensor, - cu_seqlens: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, - max_seqlen: int | None = None, - **kwargs, - ) -> torch.Tensor: - seq_length = hidden_states.shape[0] - - query_states = self.q_proj(hidden_states).reshape(1, seq_length, -1, self.head_dim) - key_states = self.k_proj(hidden_states).reshape(1, seq_length, -1, self.head_dim) - value_states = self.v_proj(hidden_states).reshape(1, seq_length, -1, self.head_dim) - - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb_vision(query_states, key_states, cos, sin) - - query_states = query_states.transpose(2, 1) - key_states = key_states.transpose(2, 1) - value_states = value_states.transpose(2, 1) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - if is_flash_attention_requested(self.config): - # Flash Attention: Use cu_seqlens for variable length attention - max_seqlen = get_max_seqlen(cu_seqlens, self.config, kwargs={"max_seqlen": max_seqlen}) - attn_output, _ = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask=None, - scaling=self.scaling, - dropout=0.0 if not self.training else self.attention_dropout, - cu_seq_lens_q=cu_seqlens, - cu_seq_lens_k=cu_seqlens, - max_length_q=max_seqlen, - max_length_k=max_seqlen, - is_causal=False, - **kwargs, - ) - else: - # Other implementations: Process each chunk separately - lengths = cu_seqlens[1:] - cu_seqlens[:-1] - splits = [ - torch.split(tensor, lengths.tolist(), dim=2) for tensor in (query_states, key_states, value_states) - ] - - attn_outputs = [ - attention_interface( - self, - q, - k, - v, - attention_mask=None, - scaling=self.scaling, - dropout=0.0 if not self.training else self.attention_dropout, - is_causal=False, - **kwargs, - )[0] - for q, k, v in zip(*splits) - ] - attn_output = torch.cat(attn_outputs, dim=1) - - attn_output = attn_output.reshape(seq_length, -1).contiguous() - attn_output = self.proj(attn_output) - return attn_output + pass class MuseGlimmerVisionMLP(Kimi_K25VisionMLP): diff --git a/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py b/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py index 75c85410b7a6..bc26e8a1b7b1 100644 --- a/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py +++ b/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py @@ -722,8 +722,8 @@ def __init__(self, config: Nemotron3_5TranscribeConfig): self.word_timestamp_head = nn.Conv1d( config.word_timestamp_config.hidden_size, config.word_timestamp_config.vocab_size, kernel_size=1 ) - self.post_init() self.model = Nemotron3_5TranscribeModel(config) + self.post_init() @auto_docstring def get_audio_features(self, input_features, input_features_mask, **kwargs): diff --git a/src/transformers/models/olmo_hybrid/modular_olmo_hybrid.py b/src/transformers/models/olmo_hybrid/modular_olmo_hybrid.py index 6ee8d85251a6..0aacd21d3c3d 100644 --- a/src/transformers/models/olmo_hybrid/modular_olmo_hybrid.py +++ b/src/transformers/models/olmo_hybrid/modular_olmo_hybrid.py @@ -544,8 +544,8 @@ def __init__(self, config: OlmoHybridConfig): and config.rope_parameters.get("rope_theta") is not None else None ) - self.post_init() self.norm = OlmoHybridRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_init() @merge_with_config_defaults @capture_outputs diff --git a/src/transformers/models/pp_doclayout_v3/modular_pp_doclayout_v3.py b/src/transformers/models/pp_doclayout_v3/modular_pp_doclayout_v3.py index 806492c10cfe..af6d084ae863 100644 --- a/src/transformers/models/pp_doclayout_v3/modular_pp_doclayout_v3.py +++ b/src/transformers/models/pp_doclayout_v3/modular_pp_doclayout_v3.py @@ -1330,9 +1330,9 @@ def __init__(self, config: PPDocLayoutV3Config): self.model.denoising_class_embed = nn.Embedding(config.num_labels, config.d_model) self.num_queries = config.num_queries + self.model = PPDocLayoutV3Model(config) self.post_init() - self.model = PPDocLayoutV3Model(config) @auto_docstring @can_return_tuple diff --git a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py index 3df1c9f06695..d307f2163a4f 100644 --- a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py +++ b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py @@ -33,8 +33,6 @@ from ...processing_utils import MultiModalData, ProcessingKwargs, Unpack, VideosKwargs from ...utils import auto_docstring, is_torchvision_available, logging from ...utils.generic import ( - get_max_seqlen, - is_flash_attention_requested, merge_with_config_defaults, ) from ...utils.output_capturing import capture_outputs @@ -53,7 +51,6 @@ Qwen2_5_VLRotaryEmbedding, Qwen2_5_VLVisionBlock, Qwen2_5_VLVisionRotaryEmbedding, - apply_rotary_pos_emb_vision, ) from ..qwen2_vl.modeling_qwen2_vl import ( PatchEmbed, @@ -264,74 +261,6 @@ def __init__(self, config: Qwen3VLVisionConfig) -> None: super().__init__() self.dim = config.hidden_size - def forward( - self, - hidden_states: torch.Tensor, - cu_seqlens: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None, - max_seqlen: int | None = None, - **kwargs, - ) -> torch.Tensor: - seq_length = hidden_states.shape[0] - query_states, key_states, value_states = ( - self.qkv(hidden_states).reshape(seq_length, 3, self.num_heads, -1).permute(1, 0, 2, 3).unbind(0) - ) - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb_vision(query_states, key_states, cos, sin) - - query_states = query_states.transpose(0, 1).unsqueeze(0) - key_states = key_states.transpose(0, 1).unsqueeze(0) - value_states = value_states.transpose(0, 1).unsqueeze(0) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - if is_flash_attention_requested(self.config): - # Flash Attention: Use cu_seqlens for variable length attention - max_seqlen = get_max_seqlen(cu_seqlens, self.config, kwargs={"max_seqlen": max_seqlen}) - attn_output, _ = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask=None, - scaling=self.scaling, - dropout=0.0 if not self.training else self.attention_dropout, - cu_seq_lens_q=cu_seqlens, - cu_seq_lens_k=cu_seqlens, - max_length_q=max_seqlen, - max_length_k=max_seqlen, - is_causal=False, - **kwargs, - ) - else: - # Other implementations: Process each chunk separately - lengths = cu_seqlens[1:] - cu_seqlens[:-1] - splits = [ - torch.split(tensor, lengths.tolist(), dim=2) for tensor in (query_states, key_states, value_states) - ] - - attn_outputs = [ - attention_interface( - self, - q, - k, - v, - attention_mask=None, - scaling=self.scaling, - dropout=0.0 if not self.training else self.attention_dropout, - is_causal=False, - **kwargs, - )[0] - for q, k, v in zip(*splits) - ] - attn_output = torch.cat(attn_outputs, dim=1) - - attn_output = attn_output.reshape(seq_length, -1).contiguous() - attn_output = self.proj(attn_output) - return attn_output - class Qwen3VLVisionBlock(Qwen2_5_VLVisionBlock): def __init__(self, config, attn_implementation: str = "sdpa") -> None: diff --git a/src/transformers/models/qwen4_exp/modular_qwen4_exp.py b/src/transformers/models/qwen4_exp/modular_qwen4_exp.py index 0c880ac870f0..0be86ee49b0e 100644 --- a/src/transformers/models/qwen4_exp/modular_qwen4_exp.py +++ b/src/transformers/models/qwen4_exp/modular_qwen4_exp.py @@ -14,7 +14,6 @@ """PyTorch Qwen4-Exp model.""" import math -from collections.abc import Callable import torch import torch.nn.functional as F @@ -28,7 +27,7 @@ from ...masking_utils import create_causal_mask, create_recurrent_attention_mask from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling -from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, logging from ...utils.generic import merge_with_config_defaults, no_inherit_decorator @@ -41,7 +40,6 @@ apply_mask_to_padding_states, causal_conv1d_fn, causal_conv1d_update, - eager_attention_forward, rotate_half, torch_chunk_gated_delta_rule, torch_recurrent_gated_delta_rule, @@ -504,45 +502,15 @@ def forward( # The cos/sin are the full positions here due to the indexer, so we need to slice to get current positions position_embeddings = (x[:, -hidden_states.shape[1] :, :] for x in position_embeddings) - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - query_states, gate = torch.chunk( - self.q_proj(hidden_states).view(*input_shape, -1, self.head_dim * 2), 2, dim=-1 - ) - gate = gate.reshape(*input_shape, -1) - - query_states = self.q_norm(query_states.view(hidden_shape)).transpose(1, 2) - key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2) - value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - cos, sin = position_embeddings - query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin) - - if past_key_values is not None: - key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - - attn_output, attn_weights = attention_interface( - self, - query_states, - key_states, - value_states, - attention_mask, - dropout=0.0 if not self.training else self.attention_dropout, - scaling=self.scaling, + return super().forward( + hidden_states=hidden_states, + position_embeddings=position_embeddings, + attention_mask=attention_mask, + past_key_values=past_key_values, **kwargs, ) - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - attn_output = attn_output * torch.sigmoid(gate) - - attn_output = self.o_proj(attn_output) - return attn_output, attn_weights - class Qwen4ExpTextMLP(Qwen3NextMLP): pass diff --git a/src/transformers/models/step3p7/modular_step3p7.py b/src/transformers/models/step3p7/modular_step3p7.py index c19642464170..7d0a5754854a 100644 --- a/src/transformers/models/step3p7/modular_step3p7.py +++ b/src/transformers/models/step3p7/modular_step3p7.py @@ -598,40 +598,7 @@ class Step3p7VisionMLP(MiniMaxM3VLVisionMLP): class Step3p7VisionAttention(MiniMaxM3VLVisionAttention): - def forward( - self, - hidden_states: torch.Tensor, - position_embeddings: tuple[torch.Tensor, torch.Tensor], - attention_mask: torch.Tensor | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> tuple[torch.Tensor, torch.Tensor | None]: - """Input shape: Batch x Time x Channel""" - input_shape = hidden_states.shape[:-1] - hidden_shape = (*input_shape, -1, self.head_dim) - - queries = self.q_proj(hidden_states).view(hidden_shape) - keys = self.k_proj(hidden_states).view(hidden_shape) - values = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) - - cos, sin = position_embeddings - queries, keys = apply_rotary_pos_emb_vision(queries, keys, cos, sin) - queries, keys = queries.transpose(1, 2), keys.transpose(1, 2) - - attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface( - self.config._attn_implementation, eager_attention_forward - ) - attn_output, attn_weights = attention_interface( - self, - queries, - keys, - values, - attention_mask, - scaling=self.scale, - dropout=0.0 if not self.training else self.dropout, - **kwargs, - ) - attn_output = attn_output.reshape(*input_shape, -1).contiguous() - return self.out_proj(attn_output), attn_weights + pass class Step3p7VisionEncoderLayer(GradientCheckpointingLayer): diff --git a/utils/fix_modular_inherited_overrides.py b/utils/fix_modular_inherited_overrides.py index e90dee078b94..879520a6d8cc 100644 --- a/utils/fix_modular_inherited_overrides.py +++ b/utils/fix_modular_inherited_overrides.py @@ -112,7 +112,9 @@ def minimal_init(generated: cst.FunctionDef, names: set[str], modular_class: cst (s for s in modular_class.body.body if isinstance(s, cst.FunctionDef) and s.name.value == "__init__"), None ) if existing is not None: - return existing.with_changes(body=existing.body.with_changes(body=[*existing.body.body, *needed])) + body = list(existing.body.body) + post_init = next((i for i, s in enumerate(body) if "post_init" in cst.Module(body=[s]).code), len(body)) + return existing.with_changes(body=existing.body.with_changes(body=[*body[:post_init], *needed, *body[post_init:]])) return generated.with_changes(body=generated.body.with_changes(body=[super_init_call(generated), *needed])) diff --git a/utils/modular_model_converter.py b/utils/modular_model_converter.py index ee346255e3dc..a22f8ed5414b 100644 --- a/utils/modular_model_converter.py +++ b/utils/modular_model_converter.py @@ -2014,7 +2014,8 @@ def find_inherited_code_mismatches( Returns `(class_name, member, used_name, parent_class)` for each such case. """ generated = {name: entry["node"] for body in files.values() for name, entry in body.items()} - modular_defined = set(modular_mapper.classes) | set(modular_mapper.functions) + # ponytail: classes only; redefined functions are looked up in module globals, the usual modular pattern + modular_defined = set(modular_mapper.classes) mismatches = [] for class_name, modular_node in modular_mapper.classes.items(): bases = [ From 2ee41edfc74f56eb2ee5f8f918342f4535b68ff6 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 30 Oct 2026 12:15:41 +0100 Subject: [PATCH 4/7] remove one-off fixer script --- utils/fix_modular_inherited_overrides.py | 205 ----------------------- 1 file changed, 205 deletions(-) delete mode 100644 utils/fix_modular_inherited_overrides.py diff --git a/utils/fix_modular_inherited_overrides.py b/utils/fix_modular_inherited_overrides.py deleted file mode 100644 index 879520a6d8cc..000000000000 --- a/utils/fix_modular_inherited_overrides.py +++ /dev/null @@ -1,205 +0,0 @@ -"""Make modular files explicit: copy generated members whose inherited version would use the parent's classes.""" - -import builtins -import json -import subprocess -import sys - -import libcst as cst -from libcst import matchers as m - -sys.path.insert(0, "utils") -import modular_model_converter as mmc # noqa: E402 - - -captured = {} -mmc.check_inherited_code_uses_parent_definitions = lambda mapper, files: captured.update(mapper=mapper, files={k: dict(v) for k, v in files.items()}) - - -def top_level_names(module): - out = [] - for node in module.body: - if isinstance(node, (cst.ClassDef, cst.FunctionDef)): - out.append(node.name.value) - else: - out.append(None) - return out - - -def import_lines_for(module, name): - """Return an import statement code importing `name` if `module` imports it at top level.""" - for node in module.body: - stmts = [node] - if isinstance(node, cst.If): # `if is_torch_available():` blocks - stmts = list(node.body.body) - for stmt in stmts: - if not m_simple(stmt): - continue - imp = stmt.body[0] - if isinstance(imp, cst.ImportFrom) and not isinstance(imp.names, cst.ImportStar): - for alias in imp.names: - asname = alias.asname.name.value if alias.asname else None - real = mmc.get_full_attribute_name(alias.name) - if (asname or real) == name: - mod = cst.Module(body=[]).code_for_node(imp.module) if imp.module else "" - dots = "." * len(imp.relative) - return f"from {dots}{mod} import {real}" + (f" as {asname}" if asname else "") - if isinstance(imp, cst.Import): - for alias in imp.names: - asname = alias.asname.name.value if alias.asname else None - real = mmc.get_full_attribute_name(alias.name) - if (asname or real.split(".")[0]) == name: - return f"import {real}" + (f" as {asname}" if asname else "") - return None - - -def m_simple(stmt): - return isinstance(stmt, cst.SimpleStatementLine) and len(stmt.body) == 1 - - -class Inserter(cst.CSTTransformer): - def __init__(self, members): # {class_name: {key: stmt}} - self.members = members - - def leave_ClassDef(self, original, updated): - todo = dict(self.members.get(updated.name.value, {})) - if not todo: - return updated - body = [] - for stmt in updated.body.body: - if isinstance(stmt, cst.BaseSmallStatement): - stmt = cst.SimpleStatementLine(body=[stmt]) - key = mmc._statement_key(stmt) - if key in todo: - body.append(todo.pop(key)) - elif m_simple(stmt) and isinstance(stmt.body[0], cst.Pass): - continue - else: - body.append(stmt) - first_method = next((i for i, s in enumerate(body) if isinstance(s, cst.FunctionDef)), len(body)) - early = [s for k, s in todo.items() if not isinstance(s, cst.FunctionDef) or k == "__init__"] - late = [s for k, s in todo.items() if isinstance(s, cst.FunctionDef) and k != "__init__"] - body = body[:first_method] + early + body[first_method:] + late - if isinstance(updated.body, cst.SimpleStatementSuite): # one-line `class A(B): pass` - return updated.with_changes(body=cst.IndentedBlock(body=body)) - return updated.with_changes(body=updated.body.with_changes(body=body)) - - -class Renamer(cst.CSTTransformer): - def __init__(self, mapping): - self.mapping = mapping - - def leave_Name(self, original, updated): - return updated.with_changes(value=self.mapping.get(updated.value, updated.value)) - - -def super_init_call(func: cst.FunctionDef) -> cst.SimpleStatementLine: - p = func.params - args = [cst.Arg(cst.Name(x.name.value)) for x in [*p.posonly_params, *p.params] if x.name.value != "self"] - if isinstance(p.star_arg, cst.Param): - args.append(cst.Arg(cst.Name(p.star_arg.name.value), star="*")) - args += [cst.Arg(cst.Name(x.name.value), keyword=cst.Name(x.name.value)) for x in p.kwonly_params] - if p.star_kwarg is not None: - args.append(cst.Arg(cst.Name(p.star_kwarg.name.value), star="**")) - return cst.parse_statement(f"super().__init__({cst.Module(body=[]).code_for_node(cst.Call(func=cst.Name('f'), args=args))[2:-1]})") - - -def minimal_init(generated: cst.FunctionDef, names: set[str], modular_class: cst.ClassDef) -> cst.FunctionDef: - """`super().__init__(...)` (or the existing modular `__init__`) + only the statements using the redefined names. - The converter replaces same-target `self.x = ...` assignments in place, so the generated code does not change.""" - needed = [s for s in generated.body.body if mmc._names_in(s) & names] - existing = next( - (s for s in modular_class.body.body if isinstance(s, cst.FunctionDef) and s.name.value == "__init__"), None - ) - if existing is not None: - body = list(existing.body.body) - post_init = next((i for i, s in enumerate(body) if "post_init" in cst.Module(body=[s]).code), len(body)) - return existing.with_changes(body=existing.body.with_changes(body=[*body[:post_init], *needed, *body[post_init:]])) - return generated.with_changes(body=generated.body.with_changes(body=[super_init_call(generated), *needed])) - - -def undefined_names(path): - out = subprocess.run( - ["ruff", "check", "--select", "F821", "--output-format", "json", "--no-cache", path], - capture_output=True, - text=True, - ).stdout - return sorted({d["message"].split("`")[1] for d in json.loads(out or "[]")}) - - -def fix(path): - captured.clear() - mmc.convert_modular_file(path) - mapper, files = captured["mapper"], captured["files"] - mismatches = mmc.find_inherited_code_mismatches(mapper, files) - if not mismatches: - return 0, [] - generated = {name: entry["node"] for body in files.values() for name, entry in body.items()} - flagged = {} - for class_name, key, name, _ in mismatches: - if key is not None: - flagged.setdefault((class_name, key), set()).add(name) - members, manual = {}, [] - for (class_name, key), names in flagged.items(): - stmt = next(s for s in generated[class_name].body.body if mmc._statement_key(s) == key) - if isinstance(stmt, cst.FunctionDef) and key == "__init__": - stmt = minimal_init(stmt, names, mapper.classes[class_name]) - elif isinstance(stmt, cst.FunctionDef) and m.findall(stmt, m.Call(func=m.Attribute(value=m.Call(func=m.Name("super"))))): - manual.append(f"{class_name}.{key}") - members.setdefault(class_name, {})[key] = stmt - source = open(path).read() - code = cst.parse_module(source).visit(Inserter(members)).code - open(path, "w").write(code) - - # Resolve names the copied code uses but the modular file does not define - renamed_to_original, import_for = {}, {} - for file, original in mapper.model_specific_modules.items(): - renamed = original.visit(mapper.renamers[file]) - rel = "..%s.%s" % tuple(file.split(".")[-2:]) - for o, r in zip(top_level_names(original), top_level_names(renamed)): - if r is not None and r not in renamed_to_original: - renamed_to_original[r] = (o, f"from {rel} import {o}") - for name in undefined_names(path): - if name not in import_for and name not in renamed_to_original: - line = import_lines_for(renamed, name) - if line is not None: - import_for[name] = line - missing, rename, imports = [], {}, [] - for name in undefined_names(path): - if name in renamed_to_original: - original_name, line = renamed_to_original[name] - rename[name] = original_name - imports.append(line) - elif name in import_for: - imports.append(import_for[name]) - elif not hasattr(builtins, name): - missing.append(name) - module = cst.parse_module(open(path).read()) - if rename: - module = module.visit(Renamer(rename)) - if imports: - idx = max( - i - for i, node in enumerate(module.body) - if m_simple(node) and isinstance(node.body[0], (cst.Import, cst.ImportFrom)) - ) - new_nodes = [cst.parse_statement(line) for line in sorted(set(imports))] - module = module.with_changes(body=[*module.body[: idx + 1], *new_nodes, *module.body[idx + 1 :]]) - code = module.code - open(path, "w").write(code) - return len(mismatches), missing + [f"super() in {x}" for x in manual] - - -if __name__ == "__main__": - import time - - paths = sys.argv[1:] - t0 = time.time() - for i, path in enumerate(paths, 1): - try: - n, missing = fix(path) - status = f"fixed {n}" + (f" | UNRESOLVED {missing}" if missing else "") if n else "clean" - except Exception as e: - status = f"CRASH {type(e).__name__}: {e}"[:200] - el = time.time() - t0 - print(f"[{i}/{len(paths)}] {path.split('/')[-1]} {status} | elapsed {el:.0f}s | eta ~{el / i * (len(paths) - i):.0f}s", flush=True) From 9f378d0bff61f07d72b87dc16adee242a06c9f3f Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 31 Oct 2026 09:31:26 +0900 Subject: [PATCH 5/7] [modular] use parent definitions explicitly in remaining modular files --- .../models/altclip/modular_altclip.py | 87 +++++- .../chinese_clip/modular_chinese_clip.py | 89 +++++- .../models/clipseg/modular_clipseg.py | 97 ++++++- .../cosmos3_edge/modular_cosmos3_edge.py | 1 - .../models/d_fine/modular_d_fine.py | 15 +- .../deepseek_ocr2/modular_deepseek_ocr2.py | 25 +- .../deepseek_v32/modular_deepseek_v32.py | 51 +++- .../modular_deepseek_vl_hybrid.py | 7 - .../models/deimv2/modular_deimv2.py | 77 ++++- .../models/edgetam/modular_edgetam.py | 10 +- .../edgetam_video/modular_edgetam_video.py | 39 ++- .../modular_embedding_gemma2.py | 96 +------ .../modular_ernie4_5_vl_moe.py | 6 + .../models/eurobert/modular_eurobert.py | 23 +- .../models/exaone4_5/modular_exaone4_5.py | 42 +-- .../models/flex_olmo/modular_flex_olmo.py | 26 +- .../models/flint/modular_flint.py | 41 ++- .../fun_asr_nano/modular_fun_asr_nano.py | 33 --- .../models/gemma/modular_gemma.py | 26 ++ .../gemma4_unified/modular_gemma4_unified.py | 6 +- .../models/glm4_moe/modular_glm4_moe.py | 31 +- .../glm4_moe_lite/modular_glm4_moe_lite.py | 12 +- .../models/glm4v/modular_glm4v.py | 42 +-- .../models/glm4v_moe/modular_glm4v_moe.py | 19 +- .../models/glm5_next/modular_glm5_next.py | 15 + .../models/glm_image/modular_glm_image.py | 29 +- .../models/glm_moe_dsa/modular_glm_moe_dsa.py | 31 ++ .../modular_gradium_phonon_tts.py | 43 ++- .../modular_granite_speech_plus.py | 37 ++- .../modular_granitemoehybrid.py | 12 +- .../modular_granitemoeshared.py | 31 ++ .../higgs_audio_v2/modular_higgs_audio_v2.py | 21 +- .../modular_instructblipvideo.py | 41 +++ .../models/jais2/modular_jais2.py | 21 +- .../models/kimi_k25/modular_kimi_k25.py | 2 - .../models/mellum/modular_mellum.py | 51 +++- .../models/metaclip_2/modular_metaclip_2.py | 129 ++++++++- .../models/minicpm_ocr/modular_minicpm_ocr.py | 14 +- .../models/minimax_m2/modular_minimax_m2.py | 35 ++- .../minimax_m3_vl/modular_minimax_m3_vl.py | 40 +-- .../models/moonshine/modular_moonshine.py | 7 + .../modular_moonshine_streaming.py | 37 +-- .../muse_glimmer/modular_muse_glimmer.py | 7 +- .../modular_nemotron3_5_transcribe.py | 30 +- .../modular_nemotron_asr_streaming.py | 15 - .../models/nomic_bert/modular_nomic_bert.py | 28 +- .../paddleocr_vl/modular_paddleocr_vl.py | 14 + .../models/pocket_tts/modular_pocket_tts.py | 19 +- .../modular_pp_doclayout_v2.py | 270 +++++++++++++++++- .../pp_formulanet/modular_pp_formulanet.py | 2 - .../qwen2_5_omni/modular_qwen2_5_omni.py | 19 ++ .../models/qwen2_5_vl/modular_qwen2_5_vl.py | 42 +-- .../models/qwen3_asr/modular_qwen3_asr.py | 18 ++ .../qwen3_omni_moe/modular_qwen3_omni_moe.py | 76 +++++ .../models/qwen3_vl/modular_qwen3_vl.py | 43 +-- .../qwen3_vl_moe/modular_qwen3_vl_moe.py | 26 +- .../models/rf_detr/modular_rf_detr.py | 106 ++++++- .../models/rt_detr_v2/modular_rt_detr_v2.py | 77 ++++- .../models/sam_hq/modular_sam_hq.py | 31 +- .../models/siglip2/modular_siglip2.py | 82 +++++- .../models/smolvlm/modular_smolvlm.py | 8 + .../models/solar_open/modular_solar_open.py | 24 +- .../models/timesfm2_5/modular_timesfm2_5.py | 30 +- .../models/tipsv2/modular_tipsv2.py | 25 ++ .../unlimited_ocr/modular_unlimited_ocr.py | 11 +- .../models/vaultgemma/modular_vaultgemma.py | 5 +- .../video_llama_3/modular_video_llama_3.py | 45 +-- .../models/videomt/modular_videomt.py | 35 ++- utils/modular_model_converter.py | 72 ++--- 69 files changed, 2072 insertions(+), 585 deletions(-) diff --git a/src/transformers/models/altclip/modular_altclip.py b/src/transformers/models/altclip/modular_altclip.py index 22921d23aa20..6f85c0fa6bbb 100644 --- a/src/transformers/models/altclip/modular_altclip.py +++ b/src/transformers/models/altclip/modular_altclip.py @@ -17,6 +17,7 @@ from huggingface_hub.dataclasses import strict from ... import initialization as init +from ...configuration_utils import PreTrainedConfig from ...masking_utils import create_bidirectional_mask from ...modeling_outputs import ( BaseModelOutputWithPooling, @@ -24,7 +25,7 @@ ) from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack -from ...utils import TransformersKwargs, auto_docstring, can_return_tuple +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging from ...utils.generic import merge_with_config_defaults from ...utils.output_capturing import capture_outputs from ..chinese_clip.modeling_chinese_clip import ( @@ -55,6 +56,9 @@ ) +logger = logging.get_logger(__name__) + + @auto_docstring(checkpoint="BAAI/AltCLIP") @strict class AltCLIPTextConfig(CLIPTextConfig): @@ -144,6 +148,83 @@ class AltCLIPConfig(CLIPConfig): ```""" projection_dim: int = 768 + sub_configs_defaults = { + "vision_config": AltCLIPVisionConfig, + "text_config": AltCLIPTextConfig, + } + + def __post_init__(self, **kwargs): + # For backward compatibility check keyword args + # Instead of simply assigning `[text|vision]_config_dict` to `[text|vision]_config`, we use the values in + # `[text|vision]_config_dict` to update the values in `[text|vision]_config`. The values should be same in most + # cases, but we don't want to break anything regarding `_config_dict` that existed before commit `8827e1b2`. + if (text_config_dict := kwargs.pop("text_config_dict", None)) is not None: + # This is the complete result when using `text_config_dict`. + _text_config_dict = AltCLIPTextConfig(**text_config_dict).to_dict() + text_config = ( + self.text_config.to_dict() if isinstance(self.text_config, PreTrainedConfig) else self.text_config + ) + text_config = text_config or {} + + # Give a warning if the values exist in both `_text_config_dict` and `text_config` but being different. + for key, value in _text_config_dict.items(): + if key in text_config and value != text_config[key] and key != "transformers_version": + # If specified in `text_config_dict` + if key in text_config_dict: + message = ( + f"`{key}` is found in both `text_config_dict` and `text_config` but with different values. " + f'The value `text_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`text_config_dict` is provided which will be used to initialize `CLIPTextConfig`. The " + f'value `text_config["{key}"]` will be overridden.' + ) + logger.info(message) + + # Update all values in `text_config` with the ones in `_text_config_dict`. + text_config.update(_text_config_dict) + self.text_config = text_config + + if (vision_config_dict := kwargs.pop("vision_config_dict", None)) is not None: + # This is the complete result when using `vision_config_dict`. + _vision_config_dict = AltCLIPVisionConfig(**vision_config_dict).to_dict() + vision_config = ( + self.vision_config.to_dict() + if isinstance(self.vision_config, PreTrainedConfig) + else self.vision_config + ) + vision_config = vision_config or {} + + # convert keys to string instead of integer + if "id2label" in _vision_config_dict: + _vision_config_dict["id2label"] = { + str(key): value for key, value in _vision_config_dict["id2label"].items() + } + + # Give a warning if the values exist in both `_vision_config_dict` and `vision_config` but being different. + for key, value in _vision_config_dict.items(): + if key in vision_config and value != vision_config[key] and key != "transformers_version": + # If specified in `vision_config_dict` + if key in vision_config_dict: + message = ( + f"`{key}` is found in both `vision_config_dict` and `vision_config` but with different " + f'values. The value `vision_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`vision_config_dict` is provided which will be used to initialize `CLIPVisionConfig`. " + f'The value `vision_config["{key}"]` will be overridden.' + ) + logger.info(message) + + # Update all values in `vision_config` with the ones in `_vision_config_dict`. + vision_config.update(_vision_config_dict) + self.vision_config = vision_config + + PreTrainedConfig.__post_init__(self, **kwargs) class AltCLIPOutput(CLIPOutput): @@ -219,7 +300,9 @@ def __init__(self, config: AltCLIPVisionConfig): class AltCLIPEncoder(CLIPEncoder): - pass + def __init__(self, config: AltCLIPConfig): + super().__init__(config) + self.layers = nn.ModuleList([AltCLIPEncoderLayer(config) for _ in range(config.num_hidden_layers)]) class AltCLIPVisionEmbeddings(CLIPVisionEmbeddings): diff --git a/src/transformers/models/chinese_clip/modular_chinese_clip.py b/src/transformers/models/chinese_clip/modular_chinese_clip.py index 567d6a1c45dd..8bbbaf962671 100644 --- a/src/transformers/models/chinese_clip/modular_chinese_clip.py +++ b/src/transformers/models/chinese_clip/modular_chinese_clip.py @@ -18,13 +18,14 @@ from torch import nn from ... import initialization as init +from ...configuration_utils import PreTrainedConfig from ...masking_utils import create_bidirectional_mask from ...modeling_outputs import ( BaseModelOutputWithPooling, ) from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack -from ...utils import TransformersKwargs, auto_docstring, can_return_tuple +from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging from ...utils.generic import merge_with_config_defaults from ...utils.output_capturing import capture_outputs from ..align.modeling_align import ( @@ -51,6 +52,9 @@ ) +logger = logging.get_logger(__name__) + + @auto_docstring(checkpoint="OFA-Sys/chinese-clip-vit-base-patch16") @strict class ChineseCLIPTextConfig(CLIPTextConfig): @@ -137,6 +141,83 @@ class ChineseCLIPConfig(CLIPConfig): ```""" initializer_range: float = 0.02 + sub_configs_defaults = { + "vision_config": ChineseCLIPVisionConfig, + "text_config": ChineseCLIPTextConfig, + } + + def __post_init__(self, **kwargs): + # For backward compatibility check keyword args + # Instead of simply assigning `[text|vision]_config_dict` to `[text|vision]_config`, we use the values in + # `[text|vision]_config_dict` to update the values in `[text|vision]_config`. The values should be same in most + # cases, but we don't want to break anything regarding `_config_dict` that existed before commit `8827e1b2`. + if (text_config_dict := kwargs.pop("text_config_dict", None)) is not None: + # This is the complete result when using `text_config_dict`. + _text_config_dict = ChineseCLIPTextConfig(**text_config_dict).to_dict() + text_config = ( + self.text_config.to_dict() if isinstance(self.text_config, PreTrainedConfig) else self.text_config + ) + text_config = text_config or {} + + # Give a warning if the values exist in both `_text_config_dict` and `text_config` but being different. + for key, value in _text_config_dict.items(): + if key in text_config and value != text_config[key] and key != "transformers_version": + # If specified in `text_config_dict` + if key in text_config_dict: + message = ( + f"`{key}` is found in both `text_config_dict` and `text_config` but with different values. " + f'The value `text_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`text_config_dict` is provided which will be used to initialize `CLIPTextConfig`. The " + f'value `text_config["{key}"]` will be overridden.' + ) + logger.info(message) + + # Update all values in `text_config` with the ones in `_text_config_dict`. + text_config.update(_text_config_dict) + self.text_config = text_config + + if (vision_config_dict := kwargs.pop("vision_config_dict", None)) is not None: + # This is the complete result when using `vision_config_dict`. + _vision_config_dict = ChineseCLIPVisionConfig(**vision_config_dict).to_dict() + vision_config = ( + self.vision_config.to_dict() + if isinstance(self.vision_config, PreTrainedConfig) + else self.vision_config + ) + vision_config = vision_config or {} + + # convert keys to string instead of integer + if "id2label" in _vision_config_dict: + _vision_config_dict["id2label"] = { + str(key): value for key, value in _vision_config_dict["id2label"].items() + } + + # Give a warning if the values exist in both `_vision_config_dict` and `vision_config` but being different. + for key, value in _vision_config_dict.items(): + if key in vision_config and value != vision_config[key] and key != "transformers_version": + # If specified in `vision_config_dict` + if key in vision_config_dict: + message = ( + f"`{key}` is found in both `vision_config_dict` and `vision_config` but with different " + f'values. The value `vision_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`vision_config_dict` is provided which will be used to initialize `CLIPVisionConfig`. " + f'The value `vision_config["{key}"]` will be overridden.' + ) + logger.info(message) + + # Update all values in `vision_config` with the ones in `_vision_config_dict`. + vision_config.update(_vision_config_dict) + self.vision_config = vision_config + + PreTrainedConfig.__post_init__(self, **kwargs) class ChineseCLIPOutput(CLIPOutput): @@ -162,7 +243,9 @@ class ChineseCLIPTextSelfOutput(BertSelfOutput): class ChineseCLIPTextAttention(AlignTextAttention): - pass + def __init__(self, config): + super().__init__(config) + self.self = ChineseCLIPTextSelfAttention(config) class ChineseCLIPVisionAttention(CLIPAttention): @@ -395,7 +478,9 @@ def forward( class ChineseCLIPModel(CLIPModel): def __init__(self, config: ChineseCLIPConfig): super().__init__(config) + vision_config = config.vision_config self.text_model = ChineseCLIPTextModel(self.config.text_config, add_pooling_layer=False) + self.vision_model = ChineseCLIPVisionModel._from_config(vision_config) def get_text_features( self, diff --git a/src/transformers/models/clipseg/modular_clipseg.py b/src/transformers/models/clipseg/modular_clipseg.py index 8057c25da9ba..6e010c97a410 100644 --- a/src/transformers/models/clipseg/modular_clipseg.py +++ b/src/transformers/models/clipseg/modular_clipseg.py @@ -23,10 +23,11 @@ from torch import nn from ... import initialization as init +from ...configuration_utils import PreTrainedConfig from ...modeling_outputs import BaseModelOutputWithPooling from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack -from ...utils import ModelOutput, TransformersKwargs, auto_docstring +from ...utils import ModelOutput, TransformersKwargs, auto_docstring, logging from ...utils.generic import can_return_tuple, merge_with_config_defaults from ...utils.output_capturing import capture_outputs from ..clip.configuration_clip import CLIPConfig, CLIPTextConfig, CLIPVisionConfig @@ -45,6 +46,9 @@ ) +logger = logging.get_logger(__name__) + + @auto_docstring(checkpoint="CIDAS/clipseg-rd64") @strict class CLIPSegTextConfig(CLIPTextConfig): @@ -135,6 +139,83 @@ class CLIPSegConfig(CLIPConfig): decoder_intermediate_size: int = 2048 conditional_layer: int = 0 use_complex_transposed_convolution: bool = False + sub_configs_defaults = { + "vision_config": CLIPSegVisionConfig, + "text_config": CLIPSegTextConfig, + } + + def __post_init__(self, **kwargs): + # For backward compatibility check keyword args + # Instead of simply assigning `[text|vision]_config_dict` to `[text|vision]_config`, we use the values in + # `[text|vision]_config_dict` to update the values in `[text|vision]_config`. The values should be same in most + # cases, but we don't want to break anything regarding `_config_dict` that existed before commit `8827e1b2`. + if (text_config_dict := kwargs.pop("text_config_dict", None)) is not None: + # This is the complete result when using `text_config_dict`. + _text_config_dict = CLIPSegTextConfig(**text_config_dict).to_dict() + text_config = ( + self.text_config.to_dict() if isinstance(self.text_config, PreTrainedConfig) else self.text_config + ) + text_config = text_config or {} + + # Give a warning if the values exist in both `_text_config_dict` and `text_config` but being different. + for key, value in _text_config_dict.items(): + if key in text_config and value != text_config[key] and key != "transformers_version": + # If specified in `text_config_dict` + if key in text_config_dict: + message = ( + f"`{key}` is found in both `text_config_dict` and `text_config` but with different values. " + f'The value `text_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`text_config_dict` is provided which will be used to initialize `CLIPTextConfig`. The " + f'value `text_config["{key}"]` will be overridden.' + ) + logger.info(message) + + # Update all values in `text_config` with the ones in `_text_config_dict`. + text_config.update(_text_config_dict) + self.text_config = text_config + + if (vision_config_dict := kwargs.pop("vision_config_dict", None)) is not None: + # This is the complete result when using `vision_config_dict`. + _vision_config_dict = CLIPSegVisionConfig(**vision_config_dict).to_dict() + vision_config = ( + self.vision_config.to_dict() + if isinstance(self.vision_config, PreTrainedConfig) + else self.vision_config + ) + vision_config = vision_config or {} + + # convert keys to string instead of integer + if "id2label" in _vision_config_dict: + _vision_config_dict["id2label"] = { + str(key): value for key, value in _vision_config_dict["id2label"].items() + } + + # Give a warning if the values exist in both `_vision_config_dict` and `vision_config` but being different. + for key, value in _vision_config_dict.items(): + if key in vision_config and value != vision_config[key] and key != "transformers_version": + # If specified in `vision_config_dict` + if key in vision_config_dict: + message = ( + f"`{key}` is found in both `vision_config_dict` and `vision_config` but with different " + f'values. The value `vision_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`vision_config_dict` is provided which will be used to initialize `CLIPVisionConfig`. " + f'The value `vision_config["{key}"]` will be overridden.' + ) + logger.info(message) + + # Update all values in `vision_config` with the ones in `_vision_config_dict`. + vision_config.update(_vision_config_dict) + self.vision_config = vision_config + + PreTrainedConfig.__post_init__(self, **kwargs) class CLIPSegOutput(CLIPOutput): @@ -401,6 +482,11 @@ def forward(self, **super_kwargs) -> tuple | BaseModelOutputWithPooling: class CLIPSegVisionModel(CLIPVisionModel): + def __init__(self, config: CLIPSegVisionConfig): + super().__init__(config) + + self.embeddings = CLIPSegVisionEmbeddings(config) + def forward( self, pixel_values: torch.FloatTensor | None, @@ -433,6 +519,15 @@ def forward( class CLIPSegModel(CLIPModel): + def __init__(self, config: CLIPSegConfig): + super().__init__(config) + + text_config = config.text_config + vision_config = config.vision_config + + self.text_model = CLIPSegTextModel._from_config(text_config) + self.vision_model = CLIPSegVisionModel._from_config(vision_config) + def get_text_features(self, **super_kwargs): r""" Examples: diff --git a/src/transformers/models/cosmos3_edge/modular_cosmos3_edge.py b/src/transformers/models/cosmos3_edge/modular_cosmos3_edge.py index 64ce27761a0e..8944cbfcf962 100644 --- a/src/transformers/models/cosmos3_edge/modular_cosmos3_edge.py +++ b/src/transformers/models/cosmos3_edge/modular_cosmos3_edge.py @@ -839,7 +839,6 @@ class Cosmos3EdgeVideoProcessor(Glm4vVideoProcessor): num_frames = None max_duration = None max_image_size = None - valid_kwargs = Cosmos3EdgeVideoProcessorInitKwargs def __init__(self, **kwargs: Unpack[Cosmos3EdgeVideoProcessorInitKwargs]): if kwargs.get("temporal_patch_size", self.temporal_patch_size) != 1: diff --git a/src/transformers/models/d_fine/modular_d_fine.py b/src/transformers/models/d_fine/modular_d_fine.py index 5912b1d110eb..4e9108803fa4 100644 --- a/src/transformers/models/d_fine/modular_d_fine.py +++ b/src/transformers/models/d_fine/modular_d_fine.py @@ -41,6 +41,7 @@ RTDetrModel, RTDetrPreTrainedModel, RTDetrRepVggBlock, + RTDetrSelfAttention, inverse_sigmoid, ) from ..rt_detr_v2.modeling_rt_detr_v2 import multi_scale_deformable_attention_v2 @@ -553,6 +554,10 @@ def forward(self, input_features: torch.Tensor) -> torch.Tensor: return input_features +class DFineSelfAttention(RTDetrSelfAttention): + pass + + class DFineEncoderLayer(RTDetrEncoderLayer): def __init__(self, config: DFineConfig): super().__init__(config) @@ -562,7 +567,9 @@ def __init__(self, config: DFineConfig): class DFineAIFILayer(RTDetrAIFILayer): - pass + def __init__(self, config: DFineConfig): + super().__init__(config) + self.layers = nn.ModuleList([DFineEncoderLayer(config) for _ in range(config.encoder_layers)]) class DFineIntegral(nn.Module): @@ -784,6 +791,12 @@ class DFineDecoder(RTDetrDecoder): to improve bounding box accuracy and robustness. """ + _can_record_outputs = { + "hidden_states": DFineDecoderLayer, + "attentions": DFineSelfAttention, + "cross_attentions": DFineMultiscaleDeformableAttention, + } + def __init__(self, config: DFineConfig): self.eval_idx = config.eval_idx if config.eval_idx >= 0 else config.decoder_layers + config.eval_idx super().__init__(config=config) diff --git a/src/transformers/models/deepseek_ocr2/modular_deepseek_ocr2.py b/src/transformers/models/deepseek_ocr2/modular_deepseek_ocr2.py index 85fbfabd56c1..8f162e5b91c6 100644 --- a/src/transformers/models/deepseek_ocr2/modular_deepseek_ocr2.py +++ b/src/transformers/models/deepseek_ocr2/modular_deepseek_ocr2.py @@ -42,14 +42,16 @@ from ...utils import TensorType, TransformersKwargs, auto_docstring, can_return_tuple, logging from ...utils.generic import merge_with_config_defaults from ...utils.import_utils import requires -from ...utils.output_capturing import capture_outputs +from ...utils.output_capturing import OutputRecorder, capture_outputs from ..deepseek_v2.configuration_deepseek_v2 import DeepseekV2Config from ..deepseek_v2.modeling_deepseek_v2 import ( DeepseekV2DecoderLayer, + DeepseekV2Experts, DeepseekV2MLP, DeepseekV2Model, DeepseekV2Moe, DeepseekV2PreTrainedModel, + DeepseekV2TopkRouter, ) from ..got_ocr2.image_processing_got_ocr2 import ( GotOcr2ImageProcessor, @@ -725,6 +727,7 @@ class DeepseekOcr2SamVisionEncoder(SamVisionEncoder, DeepseekOcr2PreTrainedModel def __init__(self, config: DeepseekOcr2SamVisionConfig): super().__init__(config) + self.patch_embed = DeepseekOcr2SamPatchEmbeddings(config) self.proj = DeepseekOcr2SamVisionProj(config) def interpolate_pos_encoding(self, height: int, width: int) -> torch.Tensor: @@ -897,6 +900,14 @@ class DeepseekOcr2TextMLP(DeepseekV2MLP): pass +class DeepseekOcr2TextExperts(DeepseekV2Experts): + pass + + +class DeepseekOcr2TextTopkRouter(DeepseekV2TopkRouter): + pass + + class DeepseekOcr2TextMoe(DeepseekV2Moe): pass @@ -914,11 +925,19 @@ def __init__(self, config, layer_idx: int): class DeepseekOcr2TextPreTrainedModel(DeepseekV2PreTrainedModel): config: DeepseekOcr2TextConfig + _can_record_outputs = { + "hidden_states": DeepseekOcr2TextDecoderLayer, + "attentions": DeepseekOcr2TextAttention, + "router_logits": OutputRecorder(DeepseekOcr2TextTopkRouter, index=0), + } class DeepseekOcr2TextModel(DeepseekV2Model): def __init__(self, config: DeepseekOcr2TextConfig): super().__init__(config) + self.layers = nn.ModuleList( + [DeepseekOcr2TextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) # Use (cos/sin) RoPE instead of complex RoPE to match LlamaAttention (MHA) self.rotary_emb = DeepseekOcr2TextRotaryEmbedding(config=config) @@ -1063,6 +1082,10 @@ class DeepseekOcr2ForConditionalGeneration(LlavaNextForConditionalGeneration): def pack_image_features(self): raise NotImplementedError("DeepseekOcr2 does not use pack_image_features") + def __init__(self, config: DeepseekOcr2Config): + super().__init__(config) + self.model = DeepseekOcr2Model(config) + @can_return_tuple @auto_docstring def get_image_features( diff --git a/src/transformers/models/deepseek_v32/modular_deepseek_v32.py b/src/transformers/models/deepseek_v32/modular_deepseek_v32.py index 0b7c2352f76d..e24295028cda 100644 --- a/src/transformers/models/deepseek_v32/modular_deepseek_v32.py +++ b/src/transformers/models/deepseek_v32/modular_deepseek_v32.py @@ -29,6 +29,7 @@ import torch.nn.functional as F from huggingface_hub.dataclasses import strict +from ... import initialization as init from ...cache_utils import Cache, DynamicCache from ...configuration_utils import PreTrainedConfig from ...masking_utils import create_causal_mask @@ -37,7 +38,8 @@ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, logging -from ..axk1.modeling_axk1 import AXK1Attention +from ...utils.output_capturing import OutputRecorder +from ..axk1.modeling_axk1 import AXK1Attention, AXK1Experts from ..deepseek_v3.modeling_deepseek_v3 import ( DeepseekV3ForCausalLM, DeepseekV3Model, @@ -49,7 +51,11 @@ eager_attention_forward, ) from ..glm4_moe_lite.configuration_glm4_moe_lite import Glm4MoeLiteConfig -from ..glm4_moe_lite.modeling_glm4_moe_lite import Glm4MoeLiteDecoderLayer +from ..glm4_moe_lite.modeling_glm4_moe_lite import ( + Glm4MoeLiteDecoderLayer, + Glm4MoeLiteMLP, + Glm4MoeLiteTopkRouter, +) logger = logging.get_logger(__name__) @@ -356,11 +362,30 @@ def forward( return attn_output, attn_weights -class DeepseekV32DecoderLayer(Glm4MoeLiteDecoderLayer): +class DeepseekV32MLP(Glm4MoeLiteMLP): + pass + + +class DeepseekV32TopkRouter(Glm4MoeLiteTopkRouter): pass +class DeepseekV32Experts(AXK1Experts): + pass + + +class DeepseekV32DecoderLayer(Glm4MoeLiteDecoderLayer): + def __init__(self, config: DeepseekV32Config, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = DeepseekV32Attention(config, layer_idx) + + class DeepseekV32PreTrainedModel(DeepseekV3PreTrainedModel): + _can_record_outputs = { + "hidden_states": DeepseekV32DecoderLayer, + "attentions": DeepseekV32Attention, + "router_logits": OutputRecorder(DeepseekV32TopkRouter, index=0), + } _keep_in_fp32_modules = ["indexer.weights_proj"] _keep_in_fp32_modules_strict = ["e_score_correction_bias"] _keys_to_ignore_on_load_unexpected = [r"model\.layers\.61.*"] @@ -368,8 +393,24 @@ class DeepseekV32PreTrainedModel(DeepseekV3PreTrainedModel): _supports_sdpa = True _supports_flex_attn = False + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + if isinstance(module, DeepseekV32TopkRouter): + init.normal_(module.weight, mean=0.0, std=self.config.initializer_range) + init.zeros_(module.e_score_correction_bias) + elif isinstance(module, DeepseekV32Experts): + init.normal_(module.gate_up_proj, mean=0.0, std=self.config.initializer_range) + init.normal_(module.down_proj, mean=0.0, std=self.config.initializer_range) + class DeepseekV32Model(DeepseekV3Model): + def __init__(self, config: DeepseekV32Config): + super().__init__(config) + self.layers = nn.ModuleList( + [DeepseekV32DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -428,7 +469,9 @@ def forward( class DeepseekV32ForCausalLM(DeepseekV3ForCausalLM): - pass + def __init__(self, config: DeepseekV32Config): + super().__init__(config) + self.model = DeepseekV32Model(config) __all__ = [ diff --git a/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py b/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py index 94dc8d860886..a24b2f823ebe 100644 --- a/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py +++ b/src/transformers/models/deepseek_vl_hybrid/modular_deepseek_vl_hybrid.py @@ -30,7 +30,6 @@ from ...image_utils import ( OPENAI_CLIP_MEAN, OPENAI_CLIP_STD, - ImageInput, PILImageResampling, SizeDict, ) @@ -423,7 +422,6 @@ class DeepseekVLHybridImageProcessorPil(DeepseekVLImageProcessorPil): high_res_size = {"height": 1024, "width": 1024} high_res_resample = PILImageResampling.BICUBIC model_input_names = ["pixel_values", "high_res_pixel_values"] - valid_kwargs = DeepseekVLHybridImageProcessorKwargs def __init__(self, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]): PilBackend.__init__(self, **kwargs) @@ -528,10 +526,6 @@ def _preprocess( tensor_type=return_tensors, ) - @auto_docstring - def preprocess(self, images: ImageInput, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]) -> BatchFeature: - return super().preprocess(images, **kwargs) - class DeepseekVLHybridImageProcessor(DeepseekVLImageProcessor): high_res_image_mean = OPENAI_CLIP_MEAN @@ -539,7 +533,6 @@ class DeepseekVLHybridImageProcessor(DeepseekVLImageProcessor): high_res_size = {"height": 1024, "width": 1024} high_res_resample = PILImageResampling.BICUBIC model_input_names = ["pixel_values", "high_res_pixel_values"] - valid_kwargs = DeepseekVLHybridImageProcessorKwargs def __init__(self, **kwargs: Unpack[DeepseekVLHybridImageProcessorKwargs]): TorchvisionBackend.__init__(self, **kwargs) diff --git a/src/transformers/models/deimv2/modular_deimv2.py b/src/transformers/models/deimv2/modular_deimv2.py index 568de14bafc4..6357c1885d8e 100644 --- a/src/transformers/models/deimv2/modular_deimv2.py +++ b/src/transformers/models/deimv2/modular_deimv2.py @@ -13,6 +13,7 @@ # limitations under the License. import copy +import math from dataclasses import dataclass import torch @@ -23,6 +24,7 @@ from ... import initialization as init from ...backbone_utils import load_backbone from ...modeling_outputs import ModelOutput +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, logging from ...utils.generic import merge_with_config_defaults @@ -47,6 +49,7 @@ DFinePreTrainedModel, DFineRepVggBlock, DFineSCDown, + DFineSelfAttention, get_contrastive_denoising_training_group, replace_batch_norm, ) @@ -315,6 +318,10 @@ class Deimv2SCDown(DFineSCDown): pass +class Deimv2SelfAttention(DFineSelfAttention): + pass + + class Deimv2EncoderLayer(DFineEncoderLayer): pass @@ -426,7 +433,65 @@ class Deimv2PreTrainedModel(DFinePreTrainedModel): @torch.no_grad() def _init_weights(self, module): - super()._init_weights(module) + """Initialize the weights""" + PreTrainedModel._init_weights(self, module) + # initialize linear layer bias value according to a given probability value. + if isinstance(module, Deimv2ForObjectDetection): + for layer in module.model.decoder.class_embed: + prior_prob = self.config.initializer_bias_prior_prob or 1 / (self.config.num_labels + 1) + bias = float(-math.log((1 - prior_prob) / prior_prob)) + init.xavier_uniform_(layer.weight) + init.constant_(layer.bias, bias) + + for layer in module.model.decoder.bbox_embed: + init.constant_(layer.layers[-1].weight, 0) + init.constant_(layer.layers[-1].bias, 0) + + if isinstance(module, Deimv2Decoder): + if hasattr(module, "reg_scale"): + init.constant_(module.reg_scale, self.config.reg_scale) + + if hasattr(module, "up"): + init.constant_(module.up, self.config.up) + + if isinstance(module, Deimv2MultiscaleDeformableAttention): + init.constant_(module.sampling_offsets.weight, 0.0) + default_dtype = torch.get_default_dtype() + thetas = torch.arange(module.n_heads, dtype=torch.int64).to(default_dtype) * ( + 2.0 * math.pi / module.n_heads + ) + grid_init = torch.stack([thetas.cos(), thetas.sin()], -1) + grid_init = grid_init / grid_init.abs().max(-1, keepdim=True).values + grid_init = grid_init.reshape(module.n_heads, 1, 2).tile([1, sum(module.num_points_list), 1]) + scaling = torch.concat([torch.arange(1, n + 1) for n in module.num_points_list]).reshape(1, -1, 1) + grid_init *= scaling + init.copy_(module.sampling_offsets.bias, grid_init.flatten()) + + init.constant_(module.attention_weights.weight, 0.0) + init.constant_(module.attention_weights.bias, 0.0) + + num_points_scale = [1 / n for n in module.num_points_list for _ in range(n)] + init.copy_(module.num_points_scale, torch.tensor(num_points_scale, dtype=torch.float32)) + + if isinstance(module, Deimv2Model): + prior_prob = self.config.initializer_bias_prior_prob or 1 / (self.config.num_labels + 1) + bias = float(-math.log((1 - prior_prob) / prior_prob)) + init.xavier_uniform_(module.enc_score_head.weight) + init.constant_(module.enc_score_head.bias, bias) + + if isinstance(module, Deimv2Gate): + bias = float(-math.log((1 - 0.5) / 0.5)) + init.constant_(module.gate.bias, bias) + init.constant_(module.gate.weight, 0) + + if isinstance(module, Deimv2LQE): + init.constant_(module.reg_conf.layers[-1].bias, 0) + init.constant_(module.reg_conf.layers[-1].weight, 0) + + if hasattr(module, "weight_embedding") and self.config.learn_initial_query: + init.xavier_uniform_(module.weight_embedding.weight) + if hasattr(module, "denoising_class_embed") and self.config.num_denoising > 0: + init.xavier_uniform_(module.denoising_class_embed.weight) if isinstance(module, Deimv2SwiGLUFFN): init.xavier_uniform_(module.gate_proj.weight) @@ -648,9 +713,19 @@ def forward( class Deimv2Decoder(DFineDecoder): + _can_record_outputs = { + "hidden_states": Deimv2DecoderLayer, + "attentions": Deimv2SelfAttention, + "cross_attentions": Deimv2MultiscaleDeformableAttention, + } + def __init__(self, config: Deimv2Config): super().__init__(config=config) self.query_pos_head = Deimv2MLP(4, config.d_model, config.d_model, 3, config.decoder_activation_function) + self.layers = nn.ModuleList( + [Deimv2DecoderLayer(config) for _ in range(config.decoder_layers)] + + [Deimv2DecoderLayer(config) for _ in range(config.decoder_layers - self.eval_idx - 1)] + ) class Deimv2Model(DFineModel): diff --git a/src/transformers/models/edgetam/modular_edgetam.py b/src/transformers/models/edgetam/modular_edgetam.py index 10ab9d5996f9..9189b98c595a 100644 --- a/src/transformers/models/edgetam/modular_edgetam.py +++ b/src/transformers/models/edgetam/modular_edgetam.py @@ -146,7 +146,15 @@ class EdgeTamConfig(Sam2Config): ``` """ - pass + model_type = "edgetam" + sub_configs_defaults = { + "vision_config": SubConfigSpec( + config_class=AutoConfig, + model_type="edgetam_vision_model", + ), + "prompt_encoder_config": EdgeTamPromptEncoderConfig, + "mask_decoder_config": EdgeTamMaskDecoderConfig, + } class EdgeTamLayerNorm(Sam2LayerNorm): diff --git a/src/transformers/models/edgetam_video/modular_edgetam_video.py b/src/transformers/models/edgetam_video/modular_edgetam_video.py index 6346ffc8cb44..2d8b5e654533 100644 --- a/src/transformers/models/edgetam_video/modular_edgetam_video.py +++ b/src/transformers/models/edgetam_video/modular_edgetam_video.py @@ -25,13 +25,13 @@ from ...activations import ACT2FN from ...configuration_utils import PreTrainedConfig, SubConfigSpec from ...modeling_flash_attention_utils import FlashAttentionKwargs -from ...modeling_utils import ALL_ATTENTION_FUNCTIONS +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import Unpack from ...pytorch_utils import compile_compatible_method_lru_cache from ...utils import auto_docstring, logging from ...utils.output_capturing import OutputRecorder from ..auto import AutoConfig -from ..sam2.modeling_sam2 import eager_attention_forward, window_partition +from ..sam2.modeling_sam2 import Sam2PositionalEmbedding, eager_attention_forward, window_partition from ..sam2_video.configuration_sam2_video import ( Sam2VideoMaskDecoderConfig, Sam2VideoPromptEncoderConfig, @@ -568,16 +568,43 @@ def build_sine_position_embedding(**super_kwargs) -> torch.Tensor: class EdgeTamVideoMemoryEncoder(Sam2VideoMemoryEncoder): - pass + def __init__(self, config: EdgeTamVideoConfig): + super().__init__(config) + output_channels = config.memory_encoder_output_channels + self.position_encoding = EdgeTamVideoPositionEmbeddingSine( + num_position_features=output_channels // 2, normalize=True + ) class EdgeTamVideoFeedForward(Sam2VideoFeedForward): pass +class EdgeTamVideoPositionalEmbedding(Sam2PositionalEmbedding): + pass + + class EdgeTamVideoPreTrainedModel(Sam2VideoPreTrainedModel): + @torch.no_grad() def _init_weights(self, module): - super()._init_weights(module) + PreTrainedModel._init_weights(self, module) + if isinstance(module, EdgeTamVideoModel): + if module.no_memory_positional_encoding is not None: + init.zeros_(module.no_memory_positional_encoding) + if module.memory_temporal_positional_encoding is not None: + init.zeros_(module.memory_temporal_positional_encoding) + if module.no_object_pointer is not None: + init.zeros_(module.no_object_pointer) + if module.occlusion_spatial_embedding_parameter is not None: + init.zeros_(module.occlusion_spatial_embedding_parameter) + if isinstance(module, EdgeTamVideoMemoryFuserCXBlock): + if module.scale is not None: + init.zeros_(module.scale) + elif isinstance(module, EdgeTamVideoPositionalEmbedding): + init.normal_(module.positional_embedding, std=module.scale) + elif isinstance(module, EdgeTamVideoMemoryAttention): + position_ids = module.precompute_positions(module.config) + init.copy_(module.position_ids, position_ids) if isinstance(module, EdgeTamVideoMemoryAttention): position_ids_k = module.precompute_positions(module.config, is_key=True) init.copy_(module.position_ids_k, position_ids_k) @@ -658,6 +685,9 @@ def __init__(self, config: EdgeTamVideoConfig): super().__init__() position_ids_k = self.precompute_positions(config, is_key=True) self.position_ids_k = nn.Buffer(position_ids_k, persistent=False) + self.layers = nn.ModuleList( + [EdgeTamVideoMemoryAttentionLayer(config) for _ in range(config.memory_attention_num_layers)] + ) @staticmethod def precompute_positions(config: EdgeTamVideoConfig, is_key: bool = False): @@ -981,6 +1011,7 @@ class EdgeTamVideoModel(Sam2VideoModel): def __init__(self, config: EdgeTamVideoConfig): super().__init__(config) + self.memory_attention = EdgeTamVideoMemoryAttention(config) self.spatial_perceiver = EdgeTamVideoPerceiverResampler(config) self.post_init() diff --git a/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py b/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py index e7650359b379..a1263e281dae 100644 --- a/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py +++ b/src/transformers/models/embedding_gemma2/modular_embedding_gemma2.py @@ -24,14 +24,13 @@ from ...activations import ACT2FN from ...audio_utils import AudioInput, is_valid_audio from ...configuration_utils import PreTrainedConfig, SubConfigSpec -from ...image_processing_utils import BatchFeature from ...image_utils import ImageInput, make_nested_list_of_images from ...integrations import use_kernelized_func from ...masking_utils import create_bidirectional_mask, create_bidirectional_sliding_window_mask from ...modeling_flash_attention_utils import FlashAttentionKwargs from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel -from ...processing_utils import MultiModalData, ProcessingKwargs, ProcessorMixin, Unpack +from ...processing_utils import ProcessingKwargs, ProcessorMixin, Unpack from ...tokenization_utils_base import PreTokenizedInput, TextInput from ...utils import ( TransformersKwargs, @@ -800,9 +799,6 @@ class EmbeddingGemma2VideoProcessor(Gemma4VideoProcessor): valid_kwargs = EmbeddingGemma2VideoProcessorKwargs - def __init__(self, **kwargs: Unpack[EmbeddingGemma2VideoProcessorKwargs]): - super().__init__(**kwargs) - def sample_frames( self, metadata: VideoMetadata, @@ -860,14 +856,6 @@ def sample_frames( return indices - @auto_docstring - def preprocess( - self, - videos: VideoInput, - **kwargs: Unpack[EmbeddingGemma2VideoProcessorKwargs], - ) -> BatchFeature: - return super().preprocess(videos, **kwargs) - class EmbeddingGemma2ProcessorKwargs(Gemma4ProcessorKwargs): _defaults = { @@ -1040,88 +1028,6 @@ def replace_video_token(self, video_inputs: dict, video_idx: int, **kwargs) -> s [f"{t} {self.boi_token}{self.video_token * num_soft_tokens}{self.eoi_token}" for t in timestamp_str] ) - def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, audio_lengths=None, **kwargs): - """ - Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. - - Args: - image_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (height, width) per each image. - video_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (num_frames, height, width) per each video. - audio_lengths (`list[int]`, *optional*): - The lengths of audio inputs in number of samples. Used to dynamically - compute per-audio token counts. - - Returns: - `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided - input modalities, along with other useful data. - """ - - images_kwargs = EmbeddingGemma2ProcessorKwargs._defaults.get("images_kwargs", {}) - images_kwargs.update(kwargs) - patch_size = images_kwargs.get("patch_size", None) or self.image_processor.patch_size - pooling_kernel_size = ( - images_kwargs.get("pooling_kernel_size", None) or self.image_processor.pooling_kernel_size - ) - max_soft_tokens = images_kwargs.get("max_soft_tokens", None) or self.image_processor.max_soft_tokens - - max_patches = max_soft_tokens * pooling_kernel_size**2 - - vision_data = {} - if image_sizes is not None: - num_image_tokens = [] - for image_size in image_sizes: - target_h, target_w = get_aspect_ratio_preserving_size( - height=image_size[0], - width=image_size[1], - patch_size=patch_size, - max_patches=max_patches, - pooling_kernel_size=pooling_kernel_size, - ) - patch_height = target_h // patch_size - patch_width = target_w // patch_size - num_image_tokens.append(patch_height * patch_width // pooling_kernel_size**2) - - num_image_patches = [1] * len(image_sizes) - vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) - - if video_sizes is not None: - videos_kwargs = EmbeddingGemma2ProcessorKwargs._defaults.get("videos_kwargs", {}) - videos_kwargs.update(kwargs) - patch_size = videos_kwargs.get("patch_size", None) or self.video_processor.patch_size - pooling_kernel_size = ( - videos_kwargs.get("pooling_kernel_size", None) or self.video_processor.pooling_kernel_size - ) - max_soft_tokens = videos_kwargs.get("max_soft_tokens", None) or self.video_processor.max_soft_tokens - - max_patches = max_soft_tokens * pooling_kernel_size**2 - - num_video_tokens = [] - for num_frames, height, width in video_sizes: - target_h, target_w = get_aspect_ratio_preserving_size( - height=height, - width=width, - patch_size=patch_size, - max_patches=max_patches, - pooling_kernel_size=pooling_kernel_size, - ) - patch_height = target_h // patch_size - patch_width = target_w // patch_size - num_video_tokens.append(num_frames * (patch_height * patch_width // pooling_kernel_size**2)) - vision_data.update({"num_video_tokens": num_video_tokens}) - - if audio_lengths is not None: - # Dynamically compute per-audio token counts from sample lengths. - # audio_lengths are in number of samples; assume default sampling rate. - sampling_rate = getattr(self.feature_extractor, "sampling_rate", 16_000) - num_audio_tokens = [ - self._compute_audio_num_tokens(np.zeros(length), sampling_rate) for length in audio_lengths - ] - vision_data.update({"num_audio_tokens": num_audio_tokens}) - - return MultiModalData(**vision_data) - __all__ = [ "EmbeddingGemma2Config", diff --git a/src/transformers/models/ernie4_5_vl_moe/modular_ernie4_5_vl_moe.py b/src/transformers/models/ernie4_5_vl_moe/modular_ernie4_5_vl_moe.py index ea483ef3516e..08ac20cfdfef 100644 --- a/src/transformers/models/ernie4_5_vl_moe/modular_ernie4_5_vl_moe.py +++ b/src/transformers/models/ernie4_5_vl_moe/modular_ernie4_5_vl_moe.py @@ -533,6 +533,9 @@ class Ernie4_5_VLMoeTextModel(Ernie4_5_MoeModel): def __init__(self, config: Ernie4_5_VLMoeTextConfig): super().__init__(config) + self.layers = nn.ModuleList( + [Ernie4_5_VLMoeDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) self.rotary_emb = Ernie4_5_VLMoeTextRotaryEmbedding(config=config) @merge_with_config_defaults @@ -650,6 +653,7 @@ class Ernie4_5_VLMoeVisionTransformerPretrainedModel(Qwen2VisionTransformerPretr def __init__(self, config: Ernie4_5_VLMoeVisionConfig) -> None: super().__init__(config) + self.blocks = nn.ModuleList([Ernie4_5_VLMoeVisionBlock(config) for _ in range(config.depth)]) del self.merger @@ -816,6 +820,7 @@ class Ernie4_5_VLMoeModel(Qwen2VLModel): def __init__(self, config: Ernie4_5_VLMoeConfig): super().__init__(config) + self.language_model = Ernie4_5_VLMoeTextModel._from_config(config.text_config) del self.visual self.vision_tower = Ernie4_5_VLMoeVisionTransformerPretrainedModel._from_config(config.vision_config) @@ -1048,6 +1053,7 @@ def forward( class Ernie4_5_VLMoeForConditionalGeneration(Glm4vForConditionalGeneration, GenerationMixin): def __init__(self, config: Ernie4_5_VLMoeConfig): super().__init__(config) + self.model = Ernie4_5_VLMoeModel(config) self.router_aux_loss_coef = config.text_config.router_aux_loss_coef self.num_experts = config.text_config.num_experts diff --git a/src/transformers/models/eurobert/modular_eurobert.py b/src/transformers/models/eurobert/modular_eurobert.py index c70b5e356e99..29433ffc9e53 100644 --- a/src/transformers/models/eurobert/modular_eurobert.py +++ b/src/transformers/models/eurobert/modular_eurobert.py @@ -25,7 +25,7 @@ from ...utils import auto_docstring from ...utils.generic import TransformersKwargs, can_return_tuple from ..llama.configuration_llama import LlamaConfig -from ..llama.modeling_llama import LlamaAttention, LlamaModel, LlamaPreTrainedModel, LlamaRMSNorm +from ..llama.modeling_llama import LlamaAttention, LlamaDecoderLayer, LlamaModel, LlamaPreTrainedModel, LlamaRMSNorm @auto_docstring(checkpoint="EuroBERT/EuroBERT-210m") @@ -92,11 +92,30 @@ def __init__(self, config: EuroBertConfig, layer_idx: int): self.is_causal = False +class EuroBertDecoderLayer(LlamaDecoderLayer): + def __init__(self, config: EuroBertConfig, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = EuroBertAttention(config=config, layer_idx=layer_idx) + self.input_layernorm = EuroBertRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = EuroBertRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + class EuroBertPreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": EuroBertDecoderLayer, + "attentions": EuroBertAttention, + } class EuroBertModel(LlamaModel): + def __init__(self, config: EuroBertConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [EuroBertDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = EuroBertRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + def forward( self, input_ids: torch.LongTensor = None, diff --git a/src/transformers/models/exaone4_5/modular_exaone4_5.py b/src/transformers/models/exaone4_5/modular_exaone4_5.py index 0061900d9bb0..c52844b5657c 100644 --- a/src/transformers/models/exaone4_5/modular_exaone4_5.py +++ b/src/transformers/models/exaone4_5/modular_exaone4_5.py @@ -24,7 +24,7 @@ from ...configuration_utils import PreTrainedConfig, SubConfigSpec from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling, CausalLMOutputWithPast from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, slice_logits_to_keep -from ...processing_utils import MultiModalData, ProcessingKwargs, Unpack +from ...processing_utils import ProcessingKwargs, Unpack from ...utils import TransformersKwargs, auto_docstring from ...utils.generic import get_max_seqlen, is_flash_attention_requested from ..auto import AutoConfig, AutoModel @@ -434,50 +434,10 @@ class Exaone4_5_ProcessorKwargs(ProcessingKwargs, total=False): class Exaone4_5_Processor(Qwen2VLProcessor): - valid_processor_kwargs = Exaone4_5_ProcessorKwargs - @property def model_input_names(self): return super().model_input_names - def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): - """ - Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. - Args: - image_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (height, width) per each image. - video_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (num_frames, height, width) per each video. - Returns: - `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided - input modalities, along with other useful data. - """ - - vision_data = {} - if image_sizes is not None: - images_kwargs = Exaone4_5_ProcessorKwargs._defaults.get("images_kwargs", {}) - images_kwargs.update(kwargs) - merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size - - num_image_patches = [ - self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) - for image_size in image_sizes - ] - num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] - vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) - - if video_sizes is not None: - videos_kwargs = Exaone4_5_ProcessorKwargs._defaults.get("videos_kwargs", {}) - videos_kwargs.update(kwargs) - merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size - num_video_patches = [ - self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes - ] - num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] - vision_data["num_video_tokens"] = num_video_tokens - - return MultiModalData(**vision_data) - __all__ = [ "Exaone4_5_Config", diff --git a/src/transformers/models/flex_olmo/modular_flex_olmo.py b/src/transformers/models/flex_olmo/modular_flex_olmo.py index 956bea08670c..fde3f7e2f591 100644 --- a/src/transformers/models/flex_olmo/modular_flex_olmo.py +++ b/src/transformers/models/flex_olmo/modular_flex_olmo.py @@ -15,7 +15,9 @@ import torch from huggingface_hub.dataclasses import strict +from torch import nn +from ... import initialization as init from ...cache_utils import Cache, DynamicCache from ...configuration_utils import PreTrainedConfig from ...masking_utils import create_causal_mask @@ -25,7 +27,7 @@ from ...utils import TransformersKwargs, auto_docstring from ...utils.generic import merge_with_config_defaults from ...utils.output_capturing import OutputRecorder, capture_outputs -from ..mixtral.modeling_mixtral import MixtralModel, MixtralPreTrainedModel +from ..mixtral.modeling_mixtral import MixtralExperts, MixtralModel, MixtralPreTrainedModel from ..olmo2.modeling_olmo2 import Olmo2Attention, Olmo2RMSNorm, Olmo2RotaryEmbedding from ..olmoe.modeling_olmoe import ( OlmoeDecoderLayer, @@ -134,6 +136,10 @@ class FlexOlmoTopKRouter(OlmoeTopKRouter): pass +class FlexOlmoExperts(MixtralExperts): + pass + + class FlexOlmoSparseMoeBlock(OlmoeSparseMoeBlock): pass @@ -188,12 +194,30 @@ class FlexOlmoPreTrainedModel(MixtralPreTrainedModel): "attentions": FlexOlmoAttention, } + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + std = self.config.initializer_range + if isinstance(module, FlexOlmoExperts): + init.normal_(module.gate_up_proj, mean=0.0, std=std) + init.normal_(module.down_proj, mean=0.0, std=std) + elif isinstance(module, FlexOlmoTopKRouter): + init.normal_(module.weight, mean=0.0, std=std) + # FlexOlmo uses Mixtral model as its base instead of OlmoE model since Mixtral is more up-to-date with the rest # of the transformers library. For example, it uses the newer mechanisms of recording submodule outputs. # FlexOlmo model is identical to Mixtral model except: # - FlexOlmo does not use sliding window attention. class FlexOlmoModel(MixtralModel): + def __init__(self, config: FlexOlmoConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [FlexOlmoDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = FlexOlmoRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = FlexOlmoRotaryEmbedding(config=config) + @merge_with_config_defaults @capture_outputs @auto_docstring diff --git a/src/transformers/models/flint/modular_flint.py b/src/transformers/models/flint/modular_flint.py index 3fcb35b60f6e..e51bd81372a1 100644 --- a/src/transformers/models/flint/modular_flint.py +++ b/src/transformers/models/flint/modular_flint.py @@ -25,12 +25,14 @@ from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring from ...utils.generic import maybe_autocast +from ...utils.output_capturing import OutputRecorder from ..gpt_oss.modeling_gpt_oss import GptOssRMSNorm from ..qwen2_moe.configuration_qwen2_moe import Qwen2MoeConfig from ..qwen2_moe.modeling_qwen2_moe import Qwen2MoeModel from ..qwen3_moe.modeling_qwen3_moe import ( Qwen3MoeAttention, Qwen3MoeDecoderLayer, + Qwen3MoeExperts, Qwen3MoeForCausalLM, Qwen3MoeMLP, Qwen3MoePreTrainedModel, @@ -130,9 +132,15 @@ def forward(self, hidden_states): return router_logits, routing_weights, selected_experts +class FlintExperts(Qwen3MoeExperts): + pass + + class FlintSparseMoeBlock(Qwen3MoeSparseMoeBlock): def __init__(self, config: FlintConfig): super().__init__(config) + self.experts = FlintExperts(config) + self.gate = FlintTopKRouter(config) self.shared_expert = FlintMLP(config, intermediate_size=config.shared_expert_intermediate_size) def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: @@ -176,6 +184,8 @@ def eager_attention_forward( class FlintAttention(Qwen3MoeAttention): def __init__(self, config: FlintConfig, layer_idx: int): super().__init__(config, layer_idx) + self.q_norm = FlintRMSNorm(self.head_dim, eps=config.rms_norm_eps) # unlike olmo, only on the head dim! + self.k_norm = FlintRMSNorm(self.head_dim, eps=config.rms_norm_eps) # thus post q_norm does not need reshape self.sliding_window = config.sliding_window if config.layer_types[layer_idx] == "sliding_attention" else None self.sinks = nn.Parameter(torch.empty(config.num_attention_heads)) @@ -224,26 +234,53 @@ def forward( class FlintDecoderLayer(Qwen3MoeDecoderLayer): - pass + def __init__(self, config: FlintConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = FlintAttention(config, layer_idx) + if (layer_idx not in config.mlp_only_layers) and ( + config.num_experts > 0 and (layer_idx + 1) % config.decoder_sparse_step == 0 + ): + self.mlp = FlintSparseMoeBlock(config) + else: + self.mlp = FlintMLP(config, intermediate_size=config.intermediate_size) + self.input_layernorm = FlintRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = FlintRMSNorm(config.hidden_size, eps=config.rms_norm_eps) class FlintPreTrainedModel(Qwen3MoePreTrainedModel): _supports_sdpa = False # SDPA cannot apply the attention sinks + _can_record_outputs = { + "router_logits": OutputRecorder(FlintTopKRouter, index=0), + "hidden_states": FlintDecoderLayer, + "attentions": FlintAttention, + } _compatible_flash_implementations = ["kernels-community/vllm-flash-attn3", "flash_attention_4"] _keep_in_fp32_modules_strict = ["gate.weight", "sinks"] @torch.no_grad() def _init_weights(self, module): super()._init_weights(module) + std = self.config.initializer_range + if isinstance(module, FlintExperts): + init.normal_(module.gate_up_proj, mean=0.0, std=std) + init.normal_(module.down_proj, mean=0.0, std=std) + elif isinstance(module, FlintTopKRouter): + init.normal_(module.weight, mean=0.0, std=std) if isinstance(module, FlintAttention): init.normal_(module.sinks, mean=0.0, std=self.config.initializer_range) class FlintModel(Qwen2MoeModel): - pass + def __init__(self, config: FlintConfig): + super().__init__(config) + self.norm = FlintRMSNorm(config.hidden_size, eps=config.rms_norm_eps) class FlintForCausalLM(Qwen3MoeForCausalLM): + def __init__(self, config: FlintConfig): + super().__init__(config) + self.model = FlintModel(config) + def forward(self, **super_kwargs): r""" Example: diff --git a/src/transformers/models/fun_asr_nano/modular_fun_asr_nano.py b/src/transformers/models/fun_asr_nano/modular_fun_asr_nano.py index 40c4ec544371..38e53072e9c6 100644 --- a/src/transformers/models/fun_asr_nano/modular_fun_asr_nano.py +++ b/src/transformers/models/fun_asr_nano/modular_fun_asr_nano.py @@ -29,7 +29,6 @@ from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import ProcessingKwargs, Unpack, prepare_keyword_inputs, prepare_prompt_input -from ...tokenization_utils_base import TextInput from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, is_torch_available, logging from ...utils.generic import merge_with_config_defaults, no_inherit_decorator from ...utils.output_capturing import capture_outputs @@ -186,38 +185,6 @@ def decode(self, *args, strip_prefix=False, **kwargs): def batch_decode(self, *args, **kwargs): raise AttributeError("Not needed") - @auto_docstring - def __call__( - self, - text: TextInput | list[TextInput], - audio: AudioInput | None = None, - output_labels: bool | None = False, - **kwargs: Unpack[FunAsrNanoProcessorKwargs], - ) -> BatchFeature: - r""" - output_labels (bool, *optional*, default=False): - Whether to return labels for training. - - Returns: - [`BatchFeature`]: A dictionary with tokenized text (`input_ids`, `attention_mask`) and - audio features (`input_features`, `input_features_mask`). - """ - # Check only if passed explicitly as another value since by default we'll use `pt` - if "return_tensors" in kwargs and kwargs["return_tensors"] != "pt": - raise ValueError(f"{self.__class__.__name__} only supports `return_tensors='pt'`.") - - if output_labels: - kwargs["return_mm_token_type_ids"] = True - model_inputs = super().__call__(audio=audio, text=text, **kwargs) - - if output_labels: - mm_token_type_ids = model_inputs.pop("mm_token_type_ids") - labels = model_inputs["input_ids"].clone() - labels[mm_token_type_ids != 0] = -100 # audio positions - labels[labels == self.tokenizer.pad_token_id] = -100 - model_inputs["labels"] = labels - return BatchFeature(data=model_inputs, tensor_type="pt") - @auto_docstring class FunAsrNanoPreTrainedModel(AudioFlamingo3PreTrainedModel): diff --git a/src/transformers/models/gemma/modular_gemma.py b/src/transformers/models/gemma/modular_gemma.py index 272d32a864f7..8cbca197664b 100644 --- a/src/transformers/models/gemma/modular_gemma.py +++ b/src/transformers/models/gemma/modular_gemma.py @@ -29,6 +29,7 @@ from ...utils import TransformersKwargs, auto_docstring, logging from ..llama.modeling_llama import ( LlamaAttention, + LlamaDecoderLayer, LlamaForCausalLM, LlamaForSequenceClassification, LlamaForTokenClassification, @@ -167,7 +168,23 @@ def __init__(self, config: GemmaConfig, layer_idx: int): self.is_causal = not getattr(config, "use_bidirectional_attention", False) +class GemmaDecoderLayer(LlamaDecoderLayer): + def __init__(self, config: GemmaConfig, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = GemmaAttention(config=config, layer_idx=layer_idx) + + self.mlp = GemmaMLP(config) + self.input_layernorm = GemmaRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = GemmaRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + + class GemmaPreTrainedModel(LlamaPreTrainedModel): + _can_record_outputs = { + "hidden_states": GemmaDecoderLayer, + "attentions": GemmaAttention, + } + @torch.no_grad() def _init_weights(self, module): PreTrainedModel._init_weights(self, module) @@ -185,6 +202,11 @@ def __init__(self, config: GemmaConfig): self.embed_tokens = GemmaTextScaledWordEmbedding( config.vocab_size, config.hidden_size, self.padding_idx, embed_scale=self.config.hidden_size**0.5 ) + self.layers = nn.ModuleList( + [GemmaDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = GemmaRMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = GemmaRotaryEmbedding(config=config) def forward( self, @@ -240,6 +262,10 @@ def forward( class GemmaForCausalLM(LlamaForCausalLM): + def __init__(self, config: GemmaConfig): + super().__init__(config) + self.model = GemmaModel(config) + def forward(**super_kwargs): r""" Example: diff --git a/src/transformers/models/gemma4_unified/modular_gemma4_unified.py b/src/transformers/models/gemma4_unified/modular_gemma4_unified.py index 372ee451fee8..1c9943661559 100644 --- a/src/transformers/models/gemma4_unified/modular_gemma4_unified.py +++ b/src/transformers/models/gemma4_unified/modular_gemma4_unified.py @@ -14,7 +14,7 @@ import math from collections import UserDict from dataclasses import dataclass -from typing import Any, Literal +from typing import Literal import torch from huggingface_hub.dataclasses import strict @@ -530,10 +530,6 @@ class Gemma4UnifiedConfig(Gemma4Config): "audio_config": SubConfigSpec(config_class=Gemma4UnifiedAudioConfig, optional=True), } - text_config: Gemma4UnifiedTextConfig | dict[str, Any] | None = None - vision_config: Gemma4UnifiedVisionConfig | dict[str, Any] | None = None - audio_config: Gemma4UnifiedAudioConfig | dict[str, Any] | None = None - @auto_docstring @dataclass diff --git a/src/transformers/models/glm4_moe/modular_glm4_moe.py b/src/transformers/models/glm4_moe/modular_glm4_moe.py index cd4e423c9ab5..67eb3d4e3c6b 100644 --- a/src/transformers/models/glm4_moe/modular_glm4_moe.py +++ b/src/transformers/models/glm4_moe/modular_glm4_moe.py @@ -17,12 +17,15 @@ from huggingface_hub.dataclasses import strict from torch import nn +from ... import initialization as init from ...configuration_utils import PreTrainedConfig from ...modeling_rope_utils import RopeParameters from ...utils import auto_docstring, logging +from ...utils.output_capturing import OutputRecorder from ..cohere.modeling_cohere import CohereAttention from ..deepseek_v3.modeling_deepseek_v3 import ( DeepseekV3DecoderLayer, + DeepseekV3Experts, DeepseekV3ForCausalLM, DeepseekV3MLP, DeepseekV3Model, @@ -191,16 +194,40 @@ class Glm4MoeRMSNorm(DeepseekV3RMSNorm): pass -class Glm4MoeDecoderLayer(DeepseekV3DecoderLayer): +class Glm4MoeExperts(DeepseekV3Experts): pass +class Glm4MoeDecoderLayer(DeepseekV3DecoderLayer): + def __init__(self, config: Glm4MoeConfig, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = Glm4MoeAttention(config=config, layer_idx=layer_idx) + + class Glm4MoePreTrainedModel(DeepseekV3PreTrainedModel): + _can_record_outputs = { + "hidden_states": Glm4MoeDecoderLayer, + "attentions": Glm4MoeAttention, + "router_logits": OutputRecorder(Glm4MoeTopkRouter, index=0), + } _keys_to_ignore_on_load_unexpected = [r"model\.layers\.92.*", r"model\.layers\.46.*"] + @torch.no_grad() + def _init_weights(self, module): + super()._init_weights(module) + if isinstance(module, Glm4MoeTopkRouter): + init.normal_(module.weight, mean=0.0, std=self.config.initializer_range) + init.zeros_(module.e_score_correction_bias) + elif isinstance(module, Glm4MoeExperts): + init.normal_(module.gate_up_proj, mean=0.0, std=self.config.initializer_range) + init.normal_(module.down_proj, mean=0.0, std=self.config.initializer_range) + class Glm4MoeModel(DeepseekV3Model): - pass + def __init__(self, config: Glm4MoeConfig): + super().__init__(config) + self.rotary_emb = Glm4MoeRotaryEmbedding(config=config) class Glm4MoeForCausalLM(DeepseekV3ForCausalLM): diff --git a/src/transformers/models/glm4_moe_lite/modular_glm4_moe_lite.py b/src/transformers/models/glm4_moe_lite/modular_glm4_moe_lite.py index db05ee5e7b6f..2a70332c24cc 100644 --- a/src/transformers/models/glm4_moe_lite/modular_glm4_moe_lite.py +++ b/src/transformers/models/glm4_moe_lite/modular_glm4_moe_lite.py @@ -19,6 +19,7 @@ from ...configuration_utils import PreTrainedConfig from ...modeling_rope_utils import RopeParameters from ...utils import auto_docstring +from ...utils.output_capturing import OutputRecorder from ..deepseek_v3.modeling_deepseek_v3 import DeepseekV3Attention from ..glm4_moe.modeling_glm4_moe import ( Glm4MoeDecoderLayer, @@ -172,11 +173,20 @@ def __init__(self, config: Glm4MoeLiteConfig, layer_idx: int): class Glm4MoeLitePreTrainedModel(Glm4MoePreTrainedModel): + _can_record_outputs = { + "hidden_states": Glm4MoeLiteDecoderLayer, + "attentions": Glm4MoeLiteAttention, + "router_logits": OutputRecorder(Glm4MoeLiteTopkRouter, index=0), + } _keys_to_ignore_on_load_unexpected = [r"model\.layers\.47.*"] class Glm4MoeLiteModel(Glm4MoeModel): - pass + def __init__(self, config: Glm4MoeLiteConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [Glm4MoeLiteDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) class Glm4MoeLiteForCausalLM(Glm4MoeForCausalLM): diff --git a/src/transformers/models/glm4v/modular_glm4v.py b/src/transformers/models/glm4v/modular_glm4v.py index a4ec5207a6b4..8991a06e0ef0 100644 --- a/src/transformers/models/glm4v/modular_glm4v.py +++ b/src/transformers/models/glm4v/modular_glm4v.py @@ -30,7 +30,7 @@ from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling from ...modeling_rope_utils import RopeParameters from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, slice_logits_to_keep -from ...processing_utils import MultiModalData, Unpack +from ...processing_utils import Unpack from ...utils import ( TransformersKwargs, auto_docstring, @@ -1095,8 +1095,6 @@ class Glm4vProcessorKwargs(Qwen2VLProcessorKwargs): class Glm4vProcessor(Qwen2VLProcessor): - valid_processor_kwargs = Glm4vProcessorKwargs - def __init__(self, image_processor=None, tokenizer=None, video_processor=None, chat_template=None, **kwargs): super().__init__(image_processor, tokenizer, video_processor, chat_template=chat_template) self.image_token = "<|image|>" if not hasattr(tokenizer, "image_token") else tokenizer.image_token @@ -1159,44 +1157,6 @@ def create_mm_token_type_ids(self, input_ids: list) -> list[list[int]]: def replace_frame_token_id(self, timestamp_sec, num_image_tokens: int = 1): return f"<|begin_of_image|>{self.image_token * num_image_tokens}<|end_of_image|>{int(timestamp_sec)}" - def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): - """ - Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. - Args: - image_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (height, width) per each image. - video_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (num_frames, height, width) per each video. - Returns: - `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided - input modalities, along with other useful data. - """ - - vision_data = {} - if image_sizes is not None: - images_kwargs = Glm4vProcessorKwargs._defaults.get("images_kwargs", {}) - images_kwargs.update(kwargs) - merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size - - num_image_patches = [ - self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) - for image_size in image_sizes - ] - num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] - vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) - - if video_sizes is not None: - videos_kwargs = Glm4vProcessorKwargs._defaults.get("videos_kwargs", {}) - videos_kwargs.update(kwargs) - merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size - num_video_patches = [ - self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes - ] - num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] - vision_data["num_video_tokens"] = num_video_tokens - - return MultiModalData(**vision_data) - __all__ = [ "Glm4vConfig", diff --git a/src/transformers/models/glm4v_moe/modular_glm4v_moe.py b/src/transformers/models/glm4v_moe/modular_glm4v_moe.py index 837f750b5476..8e10dc3b4aba 100644 --- a/src/transformers/models/glm4v_moe/modular_glm4v_moe.py +++ b/src/transformers/models/glm4v_moe/modular_glm4v_moe.py @@ -37,7 +37,7 @@ Glm4MoeTopkRouter, eager_attention_forward, ) -from ..glm4v.configuration_glm4v import Glm4vConfig +from ..glm4v.configuration_glm4v import Glm4vConfig, Glm4vVisionConfig from ..glm4v.modeling_glm4v import ( Glm4vForConditionalGeneration, Glm4vTextModel, @@ -103,6 +103,10 @@ class Glm4vMoeTextConfig(Glm4MoeConfig): num_mtp_layers = AttributeError() +class Glm4vMoeVisionConfig(Glm4vVisionConfig): + pass + + @auto_docstring(checkpoint="zai-org/GLM-4.5V") @strict class Glm4vMoeConfig(Glm4vConfig): @@ -131,6 +135,10 @@ class Glm4vMoeConfig(Glm4vConfig): image_token_id: int = 151363 video_token_id: int = 151364 + sub_configs_defaults = { + "vision_config": Glm4vMoeVisionConfig, + "text_config": Glm4vMoeTextConfig, + } class Glm4vMoeTextRotaryEmbedding(Glm4vTextRotaryEmbedding): @@ -220,6 +228,8 @@ class Glm4vMoeTextDecoderLayer(Glm4MoeDecoderLayer): def __init__(self, config: Glm4vMoeTextConfig, layer_idx: int): super().__init__(config, layer_idx) + self.self_attn = Glm4vMoeTextAttention(config=config, layer_idx=layer_idx) + class Glm4vMoePreTrainedModel(Glm4MoePreTrainedModel): config: Glm4vMoeConfig @@ -251,6 +261,13 @@ class Glm4vMoeTextModel(Glm4vTextModel): "router_logits": OutputRecorder(Glm4vMoeTextTopkRouter, index=0), } + def __init__(self, config: Glm4vMoeTextConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [Glm4vMoeTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = Glm4vMoeTextRotaryEmbedding(config=config) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/glm5_next/modular_glm5_next.py b/src/transformers/models/glm5_next/modular_glm5_next.py index 07efde79cabf..637c914688b9 100644 --- a/src/transformers/models/glm5_next/modular_glm5_next.py +++ b/src/transformers/models/glm5_next/modular_glm5_next.py @@ -72,6 +72,7 @@ from ..glm_moe_dsa.modeling_glm_moe_dsa import GlmMoeDsaAttention, GlmMoeDsaDecoderLayer, GlmMoeDsaIndexer from ..glm_ocr.configuration_glm_ocr import GlmOcrVisionConfig from ..glm_ocr.modeling_glm_ocr import ( + GlmOcrVisionAttention, GlmOcrVisionBlock, GlmOcrVisionMlp, GlmOcrVisionModel, @@ -1149,6 +1150,10 @@ def __init__(self, config: Glm5NextTextConfig, layer_idx: int): else Glm5NextTextAttention(config, layer_idx) ) + self.mlp = ( + Glm5NextTextMoE(config) if config.mlp_layer_types[layer_idx] == "sparse" else Glm5NextTextMLP(config) + ) + self.attn_hc = Glm5NextTextHyperConnection(config) self.ffn_hc = Glm5NextTextHyperConnection(config) @@ -1396,6 +1401,10 @@ def forward(self, hidden_state: torch.Tensor) -> torch.Tensor: return self.down_proj(self.act_fn(gate) * up) +class Glm5NextVisionAttention(GlmOcrVisionAttention): + pass + + class Glm5NextVisionBlock(GlmOcrVisionBlock): def __init__(self, config) -> None: super().__init__(config) @@ -1404,6 +1413,11 @@ def __init__(self, config) -> None: @auto_docstring class Glm5NextVisionModel(GlmOcrVisionModel): + _can_record_outputs = { + "hidden_states": Glm5NextVisionBlock, + "attentions": Glm5NextVisionAttention, + } + def __init__(self, config: Glm5NextVisionConfig) -> None: super().__init__(config) self.blocks = nn.ModuleList([Glm5NextVisionBlock(config) for _ in range(config.depth)]) @@ -1584,6 +1598,7 @@ class Glm5NextForConditionalGeneration(Glm46VForConditionalGeneration, Glm5NextP def __init__(self, config: Glm5NextConfig): super().__init__(config) + self.model = Glm5NextModel(config) self.router_aux_loss_coef = config.text_config.router_aux_loss_coef self.num_experts = config.text_config.num_local_experts self.num_experts_per_tok = config.text_config.num_experts_per_tok diff --git a/src/transformers/models/glm_image/modular_glm_image.py b/src/transformers/models/glm_image/modular_glm_image.py index 991d5fa37141..ceb1ed9cd296 100644 --- a/src/transformers/models/glm_image/modular_glm_image.py +++ b/src/transformers/models/glm_image/modular_glm_image.py @@ -45,6 +45,7 @@ Glm4vModel, Glm4vModelOutputWithPast, Glm4vPreTrainedModel, + Glm4vTextDecoderLayer, Glm4vTextModel, Glm4vVisionAttention, Glm4vVisionBlock, @@ -386,6 +387,7 @@ class GlmImageVQVAE(ChameleonVQVAE): def __init__(self, config: GlmImageVQVAEConfig): super().__init__(config) + self.quantize = GlmImageVQVAEVectorQuantizer(config) del self.encoder def encode(self, hidden_states): @@ -403,10 +405,19 @@ class GlmImageVisionModel(Glm4vVisionModel): config: GlmImageVisionConfig main_input_name = "pixel_values" input_modalities = ("image",) + _can_record_outputs = { + "hidden_states": GlmImageVisionBlock, + "attentions": GlmImageVisionAttention, + } def __init__(self, config: GlmImageVisionConfig): super().__init__(config) + self.embeddings = GlmImageVisionEmbeddings(config) + self.patch_embed = GlmImageVisionPatchEmbed(config) + + self.blocks = nn.ModuleList([GlmImageVisionBlock(config) for _ in range(config.depth)]) + head_dim = config.hidden_size // config.num_heads self.head_dim = head_dim @@ -455,8 +466,24 @@ def forward( return BaseModelOutputWithPooling(last_hidden_state=hidden_states, pooler_output=hidden_states) +class GlmImageTextDecoderLayer(Glm4vTextDecoderLayer): + def __init__(self, config: GlmImageTextConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = GlmImageTextAttention(config, layer_idx) + + class GlmImageTextModel(Glm4vTextModel): - pass + _can_record_outputs = { + "hidden_states": GlmImageTextDecoderLayer, + "attentions": GlmImageTextAttention, + } + + def __init__(self, config: GlmImageTextConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [GlmImageTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = GlmImageTextRotaryEmbedding(config=config) class GlmImageModel(Glm4vModel): diff --git a/src/transformers/models/glm_moe_dsa/modular_glm_moe_dsa.py b/src/transformers/models/glm_moe_dsa/modular_glm_moe_dsa.py index 45f3710c0496..c27ff1907b94 100644 --- a/src/transformers/models/glm_moe_dsa/modular_glm_moe_dsa.py +++ b/src/transformers/models/glm_moe_dsa/modular_glm_moe_dsa.py @@ -17,6 +17,7 @@ import torch import torch.nn.functional as F from huggingface_hub.dataclasses import strict +from torch import nn from ...cache_utils import Cache, DynamicCache from ...masking_utils import create_causal_mask @@ -25,6 +26,7 @@ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, logging +from ...utils.output_capturing import OutputRecorder from ..axk1.modeling_axk1 import AXK1Attention from ..deepseek_v3.modeling_deepseek_v3 import ( DeepseekV3RMSNorm, @@ -36,9 +38,11 @@ DeepseekV32DecoderLayer, DeepseekV32ForCausalLM, DeepseekV32Indexer, + DeepseekV32MLP, DeepseekV32Model, DeepseekV32PreTrainedModel, DeepseekV32RotaryEmbedding, + DeepseekV32TopkRouter, ) @@ -291,7 +295,19 @@ def forward( return attn_output, attn_weights, topk_indices +class GlmMoeDsaMLP(DeepseekV32MLP): + pass + + +class GlmMoeDsaTopkRouter(DeepseekV32TopkRouter): + pass + + class GlmMoeDsaDecoderLayer(DeepseekV32DecoderLayer): + def __init__(self, config: GlmMoeDsaConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = GlmMoeDsaAttention(config, layer_idx) + def forward( self, hidden_states: torch.Tensor, @@ -326,10 +342,21 @@ def forward( class GlmMoeDsaPreTrainedModel(DeepseekV32PreTrainedModel): + _can_record_outputs = { + "hidden_states": GlmMoeDsaDecoderLayer, + "attentions": GlmMoeDsaAttention, + "router_logits": OutputRecorder(GlmMoeDsaTopkRouter, index=0), + } _keys_to_ignore_on_load_unexpected = [r"model\.layers\.78.*"] class GlmMoeDsaModel(DeepseekV32Model): + def __init__(self, config: GlmMoeDsaConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [GlmMoeDsaDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + def forward( self, input_ids: torch.LongTensor | None = None, @@ -392,6 +419,10 @@ def forward( class GlmMoeDsaForCausalLM(DeepseekV32ForCausalLM): _fsdp_plan = {"lm_head": "keep_full_weight"} + def __init__(self, config: GlmMoeDsaConfig): + super().__init__(config) + self.model = GlmMoeDsaModel(config) + __all__ = [ "GlmMoeDsaConfig", diff --git a/src/transformers/models/gradium_phonon_tts/modular_gradium_phonon_tts.py b/src/transformers/models/gradium_phonon_tts/modular_gradium_phonon_tts.py index 44c3103c3eef..34b6055083af 100644 --- a/src/transformers/models/gradium_phonon_tts/modular_gradium_phonon_tts.py +++ b/src/transformers/models/gradium_phonon_tts/modular_gradium_phonon_tts.py @@ -16,13 +16,19 @@ from huggingface_hub.dataclasses import strict from torch import nn +from ... import initialization as init +from ...configuration_utils import SubConfigSpec +from ...modeling_utils import PreTrainedModel from ...utils import auto_docstring from ...utils.type_validators import activation_fn_key, positive_int_field from ..pocket_tts.configuration_pocket_tts import PocketTTSConfig, PocketTTSFlowHeadConfig from ..pocket_tts.modeling_pocket_tts import ( + PocketTTSDecoderLayer, + PocketTTSFlowLossWeighting, PocketTTSForConditionalGeneration, PocketTTSModel, PocketTTSPreTrainedModel, + PocketTTSTimestepEmbedding, PocketTTSTimestepNorm, ) from .generation_gradium_phonon_tts import GradiumPhononTTSGenerationMixin @@ -131,6 +137,7 @@ class GradiumPhononTTSConfig(PocketTTSConfig): duration_delta_embedding_dim: int = positive_int_field(default=128) duration_delta_scale: float = 1000.0 duration_delta_max_period: float = 10000.0 + sub_configs_defaults = {"flow_head_config": SubConfigSpec(config_class=GradiumPhononTTSFlowHeadConfig)} # Difference to Pocket TTS: no learnt vector before the voice prompt audio_prompt_bos_token_id = AttributeError() @@ -142,7 +149,37 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return self.weight * hidden_states * torch.rsqrt(mean_square + self.variance_epsilon) -class GradiumPhononTTSPreTrainedModel(PocketTTSPreTrainedModel): ... +class GradiumPhononTTSDecoderLayer(PocketTTSDecoderLayer): + pass + + +class GradiumPhononTTSTimestepEmbedding(PocketTTSTimestepEmbedding): + def __init__(self, config: GradiumPhononTTSFlowHeadConfig): + super().__init__(config) + self.norm = GradiumPhononTTSTimestepNorm(config.hidden_size, eps=config.rms_norm_eps) + + +class GradiumPhononTTSFlowLossWeighting(PocketTTSFlowLossWeighting): + pass + + +class GradiumPhononTTSPreTrainedModel(PocketTTSPreTrainedModel): + @torch.no_grad() + def _init_weights(self, module): + PreTrainedModel._init_weights(self, module) + if isinstance(module, GradiumPhononTTSTimestepNorm): + init.ones_(module.weight) + elif isinstance(module, GradiumPhononTTSTimestepEmbedding): + init.copy_(module.freqs, module.compute_default_freqs(self.config.flow_head_config)) + elif isinstance(module, GradiumPhononTTSModel): + init.zeros_(module.bos_latent) + elif isinstance(module, GradiumPhononTTSFlowLossWeighting): + for parameter in module.parameters(): + init.zeros_(parameter) + elif isinstance(module, GradiumPhononTTSForConditionalGeneration): + init.zeros_(module.latent_mean) + init.ones_(module.latent_std) + init.zeros_(module.latent_stats_num_updates) @auto_docstring( @@ -192,6 +229,10 @@ class GradiumPhononTTSForConditionalGeneration(PocketTTSForConditionalGeneration # Gradium's runtime checkpoint also holds the codec (the processor's audio tokenizer) and training-only tensors _keys_to_ignore_on_load_unexpected = [r"^mimi\.", r"^flow_lm\.flow\.w_s_t\.", r"\.learnt_padding$"] + def __init__(self, config: GradiumPhononTTSConfig): + super().__init__(config) + self.model = GradiumPhononTTSModel(config) + __all__ = [ "GradiumPhononTTSConfig", diff --git a/src/transformers/models/granite_speech_plus/modular_granite_speech_plus.py b/src/transformers/models/granite_speech_plus/modular_granite_speech_plus.py index ab047830e39d..b84cc4916bdb 100644 --- a/src/transformers/models/granite_speech_plus/modular_granite_speech_plus.py +++ b/src/transformers/models/granite_speech_plus/modular_granite_speech_plus.py @@ -18,15 +18,19 @@ from huggingface_hub.dataclasses import strict from torch import nn -from ...configuration_utils import PreTrainedConfig +from ... import initialization as init +from ...configuration_utils import PreTrainedConfig, SubConfigSpec from ...modeling_outputs import BaseModelOutputWithPooling +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring from ...utils.generic import merge_with_config_defaults from ...utils.output_capturing import capture_outputs +from ..auto import AutoConfig from ..granite_speech.configuration_granite_speech import GraniteSpeechConfig, GraniteSpeechEncoderConfig from ..granite_speech.modeling_granite_speech import ( GraniteSpeechCTCEncoder, + GraniteSpeechEncoderProjector, GraniteSpeechForConditionalGeneration, GraniteSpeechModel, GraniteSpeechPreTrainedModel, @@ -102,6 +106,14 @@ class GraniteSpeechPlusConfig(GraniteSpeechConfig): >>> configuration = model.config ```""" + model_type = "granite_speech_plus" + attribute_map = {"audio_token_id": "audio_token_index"} + sub_configs_defaults = { + "text_config": SubConfigSpec(config_class=AutoConfig, model_type="granite"), + "encoder_config": GraniteSpeechPlusEncoderConfig, + "projector_config": SubConfigSpec(config_class=AutoConfig, model_type="blip_2_qformer"), + } + def __post_init__(self, **kwargs): PreTrainedConfig.__post_init__(**kwargs) @@ -121,10 +133,29 @@ def __post_init__(self, **kwargs): ) -class GraniteSpeechPlusPreTrainedModel(GraniteSpeechPreTrainedModel): ... +class GraniteSpeechPlusEncoderProjector(GraniteSpeechEncoderProjector): + pass + + +class GraniteSpeechPlusPreTrainedModel(GraniteSpeechPreTrainedModel): + @torch.no_grad() + def _init_weights(self, module: nn.Module): + """Initialize the weights.""" + PreTrainedModel._init_weights(self, module) + if isinstance(module, GraniteSpeechPlusEncoderProjector): + init.normal_(module.query) + elif isinstance(module, GraniteSpeechPlusCTCEncoder): + context_size = module.config.context_size + seq = torch.arange(context_size) + relpos_dist = seq.view(-1, 1) - seq.view(1, -1) + attention_dists = torch.clamp(relpos_dist, -context_size, context_size) + module.config.max_pos_emb + init.copy_(module.attention_dists, attention_dists) -class GraniteSpeechPlusModel(GraniteSpeechModel): ... +class GraniteSpeechPlusModel(GraniteSpeechModel): + def __init__(self, config: GraniteSpeechPlusConfig): + super().__init__(config) + self.encoder = GraniteSpeechPlusCTCEncoder(config.encoder_config) class GraniteSpeechPlusCTCEncoder(GraniteSpeechCTCEncoder): diff --git a/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py b/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py index f1ad8ae3b950..d59ba76df44e 100644 --- a/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py +++ b/src/transformers/models/granitemoehybrid/modular_granitemoehybrid.py @@ -25,7 +25,7 @@ from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, logging from ...utils.generic import merge_with_config_defaults -from ...utils.output_capturing import capture_outputs +from ...utils.output_capturing import OutputRecorder, capture_outputs from ..bamba.modeling_bamba import BambaMixer, BambaRMSNormGated from ..gemma2.modeling_gemma2 import Gemma2RotaryEmbedding from ..granitemoeshared.modeling_granitemoeshared import ( @@ -37,6 +37,7 @@ GraniteMoeSharedModel, GraniteMoeSharedMoE, GraniteMoeSharedPreTrainedModel, + GraniteMoeSharedTopKRouter, apply_rotary_pos_emb, eager_attention_forward, ) @@ -110,6 +111,10 @@ class GraniteMoeHybridRotaryEmbedding(Gemma2RotaryEmbedding): pass +class GraniteMoeHybridTopKRouter(GraniteMoeSharedTopKRouter): + pass + + class GraniteMoeHybridMoE(GraniteMoeSharedMoE): pass @@ -181,6 +186,11 @@ def forward( class GraniteMoeHybridPreTrainedModel(GraniteMoeSharedPreTrainedModel): config: GraniteMoeHybridConfig _no_split_modules = ["GraniteMoeHybridDecoderLayer"] + _can_record_outputs = { + "router_logits": OutputRecorder(GraniteMoeHybridTopKRouter, index=0), + "hidden_states": GraniteMoeHybridDecoderLayer, + "attentions": GraniteMoeHybridAttention, + } _is_stateful = True @torch.no_grad() diff --git a/src/transformers/models/granitemoeshared/modular_granitemoeshared.py b/src/transformers/models/granitemoeshared/modular_granitemoeshared.py index e51cd7712b9b..5a9545248ed1 100644 --- a/src/transformers/models/granitemoeshared/modular_granitemoeshared.py +++ b/src/transformers/models/granitemoeshared/modular_granitemoeshared.py @@ -21,11 +21,17 @@ from ...cache_utils import Cache from ...processing_utils import Unpack from ...utils import logging +from ...utils.output_capturing import OutputRecorder from ..granitemoe.modeling_granitemoe import ( + GraniteMoeAttention, GraniteMoeDecoderLayer, + GraniteMoeExperts, GraniteMoeForCausalLM, GraniteMoeModel, + GraniteMoeMoE, GraniteMoePreTrainedModel, + GraniteMoeRMSNorm, + GraniteMoeTopKRouter, ) from .configuration_granitemoeshared import GraniteMoeSharedConfig @@ -83,6 +89,26 @@ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: return hidden_states +class GraniteMoeSharedRMSNorm(GraniteMoeRMSNorm): + pass + + +class GraniteMoeSharedTopKRouter(GraniteMoeTopKRouter): + pass + + +class GraniteMoeSharedExperts(GraniteMoeExperts): + pass + + +class GraniteMoeSharedMoE(GraniteMoeMoE): + pass + + +class GraniteMoeSharedAttention(GraniteMoeAttention): + pass + + class GraniteMoeSharedDecoderLayer(GraniteMoeDecoderLayer): def __init__(self, config: GraniteMoeSharedConfig, layer_idx: int): super().__init__(config, layer_idx) @@ -131,6 +157,11 @@ def forward( class GraniteMoeSharedPreTrainedModel(GraniteMoePreTrainedModel): config: GraniteMoeSharedConfig _no_split_modules = ["GraniteMoeSharedDecoderLayer"] + _can_record_outputs = { + "router_logits": OutputRecorder(GraniteMoeSharedTopKRouter, index=0), + "hidden_states": GraniteMoeSharedDecoderLayer, + "attentions": GraniteMoeSharedAttention, + } class GraniteMoeSharedModel(GraniteMoeModel): diff --git a/src/transformers/models/higgs_audio_v2/modular_higgs_audio_v2.py b/src/transformers/models/higgs_audio_v2/modular_higgs_audio_v2.py index 18bfea514cf7..190edc594450 100644 --- a/src/transformers/models/higgs_audio_v2/modular_higgs_audio_v2.py +++ b/src/transformers/models/higgs_audio_v2/modular_higgs_audio_v2.py @@ -32,7 +32,14 @@ from ...utils.output_capturing import capture_outputs from ..csm.modeling_csm import CsmBackboneModelEmbeddings from ..llama.configuration_llama import LlamaConfig -from ..llama.modeling_llama import LlamaDecoderLayer, LlamaMLP, LlamaModel, LlamaPreTrainedModel, LlamaRMSNorm +from ..llama.modeling_llama import ( + LlamaAttention, + LlamaDecoderLayer, + LlamaMLP, + LlamaModel, + LlamaPreTrainedModel, + LlamaRMSNorm, +) from .generation_higgs_audio_v2 import HiggsAudioV2GenerationMixin @@ -106,6 +113,10 @@ class HiggsAudioV2RMSNorm(LlamaRMSNorm): pass +class HiggsAudioV2Attention(LlamaAttention): + pass + + class HiggsAudioV2DecoderLayer(LlamaDecoderLayer): def __init__(self, config: HiggsAudioV2Config, layer_idx: int): super().__init__(config, layer_idx) @@ -177,6 +188,11 @@ def forward(self, input_ids): class HiggsAudioV2PreTrainedModel(LlamaPreTrainedModel, PreTrainedModel): + _can_record_outputs = { + "hidden_states": HiggsAudioV2DecoderLayer, + "attentions": HiggsAudioV2Attention, + } + @torch.no_grad() def _init_weights(self, module): PreTrainedModel._init_weights(module) @@ -190,6 +206,9 @@ def _init_weights(self, module): class HiggsAudioV2Model(LlamaModel): def __init__(self, config: HiggsAudioV2Config): super().__init__(config) + self.layers = nn.ModuleList( + [HiggsAudioV2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) self.embed_audio_tokens = HiggsAudioV2Embeddings(config) def get_placeholder_mask( diff --git a/src/transformers/models/instructblipvideo/modular_instructblipvideo.py b/src/transformers/models/instructblipvideo/modular_instructblipvideo.py index 93a73ea655dd..5560c02538ac 100644 --- a/src/transformers/models/instructblipvideo/modular_instructblipvideo.py +++ b/src/transformers/models/instructblipvideo/modular_instructblipvideo.py @@ -32,9 +32,14 @@ TransformersKwargs, ) +from ... import initialization as init +from ...configuration_utils import SubConfigSpec from ...modeling_outputs import BaseModelOutputWithPooling +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import auto_docstring, can_return_tuple +from ..auto import AutoConfig +from ..instructblip.modeling_instructblip import InstructBlipQFormerEmbeddings, InstructBlipVisionEmbeddings @auto_docstring(checkpoint="Salesforce/instructblip-flan-t5-xl") @@ -123,11 +128,37 @@ class InstructBlipVideoConfig(InstructBlipConfig): attribute_map = {"video_token_id": "video_token_index"} video_token_index: int | None = None image_token_index = AttributeError() + sub_configs_defaults = { + "text_config": SubConfigSpec(config_class=AutoConfig, model_type="opt"), + "vision_config": InstructBlipVideoVisionConfig, + "qformer_config": InstructBlipVideoQFormerConfig, + } + + +class InstructBlipVideoVisionEmbeddings(InstructBlipVisionEmbeddings): + pass + + +class InstructBlipVideoQFormerEmbeddings(InstructBlipQFormerEmbeddings): + pass class InstructBlipVideoPreTrainedModel(InstructBlipPreTrainedModel): input_modalities = ("video", "text") + @torch.no_grad() + def _init_weights(self, module): + """Initialize the weights""" + PreTrainedModel._init_weights(self, module) + factor = self.config.initializer_range + if isinstance(module, InstructBlipVideoVisionEmbeddings): + init.trunc_normal_(module.position_embedding, mean=0.0, std=factor) + init.trunc_normal_(module.class_embedding, mean=0.0, std=factor) + elif isinstance(module, (InstructBlipVideoForConditionalGeneration, InstructBlipVideoModel)): + init.zeros_(module.query_tokens) + elif isinstance(module, InstructBlipVideoQFormerEmbeddings): + init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1))) + class InstructBlipVideoVisionModel(InstructBlipVisionModel): input_modalities = "video" @@ -142,6 +173,11 @@ class InstructBlipVideoForConditionalGenerationModelOutput(InstructBlipForCondit class InstructBlipVideoModel(InstructBlipModel): + def __init__(self, config: InstructBlipVideoConfig): + super().__init__(config) + + self.vision_model = InstructBlipVideoVisionModel(config.vision_config) + @can_return_tuple @auto_docstring def forward( @@ -239,6 +275,11 @@ def forward( class InstructBlipVideoForConditionalGeneration(InstructBlipForConditionalGeneration): + def __init__(self, config: InstructBlipVideoConfig): + super().__init__(config) + + self.vision_model = InstructBlipVideoVisionModel._from_config(config.vision_config) + @can_return_tuple @auto_docstring def get_video_features( diff --git a/src/transformers/models/jais2/modular_jais2.py b/src/transformers/models/jais2/modular_jais2.py index 3fbdf2c8cd46..65a0aa6a7125 100644 --- a/src/transformers/models/jais2/modular_jais2.py +++ b/src/transformers/models/jais2/modular_jais2.py @@ -19,6 +19,7 @@ from ...utils import auto_docstring, can_return_tuple from ..llama.configuration_llama import LlamaConfig from ..llama.modeling_llama import ( + LlamaAttention, LlamaDecoderLayer, LlamaForCausalLM, LlamaModel, @@ -58,24 +59,42 @@ class Jais2MLP(NemotronMLP): pass +class Jais2Attention(LlamaAttention): + pass + + class Jais2DecoderLayer(LlamaDecoderLayer): def __init__(self, config: Jais2Config, layer_idx: int): super().__init__(config, layer_idx) + + self.self_attn = Jais2Attention(config=config, layer_idx=layer_idx) + + self.mlp = Jais2MLP(config) self.input_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.post_attention_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) class Jais2PreTrainedModel(LlamaPreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": Jais2DecoderLayer, + "attentions": Jais2Attention, + } class Jais2Model(LlamaModel): def __init__(self, config: Jais2Config): super().__init__(config) + self.layers = nn.ModuleList( + [Jais2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) self.norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) class Jais2ForCausalLM(LlamaForCausalLM): + def __init__(self, config: Jais2Config): + super().__init__(config) + self.model = Jais2Model(config) + @can_return_tuple @auto_docstring def forward(self, **super_kwargs): diff --git a/src/transformers/models/kimi_k25/modular_kimi_k25.py b/src/transformers/models/kimi_k25/modular_kimi_k25.py index e991df9f5dde..bc5344b63911 100644 --- a/src/transformers/models/kimi_k25/modular_kimi_k25.py +++ b/src/transformers/models/kimi_k25/modular_kimi_k25.py @@ -732,8 +732,6 @@ class Kimi_K25ProcessorKwargs(ProcessingKwargs, total=False): @auto_docstring class Kimi_K25Processor(Qwen2VLProcessor): - valid_processor_kwargs = Kimi_K25ProcessorKwargs - def __init__( self, image_processor=None, diff --git a/src/transformers/models/mellum/modular_mellum.py b/src/transformers/models/mellum/modular_mellum.py index db3b29fa7554..9c6e30a4f63f 100644 --- a/src/transformers/models/mellum/modular_mellum.py +++ b/src/transformers/models/mellum/modular_mellum.py @@ -14,6 +14,7 @@ import torch from huggingface_hub.dataclasses import strict +from torch import nn from ... import initialization as init from ...configuration_utils import PreTrainedConfig @@ -22,13 +23,21 @@ RopeParameters, ) from ...utils import auto_docstring, logging -from ..laguna.modeling_laguna import LagunaDecoderLayer, LagunaModel, LagunaRotaryEmbedding +from ...utils.output_capturing import OutputRecorder +from ..laguna.modeling_laguna import ( + LagunaDecoderLayer, + LagunaMLP, + LagunaModel, + LagunaRotaryEmbedding, +) from ..qwen3_moe.configuration_qwen3_moe import Qwen3MoeConfig from ..qwen3_moe.modeling_qwen3_moe import ( Qwen3MoeAttention, + Qwen3MoeExperts, Qwen3MoeForCausalLM, Qwen3MoePreTrainedModel, Qwen3MoeSparseMoeBlock, + Qwen3MoeTopKRouter, ) @@ -130,7 +139,22 @@ def __init__(self, config: MellumConfig, layer_idx: int): self.sliding_window = config.sliding_window if config.layer_types[layer_idx] == "sliding_attention" else None +class MellumExperts(Qwen3MoeExperts): + pass + + +class MellumTopKRouter(Qwen3MoeTopKRouter): + pass + + class MellumSparseMoeBlock(Qwen3MoeSparseMoeBlock): + def __init__(self, config: MellumConfig): + super().__init__(config) + self.experts = MellumExperts(config) + self.gate = MellumTopKRouter(config) + + +class MellumMLP(LagunaMLP): pass @@ -138,14 +162,29 @@ class MellumDecoderLayer(LagunaDecoderLayer): def __init__(self, config: MellumConfig, layer_idx: int): super().__init__() self.self_attn = MellumAttention(config, layer_idx) + if config.mlp_layer_types[layer_idx] == "sparse": + self.mlp = MellumSparseMoeBlock(config) + else: + self.mlp = MellumMLP(config, intermediate_size=config.intermediate_size) class MellumPreTrainedModel(Qwen3MoePreTrainedModel): + _can_record_outputs = { + "router_logits": OutputRecorder(MellumTopKRouter, index=0), + "hidden_states": MellumDecoderLayer, + "attentions": MellumAttention, + } _keys_to_ignore_on_load_unexpected = [r"^mtp\."] @torch.no_grad() def _init_weights(self, module): super()._init_weights(module) + std = self.config.initializer_range + if isinstance(module, MellumExperts): + init.normal_(module.gate_up_proj, mean=0.0, std=std) + init.normal_(module.down_proj, mean=0.0, std=std) + elif isinstance(module, MellumTopKRouter): + init.normal_(module.weight, mean=0.0, std=std) if isinstance(module, MellumRotaryEmbedding): for layer_type in module.layer_types: rope_init_fn = module.compute_default_rope_parameters @@ -157,11 +196,17 @@ def _init_weights(self, module): class MellumModel(LagunaModel): - pass + def __init__(self, config: MellumConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [MellumDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) class MellumForCausalLM(Qwen3MoeForCausalLM): - pass + def __init__(self, config: MellumConfig): + super().__init__(config) + self.model = MellumModel(config) __all__ = [ diff --git a/src/transformers/models/metaclip_2/modular_metaclip_2.py b/src/transformers/models/metaclip_2/modular_metaclip_2.py index 7a11b088aa3c..5d9e955f7398 100644 --- a/src/transformers/models/metaclip_2/modular_metaclip_2.py +++ b/src/transformers/models/metaclip_2/modular_metaclip_2.py @@ -18,8 +18,10 @@ from torch import nn from ... import initialization as init +from ...configuration_utils import PreTrainedConfig from ...masking_utils import create_causal_mask from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging from ..clip.configuration_clip import CLIPConfig, CLIPTextConfig, CLIPVisionConfig @@ -35,6 +37,7 @@ CLIPVisionEmbeddings, CLIPVisionModel, CLIPVisionModelWithProjection, + _init_child_weight, ) @@ -113,6 +116,85 @@ class MetaClip2Config(CLIPConfig): >>> config = MetaClip2Config(text_config=config_text, vision_config=config_vision) ```""" + model_type = "metaclip_2" + sub_configs_defaults = { + "vision_config": MetaClip2VisionConfig, + "text_config": MetaClip2TextConfig, + } + + def __post_init__(self, **kwargs): + # For backward compatibility check keyword args + # Instead of simply assigning `[text|vision]_config_dict` to `[text|vision]_config`, we use the values in + # `[text|vision]_config_dict` to update the values in `[text|vision]_config`. The values should be same in most + # cases, but we don't want to break anything regarding `_config_dict` that existed before commit `8827e1b2`. + if (text_config_dict := kwargs.pop("text_config_dict", None)) is not None: + # This is the complete result when using `text_config_dict`. + _text_config_dict = MetaClip2TextConfig(**text_config_dict).to_dict() + text_config = ( + self.text_config.to_dict() if isinstance(self.text_config, PreTrainedConfig) else self.text_config + ) + text_config = text_config or {} + + # Give a warning if the values exist in both `_text_config_dict` and `text_config` but being different. + for key, value in _text_config_dict.items(): + if key in text_config and value != text_config[key] and key != "transformers_version": + # If specified in `text_config_dict` + if key in text_config_dict: + message = ( + f"`{key}` is found in both `text_config_dict` and `text_config` but with different values. " + f'The value `text_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`text_config_dict` is provided which will be used to initialize `CLIPTextConfig`. The " + f'value `text_config["{key}"]` will be overridden.' + ) + logger.info(message) + + # Update all values in `text_config` with the ones in `_text_config_dict`. + text_config.update(_text_config_dict) + self.text_config = text_config + + if (vision_config_dict := kwargs.pop("vision_config_dict", None)) is not None: + # This is the complete result when using `vision_config_dict`. + _vision_config_dict = MetaClip2VisionConfig(**vision_config_dict).to_dict() + vision_config = ( + self.vision_config.to_dict() + if isinstance(self.vision_config, PreTrainedConfig) + else self.vision_config + ) + vision_config = vision_config or {} + + # convert keys to string instead of integer + if "id2label" in _vision_config_dict: + _vision_config_dict["id2label"] = { + str(key): value for key, value in _vision_config_dict["id2label"].items() + } + + # Give a warning if the values exist in both `_vision_config_dict` and `vision_config` but being different. + for key, value in _vision_config_dict.items(): + if key in vision_config and value != vision_config[key] and key != "transformers_version": + # If specified in `vision_config_dict` + if key in vision_config_dict: + message = ( + f"`{key}` is found in both `vision_config_dict` and `vision_config` but with different " + f'values. The value `vision_config_dict["{key}"]` will be used instead.' + ) + # If inferred from default argument values (just to be super careful) + else: + message = ( + f"`vision_config_dict` is provided which will be used to initialize `CLIPVisionConfig`. " + f'The value `vision_config["{key}"]` will be overridden.' + ) + logger.info(message) + + # Update all values in `vision_config` with the ones in `_vision_config_dict`. + vision_config.update(_vision_config_dict) + self.vision_config = vision_config + + PreTrainedConfig.__post_init__(self, **kwargs) + class MetaClip2TextEmbeddings(CLIPTextEmbeddings): pass @@ -137,7 +219,38 @@ class MetaClip2PreTrainedModel(CLIPPreTrainedModel): @torch.no_grad() def _init_weights(self, module): """Initialize the weights""" - super()._init_weights(module) + PreTrainedModel._init_weights(self, module) + factor = self.config.initializer_factor + if isinstance(module, MetaClip2TextEmbeddings): + _init_child_weight(module.token_embedding, factor * 0.02) + _init_child_weight(module.position_embedding, factor * 0.02) + init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1))) + elif isinstance(module, MetaClip2VisionEmbeddings): + init.normal_(module.class_embedding, mean=0.0, std=module.embed_dim**-0.5 * factor) + _init_child_weight(module.patch_embedding, module.config.initializer_range * factor) + _init_child_weight(module.position_embedding, module.config.initializer_range * factor) + init.copy_(module.position_ids, torch.arange(module.num_positions).expand((1, -1))) + elif isinstance(module, MetaClip2Attention): + in_proj_std = (module.embed_dim**-0.5) * ((2 * module.config.num_hidden_layers) ** -0.5) * factor + out_proj_std = (module.embed_dim**-0.5) * factor + _init_child_weight(module.q_proj, in_proj_std) + _init_child_weight(module.k_proj, in_proj_std) + _init_child_weight(module.v_proj, in_proj_std) + _init_child_weight(module.out_proj, out_proj_std) + elif isinstance(module, MetaClip2MLP): + in_proj_std = (module.config.hidden_size**-0.5) * ((2 * module.config.num_hidden_layers) ** -0.5) * factor + fc_std = (2 * module.config.hidden_size) ** -0.5 * factor + _init_child_weight(module.fc1, fc_std) + _init_child_weight(module.fc2, in_proj_std) + elif isinstance(module, MetaClip2Model): + _init_child_weight(module.text_projection, module.text_embed_dim**-0.5 * factor) + _init_child_weight(module.visual_projection, module.vision_embed_dim**-0.5 * factor) + elif isinstance(module, MetaClip2VisionModelWithProjection): + _init_child_weight(module.visual_projection, self.config.hidden_size**-0.5 * factor) + elif isinstance(module, MetaClip2TextModelWithProjection): + _init_child_weight(module.text_projection, self.config.hidden_size**-0.5 * factor) + elif isinstance(module, MetaClip2ForImageClassification): + _init_child_weight(module.classifier, self.config.vision_config.hidden_size**-0.5 * factor) if hasattr(module, "logit_scale"): init.constant_(module.logit_scale, self.config.logit_scale_init_value) @@ -265,6 +378,11 @@ class MetaClip2TextModelWithProjection(CLIPTextModelWithProjection): >>> text_embeds = outputs.text_embeds ```""" + def __init__(self, config: MetaClip2TextConfig): + super().__init__(config) + + self.text_model = MetaClip2TextModel._from_config(config) + def forward( self, input_ids: torch.Tensor | None = None, @@ -577,6 +695,11 @@ class MetaClip2VisionModelWithProjection(CLIPVisionModelWithProjection): >>> image_embeds = outputs.image_embeds ```""" + def __init__(self, config: MetaClip2VisionConfig): + super().__init__(config) + + self.vision_model = MetaClip2VisionModel._from_config(config) + def forward( self, pixel_values: torch.FloatTensor | None = None, @@ -612,7 +735,9 @@ def forward( class MetaClip2ForImageClassification(CLIPForImageClassification): - pass + def __init__(self, config: MetaClip2Config) -> None: + super().__init__(config) + self.vision_model = MetaClip2VisionModel._from_config(config.vision_config) __all__ = [ diff --git a/src/transformers/models/minicpm_ocr/modular_minicpm_ocr.py b/src/transformers/models/minicpm_ocr/modular_minicpm_ocr.py index 6c2ef54fc543..c68b672b26cf 100644 --- a/src/transformers/models/minicpm_ocr/modular_minicpm_ocr.py +++ b/src/transformers/models/minicpm_ocr/modular_minicpm_ocr.py @@ -21,8 +21,7 @@ from ...configuration_utils import SubConfigSpec from ...feature_extraction_utils import BatchFeature from ...image_transforms import divide_to_patches, group_images_by_shape, reorder_images -from ...image_utils import ImageInput, SizeDict -from ...processing_utils import Unpack +from ...image_utils import SizeDict from ...utils import TensorType, auto_docstring, is_cv2_available, logging, requires_backends from ..auto import AutoConfig from ..minicpmv4_6.configuration_minicpmv4_6 import MiniCPMV4_6Config, MiniCPMV4_6VisionConfig @@ -161,9 +160,6 @@ class MiniCPMOcrImageProcessor(MiniCPMV4_6ImageProcessor): small_image_upsize = "always" valid_kwargs = MiniCPMOcrImageProcessorKwargs - def __init__(self, **kwargs: Unpack[MiniCPMOcrImageProcessorKwargs]): - super().__init__(**kwargs) - def _resolve_tile_size( self, image: "torch.Tensor", @@ -319,14 +315,6 @@ def _preprocess( skip_tensor_conversion=["grids", "num_patches_per_image"], ) - @auto_docstring - def preprocess( - self, - images: ImageInput, - **kwargs: Unpack[MiniCPMOcrImageProcessorKwargs], - ) -> BatchFeature: - return super().preprocess(images, **kwargs) - class MiniCPMOcrVideoProcessorKwargs(MiniCPMV4_6VideoProcessorKwargs, total=False): r""" diff --git a/src/transformers/models/minimax_m2/modular_minimax_m2.py b/src/transformers/models/minimax_m2/modular_minimax_m2.py index 57090e31a927..8913256486e1 100644 --- a/src/transformers/models/minimax_m2/modular_minimax_m2.py +++ b/src/transformers/models/minimax_m2/modular_minimax_m2.py @@ -28,13 +28,14 @@ from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring from ...utils.generic import merge_with_config_defaults, no_inherit_decorator -from ...utils.output_capturing import capture_outputs +from ...utils.output_capturing import OutputRecorder, capture_outputs from ..flex_olmo.modeling_flex_olmo import FlexOlmoAttention from ..glm4_moe.modeling_glm4_moe import ( Glm4MoeRotaryEmbedding, apply_rotary_pos_emb, # noqa: F401 ) from ..mixtral.modeling_mixtral import ( + MixtralDecoderLayer, MixtralExperts, MixtralForCausalLM, MixtralModel, @@ -144,6 +145,7 @@ class MiniMaxM2Experts(MixtralExperts): class MiniMaxM2SparseMoeBlock(MixtralSparseMoeBlock): def __init__(self, config): super().__init__() + self.gate = MiniMaxM2TopKRouter(config) self.e_score_correction_bias = nn.Buffer(torch.zeros(config.num_local_experts)) def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: @@ -173,9 +175,28 @@ def __init__(self, config: MiniMaxM2Config, layer_idx: int): self.k_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=False) self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=False) self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=False) + self.q_norm = MiniMaxM2RMSNorm(config.num_attention_heads * self.head_dim, config.rms_norm_eps) + self.k_norm = MiniMaxM2RMSNorm(config.num_key_value_heads * self.head_dim, config.rms_norm_eps) + + +class MiniMaxM2DecoderLayer(MixtralDecoderLayer): + def __init__(self, config: MiniMaxM2Config, layer_idx: int): + super().__init__(config, layer_idx) + + self.self_attn = MiniMaxM2Attention(config, layer_idx) + + self.mlp = MiniMaxM2SparseMoeBlock(config) + self.input_layernorm = MiniMaxM2RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.post_attention_layernorm = MiniMaxM2RMSNorm(config.hidden_size, eps=config.rms_norm_eps) class MiniMaxM2PreTrainedModel(MixtralPreTrainedModel): + _can_record_outputs = { + "router_logits": OutputRecorder(MiniMaxM2TopKRouter, index=0), + "hidden_states": MiniMaxM2DecoderLayer, + "attentions": MiniMaxM2Attention, + } + @torch.no_grad() def _init_weights(self, module): PreTrainedModel._init_weights(self, module) @@ -190,6 +211,14 @@ def _init_weights(self, module): class MiniMaxM2Model(MixtralModel): + def __init__(self, config: MiniMaxM2Config): + super().__init__(config) + self.layers = nn.ModuleList( + [MiniMaxM2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.norm = MiniMaxM2RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = MiniMaxM2RotaryEmbedding(config=config) + @merge_with_config_defaults @capture_outputs @auto_docstring @@ -249,7 +278,9 @@ def forward( class MiniMaxM2ForCausalLM(MixtralForCausalLM): - pass + def __init__(self, config: MiniMaxM2Config): + super().__init__(config) + self.model = MiniMaxM2Model(config) __all__ = [ diff --git a/src/transformers/models/minimax_m3_vl/modular_minimax_m3_vl.py b/src/transformers/models/minimax_m3_vl/modular_minimax_m3_vl.py index 2dc75e717faa..0d3d349859d9 100644 --- a/src/transformers/models/minimax_m3_vl/modular_minimax_m3_vl.py +++ b/src/transformers/models/minimax_m3_vl/modular_minimax_m3_vl.py @@ -29,7 +29,7 @@ from ...modeling_outputs import BaseModelOutputWithPooling, MoeModelOutputWithPast from ...modeling_rope_utils import RopeParameters from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel, slice_logits_to_keep -from ...processing_utils import MultiModalData, Unpack +from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, logging, torch_compilable_check from ...utils.generic import can_return_tuple, merge_with_config_defaults from ...utils.import_utils import is_torchdynamo_compiling @@ -1299,44 +1299,6 @@ def replace_video_token(self, video_inputs: dict, video_idx: int, **kwargs) -> s chunk += self.VISION_START_TOKEN + self.VIDEO_TOKEN * frame_seqlen + self.VISION_END_TOKEN return chunk - def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): - """ - Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. - Args: - image_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (height, width) per each image. - video_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (num_frames, height, width) per each video. - Returns: - `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided - input modalities, along with other useful data. - """ - - vision_data = {} - if image_sizes is not None: - images_kwargs = MiniMaxM3VLProcessorKwargs._defaults.get("images_kwargs", {}) - images_kwargs.update(kwargs) - merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size - - num_image_patches = [ - self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) - for image_size in image_sizes - ] - num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] - vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) - - if video_sizes is not None: - videos_kwargs = MiniMaxM3VLProcessorKwargs._defaults.get("videos_kwargs", {}) - videos_kwargs.update(kwargs) - merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size - num_video_patches = [ - self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes - ] - num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] - vision_data["num_video_tokens"] = num_video_tokens - - return MultiModalData(**vision_data) - __all__ = [ "MiniMaxM3VLConfig", diff --git a/src/transformers/models/moonshine/modular_moonshine.py b/src/transformers/models/moonshine/modular_moonshine.py index 1ffce55ff3e4..f03c86191f7b 100644 --- a/src/transformers/models/moonshine/modular_moonshine.py +++ b/src/transformers/models/moonshine/modular_moonshine.py @@ -522,6 +522,7 @@ def __init__(self, config: MoonshineConfig): super().__init__(config) self.norm = nn.LayerNorm(config.hidden_size, bias=False) self.layers = nn.ModuleList([MoonshineDecoderLayer(config, idx) for idx in range(config.num_hidden_layers)]) + self.rotary_emb = MoonshineRotaryEmbedding(config=config) @merge_with_config_defaults @capture_outputs @@ -603,6 +604,12 @@ class MoonshineModel(WhisperModel): def _mask_input_features(self): raise AttributeError("Not needed for Moonshine") + def __init__(self, config: MoonshineConfig): + super().__init__(config) + + self.encoder = MoonshineEncoder(config) + self.decoder = MoonshineDecoder(config) + @can_return_tuple @auto_docstring def forward( diff --git a/src/transformers/models/moonshine_streaming/modular_moonshine_streaming.py b/src/transformers/models/moonshine_streaming/modular_moonshine_streaming.py index cd1be7dbf22a..8674a4065a87 100644 --- a/src/transformers/models/moonshine_streaming/modular_moonshine_streaming.py +++ b/src/transformers/models/moonshine_streaming/modular_moonshine_streaming.py @@ -28,7 +28,6 @@ ) from ...modeling_utils import ALL_ATTENTION_FUNCTIONS from ...processing_utils import ProcessingKwargs, Unpack -from ...tokenization_utils_base import AudioInput, PreTokenizedInput, TextInput from ...utils import TransformersKwargs, auto_docstring, logging from ...utils.generic import merge_with_config_defaults from ...utils.output_capturing import OutputRecorder, capture_outputs @@ -58,41 +57,7 @@ class MoonshineStreamingProcessorKwargs(ProcessingKwargs, total=False): } -class MoonshineStreamingProcessor(Wav2Vec2Processor): - ... - - @auto_docstring - def __call__( - self, - audio: AudioInput | None = None, - text: str | list[str] | TextInput | PreTokenizedInput | None = None, - **kwargs: Unpack[MoonshineStreamingProcessorKwargs], - ): - r""" - Returns: - This method returns the results of each `call` method. If both are used, the output is a dictionary containing the results of both. - """ - if audio is None and text is None: - raise ValueError("You need to specify either an `audio` or `text` input to process.") - - output_kwargs = self._merge_kwargs( - MoonshineStreamingProcessorKwargs, - tokenizer_init_kwargs=self.tokenizer.init_kwargs, - **kwargs, - ) - - if audio is not None: - inputs = self.feature_extractor(audio, **output_kwargs["audio_kwargs"]) - if text is not None: - encodings = self.tokenizer(text, **output_kwargs["text_kwargs"]) - - if text is None: - return inputs - elif audio is None: - return encodings - else: - inputs["labels"] = encodings["input_ids"] - return inputs +class MoonshineStreamingProcessor(Wav2Vec2Processor): ... @auto_docstring( diff --git a/src/transformers/models/muse_glimmer/modular_muse_glimmer.py b/src/transformers/models/muse_glimmer/modular_muse_glimmer.py index 08bc613d8bea..9b0110e352e2 100644 --- a/src/transformers/models/muse_glimmer/modular_muse_glimmer.py +++ b/src/transformers/models/muse_glimmer/modular_muse_glimmer.py @@ -28,7 +28,7 @@ from ...image_processing_backends import TorchvisionBackend from ...image_processing_utils import BatchFeature from ...image_transforms import group_images_by_shape, reorder_images -from ...image_utils import ImageInput, PILImageResampling, SizeDict +from ...image_utils import PILImageResampling, SizeDict from ...masking_utils import create_causal_mask, create_sliding_window_causal_mask from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, slice_logits_to_keep @@ -132,7 +132,6 @@ class MuseGlimmerImageProcessor(Glm4vImageProcessor): size = None merge_size = 2 max_image_tokens = 4096 - valid_kwargs = MuseGlimmerImageProcessorKwargs def _validate_preprocess_kwargs(self, **kwargs): # MuseGlimmer uses aspect_ratio_preserving_resize driven by patch_size, @@ -286,10 +285,6 @@ def get_number_of_image_patches(self, height: int, width: int, images_kwargs=Non grid_h, grid_w = resized_height // patch_size, resized_width // patch_size return grid_h * grid_w - @auto_docstring - def preprocess(self, images: ImageInput, **kwargs: Unpack[MuseGlimmerImageProcessorKwargs]) -> BatchFeature: - return super().preprocess(images, **kwargs) - class MuseGlimmerVideoProcessorInitKwargs(VideosKwargs, total=False): """ diff --git a/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py b/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py index bc26e8a1b7b1..287e87f68af8 100644 --- a/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py +++ b/src/transformers/models/nemotron3_5_transcribe/modular_nemotron3_5_transcribe.py @@ -663,18 +663,38 @@ def forward( """ if inputs_embeds is None and input_ids is not None: inputs_embeds = self._embed_input_ids(input_ids) - return super().forward( - input_ids=input_ids, - input_features=input_features, - input_features_mask=input_features_mask, + if inputs_embeds is None: + inputs_embeds = self.get_input_embeddings()(input_ids) + + audio_embeds = None + if input_features is not None and input_ids is not None: + audio_embeds = self.get_audio_features(input_features, input_features_mask, return_dict=True).pooler_output + + # replace text-audio token placeholders with audio embeddings + special_audio_mask = self.get_placeholder_mask( + input_ids, inputs_embeds=inputs_embeds, audio_features=audio_embeds + ) + inputs_embeds = inputs_embeds.masked_scatter( + special_audio_mask, audio_embeds.to(inputs_embeds.device, inputs_embeds.dtype) + ) + + outputs = self.language_model( + inputs_embeds=inputs_embeds, attention_mask=attention_mask, position_ids=position_ids, past_key_values=past_key_values, - inputs_embeds=inputs_embeds, use_cache=use_cache, **kwargs, ) + return Nemotron3_5TranscribeModelOutputWithPast( + last_hidden_state=outputs.last_hidden_state, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + audio_hidden_states=audio_embeds, + ) + @auto_docstring( custom_intro=""" Runs the word timestamp encoder on the speech recognition encoder states, in the chunks of the encoder: the diff --git a/src/transformers/models/nemotron_asr_streaming/modular_nemotron_asr_streaming.py b/src/transformers/models/nemotron_asr_streaming/modular_nemotron_asr_streaming.py index 43ee8465dadb..795473a97934 100644 --- a/src/transformers/models/nemotron_asr_streaming/modular_nemotron_asr_streaming.py +++ b/src/transformers/models/nemotron_asr_streaming/modular_nemotron_asr_streaming.py @@ -1148,21 +1148,6 @@ def forward( padding_cache=encoder_outputs.padding_cache, ) - @can_return_tuple - def get_audio_features( - self, - input_features: torch.Tensor, - attention_mask: torch.Tensor | None = None, - **kwargs: Unpack[TransformersKwargs], - ) -> NemotronAsrStreamingEncoderModelOutput: - encoder_outputs = self.encoder( - input_features=input_features, - attention_mask=attention_mask, - **kwargs, - ) - encoder_outputs.pooler_output = self.encoder_projector(encoder_outputs.last_hidden_state) - return encoder_outputs - __all__ = [ "NemotronAsrStreamingConfig", diff --git a/src/transformers/models/nomic_bert/modular_nomic_bert.py b/src/transformers/models/nomic_bert/modular_nomic_bert.py index e0ed6bc42b00..2c8c1514b562 100644 --- a/src/transformers/models/nomic_bert/modular_nomic_bert.py +++ b/src/transformers/models/nomic_bert/modular_nomic_bert.py @@ -18,6 +18,7 @@ from huggingface_hub.dataclasses import strict from torch.nn import CrossEntropyLoss +from ... import initialization as init from ...configuration_utils import PreTrainedConfig from ...masking_utils import create_bidirectional_mask from ...modeling_outputs import ( @@ -35,6 +36,7 @@ BertForMaskedLM, BertForSequenceClassification, BertForTokenClassification, + BertLMPredictionHead, BertOnlyMLMHead, BertPredictionHeadTransform, BertPreTrainedModel, @@ -122,7 +124,16 @@ class NomicBertMLP(GemmaMLP): class NomicBertLayer(JinaEmbeddingsV3Layer): - pass + def __init__(self, config: NomicBertConfig): + super().__init__(config) + self.mlp = NomicBertMLP(config) + self.self_attn = NomicBertAttention(config=config) + + +class NomicBertLMPredictionHead(BertLMPredictionHead): + def __init__(self, config): + super().__init__(config) + self.transform = NomicBertPredictionHeadTransform(config) class NomicBertPreTrainedModel(BertPreTrainedModel): @@ -137,6 +148,16 @@ class NomicBertPreTrainedModel(BertPreTrainedModel): "attentions": NomicBertAttention, } + @torch.no_grad() + def _init_weights(self, module): + """Initialize the weights""" + PreTrainedModel._init_weights(self, module) + if isinstance(module, NomicBertLMPredictionHead): + init.zeros_(module.bias) + elif isinstance(module, NomicBertEmbeddings): + init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1))) + init.zeros_(module.token_type_ids) + @auto_docstring class NomicBertModel(JinaEmbeddingsV3Model): @@ -280,7 +301,10 @@ def __init__(self, config: NomicBertConfig): class NomicBertForTokenClassification(BertForTokenClassification): - pass + def __init__(self, config: NomicBertConfig): + super().__init__(config) + + self.nomic_bert = NomicBertModel(config, add_pooling_layer=False) __all__ = [ diff --git a/src/transformers/models/paddleocr_vl/modular_paddleocr_vl.py b/src/transformers/models/paddleocr_vl/modular_paddleocr_vl.py index e7a20d1f1d59..7037855f8d54 100644 --- a/src/transformers/models/paddleocr_vl/modular_paddleocr_vl.py +++ b/src/transformers/models/paddleocr_vl/modular_paddleocr_vl.py @@ -390,6 +390,10 @@ class PaddleOCRDecoderLayer(Ernie4_5DecoderLayer): def __init__(self, config: PaddleOCRTextConfig, layer_idx: int): super().__init__() + self.self_attn = PaddleOCRAttention(config=config, layer_idx=layer_idx) + + self.mlp = PaddleOCRMLP(config) + @auto_docstring class PaddleOCRVLPreTrainedModel(PreTrainedModel): @@ -422,6 +426,10 @@ class PaddleOCRTextModel(PaddleOCRVLPreTrainedModel, Ernie4_5Model): def __init__(self, config: PaddleOCRTextConfig): super().__init__(config) + self.layers = nn.ModuleList( + [PaddleOCRDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + self.rotary_emb = PaddleOCRRotaryEmbedding(config=config) @merge_with_config_defaults @capture_outputs @@ -545,6 +553,8 @@ def __init__(self, config: PaddleOCRVisionConfig): class PaddleOCRVisionEncoderLayer(VideoLlama3VisionEncoderLayer): def __init__(self, config: PaddleOCRVisionConfig): super().__init__() + self.self_attn = PaddleOCRVisionAttention(config=config) + self.mlp = PaddleOCRVisionMLP(config=config) class PaddleOCRVisionEncoder(VideoLlama3VisionEncoder): @@ -810,6 +820,10 @@ def forward( class PaddleOCRVLForConditionalGeneration(Qwen2VLForConditionalGeneration): _keys_to_ignore_on_load_unexpected = ["packing_position_embedding", "vision_model.head"] + def __init__(self, config: PaddleOCRVLConfig): + super().__init__(config) + self.model = PaddleOCRVLModel(config) + def get_video_features(self): raise AttributeError("PaddleOCRVLForConditionalGeneration does not support video.") diff --git a/src/transformers/models/pocket_tts/modular_pocket_tts.py b/src/transformers/models/pocket_tts/modular_pocket_tts.py index ecf2308ac53c..7c704ddd1aec 100644 --- a/src/transformers/models/pocket_tts/modular_pocket_tts.py +++ b/src/transformers/models/pocket_tts/modular_pocket_tts.py @@ -28,7 +28,7 @@ from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, torch_compilable_check from ...utils.generic import merge_with_config_defaults from ...utils.output_capturing import capture_outputs -from ..jais2.modeling_jais2 import Jais2DecoderLayer +from ..jais2.modeling_jais2 import Jais2Attention, Jais2DecoderLayer from ..llama.modeling_llama import ( LlamaModel, LlamaPreTrainedModel, @@ -58,7 +58,15 @@ class PocketTTSOutputWithPast(CausalLMOutputWithPast): class PocketTTSMLP(MimiMLP): ... -class PocketTTSDecoderLayer(Jais2DecoderLayer): ... +class PocketTTSAttention(Jais2Attention): + pass + + +class PocketTTSDecoderLayer(Jais2DecoderLayer): + def __init__(self, config: PocketTTSConfig, layer_idx: int): + super().__init__(config, layer_idx) + + self.mlp = PocketTTSMLP(config) class PocketTTSTimestepNorm(nn.Module): @@ -214,6 +222,10 @@ class PocketTTSPreTrainedModel(LlamaPreTrainedModel): config: PocketTTSConfig # the flow head runs as one unit per step: split across devices, its blocks would mix devices mid-computation _no_split_modules = ["PocketTTSDecoderLayer", "PocketTTSFlowHead"] + _can_record_outputs = { + "hidden_states": PocketTTSDecoderLayer, + "attentions": PocketTTSAttention, + } input_modalities = ("text", "audio") @torch.no_grad() @@ -244,6 +256,9 @@ def _init_weights(self, module): class PocketTTSModel(LlamaModel): def __init__(self, config: PocketTTSConfig): super().__init__(config) + self.layers = nn.ModuleList( + [PocketTTSDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) self.norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) self.audio_prompt_proj = nn.Linear(config.latent_dim, config.hidden_size, bias=False) self.audio_latent_proj = nn.Linear(config.latent_dim, config.hidden_size, bias=False) diff --git a/src/transformers/models/pp_doclayout_v2/modular_pp_doclayout_v2.py b/src/transformers/models/pp_doclayout_v2/modular_pp_doclayout_v2.py index 51d7271edb54..7b266ff8b20b 100644 --- a/src/transformers/models/pp_doclayout_v2/modular_pp_doclayout_v2.py +++ b/src/transformers/models/pp_doclayout_v2/modular_pp_doclayout_v2.py @@ -16,12 +16,15 @@ from dataclasses import dataclass import torch +import torch.nn.functional as F from huggingface_hub.dataclasses import strict from torch import nn from ... import initialization as init from ...configuration_utils import PreTrainedConfig, SubConfigSpec from ...masking_utils import create_bidirectional_mask +from ...modeling_outputs import BaseModelOutput +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import ( ModelOutput, @@ -43,13 +46,17 @@ LayoutLMv3TextEmbeddings, ) from ..pp_doclayout_v3.image_processing_pp_doclayout_v3 import PPDocLayoutV3ImageProcessor -from ..pp_doclayout_v3.modeling_pp_doclayout_v3 import PPDocLayoutV3GlobalPointer +from ..pp_doclayout_v3.modeling_pp_doclayout_v3 import ( + PPDocLayoutV3GlobalPointer, + PPDocLayoutV3MultiscaleDeformableAttention, +) from ..rt_detr.modeling_rt_detr import ( RTDetrForObjectDetection, RTDetrMLPPredictionHead, RTDetrModel, RTDetrModelOutput, RTDetrPreTrainedModel, + get_contrastive_denoising_training_group, ) @@ -615,12 +622,71 @@ def forward( return embeddings +class PPDocLayoutV2MultiscaleDeformableAttention(PPDocLayoutV3MultiscaleDeformableAttention): + pass + + @auto_docstring class PPDocLayoutV2PreTrainedModel(RTDetrPreTrainedModel): @torch.no_grad() def _init_weights(self, module): """Initialize the weights""" - super()._init_weights(module) + PreTrainedModel._init_weights(self, module) + if isinstance(module, PPDocLayoutV2ForObjectDetection): + if module.model.decoder.class_embed is not None: + for layer in module.model.decoder.class_embed: + prior_prob = self.config.initializer_bias_prior_prob or 1 / (self.config.num_labels + 1) + bias = float(-math.log((1 - prior_prob) / prior_prob)) + init.xavier_uniform_(layer.weight) + init.constant_(layer.bias, bias) + + if module.model.decoder.bbox_embed is not None: + for layer in module.model.decoder.bbox_embed: + init.constant_(layer.layers[-1].weight, 0) + init.constant_(layer.layers[-1].bias, 0) + + elif isinstance(module, PPDocLayoutV2MultiscaleDeformableAttention): + init.constant_(module.sampling_offsets.weight, 0.0) + default_dtype = torch.get_default_dtype() + thetas = torch.arange(module.n_heads, dtype=torch.int64).to(default_dtype) * ( + 2.0 * math.pi / module.n_heads + ) + grid_init = torch.stack([thetas.cos(), thetas.sin()], -1) + grid_init = ( + (grid_init / grid_init.abs().max(-1, keepdim=True)[0]) + .view(module.n_heads, 1, 1, 2) + .repeat(1, module.n_levels, module.n_points, 1) + ) + for i in range(module.n_points): + grid_init[:, :, i, :] *= i + 1 + + init.copy_(module.sampling_offsets.bias, grid_init.view(-1)) + init.constant_(module.attention_weights.weight, 0.0) + init.constant_(module.attention_weights.bias, 0.0) + init.xavier_uniform_(module.value_proj.weight) + init.constant_(module.value_proj.bias, 0.0) + init.xavier_uniform_(module.output_proj.weight) + init.constant_(module.output_proj.bias, 0.0) + + elif isinstance(module, PPDocLayoutV2Model): + prior_prob = self.config.initializer_bias_prior_prob or 1 / (self.config.num_labels + 1) + bias = float(-math.log((1 - prior_prob) / prior_prob)) + init.xavier_uniform_(module.enc_score_head.weight) + init.constant_(module.enc_score_head.bias, bias) + + elif isinstance(module, nn.BatchNorm2d): + init.normal_(module.weight, mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + init.zeros_(module.bias) + if getattr(module, "running_mean", None) is not None: + init.zeros_(module.running_mean) + init.ones_(module.running_var) + init.zeros_(module.num_batches_tracked) + + if hasattr(module, "weight_embedding") and self.config.learn_initial_query: + init.xavier_uniform_(module.weight_embedding.weight) + if hasattr(module, "denoising_class_embed") and self.config.num_denoising > 0: + init.xavier_uniform_(module.denoising_class_embed.weight) if isinstance(module, PPDocLayoutV2TextEmbeddings): init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1))) if isinstance(module, PPDocLayoutV2PositionRelationEmbedding): @@ -804,6 +870,205 @@ def __init__(self, config: PPDocLayoutV2Config): super().__init__() self.denoising_class_embed = nn.Embedding(config.num_labels, config.d_model) + @auto_docstring + @can_return_tuple + def forward( + self, + pixel_values: torch.FloatTensor, + pixel_mask: torch.LongTensor | None = None, + encoder_outputs: torch.FloatTensor | None = None, + inputs_embeds: torch.FloatTensor | None = None, + labels: list[dict] | None = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.FloatTensor] | PPDocLayoutV2ModelOutput: + r""" + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): + Optionally, instead of passing the flattened feature map (output of the backbone + projection layer), you + can choose to directly pass a flattened representation of an image. + labels (`list[Dict]` of len `(batch_size,)`, *optional*): + Labels for computing the bipartite matching loss. List of dicts, each dictionary containing at least the + following 2 keys: 'class_labels' and 'boxes' (the class labels and bounding boxes of an image in the batch + respectively). The class labels themselves should be a `torch.LongTensor` of len `(number of bounding boxes + in the image,)` and the boxes a `torch.FloatTensor` of shape `(number of bounding boxes in the image, 4)`. + + Examples: + + ```python + >>> from transformers import AutoImageProcessor, PPDocLayoutV2Model + >>> from PIL import Image + >>> from huggingface_hub.utils import httpx + >>> from io import BytesIO + + >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" + >>> with httpx.stream("GET", url) as response: + ... image = Image.open(BytesIO(response.read())) + + >>> image_processor = AutoImageProcessor.from_pretrained("PekingU/PPDocLayoutV2_r50vd") + >>> model = PPDocLayoutV2Model.from_pretrained("PekingU/PPDocLayoutV2_r50vd") + + >>> inputs = image_processor(images=image, return_tensors="pt") + + >>> outputs = model(**inputs) + + >>> last_hidden_states = outputs.last_hidden_state + >>> list(last_hidden_states.shape) + [1, 300, 256] + ```""" + if pixel_values is None and inputs_embeds is None: + raise ValueError("You have to specify either pixel_values or inputs_embeds") + + if inputs_embeds is None: + batch_size, num_channels, height, width = pixel_values.shape + device = pixel_values.device + if pixel_mask is None: + pixel_mask = torch.ones(((batch_size, height, width)), device=device) + features = self.backbone(pixel_values, pixel_mask) + proj_feats = [self.encoder_input_proj[level](source) for level, (source, mask) in enumerate(features)] + else: + batch_size = inputs_embeds.shape[0] + device = inputs_embeds.device + proj_feats = inputs_embeds + + if encoder_outputs is None: + encoder_outputs = self.encoder( + proj_feats, + **kwargs, + ) + # If the user passed a tuple for encoder_outputs, we wrap it in a BaseModelOutput + elif not isinstance(encoder_outputs, BaseModelOutput): + encoder_outputs = BaseModelOutput( + last_hidden_state=encoder_outputs[0], + hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None, + attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None, + ) + + # Equivalent to def _get_encoder_input + # https://github.com/lyuwenyu/RT-DETR/blob/94f5e16708329d2f2716426868ec89aa774af016/PPDocLayoutV2_pytorch/src/zoo/PPDocLayoutV2/PPDocLayoutV2_decoder.py#L412 + sources = [] + for level, source in enumerate(encoder_outputs.last_hidden_state): + sources.append(self.decoder_input_proj[level](source)) + + # Lowest resolution feature maps are obtained via 3x3 stride 2 convolutions on the final stage + if self.config.num_feature_levels > len(sources): + _len_sources = len(sources) + sources.append(self.decoder_input_proj[_len_sources](encoder_outputs.last_hidden_state[-1])) + for i in range(_len_sources + 1, self.config.num_feature_levels): + sources.append(self.decoder_input_proj[i](encoder_outputs.last_hidden_state[-1])) + + # Prepare encoder inputs (by flattening) + source_flatten = [] + spatial_shapes_list = [] + spatial_shapes = torch.empty((len(sources), 2), device=device, dtype=torch.long) + for level, source in enumerate(sources): + height, width = source.shape[-2:] + spatial_shapes[level, 0] = height + spatial_shapes[level, 1] = width + spatial_shapes_list.append((height, width)) + source = source.flatten(2).transpose(1, 2) + source_flatten.append(source) + source_flatten = torch.cat(source_flatten, 1) + level_start_index = torch.cat((spatial_shapes.new_zeros((1,)), spatial_shapes.prod(1).cumsum(0)[:-1])) + + # prepare denoising training + if self.training and self.config.num_denoising > 0 and labels is not None: + ( + denoising_class, + denoising_bbox_unact, + attention_mask, + denoising_meta_values, + ) = get_contrastive_denoising_training_group( + targets=labels, + num_classes=self.config.num_labels, + num_queries=self.config.num_queries, + class_embed=self.denoising_class_embed, + num_denoising_queries=self.config.num_denoising, + label_noise_ratio=self.config.label_noise_ratio, + box_noise_scale=self.config.box_noise_scale, + ) + else: + denoising_class, denoising_bbox_unact, attention_mask, denoising_meta_values = None, None, None, None + + batch_size = len(source_flatten) + device = source_flatten.device + dtype = source_flatten.dtype + + # prepare input for decoder + if self.training or self.config.anchor_image_size is None: + # Pass spatial_shapes as tuple to make it hashable and make sure + # lru_cache is working for generate_anchors() + spatial_shapes_tuple = tuple(spatial_shapes_list) + anchors, valid_mask = self.generate_anchors(spatial_shapes_tuple, device=device, dtype=dtype) + else: + anchors, valid_mask = self.anchors, self.valid_mask + anchors, valid_mask = anchors.to(device, dtype), valid_mask.to(device, dtype) + + # use the valid_mask to selectively retain values in the feature map where the mask is `True` + memory = valid_mask.to(source_flatten.dtype) * source_flatten + + output_memory = self.enc_output(memory) + + enc_outputs_class = self.enc_score_head(output_memory) + enc_outputs_coord_logits = self.enc_bbox_head(output_memory) + anchors + + _, topk_ind = torch.topk(enc_outputs_class.max(-1).values, self.config.num_queries, dim=1) + + reference_points_unact = enc_outputs_coord_logits.gather( + dim=1, index=topk_ind.unsqueeze(-1).repeat(1, 1, enc_outputs_coord_logits.shape[-1]) + ) + + enc_topk_bboxes = F.sigmoid(reference_points_unact) + if denoising_bbox_unact is not None: + reference_points_unact = torch.concat([denoising_bbox_unact, reference_points_unact], 1) + + enc_topk_logits = enc_outputs_class.gather( + dim=1, index=topk_ind.unsqueeze(-1).repeat(1, 1, enc_outputs_class.shape[-1]) + ) + + # extract region features + if self.config.learn_initial_query: + target = self.weight_embedding.tile([batch_size, 1, 1]) + else: + target = output_memory.gather(dim=1, index=topk_ind.unsqueeze(-1).repeat(1, 1, output_memory.shape[-1])) + target = target.detach() + + if denoising_class is not None: + target = torch.concat([denoising_class, target], 1) + + init_reference_points = reference_points_unact.detach() + + # decoder + decoder_outputs = self.decoder( + inputs_embeds=target, + encoder_hidden_states=source_flatten, + encoder_attention_mask=attention_mask, + reference_points=init_reference_points, + spatial_shapes=spatial_shapes, + spatial_shapes_list=spatial_shapes_list, + level_start_index=level_start_index, + **kwargs, + ) + + return PPDocLayoutV2ModelOutput( + last_hidden_state=decoder_outputs.last_hidden_state, + intermediate_hidden_states=decoder_outputs.intermediate_hidden_states, + intermediate_logits=decoder_outputs.intermediate_logits, + intermediate_reference_points=decoder_outputs.intermediate_reference_points, + intermediate_predicted_corners=decoder_outputs.intermediate_predicted_corners, + initial_reference_points=decoder_outputs.initial_reference_points, + decoder_hidden_states=decoder_outputs.hidden_states, + decoder_attentions=decoder_outputs.attentions, + cross_attentions=decoder_outputs.cross_attentions, + encoder_last_hidden_state=encoder_outputs.last_hidden_state, + encoder_hidden_states=encoder_outputs.hidden_states, + encoder_attentions=encoder_outputs.attentions, + init_reference_points=init_reference_points, + enc_topk_logits=enc_topk_logits, + enc_topk_bboxes=enc_topk_bboxes, + enc_outputs_class=enc_outputs_class, + enc_outputs_coord_logits=enc_outputs_coord_logits, + denoising_meta_values=denoising_meta_values, + ) + @auto_docstring( custom_intro=""" @@ -819,6 +1084,7 @@ def __init__(self, config: PPDocLayoutV2Config): self.reading_order = PPDocLayoutV2ReadingOrder(config.reading_order_config) self.num_queries = config.num_queries + self.model = PPDocLayoutV2Model(config) self.config = config self.post_init() diff --git a/src/transformers/models/pp_formulanet/modular_pp_formulanet.py b/src/transformers/models/pp_formulanet/modular_pp_formulanet.py index 0b69c16ac977..de446f1b5446 100644 --- a/src/transformers/models/pp_formulanet/modular_pp_formulanet.py +++ b/src/transformers/models/pp_formulanet/modular_pp_formulanet.py @@ -143,8 +143,6 @@ class PPFormulaNetProcessor(NougatProcessor): [`~PPFormulaNetProcessor.__call__`] and [`~PPFormulaNetProcessor.decode`] for more information. """ - valid_processor_kwargs = PPFormulaNetProcessorKwargs - def __init__(self, image_processor, tokenizer): super().__init__(image_processor, tokenizer) diff --git a/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py b/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py index 18268280b58d..dd663d06d9f7 100644 --- a/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py +++ b/src/transformers/models/qwen2_5_omni/modular_qwen2_5_omni.py @@ -65,6 +65,7 @@ from ..qwen2_5_vl.modeling_qwen2_5_vl import ( Qwen2_5_VisionTransformerPretrainedModel, Qwen2_5_VLAttention, + Qwen2_5_VLDecoderLayer, Qwen2_5_VLMLP, Qwen2_5_VLPreTrainedModel, Qwen2_5_VLTextModel, @@ -1490,6 +1491,8 @@ class Qwen2_5OmniVisionEncoder(Qwen2_5_VisionTransformerPretrainedModel): def __init__(self, config: Qwen2_5OmniVisionEncoderConfig, *inputs, **kwargs) -> None: super().__init__(config, *inputs, **kwargs) + + self.rotary_pos_emb = Qwen2_5OmniVisionRotaryEmbedding(config) self.blocks = nn.ModuleList([Qwen2_5OmniVisionBlock(config) for _ in range(config.depth)]) def permute_input_for_window_attn(self, input_tensor: torch.Tensor, window_index: torch.Tensor, seq_len: int): @@ -1603,8 +1606,20 @@ class Qwen2MLP(Qwen2_5_VLMLP): pass +class Qwen2_5OmniDecoderLayer(Qwen2_5_VLDecoderLayer): + def __init__(self, config: Qwen2_5OmniTextConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = Qwen2_5OmniAttention(config, layer_idx) + + self.mlp = Qwen2MLP(config) + + class Qwen2_5OmniThinkerTextModel(Qwen2_5_VLTextModel): config: Qwen2_5OmniTextConfig + _can_record_outputs = { + "hidden_states": Qwen2_5OmniDecoderLayer, + "attentions": Qwen2_5OmniAttention, + } _no_split_modules = ["Qwen2_5OmniDecoderLayer"] def __init__(self, config: Qwen2_5OmniTextConfig): @@ -2140,6 +2155,10 @@ class Qwen2_5OmniTalkerCausalLMOutputWithPast(CausalLMOutputWithPast): class Qwen2_5OmniTalkerModel(Qwen2_5_VLTextModel): config: Qwen2_5OmniTalkerConfig input_modalities = ("image", "video", "audio", "text") + _can_record_outputs = { + "hidden_states": Qwen2_5OmniDecoderLayer, + "attentions": Qwen2_5OmniAttention, + } _no_split_modules = ["Qwen2_5OmniDecoderLayer"] diff --git a/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py b/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py index 20844d3b165f..a29283967bd5 100644 --- a/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py +++ b/src/transformers/models/qwen2_5_vl/modular_qwen2_5_vl.py @@ -30,7 +30,7 @@ from ...modeling_layers import GradientCheckpointingLayer from ...modeling_outputs import BaseModelOutputWithPooling from ...modeling_utils import slice_logits_to_keep -from ...processing_utils import MultiModalData, ProcessingKwargs, Unpack +from ...processing_utils import ProcessingKwargs, Unpack from ...utils import auto_docstring, logging from ...utils.generic import get_max_seqlen, merge_with_config_defaults from ...utils.output_capturing import capture_outputs @@ -693,8 +693,6 @@ class Qwen2_5_VLProcessorKwargs(ProcessingKwargs, total=False): class Qwen2_5_VLProcessor(Qwen2VLProcessor): - valid_processor_kwargs = Qwen2_5_VLProcessorKwargs - def _process_videos(self, videos: VideoInput, **kwargs): processed_data, video_replacements = super()._process_videos(videos, **kwargs) video_grid_thw = processed_data["video_grid_thw"] @@ -717,44 +715,6 @@ def _process_videos(self, videos: VideoInput, **kwargs): def model_input_names(self): return super().model_input_names + ["second_per_grid_ts", "mm_token_type_ids"] - def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): - """ - Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. - Args: - image_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (height, width) per each image. - video_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (num_frames, height, width) per each video. - Returns: - `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided - input modalities, along with other useful data. - """ - - vision_data = {} - if image_sizes is not None: - images_kwargs = Qwen2_5_VLProcessorKwargs._defaults.get("images_kwargs", {}) - images_kwargs.update(kwargs) - merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size - - num_image_patches = [ - self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) - for image_size in image_sizes - ] - num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] - vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) - - if video_sizes is not None: - videos_kwargs = Qwen2_5_VLProcessorKwargs._defaults.get("videos_kwargs", {}) - videos_kwargs.update(kwargs) - merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size - num_video_patches = [ - self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes - ] - num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] - vision_data["num_video_tokens"] = num_video_tokens - - return MultiModalData(**vision_data) - __all__ = [ "Qwen2_5_VLConfig", diff --git a/src/transformers/models/qwen3_asr/modular_qwen3_asr.py b/src/transformers/models/qwen3_asr/modular_qwen3_asr.py index 6fd0d39b143b..70c3f1c0cd31 100644 --- a/src/transformers/models/qwen3_asr/modular_qwen3_asr.py +++ b/src/transformers/models/qwen3_asr/modular_qwen3_asr.py @@ -32,6 +32,7 @@ from ..qwen2_audio.modeling_qwen2_audio import Qwen2AudioPreTrainedModel from ..qwen3_omni_moe.configuration_qwen3_omni_moe import Qwen3OmniMoeAudioEncoderConfig from ..qwen3_omni_moe.modeling_qwen3_omni_moe import ( + Qwen3OmniMoeAudioAttention, Qwen3OmniMoeAudioEncoder, Qwen3OmniMoeAudioEncoderLayer, SinusoidsPositionEmbedding, @@ -136,6 +137,10 @@ def _init_weights(self, module): init.copy_(module.positional_embedding, position_embeddings) +class Qwen3ASRAudioAttention(Qwen3OmniMoeAudioAttention): + pass + + class Qwen3ASRAudioEncoderLayer(Qwen3OmniMoeAudioEncoderLayer): def __init__(self, config: Qwen3ASREncoderConfig): super().__init__(config) @@ -149,11 +154,16 @@ def __init__(self, config: Qwen3ASREncoderConfig): class Qwen3ASREncoder(Qwen3OmniMoeAudioEncoder): config: Qwen3ASREncoderConfig _no_split_modules = ["Qwen3ASRAudioEncoderLayer"] + _can_record_outputs = { + "hidden_states": Qwen3ASRAudioEncoderLayer, + "attentions": Qwen3ASRAudioAttention, + } def __init__(self, config: Qwen3ASREncoderConfig): super().__init__(config) embed_dim = config.d_model self.positional_embedding = SinusoidsPositionEmbedding(config.max_position_embeddings, embed_dim) + self.layers = nn.ModuleList([Qwen3ASRAudioEncoderLayer(config) for _ in range(config.encoder_layers)]) del self.conv_chunksize del self.proj1 del self.act @@ -242,6 +252,10 @@ def __init__(self, config: Qwen3ASRConfig): class Qwen3ASRModel(AudioFlamingo3Model): + def __init__(self, config: Qwen3ASRConfig): + super().__init__(config) + self.multi_modal_projector = Qwen3ASRMultiModalProjector(config) + @can_return_tuple @auto_docstring( custom_intro="This method is used to get the audio embeddings from input features (a log mel spectrogram)." @@ -274,6 +288,10 @@ class Qwen3ASRForConditionalGeneration(AudioFlamingo3ForConditionalGeneration): _tied_weights_keys = {"lm_head.weight": "model.language_model.embed_tokens.weight"} _tp_plan = {"lm_head": "colwise_gather_output"} + def __init__(self, config: Qwen3ASRConfig): + super().__init__(config) + self.model = Qwen3ASRModel(config) + def forward(self, **super_kwargs): r""" input_features_mask (`torch.Tensor` of shape `(batch_size, feature_sequence_length)`): diff --git a/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py b/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py index 69a0440b8deb..327a71d792a8 100644 --- a/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py +++ b/src/transformers/models/qwen3_omni_moe/modular_qwen3_omni_moe.py @@ -62,6 +62,7 @@ from ..qwen2_5_omni.modeling_qwen2_5_omni import ( Qwen2_5OmniAudioAttention, Qwen2_5OmniAudioEncoder, + Qwen2_5OmniAudioEncoderLayer, Qwen2_5OmniPreTrainedModel, Qwen2_5OmniPreTrainedModelForConditionalGeneration, Qwen2_5OmniSnakeBeta, @@ -100,7 +101,9 @@ from ..qwen3_vl_moe.modeling_qwen3_vl_moe import ( Qwen3VLMoeTextModel, Qwen3VLMoeTextRotaryEmbedding, + Qwen3VLMoeTextTopKRouter, Qwen3VLMoeVisionAttention, + Qwen3VLMoeVisionBlock, Qwen3VLMoeVisionModel, Qwen3VLMoeVisionRotaryEmbedding, ) @@ -371,6 +374,11 @@ class Qwen3OmniMoeThinkerConfig(Qwen2_5OmniThinkerConfig): model_type = "qwen3_omni_moe_thinker" # Override parent's attribute_map as we use audio_token_id directly, not audio_token_index attribute_map = {} + sub_configs_defaults = { + "text_config": Qwen3OmniMoeTextConfig, + "vision_config": Qwen3OmniMoeVisionEncoderConfig, + "audio_config": Qwen3OmniMoeAudioEncoderConfig, + } audio_token_id: int = 151646 image_token_id: int = 151655 @@ -957,7 +965,18 @@ def __init__(self, config): self.k_proj = nn.Linear(self.embed_dim, self.embed_dim, bias=True) +class Qwen3OmniMoeAudioEncoderLayer(Qwen2_5OmniAudioEncoderLayer): + def __init__(self, config: Qwen3OmniMoeAudioEncoderConfig): + super().__init__(config) + self.self_attn = Qwen3OmniMoeAudioAttention(config) + + class Qwen3OmniMoeAudioEncoder(Qwen2_5OmniAudioEncoder): + _can_record_outputs = { + "hidden_states": Qwen3OmniMoeAudioEncoderLayer, + "attentions": Qwen3OmniMoeAudioAttention, + } + def __init__(self, config: Qwen3OmniMoeAudioEncoderConfig): super().__init__(config) del self.proj @@ -1077,8 +1096,23 @@ def compute_axial_rope_parameters( return super().compute_axial_rope_parameters(config, device=device, **kwargs) +class Qwen3OmniMoeTextTopKRouter(Qwen3VLMoeTextTopKRouter): + pass + + +class Qwen3OmniMoeVisionBlock(Qwen3VLMoeVisionBlock): + def __init__(self, config, attn_implementation: str = "sdpa") -> None: + super().__init__(config, attn_implementation) + self.attn = Qwen3OmniMoeVisionAttention(config=config) + + class Qwen3OmniMoeVisionEncoder(Qwen3VLMoeVisionModel): config: Qwen3OmniMoeVisionEncoderConfig + _can_record_outputs = { + "router_logits": OutputRecorder(Qwen3OmniMoeTextTopKRouter, layer_name="mlp.gate", index=0), + "hidden_states": Qwen3OmniMoeVisionBlock, + "attentions": Qwen3OmniMoeVisionAttention, + } def __init__(self, config: Qwen3OmniMoeVisionEncoderConfig, *inputs, **kwargs): self.merger_list = nn.ModuleList( @@ -1091,6 +1125,8 @@ def __init__(self, config: Qwen3OmniMoeVisionEncoderConfig, *inputs, **kwargs): ] ) super().__init__(config, *inputs, **kwargs) + + self.rotary_pos_emb = Qwen3OmniMoeVisionRotaryEmbedding(config) del self.deepstack_merger_list @property @@ -1118,6 +1154,8 @@ class Qwen3OmniMoeThinkerTextTopKRouter(Qwen3MoeTopKRouter): class Qwen3OmniMoeThinkerTextSparseMoeBlock(Qwen3MoeSparseMoeBlock): def __init__(self, config: Qwen3OmniMoeThinkerConfig): super().__init__(config) + self.experts = Qwen3OmniMoeThinkerTextExperts(config) + self.gate = Qwen3OmniMoeThinkerTextTopKRouter(config) class Qwen3OmniMoeThinkerTextAttention(Qwen3MoeAttention): @@ -1126,15 +1164,40 @@ def __init__(self, config, layer_idx): self.sliding_window = None +class Qwen3OmniMoeThinkerTextMLP(Qwen3MoeMLP): + pass + + class Qwen3OmniMoeThinkerTextDecoderLayer(Qwen3MoeDecoderLayer): def __init__(self, config, layer_idx): super().__init__(config, layer_idx) self.self_attn = Qwen3OmniMoeThinkerTextAttention(config, layer_idx) + if (layer_idx not in config.mlp_only_layers) and ( + config.num_experts > 0 and (layer_idx + 1) % config.decoder_sparse_step == 0 + ): + self.mlp = Qwen3OmniMoeThinkerTextSparseMoeBlock(config) + else: + self.mlp = Qwen3OmniMoeThinkerTextMLP(config, intermediate_size=config.intermediate_size) class Qwen3OmniMoeThinkerTextPreTrainedModel(Qwen3MoePreTrainedModel): config: Qwen3OmniMoeTextConfig config: Qwen3OmniMoeTextConfig + _can_record_outputs = { + "router_logits": OutputRecorder(Qwen3OmniMoeThinkerTextTopKRouter, index=0), + "hidden_states": Qwen3OmniMoeThinkerTextDecoderLayer, + "attentions": Qwen3OmniMoeThinkerTextAttention, + } + + @torch.no_grad() + def _init_weights(self, module): + PreTrainedModel._init_weights(self, module) + std = self.config.initializer_range + if isinstance(module, Qwen3OmniMoeThinkerTextExperts): + init.normal_(module.gate_up_proj, mean=0.0, std=std) + init.normal_(module.down_proj, mean=0.0, std=std) + elif isinstance(module, Qwen3OmniMoeThinkerTextTopKRouter): + init.normal_(module.weight, mean=0.0, std=std) class Qwen3OmniMoeThinkerTextModel(Qwen3VLMoeTextModel): @@ -1178,6 +1241,12 @@ class Qwen3OmniMoeThinkerModel(Qwen2_5OmniThinkerModel): "router_logits": OutputRecorder(Qwen3OmniMoeThinkerTextTopKRouter, index=0), } + def __init__(self, config: Qwen3OmniMoeThinkerConfig): + super().__init__(config) + self.audio_tower = Qwen3OmniMoeAudioEncoder._from_config(config.audio_config) + self.visual = Qwen3OmniMoeVisionEncoder._from_config(config.vision_config) + self.language_model = Qwen3OmniMoeThinkerTextModel._from_config(config.text_config) + def get_video_features( self, pixel_values_videos: torch.FloatTensor, @@ -1379,6 +1448,7 @@ def forward( class Qwen3OmniMoeThinkerForConditionalGeneration(Qwen2_5OmniThinkerForConditionalGeneration): def __init__(self, config: Qwen3OmniMoeThinkerConfig): super().__init__(config) + self.model = Qwen3OmniMoeThinkerModel(config) self.num_experts = config.text_config.num_experts self.num_experts_per_tok = config.text_config.num_experts_per_tok self.router_aux_loss_coef = config.text_config.router_aux_loss_coef @@ -1693,6 +1763,12 @@ class Qwen3OmniMoeTalkerDecoderLayer(Qwen3MoeDecoderLayer): def __init__(self, config, layer_idx): super().__init__(config, layer_idx) self.self_attn = Qwen3OmniMoeThinkerTextAttention(config, layer_idx) + if (layer_idx not in config.mlp_only_layers) and ( + config.num_experts > 0 and (layer_idx + 1) % config.decoder_sparse_step == 0 + ): + self.mlp = Qwen3OmniMoeThinkerTextSparseMoeBlock(config) + else: + self.mlp = Qwen3OmniMoeThinkerTextMLP(config, intermediate_size=config.intermediate_size) self.mlp = Qwen3OmniMoeTalkerTextSparseMoeBlock(config) diff --git a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py index d307f2163a4f..dc11ae1ea1e4 100644 --- a/src/transformers/models/qwen3_vl/modular_qwen3_vl.py +++ b/src/transformers/models/qwen3_vl/modular_qwen3_vl.py @@ -30,7 +30,7 @@ from ...modeling_outputs import BaseModelOutputWithPast, BaseModelOutputWithPooling from ...modeling_rope_utils import RopeParameters from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, slice_logits_to_keep -from ...processing_utils import MultiModalData, ProcessingKwargs, Unpack, VideosKwargs +from ...processing_utils import ProcessingKwargs, Unpack, VideosKwargs from ...utils import auto_docstring, is_torchvision_available, logging from ...utils.generic import ( merge_with_config_defaults, @@ -906,8 +906,6 @@ class Qwen3VLProcessorKwargs(ProcessingKwargs, total=False): class Qwen3VLProcessor(Qwen2VLProcessor): - valid_processor_kwargs = Qwen3VLProcessorKwargs - def __init__(self, image_processor=None, tokenizer=None, video_processor=None, chat_template=None, **kwargs): super().__init__(image_processor, tokenizer, video_processor, chat_template, **kwargs) self.vision_start_token = ( @@ -968,44 +966,6 @@ def _calculate_timestamps(self, indices: list[int] | np.ndarray, video_fps: floa ] return timestamps - def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): - """ - Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. - Args: - image_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (height, width) per each image. - video_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (num_frames, height, width) per each video. - Returns: - `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided - input modalities, along with other useful data. - """ - - vision_data = {} - if image_sizes is not None: - images_kwargs = Qwen3VLProcessorKwargs._defaults.get("images_kwargs", {}) - images_kwargs.update(kwargs) - merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size - - num_image_patches = [ - self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) - for image_size in image_sizes - ] - num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] - vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) - - if video_sizes is not None: - videos_kwargs = Qwen3VLProcessorKwargs._defaults.get("videos_kwargs", {}) - videos_kwargs.update(kwargs) - merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size - num_video_patches = [ - self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes - ] - num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] - vision_data["num_video_tokens"] = num_video_tokens - - return MultiModalData(**vision_data) - class Qwen3VLVideoProcessorInitKwargs(VideosKwargs, total=False): r""" @@ -1055,7 +1015,6 @@ class Qwen3VLVideoProcessor(Qwen2VLVideoProcessor): fps = 2 cap_pixels_per_frame = None max_video_tokens = 768 - valid_kwargs = Qwen3VLVideoProcessorInitKwargs def __init__(self, **kwargs: Unpack[Qwen3VLVideoProcessorInitKwargs]): BaseVideoProcessor.__init__(self, **kwargs) diff --git a/src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py b/src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py index 3e1a94f1ca85..58e618b90564 100644 --- a/src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py +++ b/src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py @@ -156,7 +156,11 @@ class Qwen3VLMoeConfig(Qwen3VLConfig): >>> configuration = model.config ```""" - pass + model_type = "qwen3_vl_moe" + sub_configs_defaults = { + "vision_config": Qwen3VLMoeVisionConfig, + "text_config": Qwen3VLMoeTextConfig, + } class Qwen3VLMoeTextRMSNorm(Qwen3MoeRMSNorm): @@ -187,7 +191,10 @@ def forward(self, hidden_states): class Qwen3VLMoeTextSparseMoeBlock(Qwen3MoeSparseMoeBlock): - pass + def __init__(self, config: Qwen3VLMoeTextConfig): + super().__init__(config) + self.experts = Qwen3VLMoeTextExperts(config) + self.gate = Qwen3VLMoeTextTopKRouter(config) class Qwen3VLMoeTextAttention(Qwen3VLTextAttention): @@ -195,13 +202,20 @@ class Qwen3VLMoeTextAttention(Qwen3VLTextAttention): class Qwen3VLMoeTextDecoderLayer(Qwen3MoeDecoderLayer): - pass + def __init__(self, config: Qwen3VLMoeTextConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = Qwen3VLMoeTextAttention(config, layer_idx) class Qwen3VLMoePreTrainedModel(Qwen3MoePreTrainedModel): config: Qwen3VLMoeConfig input_modalities = ("text", "image", "video") _no_split_modules = ["Qwen3VLMoeTextDecoderLayer", "Qwen3VLMoeVisionBlock"] + _can_record_outputs = { + "router_logits": OutputRecorder(Qwen3VLMoeTextTopKRouter, index=0), + "hidden_states": Qwen3VLMoeTextDecoderLayer, + "attentions": Qwen3VLMoeTextAttention, + } @torch.no_grad() def _init_weights(self, module): @@ -239,6 +253,12 @@ class Qwen3VLMoeVisionModel(Qwen3VLVisionModel): class Qwen3VLMoeTextModel(Qwen3VLTextModel): + def __init__(self, config: Qwen3VLMoeTextConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [Qwen3VLMoeTextDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) + def forward( self, input_ids: torch.LongTensor | None = None, diff --git a/src/transformers/models/rf_detr/modular_rf_detr.py b/src/transformers/models/rf_detr/modular_rf_detr.py index b229433a00b2..eef7e45d1b1d 100644 --- a/src/transformers/models/rf_detr/modular_rf_detr.py +++ b/src/transformers/models/rf_detr/modular_rf_detr.py @@ -11,6 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import math import pathlib from dataclasses import dataclass from typing import Any @@ -44,6 +45,7 @@ validate_annotations, ) from ...modeling_outputs import BackboneOutput, BaseModelOutput +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import ( TensorType, @@ -62,20 +64,24 @@ ) from ..dinov2.configuration_dinov2 import Dinov2Config from ..dinov2.modeling_dinov2 import ( + Dinov2Attention, Dinov2Backbone, Dinov2Embeddings, Dinov2Encoder, Dinov2Layer, + Dinov2LayerScale, Dinov2PreTrainedModel, ) from ..lw_detr.configuration_lw_detr import LwDetrConfig from ..lw_detr.modeling_lw_detr import ( + LwDetrAttention, LwDetrC2FLayer, LwDetrConvEncoder, LwDetrConvNormLayer, LwDetrForObjectDetection, LwDetrLayerNorm, LwDetrModel, + LwDetrMultiscaleDeformableAttention, LwDetrObjectDetectionOutput, LwDetrPreTrainedModel, refine_bboxes, @@ -653,6 +659,14 @@ def forward(self, pixel_values: torch.Tensor, bool_masked_pos: torch.Tensor | No return embeddings +class RfDetrDinov2Attention(Dinov2Attention): + pass + + +class RfDetrDinov2LayerScale(Dinov2LayerScale): + pass + + class RfDetrDinov2Layer(Dinov2Layer): def __init__(self, config: RfDetrDinov2Config, layer_idx: int): super().__init__(config) @@ -721,7 +735,27 @@ def forward( class RfDetrDinov2PreTrainedModel(Dinov2PreTrainedModel): - pass + _can_record_outputs = { + "hidden_states": RfDetrDinov2Layer, + "attentions": RfDetrDinov2Attention, + } + + @torch.no_grad() + def _init_weights(self, module) -> None: + """Initialize the weights""" + PreTrainedModel._init_weights(self, module) + if isinstance(module, RfDetrDinov2Embeddings): + if module.position_embeddings is not None: + init.trunc_normal_(module.position_embeddings, mean=0.0, std=self.config.initializer_range) + init.trunc_normal_(module.cls_token, mean=0.0, std=self.config.initializer_range) + if module.mask_token is not None: + init.zeros_(module.mask_token) + if isinstance(module, (nn.Linear, nn.Conv2d)): + init.trunc_normal_(module.weight, mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + init.zeros_(module.bias) + if isinstance(module, RfDetrDinov2LayerScale): + init.constant_(module.lambda1, self.config.layerscale_value) class RfDetrDinov2Encoder(Dinov2Encoder): @@ -731,6 +765,11 @@ def __init__(self, config: RfDetrDinov2Config): class RfDetrDinov2Backbone(Dinov2Backbone): + def __init__(self, config: RfDetrDinov2Config): + super().__init__(config) + self.embeddings = RfDetrDinov2Embeddings(config) + self.encoder = RfDetrDinov2Encoder(config) + def window_unpartition(self, hidden_state: torch.Tensor, height: int, width: int) -> torch.Tensor: """ Reassembles windowed patch tokens into their original 2D patch layout (image-level grid structure) @@ -848,7 +887,18 @@ def __init__( class RfDetrC2FLayer(LwDetrC2FLayer): - pass + # Inspired by RTDetrCSPRepLayer + def __init__(self, config: RfDetrConfig, in_channels: int): + super().__init__(config, in_channels) + num_blocks = config.c2f_num_blocks + activation = config.activation_function + out_channels = config.d_model + + conv1_out_channels = 2 * self.hidden_channels + self.conv1 = RfDetrConvNormLayer(config, in_channels, conv1_out_channels, 1, 1, activation=activation) + + conv2_in_channels = (2 + num_blocks) * self.hidden_channels + self.conv2 = RfDetrConvNormLayer(config, conv2_in_channels, out_channels, 1, 1, activation=activation) class RfDetrScaleProjector(nn.Module): @@ -879,13 +929,56 @@ def forward(self, pixel_values: torch.Tensor, pixel_mask: torch.Tensor): return features, mask +class RfDetrAttention(LwDetrAttention): + pass + + +class RfDetrMultiscaleDeformableAttention(LwDetrMultiscaleDeformableAttention): + pass + + class RfDetrPreTrainedModel(LwDetrPreTrainedModel): # Roboflow checkpoints use bare keys with no top-level prefix _checkpoint_conversion_prefix_free = True @torch.no_grad() def _init_weights(self, module): - super()._init_weights(module) + PreTrainedModel._init_weights(self, module) + + if isinstance(module, RfDetrMultiscaleDeformableAttention): + init.constant_(module.sampling_offsets.weight, 0.0) + thetas = torch.arange(module.n_heads, dtype=torch.int64).float() * (2.0 * math.pi / module.n_heads) + grid_init = torch.stack([thetas.cos(), thetas.sin()], -1) + grid_init = ( + (grid_init / grid_init.abs().max(-1, keepdim=True)[0]) + .view(module.n_heads, 1, 1, 2) + .repeat(1, module.n_levels, module.n_points, 1) + ) + for i in range(module.n_points): + grid_init[:, :, i, :] *= i + 1 + + init.copy_(module.sampling_offsets.bias, grid_init.view(-1)) + init.constant_(module.attention_weights.weight, 0.0) + init.constant_(module.attention_weights.bias, 0.0) + init.xavier_uniform_(module.value_proj.weight) + init.constant_(module.value_proj.bias, 0.0) + init.xavier_uniform_(module.output_proj.weight) + init.constant_(module.output_proj.bias, 0.0) + if hasattr(module, "level_embed"): + init.normal_(module.level_embed) + if hasattr(module, "refpoint_embed") and module.refpoint_embed is not None: + init.constant_(module.refpoint_embed.weight, 0) + if hasattr(module, "class_embed") and module.class_embed is not None: + init.constant_(module.class_embed.bias, -math.log(99)) + if hasattr(module, "bbox_embed") and module.bbox_embed is not None: + init.constant_(module.bbox_embed.layers[-1].weight, 0) + init.constant_(module.bbox_embed.layers[-1].bias, 0) + # The original deep-copies the initialized `class_embed` / `bbox_embed` into the encoder heads + if isinstance(module, RfDetrModel): + for class_head, bbox_head in zip(module.enc_out_class_embed, module.enc_out_bbox_embed): + init.constant_(class_head.bias, -math.log(99)) + init.zeros_(bbox_head.layers[-1].weight) + init.zeros_(bbox_head.layers[-1].bias) if hasattr(module, "segmentation_bias") and isinstance(module.segmentation_bias, nn.Parameter): init.constant_(module.segmentation_bias, 0.0) @@ -931,6 +1024,9 @@ def __init__(self, config: RfDetrConfig): super().__init__(config) self.d_model = config.d_model + # Create backbone + positional encoding + self.backbone = RfDetrConvEncoder(config) + def generate_topk_proposals( self, group_id: int, object_query_embedding: Tensor, output_proposals: Tensor, invalid_mask: Tensor, topk: int ) -> tuple[Tensor, Tensor, Tensor]: @@ -1146,6 +1242,10 @@ class RfDetrObjectDetectionOutput(LwDetrObjectDetectionOutput): class RfDetrForObjectDetection(LwDetrForObjectDetection): + def __init__(self, config: RfDetrConfig): + super().__init__(config) + self.model = RfDetrModel(config) + def predict_encoder_class_logits(self, enc_outputs_class: torch.Tensor) -> Tensor: """ Predicts classification logits from encoder hidden states for each query group. diff --git a/src/transformers/models/rt_detr_v2/modular_rt_detr_v2.py b/src/transformers/models/rt_detr_v2/modular_rt_detr_v2.py index c48a34c8275e..0e09d74cb52e 100644 --- a/src/transformers/models/rt_detr_v2/modular_rt_detr_v2.py +++ b/src/transformers/models/rt_detr_v2/modular_rt_detr_v2.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import copy +import math import warnings import torch @@ -22,6 +23,7 @@ from ... import initialization as init from ...configuration_utils import PreTrainedConfig, SubConfigSpec +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, logging, torch_compilable_check from ..auto import AutoConfig @@ -29,9 +31,11 @@ RTDetrDecoder, RTDetrDecoderLayer, RTDetrForObjectDetection, + RTDetrMLP, RTDetrMLPPredictionHead, RTDetrModel, RTDetrPreTrainedModel, + RTDetrSelfAttention, ) @@ -391,6 +395,14 @@ def forward( return output, attention_weights +class RTDetrV2MLP(RTDetrMLP): + pass + + +class RTDetrV2SelfAttention(RTDetrSelfAttention): + pass + + class RTDetrV2DecoderLayer(RTDetrDecoderLayer): def __init__(self, config: RTDetrV2Config): # initialize parent class @@ -400,14 +412,77 @@ def __init__(self, config: RTDetrV2Config): class RTDetrV2PreTrainedModel(RTDetrPreTrainedModel): + @torch.no_grad() def _init_weights(self, module): - super()._init_weights(module) + """Initialize the weights""" + PreTrainedModel._init_weights(self, module) + if isinstance(module, RTDetrV2ForObjectDetection): + if module.model.decoder.class_embed is not None: + for layer in module.model.decoder.class_embed: + prior_prob = self.config.initializer_bias_prior_prob or 1 / (self.config.num_labels + 1) + bias = float(-math.log((1 - prior_prob) / prior_prob)) + init.xavier_uniform_(layer.weight) + init.constant_(layer.bias, bias) + + if module.model.decoder.bbox_embed is not None: + for layer in module.model.decoder.bbox_embed: + init.constant_(layer.layers[-1].weight, 0) + init.constant_(layer.layers[-1].bias, 0) + + elif isinstance(module, RTDetrV2MultiscaleDeformableAttention): + init.constant_(module.sampling_offsets.weight, 0.0) + default_dtype = torch.get_default_dtype() + thetas = torch.arange(module.n_heads, dtype=torch.int64).to(default_dtype) * ( + 2.0 * math.pi / module.n_heads + ) + grid_init = torch.stack([thetas.cos(), thetas.sin()], -1) + grid_init = ( + (grid_init / grid_init.abs().max(-1, keepdim=True)[0]) + .view(module.n_heads, 1, 1, 2) + .repeat(1, module.n_levels, module.n_points, 1) + ) + for i in range(module.n_points): + grid_init[:, :, i, :] *= i + 1 + + init.copy_(module.sampling_offsets.bias, grid_init.view(-1)) + init.constant_(module.attention_weights.weight, 0.0) + init.constant_(module.attention_weights.bias, 0.0) + init.xavier_uniform_(module.value_proj.weight) + init.constant_(module.value_proj.bias, 0.0) + init.xavier_uniform_(module.output_proj.weight) + init.constant_(module.output_proj.bias, 0.0) + + elif isinstance(module, RTDetrV2Model): + prior_prob = self.config.initializer_bias_prior_prob or 1 / (self.config.num_labels + 1) + bias = float(-math.log((1 - prior_prob) / prior_prob)) + init.xavier_uniform_(module.enc_score_head.weight) + init.constant_(module.enc_score_head.bias, bias) + + elif isinstance(module, nn.BatchNorm2d): + init.normal_(module.weight, mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + init.zeros_(module.bias) + if getattr(module, "running_mean", None) is not None: + init.zeros_(module.running_mean) + init.ones_(module.running_var) + init.zeros_(module.num_batches_tracked) + + if hasattr(module, "weight_embedding") and self.config.learn_initial_query: + init.xavier_uniform_(module.weight_embedding.weight) + if hasattr(module, "denoising_class_embed") and self.config.num_denoising > 0: + init.xavier_uniform_(module.denoising_class_embed.weight) if isinstance(module, RTDetrV2MultiscaleDeformableAttention): n_points_scale = [1 / n for n in module.n_points_list for _ in range(n)] init.copy_(module.n_points_scale, torch.tensor(n_points_scale, dtype=torch.float32)) class RTDetrV2Decoder(RTDetrDecoder): + _can_record_outputs = { + "hidden_states": RTDetrV2DecoderLayer, + "attentions": RTDetrV2SelfAttention, + "cross_attentions": RTDetrV2MultiscaleDeformableAttention, + } + def __init__(self, config: RTDetrV2Config): super().__init__(config) self.layers = nn.ModuleList([RTDetrV2DecoderLayer(config) for _ in range(config.decoder_layers)]) diff --git a/src/transformers/models/sam_hq/modular_sam_hq.py b/src/transformers/models/sam_hq/modular_sam_hq.py index f94a154910f9..7385eceb7736 100644 --- a/src/transformers/models/sam_hq/modular_sam_hq.py +++ b/src/transformers/models/sam_hq/modular_sam_hq.py @@ -18,6 +18,8 @@ from huggingface_hub.dataclasses import strict from torch import nn +from ... import initialization as init +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import auto_docstring, logging from ...utils.generic import ModelOutput, TransformersKwargs, merge_with_config_defaults @@ -28,6 +30,7 @@ SamImageSegmentationOutput, SamLayerNorm, SamModel, + SamPositionalEmbedding, SamPreTrainedModel, SamTwoWayTransformer, SamVisionAttention, @@ -84,6 +87,13 @@ class SamHQConfig(SamConfig): Dictionary of configuration options used to initialize [`SamHQMaskDecoderConfig`]. """ + model_type = "sam_hq" + sub_configs_defaults = { + "prompt_encoder_config": SamHQPromptEncoderConfig, + "mask_decoder_config": SamHQMaskDecoderConfig, + "vision_config": SamHQVisionConfig, + } + class SamHQVisionEncoderOutput(SamVisionEncoderOutput): r""" @@ -127,10 +137,25 @@ class SamHQVisionLayer(SamVisionLayer): pass -class SamHQPreTrainedModel(SamPreTrainedModel): +class SamHQPositionalEmbedding(SamPositionalEmbedding): pass +class SamHQPreTrainedModel(SamPreTrainedModel): + @torch.no_grad() + def _init_weights(self, module: nn.Module): + PreTrainedModel._init_weights(self, module) + if isinstance(module, SamHQVisionAttention): + if module.use_rel_pos: + init.zeros_(module.rel_pos_h) + init.zeros_(module.rel_pos_w) + elif isinstance(module, SamHQVisionEncoder): + if self.config.use_abs_pos: + init.zeros_(module.pos_embed) + elif isinstance(module, SamHQPositionalEmbedding): + init.normal_(module.positional_embedding, std=module.scale) + + class SamHQVisionEncoder(SamVisionEncoder, SamHQPreTrainedModel): _can_record_outputs = { "hidden_states": SamHQVisionLayer, @@ -380,7 +405,9 @@ def forward( class SamHQVisionModel(SamVisionModel): - pass + def __init__(self, config: SamHQVisionConfig): + super().__init__(config) + self.vision_encoder = SamHQVisionEncoder(config) @auto_docstring( diff --git a/src/transformers/models/siglip2/modular_siglip2.py b/src/transformers/models/siglip2/modular_siglip2.py index ea19249fe47d..3a7ed0520fd7 100644 --- a/src/transformers/models/siglip2/modular_siglip2.py +++ b/src/transformers/models/siglip2/modular_siglip2.py @@ -13,6 +13,7 @@ # limitations under the License. +import numpy as np import torch import torch.nn as nn import torch.nn.functional as F @@ -36,7 +37,9 @@ SiglipVisionModelOutput, ) +from ... import initialization as init from ...masking_utils import create_bidirectional_mask +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import ( TransformersKwargs, @@ -45,6 +48,7 @@ ) from ...utils.generic import can_return_tuple, merge_with_config_defaults from ...utils.output_capturing import capture_outputs +from ..siglip.modeling_siglip import SiglipAttention, SiglipMLP, SiglipTextEmbeddings class Siglip2Tokenizer(GemmaTokenizer): @@ -121,7 +125,10 @@ class Siglip2VisionConfig(SiglipVisionConfig): @auto_docstring(checkpoint="google/siglip2-base-patch16-naflex") @strict class Siglip2Config(SiglipConfig): - pass + sub_configs_defaults = { + "vision_config": Siglip2VisionConfig, + "text_config": Siglip2TextConfig, + } class Siglip2VisionOutput(SiglipVisionModelOutput): @@ -240,16 +247,80 @@ def forward(self, pixel_values: torch.FloatTensor, spatial_shapes: torch.LongTen return embeddings +class Siglip2TextEmbeddings(SiglipTextEmbeddings): + pass + + +class Siglip2Attention(SiglipAttention): + pass + + +class Siglip2MLP(SiglipMLP): + pass + + class Siglip2PreTrainedModel(SiglipPreTrainedModel): # nn.MultiHeadAttention mask doesn't allow for non 4d mask _supports_flex_attn = False _supports_flash_attn = False + @torch.no_grad() + def _init_weights(self, module): + """Initialize the weights""" + PreTrainedModel._init_weights(self, module) + if isinstance(module, Siglip2VisionEmbeddings): + width = ( + self.config.vision_config.hidden_size + if isinstance(self.config, Siglip2Config) + else self.config.hidden_size + ) + init.normal_(module.position_embedding.weight, std=1 / np.sqrt(width)) + if hasattr(module, "position_ids"): + init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1))) + elif isinstance(module, nn.Embedding): + init.default_flax_embed_init_(module.weight) + elif isinstance(module, Siglip2Attention): + init.xavier_uniform_(module.q_proj.weight) + init.xavier_uniform_(module.k_proj.weight) + init.xavier_uniform_(module.v_proj.weight) + init.xavier_uniform_(module.out_proj.weight) + init.zeros_(module.q_proj.bias) + init.zeros_(module.k_proj.bias) + init.zeros_(module.v_proj.bias) + init.zeros_(module.out_proj.bias) + elif isinstance(module, Siglip2MLP): + init.xavier_uniform_(module.fc1.weight) + init.xavier_uniform_(module.fc2.weight) + init.normal_(module.fc1.bias, std=1e-6) + init.normal_(module.fc2.bias, std=1e-6) + elif isinstance(module, Siglip2MultiheadAttentionPoolingHead): + init.xavier_uniform_(module.probe) + init.xavier_uniform_(module.attention.in_proj_weight) + init.zeros_(module.attention.in_proj_bias) + elif isinstance(module, Siglip2Model): + init.zeros_(module.logit_scale) + init.zeros_(module.logit_bias) + elif isinstance(module, Siglip2ForImageClassification): + init.normal_( + module.classifier.weight, + std=self.config.vision_config.hidden_size**-0.5 * self.config.initializer_factor, + ) + elif isinstance(module, (nn.Linear, nn.Conv2d)): + init.lecun_normal_(module.weight) + if module.bias is not None: + init.zeros_(module.bias) + elif isinstance(module, Siglip2TextEmbeddings): + init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1))) + class Siglip2VisionModel(SiglipVisionModel): def __init__(self, config: Siglip2VisionConfig): super().__init__(config) + self.embeddings = Siglip2VisionEmbeddings(config) + if self.use_head: + self.head = Siglip2MultiheadAttentionPoolingHead(config) + @merge_with_config_defaults @capture_outputs(tie_last_hidden_states=False) @auto_docstring @@ -358,6 +429,11 @@ def forward(self, hidden_state: torch.Tensor, attention_mask: torch.Tensor | Non class Siglip2Model(SiglipModel): + def __init__(self, config: Siglip2Config): + super().__init__(config) + vision_config = config.vision_config + self.vision_model = Siglip2VisionModel._from_config(vision_config) + # Update: add `spatial_shapes` and `pixel_attention_mask` @can_return_tuple @auto_docstring @@ -501,6 +577,10 @@ def forward( class Siglip2ForImageClassification(SiglipForImageClassification): + def __init__(self, config: Siglip2Config) -> None: + super().__init__(config) + self.vision_model = Siglip2VisionModel._from_config(config.vision_config) + # Update: add `spatial_shapes` and `pixel_attention_mask` @can_return_tuple @auto_docstring diff --git a/src/transformers/models/smolvlm/modular_smolvlm.py b/src/transformers/models/smolvlm/modular_smolvlm.py index 25814f97f752..77f9c39f044e 100644 --- a/src/transformers/models/smolvlm/modular_smolvlm.py +++ b/src/transformers/models/smolvlm/modular_smolvlm.py @@ -19,12 +19,14 @@ from torch import nn from ...cache_utils import Cache, DynamicCache +from ...configuration_utils import SubConfigSpec from ...generation import GenerationConfig from ...modeling_flash_attention_utils import FlashAttentionKwargs from ...modeling_outputs import BaseModelOutputWithPooling from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging, torch_compilable_check from ...utils.generic import merge_with_config_defaults +from ..auto import AutoConfig from ..idefics3.configuration_idefics3 import Idefics3Config, Idefics3VisionConfig from ..idefics3.image_processing_idefics3 import Idefics3ImageProcessor from ..idefics3.image_processing_pil_idefics3 import Idefics3ImageProcessorPil @@ -87,6 +89,12 @@ class SmolVLMConfig(Idefics3Config): >>> configuration = model.config ```""" + model_type = "smolvlm" + sub_configs_defaults = { + "text_config": SubConfigSpec(config_class=AutoConfig, model_type="llama", init_kwargs={"rms_norm_eps": 1e-5}), + "vision_config": SmolVLMVisionConfig, + } + class SmolVLMImageProcessor(Idefics3ImageProcessor): pass diff --git a/src/transformers/models/solar_open/modular_solar_open.py b/src/transformers/models/solar_open/modular_solar_open.py index 74236a466411..294c86d5c68d 100644 --- a/src/transformers/models/solar_open/modular_solar_open.py +++ b/src/transformers/models/solar_open/modular_solar_open.py @@ -17,13 +17,16 @@ from torch import nn from ...utils import auto_docstring, logging +from ...utils.output_capturing import OutputRecorder from ..glm4_moe.configuration_glm4_moe import Glm4MoeConfig from ..glm4_moe.modeling_glm4_moe import ( Glm4MoeForCausalLM, + Glm4MoeMLP, Glm4MoeModel, Glm4MoeMoE, Glm4MoePreTrainedModel, Glm4MoeRMSNorm, + Glm4MoeTopkRouter, ) from ..llama.modeling_llama import LlamaAttention, LlamaDecoderLayer @@ -74,9 +77,19 @@ def __post_init__(self, **kwargs): class SolarOpenDecoderLayer(LlamaDecoderLayer): def __init__(self, config: SolarOpenConfig, layer_idx: int): super().__init__(config, layer_idx) + + self.self_attn = SolarOpenAttention(config=config, layer_idx=layer_idx) self.mlp = SolarOpenMoE(config) +class SolarOpenMLP(Glm4MoeMLP): + pass + + +class SolarOpenTopkRouter(Glm4MoeTopkRouter): + pass + + class SolarOpenMoE(Glm4MoeMoE): pass @@ -92,11 +105,20 @@ class SolarOpenRMSNorm(Glm4MoeRMSNorm): class SolarOpenPreTrainedModel(Glm4MoePreTrainedModel): + _can_record_outputs = { + "hidden_states": SolarOpenDecoderLayer, + "attentions": SolarOpenAttention, + "router_logits": OutputRecorder(SolarOpenTopkRouter, index=0), + } _keys_to_ignore_on_load_unexpected = None class SolarOpenModel(Glm4MoeModel): - pass + def __init__(self, config: SolarOpenConfig): + super().__init__(config) + self.layers = nn.ModuleList( + [SolarOpenDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)] + ) class SolarOpenForCausalLM(Glm4MoeForCausalLM): diff --git a/src/transformers/models/timesfm2_5/modular_timesfm2_5.py b/src/transformers/models/timesfm2_5/modular_timesfm2_5.py index 2b4dadb7d223..16aa46d5fd81 100644 --- a/src/transformers/models/timesfm2_5/modular_timesfm2_5.py +++ b/src/transformers/models/timesfm2_5/modular_timesfm2_5.py @@ -21,10 +21,11 @@ import torch.nn.functional as F from huggingface_hub.dataclasses import strict +from ... import initialization as init from ...activations import ACT2FN from ...masking_utils import create_causal_mask from ...modeling_rope_utils import RopeParameters -from ...modeling_utils import ALL_ATTENTION_FUNCTIONS +from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring, can_return_tuple, logging from ...utils.generic import merge_with_config_defaults @@ -43,6 +44,7 @@ TimesFmModelForPrediction, TimesFmOutput, TimesFmOutputForPrediction, + TimesFmPositionalEmbedding, TimesFmPreTrainedModel, TimesFmResidualBlock, ) @@ -232,6 +234,10 @@ class TimesFm2_5DecoderLayer(LlamaDecoderLayer): def __init__(self, config: TimesFm2_5Config, layer_idx: int): super().__init__(config, layer_idx) + + self.self_attn = TimesFm2_5Attention(config=config, layer_idx=layer_idx) + + self.mlp = TimesFm2_5MLP(config) self.pre_feedforward_layernorm = TimesFm2_5RMSNorm(config.hidden_size, eps=config.rms_norm_eps) self.post_feedforward_layernorm = TimesFm2_5RMSNorm(config.hidden_size, eps=config.rms_norm_eps) @@ -262,6 +268,10 @@ def forward( return hidden_states +class TimesFm2_5PositionalEmbedding(TimesFmPositionalEmbedding): + pass + + @auto_docstring class TimesFm2_5PreTrainedModel(TimesFmPreTrainedModel): config: TimesFm2_5Config @@ -274,6 +284,24 @@ class TimesFm2_5PreTrainedModel(TimesFmPreTrainedModel): "attentions": TimesFm2_5Attention, } + @torch.no_grad() + def _init_weights(self, module): + PreTrainedModel._init_weights(self, module) + if isinstance(module, TimesFm2_5Attention): + # Initialize scaling parameter + init.ones_(module.scaling) + elif isinstance(module, TimesFm2_5PositionalEmbedding): + num_timescales = module.embedding_dims // 2 + max_timescale, min_timescale = module.max_timescale, module.min_timescale + log_timescale_increment = math.log(float(max_timescale) / float(min_timescale)) / max( + num_timescales - 1, 1 + ) + init.copy_( + module.inv_timescales, + min_timescale + * torch.exp(torch.arange(num_timescales, dtype=torch.float32) * -log_timescale_increment), + ) + class TimesFm2_5Model(TimesFm2_5PreTrainedModel): def __init__(self, config: TimesFm2_5Config): diff --git a/src/transformers/models/tipsv2/modular_tipsv2.py b/src/transformers/models/tipsv2/modular_tipsv2.py index cefb541bf573..49b0fb69c09d 100644 --- a/src/transformers/models/tipsv2/modular_tipsv2.py +++ b/src/transformers/models/tipsv2/modular_tipsv2.py @@ -48,6 +48,7 @@ Dinov2WithRegistersBackbone, Dinov2WithRegistersEmbeddings, Dinov2WithRegistersEncoder, + Dinov2WithRegistersLayerScale, Dinov2WithRegistersModel, Dinov2WithRegistersPreTrainedModel, ) @@ -357,18 +358,42 @@ def interpolate_pos_encoding(self, embeddings: torch.Tensor, height: int, width: return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1) +class Tipsv2VisionLayerScale(Dinov2WithRegistersLayerScale): + pass + + class Tipsv2VisionPreTrainedModel(Dinov2WithRegistersPreTrainedModel): config: Tipsv2VisionConfig base_model_prefix = "vision_model" _no_split_modules = ["Tipsv2VisionEmbeddings", "Tipsv2VisionLayer"] _keys_to_ignore_on_load_unexpected = {"text_encoder"} + @torch.no_grad() + def _init_weights(self, module) -> None: + """Initialize the weights""" + PreTrainedModel._init_weights(self, module) + if isinstance(module, (nn.Linear, nn.Conv2d)): + init.trunc_normal_(module.weight, mean=0.0, std=self.config.initializer_range) + if module.bias is not None: + init.zeros_(module.bias) + if isinstance(module, Tipsv2VisionEmbeddings): + init.trunc_normal_(module.position_embeddings, mean=0.0, std=self.config.initializer_range) + init.trunc_normal_(module.cls_token, mean=0.0, std=self.config.initializer_range) + init.zeros_(module.mask_token) + init.zeros_(module.register_tokens) + if isinstance(module, Tipsv2VisionLayerScale): + init.constant_(module.lambda1, self.config.layerscale_value) + class Tipsv2VisionEncoder(Dinov2WithRegistersEncoder): pass class Tipsv2VisionModel(Dinov2WithRegistersModel): + def __init__(self, config: Tipsv2VisionConfig): + super().__init__(config) + self.embeddings = Tipsv2VisionEmbeddings(config) + def forward(self, **super_kwargs) -> BaseModelOutputWithPooling: r""" bool_masked_pos (`torch.BoolTensor` of shape `(batch_size, sequence_length)`): diff --git a/src/transformers/models/unlimited_ocr/modular_unlimited_ocr.py b/src/transformers/models/unlimited_ocr/modular_unlimited_ocr.py index bd1f5f5706c4..10aa9d4bca56 100644 --- a/src/transformers/models/unlimited_ocr/modular_unlimited_ocr.py +++ b/src/transformers/models/unlimited_ocr/modular_unlimited_ocr.py @@ -529,7 +529,9 @@ def __init__(self, config: UnlimitedOcrVisionEncoderConfig): class UnlimitedOcrEncoderLayer(CLIPEncoderLayer): - pass + def __init__(self, config: UnlimitedOcrVisionConfig | UnlimitedOcrTextConfig): + super().__init__(config) + self.self_attn = UnlimitedOcrAttention(config) class UnlimitedOcrVisionEmbeddings(CLIPVisionEmbeddings): @@ -613,6 +615,8 @@ class UnlimitedOcrVisionEncoder(CLIPVisionModel): def __init__(self, config: UnlimitedOcrVisionEncoderConfig): super().__init__(config) + + self.embeddings = UnlimitedOcrVisionEmbeddings(config) del self.post_layernorm @merge_with_config_defaults @@ -633,6 +637,7 @@ def forward(self, patch_embeds: torch.Tensor, **kwargs: Unpack[TransformersKwarg class UnlimitedOcrVisionModel(DeepseekOcr2VisionModel): def __init__(self, config: UnlimitedOcrVisionConfig): super().__init__(config) + self.vision_encoder = UnlimitedOcrVisionEncoder(config.encoder_config) del self.query_768_resolution del self.query_1024_resolution @@ -1137,11 +1142,15 @@ class UnlimitedOcrModel(DeepseekOcr2Model): def __init__(self, config: UnlimitedOcrConfig): super().__init__(config) + + self.vision_tower = UnlimitedOcrVisionModel(config.vision_config) self.multi_modal_projector = nn.Linear( # trf-ignore: TRF030 config.vision_config.sam_config.downsample_channels[-1] + config.vision_config.encoder_config.hidden_size, config.text_config.hidden_size, ) + + self.language_model = UnlimitedOcrTextModel(config.text_config) self.image_newline = nn.Parameter(torch.empty(config.text_config.hidden_size)) def get_image_features( diff --git a/src/transformers/models/vaultgemma/modular_vaultgemma.py b/src/transformers/models/vaultgemma/modular_vaultgemma.py index 9a4ce67c9a55..72ee83595c58 100644 --- a/src/transformers/models/vaultgemma/modular_vaultgemma.py +++ b/src/transformers/models/vaultgemma/modular_vaultgemma.py @@ -63,8 +63,9 @@ def __init__(self, config: VaultGemmaConfig, layer_idx: int): class VaultGemmaDecoderLayer(Gemma2DecoderLayer): - def __init__(self, **super_kwargs): - super().__init__(**super_kwargs) + def __init__(self, config: VaultGemmaConfig, layer_idx: int): + super().__init__(config, layer_idx) + self.self_attn = VaultGemmaAttention(config=config, layer_idx=layer_idx) del self.post_attention_layernorm del self.post_feedforward_layernorm diff --git a/src/transformers/models/video_llama_3/modular_video_llama_3.py b/src/transformers/models/video_llama_3/modular_video_llama_3.py index a6fb76a0bb01..776edda1ad81 100644 --- a/src/transformers/models/video_llama_3/modular_video_llama_3.py +++ b/src/transformers/models/video_llama_3/modular_video_llama_3.py @@ -34,7 +34,7 @@ ) from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, ModelOutput from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel -from ...processing_utils import MultiModalData, ProcessorMixin, Unpack, VideosKwargs +from ...processing_utils import ProcessorMixin, Unpack, VideosKwargs from ...utils import TensorType, auto_docstring, can_return_tuple, logging from ...utils.generic import ( get_max_seqlen, @@ -701,8 +701,6 @@ class VideoLlama3ProcessorKwargs(Qwen2VLProcessorKwargs): class VideoLlama3Processor(Qwen3VLProcessor): - valid_processor_kwargs = VideoLlama3ProcessorKwargs - def __init__(self, image_processor=None, tokenizer=None, video_processor=None, chat_template=None, **kwargs): self.image_token = "<|image_pad|>" if not hasattr(tokenizer, "image_token") else tokenizer.image_token self.video_token = "<|video_pad|>" if not hasattr(tokenizer, "video_token") else tokenizer.video_token @@ -750,44 +748,6 @@ def model_input_names(self): def _calculate_timestamps(self): raise AttributeError("VideoLlama doesn't need this method") - def _get_num_multimodal_tokens(self, image_sizes=None, video_sizes=None, **kwargs): - """ - Computes the number of placeholder tokens needed for multimodal inputs with the given sizes. - Args: - image_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (height, width) per each image. - video_sizes (`list[list[int]]`, *optional*): - The input sizes formatted as (num_frames, height, width) per each video. - Returns: - `MultiModalData`: A `MultiModalData` object holding number of tokens per each of the provided - input modalities, along with other useful data. - """ - - vision_data = {} - if image_sizes is not None: - images_kwargs = VideoLlama3ProcessorKwargs._defaults.get("images_kwargs", {}) - images_kwargs.update(kwargs) - merge_size = images_kwargs.get("merge_size", None) or self.image_processor.merge_size - - num_image_patches = [ - self.image_processor.get_number_of_image_patches(*image_size, images_kwargs) - for image_size in image_sizes - ] - num_image_tokens = [(num_patches // merge_size**2) for num_patches in num_image_patches] - vision_data.update({"num_image_tokens": num_image_tokens, "num_image_patches": num_image_patches}) - - if video_sizes is not None: - videos_kwargs = VideoLlama3ProcessorKwargs._defaults.get("videos_kwargs", {}) - videos_kwargs.update(kwargs) - merge_size = videos_kwargs.get("merge_size", None) or self.video_processor.merge_size - num_video_patches = [ - self.video_processor.get_num_of_video_patches(*video_size, videos_kwargs) for video_size in video_sizes - ] - num_video_tokens = [(num_patches // merge_size**2) for num_patches in num_video_patches] - vision_data["num_video_tokens"] = num_video_tokens - - return MultiModalData(**vision_data) - class VideoLlama3ImageProcessorKwargs(Qwen2VLImageProcessorKwargs): r""" @@ -998,9 +958,6 @@ class VideoLlama3VideoProcessor(Qwen2VLVideoProcessor): valid_kwargs = VideoLlama3VideoProcessorInitKwargs model_input_names = ["pixel_values_videos", "video_grid_thw", "video_merge_sizes", "video_compression_mask"] - def __init__(self, **kwargs: Unpack[VideoLlama3VideoProcessorInitKwargs]): - super().__init__(**kwargs) - def _get_compression_mask( self, pixel_values_videos: torch.FloatTensor, diff --git a/src/transformers/models/videomt/modular_videomt.py b/src/transformers/models/videomt/modular_videomt.py index 99f04bfbea2c..2a1206b872bc 100644 --- a/src/transformers/models/videomt/modular_videomt.py +++ b/src/transformers/models/videomt/modular_videomt.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import math from dataclasses import dataclass import torch @@ -20,6 +21,7 @@ from ... import initialization as init from ...file_utils import ModelOutput +from ...modeling_utils import PreTrainedModel from ...processing_utils import Unpack from ...utils import TransformersKwargs, auto_docstring from ..eomt.configuration_eomt import EomtConfig @@ -29,6 +31,7 @@ EomtLayer, EomtLayerNorm2d, EomtLayerScale, + EomtLoss, EomtMLP, EomtPatchEmbeddings, EomtPreTrainedModel, @@ -145,13 +148,42 @@ class VideomtForUniversalSegmentationOutput(ModelOutput): attentions: tuple[torch.FloatTensor] | None = None +class VideomtLoss(EomtLoss): + pass + + class VideomtPreTrainedModel(EomtPreTrainedModel): main_input_name = "pixel_values_videos" input_modalities = ("video",) @torch.no_grad() def _init_weights(self, module: nn.Module) -> None: - super()._init_weights(module) + PreTrainedModel._init_weights(self, module) + std = self.config.initializer_range + if isinstance(module, (nn.Linear, nn.Conv2d, nn.ConvTranspose2d)): + init.kaiming_uniform_(module.weight, a=math.sqrt(5)) + if module.bias is not None: + fan_in, _ = torch.nn.init._calculate_fan_in_and_fan_out(module.weight) + bound = 1 / math.sqrt(fan_in) if fan_in > 0 else 0 + init.uniform_(module.bias, -bound, bound) + elif isinstance(module, nn.Embedding): + init.normal_(module.weight, mean=0.0, std=1) + # Here we need the check explicitly, as we slice the weight in the `zeros_` call, so it looses the flag + if module.padding_idx is not None and not getattr(module.weight, "_is_hf_initialized", False): + init.zeros_(module.weight[module.padding_idx]) + elif isinstance(module, VideomtLayerScale): + if hasattr(module, "lambda1"): + init.constant_(module.lambda1, self.config.layerscale_value) + elif isinstance(module, VideomtEmbeddings): + init.trunc_normal_(module.cls_token, mean=0.0, std=std) + init.zeros_(module.register_tokens) + init.copy_(module.position_ids, torch.arange(module.position_ids.shape[-1]).expand((1, -1))) + elif isinstance(module, VideomtLoss): + empty_weight = torch.ones(module.num_labels + 1) + empty_weight[-1] = module.eos_coef + init.copy_(module.empty_weight, empty_weight) + elif isinstance(module, VideomtForUniversalSegmentation): + init.ones_(module.attn_mask_probs) if isinstance(module, VideomtEmbeddings): init.zeros_(module.mask_token) @@ -174,6 +206,7 @@ class VideomtForUniversalSegmentation(EomtForUniversalSegmentation): def __init__(self, config: VideomtConfig): super().__init__(config) self.query_updater = nn.Linear(config.hidden_size, config.hidden_size) + self.embeddings = VideomtEmbeddings(config) def _disable_attention_mask(attn_mask, prob, num_query_tokens, encoder_start_tokens, device): raise AttributeError("Not needed for Videomt") diff --git a/utils/modular_model_converter.py b/utils/modular_model_converter.py index a22f8ed5414b..9cb441f505db 100644 --- a/utils/modular_model_converter.py +++ b/utils/modular_model_converter.py @@ -2000,8 +2000,23 @@ def _statement_key(node: cst.CSTNode) -> str | None: return target.value if isinstance(target, cst.Name) else None +class _BehaviorNamesCollector(cst.CSTVisitor): + """Collect names used by the code, skipping type annotations (they do not change behavior).""" + + def __init__(self): + self.names = set() + + def visit_Annotation(self, node): + return False + + def visit_Name(self, node): + self.names.add(node.value) + + def _names_in(node: cst.CSTNode) -> set[str]: - return {name.value for name in m.findall(node, m.Name())} + collector = _BehaviorNamesCollector() + cst.Module(body=[node]).visit(collector) + return collector.names def find_inherited_code_mismatches( @@ -2015,7 +2030,8 @@ def find_inherited_code_mismatches( """ generated = {name: entry["node"] for body in files.values() for name, entry in body.items()} # ponytail: classes only; redefined functions are looked up in module globals, the usual modular pattern - modular_defined = set(modular_mapper.classes) + # ponytail: `*Kwargs` TypedDicts only carry processor defaults, not worth explicit overrides + modular_defined = {name for name in modular_mapper.classes if not name.endswith("Kwargs")} mismatches = [] for class_name, modular_node in modular_mapper.classes.items(): bases = [ @@ -2043,59 +2059,7 @@ def find_inherited_code_mismatches( # Modular files whose inherited code still silently uses classes they redefine. Do not add to this list: override # the inherited method instead (see `check_inherited_code_uses_parent_definitions`). INHERITANCE_MISMATCH_ALLOWLIST = { - "altclip", - "chinese_clip", - "clipseg", - "colmodernvbert", - "d_fine", - "deepseek_ocr2", - "deepseek_v32", - "deimv2", - "edgetam", - "edgetam_video", - "ernie4_5_vl_moe", - "eurobert", "falcon_mamba", - "flex_olmo", - "flint", - "gemma", - "glm4_moe", - "glm4_moe_lite", - "glm4v_moe", - "glm5_next", - "glm_image", - "glm_moe_dsa", - "gradium_phonon_tts", - "granite_speech_plus", - "granitemoehybrid", - "granitemoeshared", - "higgs_audio_v2", - "instructblipvideo", - "jais2", - "mellum", - "metaclip_2", - "minimax_m2", - "moonshine", - "nomic_bert", - "owlv2", - "paddleocr_vl", - "pocket_tts", - "pp_doclayout_v2", - "qwen2_5_omni", - "qwen3_asr", - "qwen3_omni_moe", - "qwen3_vl_moe", - "rf_detr", - "rt_detr_v2", - "sam_hq", - "siglip2", - "smolvlm", - "solar_open", - "timesfm2_5", - "tipsv2", - "unlimited_ocr", - "vaultgemma", - "videomt", } From 052afe517c799fcc70e11be59b56f191597e6899 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 31 Oct 2026 11:54:13 +0900 Subject: [PATCH 6/7] [modular] unpack classes whose parent is defined earlier in the same modular file --- docs/source/en/modular_transformers.md | 16 +++++ .../modeling_granite_speech5.py | 15 ++++- .../qwen3_omni_moe/modeling_qwen3_omni_moe.py | 65 ++++++++++++++++++- .../modular/test_same_file_unpack.py | 43 ++++++++++++ utils/modular_model_converter.py | 50 ++++++++++++-- 5 files changed, 180 insertions(+), 9 deletions(-) create mode 100644 tests/repo_utils/modular/test_same_file_unpack.py diff --git a/docs/source/en/modular_transformers.md b/docs/source/en/modular_transformers.md index 8eccf2c29d3c..5db3e3d015a5 100644 --- a/docs/source/en/modular_transformers.md +++ b/docs/source/en/modular_transformers.md @@ -389,6 +389,22 @@ class GemmaTokenizer(LlamaTokenizer): raise AttributeError("Not needed for Gemma") ``` +### Inheriting from a class in the same modular file + +A modeling block inheriting from a class defined earlier in the same modular file is unpacked like a cross-model parent, from the parent's generated code. `super()` calls, `del`, and `AttributeError` work the same, and chains work too. Below, `MyModelKVSharedAttention` is generated as a standalone `nn.Module` without `k_proj`. + +```py +class MyModelAttention(LlamaAttention): + ... + +class MyModelKVSharedAttention(MyModelAttention): + def __init__(self, config, layer_idx): + super().__init__(config, layer_idx) + del self.k_proj +``` + +`PreTrainedModel` subclasses, configs, processors and thin `*args` wrappers (such as deprecated aliases) keep regular inheritance. + ### Overriding decorated methods When you override a decorated parent method, the parent's decorator carries over automatically. If you add your own decorator, it replaces the parent's. diff --git a/src/transformers/models/granite_speech5/modeling_granite_speech5.py b/src/transformers/models/granite_speech5/modeling_granite_speech5.py index e7398ad26fc6..893c89a92f1d 100644 --- a/src/transformers/models/granite_speech5/modeling_granite_speech5.py +++ b/src/transformers/models/granite_speech5/modeling_granite_speech5.py @@ -264,12 +264,23 @@ def forward( return hidden_states -class GraniteSpeech5EncoderSubsamplingBlock(GraniteSpeech5EncoderBlock): +class GraniteSpeech5EncoderSubsamplingBlock(GradientCheckpointingLayer): """Conformer block that subsamples time by 2""" def __init__(self, config: GraniteSpeech5EncoderConfig, layer_idx: int | None = None): - super().__init__(config, layer_idx) + super().__init__() + self.gradient_checkpointing = False + + self.feed_forward1 = GraniteSpeech5EncoderFeedForward(config) + self.self_attn = GraniteSpeech5EncoderAttention(config, layer_idx) self.conv = GraniteSpeech5EncoderConvolutionModule(config, stride=2) + self.feed_forward2 = GraniteSpeech5EncoderFeedForward(config) + + self.norm_feed_forward1 = nn.LayerNorm(config.hidden_size) + self.norm_self_att = nn.LayerNorm(config.hidden_size) + self.norm_conv = nn.LayerNorm(config.hidden_size) + self.norm_feed_forward2 = nn.LayerNorm(config.hidden_size) + self.norm_out = nn.LayerNorm(config.hidden_size) def forward( self, diff --git a/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py b/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py index 750b84994111..4837a32a4e6b 100644 --- a/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py +++ b/src/transformers/models/qwen3_omni_moe/modeling_qwen3_omni_moe.py @@ -2802,8 +2802,69 @@ class Qwen3OmniMoeTalkerOutputWithPast(MoeCausalLMOutputWithPast): generation_step: int | None = None -class Qwen3OmniMoeTalkerRotaryEmbedding(Qwen3OmniMoeThinkerTextRotaryEmbedding): - pass +class Qwen3OmniMoeTalkerRotaryEmbedding(nn.Module): + def __init__(self, config: Qwen3OmniMoeTextConfig): + super().__init__() + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + + self.rope_type = self.config.rope_parameters["rope_type"] + rope_init_fn: Callable = self.compute_default_rope_parameters + if self.rope_type != "default": + rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + inv_freq, self.attention_scaling = rope_init_fn(self.config) + + self.inv_freq = nn.Buffer(inv_freq, persistent=False) + self.original_inv_freq = nn.Buffer(inv_freq.clone(), persistent=False) + self.mrope_section = config.rope_parameters.get("mrope_section", [24, 20, 20]) + + @staticmethod + def compute_default_rope_parameters( + config: Qwen3OmniMoeTextConfig, device=None, **kwargs + ) -> tuple[torch.Tensor, float]: + """ + Computes the inverse frequencies according to the original RoPE implementation + Args: + config ([`~transformers.PreTrainedConfig`]): + The model configuration. + Returns: + Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the + post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE). + """ + base = config.rope_parameters["rope_theta"] + dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads + + attention_factor = 1.0 # Unused in this type of RoPE + # Compute the inverse frequencies + inv_freq = 1.0 / (base ** (torch.arange(0, dim, 2, dtype=torch.float) / dim)) + return inv_freq, attention_factor + + @torch.no_grad() + @dynamic_rope_update + def forward(self, x, position_ids): + # In contrast to other models, Qwen3OmniMoeThinkerText has different position ids for the grids + # So position_ids is broadcast to (3, bs, positions) and freqs has shape (3, bs, positions, dim // 2) + position_ids = position_ids.expand(3, -1, -1) + freqs = position_ids[..., None].float() * self.inv_freq.to(device=x.device, dtype=torch.float) + cos = freqs.cos() * self.attention_scaling + sin = freqs.sin() * self.attention_scaling + + sin = self.recomposition_frequencies(sin) + cos = self.recomposition_frequencies(cos) + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + def recomposition_frequencies(self, freq): + """ + Recompose the frequencies into the final spatial layout used per each grid. + """ + freqs_thw = freq[0] # just overwrite the first dimension T + for dim, offset in enumerate((1, 2), start=1): # H, W + length = self.mrope_section[dim] * 3 + idx = slice(offset, length, 3) + freqs_thw[..., idx] = freq[dim, ..., idx] + return torch.cat((freqs_thw, freqs_thw), dim=-1) class Qwen3OmniMoeTalkerTextMLP(nn.Module): diff --git a/tests/repo_utils/modular/test_same_file_unpack.py b/tests/repo_utils/modular/test_same_file_unpack.py new file mode 100644 index 000000000000..817f429bcf1a --- /dev/null +++ b/tests/repo_utils/modular/test_same_file_unpack.py @@ -0,0 +1,43 @@ +import os +import sys +import unittest + +import libcst as cst + + +ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) +sys.path.append(os.path.join(ROOT_DIR, "utils")) + +from modular_model_converter import ModularFileMapper, create_modules # noqa: E402 + + +MODULAR_CODE = """ +from ..llama.modeling_llama import LlamaAttention + + +class DummyAttention(LlamaAttention): + def __init__(self, config, layer_idx): + super().__init__(config, layer_idx) + self.foo = 1 + + +class DummyKVSharedAttention(DummyAttention): + def __init__(self, config, layer_idx): + super().__init__(config, layer_idx) + del self.k_proj +""" + + +class SameFileUnpackTest(unittest.TestCase): + def test_same_file_parent_is_unpacked(self): + module = cst.parse_module(MODULAR_CODE) + mapper = ModularFileMapper(module, "dummy", "transformers") + module.visit(mapper) + code = create_modules(mapper)["modeling"].code + child = code[code.index("class DummyKVSharedAttention") :] + + self.assertTrue(child.startswith("class DummyKVSharedAttention(nn.Module):")) + self.assertIn("self.foo = 1", child) + self.assertIn("def forward(", child) + self.assertNotIn("self.k_proj =", child) + self.assertNotIn("del self.k_proj", child) diff --git a/utils/modular_model_converter.py b/utils/modular_model_converter.py index 9cb441f505db..8db9bb0cf5b6 100644 --- a/utils/modular_model_converter.py +++ b/utils/modular_model_converter.py @@ -985,7 +985,11 @@ def get_decorators_to_keep( def replace_class_node( - mapper: ModelFileMapper, modular_class_node: cst.ClassDef, renamed_super_class: str, original_super_class: str + mapper: ModuleMapper, + modular_class_node: cst.ClassDef, + renamed_super_class: str, + original_super_class: str, + original_modeling_node: cst.ClassDef | None = None, ) -> cst.ClassDef: """ Replace a class node which inherits from another modeling class. This function works in the following way: @@ -1004,6 +1008,9 @@ def replace_class_node( The name of the class from which `modular_class_node` inherits after automatic renaming. original_super_class (`str`): The name of the class from which `modular_class_node` inherits before automatic renaming. + original_modeling_node (`cst.ClassDef`, *optional*): + The already unpacked parent node, when the parent is defined in the same modular file. In this case, no + renaming happens as both classes already share the same model name. Returns: A new class node corresponding to the modular definition. @@ -1012,12 +1019,14 @@ def replace_class_node( if any(base is None for base in all_new_bases.keys()): raise ValueError(f"Could not parse the name of the bases for {modular_class_node.name.value}") - original_modeling_node = mapper.classes[renamed_super_class] + same_file_parent = original_modeling_node is not None + if not same_file_parent: + original_modeling_node = mapper.classes[renamed_super_class] # Always use the new name of the class (in case we use e.g. `ColPaliForRetrieval` inheriting from `PaliGemmaForConditionalGeneration`) new_class_name = modular_class_node.name # If the new class name is different from the renamed super class name, we need to update the docstrings/comments accordingly - if new_class_name.value != renamed_super_class: + if new_class_name.value != renamed_super_class and not same_file_parent: common_suffix = common_partial_suffix(new_class_name.value, renamed_super_class) # Note that this works even without common prefix, in which case it does not replace anything old, new = renamed_super_class.replace(common_suffix, ""), new_class_name.value.replace(common_suffix, "") @@ -1891,6 +1900,32 @@ class NewNameModel(LlamaModel): return corrected_dependencies, new_imports +def get_same_file_parent_to_unpack( + modular_mapper: ModularFileMapper, node: cst.ClassDef, files: dict[str, dict] +) -> cst.ClassDef | None: + """ + Return the generated node of the parent of `node` if `node` should be unpacked from it as for a cross-model parent, + i.e. if the parent is a modeling block of the same modular file that was itself unpacked from another model (directly + or through a chain of such same-file parents). `PreTrainedModel` subclasses and other files' classes (configs, + processors, ...) stay inherited, as do thin `*args` wrappers such as deprecated aliases. + """ + bases = [ + k.value.value for k in node.bases if m.matches(k.value, m.Name()) and k.value.value in modular_mapper.classes + ] + if len(bases) != 1 or bases[0] not in files["modeling"]: + return None + parent_node = files["modeling"][bases[0]]["node"] + # The parent was not unpacked: the generated node is the modular one + if parent_node is modular_mapper.classes[bases[0]]: + return None + parent_bases = [bases[0]] + [get_full_attribute_name(k.value) or "" for k in parent_node.bases] + if any(base.endswith("PreTrainedModel") for base in parent_bases): + return None + if any(m.matches(k, m.FunctionDef(params=m.Parameters(star_arg=m.Param()))) for k in node.body.body): + return None + return parent_node + + def get_class_node_and_dependencies( modular_mapper: ModularFileMapper, class_name: str, node: cst.CSTNode, files: dict[str, dict] ) -> tuple[dict, str, dict]: @@ -1953,8 +1988,13 @@ class node based on the inherited classes if needed. Also returns any new import # No transformers (modeling file) super class, just check functions and assignments dependencies else: updated_node = node - # The node was NOT modified -> no need to look recursively for other class dependencies. Indeed, even if they are not - # already defined (which would mean a weird order of the code in the modular...), they will be in the future + # A same-file parent unpacked from another model is unpacked in turn, from its already generated node + if file_type == "modeling" and (parent_node := get_same_file_parent_to_unpack(modular_mapper, node, files)): + parent_name = parent_node.name.value + updated_node = replace_class_node(modular_mapper, node, parent_name, parent_name, parent_node) + # No need to look recursively for other class dependencies. Indeed, even if they are not already defined (which + # would mean a weird order of the code in the modular...), they will be in the future. The dependencies of an + # unpacked same-file parent were already added with it all_dependencies_to_add = augmented_dependencies_for_class_node(updated_node, modular_mapper, imported_objects) # At this point, if any class dependency is found, but belongs to another file, it means that we need to remove From b9fe6322a7f5543ad8c2397930a3a2d2fb0aa946 Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 9 Nov 2026 17:16:03 +0900 Subject: [PATCH 7/7] nit --- src/transformers/models/dpt/modular_dpt.py | 19 ------------------- .../models/glmga/modular_glmga.py | 19 ++----------------- 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/src/transformers/models/dpt/modular_dpt.py b/src/transformers/models/dpt/modular_dpt.py index 72b287ff5f5f..9577f034cd17 100644 --- a/src/transformers/models/dpt/modular_dpt.py +++ b/src/transformers/models/dpt/modular_dpt.py @@ -38,9 +38,6 @@ from torchvision.transforms.v2 import functional as tvF -from ...image_utils import ImageInput -from ...processing_utils import Unpack - def get_resize_output_image_size( input_image: "torch.Tensor", @@ -122,9 +119,6 @@ class DPTImageProcessor(BeitImageProcessor): valid_kwargs = DPTImageProcessorKwargs - def __init__(self, **kwargs: Unpack[DPTImageProcessorKwargs]): - super().__init__(**kwargs) - def resize( self, image: "torch.Tensor", @@ -291,18 +285,5 @@ def post_process_depth_estimation( return results - @auto_docstring - def preprocess( - self, - images: ImageInput, - segmentation_maps: ImageInput | None = None, - **kwargs: Unpack[DPTImageProcessorKwargs], - ) -> BatchFeature: - r""" - segmentation_maps (`ImageInput`, *optional*): - The segmentation maps to preprocess. - """ - return super().preprocess(images, segmentation_maps, **kwargs) - __all__ = ["DPTImageProcessor"] diff --git a/src/transformers/models/glmga/modular_glmga.py b/src/transformers/models/glmga/modular_glmga.py index 89aeece1d0e4..1f407bb18f26 100644 --- a/src/transformers/models/glmga/modular_glmga.py +++ b/src/transformers/models/glmga/modular_glmga.py @@ -22,13 +22,12 @@ from ...image_transforms import group_images_by_shape, reorder_images from ...image_utils import ( ChannelDimension, - ImageInput, PILImageResampling, SizeDict, get_image_size, ) -from ...processing_utils import ImagesKwargs, Unpack, VideosKwargs -from ...utils import TensorType, auto_docstring +from ...processing_utils import ImagesKwargs, VideosKwargs +from ...utils import TensorType from ...video_utils import VideoMetadata, group_videos_by_shape, reorder_videos from ..glm4v.video_processing_glm4v import smart_resize from ..glm46v.configuration_glm46v import Glm46VConfig @@ -87,7 +86,6 @@ class GlmgaImageProcessorKwargs(ImagesKwargs, total=False): class GlmgaImageProcessor(Glm46VImageProcessor): patch_expand_factor = 1 - valid_kwargs = GlmgaImageProcessorKwargs def _preprocess( self, @@ -154,14 +152,9 @@ def _preprocess( data={"pixel_values": pixel_values, "image_grid_thw": image_grid_thw}, tensor_type=return_tensors ) - @auto_docstring - def preprocess(self, images: ImageInput, **kwargs: Unpack[GlmgaImageProcessorKwargs]) -> BatchFeature: - return super().preprocess(images, **kwargs) - class GlmgaImageProcessorPil(Glm46VImageProcessorPil): patch_expand_factor = 1 - valid_kwargs = GlmgaImageProcessorKwargs def _preprocess( self, @@ -222,10 +215,6 @@ def _preprocess( data={"pixel_values": pixel_values, "image_grid_thw": image_grid_thw}, tensor_type=return_tensors ) - @auto_docstring - def preprocess(self, images: ImageInput, **kwargs: Unpack[GlmgaImageProcessorKwargs]) -> BatchFeature: - return super().preprocess(images, **kwargs) - class GlmgaVideoProcessorInitKwargs(VideosKwargs, total=False): r""" @@ -257,10 +246,6 @@ class GlmgaVideoProcessor(Glm46VVideoProcessor): fps = 2 patch_expand_factor = 1 max_frames = 640 - valid_kwargs = GlmgaVideoProcessorInitKwargs - - def __init__(self, **kwargs: Unpack[GlmgaVideoProcessorInitKwargs]): - super().__init__(**kwargs) def sample_frames( self,