Transformers documentation

Aturan struktur model

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Aturan struktur model

Transformers menerapkan seperangkat aturan statis pada setiap file modeling_*.py, modular_*.py, dan configuration_*.py. Paket mlinter menyediakan mesin checker, dan repositori menyimpan kumpulan aturan aktifnya di utils/rules.toml. File TOML lokal tersebut memungkinkan kami mengaktifkan, menonaktifkan, atau menyesuaikan aturan dengan cepat tanpa harus menunggu rilis baru transformers-mlinter.

Lihat dokumentasi mlinter untuk referensi lengkap checker dan detail penggunaan.

Ini adalah konvensi model yang diharapkan untuk menambahkan atau mengubah kode pemodelan. Konvensi ini menjaga konsistensi basis kode dan memastikan kompatibilitas dengan fitur seperti pipeline parallelism, device maps, dan weight tying.

Menjalankan checker

make typing menjalankan mlinter bersama type checker ty melalui repo wrapper, sehingga mengambil utils/rules.toml. Jalankan wrapper yang sama secara langsung dengan perintah berikut.

python utils/check_modeling_structure.py                 # check all modeling files
python utils/check_modeling_structure.py --changed-only  # check only files changed vs origin/main
python utils/check_modeling_structure.py --list-rules    # list all rules and their enabled status
python utils/check_modeling_structure.py --rule TRF001   # show built-in docs for a specific rule

Flag --changed-only adalah opsi tercepat selama pengembangan. Flag ini hanya memeriksa file yang telah Anda modifikasi relatif terhadap cabang utama. Jika Anda memanggil mlinter secara langsung alih-alih melalui wrapper, berikan --rules-toml utils/rules.toml agar override lokal diterapkan.

Memperbaiki pelanggaran

Ketika pelanggaran aturan terdeteksi, error akan terlihat seperti ini:

src/transformers/models/acme/modeling_acme.py:18: TRF013: AcmeModel.__init__ does not call self.post_init().

Gunakan ID aturan untuk mencari perbaikannya di referensi aturan. TRF013 dipicu ketika subclass PreTrainedModel tidak memanggil self.post_init(). Metode tersebut menjalankan langkah finalisasi yang esensial, dan mengabaikannya menyebabkan bug saat runtime.

 class AcmeModel(AcmePreTrainedModel):
     def __init__(self, config):
         super().__init__(config)
         self.layers = nn.ModuleList(
             [AcmeDecoderLayer(config) for _ in range(config.num_hidden_layers)]
         )
+        self.post_init()

Referensi aturan

Setiap aturan di bawah ini mencantumkan apa yang ditegakkan beserta diff yang menunjukkan perbaikannya. Jalankan python utils/check_modeling_structure.py --rule TRF001 untuk melihat dokumentasi bawaan untuk aturan mana pun dengan set aturan saat ini dari repo.

TRF001

Memeriksa bahwa config_class dari <Model>PreTrainedModel bernama <Model>Config. Ketidakcocokan dapat merusak proses pemuatan, kelas otomatis, dan ekspektasi pengembang.

class AcmePreTrainedModel(PreTrainedModel):
-    config_class = WileConfig
+    config_class = AcmeConfig

TRF002

Memeriksa bahwa base_model_prefix adalah string literal yang tidak kosong dan bebas spasi. Prefiks yang tidak valid dapat merusak pemetaan kunci saat memuat bobot dan akses ke model dasar.

class AcmePreTrainedModel(PreTrainedModel):
-    base_model_prefix = ""
+    base_model_prefix = "model"

TRF003

Menandai pola lama if not return_dict: return (x,) di dalam forward. Percabangan return_dict manual bersifat verbose dan mudah salah. Biarkan @capture_output atau @can_return_tuple yang melakukannya.

-def forward(self, x, return_dict=None):
-    if not return_dict:
-        return (x,)
-    return AcmeModelOutput(last_hidden_state=x)
+@can_return_tuple
+def forward(self, x):
+    return AcmeModelOutput(last_hidden_state=x)

TRF004

Memeriksa bahwa tidak ada kelas model yang mendefinisikan metode tie_weights. Menimpa tie_weights akan merusak proses pemuatan, perhitungan device_map, dan penyimpanan. Deklarasikan bobot terikat melalui atribut kelas _tied_weights_keys.

-def tie_weights(self):
-    self.lm_head.weight = self.emb.weight
+class AcmeForCausalLM(AcmePreTrainedModel):
+    _tied_weights_keys = ["lm_head.weight"]

TRF005

Memeriksa bentuk _no_split_modules jika ada. Nilai yang tidak valid dapat merusak partisi device-map dan sharding.

-_no_split_modules = [SomeLayerClass, ""]
+_no_split_modules = ["AcmeDecoderLayer", "AcmeAttention"]

TRF006

Memeriksa bahwa argumen cache dalam tanda tangan forward digunakan di dalam badan fungsi. Argumen cache yang tidak digunakan mengindikasikan dukungan cache yang tidak lengkap dan perilaku API yang tidak konsisten.

def forward(self, x, past_key_values=None, use_cache=False):
+    if use_cache:
+        ...
     return x

TRF007

Memeriksa penugasan atribut self setelah self.post_init() di init. Mengubah struktur model setelah post_init akan melewati proses inisialisasi dan finalisasi-nya.

def __init__(self, config):
     ...
-    self.post_init()
-    self.proj = nn.Linear(...)
+    self.proj = nn.Linear(...)
+    self.post_init()

TRF008

Memeriksa bahwa add_start_docstrings pada kelas model menerima argumen yang tidak kosong. Argumen kosong menghasilkan dokumentasi API yang dihasilkan dengan kualitas rendah dan tidak jelas.

-@add_start_docstrings("")
+@add_start_docstrings("The Acme model.")
 class AcmeModel(AcmePreTrainedModel):
     ...

TRF009

Flags imports into another model’s package from a model’s shipped implementation files: modeling*, configuration, processing_, imageprocessing, videoprocessing, featureextraction, tokenization_ and generation*.py. Three forms count: package path (from transformers.models.other.modeling_other import X), relative path (from ..other.configuration_other import X) and public API (from transformers import OtherModel) — for the last the owning directory is inferred from the class name and confirmed against the classes it defines, so an unresolvable name is left alone. Out of scope: `modular.py(building on another model is its purpose, and the converter flattens those imports away),convert_.py,init.pyand files underauto. Allowed targets: the model's own directory,autoandtimm_wrapper`. One model, one definition: model A’s behavior lives in its own files, and a change to model B must not silently change model A — for every file kind, not just modeling. Reach sub-configs through AutoConfig and CONFIG_MAPPING, and use a modular file to build on another model’s code.

-from transformers.models.llama.modeling_llama import LlamaAttention
-from transformers import CLIPTextModelWithProjection
+# Keep implementation local to this model's own files.
+# To build on another model, write modular_acme.py; to reuse a snippet,
+# copy it with a # Copied from comment.

TRF010

