Taykhoom commited on
Commit
ae5d89c
·
0 Parent(s):

Initial GENA-LM Hugging Face port

Browse files
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: transformers
3
+ tags:
4
+ - biology
5
+ - DNA
6
+ - language-model
7
+ license: mit
8
+ ---
9
+
10
+ # GENA-LM-bert-base
11
+
12
+ Minimal HuggingFace port of the **bert-base** variant of
13
+ [GENA-LM](https://huggingface.co/AIRI-Institute/gena-lm-bert-base) -- a transformer masked language
14
+ model for long human / multi-species DNA sequences, using byte-pair (BPE) tokenization.
15
+
16
+ ## Architecture
17
+
18
+ | Parameter | Value |
19
+ |---|---|
20
+ | Layers | 12 |
21
+ | Attention heads | 12 |
22
+ | Embedding dimension | 768 |
23
+ | FFN hidden dimension | 3072 (GELU) |
24
+ | Vocabulary size | 32000 |
25
+ | Positional encoding | learned absolute |
26
+ | Normalization | Pre-LayerNorm (eps=1e-12); final-layer LayerNorm: No |
27
+ | Architecture | Pre-LayerNorm BERT (without a final-layer LayerNorm) |
28
+ | Max sequence length | 512 BPE tokens (~4608 nucleotides) |
29
+
30
+ **Vocabulary:** 32,000 BPE tokens trained on DNA, including `[CLS]`, `[SEP]`, `[PAD]`,
31
+ `[UNK]`, and `[MASK]`.
32
+
33
+ ## Pretraining
34
+
35
+ - **Objective:** Masked language modeling (15% masking, BigBird-style).
36
+ - **Data:** Human T2T genome assembly (GCA_009914755.3).
37
+ - **Pretraining iterations:** 500,000 (batch size 256, sequence length 512).
38
+ - **Source checkpoint:** `AIRI-Institute/gena-lm-bert-base`
39
+
40
+ ## Parity Verification
41
+
42
+ All 13 representation levels (embedding + 12 transformer blocks) and the
43
+ masked-LM logits were verified to be bit-exact (max abs diff = 0.00) against the
44
+ original `AIRI-Institute/gena-lm-bert-base` weights, for the `eager` backend. The added `sdpa` and
45
+ `flash_attention_2` backends agree with `eager` up to the expected fused-kernel
46
+ floating-point tolerance. Verified on GPU with PyTorch 2.7 / CUDA 12.9.
47
+
48
+ ## Related Models
49
+
50
+ See the full [GENA-LM collection](https://huggingface.co/collections/Taykhoom/gena-lm-6a8cec0862e11d4f81d059ab).
51
+
52
+ | Model | Parameters | Notes |
53
+ |---|---|---|
54
+ | **[GENA-LM-bert-base](https://huggingface.co/Taykhoom/GENA-LM-bert-base)** | 110M | 12L / 768d, 512 ctx (this model) |
55
+ | [GENA-LM-t2t-bert-base](https://huggingface.co/Taykhoom/GENA-LM-t2t-bert-base) | 110M | 12L / 768d, 512 ctx |
56
+ | [GENA-LM-t2t-multi-species-bert-base](https://huggingface.co/Taykhoom/GENA-LM-t2t-multi-species-bert-base) | 110M | 12L / 768d, 512 ctx |
57
+ | [GENA-LM-t2t-lastln-base](https://huggingface.co/Taykhoom/GENA-LM-t2t-lastln-base) | 110M | 12L / 768d, 512 ctx |
58
+ | [GENA-LM-t2t-bert-large](https://huggingface.co/Taykhoom/GENA-LM-t2t-bert-large) | 336M | 24L / 1024d, 512 ctx |
59
+ | [GENA-LM-t2t-bigbird-base](https://huggingface.co/Taykhoom/GENA-LM-t2t-bigbird-base) | 110M | 12L / 768d, 4096 ctx |
60
+ | [GENA-LM-t2t-sparse-bigbird-base](https://huggingface.co/Taykhoom/GENA-LM-t2t-sparse-bigbird-base) | 110M | 12L / 768d, 4096 ctx |
61
+ | [GENA-LM-sparse-bigbird-base](https://huggingface.co/Taykhoom/GENA-LM-sparse-bigbird-base) | 110M | 12L / 768d, 4096 ctx |
62
+
63
+ ## Usage
64
+
65
+ ### Embedding generation
66
+
67
+ ```python
68
+ import torch
69
+ from transformers import AutoTokenizer, AutoModel
70
+
71
+ tokenizer = AutoTokenizer.from_pretrained("Taykhoom/GENA-LM-bert-base", trust_remote_code=True)
72
+ model = AutoModel.from_pretrained("Taykhoom/GENA-LM-bert-base", trust_remote_code=True)
73
+ model.eval()
74
+
75
+ sequences = ["ACGTACGTACGTACGT", "TTACGGGCATACGACGT"]
76
+ enc = tokenizer(sequences, return_tensors="pt", padding=True)
77
+
78
+ with torch.no_grad():
79
+ out = model(**enc)
80
+
81
+ cls_emb = out.last_hidden_state[:, 0, :] # (batch, dim) -- CLS token
82
+ token_emb = out.last_hidden_state # (batch, seq_len, dim)
83
+
84
+ # Intermediate layers
85
+ out_all = model(**enc, output_hidden_states=True)
86
+ layer6_emb = out_all.hidden_states[6]
87
+ ```
88
+
89
+ ### MLM logits
90
+
91
+ ```python
92
+ from transformers import AutoTokenizer, AutoModelForMaskedLM
93
+
94
+ tokenizer = AutoTokenizer.from_pretrained("Taykhoom/GENA-LM-bert-base", trust_remote_code=True)
95
+ model = AutoModelForMaskedLM.from_pretrained("Taykhoom/GENA-LM-bert-base", trust_remote_code=True)
96
+ model.eval()
97
+
98
+ enc = tokenizer(["ACGT[MASK]CGTACGT"], return_tensors="pt")
99
+ with torch.no_grad():
100
+ logits = model(**enc).logits # (1, seq_len, vocab_size)
101
+ ```
102
+
103
+ ### Faster attention backends
104
+
105
+ ```python
106
+ # SDPA (PyTorch 2.0+) -- recommended for production
107
+ model = AutoModel.from_pretrained("Taykhoom/GENA-LM-bert-base", trust_remote_code=True,
108
+ attn_implementation="sdpa")
109
+
110
+ # Flash Attention 2 (requires flash-attn) -- fastest on long sequences
111
+ import torch
112
+ model = AutoModel.from_pretrained("Taykhoom/GENA-LM-bert-base", trust_remote_code=True,
113
+ attn_implementation="flash_attention_2",
114
+ dtype=torch.bfloat16)
115
+ ```
116
+
117
+ ### Fine-tuning
118
+
119
+ Standard HuggingFace conventions. For sequence-level tasks, pool over non-padding
120
+ positions or use the `[CLS]` token embedding as input to a prediction head.
121
+
122
+ ## Implementation Notes
123
+
124
+ This is a minimal, self-contained reimplementation of the GENA-LM pre-LayerNorm BERT
125
+ backbone. The only behavioural additions over the original (eager-only) code are the
126
+ `sdpa` and `flash_attention_2` attention backends, selectable via `attn_implementation`;
127
+ the `eager` backend reproduces the original outputs bit-for-bit. The original NSP head
128
+ and pooler are not included, since this port targets embedding and masked-LM use.
129
+ `AutoModel` returns the backbone without a pooler; use the `[CLS]` hidden state or
130
+ masked mean pooling for sequence embeddings. The input embeddings and MLM decoder are tied.
131
+
132
+ ## Citation
133
+
134
+ ```bibtex
135
+ @article{fishman2025_genalm,
136
+ title = {{GENA-LM}: a family of open-source foundational {DNA} language models for long sequences},
137
+ author = {Fishman, Veniamin and Kuratov, Yuri and Shmelev, Aleksei and Petrov, Maxim and Penzar, Dmitry and Shepelin, Denis and Chekanov, Nikolay and Kardymon, Olga and Burtsev, Mikhail},
138
+ journal = {Nucleic Acids Research},
139
+ volume = {53},
140
+ number = {2},
141
+ pages = {gkae1310},
142
+ year = {2025},
143
+ doi = {10.1093/nar/gkae1310}
144
+ }
145
+ ```
146
+
147
+ ## Credits
148
+
149
+ Original model and code by Fishman, Kuratov, et al. (AIRI Institute).
150
+ Source: [GitHub](https://github.com/AIRI-Institute/GENA_LM).
151
+ The HF conversion code was authored primarily by [Claude Code](https://claude.ai/code)
152
+ and reviewed manually by Taykhoom Dalal.
153
+
154
+ ## License
155
+
156
+ MIT, following the original repository.
config.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "GenaLMForMaskedLM"
4
+ ],
5
+ "attention_probs_dropout_prob": 0.1,
6
+ "dtype": "float32",
7
+ "hidden_act": "gelu",
8
+ "hidden_dropout_prob": 0.1,
9
+ "hidden_size": 768,
10
+ "initializer_range": 0.02,
11
+ "intermediate_size": 3072,
12
+ "last_layer_norm": false,
13
+ "layer_norm_eps": 1e-12,
14
+ "max_position_embeddings": 512,
15
+ "model_max_length": 512,
16
+ "model_type": "genalm",
17
+ "num_attention_heads": 12,
18
+ "num_hidden_layers": 12,
19
+ "pad_token_id": 3,
20
+ "position_embedding_type": "absolute",
21
+ "pre_layer_norm": true,
22
+ "rotary_base": 10000,
23
+ "rotary_dim": 32,
24
+ "sparse_block_size": 0,
25
+ "transformers_version": "4.57.6",
26
+ "type_vocab_size": 2,
27
+ "vocab_size": 32000,
28
+ "auto_map": {
29
+ "AutoConfig": "configuration_genalm.GenaLMConfig",
30
+ "AutoModel": "modeling_genalm.GenaLMModel",
31
+ "AutoModelForMaskedLM": "modeling_genalm.GenaLMForMaskedLM"
32
+ },
33
+ "tie_word_embeddings": true
34
+ }
configuration_genalm.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Configuration for the minimal GENA-LM (pre-LayerNorm BERT) port."""
2
+
3
+ from transformers import PretrainedConfig
4
+
5
+
6
+ class GenaLMConfig(PretrainedConfig):
7
+ """Configuration for the GENA-LM backbone.
8
+
9
+ GENA-LM is a pre-LayerNorm BERT (x = x + mha(ln(x)); x = x + ffn(ln(x))) with an
10
+ optional final LayerNorm. It supports learned absolute position embeddings and,
11
+ for some checkpoints, rotary position embeddings.
12
+ """
13
+
14
+ model_type = "genalm"
15
+
16
+ auto_map = {
17
+ "AutoConfig": "configuration_genalm.GenaLMConfig",
18
+ "AutoModel": "modeling_genalm.GenaLMModel",
19
+ "AutoModelForMaskedLM": "modeling_genalm.GenaLMForMaskedLM",
20
+ }
21
+
22
+ def __init__(
23
+ self,
24
+ vocab_size: int = 32000,
25
+ hidden_size: int = 768,
26
+ num_hidden_layers: int = 12,
27
+ num_attention_heads: int = 12,
28
+ intermediate_size: int = 3072,
29
+ hidden_act: str = "gelu",
30
+ hidden_dropout_prob: float = 0.1,
31
+ attention_probs_dropout_prob: float = 0.1,
32
+ max_position_embeddings: int = 512,
33
+ type_vocab_size: int = 2,
34
+ initializer_range: float = 0.02,
35
+ layer_norm_eps: float = 1e-12,
36
+ pad_token_id: int = 3,
37
+ position_embedding_type: str = "absolute",
38
+ pre_layer_norm: bool = True,
39
+ last_layer_norm: bool = False,
40
+ rotary_base: int = 10000,
41
+ rotary_dim: int = 32,
42
+ sparse_block_size: int = 0,
43
+ model_max_length: int = 512,
44
+ tie_word_embeddings: bool = True,
45
+ **kwargs,
46
+ ):
47
+ super().__init__(
48
+ pad_token_id=pad_token_id,
49
+ tie_word_embeddings=tie_word_embeddings,
50
+ **kwargs,
51
+ )
52
+ self.vocab_size = vocab_size
53
+ self.hidden_size = hidden_size
54
+ self.num_hidden_layers = num_hidden_layers
55
+ self.num_attention_heads = num_attention_heads
56
+ self.intermediate_size = intermediate_size
57
+ self.hidden_act = hidden_act
58
+ self.hidden_dropout_prob = hidden_dropout_prob
59
+ self.attention_probs_dropout_prob = attention_probs_dropout_prob
60
+ self.max_position_embeddings = max_position_embeddings
61
+ self.type_vocab_size = type_vocab_size
62
+ self.initializer_range = initializer_range
63
+ self.layer_norm_eps = layer_norm_eps
64
+ self.position_embedding_type = position_embedding_type
65
+ self.pre_layer_norm = pre_layer_norm
66
+ self.last_layer_norm = last_layer_norm
67
+ self.rotary_base = rotary_base
68
+ self.rotary_dim = rotary_dim
69
+ # BigBird block-sparse attention: 0 disables (dense). When > 0, attention is
70
+ # restricted to the (per-head) block layout stored in each layer's master_layout
71
+ # buffer, reproducing the original DeepSpeed block-sparse attention pattern.
72
+ self.sparse_block_size = sparse_block_size
73
+ self.model_max_length = model_max_length
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b538b52aae85f4c9346a59ac6d6879d3cdbdfb963f937b52bd07f1c3bee1ee21
3
+ size 442627016
modeling_genalm.py ADDED
@@ -0,0 +1,635 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Minimal GENA-LM backbone: pre-LayerNorm BERT with eager / sdpa / flash_attention_2.
2
+
3
+ GENA-LM (AIRI-Institute) is a pre-LayerNorm BERT trained on human / multi-species DNA.
4
+ The residual structure is::
5
+
6
+ a = pre_attention_ln(x)
7
+ x = x + attn_out_dense(self_attention(a))
8
+ b = post_attention_ln(x)
9
+ x = x + ffn_out_dense(act(ffn_in_dense(b)))
10
+
11
+ and, for checkpoints with ``last_layer_norm=True``, a final LayerNorm is applied after
12
+ the last block. Both learned absolute and rotary position embeddings are supported.
13
+
14
+ This file adds ``sdpa`` and ``flash_attention_2`` dispatch on top of the original eager
15
+ attention; the upstream model only ships eager attention.
16
+ """
17
+
18
+ import math
19
+ from typing import Optional, Tuple, Union
20
+
21
+ import torch
22
+ import torch.nn as nn
23
+ import torch.nn.functional as F
24
+ from transformers import PreTrainedModel
25
+ from transformers.activations import ACT2FN
26
+ from transformers.modeling_outputs import BaseModelOutputWithPooling, MaskedLMOutput
27
+
28
+ from .configuration_genalm import GenaLMConfig
29
+
30
+
31
+ # ---------------------------------------------------------------------------
32
+ # Rotary position embeddings (used by the rotary checkpoints)
33
+ # ---------------------------------------------------------------------------
34
+
35
+ class GenaLMRotaryEmbedding(nn.Module):
36
+ def __init__(self, dim: int, base: int = 10000):
37
+ super().__init__()
38
+ inv_freq = 1.0 / (base ** (torch.arange(0, dim, 2).float() / dim))
39
+ # persistent so the checkpoint's (fp16-rounded) inv_freq is loaded exactly rather
40
+ # than recomputed in fp32, which keeps rotary outputs bit-identical to the original.
41
+ self.register_buffer("inv_freq", inv_freq, persistent=True)
42
+ self._seq_len_cached = None
43
+ self._cos_cached = None
44
+ self._sin_cached = None
45
+
46
+ def forward(self, seq_len: int, device, dtype) -> Tuple[torch.Tensor, torch.Tensor]:
47
+ if seq_len != self._seq_len_cached or self._cos_cached is None or self._cos_cached.device != device:
48
+ self._seq_len_cached = seq_len
49
+ t = torch.arange(seq_len, device=device).type_as(self.inv_freq)
50
+ freqs = torch.einsum("i,j->ij", t, self.inv_freq)
51
+ emb = torch.cat((freqs, freqs), dim=-1)
52
+ self._cos_cached = emb.cos()[None, None, :, :]
53
+ self._sin_cached = emb.sin()[None, None, :, :]
54
+ # A cache populated under torch.inference_mode() contains inference
55
+ # tensors, which cannot later participate in a grad-enabled forward.
56
+ # Clone in the caller's current mode so logits()/embed() can be mixed.
57
+ return self._cos_cached.to(dtype).clone(), self._sin_cached.to(dtype).clone()
58
+
59
+
60
+ def _rotate_half(x: torch.Tensor) -> torch.Tensor:
61
+ x1, x2 = x[..., : x.shape[-1] // 2], x[..., x.shape[-1] // 2:]
62
+ return torch.cat((-x2, x1), dim=-1)
63
+
64
+
65
+ def _apply_rotary(q: torch.Tensor, k: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor):
66
+ cos = cos[:, :, : q.shape[2], :].to(q.dtype)
67
+ sin = sin[:, :, : q.shape[2], :].to(q.dtype)
68
+ return (q * cos) + (_rotate_half(q) * sin), (k * cos) + (_rotate_half(k) * sin)
69
+
70
+
71
+ # ---------------------------------------------------------------------------
72
+ # Attention variants
73
+ # ---------------------------------------------------------------------------
74
+
75
+ class GenaLMSelfAttention(nn.Module):
76
+ """Eager scaled dot-product self-attention (matches the original)."""
77
+
78
+ def __init__(self, config: GenaLMConfig):
79
+ super().__init__()
80
+ self.num_attention_heads = config.num_attention_heads
81
+ self.attention_head_size = config.hidden_size // config.num_attention_heads
82
+ self.all_head_size = self.num_attention_heads * self.attention_head_size
83
+
84
+ self.query = nn.Linear(config.hidden_size, self.all_head_size)
85
+ self.key = nn.Linear(config.hidden_size, self.all_head_size)
86
+ self.value = nn.Linear(config.hidden_size, self.all_head_size)
87
+ self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
88
+
89
+ self.position_embedding_type = config.position_embedding_type
90
+ if self.position_embedding_type == "rotary":
91
+ self.rotary_dim = config.rotary_dim
92
+ self.rotary_emb = GenaLMRotaryEmbedding(self.rotary_dim, base=config.rotary_base)
93
+
94
+ def _split_heads(self, x: torch.Tensor) -> torch.Tensor:
95
+ B, T, _ = x.shape
96
+ return x.view(B, T, self.num_attention_heads, self.attention_head_size).permute(0, 2, 1, 3)
97
+
98
+ def _maybe_rotary(self, q: torch.Tensor, k: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
99
+ if self.position_embedding_type != "rotary":
100
+ return q, k
101
+ cos, sin = self.rotary_emb(q.shape[2], q.device, q.dtype)
102
+ if self.rotary_dim < self.attention_head_size:
103
+ q_rot, q_pass = q[..., : self.rotary_dim], q[..., self.rotary_dim:]
104
+ k_rot, k_pass = k[..., : self.rotary_dim], k[..., self.rotary_dim:]
105
+ q_rot, k_rot = _apply_rotary(q_rot, k_rot, cos, sin)
106
+ q = torch.cat((q_rot, q_pass), dim=-1)
107
+ k = torch.cat((k_rot, k_pass), dim=-1)
108
+ else:
109
+ q, k = _apply_rotary(q, k, cos, sin)
110
+ return q, k
111
+
112
+ def forward(
113
+ self,
114
+ hidden_states: torch.Tensor,
115
+ key_padding_mask: Optional[torch.Tensor] = None,
116
+ output_attentions: bool = False,
117
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
118
+ q = self._split_heads(self.query(hidden_states))
119
+ k = self._split_heads(self.key(hidden_states))
120
+ v = self._split_heads(self.value(hidden_states))
121
+ q, k = self._maybe_rotary(q, k)
122
+
123
+ scores = torch.matmul(q, k.transpose(-1, -2)) / math.sqrt(self.attention_head_size)
124
+ if key_padding_mask is not None:
125
+ scores = scores.masked_fill(key_padding_mask[:, None, None, :], float("-inf"))
126
+ probs = F.softmax(scores, dim=-1)
127
+ attn_weights = probs if output_attentions else None
128
+ probs = self.dropout(probs)
129
+ context = torch.matmul(probs, v)
130
+
131
+ B, _, T, _ = context.shape
132
+ context = context.permute(0, 2, 1, 3).contiguous().view(B, T, self.all_head_size)
133
+ return context, attn_weights
134
+
135
+
136
+ class GenaLMSdpaSelfAttention(GenaLMSelfAttention):
137
+ """SDPA self-attention via torch.nn.functional.scaled_dot_product_attention."""
138
+
139
+ def forward(
140
+ self,
141
+ hidden_states: torch.Tensor,
142
+ key_padding_mask: Optional[torch.Tensor] = None,
143
+ output_attentions: bool = False,
144
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
145
+ if output_attentions:
146
+ return super().forward(hidden_states, key_padding_mask, output_attentions=True)
147
+
148
+ B, T, _ = hidden_states.shape
149
+ q = self._split_heads(self.query(hidden_states))
150
+ k = self._split_heads(self.key(hidden_states))
151
+ v = self._split_heads(self.value(hidden_states))
152
+ q, k = self._maybe_rotary(q, k)
153
+
154
+ attn_mask = None
155
+ if key_padding_mask is not None:
156
+ attn_mask = torch.zeros(B, 1, 1, T, dtype=q.dtype, device=q.device)
157
+ attn_mask = attn_mask.masked_fill(key_padding_mask[:, None, None, :], float("-inf"))
158
+
159
+ context = F.scaled_dot_product_attention(q, k, v, attn_mask=attn_mask)
160
+ context = context.permute(0, 2, 1, 3).contiguous().view(B, T, self.all_head_size)
161
+ return context, None
162
+
163
+
164
+ class GenaLMFlashSelfAttention(GenaLMSelfAttention):
165
+ """Flash Attention 2 self-attention."""
166
+
167
+ def forward(
168
+ self,
169
+ hidden_states: torch.Tensor,
170
+ key_padding_mask: Optional[torch.Tensor] = None,
171
+ output_attentions: bool = False,
172
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
173
+ if output_attentions:
174
+ return super().forward(hidden_states, key_padding_mask, output_attentions=True)
175
+
176
+ try:
177
+ from flash_attn import flash_attn_func, flash_attn_varlen_func
178
+ from flash_attn.bert_padding import pad_input, unpad_input
179
+ except ImportError as e:
180
+ raise ImportError(
181
+ "flash_attn is required for attn_implementation='flash_attention_2'. "
182
+ "Install with: pip install flash-attn --no-build-isolation"
183
+ ) from e
184
+
185
+ B, T, _ = hidden_states.shape
186
+ q = self._split_heads(self.query(hidden_states)) # (B, H, T, D)
187
+ k = self._split_heads(self.key(hidden_states))
188
+ v = self._split_heads(self.value(hidden_states))
189
+ q, k = self._maybe_rotary(q, k)
190
+
191
+ # flash_attn expects (B, T, H, D)
192
+ q = q.permute(0, 2, 1, 3)
193
+ k = k.permute(0, 2, 1, 3)
194
+ v = v.permute(0, 2, 1, 3)
195
+
196
+ orig_dtype = q.dtype
197
+ if orig_dtype not in (torch.float16, torch.bfloat16):
198
+ q, k, v = q.to(torch.bfloat16), k.to(torch.bfloat16), v.to(torch.bfloat16)
199
+
200
+ if key_padding_mask is not None and key_padding_mask.any():
201
+ attend = ~key_padding_mask # True = valid token
202
+ q_u, indices, cu_seqlens, max_seqlen, _ = unpad_input(q, attend)
203
+ k_u, _, _, _, _ = unpad_input(k, attend)
204
+ v_u, _, _, _, _ = unpad_input(v, attend)
205
+ out_u = flash_attn_varlen_func(
206
+ q_u, k_u, v_u,
207
+ cu_seqlens_q=cu_seqlens, cu_seqlens_k=cu_seqlens,
208
+ max_seqlen_q=max_seqlen, max_seqlen_k=max_seqlen,
209
+ causal=False,
210
+ )
211
+ out = pad_input(out_u, indices, B, T)
212
+ else:
213
+ out = flash_attn_func(q, k, v, causal=False)
214
+
215
+ out = out.to(orig_dtype).reshape(B, T, self.all_head_size)
216
+ return out, None
217
+
218
+
219
+ GENALM_SELF_ATTENTION_CLASSES = {
220
+ "eager": GenaLMSelfAttention,
221
+ "sdpa": GenaLMSdpaSelfAttention,
222
+ "flash_attention_2": GenaLMFlashSelfAttention,
223
+ }
224
+
225
+
226
+ class GenaLMBlockSparseSelfAttention(GenaLMSelfAttention):
227
+ """BigBird block-sparse self-attention, computed as masked dense attention.
228
+
229
+ Block-sparse attention is, by definition, dense attention restricted to a set of
230
+ allowed (query-block, key-block) pairs, with the softmax taken over the allowed keys
231
+ only. Each layer's allowed pattern is stored in ``master_layout`` (num_heads,
232
+ max_blocks, max_blocks), loaded from the original checkpoint; for a sequence of
233
+ ``nb = ceil(T / block)`` blocks we use ``master_layout[:, :nb, :nb]`` exactly as the
234
+ original DeepSpeed implementation does. This reproduces the original attention pattern
235
+ without requiring DeepSpeed's (triton-1.x-only) sparse kernels.
236
+
237
+ ``use_sdpa=True`` evaluates the masked attention with
238
+ ``F.scaled_dot_product_attention``; ``output_attentions`` always uses the explicit
239
+ (eager) path so the post-softmax probabilities can be returned.
240
+ """
241
+
242
+ def __init__(self, config: GenaLMConfig, use_sdpa: bool = False):
243
+ super().__init__(config)
244
+ self.block = config.sparse_block_size
245
+ self.use_sdpa = use_sdpa
246
+ max_blocks = config.max_position_embeddings // self.block
247
+ self.register_buffer(
248
+ "master_layout",
249
+ torch.zeros(self.num_attention_heads, max_blocks, max_blocks, dtype=torch.int64),
250
+ persistent=True,
251
+ )
252
+
253
+ def _block_mask(self, nb: int, device) -> torch.Tensor:
254
+ """(num_heads, nb*block, nb*block) bool, True where attention is allowed."""
255
+ layout = self.master_layout[:, :nb, :nb].to(device).bool()
256
+ return layout.repeat_interleave(self.block, dim=1).repeat_interleave(self.block, dim=2)
257
+
258
+ def forward(
259
+ self,
260
+ hidden_states: torch.Tensor,
261
+ key_padding_mask: Optional[torch.Tensor] = None,
262
+ output_attentions: bool = False,
263
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
264
+ B, T, _ = hidden_states.shape
265
+ q = self._split_heads(self.query(hidden_states)) # (B, H, T, D)
266
+ k = self._split_heads(self.key(hidden_states))
267
+ v = self._split_heads(self.value(hidden_states))
268
+ q, k = self._maybe_rotary(q, k)
269
+
270
+ # pad sequence up to a multiple of the block size
271
+ pad = (-T) % self.block
272
+ Tp = T + pad
273
+ if pad:
274
+ q = F.pad(q, (0, 0, 0, pad))
275
+ k = F.pad(k, (0, 0, 0, pad))
276
+ v = F.pad(v, (0, 0, 0, pad))
277
+ nb = Tp // self.block
278
+
279
+ # key positions that must never be attended to: original padding + block padding
280
+ key_pad = torch.zeros(B, Tp, dtype=torch.bool, device=q.device)
281
+ if key_padding_mask is not None:
282
+ key_pad[:, :T] = key_padding_mask
283
+ if pad:
284
+ key_pad[:, T:] = True
285
+
286
+ allowed = self._block_mask(nb, q.device) # (H, Tp, Tp)
287
+ disallowed = (~allowed)[None] # (1, H, Tp, Tp)
288
+ key_pad_b = key_pad[:, None, None, :] # (B, 1, 1, Tp)
289
+
290
+ if self.use_sdpa and not output_attentions:
291
+ attn_mask = torch.zeros(B, self.num_attention_heads, Tp, Tp, dtype=q.dtype, device=q.device)
292
+ attn_mask = attn_mask.masked_fill(disallowed, float("-inf"))
293
+ attn_mask = attn_mask.masked_fill(key_pad_b, float("-inf"))
294
+ context = F.scaled_dot_product_attention(q, k, v, attn_mask=attn_mask)
295
+ attn_weights = None
296
+ else:
297
+ scores = torch.matmul(q, k.transpose(-1, -2)) / math.sqrt(self.attention_head_size)
298
+ scores = scores.masked_fill(disallowed, float("-inf"))
299
+ scores = scores.masked_fill(key_pad_b, float("-inf"))
300
+ probs = F.softmax(scores, dim=-1)
301
+ attn_weights = probs[:, :, :T, :T] if output_attentions else None
302
+ probs = self.dropout(probs)
303
+ context = torch.matmul(probs, v)
304
+
305
+ context = context[:, :, :T, :].permute(0, 2, 1, 3).contiguous().view(B, T, self.all_head_size)
306
+ return context, attn_weights
307
+
308
+
309
+ # ---------------------------------------------------------------------------
310
+ # Layer components (pre-LayerNorm)
311
+ # ---------------------------------------------------------------------------
312
+
313
+ class GenaLMSelfOutput(nn.Module):
314
+ def __init__(self, config: GenaLMConfig):
315
+ super().__init__()
316
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
317
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
318
+
319
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
320
+ return self.dropout(self.dense(hidden_states))
321
+
322
+
323
+ class GenaLMAttention(nn.Module):
324
+ def __init__(self, config: GenaLMConfig):
325
+ super().__init__()
326
+ impl = getattr(config, "_attn_implementation", "eager")
327
+ if getattr(config, "sparse_block_size", 0):
328
+ if impl == "flash_attention_2":
329
+ raise ValueError(
330
+ "flash_attention_2 is not supported by GENA-LM block-sparse checkpoints: "
331
+ "Flash Attention cannot express their checkpoint-specific block mask. "
332
+ "Use attn_implementation='eager' or 'sdpa'."
333
+ )
334
+ self.self = GenaLMBlockSparseSelfAttention(config, use_sdpa=(impl == "sdpa"))
335
+ else:
336
+ self.self = GENALM_SELF_ATTENTION_CLASSES[impl](config)
337
+ self.output = GenaLMSelfOutput(config)
338
+
339
+ def forward(
340
+ self,
341
+ hidden_states: torch.Tensor,
342
+ key_padding_mask: Optional[torch.Tensor],
343
+ output_attentions: bool = False,
344
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
345
+ self_out, attn_weights = self.self(hidden_states, key_padding_mask, output_attentions)
346
+ return self.output(self_out), attn_weights
347
+
348
+
349
+ class GenaLMIntermediate(nn.Module):
350
+ def __init__(self, config: GenaLMConfig):
351
+ super().__init__()
352
+ self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
353
+ self.intermediate_act_fn = ACT2FN[config.hidden_act] if isinstance(config.hidden_act, str) else config.hidden_act
354
+
355
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
356
+ return self.intermediate_act_fn(self.dense(hidden_states))
357
+
358
+
359
+ class GenaLMOutput(nn.Module):
360
+ def __init__(self, config: GenaLMConfig):
361
+ super().__init__()
362
+ self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
363
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
364
+
365
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
366
+ return self.dropout(self.dense(hidden_states))
367
+
368
+
369
+ class GenaLMLayer(nn.Module):
370
+ def __init__(self, config: GenaLMConfig):
371
+ super().__init__()
372
+ self.pre_attention_ln = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
373
+ self.post_attention_ln = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
374
+ self.attention = GenaLMAttention(config)
375
+ self.intermediate = GenaLMIntermediate(config)
376
+ self.output = GenaLMOutput(config)
377
+
378
+ def forward(
379
+ self,
380
+ hidden_states: torch.Tensor,
381
+ key_padding_mask: Optional[torch.Tensor],
382
+ output_attentions: bool = False,
383
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
384
+ attn_out, attn_weights = self.attention(
385
+ self.pre_attention_ln(hidden_states), key_padding_mask, output_attentions
386
+ )
387
+ hidden_states = hidden_states + attn_out
388
+ ffn_out = self.output(self.intermediate(self.post_attention_ln(hidden_states)))
389
+ hidden_states = hidden_states + ffn_out
390
+ return hidden_states, attn_weights
391
+
392
+
393
+ class GenaLMEncoder(nn.Module):
394
+ def __init__(self, config: GenaLMConfig):
395
+ super().__init__()
396
+ self.layer = nn.ModuleList([GenaLMLayer(config) for _ in range(config.num_hidden_layers)])
397
+ self.last_layer_norm = config.last_layer_norm
398
+ if self.last_layer_norm:
399
+ self.last_layer_ln = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
400
+
401
+ def forward(
402
+ self,
403
+ hidden_states: torch.Tensor,
404
+ key_padding_mask: Optional[torch.Tensor],
405
+ output_hidden_states: bool = False,
406
+ output_attentions: bool = False,
407
+ ) -> Tuple:
408
+ all_hidden_states = () if output_hidden_states else None
409
+ all_attentions = () if output_attentions else None
410
+
411
+ for layer in self.layer:
412
+ if output_hidden_states:
413
+ all_hidden_states = all_hidden_states + (hidden_states,)
414
+ hidden_states, attn_weights = layer(hidden_states, key_padding_mask, output_attentions)
415
+ if output_attentions:
416
+ all_attentions = all_attentions + (attn_weights,)
417
+
418
+ if self.last_layer_norm:
419
+ hidden_states = self.last_layer_ln(hidden_states)
420
+ if output_hidden_states:
421
+ all_hidden_states = all_hidden_states + (hidden_states,)
422
+
423
+ return hidden_states, all_hidden_states, all_attentions
424
+
425
+
426
+ # ---------------------------------------------------------------------------
427
+ # Embeddings, pooler, MLM head
428
+ # ---------------------------------------------------------------------------
429
+
430
+ class GenaLMEmbeddings(nn.Module):
431
+ def __init__(self, config: GenaLMConfig):
432
+ super().__init__()
433
+ self.position_embedding_type = config.position_embedding_type
434
+ self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
435
+ if self.position_embedding_type == "absolute":
436
+ self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)
437
+ self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
438
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
439
+ self.dropout = nn.Dropout(config.hidden_dropout_prob)
440
+ self.register_buffer(
441
+ "position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False
442
+ )
443
+
444
+ def forward(self, input_ids: torch.LongTensor, token_type_ids: Optional[torch.LongTensor] = None) -> torch.Tensor:
445
+ B, T = input_ids.shape
446
+ if token_type_ids is None:
447
+ token_type_ids = torch.zeros_like(input_ids)
448
+ x = self.word_embeddings(input_ids) + self.token_type_embeddings(token_type_ids)
449
+ if self.position_embedding_type == "absolute":
450
+ x = x + self.position_embeddings(self.position_ids[:, :T])
451
+ return self.dropout(self.LayerNorm(x))
452
+
453
+
454
+ class GenaLMPooler(nn.Module):
455
+ def __init__(self, config: GenaLMConfig):
456
+ super().__init__()
457
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
458
+ self.activation = nn.Tanh()
459
+
460
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
461
+ return self.activation(self.dense(hidden_states[:, 0]))
462
+
463
+
464
+ class GenaLMPredictionHeadTransform(nn.Module):
465
+ def __init__(self, config: GenaLMConfig):
466
+ super().__init__()
467
+ self.dense = nn.Linear(config.hidden_size, config.hidden_size)
468
+ self.transform_act_fn = ACT2FN[config.hidden_act] if isinstance(config.hidden_act, str) else config.hidden_act
469
+ self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
470
+
471
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
472
+ return self.LayerNorm(self.transform_act_fn(self.dense(hidden_states)))
473
+
474
+
475
+ class GenaLMLMPredictionHead(nn.Module):
476
+ def __init__(self, config: GenaLMConfig):
477
+ super().__init__()
478
+ self.transform = GenaLMPredictionHeadTransform(config)
479
+ self.decoder = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
480
+ self.bias = nn.Parameter(torch.zeros(config.vocab_size))
481
+ self.decoder.bias = self.bias
482
+
483
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
484
+ return self.decoder(self.transform(hidden_states))
485
+
486
+ def _tie_weights(self):
487
+ self.decoder.bias = self.bias
488
+
489
+
490
+ class GenaLMOnlyMLMHead(nn.Module):
491
+ def __init__(self, config: GenaLMConfig):
492
+ super().__init__()
493
+ self.predictions = GenaLMLMPredictionHead(config)
494
+
495
+ def forward(self, sequence_output: torch.Tensor) -> torch.Tensor:
496
+ return self.predictions(sequence_output)
497
+
498
+
499
+ # ---------------------------------------------------------------------------
500
+ # Top-level models
501
+ # ---------------------------------------------------------------------------
502
+
503
+ class GenaLMPreTrainedModel(PreTrainedModel):
504
+ config_class = GenaLMConfig
505
+ base_model_prefix = "bert"
506
+ supports_gradient_checkpointing = False
507
+ _supports_sdpa = True
508
+ _supports_flash_attn_2 = True
509
+
510
+ def _init_weights(self, module):
511
+ std = self.config.initializer_range
512
+ if isinstance(module, nn.Linear):
513
+ module.weight.data.normal_(mean=0.0, std=std)
514
+ if module.bias is not None:
515
+ module.bias.data.zero_()
516
+ elif isinstance(module, nn.Embedding):
517
+ module.weight.data.normal_(mean=0.0, std=std)
518
+ if module.padding_idx is not None:
519
+ module.weight.data[module.padding_idx].zero_()
520
+ elif isinstance(module, nn.LayerNorm):
521
+ module.bias.data.zero_()
522
+ module.weight.data.fill_(1.0)
523
+
524
+
525
+ def _key_padding_mask(input_ids, attention_mask, pad_token_id):
526
+ if attention_mask is None:
527
+ mask = input_ids.ne(pad_token_id)
528
+ else:
529
+ mask = attention_mask.ne(0)
530
+ key_padding_mask = ~mask # True = padding
531
+ if not key_padding_mask.any():
532
+ return None
533
+ return key_padding_mask
534
+
535
+
536
+ class GenaLMModel(GenaLMPreTrainedModel):
537
+ def __init__(self, config: GenaLMConfig, add_pooling_layer: bool = False):
538
+ super().__init__(config)
539
+ self.embeddings = GenaLMEmbeddings(config)
540
+ self.encoder = GenaLMEncoder(config)
541
+ self.pooler = GenaLMPooler(config) if add_pooling_layer else None
542
+ self.post_init()
543
+
544
+ def get_input_embeddings(self):
545
+ return self.embeddings.word_embeddings
546
+
547
+ def set_input_embeddings(self, value):
548
+ self.embeddings.word_embeddings = value
549
+
550
+ def forward(
551
+ self,
552
+ input_ids: torch.LongTensor,
553
+ attention_mask: Optional[torch.Tensor] = None,
554
+ token_type_ids: Optional[torch.LongTensor] = None,
555
+ output_hidden_states: Optional[bool] = None,
556
+ output_attentions: Optional[bool] = None,
557
+ return_dict: Optional[bool] = None,
558
+ ) -> Union[Tuple, BaseModelOutputWithPooling]:
559
+ output_hidden_states = (
560
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
561
+ )
562
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
563
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
564
+
565
+ key_padding_mask = _key_padding_mask(input_ids, attention_mask, self.config.pad_token_id)
566
+
567
+ x = self.embeddings(input_ids, token_type_ids)
568
+ last_hidden_state, all_hidden_states, all_attentions = self.encoder(
569
+ x, key_padding_mask,
570
+ output_hidden_states=output_hidden_states,
571
+ output_attentions=output_attentions,
572
+ )
573
+ pooled = self.pooler(last_hidden_state) if self.pooler is not None else None
574
+
575
+ if not return_dict:
576
+ return tuple(v for v in [last_hidden_state, pooled, all_hidden_states, all_attentions] if v is not None)
577
+
578
+ return BaseModelOutputWithPooling(
579
+ last_hidden_state=last_hidden_state,
580
+ pooler_output=pooled,
581
+ hidden_states=all_hidden_states,
582
+ attentions=all_attentions,
583
+ )
584
+
585
+
586
+ class GenaLMForMaskedLM(GenaLMPreTrainedModel):
587
+ _tied_weights_keys = ["cls.predictions.decoder.weight", "cls.predictions.decoder.bias"]
588
+
589
+ def __init__(self, config: GenaLMConfig):
590
+ super().__init__(config)
591
+ self.bert = GenaLMModel(config, add_pooling_layer=False)
592
+ self.cls = GenaLMOnlyMLMHead(config)
593
+ self.post_init()
594
+
595
+ def get_input_embeddings(self):
596
+ return self.bert.embeddings.word_embeddings
597
+
598
+ def get_output_embeddings(self):
599
+ return self.cls.predictions.decoder
600
+
601
+ def set_output_embeddings(self, new_embeddings):
602
+ self.cls.predictions.decoder = new_embeddings
603
+
604
+ def forward(
605
+ self,
606
+ input_ids: torch.LongTensor,
607
+ attention_mask: Optional[torch.Tensor] = None,
608
+ token_type_ids: Optional[torch.LongTensor] = None,
609
+ labels: Optional[torch.LongTensor] = None,
610
+ output_hidden_states: Optional[bool] = None,
611
+ output_attentions: Optional[bool] = None,
612
+ return_dict: Optional[bool] = None,
613
+ ) -> Union[Tuple, MaskedLMOutput]:
614
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
615
+
616
+ outputs = self.bert(
617
+ input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids,
618
+ output_hidden_states=output_hidden_states, output_attentions=output_attentions,
619
+ return_dict=True,
620
+ )
621
+ logits = self.cls(outputs.last_hidden_state)
622
+
623
+ loss = None
624
+ if labels is not None:
625
+ loss = F.cross_entropy(logits.view(-1, self.config.vocab_size), labels.view(-1), ignore_index=-100)
626
+
627
+ if not return_dict:
628
+ output = (logits, outputs.hidden_states, outputs.attentions)
629
+ output = tuple(v for v in output if v is not None)
630
+ return ((loss,) + output) if loss is not None else output
631
+
632
+ return MaskedLMOutput(
633
+ loss=loss, logits=logits,
634
+ hidden_states=outputs.hidden_states, attentions=outputs.attentions,
635
+ )
special_tokens_map.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"unk_token": "[UNK]", "sep_token": "[SEP]", "pad_token": "[PAD]", "cls_token": "[CLS]", "mask_token": "[MASK]"}
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "tokenizer_class": "PreTrainedTokenizerFast",
3
+ "model_max_length": 512,
4
+ "unk_token": "[UNK]",
5
+ "sep_token": "[SEP]",
6
+ "pad_token": "[PAD]",
7
+ "cls_token": "[CLS]",
8
+ "mask_token": "[MASK]"
9
+ }