Coverage for transformer_lens/model_bridge/supported_architectures/roberta.py: 100%
11 statements
« prev ^ index » next coverage.py v7.10.1, created at 2026-10-23 20:45 +0000
« prev ^ index » next coverage.py v7.10.1, created at 2026-10-23 20:45 +0000
1"""RoBERTa architecture adapter."""
3from typing import Any
5from transformer_lens.model_bridge.generalized_components import (
6 AttentionBridge,
7 BlockBridge,
8 EmbeddingBridge,
9 LinearBridge,
10 MLPBridge,
11 NormalizationBridge,
12 PosEmbedBridge,
13 UnembeddingBridge,
14)
15from transformer_lens.model_bridge.supported_architectures.bert import (
16 BertArchitectureAdapter,
17)
20class RobertaArchitectureAdapter(BertArchitectureAdapter):
21 """Architecture adapter for ``RobertaForMaskedLM``: BERT's layer, MLM head under ``lm_head.*``.
23 Positions start at ``padding_idx + 1 = 2``, so ``W_pos`` drops the table's first two rows.
24 """
26 def __init__(self, cfg: Any) -> None:
27 """Initialize the RoBERTa architecture adapter."""
28 super().__init__(cfg)
30 self.component_mapping = {
31 "embed": EmbeddingBridge(name="roberta.embeddings.word_embeddings"),
32 # Real [1, d_model] table at type_vocab_size = 1; HF adds it on every forward.
33 "token_type_embed": EmbeddingBridge(name="roberta.embeddings.token_type_embeddings"),
34 "pos_embed": PosEmbedBridge(name="roberta.embeddings.position_embeddings"),
35 "embed_ln": NormalizationBridge(
36 name="roberta.embeddings.LayerNorm",
37 config=self.cfg,
38 use_native_layernorm_autograd=True,
39 ),
40 "blocks": BlockBridge(
41 name="roberta.encoder.layer",
42 # Same split intermediate.dense / output.dense layout as BertLayer, see bert.py.
43 hook_alias_overrides={
44 "hook_mlp_out": "mlp.out.hook_out",
45 "hook_mlp_in": "mlp.in.hook_in",
46 },
47 submodules={
48 "ln1": NormalizationBridge(
49 name="attention.output.LayerNorm",
50 config=self.cfg,
51 use_native_layernorm_autograd=True,
52 ),
53 "ln2": NormalizationBridge(
54 name="output.LayerNorm",
55 config=self.cfg,
56 use_native_layernorm_autograd=True,
57 ),
58 "attn": AttentionBridge(
59 name="attention",
60 config=self.cfg,
61 submodules={
62 "q": LinearBridge(name="self.query"),
63 "k": LinearBridge(name="self.key"),
64 "v": LinearBridge(name="self.value"),
65 "o": LinearBridge(name="output.dense"),
66 },
67 ),
68 "mlp": MLPBridge(
69 name=None,
70 config=self.cfg,
71 submodules={
72 "in": LinearBridge(name="intermediate.dense"),
73 "out": LinearBridge(name="output.dense"),
74 },
75 ),
76 },
77 ),
78 "mlm_head": LinearBridge(name="lm_head.dense"),
79 "unembed": UnembeddingBridge(name="lm_head.decoder"),
80 "ln_final": NormalizationBridge(
81 name="lm_head.layer_norm",
82 config=self.cfg,
83 use_native_layernorm_autograd=True,
84 ),
85 }
87 def prepare_model(self, hf_model: Any) -> None:
88 """Read the usable context off the loaded position table."""
89 super().prepare_model(hf_model)
90 # Drop the padding_idx + 1 reserved rows; n_ctx + 2 rows is what makes W_pos slice.
91 table = hf_model.roberta.embeddings.position_embeddings
92 self.cfg.n_ctx = table.num_embeddings - ((table.padding_idx or 0) + 1)