Memeriksa bahwa subclass langsung dari PreTrainedConfig/PretrainedConfig di configuration*.py dan modular*.py memiliki @strict(accept_kwargs=True). Tanpa ini, config baru akan kehilangan kontrak validasi tipe runtime dari repo dan menyimpang dari standar config berbasis dataclass.

+@strict(accept_kwargs=True)
 class AcmeConfig(PreTrainedConfig):
     ...

TRF011

Pada forward() dari subclass PreTrainedModel, akses atribut submodule pada variabel loop di self.layers, serta self.<submodule>.<attr> di mana <attr> bukan atribut standar nn.Module, tidak akan dimiliki oleh torch.nn.Identity. Parallelism pipeline dapat mengganti submodule apa pun dengan torch.nn.Identity, sehingga membaca atribut kustom (misalnya decoder_layer.attention_type) darinya akan memicu AttributeError saat runtime. Baca metadata per-layer dari self.config.

def forward(self, ...):
-    for decoder_layer in self.layers:
+    for i, decoder_layer in enumerate(self.layers):
         hidden_states = decoder_layer(
             hidden_states,
-            attention_mask=causal_mask_mapping[decoder_layer.attention_type],
+            attention_mask=causal_mask_mapping[self.config.layer_types[i]],
         )

TRF012

Operasi in-place (seperti .normal(), .zero(), …) pada bobot modul di dalam _init_weights. Parameter memiliki flag internal yang melacak apakah masih perlu diinisialisasi ulang; operasi in-place melewati flag tersebut. Gunakan primitif init.

+from transformers import initialization as init
+
 def _init_weights(self, module):
-    module.weight.normal_(mean=0.0, std=0.02)
+    init.normal_(module.weight, mean=0.0, std=0.02)

TRF013

Memeriksa bahwa setiap subclass PreTrainedModel yang mendefinisikan init memanggil self.post_init(). Dalam file modular, super().init() dianggap memenuhi syarat, karena hal ini meneruskan post_init dari kelas induk. post_init melakukan finalisasi penting (inisialisasi bobot, pengaturan gradient checkpointing, …); melewatkan langkah ini dapat menyebabkan bug runtime yang halus.

class AcmeModel(AcmePreTrainedModel):
     def __init__(self, config):
         super().__init__(config)
         self.layers = nn.ModuleList(...)
+        self.post_init()

TRF014

Flag trust_remote_code yang digunakan atau diteruskan (misalnya sebagai kwarg) dalam file integrasi model native. trust_remote_code memuat kode arbitrer, termasuk biner — sebuah fitur bertenaga bagi pengguna, bukan sesuatu yang boleh diandalkan oleh integrasi native, karena kode remote tidak dapat ditinjau atau dipelihara di transformers.

class AcmeModel(AcmePreTrainedModel):
     def __init__(self, config):
         super().__init__(config)
-        self.model = AutoModel.from_pretrained(..., trust_remote_code=True)
+        self.model = AutoModel.from_pretrained(...)

TRF015

Ketika subclass dari PreTrainedModel menetapkan _tied_weights_keys yang tidak kosong, periksa file konfigurasi pendamping untuk field tie_word_embeddings. Tanpa field ini, pengguna tidak dapat mengontrol penautan bobot: model akan menautkan bobot secara tidak bersyarat, yang merusak round-trip serialisasi dan fine-tuning dengan kepala yang tidak ditautkan.

# configuration_foo.py
 @strict(accept_kwargs=True)
 class FooConfig(PreTrainedConfig):
     hidden_size: int = 768
+    tie_word_embeddings: bool = True

TRF016

Ketika kelas imageprocessing.py atau videoprocessing.py mendeklarasikan atribut boolean do_* (do_resize, do_rescale, do_normalize, do_convert_rgb, …) dan menimpa preprocess() atau _preprocess(), periksa apakah setiap flag masih dikonsumsi di sana: dirujuk secara langsung, didelegasikan melalui super().preprocess/_preprocess(…, **kwargs), atau — khusus image processor — diteruskan melalui _preprocess_image_like_inputs/_prepare_image_like_inputs. do_sample_frames dikecualikan: preprocess() dasar mengonsumsinya sebelum _preprocess() dijalankan. do_X yang tidak pernah dirujuk oleh override tersebut adalah mati: mengatur do_X=False tidak memiliki efek, operasi tetap dijalankan, dan override per-panggilan rusak secara diam-diam.

class AcmeVideoProcessor(BaseVideoProcessor):
     do_resize = True
     do_normalize = True

     def _preprocess(
         self,
         videos,
+        do_resize: bool,
+        do_normalize: bool,
         size,
         image_mean,
         image_std,
         **kwargs,
     ):
         for video in videos:
-            video = self.resize(video, size=size)
-            video = self.normalize(video, image_mean, image_std)
+            if do_resize:
+                video = self.resize(video, size=size)
+            if do_normalize:
+                video = self.normalize(video, image_mean, image_std)

TRF017

Pada kelas yang memiliki @auto_docstring dan @dataclass, pastikan @auto_docstring diletakkan lebih dulu. Dekorator diterapkan dari bawah ke atas, sehingga @dataclass di atas akan menjalankan @auto_docstring terlebih dahulu, pada kelas yang belum memiliki init yang disintesis: kemudian ia memodifikasi init dari kelas induk, bukan doc dari subkelas.

-@dataclass
 @auto_docstring(
     custom_intro="""
     Output type of `AcmeForPreTraining`.
     """
 )
+@dataclass
 class AcmeForPreTrainingOutput(ModelOutput):
     ...

TRF018

Memeriksa bahwa setiap subclass _init_weights(self, module, ...) dari PreTrainedModel yang menimpa metode tersebut memanggil rantai ke atas melalui super()._init_weights(...). File modular juga menerima sentinel PreTrainedModel._init_weights(self, module), PreTrainedModel._init_weights(module), dan raise AttributeError(...). Untuk penimpaan penuh yang disengaja, tekan dengan # trf-ignore: TRF018 di atas metode. _init_weights dasar mencakup tipe modul standar (Linear, Embedding, LayerNorm, RotaryEmbedding, …). Melewakkannya akan membuat setiap submodul yang tidak ditangani oleh penimpaan tetap tidak terinisialisasi — yang lolos pengujian dan kemudian muncul sebagai bug inisialisasi bobot yang halus (lihat https://github.com/huggingface/transformers/pull/45597).

from ... import initialization as init

 def _init_weights(self, module):
+    super()._init_weights(module)
     if isinstance(module, AcmeCustomLayer):
-        module.gate.data.zero_()
+        init.zeros_(module.gate)

TRF019

Menandai _defaults yang tidak kosong pada TypedDict *ProcessorKwargs di processing_*.py. Model yang dirilis sebelum tanggal batas dikecualikan. _defaults yang di-hardcode menyebarkan konfigurasi processor ke seluruh sumber Python, sulit untuk dioverride dari config, dan membuat kode membengkak. Di processor_config.json pada hub, konfigurasi ini ikut bersama checkpoint dan dapat diperbarui tanpa perubahan kode.

