Transformers documentation

إضافة نموذج باستخدام محولات معيارية

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

إضافة نموذج باستخدام محولات معيارية

يقلل Modular transformers من الكود المطلوب لإضافة نموذج من خلال السماح بالاستيراد والإرث، على عكس سياسة النموذج الواحد، الملف الواحد. بدلاً من تكرار مكوّنات النموذج عبر الملفات، أضف ملف modular إلى مجلد نموذجك وارث من الفئات الموجودة.

يولّد المحوّل ملفات مستقلة من الملف المعياري. يحصل المستخدمون على واجهة الملف الواحد نفسها التي يعرفونها مسبقًا.

لا يُقصد بـ Modular transformers أن يحل محل كود النمذجة القديم. إذا لم يكن نموذجك مبنياً على نموذج قائم مسبقاً، أضف ملف modeling.py يدوياً. وينطبق الأمر نفسه على ملفات الإعداد أو الترميز أو المعالجة التي لا يمكنها الوراثة بشكل نظيف من ملف مشابه.

لا يوجد ترتيب صحيح واحد أيضاً. بعض المساهمين يكتبون الملف المعياري أولاً ثم يولّدون منه. بينما يبدأ آخرون بـmodeling.py مكتوب يدوياً ويعيدون هيكليته إلى ملف معياري لاحقاً. كلا النهجين يعملان.

تنفيذ ملف معياري

ابدأ بالبحث عن نموذج في Transformers مشابه لنموذجك. من نقاط البداية الجيدة Mistral وQwen2 وCohere وCohere2 وLlama. يوضح الجدول أدناه المكوّنات الشائعة والنماذج التي يمكنك الوراثة منها.

مكوّنالنموذج
مزيج الخبراءMixtral أو Qwen2-MoE
تضمين دوّار متناوب (و/أو جزئي)GLM، Phi
نماذج فضاء الحالةJamba, Bamba, Zamba, Mamba2
حالات المخفي المتكررةGemma2
أنماط الانتباه النافذي المتحرك/الانتباه الكامل لكل طبقةGemma2، Cohere2
قص QKVOlmo
تطبيع QKOlmo2، Cohere
دمج QKV (غير موصى به)Phi3

استخدم أداة modular-detector-v2 للعثور على تنفيذهات موجودة يمكن الوراثة منها. الصق مقتطفًا من الكود وستُرجع الأداة أكثر الطرق تشابهًا الموجودة مسبقًا في Transformers، مما يتيح لك تحديد أفضل فئة أم قبل أن تبدأ في الكتابة.

لا تعدّل نموذجًا قائمًا فقط لجعل الوراثة تعمل لنموذجك الجديد. إذا كان إعادة تسمية فئة الوالد أو إنشاء فئة فرعية منها أمرًا غير مريح، فقم بنسخ الكود ذي الصلة مباشرةً بدلاً من ذلك.

أنشئ src/transformers/models/<name>/modular_<name>.py، حيث يتطابق <name> مع اسم مجلد النموذج بصيغة snake_case. تستعرض هذه القسم كيفية تنفيذ Olmo2 انطلاقاً من Olmo باستخدام النهج المعياري (راجع الملف الأصلي modular_olmo2.py).

إعداد

يوجد نقطتان يختلف فيهما Olmo2Config عن OlmoConfig.

  1. يوجد حجة جديدة، rms_norm_eps.
  2. لم يعد يُستخدم الحجة clip_qkv.

أعلن عن الحُجج الجديدة كإشارات نوع على مستوى الفئة مع قيمة افتراضية. أما بالنسبة للحُجج المُزالة، فعيّن AttributeError() لكبح الخاصية الموروثة في الملف المُولَّد (انظر إزالة الخصائص).

- @auto_docstring(checkpoint="allenai/OLMo-7B-hf")
+ @auto_docstring(checkpoint="allenai/Olmo2-7B-1124-hf")
+ @strict
- class OlmoConfig(PreTrainedConfig):
+ class Olmo2Config(OlmoConfig):
      ...
