Transformers documentation
Bộ công cụ gỡ lỗi mô hình
Bộ công cụ gỡ lỗi mô hình
Trang này liệt kê tất cả các công cụ gỡ lỗi và thêm mô hình được thư viện sử dụng, cũng như các hàm tiện ích mà nó cung cấp.
Phần lớn những điều đó chỉ hữu ích nếu bạn đang thêm các mô hình mới vào thư viện.
Trình gỡ lỗi thêm mô hình
Trình gỡ lỗi thêm mô hình - trình quản lý ngữ cảnh cho các trình thêm mô hình
Context manager này là công cụ dành cho người dùng nâng cao, được thiết kế cho những người thêm model. Nó theo dõi tất cả các lời gọi forward bên trong một forward của model và ghi log một phần (slice) của mỗi input và output vào một JSON lồng nhau. Lưu ý rằng context manager này ép buộc torch.no_grad().
Lý do
Khi chuyển các mô hình sang transformers, ngay cả khi chuyển từ python sang python, những người thêm mô hình thường phải thực hiện nhiều thao tác thủ công, bao gồm lưu và nạp tensor, so sánh dtype, v.v. Công cụ nhỏ này hy vọng có thể giúp tiết kiệm một ít thời gian.
Cách sử dụng
Thêm trình quản lý ngữ cảnh này như sau để gỡ lỗi một mô hình:
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)
Đọc kết quả
Bộ gỡ lỗi tạo ra hai tệp từ lời gọi forward, cả hai đều có cùng tên cơ sở, nhưng kết thúc bằng _SUMMARY.json hoặc _FULL_TENSORS.json.
Phần đầu tiên sẽ chứa tóm tắt về giá trị và hình dạng của tensor đầu vào và đầu ra của từng module.
{
"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 onTệp _FULL_TENSORS.json sẽ hiển thị toàn bộ các tensor, rất hữu ích để so sánh hai tệp.
"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')"
},Lưu tensor vào đĩa
Một số người thêm model có thể được hưởng lợi từ việc ghi log giá trị tensor đầy đủ xuống đĩa để hỗ trợ, ví dụ, phân tích số học giữa các triển khai.
Đặt use_repr=False để ghi các tensor ra đĩa bằng 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)Khi sử dụng use_repr=False, các tensor được ghi vào cùng vị trí trên đĩa với các tệp _SUMMARY.json và _FULL_TENSORS.json. Thuộc tính value của các mục trong tệp _FULL_TENSORS.json sẽ chứa tham chiếu đường dẫn tương đối đến tệp .safetensors liên quan. Mỗi tensor được ghi vào tệp riêng của nó dưới dạng thuộc tính data của từ điển trạng thái. Tên tệp được xây dựng bằng cách sử dụng module_path làm tiền tố cùng một vài hậu tố có thể, được xây dựng đệ quy.
- Đầu vào của module được ký hiệu bằng
_inputsvà đầu ra bằng_outputs. - Các instance của
listvàtuple, chẳng hạn nhưargshoặc giá trị trả về của hàm, sẽ được thêm hậu tố_{index}. - Các instance
dictsẽ được thêm hậu tố_{key}.
So sánh giữa các bản triển khai
Sau khi các bước truyền tiến (forward passes) của hai mô hình đã được debugger theo dõi, ta có thể so sánh các tệp đầu ra json. Xem bên dưới: ta có thể thấy những khác biệt nhỏ giữa lớp dự đoán khóa (key projection layer) của hai cài đặt này. Đầu vào phần lớn là giống hệt nhau, nhưng không hoàn toàn. Việc xem xét các khác biệt trong tệp giúp dễ dàng xác định chính xác lớp nào đang có lỗi.