class Gemma4ProcessorKwargs(ProcessingKwargs, total=False):
-    _defaults = {
-        "text_kwargs": {"padding": False},
-        "images_kwargs": {"return_tensors": "pt"},
-    }
     images_kwargs: Gemma4ImageProcessorKwargs

TRF020

Pada direktori model yang konfigurasinya mendeklarasikan kv_lora_rank (Multi-head Latent Attention), periksa kelas atensi yang memiliki proyeksi ekspansi KV LoRA (kv_b_proj, atau nn.Linear(config.kv_lora_rank, ...) apa pun): ekspansi tersebut harus berada di metode khusus (misalnya expand_kv) yang dipanggil oleh forward(), bukan ditulis inline. Pada file modular, metode yang diwarisi dari basis yang diimpor tetap dihitung. Backend eksternal (vLLM/SGLang) menimpa ekspansi tersebut untuk mengonsumsi cache KV terkompresi secara langsung. Jika ditulis inline di forward(), tidak ada yang bisa ditimpa, sehingga backend harus mematerialisasi cache penuh — kehilangan penghematan memori yang menjadi alasan keberadaan MLA.

+    def expand_kv(self, k_nope, k_pe):
+        key_shape = (*k_nope.shape[:-1], -1, self.qk_nope_head_dim + self.v_head_dim)
+        k_nope = self.kv_b_proj(k_nope).view(key_shape).transpose(1, 2)
+        k_nope, value_states = torch.split(k_nope, [self.qk_nope_head_dim, self.v_head_dim], dim=-1)
+        k_pe = k_pe.expand(*k_nope.shape[:-1], -1)
+        key_states = torch.cat((k_nope, k_pe), dim=-1)
+        return key_states, value_states
+
     def forward(self, hidden_states, ...):
         ...
-        k_nope = self.kv_b_proj(k_pass).view(key_shape).transpose(1, 2)
-        k_nope, value_states = torch.split(k_nope, [self.qk_nope_head_dim, self.v_head_dim], dim=-1)
-        k_pe = k_rot.expand(*k_nope.shape[:-1], -1)
-        key_states = torch.cat((k_nope, k_pe), dim=-1)
+        key_states, value_states = self.expand_kv(k_pass, k_rot)

TRF021

Dalam modeling*.py dan modular.py, flag torch.tensor(<value>, ..., device=<non-cpu>) di mana <value> terbukti teresolusi menjadi skalar Python — dari literal numerik dan aritmetika di atasnya, field torch.finfo/iinfo, built-in yang mengembalikan skalar dan math. calls, lokal yang diikat tepat sekali, self.<attr> yang ditugaskan di badan kelas, dan field config yang dianotasi int/float/bool di file konfigurasi pendamping (mengikuti attribute_map). Sesuatu yang mungkin juga berupa sequence (eos_token_id: int | list[int] | None) atau yang tidak dapat diresolusi dibiarkan apa adanya. init, _init_weights, post_init dan post_init dikecualikan: mereka tidak pernah berjalan di dalam region capture. torch.tensor(<python scalar>, device=<accelerator>) mematerialisasi nilai di host lalu menyalinnya ke device; capture CUDA graph melarang salinan tersebut, sehingga model tidak dapat di-capture. torch.full((), <value>, dtype=…, device=…) mengisi tensor 0-d yang sama di-device dengan kernel yang dapat di-capture dan tanpa sinkronisasi.