-     model_type = "olmo"
+     model_type = "olmo2"
      ...
+     rms_norm_eps: float = 1e-5
-     clip_qkv: float | None = None
+     clip_qkv = AttributeError()

@auto_docstring يولّد توثيق المعايير القياسية تلقائيًا (انظر دليل @auto_docstring). يرفض @strict معاملات kwargs غير المعروفة عند وقت الإنشاء، مما يكشف عن الأخطاء الإملائية والمعاملات القديمة مبكرًا. أضف كلاهما إلى كل فئة إعدادات، لأن الزخارف لا تُورَّث من الفئة الأم. اذكرها صراحةً حتى لو كانت فئة الإعدادات الأم تحتوي عليها بالفعل.

لضبط سمة مشتقة أو معالجة منطق التوافق العكسي، استخدم __post_init__ بدلاً من __init__. على سبيل المثال، يحسب Cohere2 قيمة head_dim ويستنتج layer_types عند التهيئة.

def __post_init__(self, **kwargs):
    if self.num_key_value_heads is None:
        self.num_key_value_heads = self.num_attention_heads
    self.head_dim = self.hidden_size // self.num_attention_heads
    super().__post_init__(**kwargs)

بالنسبة إلى النماذج التي تدعم توازي الموترات أو توازي خط الأنابيب، عرّف base_model_tp_plan وbase_model_pp_plan كقاموس على مستوى الفئة في الإعداد. يحدد كلا القاموسين كيفية تقسيم النموذج عبر الأجهزة. راجع الإعدادات الموجودة مثل Olmo2 أو Cohere2 كمثال.

class MyNewModelConfig(PreTrainedConfig):
    model_type = "my_new_model"

    # Tensor parallelism: maps layer name patterns to sharding strategies.
    # Use "colwise" / "rowwise" for standard sharding, or the "gather_output" /
    # "split_input" variants when an extra op (e.g. a QK norm) prevents fusing.
    base_model_tp_plan = {
        "layers.*.self_attn.q_proj": "colwise",
        "layers.*.self_attn.k_proj": "colwise",
        "layers.*.self_attn.v_proj": "colwise",
        "layers.*.self_attn.o_proj": "rowwise",
        "layers.*.mlp.gate_proj": "colwise",
        "layers.*.mlp.up_proj": "colwise",
        "layers.*.mlp.down_proj": "rowwise",
    }

    # Pipeline parallelism: maps submodule names to their (input, output) tensor names.
    base_model_pp_plan = {
        "embed_tokens": (["input_ids"], ["inputs_embeds"]),
        "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
        "norm": (["hidden_states"], ["hidden_states"]),
    }

الطبيعي

لنسخ فئة الوالد دون إجراء أي تغييرات، ورّث باستخدام pass. يقوم أداة الفحص بنسخ محتوى فئة الوالد وإعادة تسمية جميع المراجع لتتطابق مع النموذج الجديد.

from ..olmo.modeling_olmo import OlmoRotaryEmbedding

class Olmo2RotaryEmbedding(OlmoRotaryEmbedding):
    pass

لتغيير سلوك معيّن، ورّث وطبّق فقط ما يختلف. Olmo2RMSNorm يختلف عن LlamaRMSNorm في سطر واحد. يتم الضرب قبل إعادة التحويل إلى نوع بيانات الإدخال، وليس بعده.

  from ..llama.modeling_llama import LlamaRMSNorm

  class Olmo2RMSNorm(LlamaRMSNorm):
      def forward(self, hidden_states):
          input_dtype = hidden_states.dtype
          hidden_states = hidden_states.to(torch.float32)
          variance = hidden_states.pow(2).mean(-1, keepdim=True)
          hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
-         return self.weight * hidden_states.to(input_dtype)
+         return (self.weight * hidden_states).to(input_dtype)

الانتباه