Hạn chế và phạm vi
Tính năng này chỉ hoạt động với các mô hình dựa trên torch. Các mô hình phụ thuộc nhiều vào các lệnh gọi kernel bên ngoài có thể hoạt động, nhưng trace có thể bỏ sót một số thứ. Dù vậy, bất kỳ cài đặt python nào nhằm mô phỏng một cài đặt khác đều có thể được trace một lần thay vì chạy lại N lần với các điểm dừng.
Nếu bạn truyền do_prune_layers=False cho trình gỡ lỗi mô hình của bạn, TẤT CẢ các lớp sẽ được xuất ra json. Ngược lại, chỉ lớp đầu tiên và lớp cuối cùng sẽ được hiển thị. Điều này hữu ích khi một số lớp (thường là cross-attention) chỉ xuất hiện sau N lớp.
transformers.model_addition_debugger_context
< source >( modeldebug_path: str | None = Nonedo_prune_layers: bool = Trueuse_repr: bool = True )
Trình gỡ lỗi thêm mô hình - trình quản lý ngữ cảnh cho các trình thêm mô hình
Trình quản lý ngữ cảnh này là công cụ dành cho người dùng nâng cao, được thiết kế cho những người thêm mô hình.
Nó theo dõi tất cả các lời gọi forward trong một forward của model và ghi lại một phần của mỗi đầu vào và đầu ra vào một tệp JSON lồng nhau.
Nếu use_repr=True (mặc định), tệp JSON sẽ ghi lại phiên bản được repr()- hóa của các tensor dưới dạng một danh sách các chuỗi. Nếu use_repr=False, các tensor đầy đủ sẽ được lưu trong các tệp SafeTensors riêng biệt và tệp JSON sẽ cung cấp đường dẫn tương đối đến tệp đó.
Lưu ý rằng trình quản lý ngữ cảnh này thực thi torch.no_grad().
Cách sử dụng
thêm context manager vào một model để gỡ lỗi
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)Trình phân tích các bài kiểm thử bị bỏ qua
Quét các bài kiểm tra bị bỏ qua - dành cho người thêm và người duy trì model
Công cụ tiện ích nhỏ này là một công cụ dành cho người dùng nâng cao, được thiết kế cho những người thêm và bảo trì model. Nó liệt kê tất cả các phương thức kiểm thử có trong test_modeling_common.py, được kế thừa bởi tất cả các lớp tester của model, và quét kho mã để đo lường số lượng kiểm thử bị bỏ qua và cho những model nào.
Lý do
Khi port các model sang transformers, các test sẽ thất bại như dự kiến, và đôi khi test_modeling_common có vẻ không thể dung hòa với những đặc thù của model hoàn toàn mới của chúng ta. Nhưng làm sao chúng ta có thể chắc chắn rằng mình không phá hỏng mọi thứ khi thêm một skip có vẻ vô hại?
Công cụ tiện ích này:
- quét tất cả các phương thức test_modeling_common
- tìm kiếm các thời điểm mà một phương thức bị bỏ qua
- trả về một tệp json tóm tắt mà bạn có thể tải lên như một DataFrame/xem xét
Ví dụ, test_inputs_embeds bị bỏ qua với tỷ lệ lên đến 39% tại thời điểm viết tiện ích này.