def get_placeholder_mask(self, input_ids, inputs_embeds):
     special_image_mask = (
         inputs_embeds
         == self.get_input_embeddings()(
-            torch.tensor(self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
+            torch.full((), self.config.image_token_id, dtype=torch.long, device=inputs_embeds.device)
         )
     ).all(-1)

TRF022

Memeriksa bahwa setiap string dalam daftar _no_split_modules di modeling*.py atau modular*.py merujuk pada kelas yang didefinisikan di file tersebut, diimpor ke dalamnya, atau didefinisikan oleh modul saudara di direktori model yang sama. Melengkapi TRF005, yang hanya memeriksa bentuk nilai. device_map mencocokkan string-string ini dengan module.__class__.__name__ saat runtime, sehingga nama yang usang atau salah eja tidak akan cocok dengan apa pun dan diabaikan secara diam-diam — modul yang seharusnya dijaga agar tetap utuh masih bisa dipecah ke berbagai perangkat. Hapus entri yang merujuk pada kelas model lain, alih-alih memperbaikinya: post_init sudah mengumpulkan _no_split_modules dari submodel anak.

class VideoLlavaPreTrainedModel(PreTrainedModel):
-    _no_split_modules = ["VideoLlavaVisionAttention"]

TRF023

Dalam konfigurasi*.py dan modular.py, flag `Configfields named after an upstream paper's abbreviation instead of the canonical name: d_model/n_embd -> hidden_size, d_ff/d_inner/ffn_dim/ffn_hidden_size/expansion_ratio -> intermediate_size, d_head -> head_dim, n_head/n_heads -> num_attention_heads, n_layer/n_layers/num_blocks -> num_hidden_layers. Fields are read from the class body and from __init__/__post_init__ assignments and defaults. Ambiguous but idiomatic names (num_heads, num_layers, embed_dim, mlp_ratio) are not flagged, and models added before cutoff_date keep theirs. Everything that reads a model's shape -- device_map planning, tensor/pipeline parallel plans, quantization, PEFT, attention-backend selection,attribute_mapconsumers -- looks up the canonical names, so a config spelling the same quantityd_model` silently opts out of all of them. Map the checkpoint’s own spelling in the conversion script.

@strict(accept_kwargs=True)
 class AcmeConfig(PreTrainedConfig):
-    d_model: int = 1024
-    d_ff: int = 4096
-    n_heads: int = 16
-    n_layers: int = 24
+    hidden_size: int = 1024
+    intermediate_size: int = 4096
+    num_attention_heads: int = 16
+    num_hidden_layers: int = 24

TRF024

Dalam modeling*.py dan modular.py, menandai literal integer yang lebih besar dari 8 dalam argumen dimensi dari konstruktor torch.nn (Linear, Embedding, LayerNorm, RMSNorm, GroupNorm, BatchNorm, InstanceNorm, Convd, ConvTranspose*d, Bilinear, MultiheadAttention), baik secara posisional maupun melalui keyword (in_features, out_features, in_channels, out_channels, num_embeddings, embedding_dim, embed_dim, normalized_shape, num_channels, hidden_size). Argumen bentuk operator (kernel_size, stride, padding, num_groups) diabaikan; literal hingga 8 menjaga agar scalar heads, binary classifiers, dan jumlah channel RGB tetap bersih. Model yang ditambahkan sebelum cutoff_date dikecualikan. Lebar yang di-hardcode mengunci modul pada satu ukuran checkpoint: arsitektur yang sama pada skala lain akan dimuat dengan shape mismatch, dan from_pretrained tidak dapat menyatakan nilai mana yang salah karena tidak ada field config yang menunjuk ke sana. Hal ini juga memecah sumber kebenaran, sehingga mengedit config tidak lagi mengubah model yang dibangun.

class AcmeAtomEmbedding(nn.Module):
     def __init__(self, config):
         super().__init__()
-        self.proj = nn.Linear(768, 3072, bias=False)
-        self.norm = nn.LayerNorm(3072)
+        self.proj = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
+        self.norm = nn.LayerNorm(config.intermediate_size)

TRF025

Dalam *.py dan modular.py, flag memanggil mask factory (entry point masking utils: create_causal_mask, create_bidirectional_mask, create_sliding_window_causal_mask, create_chunked_causal_mask, create_masks_for_generate, dan helper create_mask) di dalam kelas yang tidak mewarisi dari PreTrainedModel — blok nn.Module polos seperti layers, attention modules, dan encoders. Konstruksi mask adalah pekerjaan O(kuadrat panjang sekuens) yang tidak bervariasi per layer, sehingga membangunnya di layer akan membayar biaya tersebut sekali per layer, dan setiap layer kemudian memiliki mask-nya sendiri, sehingga attention backends tidak lagi dapat diberikan satu mask yang sudah disiapkan. Bangun sekali di model dan teruskan ke bawah.

class AcmeLayer(nn.Module):
     def forward(self, hidden_states, attention_mask=None, **kwargs):
-        attention_mask = create_causal_mask(
-            config=self.config, input_embeds=hidden_states, attention_mask=attention_mask, ...
-        )
         return self.self_attn(hidden_states, attention_mask, **kwargs)

 class AcmeModel(AcmePreTrainedModel):
     def forward(self, input_ids=None, attention_mask=None, **kwargs):
+        causal_mask = create_causal_mask(
+            config=self.config, input_embeds=inputs_embeds, attention_mask=attention_mask, ...
+        )
         for layer in self.layers:
-            hidden_states = layer(hidden_states, attention_mask, **kwargs)
+            hidden_states = layer(hidden_states, causal_mask, **kwargs)

TRF026

Dalam modeling*.py dan modular*.py, menandai kelas non-PreTrainedModel yang hanya mendefinisikan init dan forward, yang menetapkan tepat satu self.<attr> di init, dan yang isi forward-nya tepat return self.<attr>(...) untuknya (docstring di awal diabaikan). Metode lain, atribut tambahan, pernyataan sebelum return, atau panggilan super() di forward berarti kelas tersebut melakukan pekerjaannya sendiri. Pembungkus ini menambahkan satu tingkat ke setiap nama bobot, ke _no_split_modules, rencana paralelisasi, dan setiap pemetaan konversi, tanpa menghitung apa pun — dan pembaca harus membuka satu kelas lagi untuk menemukan hal itu. Subkelas PreTrainedModel dikecualikan: mereka ada untuk from_pretrained dan kelas auto bahkan ketika forward hanya mendelegasikan.

-class AcmeAtomTransformer(nn.Module):
-    def __init__(self, config):
-        super().__init__()
-        self.encoder = AcmeEncoder(config)
-
-    def forward(self, hidden_states, **kwargs):
-        return self.encoder(hidden_states, **kwargs)
-
 class AcmeModel(AcmePreTrainedModel):
     def __init__(self, config):
         super().__init__(config)
-        self.atom_transformer = AcmeAtomTransformer(config)
+        self.encoder = AcmeEncoder(config)

TRF027

Menandai setiap pernyataan assert di modeling*.py, modular.py dan configuration_.py. python -O menghapus assert, sehingga pemeriksaan bentuk atau konfigurasi yang ditulis sebagai assert akan hilang secara diam-diam pada eksekusi yang dioptimalkan. Assert juga hanya menghasilkan AssertionError polos, sedangkan ValueError dapat menyebutkan nilai yang bermasalah dan menjelaskan apa yang harus dilakukan.

def forward(self, hidden_states):
-    assert hidden_states.dim() == 3
+    if hidden_states.dim() != 3:
+        raise ValueError(f"Expected a 3D tensor, got shape {tuple(hidden_states.shape)}.")

TRF028

Memeriksa 25 baris pertama dari modeling*.py, modular.py, configuration_.py, processing*.py, image_processing.py dan videoprocessing.py untuk baris Licensed under the <name> License yang diikuti oleh setiap klausul dari paragraf standar garansi, mulai dari You may obtain a copy of the License at hingga limitations under the License.. Baris-baris diratakan dan diubah menjadi huruf kecil terlebih dahulu, sehingga pembungkus dan gaya komentar tidak menjadi masalah. Nama lisensi dan baris hak cipta tidak diperiksa: keduanya bervariasi untuk setiap model. File yang dikirim tanpa header akan membuat asal-usulnya menjadi ambigu, dan menambahkannya kemudian berarti menyentuh file yang sudah dirilis. Pencocokan hanya Apache License akan membiarkan lolos cacat yang sebenarnya terjadi: paragraf yang terpotong di tengah, header yang berhenti setelah URL, atau header yang rusak akibat pencarian dan penggantian yang buruk.

+# Copyright 2026 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# ...
 """PyTorch Acme model."""

TRF029

Dalam modeling*.py dan modular*.py, menandai __init__ yang menerima config berdampingan dengan argumen yang namanya secara tegas merupakan field config (hidden_size, num_attention_heads, intermediate_size, head_dim, num_hidden_layers, embed_dim, dropout, eps, patch_size, rope_theta, …). Parameter opsional dengan default None dikecualikan: itu adalah override, bukan sumber kebenaran kedua, dan itulah cara satu kelas MLP melayani baik lebar dense maupun lebar expert dari model MoE. Default yang di-hardcode seperti hidden_size: int = 1024 tidak termasuk — ia menang atas config setiap kali pemanggil tidak meneruskan apa pun. kosmos2 diizinkan: halaman dokumennya tidak dapat diturunkan dari nama direktori, sehingga cutoff tidak dapat memberinya kekebalan. Angka yang sama kini memiliki dua sumber kebenaran dan pemanggil yang memilih pemenangnya, sehingga mengedit config tidak lagi mengubah model yang dibangun. Hal ini juga mendorong pengetahuan arsitektur keluar ke setiap call site, tempat ia tidak seharusnya berada.

class AcmeAttention(nn.Module):
-    def __init__(self, config, embed_dim, num_heads, dropout):
+    def __init__(self, config, layer_idx=None):
         super().__init__()
-        self.embed_dim = embed_dim
-        self.num_heads = num_heads
+        self.embed_dim = config.hidden_size
+        self.num_heads = config.num_attention_heads

 class AcmeMLP(nn.Module):
     # an optional override is fine: omitting it reads the config
     def __init__(self, config, intermediate_size=None):
         super().__init__()
         self.intermediate_size = intermediate_size or config.intermediate_size

TRF030

Dalam modeling*.py dan modular*.py, atribut flag rantai yang berakar pada config atau self.config dengan kedalaman tiga tingkat atau lebih. config.hidden_size (satu hop) dan config.text_config.hidden_size (dua hop, akses sub-config normal) tidak masalah. Satu pelanggaran per baris. Modul yang menelusuri config.diffusion_config.atom_encoder_config.hidden_size terikat pada seluruh hierarki config, bukan pada slice-nya sendiri, sehingga tidak dapat digunakan ulang, diuji, atau diberikan sub-config yang berbeda. Teruskan sub-config yang relevan ke bawah dan rantai akan menyusut menjadi satu hop.

class AcmeAtomEncoder(nn.Module):
     def __init__(self, config):
         super().__init__()
-        self.norm = AcmeLayerNorm(config.diffusion_config.atom_encoder_config.hidden_size)
+        self.norm = AcmeLayerNorm(config.hidden_size)

TRF031

Dalam modeling*.py dan modular*.py, menandai @dataclass tingkat atas yang basisnya tidak ada yang berakhiran Output, kecuali jika memiliki dua atau lebih field wajib — itu adalah bundel argumen internal, yang ModelOutput tolak saat runtime. Dataclass output biasa tidak dapat diindeks seperti tuple, tidak bertahan dengan return_dict=False, dan tidak terlihat oleh @auto_docstring, sehingga field-nya tidak pernah mencapai dokumentasi API yang dihasilkan. ModelOutput mendapatkan ketiga hal tersebut secara gratis.

@auto_docstring
 @dataclass
-class AcmeStructureOutput:
+class AcmeStructureOutput(ModelOutput):
     positions: torch.Tensor
     confidence: Optional[torch.Tensor] = None

TRF032

Dalam modeling*.py dan modular*.py, flag maskedfill, masked_fill, full, full_like dan new_full dipanggil dengan literal numerik bernilai negatif yang magnitudenya 1e3 atau lebih. Nilai -1e9 yang di-hardcode akan meluap menjadi -inf pada float16 dan sama sekali tidak mendekati nilai terkecil pada float32, sehingga mask yang sama akan berperilaku berbeda untuk setiap dtype dan dapat menghasilkan NaN setelah softmax. torch.finfo(dtype).min adalah nilai terkecil yang dapat direpresentasikan pada dtype apa pun yang sedang berjalan.

-attention_scores = attention_scores.masked_fill(~mask, -1e9)
+attention_scores = attention_scores.masked_fill(~mask, torch.finfo(attention_scores.dtype).min)

TRF033

Dalam modeling*.py dan modular*.py, metode yang namanya diawali dengan set_ ditandai, kecuali metode kontrak PreTrainedModel yaitu set_input_embeddings, set_output_embeddings, set_decoder, set_encoder, set_attn_implementation, dan set_default_language. Setter membuat perilaku bergantung pada urutan pemanggilan: nilainya tidak ada di config, sehingga tidak disimpan, tidak dipulihkan oleh from_pretrained, dan tidak terlihat oleh device-map atau perencanaan paralelisasi. Pengguna harus tahu untuk memanggilnya, dan jika lupa, hal itu terjadi tanpa peringatan.

class AcmeTriangleAttention(nn.Module):
-    def set_chunk_size(self, chunk_size):
-        self.chunk_size = chunk_size
+    def __init__(self, config):
+        super().__init__()
+        self.chunk_size = config.chunk_size

TRF034

In modeling*.py and modular.py, flags a locally-defined `Layer/Blockclass instantiated in annn.ModuleList(…)that does not reachGradientCheckpointingLayerthrough its base chain; modular files follow relative imports into sibling models, and unresolved chains are inconclusive. Out of scope: a model that never setssupports_gradient_checkpointing = True, which raises fromgradient_checkpointing_enable()instead of skipping a layer; a layer holdingnn.BatchNorm/nn.InstanceNorm*, whose statistics would be recomputed twice; and a stack that is not the model's token mixer, shown by an attention, modulation, mixer or SSM module assigned asself.x = Y(…).gradient_checkpointing_enable()` wraps a layer only if it is a GradientCheckpointingLayer. A plain nn.Module on the trunk is skipped silently, so training looks checkpointed while still allocating full activations, and the OOM surfaces far from the cause. Elsewhere — a conv backbone, a decode head — the trade is the author’s call, so the rule stays out.

-class AcmeDecoderLayer(nn.Module):
+class AcmeDecoderLayer(GradientCheckpointingLayer):
     def __init__(self, config, layer_idx):
         super().__init__()

TRF035

Flag komentar # noqa, dengan atau tanpa kode, di modeling*.py, modular.py dan configuration_.py. Pada file modular, F401, F821, dan F822 diterima: file tersebut adalah sumber hasil konversi yang secara sengaja tidak mendefinisikan setiap nama yang digunakan, sehingga aturan undefined-name dari ruff terpicu pada kode yang benar — entri __all__ yang diisi oleh konverter, kelas yang berada di model induk, dan impor yang dipertahankan untuk diekspor ulang. # noqa yang hanya menyebutkan kode-kode tersebut akan dilewati; yang menyebutkan kode lain akan dilaporkan pada kode yang tersisa. # noqa polos selalu dilaporkan; pada file modular, pesannya meminta kode spesifik alih-alih penulisan ulang. File model adalah kode biasa yang tunduk pada aturan lint repo, sehingga penekanan berarti masalah mendasar dibiarkan begitu saja — dan # noqa polos juga menyembunyikan setiap pelanggaran di masa depan pada baris tersebut. Perbaiki kodenya alih-alih menekan.

-from ...modeling_utils import PreTrainedModel  # noqa: F401
+from ...modeling_utils import PreTrainedModel

TRF036

Dalam modeling*.py dan modular*.py, menandai setiap konstruksi nn.Sequential(...). Sequential memberi nama anak-anaknya berdasarkan posisi, sehingga bobot berada di mlp.0.weight dan mlp.2.weight: pemetaan konversi, _tied_weights_keys, dan setiap rencana paralelisasi kemudian merujuk pada indeks, dan menyisipkan satu lapisan akan mengubah nama semua lapisan setelahnya. Hal ini juga menyembunyikan forward, sehingga cast dtype dan residual di antara langkah-langkah tidak terlihat di tempat terjadinya.

-        self.mlp = nn.Sequential(
-            nn.Linear(config.hidden_size, config.intermediate_size),
-            nn.GELU(),
-            nn.Linear(config.intermediate_size, config.hidden_size),
-        )
+        self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size)
+        self.act = ACT2FN[config.hidden_act]
+        self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size)