انتباه Olmo2 مطابق لانتباه Olmo باستثناء تطبيقه RMSNorm على الاستعلامات والمفاتيح، وإزالة قصّ qkv. ينسخ super().__init__(...) جسم الوالد ويضيف سطري المعيار الجديدين. تم إعادة تعريف forward بالكامل لأن الاستعلامات والمفاتيح تمر الآن عبر المعايير قبل الإسقاط. كما يجلب أداة التدقيق أي دوال مستوردة إلى الملف المولّد، بما في ذلك apply_rotary_pos_emb وeager_attention_forward وتبعياتهما.

  class Olmo2Attention(OlmoAttention):
      def __init__(self, config: Olmo2Config, layer_idx: int | None = None):
          super().__init__(config, layer_idx=layer_idx)
+         self.q_norm = Olmo2RMSNorm(config.num_attention_heads * self.head_dim, config.rms_norm_eps)
+         self.k_norm = Olmo2RMSNorm(config.num_key_value_heads * self.head_dim, config.rms_norm_eps)

      def forward(self, ...):
          ...
-         query_states = self.q_proj(hidden_states)
-         key_states = self.k_proj(hidden_states)
+         query_states = self.q_norm(self.q_proj(hidden_states))
+         key_states = self.k_norm(self.k_proj(hidden_states))
          value_states = self.v_proj(hidden_states)

-         if self.config.clip_qkv is not None:
-             query_states.clamp_(min=-self.config.clip_qkv, max=self.config.clip_qkv)
-             key_states.clamp_(min=-self.config.clip_qkv, max=self.config.clip_qkv)
-             value_states.clamp_(min=-self.config.clip_qkv, max=self.config.clip_qkv)
-
          ...

DecoderLayer

بعد super().__init__(...)، استبدل سمات norm بمهام Olmo2RMSNorm وأعد إسناد self.self_attn إلى فئة Olmo2Attention الجديدة. يزيل del self.input_layernorm إسناد input_layernorm الخاص بالفئة الأم، لأن Olmo2 يطبّق norm بعد الانتباه وليس قبله. راجع إزالة السمات لمعرفة التفاصيل حول ما يزيله del وما لا يزيله.

يتم إعادة كتابة forward لتعكس موضع تطبيع ما بعد الانتباه. لا تكون إعادة كتابة forward ضرورية إلا عند إعادة تسمية خاصية، وليس عند تغيير نوعها فقط.

  class Olmo2DecoderLayer(OlmoDecoderLayer):
      def __init__(self, config: Olmo2Config, layer_idx: int):
          super().__init__(config, layer_idx=layer_idx)
-         self.self_attn = OlmoAttention(config=config, layer_idx=layer_idx)
-         self.input_layernorm = OlmoLayerNorm(config.hidden_size)
-         self.post_attention_layernorm = OlmoLayerNorm(config.hidden_size)
+         self.self_attn = Olmo2Attention(config=config, layer_idx=layer_idx)
+         del self.input_layernorm
+         self.post_attention_layernorm = Olmo2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
+         self.post_feedforward_layernorm = Olmo2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)

      def forward(self, ...):
          residual = hidden_states
-         hidden_states = self.input_layernorm(hidden_states)
          # Self Attention
          hidden_states, _ = self.self_attn(...)
-         hidden_states = residual + hidden_states
+         hidden_states = self.post_attention_layernorm(hidden_states)
+         hidden_states = residual + hidden_states

          # Fully Connected
          residual = hidden_states
-         hidden_states = self.post_attention_layernorm(hidden_states)
          hidden_states = self.mlp(hidden_states)
-         hidden_states = residual + hidden_states
+         hidden_states = self.post_feedforward_layernorm(hidden_states)
+         hidden_states = residual + hidden_states
          return hidden_states

النموذج

يتغير هنا نوع self.norm فقط. طريقة forward مطابقة لطريقة الأصل، لذا ينقلها أداة الفحص تلقائيًا.

  class Olmo2Model(OlmoModel):
      def __init__(self, config: Olmo2Config):
          super().__init__(config)
