Instructions to use Taykhoom/structRFM with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Taykhoom/structRFM with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("fill-mask", model="Taykhoom/structRFM", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForMaskedLM model = AutoModelForMaskedLM.from_pretrained("Taykhoom/structRFM", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
Commit ·
933cd85
0
Parent(s):
Initial structRFM HF port
Browse files- .gitattributes +35 -0
- README.md +210 -0
- config.json +27 -0
- configuration_bert_updated.py +43 -0
- model.safetensors +3 -0
- modeling_bert.py +547 -0
- special_tokens_map.json +7 -0
- tokenization_structrfm.py +104 -0
- tokenizer_config.json +17 -0
- vocab.json +12 -0
.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,210 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
library_name: transformers
|
| 3 |
+
tags:
|
| 4 |
+
- biology
|
| 5 |
+
- RNA
|
| 6 |
+
- language-model
|
| 7 |
+
- bert
|
| 8 |
+
license: mit
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
# structRFM
|
| 12 |
+
|
| 13 |
+
Minimal HuggingFace port of [structRFM](https://huggingface.co/heqin-zhu/structRFM)
|
| 14 |
+
-- a structure-guided RNA foundation model: a BERT encoder pretrained with
|
| 15 |
+
structure-guided masked language modeling on ~21M RNAcentral sequences paired
|
| 16 |
+
with ensemble-predicted secondary structures.
|
| 17 |
+
|
| 18 |
+
## Why this port?
|
| 19 |
+
|
| 20 |
+
[heqin-zhu/structRFM](https://huggingface.co/heqin-zhu/structRFM) ships the
|
| 21 |
+
weights as a stock `BertForMaskedLM`, but its tokenizer has no post-processing
|
| 22 |
+
template or normalizer. Upstream code builds the model input by hand
|
| 23 |
+
(`"[CLS]" + seq.upper().replace("T", "U") + "[SEP]"`); calling its
|
| 24 |
+
`AutoTokenizer` directly on a sequence silently:
|
| 25 |
+
|
| 26 |
+
1. adds **no** `[CLS]` / `[SEP]` tokens, and
|
| 27 |
+
2. maps `T` and every lowercase base to `[UNK]`.
|
| 28 |
+
|
| 29 |
+
This repo's tokenizer applies the upstream preprocessing itself (uppercase,
|
| 30 |
+
T->U, `[CLS] ... [SEP]`), so `tokenizer(seq)` produces exactly the token ids the
|
| 31 |
+
model was pretrained on. It also adds `flash_attention_2` support. The weights
|
| 32 |
+
are unchanged and bit-exact with the upstream release (see
|
| 33 |
+
[Parity Verification](#parity-verification)).
|
| 34 |
+
|
| 35 |
+
## Architecture
|
| 36 |
+
|
| 37 |
+
| Parameter | Value |
|
| 38 |
+
|---|---|
|
| 39 |
+
| Layers | 12 |
|
| 40 |
+
| Attention heads | 12 |
|
| 41 |
+
| Embedding dimension | 768 |
|
| 42 |
+
| FFN hidden dimension | 3072 (GELU) |
|
| 43 |
+
| Vocabulary size | 10 |
|
| 44 |
+
| Positional encoding | Learned absolute |
|
| 45 |
+
| Normalization | LayerNorm (post-residual, eps=1e-12) |
|
| 46 |
+
| Architecture | Post-LN BERT encoder |
|
| 47 |
+
| Max sequence length | 512 nt (514 tokens with [CLS] and [SEP]) |
|
| 48 |
+
| Parameters | 85.5M (encoder) + 0.6M (MLM head) |
|
| 49 |
+
|
| 50 |
+
**Vocabulary:** `[UNK]`=0, `[CLS]`=1, `[SEP]`=2, `[PAD]`=3, `[MASK]`=4,
|
| 51 |
+
`A`=5, `U`=6, `C`=7, `G`=8, `N`=9. Input is uppercased and `T` is read as `U`;
|
| 52 |
+
any other character (including whitespace) maps to `[UNK]`, as upstream.
|
| 53 |
+
|
| 54 |
+
## Pretraining
|
| 55 |
+
|
| 56 |
+
- **Objective:** Structure-guided masked language modeling (SgMLM): each batch
|
| 57 |
+
uses either standard 15% token masking or structure masking, where masking a
|
| 58 |
+
paired base also masks its partner; the share of structure-masked batches is
|
| 59 |
+
scheduled over training
|
| 60 |
+
- **Data:** ~21M RNAcentral sequences (<= 512 nt) with secondary structures from
|
| 61 |
+
MUSES, a multi-source ensemble of thermodynamic, probabilistic and
|
| 62 |
+
deep-learning predictors
|
| 63 |
+
- **Source checkpoint:** `structRFM_checkpoint.tar.gz` from the upstream
|
| 64 |
+
[v0.0.8 release](https://github.com/heqin-zhu/structRFM/releases/tag/v0.0.8)
|
| 65 |
+
(identical to [`heqin-zhu/structRFM`](https://huggingface.co/heqin-zhu/structRFM))
|
| 66 |
+
|
| 67 |
+
### Checkpoint selection
|
| 68 |
+
|
| 69 |
+
Upstream released two pretrained models: v0.0.3, pretrained on single-predictor
|
| 70 |
+
(BPfold) structures, and v0.0.8, re-pretrained on MUSES ensemble structures.
|
| 71 |
+
v0.0.8 replaced v0.0.3 on the Hub and is the base of every released downstream
|
| 72 |
+
checkpoint, so it is the one ported here.
|
| 73 |
+
|
| 74 |
+
The released secondary-structure (`structRFM_SSP_bpRNA1m.pt`,
|
| 75 |
+
`structRFM_SSP_RNAStrAlign.pt`), tertiary-structure and IRES checkpoints train a
|
| 76 |
+
task head on detached encoder features, so their encoder weights are
|
| 77 |
+
bit-identical to this model; use this repo for their embeddings.
|
| 78 |
+
|
| 79 |
+
## Parity Verification
|
| 80 |
+
|
| 81 |
+
All 13 representation levels (embedding + 12 transformer blocks) and the MLM
|
| 82 |
+
logits verified to be bit-exact (max abs diff = 0.00) against the original
|
| 83 |
+
v0.0.8 weights run through the upstream `structRFM` code, with `eager` and `sdpa`
|
| 84 |
+
attention, on padded and unpadded batches. The tokenizer reproduces the upstream
|
| 85 |
+
token ids exactly. Verified on an NVIDIA H100 with PyTorch 2.7 / CUDA 12.9.
|
| 86 |
+
|
| 87 |
+
## Related Models
|
| 88 |
+
|
| 89 |
+
See the full [structRFM collection](https://huggingface.co/collections/Taykhoom/structrfm-6aebd71d994e3b036c62ed23).
|
| 90 |
+
|
| 91 |
+
| Model | Parameters | Notes |
|
| 92 |
+
|---|---:|---|
|
| 93 |
+
| **[structRFM](https://huggingface.co/Taykhoom/structRFM)** | 86M | This model |
|
| 94 |
+
|
| 95 |
+
## Usage
|
| 96 |
+
|
| 97 |
+
### Embedding generation
|
| 98 |
+
|
| 99 |
+
```python
|
| 100 |
+
import torch
|
| 101 |
+
from transformers import AutoTokenizer, AutoModel
|
| 102 |
+
|
| 103 |
+
tokenizer = AutoTokenizer.from_pretrained("Taykhoom/structRFM", trust_remote_code=True)
|
| 104 |
+
model = AutoModel.from_pretrained("Taykhoom/structRFM", trust_remote_code=True)
|
| 105 |
+
model.eval()
|
| 106 |
+
|
| 107 |
+
sequences = ["GUCCCAACUCUUGCGGGGAGGGAU", "ATGGCTACGTAG"] # T is read as U
|
| 108 |
+
enc = tokenizer(sequences, return_tensors="pt", padding=True)
|
| 109 |
+
|
| 110 |
+
with torch.no_grad():
|
| 111 |
+
out = model(**enc)
|
| 112 |
+
|
| 113 |
+
cls_emb = out.last_hidden_state[:, 0, :] # (batch, 768) -- CLS token
|
| 114 |
+
token_emb = out.last_hidden_state # (batch, seq_len, 768)
|
| 115 |
+
|
| 116 |
+
# Mean over nucleotides only (drop [CLS], [SEP] and padding)
|
| 117 |
+
special = torch.isin(enc.input_ids, torch.tensor([tokenizer.cls_token_id, tokenizer.sep_token_id]))
|
| 118 |
+
mask = (enc.attention_mask.bool() & ~special).unsqueeze(-1)
|
| 119 |
+
mean_emb = (token_emb * mask).sum(1) / mask.sum(1) # (batch, 768)
|
| 120 |
+
|
| 121 |
+
# Intermediate layers: hidden_states[0] is the embedding, [i] block i
|
| 122 |
+
out_all = model(**enc, output_hidden_states=True)
|
| 123 |
+
layer6_emb = out_all.hidden_states[6]
|
| 124 |
+
```
|
| 125 |
+
|
| 126 |
+
Sequences longer than 512 nt must be split into windows (e.g. 512 nt chunks)
|
| 127 |
+
and the per-window embeddings pooled.
|
| 128 |
+
|
| 129 |
+
### MLM logits
|
| 130 |
+
|
| 131 |
+
```python
|
| 132 |
+
import torch
|
| 133 |
+
from transformers import AutoTokenizer, AutoModelForMaskedLM
|
| 134 |
+
|
| 135 |
+
tokenizer = AutoTokenizer.from_pretrained("Taykhoom/structRFM", trust_remote_code=True)
|
| 136 |
+
model = AutoModelForMaskedLM.from_pretrained("Taykhoom/structRFM", trust_remote_code=True)
|
| 137 |
+
model.eval()
|
| 138 |
+
|
| 139 |
+
enc = tokenizer(["GUCCCAAC[MASK]CUUGCGG"], return_tensors="pt")
|
| 140 |
+
with torch.no_grad():
|
| 141 |
+
logits = model(**enc).logits # (1, seq_len, 10)
|
| 142 |
+
```
|
| 143 |
+
|
| 144 |
+
### Faster attention backends
|
| 145 |
+
|
| 146 |
+
```python
|
| 147 |
+
# SDPA (PyTorch 2.0+) -- recommended for production
|
| 148 |
+
model = AutoModel.from_pretrained("Taykhoom/structRFM", trust_remote_code=True,
|
| 149 |
+
attn_implementation="sdpa")
|
| 150 |
+
|
| 151 |
+
# Flash Attention 2 (requires flash-attn) -- fastest on long sequences
|
| 152 |
+
model = AutoModel.from_pretrained("Taykhoom/structRFM", trust_remote_code=True,
|
| 153 |
+
attn_implementation="flash_attention_2",
|
| 154 |
+
dtype=torch.bfloat16)
|
| 155 |
+
```
|
| 156 |
+
|
| 157 |
+
| Backend | Status |
|
| 158 |
+
|---|---|
|
| 159 |
+
| `eager` | Supported; bit-exact with upstream eager |
|
| 160 |
+
| `sdpa` | Supported; bit-exact with upstream (the upstream default backend) |
|
| 161 |
+
| `flash_attention_2` | Supported (added by this port); requires fp16/bf16 weights |
|
| 162 |
+
|
| 163 |
+
`output_attentions=True` falls back to eager under `sdpa` and
|
| 164 |
+
`flash_attention_2` and returns post-softmax attention probabilities
|
| 165 |
+
`(batch, heads, seq_len, seq_len)`.
|
| 166 |
+
|
| 167 |
+
### Fine-tuning
|
| 168 |
+
|
| 169 |
+
Standard HF conventions. For sequence-level tasks, use the CLS embedding or a
|
| 170 |
+
masked mean over nucleotide positions as input to a prediction head; for
|
| 171 |
+
nucleotide- or pair-level tasks use `last_hidden_state` directly.
|
| 172 |
+
`gradient_checkpointing_enable()` is supported.
|
| 173 |
+
|
| 174 |
+
## Implementation Notes
|
| 175 |
+
|
| 176 |
+
This port reuses the shared [BERT-updated](https://huggingface.co/Taykhoom/BERT-updated)
|
| 177 |
+
runtime (identical to the stock `transformers` BERT architecture), which adds
|
| 178 |
+
`flash_attention_2` alongside `eager` and `sdpa`. The MLM decoder is tied to the
|
| 179 |
+
input embeddings, as in the upstream checkpoint.
|
| 180 |
+
|
| 181 |
+
`config.pad_token_id` is 0 (`[UNK]`), the value in the upstream config, while
|
| 182 |
+
the tokenizer pads with `[PAD]`=3. The config value only sets the embedding's
|
| 183 |
+
`padding_idx` (no gradient into that row during fine-tuning) and is kept for
|
| 184 |
+
fidelity; padding is controlled by `attention_mask`.
|
| 185 |
+
|
| 186 |
+
The pooler (`pooler_output`) is not part of the pretrained checkpoint and is
|
| 187 |
+
randomly initialized; do not use it without fine-tuning.
|
| 188 |
+
|
| 189 |
+
## Citation
|
| 190 |
+
|
| 191 |
+
```bibtex
|
| 192 |
+
@article{zhu2026_structrfm,
|
| 193 |
+
title = {An open structure-guided {RNA} foundation model for generalizable prediction},
|
| 194 |
+
author = {Zhu, Heqin and Li, Ruifeng and Chang, Ao and Chen, Haobin and Zhang, Feng and Tang, Fenghe and Ye, Tong and Li, Xin and Gu, Yunjie and Xiong, Peng and Zhou, S. Kevin},
|
| 195 |
+
journal = {Nature},
|
| 196 |
+
year = {2026},
|
| 197 |
+
doi = {10.1038/s41586-026-11210-2}
|
| 198 |
+
}
|
| 199 |
+
```
|
| 200 |
+
|
| 201 |
+
## Credits
|
| 202 |
+
|
| 203 |
+
Original model and code by Zhu et al. Source:
|
| 204 |
+
[GitHub](https://github.com/heqin-zhu/structRFM),
|
| 205 |
+
[`heqin-zhu/structRFM` on the Hub](https://huggingface.co/heqin-zhu/structRFM).
|
| 206 |
+
Hugging Face port maintained by Taykhoom Dalal.
|
| 207 |
+
|
| 208 |
+
## License
|
| 209 |
+
|
| 210 |
+
MIT, following the original repository.
|
config.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"BertForMaskedLM"
|
| 4 |
+
],
|
| 5 |
+
"model_type": "bert_updated",
|
| 6 |
+
"auto_map": {
|
| 7 |
+
"AutoConfig": "configuration_bert_updated.BertUpdatedConfig",
|
| 8 |
+
"AutoModel": "modeling_bert.BertModel",
|
| 9 |
+
"AutoModelForMaskedLM": "modeling_bert.BertForMaskedLM"
|
| 10 |
+
},
|
| 11 |
+
"vocab_size": 10,
|
| 12 |
+
"hidden_size": 768,
|
| 13 |
+
"num_hidden_layers": 12,
|
| 14 |
+
"num_attention_heads": 12,
|
| 15 |
+
"intermediate_size": 3072,
|
| 16 |
+
"hidden_act": "gelu",
|
| 17 |
+
"hidden_dropout_prob": 0.1,
|
| 18 |
+
"attention_probs_dropout_prob": 0.1,
|
| 19 |
+
"max_position_embeddings": 514,
|
| 20 |
+
"type_vocab_size": 2,
|
| 21 |
+
"initializer_range": 0.02,
|
| 22 |
+
"layer_norm_eps": 1e-12,
|
| 23 |
+
"pad_token_id": 0,
|
| 24 |
+
"model_max_length": 514,
|
| 25 |
+
"transformers_version": "4.57.6",
|
| 26 |
+
"_name_or_path": "Taykhoom/structRFM"
|
| 27 |
+
}
|
configuration_bert_updated.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from transformers import PretrainedConfig
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
class BertUpdatedConfig(PretrainedConfig):
|
| 5 |
+
model_type = "bert_updated"
|
| 6 |
+
|
| 7 |
+
auto_map = {
|
| 8 |
+
"AutoConfig": "configuration_bert_updated.BertUpdatedConfig",
|
| 9 |
+
"AutoModel": "modeling_bert.BertModel",
|
| 10 |
+
"AutoModelForMaskedLM": "modeling_bert.BertForMaskedLM",
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
def __init__(
|
| 14 |
+
self,
|
| 15 |
+
vocab_size=30522,
|
| 16 |
+
hidden_size=768,
|
| 17 |
+
num_hidden_layers=12,
|
| 18 |
+
num_attention_heads=12,
|
| 19 |
+
intermediate_size=3072,
|
| 20 |
+
hidden_act="gelu",
|
| 21 |
+
mlm_hidden_act=None,
|
| 22 |
+
hidden_dropout_prob=0.1,
|
| 23 |
+
attention_probs_dropout_prob=0.1,
|
| 24 |
+
max_position_embeddings=512,
|
| 25 |
+
type_vocab_size=2,
|
| 26 |
+
initializer_range=0.02,
|
| 27 |
+
layer_norm_eps=1e-12,
|
| 28 |
+
**kwargs,
|
| 29 |
+
):
|
| 30 |
+
super().__init__(**kwargs)
|
| 31 |
+
self.vocab_size = vocab_size
|
| 32 |
+
self.hidden_size = hidden_size
|
| 33 |
+
self.num_hidden_layers = num_hidden_layers
|
| 34 |
+
self.num_attention_heads = num_attention_heads
|
| 35 |
+
self.intermediate_size = intermediate_size
|
| 36 |
+
self.hidden_act = hidden_act
|
| 37 |
+
self.mlm_hidden_act = mlm_hidden_act
|
| 38 |
+
self.hidden_dropout_prob = hidden_dropout_prob
|
| 39 |
+
self.attention_probs_dropout_prob = attention_probs_dropout_prob
|
| 40 |
+
self.max_position_embeddings = max_position_embeddings
|
| 41 |
+
self.type_vocab_size = type_vocab_size
|
| 42 |
+
self.initializer_range = initializer_range
|
| 43 |
+
self.layer_norm_eps = layer_norm_eps
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8d8e8dcc064b1b584b8ba6ee756cbfbc7953002e8ce580dfcfe85dc27a216a36
|
| 3 |
+
size 344262720
|
modeling_bert.py
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import math
|
| 2 |
+
from typing import Optional, Tuple, Union
|
| 3 |
+
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.nn.functional as F
|
| 7 |
+
import torch.utils.checkpoint
|
| 8 |
+
from transformers.activations import ACT2FN
|
| 9 |
+
from transformers import PreTrainedModel, PretrainedConfig
|
| 10 |
+
from transformers.modeling_outputs import BaseModelOutputWithPooling, MaskedLMOutput
|
| 11 |
+
|
| 12 |
+
from .configuration_bert_updated import BertUpdatedConfig
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class BertSelfAttention(nn.Module):
|
| 16 |
+
|
| 17 |
+
def __init__(self, config):
|
| 18 |
+
super().__init__()
|
| 19 |
+
self.num_attention_heads = config.num_attention_heads
|
| 20 |
+
self.attention_head_size = config.hidden_size // config.num_attention_heads
|
| 21 |
+
self.all_head_size = self.num_attention_heads * self.attention_head_size
|
| 22 |
+
|
| 23 |
+
self.query = nn.Linear(config.hidden_size, self.all_head_size)
|
| 24 |
+
self.key = nn.Linear(config.hidden_size, self.all_head_size)
|
| 25 |
+
self.value = nn.Linear(config.hidden_size, self.all_head_size)
|
| 26 |
+
self.dropout = nn.Dropout(config.attention_probs_dropout_prob)
|
| 27 |
+
|
| 28 |
+
def _split_heads(self, x: torch.Tensor) -> torch.Tensor:
|
| 29 |
+
B, T, _ = x.shape
|
| 30 |
+
return x.view(B, T, self.num_attention_heads, self.attention_head_size).permute(0, 2, 1, 3)
|
| 31 |
+
|
| 32 |
+
def forward(
|
| 33 |
+
self,
|
| 34 |
+
hidden_states: torch.Tensor,
|
| 35 |
+
key_padding_mask: Optional[torch.Tensor] = None,
|
| 36 |
+
output_attentions: bool = False,
|
| 37 |
+
head_mask: Optional[torch.Tensor] = None,
|
| 38 |
+
) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
|
| 39 |
+
q = self._split_heads(self.query(hidden_states))
|
| 40 |
+
k = self._split_heads(self.key(hidden_states))
|
| 41 |
+
v = self._split_heads(self.value(hidden_states))
|
| 42 |
+
|
| 43 |
+
scale = math.sqrt(self.attention_head_size)
|
| 44 |
+
scores = torch.matmul(q, k.transpose(-1, -2)) / scale
|
| 45 |
+
if key_padding_mask is not None:
|
| 46 |
+
scores = scores.masked_fill(key_padding_mask[:, None, None, :], float("-inf"))
|
| 47 |
+
probs = torch.nan_to_num(
|
| 48 |
+
F.softmax(scores.float(), dim=-1),
|
| 49 |
+
nan=0.0,
|
| 50 |
+
)
|
| 51 |
+
context_probs = self.dropout(probs)
|
| 52 |
+
if head_mask is not None:
|
| 53 |
+
context_probs = context_probs * head_mask
|
| 54 |
+
context = torch.matmul(context_probs.to(v.dtype), v)
|
| 55 |
+
|
| 56 |
+
B, _, T, _ = context.shape
|
| 57 |
+
context = context.permute(0, 2, 1, 3).contiguous().view(B, T, self.all_head_size)
|
| 58 |
+
|
| 59 |
+
if output_attentions:
|
| 60 |
+
return context, probs
|
| 61 |
+
return context, None
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
class BertSdpaSelfAttention(BertSelfAttention):
|
| 65 |
+
|
| 66 |
+
def forward(
|
| 67 |
+
self,
|
| 68 |
+
hidden_states: torch.Tensor,
|
| 69 |
+
key_padding_mask: Optional[torch.Tensor] = None,
|
| 70 |
+
output_attentions: bool = False,
|
| 71 |
+
head_mask: Optional[torch.Tensor] = None,
|
| 72 |
+
) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
|
| 73 |
+
if output_attentions or head_mask is not None:
|
| 74 |
+
return super().forward(
|
| 75 |
+
hidden_states,
|
| 76 |
+
key_padding_mask,
|
| 77 |
+
output_attentions=output_attentions,
|
| 78 |
+
head_mask=head_mask,
|
| 79 |
+
)
|
| 80 |
+
|
| 81 |
+
B, T, _ = hidden_states.shape
|
| 82 |
+
q = self._split_heads(self.query(hidden_states))
|
| 83 |
+
k = self._split_heads(self.key(hidden_states))
|
| 84 |
+
v = self._split_heads(self.value(hidden_states))
|
| 85 |
+
|
| 86 |
+
attn_mask = None
|
| 87 |
+
if key_padding_mask is not None:
|
| 88 |
+
attn_mask = torch.zeros(B, 1, 1, T, dtype=q.dtype, device=q.device)
|
| 89 |
+
attn_mask = attn_mask.masked_fill(key_padding_mask[:, None, None, :], float("-inf"))
|
| 90 |
+
|
| 91 |
+
context = F.scaled_dot_product_attention(
|
| 92 |
+
q,
|
| 93 |
+
k,
|
| 94 |
+
v,
|
| 95 |
+
attn_mask=attn_mask,
|
| 96 |
+
dropout_p=self.dropout.p if self.training else 0.0,
|
| 97 |
+
)
|
| 98 |
+
context = context.permute(0, 2, 1, 3).contiguous().view(B, T, self.all_head_size)
|
| 99 |
+
return context, None
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
class BertFlashSelfAttention(BertSelfAttention):
|
| 103 |
+
|
| 104 |
+
def forward(
|
| 105 |
+
self,
|
| 106 |
+
hidden_states: torch.Tensor,
|
| 107 |
+
key_padding_mask: Optional[torch.Tensor] = None,
|
| 108 |
+
output_attentions: bool = False,
|
| 109 |
+
head_mask: Optional[torch.Tensor] = None,
|
| 110 |
+
) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
|
| 111 |
+
if (
|
| 112 |
+
output_attentions
|
| 113 |
+
or head_mask is not None
|
| 114 |
+
or (
|
| 115 |
+
key_padding_mask is not None
|
| 116 |
+
and (~key_padding_mask).sum(dim=-1).eq(0).any()
|
| 117 |
+
)
|
| 118 |
+
):
|
| 119 |
+
return super().forward(
|
| 120 |
+
hidden_states,
|
| 121 |
+
key_padding_mask,
|
| 122 |
+
output_attentions=output_attentions,
|
| 123 |
+
head_mask=head_mask,
|
| 124 |
+
)
|
| 125 |
+
|
| 126 |
+
try:
|
| 127 |
+
from flash_attn import flash_attn_func, flash_attn_varlen_func
|
| 128 |
+
from flash_attn.bert_padding import pad_input, unpad_input
|
| 129 |
+
except ImportError as e:
|
| 130 |
+
raise ImportError(
|
| 131 |
+
"flash_attn is required for attn_implementation='flash_attention_2'. "
|
| 132 |
+
"Install with: pip install flash-attn --no-build-isolation"
|
| 133 |
+
) from e
|
| 134 |
+
|
| 135 |
+
B, T, _ = hidden_states.shape
|
| 136 |
+
q = self._split_heads(self.query(hidden_states)).permute(0, 2, 1, 3)
|
| 137 |
+
k = self._split_heads(self.key(hidden_states)).permute(0, 2, 1, 3)
|
| 138 |
+
v = self._split_heads(self.value(hidden_states)).permute(0, 2, 1, 3)
|
| 139 |
+
|
| 140 |
+
if q.dtype not in (torch.float16, torch.bfloat16):
|
| 141 |
+
raise ValueError(
|
| 142 |
+
"flash_attention_2 requires float16 or bfloat16 model weights. "
|
| 143 |
+
f"Received {q.dtype}."
|
| 144 |
+
)
|
| 145 |
+
|
| 146 |
+
if key_padding_mask is not None and key_padding_mask.any():
|
| 147 |
+
attend = ~key_padding_mask
|
| 148 |
+
q_u, indices, cu_seqlens, max_seqlen, _ = unpad_input(q, attend)
|
| 149 |
+
k_u, _, _, _, _ = unpad_input(k, attend)
|
| 150 |
+
v_u, _, _, _, _ = unpad_input(v, attend)
|
| 151 |
+
out_u = flash_attn_varlen_func(
|
| 152 |
+
q_u, k_u, v_u,
|
| 153 |
+
cu_seqlens_q=cu_seqlens, cu_seqlens_k=cu_seqlens,
|
| 154 |
+
max_seqlen_q=max_seqlen, max_seqlen_k=max_seqlen,
|
| 155 |
+
dropout_p=self.dropout.p if self.training else 0.0,
|
| 156 |
+
causal=False,
|
| 157 |
+
)
|
| 158 |
+
out = pad_input(out_u, indices, B, T)
|
| 159 |
+
else:
|
| 160 |
+
out = flash_attn_func(
|
| 161 |
+
q,
|
| 162 |
+
k,
|
| 163 |
+
v,
|
| 164 |
+
dropout_p=self.dropout.p if self.training else 0.0,
|
| 165 |
+
causal=False,
|
| 166 |
+
)
|
| 167 |
+
|
| 168 |
+
out = out.reshape(B, T, self.all_head_size)
|
| 169 |
+
return out, None
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
BERT_SELF_ATTENTION_CLASSES = {
|
| 173 |
+
"eager": BertSelfAttention,
|
| 174 |
+
"sdpa": BertSdpaSelfAttention,
|
| 175 |
+
"flash_attention_2": BertFlashSelfAttention,
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
class BertSelfOutput(nn.Module):
|
| 180 |
+
def __init__(self, config):
|
| 181 |
+
super().__init__()
|
| 182 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 183 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 184 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 185 |
+
|
| 186 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 187 |
+
hidden_states = self.dropout(self.dense(hidden_states))
|
| 188 |
+
return self.LayerNorm(hidden_states + input_tensor)
|
| 189 |
+
|
| 190 |
+
|
| 191 |
+
class BertAttention(nn.Module):
|
| 192 |
+
def __init__(self, config):
|
| 193 |
+
super().__init__()
|
| 194 |
+
attn_cls = BERT_SELF_ATTENTION_CLASSES[getattr(config, "_attn_implementation", "eager")]
|
| 195 |
+
self.self = attn_cls(config)
|
| 196 |
+
self.output = BertSelfOutput(config)
|
| 197 |
+
|
| 198 |
+
def forward(
|
| 199 |
+
self,
|
| 200 |
+
hidden_states: torch.Tensor,
|
| 201 |
+
key_padding_mask: Optional[torch.Tensor],
|
| 202 |
+
output_attentions: bool = False,
|
| 203 |
+
head_mask: Optional[torch.Tensor] = None,
|
| 204 |
+
) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
|
| 205 |
+
self_out, attn_weights = self.self(
|
| 206 |
+
hidden_states,
|
| 207 |
+
key_padding_mask,
|
| 208 |
+
output_attentions,
|
| 209 |
+
head_mask,
|
| 210 |
+
)
|
| 211 |
+
return self.output(self_out, hidden_states), attn_weights
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
class BertIntermediate(nn.Module):
|
| 215 |
+
def __init__(self, config):
|
| 216 |
+
super().__init__()
|
| 217 |
+
self.dense = nn.Linear(config.hidden_size, config.intermediate_size)
|
| 218 |
+
if config.hidden_act in (None, "identity", "linear"):
|
| 219 |
+
self.intermediate_act_fn = lambda value: value
|
| 220 |
+
elif isinstance(config.hidden_act, str):
|
| 221 |
+
self.intermediate_act_fn = ACT2FN[config.hidden_act]
|
| 222 |
+
else:
|
| 223 |
+
self.intermediate_act_fn = config.hidden_act
|
| 224 |
+
|
| 225 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 226 |
+
return self.intermediate_act_fn(self.dense(hidden_states))
|
| 227 |
+
|
| 228 |
+
|
| 229 |
+
class BertOutput(nn.Module):
|
| 230 |
+
def __init__(self, config):
|
| 231 |
+
super().__init__()
|
| 232 |
+
self.dense = nn.Linear(config.intermediate_size, config.hidden_size)
|
| 233 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 234 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 235 |
+
|
| 236 |
+
def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:
|
| 237 |
+
hidden_states = self.dropout(self.dense(hidden_states))
|
| 238 |
+
return self.LayerNorm(hidden_states + input_tensor)
|
| 239 |
+
|
| 240 |
+
|
| 241 |
+
class BertLayer(nn.Module):
|
| 242 |
+
def __init__(self, config):
|
| 243 |
+
super().__init__()
|
| 244 |
+
self.attention = BertAttention(config)
|
| 245 |
+
self.intermediate = BertIntermediate(config)
|
| 246 |
+
self.output = BertOutput(config)
|
| 247 |
+
|
| 248 |
+
def forward(
|
| 249 |
+
self,
|
| 250 |
+
hidden_states: torch.Tensor,
|
| 251 |
+
key_padding_mask: Optional[torch.Tensor],
|
| 252 |
+
output_attentions: bool = False,
|
| 253 |
+
head_mask: Optional[torch.Tensor] = None,
|
| 254 |
+
) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
|
| 255 |
+
attn_out, attn_weights = self.attention(
|
| 256 |
+
hidden_states,
|
| 257 |
+
key_padding_mask,
|
| 258 |
+
output_attentions,
|
| 259 |
+
head_mask,
|
| 260 |
+
)
|
| 261 |
+
return self.output(self.intermediate(attn_out), attn_out), attn_weights
|
| 262 |
+
|
| 263 |
+
|
| 264 |
+
class BertEncoder(nn.Module):
|
| 265 |
+
def __init__(self, config):
|
| 266 |
+
super().__init__()
|
| 267 |
+
self.layer = nn.ModuleList([BertLayer(config) for _ in range(config.num_hidden_layers)])
|
| 268 |
+
self.gradient_checkpointing = False
|
| 269 |
+
|
| 270 |
+
def forward(
|
| 271 |
+
self,
|
| 272 |
+
hidden_states: torch.Tensor,
|
| 273 |
+
key_padding_mask: Optional[torch.Tensor],
|
| 274 |
+
output_hidden_states: bool = False,
|
| 275 |
+
output_attentions: bool = False,
|
| 276 |
+
head_mask: Optional[torch.Tensor] = None,
|
| 277 |
+
) -> Tuple:
|
| 278 |
+
all_hidden_states = (hidden_states,) if output_hidden_states else None
|
| 279 |
+
all_attentions = () if output_attentions else None
|
| 280 |
+
|
| 281 |
+
for layer_index, layer in enumerate(self.layer):
|
| 282 |
+
layer_head_mask = (
|
| 283 |
+
head_mask[layer_index] if head_mask is not None else None
|
| 284 |
+
)
|
| 285 |
+
if self.gradient_checkpointing and self.training:
|
| 286 |
+
hidden_states, attn_weights = torch.utils.checkpoint.checkpoint(
|
| 287 |
+
layer.__call__,
|
| 288 |
+
hidden_states,
|
| 289 |
+
key_padding_mask,
|
| 290 |
+
output_attentions,
|
| 291 |
+
layer_head_mask,
|
| 292 |
+
use_reentrant=False,
|
| 293 |
+
)
|
| 294 |
+
else:
|
| 295 |
+
hidden_states, attn_weights = layer(
|
| 296 |
+
hidden_states,
|
| 297 |
+
key_padding_mask,
|
| 298 |
+
output_attentions,
|
| 299 |
+
layer_head_mask,
|
| 300 |
+
)
|
| 301 |
+
if output_hidden_states:
|
| 302 |
+
all_hidden_states = all_hidden_states + (hidden_states,)
|
| 303 |
+
if output_attentions:
|
| 304 |
+
all_attentions = all_attentions + (attn_weights,)
|
| 305 |
+
|
| 306 |
+
return hidden_states, all_hidden_states, all_attentions
|
| 307 |
+
|
| 308 |
+
|
| 309 |
+
class BertEmbeddings(nn.Module):
|
| 310 |
+
def __init__(self, config):
|
| 311 |
+
super().__init__()
|
| 312 |
+
self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)
|
| 313 |
+
self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)
|
| 314 |
+
self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
|
| 315 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 316 |
+
self.dropout = nn.Dropout(config.hidden_dropout_prob)
|
| 317 |
+
self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)), persistent=False)
|
| 318 |
+
|
| 319 |
+
def forward(
|
| 320 |
+
self,
|
| 321 |
+
input_ids: Optional[torch.LongTensor] = None,
|
| 322 |
+
token_type_ids: Optional[torch.LongTensor] = None,
|
| 323 |
+
position_ids: Optional[torch.LongTensor] = None,
|
| 324 |
+
inputs_embeds: Optional[torch.FloatTensor] = None,
|
| 325 |
+
) -> torch.Tensor:
|
| 326 |
+
if (input_ids is None) == (inputs_embeds is None):
|
| 327 |
+
raise ValueError("Specify exactly one of input_ids or inputs_embeds.")
|
| 328 |
+
B, T = (
|
| 329 |
+
input_ids.shape
|
| 330 |
+
if input_ids is not None
|
| 331 |
+
else inputs_embeds.shape[:2]
|
| 332 |
+
)
|
| 333 |
+
if token_type_ids is None:
|
| 334 |
+
token_type_ids = torch.zeros(
|
| 335 |
+
(B, T),
|
| 336 |
+
dtype=torch.long,
|
| 337 |
+
device=(
|
| 338 |
+
input_ids.device
|
| 339 |
+
if input_ids is not None
|
| 340 |
+
else inputs_embeds.device
|
| 341 |
+
),
|
| 342 |
+
)
|
| 343 |
+
if position_ids is None:
|
| 344 |
+
position_ids = self.position_ids[:, :T]
|
| 345 |
+
x = (
|
| 346 |
+
self.word_embeddings(input_ids)
|
| 347 |
+
if inputs_embeds is None
|
| 348 |
+
else inputs_embeds
|
| 349 |
+
)
|
| 350 |
+
x = x + self.token_type_embeddings(token_type_ids)
|
| 351 |
+
x = x + self.position_embeddings(position_ids)
|
| 352 |
+
return self.dropout(self.LayerNorm(x))
|
| 353 |
+
|
| 354 |
+
|
| 355 |
+
class BertPooler(nn.Module):
|
| 356 |
+
def __init__(self, config):
|
| 357 |
+
super().__init__()
|
| 358 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 359 |
+
self.activation = nn.Tanh()
|
| 360 |
+
|
| 361 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 362 |
+
return self.activation(self.dense(hidden_states[:, 0]))
|
| 363 |
+
|
| 364 |
+
|
| 365 |
+
class BertPredictionHeadTransform(nn.Module):
|
| 366 |
+
def __init__(self, config):
|
| 367 |
+
super().__init__()
|
| 368 |
+
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
|
| 369 |
+
self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
|
| 370 |
+
hidden_act = (
|
| 371 |
+
config.mlm_hidden_act
|
| 372 |
+
if getattr(config, "mlm_hidden_act", None) is not None
|
| 373 |
+
else config.hidden_act
|
| 374 |
+
)
|
| 375 |
+
if hidden_act in (None, "identity", "linear"):
|
| 376 |
+
self.transform_act_fn = lambda value: value
|
| 377 |
+
elif isinstance(hidden_act, str):
|
| 378 |
+
self.transform_act_fn = ACT2FN[hidden_act]
|
| 379 |
+
else:
|
| 380 |
+
self.transform_act_fn = hidden_act
|
| 381 |
+
|
| 382 |
+
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
|
| 383 |
+
return self.LayerNorm(self.transform_act_fn(self.dense(hidden_states)))
|
| 384 |
+
|
| 385 |
+
|
| 386 |
+
class BertModel(PreTrainedModel):
|
| 387 |
+
config_class = BertUpdatedConfig
|
| 388 |
+
base_model_prefix = "bert"
|
| 389 |
+
_supports_sdpa = True
|
| 390 |
+
_supports_flash_attn_2 = True
|
| 391 |
+
supports_gradient_checkpointing = True
|
| 392 |
+
_keys_to_ignore_on_load_missing = [r"pooler\."]
|
| 393 |
+
|
| 394 |
+
def __init__(self, config, add_pooling_layer=True):
|
| 395 |
+
super().__init__(config)
|
| 396 |
+
self.embeddings = BertEmbeddings(config)
|
| 397 |
+
self.encoder = BertEncoder(config)
|
| 398 |
+
self.pooler = BertPooler(config) if add_pooling_layer else None
|
| 399 |
+
self.post_init()
|
| 400 |
+
|
| 401 |
+
def get_input_embeddings(self):
|
| 402 |
+
return self.embeddings.word_embeddings
|
| 403 |
+
|
| 404 |
+
def set_input_embeddings(self, value):
|
| 405 |
+
self.embeddings.word_embeddings = value
|
| 406 |
+
|
| 407 |
+
def forward(
|
| 408 |
+
self,
|
| 409 |
+
input_ids: Optional[torch.LongTensor] = None,
|
| 410 |
+
attention_mask: Optional[torch.Tensor] = None,
|
| 411 |
+
token_type_ids: Optional[torch.LongTensor] = None,
|
| 412 |
+
position_ids: Optional[torch.LongTensor] = None,
|
| 413 |
+
head_mask: Optional[torch.Tensor] = None,
|
| 414 |
+
inputs_embeds: Optional[torch.FloatTensor] = None,
|
| 415 |
+
output_hidden_states: Optional[bool] = None,
|
| 416 |
+
output_attentions: Optional[bool] = None,
|
| 417 |
+
return_dict: Optional[bool] = None,
|
| 418 |
+
) -> Union[Tuple, BaseModelOutputWithPooling]:
|
| 419 |
+
output_hidden_states = output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
| 420 |
+
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
|
| 421 |
+
return_dict = return_dict if return_dict is not None else self.config.use_return_dict
|
| 422 |
+
|
| 423 |
+
if (input_ids is None) == (inputs_embeds is None):
|
| 424 |
+
raise ValueError("Specify exactly one of input_ids or inputs_embeds.")
|
| 425 |
+
input_shape = (
|
| 426 |
+
input_ids.shape
|
| 427 |
+
if input_ids is not None
|
| 428 |
+
else inputs_embeds.shape[:2]
|
| 429 |
+
)
|
| 430 |
+
input_device = (
|
| 431 |
+
input_ids.device
|
| 432 |
+
if input_ids is not None
|
| 433 |
+
else inputs_embeds.device
|
| 434 |
+
)
|
| 435 |
+
if attention_mask is None:
|
| 436 |
+
attention_mask = torch.ones(input_shape, device=input_device)
|
| 437 |
+
key_padding_mask = attention_mask.eq(0)
|
| 438 |
+
if not key_padding_mask.any():
|
| 439 |
+
key_padding_mask = None
|
| 440 |
+
head_mask = self.get_head_mask(
|
| 441 |
+
head_mask,
|
| 442 |
+
self.config.num_hidden_layers,
|
| 443 |
+
)
|
| 444 |
+
if all(mask is None for mask in head_mask):
|
| 445 |
+
head_mask = None
|
| 446 |
+
|
| 447 |
+
x = self.embeddings(
|
| 448 |
+
input_ids=input_ids,
|
| 449 |
+
token_type_ids=token_type_ids,
|
| 450 |
+
position_ids=position_ids,
|
| 451 |
+
inputs_embeds=inputs_embeds,
|
| 452 |
+
)
|
| 453 |
+
last_hidden_state, all_hidden_states, all_attentions = self.encoder(
|
| 454 |
+
x, key_padding_mask,
|
| 455 |
+
output_hidden_states=output_hidden_states,
|
| 456 |
+
output_attentions=output_attentions,
|
| 457 |
+
head_mask=head_mask,
|
| 458 |
+
)
|
| 459 |
+
pooled = self.pooler(last_hidden_state) if self.pooler is not None else None
|
| 460 |
+
|
| 461 |
+
if not return_dict:
|
| 462 |
+
output = (last_hidden_state, pooled)
|
| 463 |
+
if output_hidden_states:
|
| 464 |
+
output += (all_hidden_states,)
|
| 465 |
+
if output_attentions:
|
| 466 |
+
output += (all_attentions,)
|
| 467 |
+
return output
|
| 468 |
+
|
| 469 |
+
return BaseModelOutputWithPooling(
|
| 470 |
+
last_hidden_state=last_hidden_state,
|
| 471 |
+
pooler_output=pooled,
|
| 472 |
+
hidden_states=all_hidden_states,
|
| 473 |
+
attentions=all_attentions,
|
| 474 |
+
)
|
| 475 |
+
|
| 476 |
+
|
| 477 |
+
class BertForMaskedLM(PreTrainedModel):
|
| 478 |
+
config_class = BertUpdatedConfig
|
| 479 |
+
base_model_prefix = "bert"
|
| 480 |
+
_supports_sdpa = True
|
| 481 |
+
_supports_flash_attn_2 = True
|
| 482 |
+
supports_gradient_checkpointing = True
|
| 483 |
+
_keys_to_ignore_on_load_unexpected = [r"bert\.pooler\."]
|
| 484 |
+
|
| 485 |
+
def __init__(self, config):
|
| 486 |
+
super().__init__(config)
|
| 487 |
+
self.bert = BertModel(config, add_pooling_layer=False)
|
| 488 |
+
self.transform = BertPredictionHeadTransform(config)
|
| 489 |
+
self.cls = nn.Linear(config.hidden_size, config.vocab_size)
|
| 490 |
+
self.post_init()
|
| 491 |
+
|
| 492 |
+
def get_input_embeddings(self):
|
| 493 |
+
return self.bert.embeddings.word_embeddings
|
| 494 |
+
|
| 495 |
+
def set_input_embeddings(self, value):
|
| 496 |
+
self.bert.embeddings.word_embeddings = value
|
| 497 |
+
|
| 498 |
+
def get_output_embeddings(self):
|
| 499 |
+
return self.cls
|
| 500 |
+
|
| 501 |
+
def set_output_embeddings(self, value):
|
| 502 |
+
self.cls = value
|
| 503 |
+
|
| 504 |
+
def forward(
|
| 505 |
+
self,
|
| 506 |
+
input_ids: Optional[torch.LongTensor] = None,
|
| 507 |
+
attention_mask: Optional[torch.Tensor] = None,
|
| 508 |
+
token_type_ids: Optional[torch.LongTensor] = None,
|
| 509 |
+
position_ids: Optional[torch.LongTensor] = None,
|
| 510 |
+
head_mask: Optional[torch.Tensor] = None,
|
| 511 |
+
inputs_embeds: Optional[torch.FloatTensor] = None,
|
| 512 |
+
labels: Optional[torch.LongTensor] = None,
|
| 513 |
+
output_hidden_states: Optional[bool] = None,
|
| 514 |
+
output_attentions: Optional[bool] = None,
|
| 515 |
+
return_dict: Optional[bool] = None,
|
| 516 |
+
) -> Union[Tuple, MaskedLMOutput]:
|
| 517 |
+
return_dict = return_dict if return_dict is not None else self.config.use_return_dict
|
| 518 |
+
|
| 519 |
+
outputs = self.bert(
|
| 520 |
+
input_ids=input_ids,
|
| 521 |
+
attention_mask=attention_mask,
|
| 522 |
+
token_type_ids=token_type_ids,
|
| 523 |
+
position_ids=position_ids,
|
| 524 |
+
head_mask=head_mask,
|
| 525 |
+
inputs_embeds=inputs_embeds,
|
| 526 |
+
output_hidden_states=output_hidden_states,
|
| 527 |
+
output_attentions=output_attentions,
|
| 528 |
+
return_dict=True,
|
| 529 |
+
)
|
| 530 |
+
logits = self.cls(self.transform(outputs.last_hidden_state))
|
| 531 |
+
|
| 532 |
+
loss = None
|
| 533 |
+
if labels is not None:
|
| 534 |
+
loss = F.cross_entropy(logits.view(-1, self.config.vocab_size), labels.view(-1), ignore_index=-100)
|
| 535 |
+
|
| 536 |
+
if not return_dict:
|
| 537 |
+
output = (logits,)
|
| 538 |
+
if output_hidden_states:
|
| 539 |
+
output += (outputs.hidden_states,)
|
| 540 |
+
if output_attentions:
|
| 541 |
+
output += (outputs.attentions,)
|
| 542 |
+
return (loss,) + output if loss is not None else output
|
| 543 |
+
|
| 544 |
+
return MaskedLMOutput(
|
| 545 |
+
loss=loss, logits=logits,
|
| 546 |
+
hidden_states=outputs.hidden_states, attentions=outputs.attentions,
|
| 547 |
+
)
|
special_tokens_map.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cls_token": "[CLS]",
|
| 3 |
+
"sep_token": "[SEP]",
|
| 4 |
+
"pad_token": "[PAD]",
|
| 5 |
+
"mask_token": "[MASK]",
|
| 6 |
+
"unk_token": "[UNK]"
|
| 7 |
+
}
|
tokenization_structrfm.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
from transformers import PreTrainedTokenizer
|
| 5 |
+
|
| 6 |
+
_DEFAULT_VOCAB = {
|
| 7 |
+
"[UNK]": 0,
|
| 8 |
+
"[CLS]": 1,
|
| 9 |
+
"[SEP]": 2,
|
| 10 |
+
"[PAD]": 3,
|
| 11 |
+
"[MASK]": 4,
|
| 12 |
+
"A": 5,
|
| 13 |
+
"U": 6,
|
| 14 |
+
"C": 7,
|
| 15 |
+
"G": 8,
|
| 16 |
+
"N": 9,
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class StructRFMTokenizer(PreTrainedTokenizer):
|
| 21 |
+
"""Single-nucleotide tokenizer for structRFM.
|
| 22 |
+
|
| 23 |
+
Matches the upstream preprocessing (`seq.upper().replace("T", "U")`,
|
| 24 |
+
then one token per character) and adds [CLS] ... [SEP] when
|
| 25 |
+
`add_special_tokens=True`. Characters outside the vocabulary
|
| 26 |
+
(including whitespace) map to [UNK], as in the upstream tokenizer.
|
| 27 |
+
"""
|
| 28 |
+
|
| 29 |
+
vocab_files_names = {"vocab_file": "vocab.json"}
|
| 30 |
+
model_input_names = ["input_ids", "attention_mask"]
|
| 31 |
+
|
| 32 |
+
def __init__(
|
| 33 |
+
self,
|
| 34 |
+
vocab_file=None,
|
| 35 |
+
cls_token="[CLS]",
|
| 36 |
+
sep_token="[SEP]",
|
| 37 |
+
pad_token="[PAD]",
|
| 38 |
+
mask_token="[MASK]",
|
| 39 |
+
unk_token="[UNK]",
|
| 40 |
+
**kwargs,
|
| 41 |
+
):
|
| 42 |
+
self._vocab = dict(_DEFAULT_VOCAB)
|
| 43 |
+
if vocab_file and os.path.isfile(vocab_file):
|
| 44 |
+
with open(vocab_file) as f:
|
| 45 |
+
self._vocab = json.load(f)
|
| 46 |
+
self._ids_to_tokens = {v: k for k, v in self._vocab.items()}
|
| 47 |
+
super().__init__(
|
| 48 |
+
cls_token=cls_token,
|
| 49 |
+
sep_token=sep_token,
|
| 50 |
+
pad_token=pad_token,
|
| 51 |
+
mask_token=mask_token,
|
| 52 |
+
unk_token=unk_token,
|
| 53 |
+
**kwargs,
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
@property
|
| 57 |
+
def vocab_size(self):
|
| 58 |
+
return len(self._vocab)
|
| 59 |
+
|
| 60 |
+
def get_vocab(self):
|
| 61 |
+
return dict(self._vocab)
|
| 62 |
+
|
| 63 |
+
def _tokenize(self, text):
|
| 64 |
+
return list(text.upper().replace("T", "U"))
|
| 65 |
+
|
| 66 |
+
def _convert_token_to_id(self, token):
|
| 67 |
+
return self._vocab.get(token, self._vocab["[UNK]"])
|
| 68 |
+
|
| 69 |
+
def _convert_id_to_token(self, index):
|
| 70 |
+
return self._ids_to_tokens.get(index, "[UNK]")
|
| 71 |
+
|
| 72 |
+
def convert_tokens_to_string(self, tokens):
|
| 73 |
+
return "".join(tokens)
|
| 74 |
+
|
| 75 |
+
def save_vocabulary(self, save_directory, filename_prefix=None):
|
| 76 |
+
os.makedirs(save_directory, exist_ok=True)
|
| 77 |
+
fname = (filename_prefix + "-" if filename_prefix else "") + "vocab.json"
|
| 78 |
+
path = os.path.join(save_directory, fname)
|
| 79 |
+
with open(path, "w") as f:
|
| 80 |
+
json.dump(self._vocab, f, indent=2)
|
| 81 |
+
return (path,)
|
| 82 |
+
|
| 83 |
+
def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None):
|
| 84 |
+
cls = [self.cls_token_id]
|
| 85 |
+
sep = [self.sep_token_id]
|
| 86 |
+
if token_ids_1 is None:
|
| 87 |
+
return cls + token_ids_0 + sep
|
| 88 |
+
return cls + token_ids_0 + sep + token_ids_1 + sep
|
| 89 |
+
|
| 90 |
+
def get_special_tokens_mask(self, token_ids_0, token_ids_1=None,
|
| 91 |
+
already_has_special_tokens=False):
|
| 92 |
+
if already_has_special_tokens:
|
| 93 |
+
return super().get_special_tokens_mask(
|
| 94 |
+
token_ids_0, token_ids_1, already_has_special_tokens=True
|
| 95 |
+
)
|
| 96 |
+
mask = [1] + [0] * len(token_ids_0) + [1]
|
| 97 |
+
if token_ids_1 is not None:
|
| 98 |
+
mask += [0] * len(token_ids_1) + [1]
|
| 99 |
+
return mask
|
| 100 |
+
|
| 101 |
+
def create_token_type_ids_from_sequences(self, token_ids_0, token_ids_1=None):
|
| 102 |
+
if token_ids_1 is None:
|
| 103 |
+
return [0] * (len(token_ids_0) + 2)
|
| 104 |
+
return [0] * (len(token_ids_0) + 2) + [1] * (len(token_ids_1) + 1)
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"auto_map": {
|
| 3 |
+
"AutoTokenizer": [
|
| 4 |
+
"tokenization_structrfm.StructRFMTokenizer",
|
| 5 |
+
null
|
| 6 |
+
]
|
| 7 |
+
},
|
| 8 |
+
"tokenizer_class": "StructRFMTokenizer",
|
| 9 |
+
"model_max_length": 514,
|
| 10 |
+
"padding_side": "right",
|
| 11 |
+
"truncation_side": "right",
|
| 12 |
+
"cls_token": "[CLS]",
|
| 13 |
+
"sep_token": "[SEP]",
|
| 14 |
+
"pad_token": "[PAD]",
|
| 15 |
+
"mask_token": "[MASK]",
|
| 16 |
+
"unk_token": "[UNK]"
|
| 17 |
+
}
|
vocab.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"[UNK]": 0,
|
| 3 |
+
"[CLS]": 1,
|
| 4 |
+
"[SEP]": 2,
|
| 5 |
+
"[PAD]": 3,
|
| 6 |
+
"[MASK]": 4,
|
| 7 |
+
"A": 5,
|
| 8 |
+
"U": 6,
|
| 9 |
+
"C": 7,
|
| 10 |
+
"G": 8,
|
| 11 |
+
"N": 9
|
| 12 |
+
}
|