Transformers documentation

Kotak perkakas untuk debugging 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.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Kotak perkakas untuk debugging model

Halaman ini mencantumkan semua alat debugging dan penambahan model yang digunakan oleh pustaka, serta fungsi utilitas yang disediakan untuknya.

Sebagian besar dari hal tersebut hanya berguna jika Anda menambahkan model baru ke dalam pustaka.

Debugger penambahan model

Debugger penambahan model - context manager untuk penambah model

Context manager ini adalah alat untuk pengguna lanjutan yang ditujukan bagi pengembang model. Alat ini melacak semua pemanggilan forward di dalam forward model dan mencatat potongan dari setiap input dan output pada JSON bersarang. Perlu dicatat bahwa context manager ini menerapkan torch.no_grad().

Rasional

Saat memindahkan model ke Transformers, bahkan dari Python ke Python, pengembang model sering kali harus melakukan banyak operasi manual, seperti menyimpan dan memuat tensor, membandingkan dtype, dan sebagainya. Alat kecil ini diharapkan dapat memangkas sebagian waktu tersebut.

Penggunaan

Tambahkan context manager ini sebagai berikut untuk men-debug model:

import torch
from PIL import Image
import requests
from transformers import LlavaProcessor, LlavaForConditionalGeneration
from transformers.model_debugging_utils import model_addition_debugger_context
torch.random.manual_seed(673)

# load pretrained model and processor
model_id = "llava-hf/llava-1.5-7b-hf"
processor = LlavaProcessor.from_pretrained(model_id)
model = LlavaForConditionalGeneration.from_pretrained(model_id)

# create random image input
random_image = Image.fromarray(torch.randint(0, 256, (224, 224, 3), dtype=torch.uint8).numpy())

# prompt
prompt = "<image>Describe this image."

# process inputs
inputs = processor(text=prompt, images=random_image, return_tensors="pt")

# call forward method (not .generate!)
with model_addition_debugger_context(
    model,
    debug_path="optional_path_to_your_directory",
    do_prune_layers=False # This will output ALL the layers of a model.
):
    output = model.forward(**inputs)

Membaca hasil

Debugger menghasilkan dua file dari panggilan forward, keduanya dengan nama dasar yang sama, tetapi diakhiri dengan _SUMMARY.json atau _FULL_TENSORS.json.

Yang pertama akan berisi ringkasan nilai dan bentuk tensor input dan output dari setiap modul.

