Monkey patching
Monkey patching (실험적 기능)
Monkey patching을 사용하면 원본 모델 코드를 수정하지 않고 모델 구성 요소를 전역적으로 교체할 수 있습니다. 일단 등록되면 from_pretrained() 또는 ~PreTrainedModel.from_config로 모델을 로드할 때 패치가 자동으로 적용됩니다. 이를 통해 양자화 호환성 같은 특정 요구 사항에 맞게 모델을 재구성하거나, 최적화를 적용하거나, 아키텍처 변형을 실험할 수 있습니다.
출처: 문서
본문
Monkey patching을 사용하면 원본 모델 코드를 수정하지 않고 모델 구성 요소를 전역적으로 교체할 수 있습니다. 일단 등록되면 from_pretrained() 또는 ~PreTrainedModel.from_config로 모델을 로드할 때 패치가 자동으로 적용됩니다. 이를 통해 양자화 호환성 같은 특정 요구 사항에 맞게 모델을 재구성하거나, 최적화를 적용하거나, 아키텍처 변형을 실험할 수 있습니다.
[!WARNING] Monkey patching은 마지막 수단으로 사용해야 합니다. 모듈 및/또는 그 가중치의 레이아웃과 구조를 변경해야 할 때 필요합니다. 많은 커스터마이징 및 최적화 요구에는 Attention interface, Experts interface, Kernels 레지스트리를 먼저 사용해 보세요. 커스텀 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는 두 단계 프로세스로 작동합니다.
-
등록(Registration):
register_patch_mapping을 호출해 전역 레지스트리에 매핑을 추가합니다. -
적용(Application): 모델 초기화 중 패치가 자동으로 적용됩니다.
from_pretrained/from_config: 패치가 내부 컨텍스트 매니저를 통해 자동으로 적용됩니다. 추가 동작이 필요 없습니다!- 수동 구성 (예:
Model(config)):apply_patches컨텍스트 매니저를 수동으로 사용해야 합니다.
패치가 등록되면 clear_patch_mapping으로 지울 때까지 유지되어 이후의 모든 모델 로드에 영향을 줍니다.
중요한 제한 사항:
transformersmodeling 모듈의 클래스만 패치할 수 있습니다(예: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이라는 클래스는 정확한 일치 교체를 사용하고, 다른 일치하는 클래스는 패턴 일치 교체를 사용합니다.
[!WARNING] 정규식 패턴은 모델을 조용히 깨뜨릴 수 있습니다.
".*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은 클래스만 교체하지 가중치는 교체하지 않습니다. 패치된 클래스에 다른 가중치 레이아웃이 있다면, 사전 훈련된 가중치와의 호환성을 보장하기 위해 weight conversions를 별도로 처리해야 합니다. monkey patch와 weight conversion 매핑을 결합하는 방법은 아래 전체 예시를 참조하세요.
-
전역 효과:
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)}")
가중치 형태 불일치 오류
패치된 클래스에 다른 가중치 형태가 있다면 weight conversion을 등록하세요.
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)에서 최적화와 양자화 호환성을 위해 전문가와 attention 모듈을 모두 재구성하는 방법을 보여주는 포괄적인 예시입니다. 이것은 다음을 보여줍니다.
- 같은 인터페이스를 유지하는 커스텀 교체 클래스 만들기
- 여러 구성 요소에 대한 monkey patch 등록
- 새 구조에 대한 weight conversion 처리
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 전문가 라우팅 기록 및 재생
RLHF 같은 Mixture-of-Experts 훈련 워크플로우는 생성 중 각 토큰이 어떤 전문가로 라우팅되었는지 기록한 다음, 별도의 훈련 forward pass에서 그 정확한 라우팅을 재생해야 합니다. 기존의 monkey patching과 출력 캡처 메커니즘으로 이 작업을 종단간(end-to-end) 구축할 수 있습니다 — modeling 파일 변경은 필요 없습니다.
패턴은 세 부분으로 구성됩니다.
- 인스턴스 속성에서 강제된 전문가 인덱스를 선택적으로 읽을 수 있는 재생 가능한(replayable) 라우터 서브클래스.
- forward pass 전에 모든 라우터에 그 속성을 설정하고 그 후에 지우는 컨텍스트 매니저.
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)
재생은 정확한 전문가 인덱스를 보존하고 현재 라우터 가중치로 라우팅 점수를 다시 계산하므로, 전문가 선택이 고정된 동안 그래디언트가 실시간 파라미터를 통해 흐릅니다. 이것은 Megatron 스타일 MoE 훈련에 사용되는 최소 재생 계약입니다.
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))을 일치시키며, 패치를 등록하세요. 정확한 시그니처는 각 모델의 라우터 클래스를 참조하세요.
API 참조[[transformers.monkey_patching.register_patch_mapping]]
transformers.monkey_patching.register_patch_mapping[[transformers.monkey_patching.register_patch_mapping]]
transformers.monkey_patching.register_patch_mapping(mapping: dict, overwrite: 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 컨텍스트 매니저 내에서 자동 패칭을 가능하게 하려면 patch 매핑을 등록합니다.
어떤 모델을 로드할 때 자동으로 적용될 클래스 교체를 등록하려면 이를 사용하세요. 이는 양자화 라이브러리 호환성, 구조적 최적화, 아키텍처 실험에 유용합니다. 매핑은 전역이며, 여러 호출로 커질 수 있고 완전히 지울 수 있습니다.
예:
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")
참고:
Weight conversion에는 ~transformers.register_checkpoint_conversion_mapping을 대신 사용하세요.
transformers.monkey_patching.unregister_patch_mapping[[transformers.monkey_patching.unregister_patch_mapping]]
transformers.monkey_patching.unregister_patch_mapping(keys: list)
파라미터:
keys (List[str]) : patch 매핑에서 제거할 매핑 키(클래스 이름 또는 정규식 패턴) 목록 (예: ["Qwen2MoeExperts"] 또는 [".*Attention"]).
자동 패칭을 비활성화하려면 patch 매핑을 등록 해제합니다.
지정된 매핑을 전역 레지스트리에서 제거하여 모델 로드 중에 적용되지 않게 합니다. 등록 중에 사용한 것과 정확히 같은 이름이나 패턴을 제공해야 합니다.
예:
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]]
transformers.monkey_patching.clear_patch_mapping()
등록된 모든 patch 매핑을 지웁니다.
전역 레지스트리에서 모든 등록된 매핑을 제거합니다.
예:
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]]
transformers.monkey_patching.get_patch_mapping()
반환: Dict[str, type[nn.Module]]
클래스 이름 또는 패턴을 교체 클래스에 매핑하는 딕셔너리.
등록된 모든 patch 매핑을 가져옵니다.
transformers.monkey_patching.apply_patches[[transformers.monkey_patching.apply_patches]]
transformers.monkey_patching.apply_patches()
코드 블록 내에서 등록된 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())