# Monkey patching (deneysel özellik)

Monkey patching, orijinal model kodunu değiştirmeden model bileşenlerini küresel olarak değiştirmenizi sağlar. Kayıt altına alındıktan sonra, yamalar [from_pretrained()](/docs/transformers/main/tr/main_classes/model#transformers.PreTrainedModel.from_pretrained) veya `~PreTrainedModel.from_config` ile herhangi bir model yüklendiğinde otomatik olarak uygulanır. Bu sayede, kuantizasyon uyumluluğu gibi belirli gereksinimler için modelleri yeniden yapılandırabilir, optimizasyonlar uygulayabilir veya mimari varyantlarla deneyler yapabilirsiniz.

> [!WARNING]
> Modülün yerleşimini ve yapısını ve/veya ağırlıklarını değiştirmeniz gerektiğinde **monkey patching** son çare olarak kullanılmalıdır. Birçok özelleştirme ve optimizasyon ihtiyacı için bunun yerine [Attention interface](./attention_interface), [Experts interface](./experts_interface) veya [Kernels registry](./kernel_doc/overview) kullanmayı deneyin. Monkey patching'i yalnızca özel forward uygulamalarıyla tek başına sağlanamayan yapısal değişikliklere (ör. kuantizasyon kütüphanesi uyumluluğu, katman birleştirme veya mimari deneyler) ihtiyacınız olduğunda kullanın.

## Hızlı başlangıç

Bir model bileşenini nasıl değiştireceğinizi gösteren basit bir örnek:

```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'>
```

## Nasıl çalışır

Monkey yamaları iki aşamalı bir süreç üzerinden çalışır:

1. **Kayıt**: Küresel bir kayıt defterine eşlemeler eklemek için `register_patch_mapping` fonksiyonunu çağırın.

2. **Uygulama**: Yamalar, model başlatma sırasında otomatik olarak uygulanır:
   - **`from_pretrained` / `from_config`**: Yama **otomatik olarak** dahili bir bağlam yöneticisi (context manager) aracılığıyla uygulanır. Ek bir işlem gerekmez!
   - **Manuel oluşturma** (ör. `Model(config)`): `apply_patches` bağlam yöneticisini manuel olarak kullanmanız gerekir.

Yamalar kaydedildikten sonra, `clear_patch_mapping` ile temizlenene kadar kalıcı olarak kalır ve sonraki tüm model yüklemelerini etkiler.

**Önemli kısıtlamalar**:

- Yalnızca `transformers` modelleme modüllerindeki sınıflar yamalanabilir (ör. `LlamaAttention`, `LlamaMLP`).
- Eşleme anahtarları tam sınıf adları veya düzenli ifade desenleri olabilir (aşağıdaki [Desen eşleştirme](#pattern-matching) bölümüne bakın).

## Küresel kayıt

Eşlemeleri küresel olarak kaydetmek için `register_patch_mapping` kullanın:

```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,
)
```

## Desen eşleştirme

Birden fazla sınıfı tek bir desenle eşleştirmek için düzenli ifadeler kullanabilirsiniz:

```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.
    }
)
```

**Önemli**: Tam eşleşmeler, desenlere göre önceliklidir. Hem `"LlamaAttention"` hem de `".*Attention"` kaydederse, `LlamaAttention` adlı sınıflar tam eşleşme ikamesini kullanırken, diğer eşleşen sınıflar desen eşleşme ikamesini kullanır.

> [!WARNING]
> **Düzenli ifade kalıpları modelleri sessizce bozabilir.** `".*Attention"` gibi geniş bir kalıp, adında "Attention" geçen *tüm* sınıflarla eşleşir — aslında değiştirmek istediğiniz dikkati saran kapsayıcı sınıflar dahil. Örneğin, BERT'te üç dikkat ile ilgili sınıf vardır: `BertSelfAttention` ve `BertCrossAttention` (içerideki dikkat uygulamaları) ve `BertAttention` (bu iç sınıflardan birini *içeren* dış bir modül). Üçünü de aynı özel dikkat katmanı ile yamalamak, dış `BertAttention` artık içtekini sarmadığı için bozuk bir model üretir — o *bir* tanesidir ve `self` ile `output` gibi beklenen alt modülleri ortadan kaldırır. Beklenmedik eşleşmelerden kaçınmak için dar kalıpları (ör. `".*SelfAttention$"`) veya tam sınıf adlarını tercih edin.

Yamaları kaydını silmek için `unregister_patch_mapping` kullanın:

```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"])
```

Tüm kayıtlı yamaları temizlemek için `clear_patch_mapping` kullanın:

```python
from transformers.monkey_patching import clear_patch_mapping

clear_patch_mapping()
```

Kayıtlı yamaları görüntülemek için `get_patch_mapping` kullanın:

```python
from transformers.monkey_patching import get_patch_mapping

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

## Manuel model oluşturma

`apply_patches` bağlam yöneticisi, `from_pretrained` veya `from_config` kullanmadan modelleri **manuel olarak** (ör. `Model(config)`) oluştururken gereklidir:

```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
```

## Önemli notlar

- **Ağırlık yönetimi**: Monkey patching yalnızca sınıfları değiştirir, ağırlıkları değil. Yama uyguladığınız sınıfın farklı bir ağırlık düzeni varsa, önceden eğitilmiş ağırlıklarla uyumluluğu sağlamak için [ağırlık dönüşümlerini](./weightconverter) ayrı olarak ele almanız gerekir. Monkey patch'lerin ağırlık dönüşüm eşlemeleriyle nasıl birleştirileceğini görmek için aşağıdaki [Tam örnek](#complete-example) bölümüne bakın.

- **Küresel etki**: `register_patch_mapping` ile kaydedilen yamalar, kayıt işleminden sonra yüklenen tüm modellere küresel olarak uygulanır. İşlem bittiğinde temizlik yapmak için her zaman `clear_patch_mapping` kullanın; özellikle testlerde, defterlerde veya uzun süreli çalıştırılan uygulamalarda bu adım önemlidir.

- **Sınıf doğrulama**: API, değiştirme sınıflarının `nn.Module` alt sınıfları olduğunu otomatik olarak doğrular. Geçersiz bir sınıf iletirseniz, net bir hata mesajı alırsınız.

- **İş parçacığı güvenliği**: Tüm yama işlemleri iş parçacığı güvenlidir. Birden fazla iş parçacığından yamaları güvenle kaydedebilir, kaydını silebilir ve uygulayabilirsiniz.

- **Eşleşme davranışı**: Tam sınıf adları kullanıldığında, bunlar modelin kaynak kodunda göründüğü gibi orijinal sınıf adlarıyla birebir eşleşmelidir (büyük/küçük harf duyarlıdır). Düzenli ifade (regex) desenleri kullanıldığında, bunlar sınıf adlarına `re.search()` kullanılarak eşleştirilir.

## Sorun Giderme

### Yamam uygulanmıyor

**Sınıf adını veya desenini kontrol edin**: Haritalamanızdaki sınıf adının veya desenin doğru olduğundan emin olun:

```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})
```

**Kayıtı doğrulayın**: Eşlemelerinizin kayıtlı olduğunu doğrulamak için `get_patch_mapping` kullanın:

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

**Model kaynağını kontrol edin**: Modelin kaynağında tam sınıf adını bulun:

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

### Yamamın çalışıp çalışmadığını nasıl anlarım?

Yüklenen modeli inceleyerek yamayı doğrulayın:

```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)}")
```

### Ağırlık şekli uyumsuzluğu hataları

Eğer yamalı sınıfınız farklı ağırlık şekillerine sahipse, bir ağırlık dönüşümü kaydedin:

```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,
)
```

### Yamaları temizleme

Tamamlandığında, diğer kodu etkilememek için yamaları her zaman temizleyin:

```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
```

## Tam örnek

Bir Mixture-of-Experts modelinde (`qwen2_moe`) uzmanları ve dikkat modüllerini optimizasyon ve kuantizasyon uyumluluğu için yeniden yapılandırmayı gösteren kapsamlı bir örnek aşağıdadır. Bu örnek şunları göstermektedir:

1. Aynı arayüzü koruyan özel değiştirme sınıfları oluşturma
2. Birden fazla bileşen için maymun yamalarının (monkey patch) kaydedilmesi
3. Yeni yapı için ağırlık dönüşümlerinin yönetimi

```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 uzman yönlendirmesinin kaydedilmesi ve yeniden oynatılması