{
  "module_path": "MolmoForConditionalGeneration",
  "inputs": {
    "args": [],
    "kwargs": {
      "input_ids": {
        "shape": "torch.Size([1, 589])",
        "dtype": "torch.int64"
      },
      "attention_mask": {
        "shape": "torch.Size([1, 589])",
        "dtype": "torch.int64"
      },
      "pixel_values": {
        "shape": "torch.Size([1, 5, 576, 588])",
        "dtype": "torch.float32",
        "mean": "tensor(-8.9514e-01, device='cuda:0')",
        "std": "tensor(9.2586e-01, device='cuda:0')",
        "min": "tensor(-1.7923e+00, device='cuda:0')",
        "max": "tensor(1.8899e+00, device='cuda:0')"
    }
  },
  "children": [
    {
      "module_path": "MolmoForConditionalGeneration.language_model.model.embed_tokens",
      "inputs": {
        "args": [
          {
            "shape": "torch.Size([1, 589])",
            "dtype": "torch.int64"
          }
        ]
      },
      "outputs": {
        "shape": "torch.Size([1, 589, 3584])",
        "dtype": "torch.float32",
        "mean": "tensor(6.5460e-06, device='cuda:0')",
        "std": "tensor(2.3807e-02, device='cuda:0')",
        "min": "tensor(-3.3398e-01, device='cuda:0')",
        "max": "tensor(3.9453e-01, device='cuda:0')"
      }
    },
    {
      "module_path": "MolmoForConditionalGeneration.vision_tower",
      "inputs": {
        "args": [
          {
            "shape": "torch.Size([5, 1, 576, 588])",
            "dtype": "torch.float32",
            "mean": "tensor(-8.9514e-01, device='cuda:0')",
            "std": "tensor(9.2586e-01, device='cuda:0')",
            "min": "tensor(-1.7923e+00, device='cuda:0')",
            "max": "tensor(1.8899e+00, device='cuda:0')"
          }
        ],
        "kwargs": {
          "output_hidden_states": "True"
        }
      },
      "children": [
        { ... and so on

File _FULL_TENSORS.json akan menampilkan tampilan lengkap dari semua tensor, yang berguna untuk membandingkan dua file.

      "pixel_values": {
        "shape": "torch.Size([1, 5, 576, 588])",
        "dtype": "torch.float32",
        "value": [
          "tensor([[[[-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          ...,",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00]],",
          "",
          "         [[-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          ...,",
          "          [-1.4857e+00, -1.4820e+00, -1.2100e+00,  ..., -6.0979e-01, -5.9650e-01, -3.8527e-01],",
          "          [-1.6755e+00, -1.7221e+00, -1.4518e+00,  ..., -7.5577e-01, -7.4658e-01, -5.5592e-01],",
          "          [-7.9957e-01, -8.2162e-01, -5.7014e-01,  ..., -1.3689e+00, -1.3169e+00, -1.0678e+00]],",
          "",
          "         [[-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          ...,",
          "          [-3.0322e-01, -5.0645e-01, -5.8436e-01,  ..., -6.2439e-01, -7.9160e-01, -8.1188e-01],",
          "          [-4.4921e-01, -6.5653e-01, -7.2656e-01,  ..., -3.4702e-01, -5.2146e-01, -5.1326e-01],",
          "          [-3.4702e-01, -5.3647e-01, -5.4170e-01,  ..., -1.0915e+00, -1.1968e+00, -1.0252e+00]],",
          "",
          "         [[-1.1207e+00, -1.2718e+00, -1.0678e+00,  ..., 1.2013e-01, -1.3126e-01, -1.7197e-01],",
          "          [-6.9738e-01, -9.1166e-01, -8.5454e-01,  ..., -5.5050e-02, -2.8134e-01, -4.2793e-01],",
          "          [-3.4702e-01, -5.5148e-01, -5.8436e-01,  ..., 1.9312e-01, -8.6235e-02, -2.1463e-01],",
          "          ...,",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00]],",
          "",
          "         [[-1.0039e+00, -9.5669e-01, -6.5546e-01,  ..., -1.4711e+00, -1.4219e+00, -1.1389e+00],",
          "          [-1.0039e+00, -9.5669e-01, -6.5546e-01,  ..., -1.7193e+00, -1.6771e+00, -1.4091e+00],",
          "          [-1.6317e+00, -1.6020e+00, -1.2669e+00,  ..., -1.2667e+00, -1.2268e+00, -8.9720e-01],",
          "          ...,",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00],",
          "          [-1.7923e+00, -1.7521e+00, -1.4802e+00,  ..., -1.7923e+00, -1.7521e+00, -1.4802e+00]]]], device='cuda:0')"
        ],
        "mean": "tensor(-8.9514e-01, device='cuda:0')",
        "std": "tensor(9.2586e-01, device='cuda:0')",
        "min": "tensor(-1.7923e+00, device='cuda:0')",
        "max": "tensor(1.8899e+00, device='cuda:0')"
      },

Menyimpan tensor ke disk

Beberapa penambah model mungkin diuntungkan oleh pencatatan nilai tensor penuh ke disk untuk mendukung, misalnya, analisis numerik di antara implementasi.

Setel use_repr=False untuk menulis tensor ke disk menggunakan SafeTensors.

with model_addition_debugger_context(
    model,
    debug_path="optional_path_to_your_directory",
    do_prune_layers=False,
    use_repr=False,   # Defaults to True
):
    output = model.forward(**inputs)

Saat menggunakan use_repr=False, tensor ditulis ke lokasi disk yang sama dengan file _SUMMARY.json dan _FULL_TENSORS.json. Properti value dari entri dalam file _FULL_TENSORS.json akan berisi referensi path relatif ke file .safetensors yang terkait. Setiap tensor ditulis ke file miliknya sendiri sebagai properti data dari state dictionary. Nama file dibangun menggunakan module_path sebagai awalan dengan beberapa kemungkinan akhiran yang dibangun secara rekursif.

  • Input modul ditandai dengan _inputs dan output dengan _outputs.
  • Instans list dan tuple, seperti args atau nilai pengembalian fungsi, akan diberi akhiran _{index}.
  • Instans dict akan diberi akhiran _{key}.

Membandingkan antar implementasi

Setelah forward passes dari dua model ditelusuri oleh debugger, file output json dapat dibandingkan. Lihat di bawah: kita dapat melihat perbedaan kecil pada lapisan proyeksi key dari kedua implementasi ini. Inputnya sebagian besar identik, tetapi tidak sepenuhnya. Menelusuri perbedaan dalam file memudahkan penentuan lapisan mana yang salah.

download-icon

Batasan dan cakupan

Fitur ini hanya akan berfungsi untuk model berbasis torch. Model yang sangat bergantung pada panggilan kernel eksternal mungkin tetap berfungsi, tetapi trace kemungkinan akan melewatkan beberapa hal. Terlepas dari itu, implementasi python mana pun yang bertujuan meniru implementasi lain dapat ditrace sekali alih-alih dijalankan ulang N kali dengan breakpoint.

Jika Anda meneruskan do_prune_layers=False ke model debugger Anda, SEMUA layer akan dioutput ke json. Sebaliknya, hanya layer pertama dan terakhir yang akan ditampilkan. Hal ini berguna ketika beberapa layer (biasanya cross-attention) hanya muncul setelah N layer.

transformers.model_addition_debugger_context

< >

( modeldebug_path: str | None = Nonedo_prune_layers: bool = Trueuse_repr: bool = True )

Debugger penambahan model - context manager untuk penambah model

Context manager ini adalah alat untuk pengguna lanjutan yang ditujukan bagi pengembang model.

It melacak semua panggilan forward di dalam forward model dan mencatat potongan dari setiap input dan output pada file JSON bersarang. Jika use_repr=True (default), file JSON akan merekam versi repr()-ized dari tensor sebagai daftar string. Jika use_repr=False, tensor penuh akan disimpan dalam file SafeTensors terpisah dan file JSON akan menyediakan path relatif ke file tersebut.

Perlu dicatat, context manager ini menerapkan torch.no_grad().

Penggunaan

tambahkan context manager ke model untuk debug

import torch

from PIL import Image
from transformers import LlavaProcessor, LlavaForConditionalGeneration, model_addition_debugger_context

torch.random.manual_seed(673)

# load pretrained model and processor
model_id = "llava-hf/llava-1.5-7b-hf"
processor = LlavaProcessor.from_pretrained(model_id)
model = LlavaForConditionalGeneration.from_pretrained(model_id)

# create random image input
random_image = Image.fromarray(torch.randint(0, 256, (224, 224, 3), dtype=torch.uint8).numpy())

# prompt
prompt = "<image>Describe this image."

# process inputs
inputs = processor(text=prompt, images=random_image, return_tensors="pt")

# call forward method (not .generate!)
with model_addition_debugger_context(model, debug_path="Your_debug_path", do_prune_layers=False):
    output = model.forward(**inputs)

Analyzer dari tes yang dilewati

Pindai tes yang dilewati - untuk penambah dan pemelihara model

Util kecil ini adalah alat untuk pengguna lanjutan yang ditujukan bagi pihak yang menambahkan dan memelihara model. Util ini mendaftar semua metode uji yang ada di test_modeling_common.py, yang diwarisi oleh semua kelas pengujian model, dan memindai repositori untuk mengukur berapa banyak uji yang dilewati dan untuk model mana saja.

Rasional

Saat memindahkan model ke transformers, tes gagal sebagaimana mestinya, dan terkadang test_modeling_common terasa tidak dapat didamaikan dengan kekhasan model baru kami. Namun, bagaimana kita bisa yakin bahwa kita tidak merusak segalanya dengan menambahkan skip yang tampak tidak berbahaya?

Utilitas ini:

  • memindai semua metode test_modeling_common
  • mencari waktu di mana sebuah metode dilewati
  • mengembalikan ringkasan json yang dapat Anda muat sebagai DataFrame/memeriksanya

Sebagai contoh, test_inputs_embeds dilewati dengan proporsi yang sangat besar, yaitu 39%, pada saat utilitas ini ditulis.

download-icon

Penggunaan

Anda dapat menjalankan analyzer test yang dilewati dengan dua cara:

Pindai penuh (default)

Dari root repo transformers, memindai semua metode pengujian umum dan mengoutputkan hasilnya ke file JSON (default: all_tests_scan_result.json).

python utils/scan_skipped_tests.py --output_dir path/to/output
  • --output_dir (opsional): Direktori tempat hasil JSON disimpan. Bawaan adalah direktori saat ini.

Contoh output:

πŸ”¬ Parsing 331 model test files once each...
πŸ“ Aggregating 224 tests...
  (224/224) test_update_candidate_strategy_with_matches_1es_3d_is_nonecodet_schedule_fa_kwargs
βœ… Scan complete.

πŸ“„ JSON saved to /home/pablo/git/transformers/all_tests_scan_result.json

Dan akan menghasilkan file all_tests_scan_result.json yang dapat Anda periksa. JSON diindeks berdasarkan nama metode, dan setiap entri mengikuti skema ini, yang juga menunjukkan asalnya (dari common atau GenerationMixin.)

{
  "<method_name>": {
    "origin": "<test suite>"
    "models_ran": ["<model_name>", ...],
    "models_skipped": ["<model_name>", ...],
    "skipped_proportion": <float>,
    "reasons_skipped": ["<model_name>: <reason>",
      ...
    ]
  },
  ...
}

Yang dapat Anda visualisasikan seperti di atas dengan, misalnya, pandas

df = pd.read_json('all_tests_scan_result.json').T
df.sort_values(by=['skipped_proportion'], ascending=False)

Pindai satu metode pengujian

Anda dapat berfokus pada metode pengujian tertentu menggunakan --test_method_name:

python utils/scan_skipped_tests.py --test_method_name test_inputs_embeds --output_dir path/to/output
  • --test_method_name: Nama metode pengujian yang akan dipindai (misalnya, test_inputs_embeds).
  • --output_dir (opsional): Direktori tempat hasil JSON akan disimpan.

Contoh output:

$ python utils/scan_skipped_tests.py --test_method_name test_inputs_embeds

πŸ”¬ Parsing 331 model test files once each...

== test_inputs_embeds ==

Ran    : 199/323
Skipped : 124/323 (38.4%)
 - aimv2: Aimv2 does not use inputs_embeds
 - align: Inputs_embeds is tested in individual model tests
 - altclip: Inputs_embeds is tested in individual model tests
 - audio_spectrogram_transformer: AST does not use inputs_embeds
 - beit: BEiT does not use inputs_embeds
 - bit: Bit does not use inputs_embeds
 - blip: Blip does not use inputs_embeds
 - blip_2: Inputs_embeds is tested in individual model tests
 - bridgetower:
 - canine: CANINE does not have a get_input_embeddings() method.
 - ...

πŸ“„ JSON saved to /home/pablo/git/transformers/scan_test_inputs_embeds.json

Detektor model modular

Analisis kesamaan kode - untuk penambah model

Utilitas ini menganalisis kemiripan kode antara implementasi model untuk mengidentifikasi peluang modularisasi. Utilitas ini membandingkan file pemodelan baru atau yang sudah ada dengan semua model di pustaka menggunakan metrik kemiripan berbasis embedding dan berbasis token.

Rasional

Saat menambahkan model baru ke Transformers, banyak komponen (lapisan perhatian, MLP, output, dll.) mungkin sudah ada dalam bentuk serupa di model lain. Alih-alih mengimplementasikan semuanya dari awal, penambah model dapat mengidentifikasi kelas mana yang serupa dan berpotensi dapat digunakan kembali melalui modularisasi.

Alat ini menghitung dua skor kemiripan:

  • Skor embedding: Menggunakan embedding kode semantik (melalui Qwen/Qwen3-Embedding-4B) untuk mendeteksi kode yang secara fungsional serupa meskipun memiliki penamaan yang berbeda
  • Skor Jaccard: Mengukur tumpang tindih himpunan token untuk mengidentifikasi pola kode yang serupa secara struktural

Skor 1.00 berarti kode tersebut identik.

Penggunaan

Dari root repositori transformers:

python utils/modular_model_detector.py --modeling-file path/to/modeling_file.py

Alat ini akan secara otomatis mengunduh indeks yang sudah dibangun sebelumnya dari Hub (memerlukan RAM/VRAM untuk model embedding).

Contoh output:

Loading checkpoint shards: 100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 2/2 [00:00<00:00, 33.62it/s]
encoding 21 query definitions with Qwen/Qwen3-Embedding-4B (device=cuda, batch=16, max_length=4096)

stuff.py::Beit3ImageTextMatchingOutput:
embedding:
    blip_2::Blip2ImageTextMatchingModelOutput (0.9994)
    chinese_clip::ChineseCLIPOutput (0.9818)
    owlvit::OwlViTOutput (0.9818)
jaccard:
    owlv2::Owlv2Output (0.9667)
    metaclip_2::MetaClip2Output (0.9667)
    altclip::AltCLIPOutput (0.9667)
intersection:
    blip::BlipOutput
    owlvit::OwlViTOutput

stuff.py::Beit3MLP:
embedding:
    efficientloftr::EfficientLoFTRMLP (0.9718)
    seggpt::SegGptMlp (0.9650)
jaccard:
    chinese_clip::ChineseCLIPTextSelfOutput (0.5294)
    bert::BertSelfOutput (0.5294)
intersection:

Bidang intersection menampilkan kelas yang muncul di kedua hasil top-5, menunjukkan tingkat kepercayaan tinggi untuk kandidat modularisasi.

Membangun indeks kustom

Untuk membangun ulang indeks dari basis kode lokal Anda (berguna setelah menambahkan model baru atau menggunakan model embedding yang berbeda):

python utils/modular_model_detector.py --build

Untuk mendorong indeks yang dibangun ulang ke dataset Hub:

python utils/modular_model_detector.py --build --push-new-index --hub-dataset your-org/your-dataset

Opsi

  • --modeling-file: Path ke file modeling yang akan dianalisis
  • --build: Membangun indeks kemiripan kode dari semua file pemodelan di src/transformers/models/
  • --push-new-index: Setelah membangun, dorong indeks ke dataset Hub (memerlukan --build)
  • --hub-dataset: ID repositori dataset Hub untuk menarik/mengirimkan indeks (default: hf-internal-testing/transformers_code_embeddings)

Keterbatasan

Alat ini memerlukan sumber daya GPU/CPU untuk menjalankan model embedding (Qwen/Qwen3-Embedding-4B). Indeks yang sudah dibangun diunduh dari Hub secara default, yang memerlukan koneksi internet pada penggunaan pertama.

Hasil adalah saran berdasarkan kemiripan kode dan harus ditinjau secara manual sebelum modularisasi. Skor kemiripan yang tinggi tidak menjamin kompatibilitas yang sempurna.

Update on GitHub