Transformers documentation
كتابة اختبارات النموذج
كتابة اختبارات النموذج
تستخدم مجموعة اختبارات Transformers بنية مبنية على مزيج (mixin) لتوليد أكثر من 100 اختبار تلقائيًا من الحد الأدنى من الكود. تكتب كمية صغيرة من الكود الخاص بالنموذج، ويتولى المزيج (mixins) مهام الحفظ/التحميل، والتوليد، والخطوط الأنابيب (pipelines)، والتدريب، والتوازي على مستوى الموترات (tensor parallelism).
شغّل اختبارات نموذجك باستخدام الأوامر التالية.
# run your model's tests
pytest tests/models/mymodel/test_modeling_mymodel.py -v
# run a specific test
pytest tests/models/mymodel/test_modeling_mymodel.py::MyModelTest::test_model
# run tests matching a keyword pattern (useful to run all integration tests)
pytest tests/models/mymodel/ -k integration -v
# include slow integration tests
RUN_SLOW=1 pytest tests/models/mymodel/ -vتشغّل منظومة Hugging Face CI اختبارات النماذج دون @slow مع كل طلب سحب، بينما تُنفَّذ الاختبارات البطيئة وفق جدول ليلي (راجع فحوصات طلبات السحب لمعرفة ما تتحقق منه منظومة CI).
اختر فئة اختبار أساسية
تغطي ثلاث فئات أساسية أكثر عائلات النماذج شيوعاً. اختر الفئة التي تتوافق مع نمط نموذجك.
| الفئة الأساسية | يُستخدم | مزيج |
|---|---|---|
CausalLMModelTest | نماذج اللغة السببية | ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin, TrainingTesterMixin, TensorParallelTesterMixin |
VLMModelTest | نماذج الرؤية واللغة | ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin |
ALMModelTest | نماذج اللغة والصوت | ModelTesterMixin, GenerationTesterMixin, PipelineTesterMixin |
يتشارك VLMModelTest وALMModelTest في الوالد المشترك MultiModalModelTest الذي يُضمّن الإعدادات الفرعية داخل إعداد علوي مركّب، ويضع رموز المحلّلات الخاصة بالأنماط في input_ids إلى جانب ميزات النمط الخام (الصوت أو الرؤية). لا يستخدم CausalLMModelTest الوالد متعدد الأنماط. بل يُبنى على المزيجات الثلاث المشتركة ويضيف TrainingTesterMixin وTensorParallelTesterMixin لتغطية التدريب والتوازي على مستوى المصفوفات.
بالنسبة إلى البنى المعمارية التي لا تنتمي إلى أيٍّ من الأنماط الثلاثة (المُشفِّر فقط، المُشفِّر-المُفكِّك، إلخ)، قم ببناء بنية الاختبار مباشرةً من نمط الصنفين ومزيجات الاختبار الموضّحة أدناه.
CausalLMModelTest
CausalLMModelTest هي الفئة الأساسية الموصى بها لاختبار نماذج اللغة السببية. ترث من خمسة مزيج اختبارات وتولّد الاختبارات تلقائيًا للحفظ/التحميل، والتوليد، والخطوط الأنابيب، والتدريب، والتوازي على مستوى الموترات.
import unittest
from transformers.testing_utils import require_torch
from transformers import is_torch_available
from ...causal_lm_tester import CausalLMModelTest, CausalLMModelTester
if is_torch_available():
from transformers import MyModel
class MyModelTester(CausalLMModelTester):
if is_torch_available():
base_model_class = MyModel
@require_torch
class MyModelTest(CausalLMModelTest, unittest.TestCase):
model_tester_class = MyModelTesterتوفر هاتان الصنفان تغطية اختبارية كاملة لـ MyModel وجميع أصناف رؤوسه (MyModelForCausalLM، MyModelForSequenceClassification، إلخ). راجع tests/models/llama/test_modeling_llama.py للحصول على مثال حقيقي.
يتطلب CausalLMModelTester فقط base_model_class. يقوم المُختبِر بإزالة لاحقة Model للحصول على الاسم الأساسي (حيث يصبح LlamaModel هو Llama)، ثم يضيف لواحق مثل Config أو ForCausalLM لاكتشاف الفئات ذات الصلة. إذا لم تكن الفئة موجودة في الوحدة، يبقى الخاصية None ويتخطى المُختبِر الاختبارات المقابلة.
التجاوز عن القيم الافتراضية في CausalLMTester
إذا لم يتبع نموذجك التسمية القياسية، أو كنت بحاجة إلى تخصيص السلوك، فقم بتجاوز السمات على المُختبِر أو فئة الاختبار.
class MyModelTester(CausalLMModelTester):
if is_torch_available():
base_model_class = MyModel
# override if the class name doesn't follow the convention
causal_lm_class = MyCustomCausalLM
@require_torch
class MyModelTest(CausalLMModelTest, unittest.TestCase):
model_tester_class = MyModelTester
# disable embedding resize tests
test_resize_embeddings = Falseبالنسبة إلى النماذج التي تتطلب معلمات مُخصّصة لمُنشئ الاختبار، تجاوز __init__ واستدعِ super().__init__(parent=parent) قبل تعيين السمات الإضافية. راجع tests/models/youtu/test_modeling_youtu.py كمثال حقيقي.
class YoutuModelTester(CausalLMModelTester):
if is_torch_available():
base_model_class = YoutuModel
def __init__(self, parent, kv_lora_rank=16, q_lora_rank=32):
super().__init__(parent=parent)
self.kv_lora_rank = kv_lora_rank
self.q_lora_rank = q_lora_rankVLMModelTest
VLMModelTest هي الفئة الأساسية لنماذج الرؤية واللغة. ترث من ثلاثة امتزاجات (ModelTesterMixin، GenerationTesterMixin، PipelineTesterMixin) وتضبط _is_composite = True للتعامل مع عدة نماذج فرعية.
import unittest
from transformers.testing_utils import require_torch
from transformers import is_torch_available
from ...vlm_tester import VLMModelTest, VLMModelTester
if is_torch_available():
from transformers import (
MyVLMConfig,
MyVLMModel,
MyVLMTextConfig,
MyVLMVisionConfig,
MyVLMForConditionalGeneration,
)
class MyVLMTester(VLMModelTester):
if is_torch_available():
base_model_class = MyVLMModel
config_class = MyVLMConfig
text_config_class = MyVLMTextConfig
vision_config_class = MyVLMVisionConfig
conditional_generation_class = MyVLMForConditionalGeneration
@require_torch
class MyVLMTest(VLMModelTest, unittest.TestCase):
model_tester_class = MyVLMTesterتجاوز القيم الافتراضية في VLMModelTester
عندما يحتاج نموذج VLM إلى معلمات رؤية مخصصة أو قيم إعدادات غير افتراضية، قم بتجاوز __init__. اضبط القيم الافتراضية باستخدام setdefault قبل استدعاء super().__init__(parent, **kwargs). يُظهر المثال أدناه بعض القيم الافتراضية الأولى من tests/models/qianfan_ocr/test_modeling_qianfan_ocr.py.
class QianfanOCRVisionText2TextModelTester(VLMModelTester):
base_model_class = QianfanOCRModel
config_class = QianfanOCRConfig
text_config_class = Qwen3Config
vision_config_class = QianfanOCRVisionConfig
conditional_generation_class = QianfanOCRForConditionalGeneration
def __init__(self, parent, **kwargs):
kwargs.setdefault("image_token_id", 1)
kwargs.setdefault("image_size", 32)
kwargs.setdefault("patch_size", 4)
kwargs.setdefault("num_channels", 3)
# ... more defaults
super().__init__(parent, **kwargs)تختلف اختبارات VLM عن CausalLMModelTest في عدة نقاط.
- يجب عليك تعيين
config_classوtext_config_classوvision_config_classوconditional_generation_classعلى المُختبِر. - لا يتضمن
VLMModelTestأيًا منTrainingTesterMixinأوTensorParallelTesterMixin. - يقبل
__init__الخاص بالمختبر معاملات الرؤية (image_size،patch_size،num_channels،num_image_tokens) من**kwargsوsetdefault(). ConfigTesterيستخدمhas_text_modality=Falseلأن الإعداد العلوي هو إعداد مركّب وليس إعداد نموذج نصي.
ALMModelTest
ALMModelTest هي الفئة الأساسية لنماذج الصوت واللغة (ALMs) مثل Qwen2Audio وAudioFlamingo3 وGraniteSpeech. وهي تعكس نمط نماذج الرؤية واللغة (VLM) مع الفئة الأم MultiModalModelTest نفسها واكتشاف تلقائي لفئات الرؤوس. يتم استبدال آلية جانب الرؤية بخصائص صوتية، وتكوين فرعي للصوت، واستراتيجية لتوزيع رموز الصوت.
class MyALMTester(ALMModelTester):
config_class = MyALMConfig
text_config_class = MyALMTextConfig
audio_config_class = MyALMAudioConfig
conditional_generation_class = MyALMForConditionalGeneration
audio_mask_key = "feature_attention_mask"
class MyALMTest(ALMModelTest, unittest.TestCase):
model_tester_class = MyALMTesterتجاوز القيم الافتراضية في ALMModelTester
يُعيّن __init__ الخاصّ بالاختبار الافتراضيات المحددة لـ ALM (feat_seq_length=128، num_mel_bins=80، audio_token_id=0). عاود ضبطها باستخدام setdefault قبل استدعاء super().__init__(parent, **kwargs).
يُخبر سِمَتان من سِمات الفئة المُختبِرَ كيف يُسمّي نموذجك الأشياء.
audio_mask_key: اسم معامل الكلمة الذي يتوقعه النموذج الخاص بك للقناع الصوتي ("feature_attention_mask"،"input_features_mask"، إلخ). اتركهNoneإذا كان نموذجك لا يستهلك قناعًا صوتيًا منفصلًا.audio_config_key: اسم الخاصية التي يستخدمها الإعداد الرئيسي لتضمين إعداد الصوت الفرعي. القيمة الافتراضية هي"audio_config"لكن نماذج مثل GraniteSpeech تستخدم"encoder_config".
class Qwen2AudioModelTester(ALMModelTester):
def __init__(self, parent, **kwargs):
kwargs.setdefault("feat_seq_length", 60)
kwargs.setdefault("max_source_positions", kwargs["feat_seq_length"] // 2)
super().__init__(parent, **kwargs)يتطلب ALMModelTester منك تجاوز خطاف واحد، وهو get_audio_embeds_mask(audio_mask)، كما يعرض خطافات اختيارية إضافية للتخصيص.
get_audio_embeds_mask(audio_mask): تُرجع قناع مواضع تضمينات الصوت لكل دفعة بعد عملية تقليل العينات في المُشفِّر. يستخدم المُختبِر مجموع هذا القناع على مستوى الصفوف لتحديد عدد عناصرaudio_token_idالتي يجب إدراجها فيinput_ids، لذا يجب أن يتطابق هذا العدد مع ما يُخرجه مُشفِّرك.create_audio_features(): تُرجع متجه ميزات الصوت. الشكل الافتراضي هو[batch_size, num_mel_bins, feat_seq_length]. تجاوز هذا الدالة إذا كان نموذجك، مثل GraniteSpeech، يتوقع ميزات ذات أولوية زمنية ([batch_size, feat_seq_length, num_mel_bins]).create_audio_mask(): تُرجع قناع الانتباه على مستوى الصوت. يقوم الإعداد الافتراضي ببناء منطقة صالحة متصلة عشوائياً لكل صف في الدفعة. استبدله بقناع حتمي بطول كامل إذا كانت اختباراتك تقارن بين استدعائين لـprepare_config_and_inputs_for_common()، أو إذا كان مُرمِّز الصوت لديك يُحوَّل إلى واجهة خلفية ترفض الأقنعة غير الفارغة.place_audio_tokens(input_ids, config, num_audio_tokens): يضع رموز المحلّلات الصوتية بشكل متتالي بعدBOS. لا تُعدّل هذا الدالة إلا إذا كان نموذجك يتطلب تخطيطًا مختلفًا.get_audio_feature_key(): تُرجع مفتاح قاموس المدخلات الخاص بسمات الصوت (افتراضيًا"input_features").
بالإضافة إلى اختبارات الوسائط المتعددة الموروثة، يضيف ALMModelTest الاختبار test_mismatching_num_audio_tokens. يتحقق هذا الاختبار من أن النموذج يرمي ValueError واضحاً عندما لا يتطابق عدد ميزات الصوت مع عدد رموز الوكيل الصوتية في input_ids، ويتأكد من أن الموجّه الذي يحتوي على مقاطع صوتية متعددة يمرر بنجاح.
اكتب اختبارات لمعماريات أخرى
للمعماريات غير القياسية مثل معماريات المُشفِّر فقط، أو المُشفِّر-المُفكِّك، أو الصوتية، أو غيرها، قم ببناء بنية الاختبار مباشرةً من نمط الصنفين ومزيجات الاختبار (test mixins) الموضحة أدناه.
ModelTester و ModelTest
يتبع كل ملف اختبار للنموذج نفس البنية.
ModelTester(فئة عادية) تنشئ إعدادات صغيرة ومدخلات وهمية للاختبار، كما يمكنها استضافة اختبارات انحدار صغيرة خاصة بالنموذج.ModelTest(المشتق منunittest.TestCaseمع مزيج من الخصائص) يرث الاختبارات المولّدة تلقائيًا وينفّذها على كل متغيّر من نماذج النموذج.
يستدعي ModelTest الدالة prepare_config_and_inputs_for_common() على المُختبِر (tester) للحصول على مجموعة مرتبة من نوع (config, inputs_dict). وتعتمد جميع الإضافات (mixins) على prepare_config_and_inputs_for_common() للحصول على بيانات الاختبار.
اختبار المزيج
اختر الإضافات التي يحتاجها نموذجك.
| مزيج | ملف المصدر | ما يختبره |
|---|---|---|
ModelTesterMixin | tests/test_modeling_common.py | الحفظ/التحميل، نقطة التفتيش للتدرّج، توقيع الدالة الأمامية، السمات الشائعة |
GenerationTesterMixin | tests/generation/test_utils.py | الطمع، العينة، البحث الحزمي، فك الترميز المساعد |
PipelineTesterMixin | tests/test_pipeline_mixin.py | اختبار واحد لكل مهمة خط أنابيب |
TrainingTesterMixin | tests/test_training_mixin.py | الانحياز على دفعة صغيرة |
TensorParallelTesterMixin | tests/test_tensor_parallel_mixin.py | التوازي الموزّع للتّنسورات |
كتابة اختبار للنموذج
راجع tests/models/modernbert/test_modeling_modernbert.py للحصول على مثال عملي كامل. الخطوات الأساسية مبيّنة أدناه.
تقوم فئة
ModelTesterببناء إعدادات صغيرة ومدخلات وهمية. حافظ على الأبعاد صغيرة حتى تنتهي الاختبارات خلال ثوانٍ على المعالج المركزي. استخدم أدوات المصفوفات الثلاثة أدناه لبناء المدخلات.ids_tensor(shape, vocab_size): مصفوفة أعداد صحيحة عشوائية ضمن[0, vocab_size). تُستخدم معinput_idsوtoken_type_idsومصفوفات التسميات.random_attention_mask(shape): مصفوفة ثنائية (تتكون من أصفار وواحدات) يكون فيها الرمز الأول دائماً 1. يُستخدم لـattention_mask.floats_tensor(shape, scale=1.0): مصفوفة عشوائية من الأعداد العشرية. تُستخدم للمدخلات المستمرة مثلpixel_valuesأوinputs_embeds.
يجب على المُختبِر تنفيذ
get_config()وprepare_config_and_inputs()وprepare_config_and_inputs_for_common(). أضف دوالcreate_and_check_*لكل رأس مهمة (النموذج الأساسي، تصنيف التسلسل، تصنيف الرموز، إلخ).ورث من المزيجات (mixins) التي يحتاجها نموذجك، وعرّف
all_model_classesوpipeline_model_mapping، وحددsetUp(). اكتب دوالtest_*تفوّض المهمة إلى دوالcreate_and_check_*الخاصة بالفاحص (tester).لكل رأس مهمة، أضف طريقة
create_and_check_*على المُختبِر تُنشئ النموذج، وتُنفّذ تمريرة أمامية، وتتحقق من أشكال المخرجات. ثم أضف طريقةtest_*مقابلة على فئة الاختبار.
تنظيم الملفات
توجد ملفات الاختبار في tests/models/mymodel/ وفقاً للهيكل الموضح أدناه.
tests/models/mymodel/ ├── __init__.py ├── test_modeling_mymodel.py # model tests (required) ├── test_tokenization_mymodel.py # tokenizer tests (if custom tokenizer) ├── test_image_processing_mymodel.py # image processor tests (if vision model) ├── test_feature_extraction_mymodel.py # feature extractor tests (if audio/speech model) └── test_processing_mymodel.py # processor tests (if multimodal)
تتبع اختبارات المُجزِّئ (Tokenizer) النمط نفسه. ورِّث TokenizerTesterMixin من tests/test_tokenization_common.py، واضبط بعض السمات، لتحصل على اختبارات مُولَّدة تلقائيًا. راجع tests/models/llama/test_tokenization_llama.py كمثال.
اختبارات الإعداد
يتحقق ConfigTester من أن فئة الإعدادات تتعامل مع التسلسل، والحفظ/التحميل، والخصائص القياسية بشكل صحيح. تتضمن CausalLMModelTest وVLMModelTest اختبارات الإعدادات تلقائيًا. بالنسبة للمسار العام باستخدام ModelTester وModelTest، عرّف مُختبِر الإعدادات يدويًا في setUp().
from tests.test_configuration_common import ConfigTester
def setUp(self):
self.config_tester = ConfigTester(self, config_class=MyModelConfig, hidden_size=32)
def test_config(self):
self.config_tester.run_common_tests()run_common_tests() ينفّذ عدة فحوصات.
- يتحقق من وجود خصائص شائعة مثل
hidden_sizeوnum_attention_headsوnum_hidden_layers(وvocab_sizeإذا كانhas_text_modality=True). - يختبر تسلسل JSON باستخدام
to_json_string()وto_json_file(). - تُعيد
save_pretrained()وfrom_pretrained()إلى الحالة الأصلية. - يتحقق من اتساق
id2labelوlabel2id. - ينشئ تكوينًا دون أي حُجج للتحقق من التهيئة الافتراضية.
- يُعيّن معاملات مشتركة مثل
output_hidden_statesويتحقق من تخزينها بشكل صحيح.
مرّر has_text_modality=False للنماذج البصرية فقط التي تفتقر إلى vocab_size، ومرّر **kwargs إضافية لتجاوز الإعدادات الافتراضية.
self.config_tester = ConfigTester(
self, config_class=MyVisionConfig, has_text_modality=False, hidden_size=64
)اختبارات التكامل والنماذج الصغيرة
تستخدم اختبارات المزيج (Mixin tests) إعدادات صغيرة بأوزان عشوائية للتحقق من سلوك النموذج بسرعة. أما اختبارات التكامل (Integration tests) فتشغّل الاستدلال (inference) باستخدام أوزان مُسبقة التدريب الفعلية للتحقق من صحة المخرجات. النماذج الصغيرة على Hub صغيرة الحجم بما يكفي لاختبارات CI السريعة، لكنها مُنظّمة على غرار نقاط التفتيش (checkpoints) الفعلية.
كتابة اختبارات التكامل
ضع اختبارات التكامل في فئة اختبار منفصلة، وعلّمها بـ @slow، وأدرج MemoryCleanupMixin. يقوم كل اختبار بتنزيل أوزان حقيقية، وتشغيل الاستدلال، والتحقق من المخرجات مقابل القيم المتوقعة. يحرر المزيج الذاكرة التي يستهلكها كل اختبار، وينفّذ طرق الاختبار تحت torch.no_grad() — راجع إطلاق الذاكرة بين الاختبارات لمعرفة ما يفعله وكيفية الاستثناء منه.
import torch
from transformers import AutoTokenizer
from transformers.testing_utils import MemoryCleanupMixin, require_torch, slow, torch_device
class MyModelIntegrationTest(MemoryCleanupMixin, unittest.TestCase):
@slow
@require_torch
def test_inference(self):
model = MyModelForCausalLM.from_pretrained("myorg/mymodel-base").to(torch_device)
tokenizer = AutoTokenizer.from_pretrained("myorg/mymodel-base")
inputs = tokenizer("Hello, world", return_tensors="pt").to(torch_device)
outputs = model(**inputs)
# check against expected values
expected_slice = torch.tensor([[-0.1234, 0.5678, -0.9012]])
torch.testing.assert_close(outputs.logits[0, :1, :3], expected_slice, atol=1e-4, rtol=1e-4)علّم أي اختبار بـ @slow إذا كان يقوم بتنزيل الأوزان، أو تحميل مجموعة بيانات كبيرة، أو يستغرق أكثر من بضع ثوانٍ. يتخطى اختبار CI الخاص بطلب السحب الاختبارات البطيئة، لكن الجدولة الليلية تشغّلها.
إفراج عن الذاكرة بين الاختبارات
تحمّل اختبارات التكامل نقاط تفتيش حقيقية، لذا فإن اختباراً يحتفظ بمراجع إلى نموذج يمكن أن يستهلك كل الذاكرة المتاحة لأي عملية تُنفَّذ بعده. يتولى MemoryCleanupMixin، الموجود في tests/test_memory_cleanup_mixin.py، معالجة ذلك على مستوى الفئة بأكملها:
- يُنفّذ
cleanup(torch_device, gc_collect=True)قبل وبعد كل اختبار حتى لا تنتقل أي بقايا. - يحذف السمات التي أضافها الاختبار على
self(بما في ذلك كاشات@cached_property) وعلى الفئة (على سبيل المثالcls.model = ...فيsetUpClass). يحافظ Pytest على بقاء كائنات الاختبار حية طوال الجلسة، لذا لا يمكن لـgc.collect()تحرير الكائنات التي لا تزال هذه المراجع تحتفظ بها. - تشغّل طرق الاختبار تحت
torch.no_grad()حتى لا تحتفظ عملية المرور الأمامي بالتفعيلات.
تضبط الفئات التي تُدرّب أو تستدعي backward() قيمة run_under_no_grad = False. أما الفئة التي تجمع بين الأمرين فتضع @with_grad أو @with_no_grad على طرق الاختبار الفردية بدلاً من ذلك.
تُحفظ السمات المُعيَّنة في جسم الفئة، بينما تُهمل كل ما يُضاف لاحقًا. إذا تجاوزت setUp، فاستدعِ super().setUp(): إذ يلتقط المزيج (mixin) سمات الكائن هناك، وسيُصدر خطأً في حال عدم استدعائه.
يجمع
MemoryCleanupTestCaseبين المكوّن المختلط (mixin) وTestCasePlus، وذلك للاختبارات التي ترغب أيضًا في إزالة المجلدات المؤقتة تلقائيًا.
لاستخراج اختبار تسرّب، اضبط TRANSFORMERS_TEST_MEMORY_LEAK_MIB على ميزانية محددة بوحدة ميغابايت؛ وسيتم الإبلاغ عن أي اختبار يترك تخصيصًا أكبر من ذلك على الجهاز مع ذكر ذروة استهلاكه. أضف TRANSFORMERS_TEST_MEMORY_LEAK_MODE=error لتحويل التحذير إلى فشل. هذا الفحص معطّل افتراضيًا، وينبغي تفعيله عند البحث عن بقايا الذاكرة. كما أن عملية التفكيك المعتادة في الميكس-إن تشغّل gc.collect، مما قد يؤدي إلى مسح التخصيص الذي ترغب في فحصه أثناء إعادة إنتاج التسرّب.
اختبارات تكامل التوليد
استخدم do_sample=False في اختبارات التوليد حتى تكون المخرجات حتمية عبر التكرارات والأجهزة. بالنسبة لنماذج مزيج الخبراء، استدعِ أيضاً model.set_experts_implementation("eager") قبل التوليد لفرض مسار ثابت لتوجيه الخبراء. بدونه، قد تُغيّر الفروق العددية الصغيرة في الموجّه الخبير الذي يتولى معالجة الرمز، مما يغيّر المخرجات.
@slow
@require_torch
def test_generate(self):
model = MyModelForCausalLM.from_pretrained("myorg/mymodel-base").to(torch_device)
tokenizer = AutoTokenizer.from_pretrained("myorg/mymodel-base")
inputs = tokenizer("Hello, world", return_tensors="pt").to(torch_device)
# model.set_experts_implementation("eager") # uncomment for MoE models
generated_ids = model.generate(**inputs, max_new_tokens=20, do_sample=False)
output = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)
self.assertEqual(output, ["Hello, world! This is the expected continuation..."])التوقعات الخاصة بالمعدات
تُنفّذ اختبارات CI الخاصة بـ Transformers الاختبارات البطيئة على بطاقة NVIDIA A10. قد تختلف النتائج العددية قليلاً بين أجيال وحدات معالجة الرسوميات (GPU)، لذا تستخدم اختبارات التكامل فئة Expectations لتسجيل القيم المتوقعة لكل جهاز. تختار Expectations التطابق الأنسب للأجهزة الحالية بناءً على مفاتيح SM من نوع (device_type, (major, minor))، وتلجأ إلى قيمة افتراضية عند عدم وجود تطابق.
شغّل torch.cuda.get_device_capability() لطباعة إصدار SM المحلي لديك (مثل (8, 6) لبطاقة A10، أو (9, 0) لبطاقة H100).
from transformers.testing_utils import Expectations
expected_texts = Expectations(
{
("cuda", (8, 6)): ["Hello, world! This is the A10 continuation..."],
("cuda", (9, 0)): ["Hello, world! This is the H100 continuation..."],
}
).get_expectation()
self.assertEqual(output, expected_texts)إنشاء نماذج صغيرة
توجد نماذج صغيرة ذات أوزان عشوائية على الـ Hub ضمن منظمة hf-internal-testing. تعتمد اختبارات خطوط الأنابيب على النماذج الصغيرة عندما تحتاج إلى نقطة تفتيش مستضافة على الـ Hub دون الاهتمام بجودة المخرجات. كما تُحمّل اختبارات الدخان السريعة النماذج الصغيرة للتحقق من أشكال المرور الأمامي دون الحاجة إلى تنزيل نقاط تفتيش كبيرة.
تُعدّ النماذج الصغيرة الملاذ الأخير لاختبارات التكامل. لا تستخدمها إلا عندما يتجاوز أصغر نقطة تفتيش (checkpoint) المتاحة حوالي 24 غيغابايت من ذاكرة الفيديو (VRAM). استخدم الأوزان المُسبقة التدريب الأصلية، كلما أمكن ذلك، للكشف عن الانحسارات العددية الحقيقية.
ينشئ السكربت utils/create_dummy_models.py نماذج صغيرة من ModelTester.get_config(). يستخرج السكربت المعاملات الفائقة الصغيرة من مُختبِرك، ويبني نموذجًا بأوزان عشوائية، ثم يرفع النتيجة إلى Hub.
أنشئ نماذج صغيرة محليًا.
python utils/create_dummy_models.py output_dir -m your_model_type
ارفعها إلى Hub.
python utils/create_dummy_models.py output_dir -m your_model_type --upload --organization hf-internal-testing
يستخدم كل نموذج الاسم hf-internal-testing/tiny-random-{ModelClassName} ويُسجَّل في tests/utils/tiny_model_summary.json. يقوم سير عمل CI (.github/workflows/check_tiny_models.yml) بإعادة توليد النماذج الصغيرة يوميًا.
تحكّم في ما يتم اختباره
تتحكم الأعلام المنطقية على ModelTesterMixin في الاختبارات المولَّدة تلقائيًا. يمكنك تجاوز أي علم في فئة الاختبار الخاصة بك لتفعيل أو تعطيل فحوصات محددة.
class MyModelTest(CausalLMModelTest, unittest.TestCase):
model_tester_class = MyModelTester
test_resize_embeddings = False
test_all_params_have_gradient = False # when not all parameters are activated in every forward pass| علم | افتراضي | ما يتحكم به |
|---|---|---|
test_resize_embeddings | True | تغيير حجم طبقة التضمين |
test_resize_position_embeddings | False | تغيير حجم تضمين الموقع |
test_mismatched_shapes | True | معالجة الأشكال غير المتطابقة للمدخلات/المخرجات |
test_missing_keys | True | تحذيرات مفاتيح مفقودة عند التحميل |
test_torch_exportable | True | التوافق مع torch.export |
test_all_params_have_gradient | True | تستقبل جميع المعاملات التدرجات (اضبط False عندما لا يتم تفعيل جميع المعاملات في كل تمريرة أمامية، كما هو الحال مع خبراء MoE) |
is_encoder_decoder | False | اختبارات محددة لمعمارية المُشفِّر-المُفكِّك |
has_attentions | True | اختبارات مخرجات الانتباه |
_is_composite | False | معالجة النماذج المركبة/المتعددة الوسائط |
model_split_percents | [0.5, 0.7, 0.9] | نسب التقسيم لاختبارات توازي النموذج |
الخطوات التالية
- تصفّح وثائق pytest لمزيد من المعلومات حول اختيار الاختبارات، والتثبيتات، والتسجيل، والمزيد.