TRF037

Dalam modeling*.py dan modular*.py, flag memanggil einsum dan melaporkan persamaan jika berupa literal. Dinonaktifkan secara default: einsum kadang merupakan cara paling jelas untuk mengekspresikan kontraksi, sehingga ini bersifat opt-in dan bukan konvensi yang kaku. Persamaan einsum mengodekan bentuk (shape) dalam notasi yang harus didekodekan oleh pembaca, dan persamaan yang dibangun secara dinamis menyembunyikan kontraksi mana yang benar-benar dijalankan. Kembangkan menjadi operasi matmul/transpose yang eksplisit.

-        pair_bias = torch.einsum("bqhc,bkhc->bhqk", query_states, key_states)
+        pair_bias = query_states.permute(0, 2, 1, 3) @ key_states.permute(0, 2, 3, 1)

TRF038

Memeriksa bahwa setiap file modeling*.py, processing.py, imageprocessing.py, videoprocessing.py, featureextraction.py, dan tokenization*.py memiliki file tests/models/<model>/test.py yang sesuai (modelingacme.py -> tests/models/acme/test_modeling_acme.py). Pengecualian: configuration.py, yang dicakup oleh ConfigTester di testmodeling.py pendamping, dan tokenization_utils.py, sebuah helper yang dicakup melalui tokenizer-nya; tokenization<name>_fast.py dipetakan ke file test dari pasangan slow-nya. Sebuah modular*.py dapat mendefinisikan beberapa keluarga sekaligus, sehingga kelasnya diarahkan berdasarkan sufiks nama — XxxModel/XxxPreTrainedModel/XxxFor<Task> untuk modeling, XxxImageProcessor(Fast) untuk image processing, XxxProcessor untuk processing, XxxVideoProcessor untuk video processing, XxxFeatureExtractor untuk feature extraction, XxxTokenizer(Fast) untuk tokenization, dan XxxConfig dilewati — dan satu pelanggaran dilaporkan untuk setiap file test yang hilang. # trf-ignore: TRF038 tidak didukung; gunakan allowlist_models agar pengecualian terlihat jelas saat review. File sumber tanpa file test tidak memiliki cakupan regresi: forward pass yang rusak, pemetaan konversi yang salah, atau tokenizer yang menghilangkan token khusus dapat masuk dan tetap rusak tanpa batas waktu. Dummy config dengan bobot acak, atau kosakata kecil yang ditulis manual, sudah cukup untuk menguji salah satu dari hal tersebut.

