Transformers documentation

Monkey patching (실험적 기능)

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

Monkey patching (실험적 기능)

Monkey patching은 원본 모델 코드를 수정하지 않고도 모델 구성 요소를 전역적으로 교체할 수 있게 합니다. 등록이 완료되면 from_pretrained() 또는 ~PreTrainedModel.from_config로 모델을 로드할 때 패치가 자동으로 적용됩니다. 이를 통해 양자화 호환성과 같은 특정 요구 사항에 맞게 모델을 재구성하거나, 최적화를 적용하거나, 아키텍처 변형을 실험할 수 있습니다.

모듈의 레이아웃과 구조 또는 가중치를 변경해야 할 때 Monkey patching은 최후의 수단으로 사용해야 합니다. 많은 커스터마이징 및 최적화 요구 사항은 Attention interface, Experts interface, 또는 Kernels registry를 사용하는 것이 좋습니다. 커스텀 forward 구현만으로는 달성할 수 없는 구조적 변경이 필요한 경우(예: 양자화 라이브러리 호환성, 레이어 퓨징, 아키텍처 실험)에만 monkey patching을 사용하세요.

빠른 시작

모델 구성 요소를 교체하는 간단한 예시를 보여 줍니다:

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 patch는 두 단계의 과정을 통해 작동합니다:

  1. 등록: register_patch_mapping을 호출하여 전역 레지스트리에 매핑을 추가합니다.

  2. Application: 모델 초기화 시 패치가 자동으로 적용됩니다:

    • from_pretrained / from_config: 패치는 내부 컨텍스트 매니저를 통해 자동으로 적용됩니다. 추가 작업이 필요하지 않습니다!
    • 수동 구성(예: Model(config)): apply_patches 컨텍스트 매니저를 수동으로 사용해야 합니다.

패치가 등록되면 clear_patch_mapping으로 지울 때까지 유지되며 이후 모든 모델 로드에 영향을 줍니다.

주요 제한 사항:

  • transformers의 modeling 모듈에 있는 클래스만 패치할 수 있습니다(예: LlamaAttention, LlamaMLP).
  • 매핑 키는 정확한 클래스 이름 또는 정규식 패턴(아래의 패턴 매칭 참조)일 수 있습니다.

전역 등록

register_patch_mapping를 사용하여 매핑을 전역으로 등록합니다:

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

패턴 매칭

정규식을 사용하여 하나의 패턴으로 여러 클래스를 일치시킬 수 있습니다:

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으로 이름이 지정된 클래스는 정확한 일치 대체를 사용하고, 다른 일치하는 클래스는 패턴 일치 대체를 사용합니다.

정규식 패턴이 모델을 조용히 깨뜨릴 수 있습니다. ".*Attention"와 같은 광범위한 패턴은 이름에 “Attention”이 포함된 모든 클래스와 일치합니다. 실제로 교체하려는 attention을 감싸는 컨테이너 클래스도 포함됩니다. 예를 들어 BERT에는 attention 관련 클래스가 세 개 있습니다: BertSelfAttention과 BertCrossAttention(내부 attention 구현) 그리고 BertAttention(해당 내부 클래스 중 하나를 포함하는 외부 모듈). 세 클래스 모두를 동일한 커스텀 attention 레이어로 패치하면 외부 BertAttention이 더 이상 내부 클래스를 감싸지 않고 그 자체로 그 클래스가 되어 self나 output과 같은 예상되는 서브모듈이 사라져 모델이 깨집니다. 의도하지 않은 매칭을 피하려면 좁은 패턴(예: ".*SelfAttention$")이나 정확한 클래스 이름을 사용하는 것이 좋습니다.

패치를 등록 해제하려면 unregister_patch_mapping를 사용합니다:

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을(를) 사용하세요:

from transformers.monkey_patching import clear_patch_mapping

clear_patch_mapping()

현재 등록된 패치를 확인하려면 get_patch_mapping을 사용하세요:

from transformers.monkey_patching import get_patch_mapping

current_patches = get_patch_mapping()
print(current_patches)

수동 모델 구성

apply_patches 컨텍스트 매니저는 from_pretrained 또는 from_config를 사용하지 않고 모델을 수동으로 구성할 때(예: Model(config))에만 필요합니다:

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은 클래스만 대체하며 가중치는 대체하지 않습니다. 패치된 클래스의 가중치 레이아웃이 다른 경우, 사전 학습된 가중치와의 호환성을 보장하기 위해 가중치 변환을 별도로 처리해야 합니다. monkey patch와 가중치 변환 매핑을 결합하는 방법은 아래 완전한 예제를 참고하세요.

  • 전역 효과: register_patch_mapping으로 등록한 패치는 등록 이후 로드되는 모든 모델에 전역적으로 적용됩니다. 특히 테스트, 노트북, 또는 장시간 실행되는 애플리케이션에서는 작업 완료 후 반드시 clear_patch_mapping을 사용하여 정리하세요.

  • 클래스 검증: API는 대체 클래스가 nn.Module의 하위 클래스인지 자동으로 검증합니다. 잘못된 클래스를 전달하면 명확한 오류 메시지가 표시됩니다.

  • 스레드 안전성: 모든 패치 작업은 스레드 안전합니다. 여러 스레드에서 패치를 등록, 등록 해제 및 적용하는 것이 안전합니다.

  • 일치 동작: 정확한 클래스 이름을 사용하는 경우, 모델 소스 코드에 나타나는 원래 클래스 이름과 정확히 일치해야 합니다(대소문자 구분). 정규식 패턴을 사용하는 경우, re.search()를 사용하여 클래스 이름과 일치 여부를 확인합니다.