RLHF gibi Mixture-of-Experts eğitim iş akışları, üretim sırasında her token'ın hangi uzmanlara yönlendirildiğini kaydetmeli ve ardından bu tam yönlendirmeyi ayrı bir eğitim ileri geçişinde yeniden oynatmalıdır. Bunu, mevcut maymun yamalaması (monkey patching) ve çıktı yakalama mekanizmalarıyla uçtan uca oluşturabilirsiniz — modelleme dosyasında değişiklik gerekmez.

Bu desen üç parçadan oluşur:

1. İsteğe bağlı olarak zorlanmış uzman indekslerini bir öznitelik örneğinden okuyabilen **yeniden oynanabilir bir yönlendirici alt sınıfı**.
2. İleri bir geçişten önce bu öznitelikleri her yönlendiricide ayarlayıp sonrasında temizleyen bir **bağlam yöneticisi**.
3. Modelin çıktı yakalama kayıt defterindeki bir giriş, böylece `output_<name>=True` endeksleri standart `@capture_outputs` yolu üzerinden açığa çıkarır.

```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)
```

Replay, tam uzman indekslerini korur ve yönlendirme skorlarını mevcut yönlendirici ağırlıklarıyla yeniden hesaplar; böylece uzman seçimi sabit kalırken gradyanlar canlı parametrelere akar. Bu, Megatron tarzı MoE eğitiminde kullanılan minimal replay sözleşmesidir.