src/transformers/models/acme/modeling_acme.py
+tests/models/acme/test_modeling_acme.py
 src/transformers/models/acme/tokenization_acme.py
+tests/models/acme/test_tokenization_acme.py

TRF039

Mencari blok if is_*_available(): import ... (termasuk kombinasi seperti is_vision_available() and is_torch_available()) dan menandai import tersebut jika nama yang diimpor tidak dirujuk di tempat lain dalam file, termasuk di dalam string type hints dan all. Pemeriksaan unused-import dari ruff tidak membersihkan hal ini: import tersebut masih dapat dijangkau, sehingga blok tersebut tampak tidak masalah secara mandiri. Setelah refactoring tidak lagi membutuhkan PIL.Image, torch, dll., import yang dijaga ini tetap tersisa sebagai beban mati dan sinyal yang menyesatkan mengenai dependensi asli file.

if is_vision_available():
-    from PIL import Image

TRF040

Dalam modeling*.py dan modular*.py, flag metode yang diberi dekorasi dengan @capture_outputs dan @can_return_tuple. Melengkapi TRF003, yang mencakup percabangan return_dict manual di forward(). Kedua dekorator tersebut mem-pop return_dict, sehingga hanya yang paling luar yang melihat nilai sebenarnya. @capture_outputs sudah menangani konversi to_tuple, sehingga @can_return_tuple menjadi redundan.

-@can_return_tuple
 @merge_with_config_defaults
 @capture_outputs
 @auto_docstring
 def forward(self, x):
     return AcmeModelOutput(last_hidden_state=x)

TRF041

Dalam modeling*.py dan modular.py, setiap if/elif dan ekspresi kondisional yang kondisinya membaca `config.orself.config.attribute without a# CODEPATH:comment, accepted on the branch line or in the contiguous comment block directly above it. Any config attribute counts, not just boolean flags. Exempt by structure:X if X is not None else fallback, where the tested field is itself one of the results --getattr(config, x, default)spelled long, which cannot fork the graph; and a guard, anifwith noelsewhose body only raises or only warns/logs, since one side aborts and nothing diverges past it. Merely mentioning None does not qualify:config.visionconfig is not Nonestill owes a note. Exempt by field: framework plumbing that gates no checkpoint divergence --problem_typeselecting a loss,hidden_actlooking up an activation,num_labels,use_cache,is_decoder, the special token ids, thesummaryhead settings; the full list isDEFAULT_EXEMPT_ATTRIBUTESinmlinter/trf041.py, extended per project byignored_attributes = […]on the rule table. A model exempts one of its own fields file-wide with a module-level# trf-ignore: TRF041 config.scale_embedding, config.auxiliary_lossat column 0 (self.config.x,config.xandxare the same field). It must name at least one field -- a bare# trf-ignore: TRF041keeps its per-line meaning -- and a condition is skipped only when every field it reads is exempt. A config-gated branch is a second architecture in the same file, and the code cannot say whether both halves are still reachable -- which is how dead experimental branches survive for releases. The rule does not forbid the branch: like Rust's// SAFETY:`, it asks for the checkpoints taking each side to be written down next to it. A branch nobody can name one for is a branch to delete.

+        # CODEPATH: ESMC-6B ships pre-normalised embeddings, the 300M/600M checkpoints do not.
         if config.use_embedding_norm:
             hidden_states = self.embedding_norm(hidden_states)

-        if config.msa_encoder_enabled:
-            hidden_states = self.msa_encoder(hidden_states)
+        # no released checkpoint sets msa_encoder_enabled -> branch removed

TRF042

Di tests/models//testtokenization.py, pemeriksaan memastikan file mendefinisikan kelas test yang dikumpulkan dan mewarisi TokenizerTesterMixin. Hanya kelas yang dikumpulkan oleh runner yang dihitung — yaitu basis TestCase, atau konvensi penamaan *Test ketika basisnya adalah kelas test model lain — sehingga file yang hanya berisi helper dilewati, dan helper yang mencampurkan suite tidak memenuhi aturan untuk kelas test yang sebenarnya. Pewarisan ditelusuri melalui basis di file yang sama dan ke test tokenizer model lain yang diimpor berdasarkan nama; basis yang tidak dapat dipecahkan tidak pernah dihitung. Laporan diberikan pada kelas test pertama yang tidak menjalankan suite. auto diizinkan: test_tokenization_auto.py menguji resolusi AutoTokenizer, bukan tokenizer. TokenizerTesterMixin adalah tempat di mana round-tripping encode/decode, padding dan truncation, penanganan token khusus, persistensi token yang ditambahkan, serta kesetaraan save/load benar-benar diperiksa. Test yang hanya memverifikasi beberapa daftar token id yang ditulis tangan akan lolos meskipun tokenizer rusak di semua aspek tersebut, dan tetap terlihat sudah diuji saat review.

-class AcmeTokenizationTest(unittest.TestCase):
+class AcmeTokenizationTest(TokenizerTesterMixin, unittest.TestCase):
+    tokenizer_class = AcmeTokenizer
+    test_slow_tokenizer = True

TRF043