문제 해결

내 패치가 적용되지 않습니다

클래스 이름 또는 패턴 확인: 매핑에 있는 클래스 이름 또는 패턴이 올바른지 확인하세요:

# 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을(를) 사용하여 매핑이 등록되었는지 확인합니다:

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

모델 소스 확인: 모델 소스에서 정확한 클래스 이름을 찾습니다:

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

패치가 제대로 작동하는지 어떻게 알 수 있나요?

…

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

가중치 형식 불일치 오류

패치된 클래스의 가중치 형상이 다른 경우, 가중치 변환을 등록하세요:

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

패치 정리

작업이 완료되면 다른 코드에 영향을 주지 않도록 패치를 항상 정리하세요:

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

완전한 예시

Mixture-of-Experts 모델(qwen2_moe)의 experts와 attention 모듈을 최적화 및 양자화 호환성을 위해 재구성하는 방법을 보여주는 포괄적인 예시입니다. 이 예시에서는 다음을 보여줍니다:

  1. 동일한 인터페이스를 유지하는 사용자 정의 대체 클래스 생성
  2. 여러 컴포넌트에 대한 monkey patch 등록
  3. 새로운 구조에 대한 가중치 변환 처리
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 training workflows like RLHF need to record which experts each token was routed to during generation, then replay that exact routing in a separate training forward pass. You can build this end-to-end with the existing monkey patching and output capturing machinery — no modeling-file changes required.

이 패턴은 세 부분으로 구성됩니다:

  1. 선택적으로 인스턴스 속성에서 강제된 expert 인덱스를 읽을 수 있는 재실행 가능한 라우터 하위 클래스입니다.
  2. 포워드 패스 전에 모든 라우터에 해당 속성을 설정하고, 이후에 해제하는 컨텍스트 매니저입니다.
  3. 모델의 출력 캡처 레지스트리에 있는 항목으로, output_<name>=True를 설정하면 인덱스가 표준 @capture_outputs 경로를 통해 노출됩니다.
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는 정확한 expert 인덱스를 보존하고 현재 router 가중치로 라우팅 점수를 다시 계산합니다. 이를 통해 expert 선택은 고정된 채로 gradients가 live parameters를 통해 흐릅니다. 이는 Megatron 스타일 MoE 학습에서 사용되는 최소 replay 계약입니다.

vLLM과의 상호 운용

vLLM의 enable_return_routed_experts=True는 CompletionOutput.routed_experts를 (seq_len, num_layers, top_k) np.int32 배열로 채웁니다. 이 패턴이 기대하는 레이어별 리스트로 변환하려면 다음 식 하나만 사용하면 됩니다:

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))을 준수한 뒤 패치를 등록합니다. 정확한 시그니처는 각 모델의 router 클래스를 참고하세요.

API 참조

transformers.monkey_patching.register_patch_mapping

< >

( mapping: dictoverwrite: bool = False )

매개변수

  • 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 컨텍스트 매니저 내에서 모델 생성 시 자동 패칭을 활성화하기 위해 패치 매핑을 등록합니다.

모든 모델 로딩 시 자동으로 적용될 클래스 대체를 등록하는 데 사용합니다. 양자화 라이브러리 호환성, 구조적 최적화, 아키텍처 실험에 유용합니다. 매핑은 전역적이며, 여러 호출을 통해 확장될 수 있고, 완전히 초기화할 수도 있습니다.

예:

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

< >

( keys: list )

매개변수

  • keys (List[str]) — 패치 매핑에서 제거할 매핑 키(클래스 이름 또는 정규식 패턴) 목록 (예: ["Qwen2MoeExperts"] 또는 [".*Attention"]).

자동 패치를 비활성화하려면 패치 매핑을 등록 해제합니다.

이 작업은 지정된 매핑을 전역 레지스트리에서 제거하여 모델 로딩 시 해당 매핑이 적용되지 않도록 합니다. 등록 시 사용된 이름 또는 패턴과 정확히 동일한 값을 제공해야 합니다.

예:

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

< >

( )

등록된 모든 패치 매핑을 삭제합니다.

이 작업은 전역 레지스트리에서 모든 등록된 매핑을 제거합니다.

예:

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

< >

( ) → Dict[str, type[nn.Module]]

반환값

Dict[str, type[nn.Module]]

클래스 이름 또는 패턴을 대체 클래스로 매핑하는 사전.

등록된 모든 patch 매핑을 가져옵니다.

transformers.monkey_patching.apply_patches

< >

( )

Context manager을 사용하여 코드 블록 내에서 등록된 monkey patch를 적용합니다.

이 문장은 블록 실행 중에 원래 클래스를 등록된 대체 클래스로 임시로 교체한 후, 실행이 끝나면 원래 클래스로 복원합니다.

예:

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())
Update on GitHub