### vLLM ile birlikte çalışma

vLLM'in `enable_return_routed_experts=True` parametresi, `CompletionOutput.routed_experts` alanını `(seq_len, num_layers, top_k)` boyutunda bir `np.int32` dizisi olarak doldurur. Bu desenin beklediği katman başına liste formatına tek bir ifadeyle dönüştürün:

```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
```

Aynı tarif diğer MoE aileleri için de geçerlidir — ailenin `*TopKRouter` sınıfından türetme yapın, orijinal dönüş sözleşmesini (genellikle `(router_logits, router_scores, router_indices)`) karşılayın ve yamayı kaydedin. Kesin imza için her modelin router sınıfına bakın.

## API referansı[[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)
```

[Kaynak](https://github.com/huggingface/transformers/blob/main/src/transformers/monkey_patching.py#L85)

**Parametreler:**

mapping (`Dict[str, type[nn.Module]]`) : Orijinal sınıf adlarından (veya regex desenlerinden) değiştirme sınıflarına eşleme. Destekler: - Tam sınıf adları: `"Qwen2MoeExperts"` → `CustomExperts` - Regex desenleri: `".*Attention"` `LlamaAttention`, `MistralAttention` vb. ile eşleşir veya `"^Llama\d+Attention$"` `Llama2Attention`, `Llama3Attention` vb. ile eşleşir. Tam eşleşmeler desenlere göre önceliklidir. Desenler `re.search()` kullanılarak eşleştirilir, bu nedenle çapalar kullanmadıkça sınıf adının herhangi bir yerinde eşleşebilirler (`^` başlangıç için, `$` son için).

overwrite (`bool`, *isteğe bağlı*, varsayılan `False`) : Zaten kayıtlı olan sınıf adları için mevcut eşlemelerin üzerine yazılıp yazılmayacağını belirtir.

`from_pretrained`, `from_config` veya `apply_patches` bağlam yöneticisi içinde model oluşturulurken otomatik yama uygulamasını etkinleştirmek için yama eşlemelerini kaydedin.

Bu, herhangi bir model yüklenirken otomatik olarak uygulanacak sınıf değişikliklerini kaydetmek için kullanılır. Bu, kuantizasyon kütüphanesi uyumluluğu, yapısal optimizasyonlar ve mimari deneyler için faydalıdır. Eşleme küreseldir, birden fazla çağrıyla büyüyebilir ve tamamen temizlenebilir.

Örnek:
```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")
```

Not: Ağırlık dönüşümleri için bunun yerine `~transformers.register_checkpoint_conversion_mapping` kullanın.

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

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

[Kaynak](https://github.com/huggingface/transformers/blob/main/src/transformers/monkey_patching.py#L158)

**Parametreler:**

keys (`List[str]`) : Yama eşlemesinden kaldırılacak eşleme anahtarlarının (sınıf adları veya regex desenleri) listesi (ör. `["Qwen2MoeExperts"]` veya `[".*Attention"]`).

Otomatik yamalamayı devre dışı bırakmak için yama eşlemelerini kayıttan çıkarın.

Bu, küresel kayıt defterinden belirtilen eşlemeleri kaldırır ve model yüklenirken bunların uygulanmasını engeller. Kayıt sırasında kullanılan tam olarak aynı adı veya deseni belirtmeniz gerekir.

Örnek:
```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()
```

[Kaynak](https://github.com/huggingface/transformers/blob/main/src/transformers/monkey_patching.py#L209)

Kayıtlı tüm yama eşlemelerini temizler.

Bu, küresel kayıt defterinden tüm kayıtlı eşlemeleri kaldırır.

Örnek:
```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()
```

[Kaynak](https://github.com/huggingface/transformers/blob/main/src/transformers/monkey_patching.py#L198)

**Dönüş:** `Dict[str, type[nn.Module]]`

Sınıf adlarını veya desenlerini değiştirme sınıflarına eşleyen sözlük.

Tüm kayıtlı yama eşlemelerini alın.

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

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

[Kaynak](https://github.com/huggingface/transformers/blob/main/src/transformers/monkey_patching.py#L233)

Bir kod bloğu içinde kayıtlı maymun yamalarını (monkey patch) uygulamak için bağlam yöneticisi.

Bu, bloğun çalıştırılması sırasında orijinal sınıfları geçici olarak kayıtlı ikame sınıflarıyla değiştirir ve ardından orijinal sınıfları geri yükler.

Örnek:
```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())
```