Menandai parameter position_ids yang dideklarasikan dalam tanda tangan forward dari kelas yang namanya diakhiri dengan Attention. position_ids dikonsumsi di hilir oleh pelatihan tanpa padding dari flash-attention dan harus mengalir melalui kwargs. Menamainya dalam tanda tangan akan menelannya sebelum antarmuka attention dapat membacanya; standar llama meneruskan position_embeddings ditambahkwargs.

class AcmeAttention(nn.Module):
     def forward(
         self,
         hidden_states,
         position_embeddings,
         attention_mask=None,
-        position_ids=None,
         **kwargs: Unpack[TransformersKwargs],
     ):

TRF044

Menandai parameter bernama cache_position pada fungsi apa pun di modeling.py dan modular_.py. cache_position telah dihapus dari semua model di v5. Memperkenalkannya kembali (biasanya disalin dari sumber pre-v5) akan mengaitkan argumen yang tidak terpakai di setiap layer; pembaruan cache adalah past_key_values.update(key_states, value_states, self.layer_idx), tanpa pengaitan posisi.

def forward(
     self,
     hidden_states,
     past_key_values=None,
-    cache_position=None,
     **kwargs,
 ):
-    key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_position)
+    key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)

TRF045

Menandai parameter output legacy attentions, output_hidden_states dan return_dict dalam tanda tangan forward di modeling.py dan modular_.py. Model yang disumbangkan sebelum tanggal batas dikecualikan. Tumpukan dekorator memiliki kendali atas output: @captureoutputs menyelesaikan flag output* terhadap config dan merekam tensor melalui _can_record_outputs, sedangkan @can_return_tuple menangani return_dict. Mendeklarasikannya dalam tanda tangan akan memperkenalkan kembali penyaluran flag manual yang menyimpang dari dekorator.

+@capture_outputs
 def forward(
     self,
     input_ids,
-    output_attentions=None,
-    output_hidden_states=None,
-    return_dict=None,
     **kwargs: Unpack[TransformersKwargs],
 ):

TRF046

Penugasan flag ke atribut self dalam metode forward di modeling*.py dan modular*.py. Penulisan state selama forward merusak batching, torch.compile, dan penalaran tentang modul. State yang dibawa diteruskan secara eksplisit (objek cache, loop generate); nilai yang hanya bergantung pada config atau bentuk statis harus berada di init.

def forward(self, hidden_states):
-    self.sequence_length = hidden_states.shape[1]
-    embeddings = self.compute_embeddings(self.sequence_length)
+    embeddings = self.compute_embeddings(hidden_states.shape[1])

TRF047

Penugasan flag ke atribut self di metode preprocess, preprocess, call dan post_process* di image_processing.py dan videoprocessing.py. Processor yang membawa state antar pemanggilan merusak batching preprocess-banyak-lalu-postprocess: preprocess kedua menimpa state yang dibutuhkan oleh postprocess pertama. Kembalikan nilainya atau lewati melalui rantai metode.

def _preprocess(self, images, **kwargs):
-    self.original_sizes = [image.shape[-2:] for image in images]
+    original_sizes = [image.shape[-2:] for image in images]
     ...
+    return BatchFeature(data={"pixel_values": pixel_values, "original_sizes": original_sizes})

TRF048

Menandai literal list/tuple/set dalam deklarasi _tied_weights_keys pada level kelas. v5 mengubah _tied_weights_keys menjadi dict yang memetakan setiap parameter target yang diikat ke sumbernya. Bentuk list tidak lagi menunjukkan parameter mana yang menjadi sumber, sehingga proses pengikatan, perhitungan device_map, dan penyimpanan menjadi tidak berfungsi secara diam-diam.

class AcmeForCausalLM(AcmePreTrainedModel):
-    _tied_weights_keys = ["lm_head.weight"]
+    _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}

TRF049

Panggilan init di metode init pada modeling*.py dan modular.py: primitif nn.init. / init.* dan inisialisator in-place pada parameter sendiri (self.weight.data.normal_()). Model diinstansiasi pada perangkat meta, sehingga nilai tensor yang ditulis di init akan dibuang sebelum dimuat: parameter yang hanya diinisialisasi di sana akan berisi konten acak saat fine-tuning dari awal atau setelah muat ulang perangkat meta. Alokasikan dengan torch.empty di init, dan inisialisasi di _init_weights.

class AcmeEmbeddings(nn.Module):
     def __init__(self, config):
         super().__init__()
         self.position_embedding = nn.Parameter(torch.empty(config.num_positions, config.hidden_size))
-        nn.init.trunc_normal_(self.position_embedding, std=config.initializer_range)

 class AcmePreTrainedModel(PreTrainedModel):
     def _init_weights(self, module):
         super()._init_weights(module)
+        if isinstance(module, AcmeEmbeddings):
+            init.trunc_normal_(module.position_embedding, std=self.config.initializer_range)

TRF050

Flags panggilan ke kelas *RotaryEmbedding* di init dari kelas-kelas yang namanya diakhiri dengan Attention. Model memiliki satu rotary_emb, membangun inv_freq sekali, dan meneruskan cos/sin ke bawah sebagai position_embeddings. Satu modul rotary per lapisan attention akan menduplikasi buffer, menghitung ulang frekuensi per lapisan, dan menyimpang dari kontrak bahwa attention menerima position_embeddings.

class AcmeAttention(nn.Module):
     def __init__(self, config, layer_idx):
         super().__init__()
-        self.rotary_emb = AcmeRotaryEmbedding(config)

 class AcmeModel(AcmePreTrainedModel):
     def __init__(self, config):
         super().__init__(config)
+        self.rotary_emb = AcmeRotaryEmbedding(config)

TRF051

Perbandingan flag terhadap atribut attn_implementation dalam modeling.py dan modular_.py. Dispatch backend berada di ALL_ATTENTION_FUNCTIONS.get_interface, dan manipulasi tensor yang bergantung pada backend (padding, reshaping) berada di wrapper bersama di bawah integrations/. Percabangan inline membuat inti model tetap sadar akan kernel, tetapi akan rusak saat backend baru didaftarkan.

-if self.config._attn_implementation == "flash_attention_2":
-    attn_output = flash_path(query_states, key_states, value_states)
-else:
-    attn_output = eager_path(query_states, key_states, value_states)
+attention_interface = 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, ...)

TRF052

Flags penugasan pada level modul ke nama-nama yang diakhiri dengan ATTENTION_CLASSES di modeling.py dan modular_.py. Kelas attention per-backend yang dipilih dari sebuah dict adalah idiom pra-interface: kelas-kelas yang hampir identik akan menyimpang satu sama lain, dan kernel attention hub yang didaftarkan ke ALL_ATTENTION_FUNCTIONS tidak pernah mencapai kelas-kelas tersebut. Satu kelas attention yang melakukan dispatch melalui interface menggantikan dict tersebut; jangan propagasikan dari parent legacy.