Cách sử dụng
Bạn có thể chạy trình phân tích kiểm thử bị bỏ qua theo hai cách:
Quét đầy đủ (mặc định)
Từ thư mục gốc của repo transformers, quét tất cả các phương thức kiểm thử phổ biến và xuất kết quả ra tệp JSON (mặc định: all_tests_scan_result.json).
python utils/scan_skipped_tests.py --output_dir path/to/output
--output_dir(tùy chọn): Thư mục nơi kết quả JSON sẽ được lưu. Mặc định là thư mục hiện tại.
Kết quả đầu ra mẫu:
🔬 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
Và nó sẽ tạo ra tệp all_tests_scan_result.json để bạn kiểm tra. JSON được lập chỉ mục theo tên phương thức, và mỗi mục tuân theo schema này, đồng thời chỉ rõ nguồn gốc (từ common hoặc GenerationMixin.)
{
"<method_name>": {
"origin": "<test suite>"
"models_ran": ["<model_name>", ...],
"models_skipped": ["<model_name>", ...],
"skipped_proportion": <float>,
"reasons_skipped": ["<model_name>: <reason>",
...
]
},
...
}Bạn có thể trực quan hóa điều này như ở trên, ví dụ bằng pandas
df = pd.read_json('all_tests_scan_result.json').T
df.sort_values(by=['skipped_proportion'], ascending=False)
Quét một phương thức kiểm thử
Bạn có thể tập trung vào một phương thức kiểm thử cụ thể bằng cách sử dụng --test_method_name:
python utils/scan_skipped_tests.py --test_method_name test_inputs_embeds --output_dir path/to/output
--test_method_name: Tên của phương thức kiểm tra cần quét (ví dụ:test_inputs_embeds).--output_dir(tùy chọn): Thư mục nơi kết quả JSON sẽ được lưu.
Kết quả đầu ra mẫu:
$ 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
Trình phát hiện mô-đun
Trình phân tích độ tương đồng mã - dành cho người thêm mô hình
Công cụ tiện ích này phân tích sự tương đồng mã giữa các cài đặt mô hình để xác định các cơ hội cho việc mô-đun hóa. Nó so sánh một tệp modeling mới hoặc hiện có với tất cả các mô hình trong thư viện bằng cách sử dụng các chỉ số tương đồng dựa trên embedding và dựa trên token.
Lý do
Khi thêm một mô hình mới vào transformers, nhiều thành phần (lớp attention, MLP, đầu ra, v.v.) có thể đã tồn tại dưới dạng tương tự trong các mô hình khác. Thay vì triển khai mọi thứ từ đầu, người thêm mô hình có thể xác định các lớp hiện có nào tương tự và có khả năng tái sử dụng thông qua việc mô-đun hóa.
Công cụ tính toán hai điểm số tương tự:
- Điểm nhúng: Sử dụng nhúng mã ngữ nghĩa (thông qua
Qwen/Qwen3-Embedding-4B) để phát hiện mã có chức năng tương tự ngay cả khi đặt tên khác nhau - Điểm Jaccard: Đo mức độ chồng chéo của tập token để xác định các mẫu mã có cấu trúc tương tự
Điểm 1.00 có nghĩa là mã giống hệt nhau.
Cách sử dụng
Từ thư mục gốc của kho transformers:
python utils/modular_model_detector.py --modeling-file path/to/modeling_file.py
Công cụ sẽ tự động tải xuống chỉ mục đã được xây dựng sẵn từ Hub (yêu cầu RAM/VRAM cho mô hình nhúng).
Kết quả đầu ra mẫu:
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:Trường intersection hiển thị các lớp xuất hiện trong cả hai kết quả top-5, cho thấy độ tin cậy cao đối với các ứng viên modularization.
Xây dựng chỉ mục tùy chỉnh
Để xây dựng lại chỉ mục từ mã nguồn cục bộ của bạn (hữu ích sau khi thêm các mô hình mới hoặc sử dụng một mô hình nhúng khác):
python utils/modular_model_detector.py --build
Để đẩy chỉ mục đã xây dựng lại lên bộ dữ liệu Hub:
python utils/modular_model_detector.py --build --push-new-index --hub-dataset your-org/your-dataset
Tùy chọn
--modeling-file: Đường dẫn đến tệp modeling cần phân tích--build: Xây dựng chỉ mục tương đồng mã từ tất cả các tệp mô hình hóa trongsrc/transformers/models/--push-new-index: Sau khi xây dựng, đẩy index lên một dataset trên Hub (yêu cầu--build)--hub-dataset: ID kho dữ liệu Hub để kéo/đẩy chỉ mục (mặc định:hf-internal-testing/transformers_code_embeddings)
Hạn chế
Công cụ này yêu cầu tài nguyên GPU/CPU để chạy mô hình embedding (Qwen/Qwen3-Embedding-4B). Chỉ mục được xây dựng sẵn sẽ được tải xuống từ Hub theo mặc định, điều này đòi hỏi kết nối internet khi sử dụng lần đầu.
Kết quả là các gợi ý dựa trên độ tương đồng của mã và nên được xem xét thủ công trước khi thực hiện modularization. Điểm số tương đồng cao không đảm bảo khả năng tương thích hoàn hảo.
Update on GitHub