-         self.layers = nn.ModuleList(
-             [OlmoDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
-         )
-         self.norm = OlmoLayerNorm(config.hidden_size)
+         self.norm = Olmo2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
+         self.layers = nn.ModuleList(
+             [Olmo2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
+         )

رأس النموذج

المنطق مطابق تمامًا لـ OlmoForCausalLM، لذا لا حاجة إلى أي تغييرات.

from ..olmo.modeling_olmo import OlmoForCausalLM

class Olmo2ForCausalLM(OlmoForCausalLM):
    pass

فئات أخرى

يحتوي modeling_olmo2.py الذي أنشأه أداة فحص الأكواد أيضًا على فئات (Olmo2MLP، Olmo2RotaryEmbedding، Olmo2PreTrainedModel) لم تُعرَّف صراحةً في modular_olmo2.py.

يستورد أداة فحص الكود أي فئة تعتمد عليها فئة موروثة، ما لم تعيد تعريفها صراحةً. تتبع الدوال المستوردة مثل apply_rotary_pos_emb القاعدة نفسها.

على سبيل المثال، يحتوي OlmoDecoderLayer على self.mlp = OlmoMLP(config). لم يُعرَّف Olmo2MLP أبداً في الملف المعياري، لذا يقوم أداة الفحص بإنشائه تلقائياً، بما يعادل استخدام pass.

from ..olmo.modeling_olmo import OlmoMLP

class Olmo2MLP(OlmoMLP):
    pass

إذا كنت تريد أن يرث Olmo2MLP من نموذج مختلف بدلاً من ذلك، فكن صريحاً.

# switch to Mistral definition
from ..mistral.modeling_mistral import MistralMLP

class Olmo2MLP(MistralMLP):
    pass

إنهاء الملف

يجب أن يُعلن كل ملفٍ معياري عن logger وقائمة __all__ على مستوى الوحدة.

logger = logging.get_logger(__name__)

__all__ = [
    "Olmo2Config",
    "Olmo2ForCausalLM",
    "Olmo2Model",
    "Olmo2PreTrainedModel",
]

يجب أن تُدرج __all__ كل فئة عامة في الملف. يعتمد المحوّل والاستيرادات اللاحقة على ذلك. الفئة غير المدرجة في __all__ لن تُصدَّر بشكل صحيح.

إنشاء ملفات النمذجة

يولّد السكربت modular_model_converter.py ملفات مستقلة مثل modeling.py وconfiguration.py وملفات أخرى من ملفك المعياري. ولكل فئة موروثة، ينسخ جسم الفئة الأم إلى الفئة الابنة، ويعيد تسمية جميع المراجع لتتطابق مع النموذج الجديد، ويستورد أي دوال مساعدة أو فئات تعتمد عليها تلك الفئات الأم.

لا تحتوي ملفات المخرجات على أي استيرادات بين النماذج ولا على أي توريث من مديريات نماذج أخرى. يقوم المُفحِّص (linter) بتسوية التوريث إلى مستوى واحد. إذا كان Olmo2Attention يرث من OlmoAttention، فإن Olmo2Attention المُولَّد يكون مكتفياً ذاتياً بالكامل. لكن إذا كان OlmoAttention نفسه يرث من شيء آخر، فإن المُفحِّص لا يُضمّن ذلك الجدّ (grandparent) في الكود.

شغّل الأمر أدناه لتوليد الملفات من ملف معياري.

python utils/modular_model_converter.py your_model

لا تعدّل الملفات المولّدة مباشرةً، لأن أي تغييرات ستُستبدل في المرة التالية عند التشغيل.

أنماط الملفات المعيارية

توثّق الأقسام أدناه أنماط الاستخدام الشائعة، مثل إزالة السمات أو تجاوز الدوال المُزيَّنة، عند العمل مع ملفٍ مُعَدَّل.

إزالة السمات

يعتمد حذف السمة الموروثة على ما إذا كنت تعمل مع فئة تكوين أو مع فئة فرعية من nn.Module.

بالنسبة لفئة الإعدادات، قم بتعيين AttributeError() إلى الخاصية على مستوى الفئة.

class MyNewConfig(ParentConfig):
    removed_attr = AttributeError()

يقوم مُصحح الأكواد بإزالة إعلان الخاصية من ملف الإعدادات المُولَّد بالكامل. تستخدم فئات الإعدادات تخطيطًا بنمط dataclass دون __init__، لذا فإن إسناد AttributeError() على مستوى الفئة هو النهج الصحيح.

بالنسبة لفئة فرعية من nn.Module، استخدم del self.attribute بعد super().__init__(...).

class MyNewModel(ParentModel):
    def __init__(self, config: MyNewConfig):
        super().__init__(config)
        del self.attribute

del self.attribute يزيل فقط سطر إسناد self.attribute = ... من جسم الوالد المنسوخ. ولا يزيل أي أسطر أخرى تشير إلى self.attribute. إذا كانت طريقة forward لدى الوالد أو طرق أخرى تشير أيضًا إلى الخاصية، فعليك تجاوز تلك الطرق أيضًا.

class DummyModel(nn.Module):
    def __init__(self, config: DummyConfig):
        super().__init__()
        self.attribute = config.attribute
        if self.attribute:
            # do more stuff with `self.attribute` here
            ...

class MyNewDummyModel(DummyModel):
    def __init__(self, config: MyNewDummyConfig):
        super().__init__(config)
        del self.attribute
        # 'self.attribute = config.attribute' is removed, but the 'if self.attribute:' block remains.
        # Override forward() or any other method that references self.attribute.

العمل مع super()

يُخبر super().__init__(config) المحوّل بنسخ جسم العنصر الأب إلى العنصر الابن. هناك نمطان يتيحان لك تجاوز هذا السلوك.

  • استدعِ الفئة الأم المحددة مباشرةً عندما تحتاج إلى أن يستدعي المخرَج المولَّد الفئة الجدّ (nn.Module.__init__) بدلاً من الفئة الأم المعيارية.
  • استخدم **super_kwargs لتوريث التوقيع الكامل لطريقة الوالد مع إضافة وصف مخصص أو استبدال مُزيّن.

استدعاء فئة الجد مباشرة

كن صريحًا بشأن الفئة التي تستدعيها عندما تحتاج إلى super() لاستهداف فئة الوالد المولّدة بدلاً من فئة الوالد المعيارية. يستدعي المثال أدناه nn.Module.__init__(self) مباشرةً. DummyModule هي نفسها nn.Module، لذا يكتب المحوّل ذلك على شكل super().__init__() في MyNewDummyModule المولّدة.

class MyNewDummyModule(DummyModule):                   |     class MyNewDummyModule(nn.Module):
                                                       |
  def __init__(self):                                  |       def __init__(self):
    nn.Module.__init__(self)                           |         super().__init__()
    self.foo = config.foo                              |         self.foo = config.foo
    ...                                                |         ...

super_kwargs

استخدم **super_kwargs لتوريث التوقيع الكامل لطريقة الأصل مع إضافة وصف مخصص أو استبدال مُزيِّن. في التوقيع المُعاد تعريفه، يُخبر هذا المُفحِّص (linter) بتوسيع جميع معاملات الأصل في المخرجات المُولَّدة.

أكثر الاستخدامات شيوعاً هو إضافة وصف خاص بالنموذج، مثل توثيق معامل labels، دون إعادة كتابة التوقيع الكامل.

# modular_gemma.py
class GemmaForCausalLM(LlamaForCausalLM):
    def forward(**super_kwargs):
        r"""
        Example:

        ```python
        >>> from transformers import AutoTokenizer, GemmaForCausalLM
        >>> model = GemmaForCausalLM.from_pretrained("google/gemma-7b")
        ...
        ```"""
        return super().forward(**super_kwargs)

يتميز GemmaForCausalLM.forward المولّد بتوقيع LlamaForCausalLM الكامل دون الحاجة إلى أي نسخ يدوي.

**super_kwargs اختصار لحالات نادرة. إذا كنت تغيّر السلوك، فاطبع التوقيع الكامل بدلاً من ذلك.

حذف الطرق غير المستخدمة

احذف طريقةً تابعةً للأب عن طريق تجاوزها ببيان raise AttributeError(""). يقوم المُفحِّص (linter) بإزالة الطريقة من الملف المُولَّد.

class GemmaTokenizer(LlamaTokenizer):
    ...

    def get_spm_processor(self):
        raise AttributeError("Not needed for Gemma")

    def unk_token_length(self):
        raise AttributeError("Not needed for Gemma")

تجاوز الطرق المزينة

عندما تُعيد تعريف طريقة أمّ مُزيَّنة، فإن مُزيِّن الطريقة الأمّ ينتقل تلقائيًا. وإذا أضفتَ مُزيِّنًا خاصًا بك، فإنه يحلّ محلّ مُزيِّن الطريقة الأمّ.

يظهر مُزيّنَين (decorators) في جميع أنحاء المكتبة، أحدهما لـالتقاط المخرجات الوسيطة للنموذج والآخر لـتوليد سلاسل التوثيق تلقائيًا.

في المثال أدناه، تتجاوز فئة فرعية طريقة أم مسجّلة دون إضافة مُزيّن خاص بها. ينتقل مُزيّن الفئة الأم تلقائيًا.

class NewModel(DummyModel):       |   class NewModel(nn.Module):
  ...                             |     ...
                                  |
  def forward(...):               |     @decorator(...)
    ...                           |     def forward(...):
                                  |       ...

إذا أضفت مُزيِّنًا جديدًا، فإن مُزيِّنك يحل محل مُزيِّن العنصر الأب.

class NewModel(DummyModel):       |   class NewModel(nn.Module):
  ...                             |     ...
                                  |
  @my_new_decorator(...)          |     @my_new_decorator(...)
  def forward(...):               |     def forward(...):
    ...                           |       ...

تسمية خاصة

يعيد أداة فحص الأكواد تسمية كل شيء تلقائياً عند الوراثة من فئة. استخدم بادئة اسم الفئة نفسها عبر جميع الفئات في الملف نفسه.

تجنّب خلط البادئات كما في المثال أدناه. MyModelIncredibleMLP يخالف قواعد التسمية، ولن يعرف أداة التدقيق (linter) ما إذا كان يجب استخدام MyModelIncredible أو MyModel عند إعادة تسمية التبعيات من الرتبة الأعلى.

class MyModelIncredibleMLP(LlamaMLP):
    ...

class MyModelDecoderLayer(LlamaDecoderLayer):
    ...

بما أنه لا توجد اعتمادات ضمنية، يمكنك إعادة تسمية فئة واحدة محليًا. أعد تعريف كل ذكر آخر لتلك الفئة صراحةً باستخدام نمط الاسم الجديد. وإلا، سيضيف أداة فحص الكود فئة MyModelMLP غير مرغوب فيها إلى جانب MyModelIncredibleMLP.

يرفع أداة فحص الأكواد تحذيراً عندما يكتشف بادئة غير محددة.

We detected multiple prefix names when inheriting from transformers.models.llama.modeling_llama: ('Emu3Text', 'Emu3'). We will only use the most used 'Emu3' prefix when grabbing args and dependencies. Make sure to subclass the intermediate classes with the prefix you want (if different from 'Emu3') or use a single prefix in all the modular (best).

تكون البادئات الغامضة أكثر شيوعاً في النماذج متعددة الوسائط التي تتضمن أسماء الفئات مؤهلاً للوسائط مثل Text. لمنح اعتمادية بادئة محددة، أعد تسميتها صراحةً باستخدام pass.

class Emu3TextMLP(LlamaMLP):
    pass

سلاسل توثيق الإعداد

لا يدعم أداة فحص الأكواد (linter) بعد وراثة جزئية لتوثيق الدوال (docstring). عند إضافة أو إزالة سمات الإعداد (config attributes)، أضف توثيق الدوال كاملاً مباشرةً في الملف المعياري (modular file) تحت تعريف الفئة.

تحويل نقاط التفتيش

بمجرد أن تولّد ملفات النمذجة الخاصة بك، تحقّق من أن الأوزان الفعلية تُحمَّل بشكل صحيح. اكتب سكربت تحويل لترجمة صيغة نقطة التفتيش الأصلية إلى صيغة متوافقة مع Transformers، ثم احفظها على Hub.

اكتب سكربت تحويل

أضف ملف convert_<model>_to_hf.py إلى src/transformers/models/<model>/. يقوم هذا السكربت بتحميل الأوزان من المصدر الأصلي، وإعادة تسمية المفاتيح وإعادة تشكيلها لتتطابق مع أسماء المعاملات في وحدة عملك، ثم يحفظ النتيجة باستخدام save_pretrained().

ابحث عن سكربت موجود لتسخيره وتكييفه. تتضمن النماذج الموجودة تحت src/transformers/models/ سكربت convert_*_to_hf.py يمكنك استخدامه كنقطة انطلاق.

بعد تشغيل السكربت، حمّل نقطة التفتيش المحفوظة باستخدام from_pretrained() وتأكد من أن كل الأوزان المتوقعة تم تحميلها بشكل صحيح. مفاتيح نقطة التفتيش غير المستخدمة تشير إلى عدم تطابق في الأسماء، لذا اطبعها لاكتشاف المشكلات مبكراً.

model = YourModelForTask.from_pretrained("path/to/output/")

تحقق من تطابق الأبعاد والأسماء عند التكرار على المفاتيح. عادةً ما تعني عدم تطابق الأبعاد أن هناك خطأً في أحد المعاملات في إعداداتك، أو أن البنية المعمارية تختلف عن الأصلية، أو أن أحد الأوزان يحتاج إلى تبديل (Transposition).

for key, tensor in original_state_dict.items():
    hf_tensor = hf_model.state_dict().get(mapped_key)
    assert hf_tensor.shape == tensor.shape, (
        f"Shape mismatch for {key}: expected {tensor.shape}, got {hf_tensor.shape}"
    )

قم بإصلاح أي مشكلات من خلال التكرار بين ملفك المعياري، وملف النمذجة المُولَّد، وسكربت التحويل، حتى يتم تحميل جميع الأوزان بسلاسة.

بمجرد تحميل نقطة التفتيش بنجاح، قم بدفعها إلى Hub باستخدام push_to_hub(). راجع دليل مشاركة النموذج لمزيد من التفاصيل.

model.push_to_hub("username/your-model-name")

خريطة التحويل وقت التشغيل

أضِف خرائط وقت التشغيل إلى src/transformers/conversion_mapping.py عندما لا تتطابق الأوزان المنشورة مع تخطيط معاملات وحدة عملك. تشمل الحالات الشائعة الأوزان المدمجة المخزنة بشكل منفصل، ومتجهات خبراء MoE التي تحتاج إلى تجميع. تتيح هذه الخريطة لـ from_pretrained() تحميل نقطة التفتيش من Hub دون الحاجة إلى خطوة تصدير منفصلة.

راجع دليل تحميل الأوزان الديناميكي لمعرفة كيفية كتابة قواعد WeightRenaming وWeightConverter وتسجيلها لنوع النموذج model_type الخاص بك.

الخطوات التالية

  • قواعد بنية النموذج هي قواعد ثابتة تُفرض على جميع ملفات modeling_*.py وmodular_*.py وconfiguration_*.py. نفّذ make typing للتحقق منها قبل فتح طلب دمج.
  • يتناول إضافة مكونات معالجة الرؤية خطوات إضافة معالج صور ومعالج فيديو ومعالج لنمط متعدد الوسائط.
  • يُبيّن توليد توثيقات تلقائيًا كيفية استخدام @auto_docstring حتى لا تضطر إلى كتابة توثيقات المعاملات يدويًا لواجهات برمجة التطبيقات المشتركة للنماذج.
  • يتناول كتابة اختبارات النموذج كيفية كتابة اختبارات التكامل لنموذجك الجديد وتشغيله محليًا.
  • يشرح فحوصات طلبات الدمج فحوصات CI التي يجب أن يجتازها طلب الدمج الخاص بك قبل أن يُدمج، وكيفية إعادة إنتاجها وإصلاحها محليًا.
Update on GitHub