-ACME_ATTENTION_CLASSES = {
-    "eager": AcmeAttention,
-    "flash_attention_2": AcmeFlashAttention2,
-    "sdpa": AcmeSdpaAttention,
-}
+class AcmeAttention(nn.Module):
+    def forward(self, ...):
+        attention_interface = ALL_ATTENTION_FUNCTIONS.get_interface(self.config._attn_implementation, eager_attention_forward)

TRF053

Dalam modeling*.py dan modular*.py, penugasan flag yang membangun shiftlogits/shift_labels (dan varian shifted) melalui slicing, seperti labels[…, 1:], akan ditandai. Menerima label yang sudah digeser (shift_labels = kwargs.pop(“shift_labels”, labels)) adalah idiom yang benar dan tidak ditandai. self.loss_function menggeser label secara mandiri, sehingga menggeser sebelumnya dalam kode modeling akan melatih pada target yang digeser dua kali atau memaksa jalur loss khusus. Model decoder-only meneruskan label mentah dan membiarkan loss menggesernya. Model encoder-decoder adalah kasus cerminnya: label mereka sudah digeser oleh token awal decoder yang ditambahkan di depan, sehingga mereka meneruskan shift_labels=labels untuk menghentikan loss menggeser lagi.

if labels is not None:
-    shift_logits = logits[..., :-1, :].contiguous()
-    shift_labels = labels[..., 1:].contiguous()
-    loss = nn.functional.cross_entropy(shift_logits.view(-1, self.config.vocab_size), shift_labels.view(-1))
+    # decoder-only: labels are unshifted, the loss shifts them
+    loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size)
+    # encoder-decoder: labels are already shifted, hand them over as shift_labels
+    loss = self.loss_function(logits=logits, labels=labels, shift_labels=labels, vocab_size=self.config.vocab_size)

TRF055

Flags config = SomeConfig sebagai atribut kelas pada subclass PreTrainedModel di modeling*.py dan modular*.py. PreTrainedModel.__init_subclass__ menurunkan config_class dari config annotation, melalui inspect.get_annotations(cls). Penugasan membuat atribut kelas yang tidak dilaporkan oleh call tersebut, sehingga subclass secara diam-diam mempertahankan config_class dari parent. Annotation polos tidak memiliki nilai runtime, tidak membuat atribut, dan diambil dengan benar.

class Gemma4VisionModel(Gemma4PreTrainedModel):
     """The Gemma 4 Vision Encoder."""
-    config = Gemma4VisionConfig
+    config: Gemma4VisionConfig

TRF056

Dalam modeling*.py dan modular*.py, flag .item() dan .tolist() dipanggil di dalam forward mana pun. Panggilan .tolist() yang memasok argumen ukuran split untuk split(...) dikecualikan: torch.split membutuhkan int Python. Kedua panggilan ini membaca tensor kembali ke host, yang tidak dapat ditelusuri oleh dynamo, sehingga graf terputus.

-        for grid, item in zip(grid_thw.tolist(), split_items):
-            _, height, width = grid
-            merged.append(self.patch_merger(item, size=(height, width)))
+        for grid, item in zip(grid_thw, split_items):
+            merged.append(self.patch_merger(item, size=(grid[1], grid[2])))

TRF057

Melakukan pemeriksaan @auto_docstring pada subkelas publik PreTrainedModel (<Model>PreTrainedModel, <Model>Model, <Model>For<Task>, backbones), subkelas PreTrainedConfig, subkelas ModelOutput, image processors dan subkelas ProcessorMixin, serta pada metode publik mereka forward, get_image_features, get_video_features, get_audio_features, get_text_features, preprocess dan __call__. Sebuah modular_*.py diperiksa terhadap file yang dihasilkan darinya. Tanpa file ini, sebuah kelas akan dirilis tanpa pendahuluan dan tanpa dokumentasi parameter, serta sebuah metode akan dirilis tanpa dokumentasi argumen, tanpa bagian Returns dan tanpa contoh penggunaan — semua hal tersebut kemudian harus ditulis secara manual untuk setiap model, alih-alih berasal dari auto_docstring.py.

+@auto_docstring
 @dataclass
 class AcmeModelOutputWithPast(ModelOutput):
     logits: torch.Tensor | None = None

+@auto_docstring
 class AcmeForConditionalGeneration(AcmePreTrainedModel):
+    @auto_docstring
     def forward(self, input_ids, pixel_values=None, **kwargs):
         ...

TRF058

Dalam modeling*.py dan modular*.py, flag register_buffer("<name>", ...) dipanggil untuk nama buffer yang berupa string literal, pada penerima apa pun (self, atau modul lain seperti layer.mamba). Nama yang dihitung — variabel atau f-string, misalnya satu buffer per layer di dalam loop — tidak memiliki ekuivalen penugasan atribut dan dikecualikan. Karena torch>=2.5, nn.Buffer mendaftarkan buffer melalui penugasan atribut biasa, seperti nn.Parameter. Buffer yang dibuat oleh pemanggilan metode hanya ada sebagai efek samping dari menjalankan __init__, sehingga file modular yang ingin menyesuaikan satu buffer harus mendefinisikan ulang seluruh __init__. Jika ditugaskan sebagai atribut, buffer tersebut dapat diwarisi dan ditimpa secara mandiri.

-        self.register_buffer("inv_freq", inv_freq, persistent=False)
-        self.register_buffer(
-            "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
-        )
+        self.inv_freq = nn.Buffer(inv_freq, persistent=False)
+        self.position_ids = nn.Buffer(torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False)

TRF059

Untuk direktori model yang rencana tensor-parallel-nya menetapkan moe_tp_experts, periksa bahwa kelas *Experts yang di-routed menerima hidden states, indeks top-k, dan bobot routing top-k sebagai tiga argumen posisional pertama forward. Alias seperti selected_experts dan routing_weights diterima. MoeExpertsParallel menerapkan transformasi gradien pada argumen posisional ke-3. Tanda tangan yang berbeda akan menerapkannya secara diam-diam ke tensor yang salah atau melewatkan transformasi tersebut.

class AcmeExperts(nn.Module):
-    def forward(self, hidden_states):
+    def forward(self, hidden_states, top_k_index, top_k_weights):
         ...

Menekan pelanggaran

Jika Anda perlu menekan pelanggaran aturan, gunakan salah satu dari dua opsi di bawah ini.

Penekanan inline

Tambahkan komentar # trf-ignore: RULE_ID pada baris yang melanggar. Sertakan penjelasan agar reviewer memahami mengapa penekanan tersebut dibenarkan.

# trf-ignore: TRF011 — mask is derived from self.config, not the layer
hidden_states = layer(hidden_states, attention_mask=mask_from_config)

Jangan gunakan trf-ignore untuk membungkam pelanggaran yang seharusnya diperbaiki di kode.

allowlist_models

Untuk model dengan kode lama yang tidak dapat diperbaiki segera, tambahkan nama direktori model tersebut ke daftar allowlist_models pada aturan terkait di mlinter rules.toml.

[rules.TRF004]
allowlist_models = ["existing_model", "your_model_name"]
Update on GitHub