# التضمين القرد (ميزة تجريبية)

يتيح لك تطبيق التصحيحات (Monkey patching) استبدال مكوّنات النموذج على مستوى شامل دون تعديل كود النموذج الأصلي. بمجرد تسجيل التصحيحات، تُطبَّق تلقائيًا عند تحميل أي نموذج باستخدام [from_pretrained()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.from_pretrained) أو `~PreTrainedModel.from_config`. وهذا يمكّنك من إعادة هيكلة النماذج لتلبية متطلبات محددة مثل التوافق مع التكميم (Quantization)، أو تطبيق تحسينات، أو إجراء تجارب على متغيرات معمارية.

> [!WARNING]
> **يجب استخدام تعديل القرد (Monkey patching) كحل أخير** عندما تحتاج إلى تغيير تخطيط وبنية وحدة أو أوزانها. للعديد من احتياجات التخصيص والتحسين، جرّب استخدام [واجهة الانتباه (Attention interface)](./attention_interface) أو [واجهة الخبراء (Experts interface)](./experts_interface) أو [سجل النوى (Kernels registry)](./kernel_doc/overview) بدلاً من ذلك. استخدم تعديل القرد فقط عندما تكون هناك حاجة إلى تغييرات بنيوية لا يمكن تحقيقها من خلال تنفيذات الأمامية المخصصة وحدها (مثل توافق مكتبات التكميم، أو دمج الطبقات، أو التجارب المعمارية).

## البدء السريع

فيما يلي مثال بسيط يوضح كيفية استبدال مكوّن في النموذج:

```python
from transformers import AutoModelForCausalLM
from transformers.models.llama.modeling_llama import LlamaAttention
from transformers.monkey_patching import register_patch_mapping

# Define your replacement class (must inherit from nn.Module)
class CustomLlamaAttention(LlamaAttention):
    def forward(self, *args, **kwargs):
        # Your custom implementation
        print("Using custom attention!")
        return super().forward(*args, **kwargs)

# Register the patch globally (only applies to transformers modeling modules)
register_patch_mapping(mapping={"LlamaAttention": CustomLlamaAttention})

# Load a model - the patch is automatically applied during initialization
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")

# All LlamaAttention layers in the model are now CustomLlamaAttention instances
print(type(model.model.layers[0].self_attn))  # <class '__main__.CustomLlamaAttention'>
```

## كيف يعمل

تعمل رقاقات القرد (Monkey patches) عبر عملية من خطوتين:

1. **التسجيل**: استدعِ `register_patch_mapping` لإضافة خرائط إلى سجل عام.

2. **التطبيق**: تُطبَّق الرقع تلقائيًا أثناء تهيئة النموذج:
   - **`from_pretrained` / `from_config`**: تُطبَّق الرقع **تلقائيًا** عبر مدير سياق داخلي. لا حاجة إلى أي إجراء إضافي!
   - **البناء اليدوي** (مثل `Model(config)`): يجب عليك استخدام مدير السياق `apply_patches` يدوياً.

بمجرد تسجيل التصحيحات، تبقى سارية وتؤثر على جميع عمليات تحميل النماذج اللاحقة حتى تقوم بإزالتها باستخدام `clear_patch_mapping`.

**قيود مهمة**:

- يُسمح بتعديل (patch) الفئات الموجودة في وحدات نمذجة `transformers` فقط (مثل `LlamaAttention`، `LlamaMLP`).
- يمكن أن تكون مفاتيح الترميز إما أسماء فئات دقيقة أو أنماط تعبيرات منتظمة (انظر [مطابقة الأنماط](#pattern-matching) أدناه).

## التسجيل العام

استخدم `register_patch_mapping` لتسجيل الخرائط على مستوى عام:

```python
from transformers.monkey_patching import register_patch_mapping

# Register a single patch
register_patch_mapping(
    mapping={"Qwen2MoeExperts": SequentialExperts}
)

# Register multiple patches at once
register_patch_mapping(
    mapping={
        "Qwen2MoeExperts": SequentialExperts,
        "Qwen2MoeAttention": CustomAttention,
    },
    # Overwrite existing patches if they exist
    overwrite=True,
)
```

## مطابقة الأنماط

يمكنك استخدام التعبيرات النمطية المطابقة (regular expressions) لمطابقة فئات متعددة بنمط واحد:

```python
from transformers.monkey_patching import register_patch_mapping

# Match all classes containing "Attention"
register_patch_mapping(
    mapping={".*Attention": CustomAttention}
)

# More examples
register_patch_mapping(
    mapping={
        ".*MoeExperts$": CustomExperts,           # Ends with "MoeExperts"
        "^Llama\\d+Attention$": CustomAttention,  # Llama2Attention, Llama3Attention, etc.
    }
)
```

**مهم**: تُعطى الأولوية للمطابقات الدقيقة على الأنماط. إذا قمت بتسجيل كلا من `"LlamaAttention"` و`".*Attention"`، فستستخدم الفئات المسماة `LlamaAttention` الاستبدال المطابق تمامًا، بينما ستستخدم الفئات الأخرى المطابقة الاستبدال المطابق للنمط.

> [!WARNING]
> **قد تُسبب أنماط Regex أضرارًا صامتة للنماذج.** فأنماط واسعة مثل `".*Attention"` ستطابق *كل* فئة تحتوي اسمها على "Attention" — بما في ذلك فئات الحاويات التي تغلف طبقة الانتباه التي تريد استبدالها فعليًا. على سبيل المثال، يحتوي BERT على ثلاث فئات مرتبطة بالانتباه: `BertSelfAttention` و`BertCrossAttention` (تنفيذات الانتباه الداخلية) و`BertAttention` (وحدة خارجية *تحتوي* على إحدى الفئات الداخلية). يؤدي تطبيق تصحيح على الفئات الثلاث جميعًا باستخدام طبقة انتباه مخصصة واحدة إلى إنتاج نموذج معطوب، لأن الفئة الخارجية `BertAttention` لم تعد تغلف الفئة الداخلية — بل *أصبحت* هي نفسها فئة داخلية، مما يلغي الوحدات الفرعية المتوقعة مثل `self` و`output`. يُفضَّل استخدام أنماط ضيقة (مثل `".*SelfAttention$"`) أو أسماء الفئات الدقيقة لتجنب التطابقات غير المقصودة.

لإلغاء تسجيل التصحيحات، استخدم `unregister_patch_mapping`:

```python
from transformers.monkey_patching import unregister_patch_mapping

# Unregister a single patch (use exact name or pattern from registration)
unregister_patch_mapping(keys=["Qwen2MoeExperts"])

# Unregister multiple patches at once
unregister_patch_mapping(keys=["Qwen2MoeExperts", "Qwen2MoeAttention"])

# Unregister a pattern
unregister_patch_mapping(keys=[".*Attention"])
```

لإزالة جميع التصحيحات المسجّلة، استخدم `clear_patch_mapping`:

```python
from transformers.monkey_patching import clear_patch_mapping

clear_patch_mapping()
```

لعرض التصحيحات المسجّلة حاليًا، استخدم `get_patch_mapping`:

```python
from transformers.monkey_patching import get_patch_mapping

current_patches = get_patch_mapping()
print(current_patches)
```

## بناء النموذج يدويًا

لا يكون مُدير السياق `apply_patches` مطلوباً إلا عند بناء النماذج **يدوياً** (على سبيل المثال، `Model(config)`) دون استخدام `from_pretrained` أو `from_config`:

```python
from transformers import LlamaModel, LlamaConfig
from transformers.monkey_patching import register_patch_mapping, apply_patches

# Register patch globally
register_patch_mapping(mapping={"LlamaAttention": CustomAttention})

# For manual construction, you need the context manager
with apply_patches():
    model = LlamaModel(LlamaConfig())  # Uses CustomAttention

# Without the context manager, manual construction uses original classes
model = LlamaModel(LlamaConfig())  # Uses LlamaAttention

# But from_pretrained and from_config will always apply registered patches
model = LlamaModel.from_pretrained("meta-llama/Llama-3.2-1B")  # Uses CustomAttention
```

## ملاحظات مهمة

- **معالجة الأوزان**: لا يستبدل Monkey patching سوى الفئات، وليس الأوزان. إذا كانت الفئة المُعدَّلة لديك تحتوي على تخطيط أوزان مختلف، فستحتاج إلى معالجة [تحويلات الأوزان](./weightconverter) بشكل منفصل لضمان التوافق مع الأوزان المُسبقة التدريب. راجع [المثال الكامل](#complete-example) أدناه لمعرفة كيفية دمج monkey patches مع خرائط تحويل الأوزان.

- **التأثير العام**: تُطبَّق البُقع المسجَّلة عبر `register_patch_mapping` على نطاق شامل لجميع النماذج التي يتم تحميلها بعد التسجيل. استخدم دائمًا `clear_patch_mapping` لتنظيف الحالة عند الانتهاء، لا سيما في الاختبارات، ودفاتر الملاحظات، أو التطبيقات طويلة الأمد.

- **التحقق من الفئة**: يتحقق الـ API تلقائيًا من أن الفئات البديلة هي فئات فرعية من `nn.Module`. إذا قمت بتمرير فئة غير صالحة، فستظهر لك رسالة خطأ واضحة.

- **أمان الخيوط**: جميع عمليات الترقيع آمنة من حيث الخيوط. يمكنك تسجيل الترقيعات وإلغاؤها وتطبيقها بأمان من خيوط متعددة.

- **سلوك المطابقة**: عند استخدام أسماء الفئات الدقيقة، يجب أن تتطابق تمامًا مع أسماء الفئات الأصلية كما تظهر في كود المصدر الخاص بالنموذج (مع مراعاة الأحرف الكبيرة والصغيرة). عند استخدام أنماط التعبيرات النمطية، تتم مطابقتها مع أسماء الفئات باستخدام `re.search()`.

## استكشاف الأخطاء وإصلاحها

### لم يتم تطبيق تصحيحي

**التحقق من اسم الفئة أو النمط**: تأكد من أن اسم الفئة أو النمط في خريطتك صحيح:

```python
# For exact names - must match exactly (case-sensitive)
register_patch_mapping(mapping={"LlamaAttention": CustomAttention})

# For patterns - use valid regex
register_patch_mapping(mapping={".*Attention": CustomAttention})
```

**التحقق من التسجيل**: استخدم `get_patch_mapping` للتأكد من تسجيل خرائطك:

```python
print(get_patch_mapping())
# Shows all registered mappings: {'LlamaAttention': <class 'CustomAttention'>, '.*MLP': <class 'CustomMLP'>}
```

**التحقق من مصدر النموذج**: ابحث عن اسم الفئة الدقيق في مصدر النموذج:

```python
from transformers.models.llama import modeling_llama
print(dir(modeling_llama))  # Look for the class name
```

### كيف أعرف ما إذا كان التصحيح الخاص بي يعمل؟

فحص النموذج المحمّل للتحقق من التصحيح:

```python
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")

# Check the type of a specific module
print(type(model.model.layers[0].self_attn))  # Should show your custom class

# Or iterate through all modules
for name, module in model.named_modules():
    if 'attention' in name.lower():
        print(f"{name}: {type(module)}")
```

### أخطاء عدم تطابق شكل الأوزان

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

```python
from transformers.conversion_mapping import register_checkpoint_conversion_mapping, WeightConverter
from transformers.monkey_patching import register_patch_mapping

register_patch_mapping(
    mapping={
        "LlamaAttention": LlamaFusedAttention,
    }
)

register_checkpoint_conversion_mapping(
    model_type_or_class_name="llama",
    mapping=[
        WeightConverter(
            source_patterns=["q_proj", "k_proj", "v_proj"],
            target_patterns=["qkv_proj"],
            operations=[
                Concatenate(dim=0),
            ],
        )
    ],
    overwrite=True,
)
```

### تنظيف التصحيحات

قم دائمًا بتنظيف التصحيحات عند الانتهاء لتجنب التأثير على أكواد أخرى:

```python
from transformers.monkey_patching import register_patch_mapping, clear_patch_mapping

try:
    register_patch_mapping(mapping={"LlamaAttention": CustomAttention})
    model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-chat-hf")
    # ... use model ...
finally:
    clear_patch_mapping()  # Always clean up
```

## مثال كامل

فيما يلي مثال شامل يوضح كيفية إعادة هيكلة كلا من وحدات الخبراء ووحدات الانتباه في نموذج مزيج الخبراء (`qwen2_moe`) من أجل التوافق مع التحسين والتكميم. يوضح هذا المثال:

1. إنشاء فئات بديلة مخصصة تحافظ على نفس الواجهة
2. تسجيل تصحيحات القرد لمكونات متعددة
3. معالجة تحويلات الأوزان للهيكل الجديد

```python
from typing import Unpack

import torch
import torch.nn as nn

from transformers import AutoModelForCausalLM, Concatenate, WeightConverter
from transformers.activations import ACT2FN
from transformers.cache_utils import Cache
from transformers.conversion_mapping import register_checkpoint_conversion_mapping
from transformers.integrations.sdpa_attention import sdpa_attention_forward
from transformers.models.qwen2_moe.modeling_qwen2_moe import apply_rotary_pos_emb
from transformers.monkey_patching import register_patch_mapping
from transformers.utils.generic import TransformersKwargs

class MoeMLP(nn.Module):
    def __init__(self, config):
        super().__init__()
        self.config = config
        self.num_experts = config.num_experts
        self.hidden_size = config.hidden_size
        self.intermediate_size = config.moe_intermediate_size
        self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
        self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
        self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
        self.act_fn = ACT2FN[config.hidden_act]

    def forward(self, x):
        down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
        return down_proj

# Adapted from the original Qwen2MoeExperts
class ModuleListExperts(nn.ModuleList):
    def __init__(self, config):
        super().__init__()
        self.config = config
        self.num_experts = config.num_experts
        for _ in range(self.num_experts):
            self.append(MoeMLP(config))

    def forward(
        self, hidden_states: torch.Tensor, top_k_index: torch.Tensor, top_k_weights: torch.Tensor
    ) -> torch.Tensor:
        final_hidden_states = torch.zeros_like(hidden_states)
        with torch.no_grad():
            expert_mask = torch.nn.functional.one_hot(top_k_index, num_classes=self.num_experts)
            expert_mask = expert_mask.permute(2, 1, 0)

        for expert_idx in range(self.num_experts):
            top_k_pos, token_idx = torch.where(expert_mask[expert_idx])
            current_state = hidden_states[token_idx]
            current_hidden_states = self[expert_idx](current_state)
            current_hidden_states = current_hidden_states * top_k_weights[token_idx, top_k_pos, None]
            final_hidden_states.index_add_(0, token_idx, current_hidden_states.to(final_hidden_states.dtype))
        return final_hidden_states

# Adapted from the original Qwen2MoeAttention
class FusedQKVAttention(nn.Module):
    def __init__(self, config, layer_idx: int):
        super().__init__()
        self.config = config
        self.layer_idx = layer_idx
        self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
        self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
        self.scaling = self.head_dim**-0.5
        self.attention_dropout = config.attention_dropout
        self.is_causal = True

        self.qkv_proj = nn.Linear(config.hidden_size, 3 * config.num_attention_heads * self.head_dim, bias=True)
        self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=False)

        if self.config.layer_types[layer_idx] == "sliding_attention":
            self.sliding_window = config.sliding_window

    def forward(
        self,
        hidden_states: torch.Tensor,
        position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
        attention_mask: torch.Tensor | None = None,
        past_key_values: Cache | None = None,
        **kwargs: Unpack[TransformersKwargs],
    ) -> tuple[torch.Tensor, torch.Tensor]:
        input_shape = hidden_states.shape[:-1]
        hidden_shape = (*input_shape, -1, self.head_dim)

        query_states, key_states, value_states = self.qkv_proj(hidden_states).chunk(3, dim=-1)

        query_states = query_states.view(hidden_shape).transpose(1, 2)
        key_states = key_states.view(hidden_shape).transpose(1, 2)
        value_states = value_states.view(hidden_shape).transpose(1, 2)

        cos, sin = position_embeddings
        query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)

        if past_key_values is not None:
            key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)

        attn_output, attn_weights = sdpa_attention_forward(
            self,
            query_states,
            key_states,
            value_states,
            attention_mask,
            dropout=0.0 if not self.training else self.attention_dropout,
            scaling=self.scaling,
            **kwargs,
        )

        attn_output = attn_output.reshape(*input_shape, -1).contiguous()
        attn_output = self.o_proj(attn_output)
        return attn_output, attn_weights

# Registering monkey patches for the new attention and experts modules.
register_patch_mapping(
    mapping={
        "Qwen2MoeExperts": ModuleListExperts,
        "Qwen2MoeAttention": FusedQKVAttention,
    }
)

# Registering weight conversion mappings adapted for the new modules. This registration will:
# - Override the original conversion mapping for qwen2_moe which concatenated the experts into a single parameter format.
# - Concatenate the q_proj, k_proj, v_proj weights/biases into a single qkv_proj weight/bias for the new fused attention module.
register_checkpoint_conversion_mapping(
    model_type_or_class_name="qwen2_moe",
    mapping=[
        WeightConverter(
            source_patterns=["q_proj", "k_proj", "v_proj"],
            target_patterns=["qkv_proj"],
            operations=[Concatenate(dim=0)],
        ),
    ],
    overwrite=True,
)

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen1.5-MoE-A2.7B")
```

## تسجيل إعادة توجيه خبراء MoE وإعادة تشغيله

تتطلب سير عمل تدريب Mixture-of-Experts مثل RLHF تسجيل الخبراء الذين تم توجيه كل رمز (token) إليهم أثناء التوليد، ثم إعادة تشغيل ذلك التوجيه الدقيق في مسار أمامي (forward pass) منفصل للتدريب. يمكنك بناء هذا النظام من البداية إلى النهاية باستخدام آلية التعديل الديناميكي (monkey patching) وآلية التقاط المخرجات الموجودة مسبقًا — دون الحاجة إلى أي تغييرات في ملفات النمذجة (modeling files).

يتكوّن النمط من ثلاثة أجزاء:

1. **فئة فرعية قابلة لإعادة التشغيل للموجّه** يمكنها اختيارياً قراءة فهارس الخبراء الإجبارية من خاصية في الكائن.
2. مدير سياق **context manager** يضبط تلك السمات عبر كل موجّه قبل تمريرة الأمامية ثم يمسحها بعد ذلك.
3. إدراج في سجل التقاط المخرجات الخاص بالنموذج بحيث يعرض `output_<name>=True` الفهارس عبر مسار `@capture_outputs` القياسي.

```python
from contextlib import contextmanager

import torch
import torch.nn.functional as F

from transformers import Qwen3MoeConfig, Qwen3MoeForCausalLM
from transformers.models.qwen3_moe.modeling_qwen3_moe import Qwen3MoeTopKRouter
from transformers.monkey_patching import apply_patches, register_patch_mapping
from transformers.utils.output_capturing import _CAN_RECORD_REGISTRY, OutputRecorder

class ReplayableQwen3MoeTopKRouter(Qwen3MoeTopKRouter):
    _forced_indices: torch.Tensor | None = None

    def forward(self, hidden_states):
        hidden_states = hidden_states.reshape(-1, self.hidden_dim)
        router_logits = F.linear(hidden_states, self.weight)
        router_logits = F.softmax(router_logits, dtype=torch.float, dim=-1)

        if self._forced_indices is not None:
            router_indices = self._forced_indices.to(router_logits.device).long()
            # Megatron-style replay: preserve expert path, recompute current scores
            router_top_value = router_logits.gather(-1, router_indices)
        else:
            router_top_value, router_indices = torch.topk(router_logits, self.top_k, dim=-1)

        if self.norm_topk_prob:
            router_top_value = router_top_value / router_top_value.sum(dim=-1, keepdim=True)
        return router_logits, router_top_value.to(router_logits.dtype), router_indices

@contextmanager
def replay_moe_routing(model, selected_experts_per_layer):
    routers = [m for m in model.modules() if isinstance(m, ReplayableQwen3MoeTopKRouter)]
    if len(routers) != len(selected_experts_per_layer):
        raise ValueError(f"Got {len(routers)} routers but {len(selected_experts_per_layer)} tensors")
    for r, t in zip(routers, selected_experts_per_layer):
        r._forced_indices = t
    try:
        yield
    finally:
        for r in routers:
            r._forced_indices = None

# Swap the router class and construct the model
register_patch_mapping({"Qwen3MoeTopKRouter": ReplayableQwen3MoeTopKRouter})
with apply_patches():
    model = Qwen3MoeForCausalLM(Qwen3MoeConfig(...)).eval()

# Expose `output_selected_experts=True` on the base model by adding an OutputRecorder
# at runtime. Index 2 of the router's tuple output is the expert indices.
inner = model.model
existing = _CAN_RECORD_REGISTRY.get(str(inner.__class__), {}) or {}
_CAN_RECORD_REGISTRY[str(inner.__class__)] = {
    **existing,
    "selected_experts": OutputRecorder(ReplayableQwen3MoeTopKRouter, index=2),
}

# Record
captured = inner(input_ids=input_ids, output_selected_experts=True)
selected_experts = captured.selected_experts  # tuple of (num_tokens, top_k) LongTensors

# Replay — same expert path regardless of current router weights
with replay_moe_routing(inner, list(selected_experts)):
    outputs = inner(input_ids=input_ids)
```

يحافظ إعادة التشغيل على فهارس الخبراء الدقيقة ويعيد حساب نقاط التوجيه باستخدام أوزان الموجّه الحالية، بحيث تتدفق التدرجات عبر المعاملات النشطة بينما تبقى عملية اختيار الخبراء ثابتة. هذا هو عقد إعادة التشغيل الحد الأدنى المستخدم في تدريب نماذج MoE بأسلوب Megatron.

### التوافق مع vLLM

يملأ `enable_return_routed_experts=True` في vLLM حقل `CompletionOutput.routed_experts` كمصفوفة من نوع `np.int32` بأبعاد `(seq_len, num_layers, top_k)`. حوّلها إلى قائمة لكل طبقة كما يتوقعها هذا النمط باستخدام تعبير واحد:

```python
selected = [
    torch.from_numpy(routed_experts[:, layer, :].copy()).long()
    for layer in range(routed_experts.shape[1])
]
with replay_moe_routing(model, selected):
    loss = model(input_ids=input_ids, labels=labels).loss
```

تنطبق الوصفة نفسها على عائلات MoE الأخرى — قم بتوريث فئة `*TopKRouter` الخاصة بالعائلة، وطابق عقد الإرجاع الأصلي (عادةً `(router_logits, router_scores, router_indices)`)، وسجّل التصحيح. راجع فئة الموجّه الخاصة بكل نموذج لمعرفة التوقيع الدقيق.

## مرجع الواجهة البرمجية[[transformers.monkey_patching.register_patch_mapping]]

#### transformers.monkey_patching.register_patch_mapping[[transformers.monkey_patching.register_patch_mapping]]

```python
transformers.monkey_patching.register_patch_mapping(mapping: dict, overwrite: bool = False)
```

[المصدر](https://github.com/huggingface/transformers/blob/main/src/transformers/monkey_patching.py#L85)

**المعاملات:**

mapping (`Dict[str, type[nn.Module]]`) : تعيين من أسماء الفئات الأصلية (أو أنماط التعبيرات النمطية) إلى الفئات البديلة. يدعم: - أسماء الفئات الدقيقة: `"Qwen2MoeExperts"` → `CustomExperts` - أنماط التعبيرات النمطية: `".*Attention"` يطابق `LlamaAttention`، `MistralAttention`، إلخ، أو `"^Llama\d+Attention$"` يطابق `Llama2Attention`، `Llama3Attention`، إلخ.  تتفوق المطابقات الدقيقة على الأنماط. يتم مطابقة الأنماط باستخدام `re.search()`، لذا يمكنها المطابقة في أي مكان داخل اسم الفئة ما لم تستخدم المرساة (`^` للبداية، `$` للنهاية).

overwrite (`bool`، *اختياري*، القيمة الافتراضية `False`) : ما إذا كان يجب تجاوز الخرائط الموجودة لأسماء الفئات المسجلة مسبقًا.

سجّل خرائط التصحيحات لتفعيل التصحيح التلقائي أثناء إنشاء النموذج باستخدام `from_pretrained` أو `from_config` أو داخل مُدير السياق `apply_patches`.

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

مثال:
```python
from transformers import AutoModelForCausalLM
from transformers.monkey_patching import register_patch_mapping

# Define custom expert implementation
class SequentialExperts(nn.Module):
    ...

# Register exact class name
register_patch_mapping(
    mapping={"Qwen2MoeExperts": SequentialExperts}
)

# Register with regex pattern to match multiple classes
register_patch_mapping(
    mapping={".*Attention": CustomAttention}  # Matches LlamaAttention, MistralAttention, etc.
)

# Match specific model versions
register_patch_mapping(
    mapping={"^Llama\d+Attention$": CustomLlamaAttention}  # Matches Llama2Attention, Llama3Attention
)

# The patch will be automatically applied during loading
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
```

ملاحظة: لتحويلات الأوزان، استخدم `~transformers.register_checkpoint_conversion_mapping` بدلاً من ذلك.

#### transformers.monkey_patching.unregister_patch_mapping[[transformers.monkey_patching.unregister_patch_mapping]]

```python
transformers.monkey_patching.unregister_patch_mapping(keys: list)
```

[المصدر](https://github.com/huggingface/transformers/blob/main/src/transformers/monkey_patching.py#L158)

**المعاملات:**

keys (`List[str]`) : قائمة بمفاتيح التطابق (أسماء الفئات أو أنماط regex) التي يجب إزالتها من خريطة التصحيح (على سبيل المثال، `["Qwen2MoeExperts"]` أو `[".*Attention"]`).

إلغاء تسجيل خرائط التصحيح لتعطيل التصحيح التلقائي.

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

مثال:
```python
from transformers import AutoModelForCausalLM
from transformers.monkey_patching import register_patch_mapping, unregister_patch_mapping

# Register a patch
register_patch_mapping(
    mapping={"Qwen2MoeExperts": CustomExperts}
)

# Unregister the patch
unregister_patch_mapping(["Qwen2MoeExperts"])

# The patch will no longer be applied during loading
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen1.5-MoE-A2.7B")
```

#### transformers.monkey_patching.clear_patch_mapping[[transformers.monkey_patching.clear_patch_mapping]]

```python
transformers.monkey_patching.clear_patch_mapping()
```

[المصدر](https://github.com/huggingface/transformers/blob/main/src/transformers/monkey_patching.py#L209)

مسح جميع خرائط التصحيح المسجّلة.

تزيل هذه العملية جميع الخرائط المسجلة من السجل العام.

مثال:
```python
from transformers.monkey_patching import register_patch_mapping, clear_patch_mapping

# Register some patches
register_patch_mapping(
    mapping={"Qwen2MoeExperts": CustomExperts}
)

# Clear all patches
clear_patch_mapping()
```

#### transformers.monkey_patching.get_patch_mapping[[transformers.monkey_patching.get_patch_mapping]]

```python
transformers.monkey_patching.get_patch_mapping()
```

[المصدر](https://github.com/huggingface/transformers/blob/main/src/transformers/monkey_patching.py#L198)

**يعيد:** `Dict[str, type[nn.Module]]`

قاموس يربط بين أسماء الفئات أو الأنماط وفئات الاستبدال.

احصل على جميع خرائط التصحيح المسجّلة.

#### transformers.monkey_patching.apply_patches[[transformers.monkey_patching.apply_patches]]

```python
transformers.monkey_patching.apply_patches()
```

[المصدر](https://github.com/huggingface/transformers/blob/main/src/transformers/monkey_patching.py#L233)

مدير سياق لتطبيق التصحيحات القردية المسجّلة داخل كتلة من الكود.

يستبدل هذا مؤقتًا الفئات الأصلية ببدائلها المسجلة أثناء تنفيذ الكتلة، ثم يعيد الفئات الأصلية بعد ذلك.

مثال:
```python
from transformers import Qwen2MoeModel, Qwen2MoeConfig
from transformers.monkey_patching import register_patch_mapping, apply_patches

# Register a patch
register_patch_mapping(
    mapping={"Qwen2MoeExperts": CustomExperts}
)

# Apply patches within the context
with apply_patches():
    # The model will use CustomExperts instead of Qwen2MoeExperts
    model = Qwen2MoeModel(Qwen2MoeConfig())

# Outside the context, original classes are restored
# The model will use Qwen2MoeExperts again
model = Qwen2MoeModel(Qwen2MoeConfig())
```

