sileod commited on
Commit
ea44dc0
·
verified ·
1 Parent(s): 4bf28ef

UltraBERT-380M-clairic-extraction

Browse files
README.md ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: transformers
3
+ base_model:
4
+ - dmis-lab/UltraBERT-380M
5
+ license: apache-2.0
6
+ language:
7
+ - en
8
+ pipeline_tag: token-classification
9
+ datasets:
10
+ - tasksource/tasksource-jev-typed-decisions
11
+ tags:
12
+ - information-extraction
13
+ - extractive-qa
14
+ - ner
15
+ - span-extraction
16
+ - tasksource
17
+ ---
18
+
19
+ # UltraBERT-380M-clairic-extraction
20
+
21
+ A 380M-parameter extractor for Clairic-style requests: give it a text and a set of fields, each described by a short instruction, and it returns the matching spans for each field (one answer, a list, or nothing when the text has no answer). Fields can be questions ("What is the total due?") or entity types ("Every company mentioned in the text"), so one model covers extractive question answering and named-entity recognition.
22
+
23
+ [UltraBERT-380M](https://huggingface.co/dmis-lab/UltraBERT-380M) trained on the `extraction` config of [tasksource-jev-typed-decisions](https://huggingface.co/datasets/tasksource/tasksource-jev-typed-decisions) (release v2026.10.24.1, 1M instruction/text pairs, 60k steps): extractive QA and span-tagging datasets from [tasksource](https://github.com/sileod/tasksource), rewritten as (instruction, text, spans) pairs. The model tags the answer tokens of the text (B/I/O) conditioned on the instruction. Inputs up to 2048 tokens.
24
+
25
+ It is the larger sibling of [UltraBERT-150M-clairic-extraction](https://huggingface.co/tasksource/UltraBERT-150M-clairic-extraction), with the same interface: more accurate, especially on list fields, and better at leaving a field empty when the text has no answer, for about 2.5x the compute.
26
+
27
+ Not affiliated with Cloudflare; "Clairic-style" refers to the request format.
28
+
29
+ ## Usage
30
+
31
+ ```python
32
+ import torch
33
+ from transformers import AutoModelForTokenClassification, AutoTokenizer
34
+
35
+ name = "tasksource/UltraBERT-380M-clairic-extraction"
36
+ tok = AutoTokenizer.from_pretrained(name)
37
+ model = AutoModelForTokenClassification.from_pretrained(name, trust_remote_code=True).eval()
38
+
39
+ def extract(text, fields):
40
+ """fields: {name: instruction}. Returns {name: [extracted spans]}, [] when the text has no answer."""
41
+ enc = tok(list(fields.values()), [text] * len(fields), truncation="only_second", max_length=2048,
42
+ padding=True, return_offsets_mapping=True, return_tensors="pt")
43
+ offsets = enc.pop("offset_mapping")
44
+ with torch.no_grad():
45
+ tags = model(**enc).logits.argmax(-1).tolist() # 0 = O, 1 = B, 2 = I
46
+ out = {}
47
+ for f, field in enumerate(fields):
48
+ spans, start, seq = [], None, enc.sequence_ids(f) + [None]
49
+ for i, tag in enumerate(tags[f] + [0]):
50
+ if start is not None and (seq[i] != 1 or tag != 2):
51
+ spans.append(text[offsets[f][start][0]:offsets[f][i - 1][1]].strip().rstrip(",;:"))
52
+ start = None
53
+ if seq[i] == 1 and tag in (1, 2) and start is None:
54
+ start = i
55
+ out[field] = spans
56
+ return out
57
+
58
+ text = "Invoice INV-2291 from Acme Corp to Globex, issued 3 March 2025. Total due: $1,240.50. Contact: billing@acme.com."
59
+ print(extract(text, {
60
+ "invoice_number": "The invoice number.",
61
+ "companies": "Every company mentioned in the text, as written.",
62
+ "total": "The total amount due.",
63
+ "phone": "The contact phone number.",
64
+ }))
65
+ # {'invoice_number': ['INV-2291'], 'companies': ['Acme Corp', 'Globex'], 'total': ['$1,240.50'], 'phone': []}
66
+ ```
67
+
68
+ `trust_remote_code=True` is needed for the UltraBERT architecture.
69
+
70
+ ## Evaluation
71
+
72
+ Test split of the extraction config (revision v2026.10.20.7), 100 rows per source, procedurally generated sources excluded. *text* fields (one answer or none) are scored by SQuAD F1, the empty answer counting as an answer. *list* fields (every span of a kind) are scored by micro F1 over normalized values. Scores are means over sources.
73
+
74
+ | Model | Params | QA (F1) | NER / span lists (F1) |
75
+ |---|---|---|---|
76
+ | **UltraBERT-380M-clairic-extraction** | 380M | **0.756** | **0.750** |
77
+ | [UltraBERT-150M-clairic-extraction](https://huggingface.co/tasksource/UltraBERT-150M-clairic-extraction) | 150M | 0.720 | 0.702 |
78
+ | [gliner-multitask-large-v0.5](https://huggingface.co/knowledgator/gliner-multitask-large-v0.5) | 440M | 0.474 | 0.408 |
79
+ | [deberta-v3-base-squad2](https://huggingface.co/deepset/deberta-v3-base-squad2) | 184M | 0.498 | 0.060 |
80
+
81
+ The test sources are the training sources (their test splits), while the baselines see most of them zero-shot, so this measures performance on these tasks rather than on unseen ones.
82
+
83
+ Out of domain (MRQA test sets the model never trained on, plus FinEntity), F1:
84
+
85
+ | Model | BioASQ | RACE | RelationExtraction | TextbookQA | FinEntity | Mean |
86
+ |---|---|---|---|---|---|---|
87
+ | **UltraBERT-380M-clairic-extraction** | 0.626 | 0.412 | 0.870 | 0.482 | 0.717 | 0.622 |
88
+ | [gliner-multitask-large-v0.5](https://huggingface.co/knowledgator/gliner-multitask-large-v0.5) | **0.643** | **0.458** | **0.899** | **0.545** | **0.913** | **0.692** |
89
+
90
+ GLiNER-multitask stays ahead out of domain.
91
+
92
+ ## Training data
93
+
94
+ The extraction config gathers extractive QA (SQuAD 2.0, Natural Questions, HotpotQA, NewsQA, DuoRC, QuAC, CUAD, Qasper, TimeQA, WebSRC, SWDE, and others) and span tagging (CoNLL-2003, OntoNotes, Few-NERD, WNUT, CrossNER, biomedical, legal and financial NER, skills, aspects, keyphrases, and others), plus procedurally generated documents. A few sources (e.g. GUM, PreCo) are licensed for non-commercial use only; check the dataset card for per-source licenses.
95
+
96
+ ## Citation
97
+
98
+ ```bibtex
99
+ @inproceedings{sileo-2024-tasksource,
100
+ title = "tasksource: A Large Collection of {NLP} tasks with a Structured Dataset Preprocessing Framework",
101
+ author = "Sileo, Damien",
102
+ booktitle = "Proceedings of the 2024 Joint International Conference on Computational Linguistics, Language Resources and Evaluation (LREC-COLING 2024)",
103
+ year = "2024",
104
+ address = "Torino, Italia",
105
+ pages = "15655--15684",
106
+ url = "https://aclanthology.org/2024.lrec-main.1361",
107
+ }
108
+ ```
config.json ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "UltrabertForTokenClassification"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "attention_windows": [
8
+ 128,
9
+ 128,
10
+ null,
11
+ 128,
12
+ 128,
13
+ null,
14
+ 128,
15
+ 128,
16
+ null,
17
+ 128,
18
+ 128,
19
+ null,
20
+ 128,
21
+ 128,
22
+ null,
23
+ 128,
24
+ 128,
25
+ null,
26
+ 128,
27
+ 128,
28
+ null,
29
+ 128,
30
+ 128,
31
+ null
32
+ ],
33
+ "auto_map": {
34
+ "AutoConfig": "configuration_ultrabert.UltrabertConfig",
35
+ "AutoModel": "modeling_ultrabert.UltrabertModel",
36
+ "AutoModelForMaskedLM": "modeling_ultrabert.UltrabertForMaskedLM",
37
+ "AutoModelForQuestionAnswering": "modeling_ultrabert.UltrabertForQuestionAnswering",
38
+ "AutoModelForSequenceClassification": "modeling_ultrabert.UltrabertForSequenceClassification",
39
+ "AutoModelForTokenClassification": "modeling_ultrabert.UltrabertForTokenClassification"
40
+ },
41
+ "bos_token_id": 0,
42
+ "classifier_dropout": 0.0,
43
+ "classifiers_size": [
44
+ 3
45
+ ],
46
+ "dtype": "float32",
47
+ "eos_token_id": 0,
48
+ "head_dim": 128,
49
+ "hidden_act": "silu",
50
+ "hidden_size": 1024,
51
+ "id2label": {
52
+ "0": "O",
53
+ "1": "B-answer",
54
+ "2": "I-answer"
55
+ },
56
+ "initializer_range": 0.02,
57
+ "intermediate_size": 3072,
58
+ "label2id": {
59
+ "B-answer": 1,
60
+ "I-answer": 2,
61
+ "O": 0
62
+ },
63
+ "max_position_embeddings": 2048,
64
+ "mlp_bias": false,
65
+ "model_type": "ultrabert",
66
+ "num_attention_heads": 8,
67
+ "num_hidden_layers": 24,
68
+ "num_key_value_heads": 8,
69
+ "pad_token_id": 0,
70
+ "prediction_head_size": 1024,
71
+ "rms_norm_eps": 1e-06,
72
+ "rope_theta": [
73
+ 10000.0,
74
+ 10000.0,
75
+ 2560000.0,
76
+ 10000.0,
77
+ 10000.0,
78
+ 2560000.0,
79
+ 10000.0,
80
+ 10000.0,
81
+ 2560000.0,
82
+ 10000.0,
83
+ 10000.0,
84
+ 2560000.0,
85
+ 10000.0,
86
+ 10000.0,
87
+ 2560000.0,
88
+ 10000.0,
89
+ 10000.0,
90
+ 2560000.0,
91
+ 10000.0,
92
+ 10000.0,
93
+ 2560000.0,
94
+ 10000.0,
95
+ 10000.0,
96
+ 2560000.0
97
+ ],
98
+ "tasks": [
99
+ "jev-extraction"
100
+ ],
101
+ "tie_word_embeddings": false,
102
+ "transformers_version": "5.17.0",
103
+ "vocab_size": 49152
104
+ }
configuration_ultrabert.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterable
4
+
5
+ from transformers.configuration_utils import PretrainedConfig
6
+
7
+
8
+ class UltrabertConfig(PretrainedConfig):
9
+ model_type = "ultrabert"
10
+
11
+ def __init__(
12
+ self,
13
+ vocab_size=32000,
14
+ hidden_size=4096,
15
+ intermediate_size=11008,
16
+ prediction_head_size=None,
17
+ num_hidden_layers=32,
18
+ num_attention_heads=32,
19
+ num_key_value_heads=None,
20
+ attention_windows=None,
21
+ hidden_act="silu",
22
+ initializer_range=0.02,
23
+ rms_norm_eps=1e-6,
24
+ pad_token_id=0,
25
+ bos_token_id=0,
26
+ eos_token_id=0,
27
+ tie_word_embeddings=False,
28
+ rope_theta=10000.0,
29
+ attention_bias=False,
30
+ attention_dropout=0.0,
31
+ mlp_bias=False,
32
+ head_dim=None,
33
+ classifier_dropout=0.0,
34
+ **kwargs,
35
+ ):
36
+ super().__init__(
37
+ pad_token_id=pad_token_id,
38
+ bos_token_id=bos_token_id,
39
+ eos_token_id=eos_token_id,
40
+ tie_word_embeddings=tie_word_embeddings,
41
+ **kwargs,
42
+ )
43
+ self.vocab_size = vocab_size
44
+ self.hidden_size = hidden_size
45
+ self.intermediate_size = intermediate_size
46
+ self.prediction_head_size = prediction_head_size
47
+ self.num_hidden_layers = num_hidden_layers
48
+ self.num_attention_heads = num_attention_heads
49
+ self.num_key_value_heads = num_key_value_heads or num_attention_heads
50
+ self.attention_windows = (
51
+ attention_windows
52
+ if isinstance(attention_windows, Iterable)
53
+ else [attention_windows] * num_hidden_layers
54
+ )
55
+ self.hidden_act = hidden_act
56
+ self.initializer_range = initializer_range
57
+ self.rms_norm_eps = rms_norm_eps
58
+ self.rope_theta = (
59
+ rope_theta
60
+ if isinstance(rope_theta, Iterable)
61
+ else [rope_theta] * num_hidden_layers
62
+ )
63
+ self.attention_bias = attention_bias
64
+ self.attention_dropout = attention_dropout
65
+ self.mlp_bias = mlp_bias
66
+ self.head_dim = head_dim or self.hidden_size // self.num_attention_heads
67
+ self.classifier_dropout = classifier_dropout
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:188edece3e65295207c3137de5af06c4011afbe1f81c7091ca049ce0048b3ce3
3
+ size 1510188284
modeling_ultrabert.py ADDED
@@ -0,0 +1,766 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from examples/modular_ultrabert.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_ultrabert.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ from collections.abc import Callable
8
+
9
+ import torch
10
+ from torch import nn
11
+ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
12
+ from transformers.activations import ACT2FN
13
+ from transformers.modeling_outputs import (
14
+ BaseModelOutput,
15
+ MaskedLMOutput,
16
+ QuestionAnsweringModelOutput,
17
+ SequenceClassifierOutput,
18
+ TokenClassifierOutput,
19
+ )
20
+ from transformers.modeling_utils import PreTrainedModel
21
+ from transformers.processing_utils import Unpack
22
+ from transformers.utils import TransformersKwargs, auto_docstring, can_return_tuple
23
+ from transformers.utils.generic import merge_with_config_defaults
24
+ from transformers.utils.output_capturing import capture_outputs
25
+
26
+ from transformers.cache_utils import Cache
27
+ from transformers.integrations import use_kernel_forward_from_hub, use_kernelized_func
28
+ from transformers.modeling_layers import GradientCheckpointingLayer
29
+ from transformers.modeling_rope_utils import dynamic_rope_update
30
+ from transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS
31
+ from transformers.utils.deprecation import deprecate_kwarg
32
+ from transformers.utils.generic import maybe_autocast
33
+ from .configuration_ultrabert import UltrabertConfig
34
+
35
+
36
+ class RotaryEmbedding(nn.Module):
37
+ @deprecate_kwarg("device", version="5.18")
38
+ def __init__(self, base: float, dim: int, device: torch.device | None = None):
39
+ super().__init__()
40
+ self.rope_type = "default"
41
+ self.attention_scaling = 1
42
+ self.base, self.dim = base, dim
43
+
44
+ inv_freq = torch.arange(0, dim, 2, dtype=torch.int64)
45
+ inv_freq = 1.0 / (base ** (inv_freq.to(device=device, dtype=torch.float) / dim))
46
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
47
+
48
+ @staticmethod
49
+ @deprecate_kwarg("device", version="5.18")
50
+ def compute_default_rope_parameters(
51
+ config: UltrabertConfig, device=None, **kwargs
52
+ ) -> tuple[torch.Tensor, float]:
53
+ """
54
+ Computes the inverse frequencies according to the original RoPE implementation
55
+ Args:
56
+ config ([`~transformers.PreTrainedConfig`]):
57
+ The model configuration.
58
+ Returns:
59
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
60
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
61
+ """
62
+ base = config.rope_parameters["rope_theta"]
63
+ dim = (
64
+ getattr(config, "head_dim", None)
65
+ or config.hidden_size // config.num_attention_heads
66
+ )
67
+
68
+ attention_factor = 1.0 # Unused in this type of RoPE
69
+ # Compute the inverse frequencies
70
+ inv_freq = 1.0 / (base ** (torch.arange(0, dim, 2, dtype=torch.float) / dim))
71
+ return inv_freq.to(device), attention_factor
72
+
73
+ @torch.no_grad()
74
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
75
+ def forward(self, x, position_ids):
76
+ inv_freq_expanded = (
77
+ self.inv_freq[None, :, None]
78
+ .expand(position_ids.shape[0], -1, 1)
79
+ .to(dtype=torch.float, device=x.device)
80
+ )
81
+ position_ids_expanded = position_ids[:, None, :].float()
82
+
83
+ device_type = (
84
+ x.device.type
85
+ if isinstance(x.device.type, str) and x.device.type != "mps"
86
+ else "cpu"
87
+ )
88
+ # Disable any outside autocast context if any, to really force fp32
89
+ with maybe_autocast(device_type=device_type, enabled=False):
90
+ freqs = (inv_freq_expanded @ position_ids_expanded).transpose(1, 2)
91
+ emb = torch.cat((freqs, freqs), dim=-1)
92
+ cos = emb.cos() * self.attention_scaling
93
+ sin = emb.sin() * self.attention_scaling
94
+
95
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
96
+
97
+
98
+ def rotate_half(x):
99
+ """Rotates half the hidden dims of the input."""
100
+ x1 = x[..., : x.shape[-1] // 2]
101
+ x2 = x[..., x.shape[-1] // 2 :]
102
+ return torch.cat((-x2, x1), dim=-1)
103
+
104
+
105
+ @use_kernel_forward_from_hub("rotary_pos_emb")
106
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
107
+ """Applies Rotary Position Embedding to the query and key tensors.
108
+
109
+ Args:
110
+ q (`torch.Tensor`): The query tensor.
111
+ k (`torch.Tensor`): The key tensor.
112
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
113
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
114
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
115
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
116
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
117
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
118
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
119
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
120
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
121
+ Returns:
122
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
123
+ """
124
+ cos = cos.unsqueeze(unsqueeze_dim)
125
+ sin = sin.unsqueeze(unsqueeze_dim)
126
+ q_embed = (q * cos) + (rotate_half(q) * sin)
127
+ k_embed = (k * cos) + (rotate_half(k) * sin)
128
+ return q_embed, k_embed
129
+
130
+
131
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
132
+ """
133
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
134
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
135
+ """
136
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
137
+ if n_rep == 1:
138
+ return hidden_states
139
+ hidden_states = hidden_states[:, :, None, :, :].expand(
140
+ batch, num_key_value_heads, n_rep, slen, head_dim
141
+ )
142
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
143
+
144
+
145
+ def eager_attention_forward(
146
+ module: nn.Module,
147
+ query: torch.Tensor,
148
+ key: torch.Tensor,
149
+ value: torch.Tensor,
150
+ attention_mask: torch.Tensor | None,
151
+ scaling: float,
152
+ dropout: float = 0.0,
153
+ **kwargs: Unpack[TransformersKwargs],
154
+ ):
155
+ key_states = repeat_kv(key, module.num_key_value_groups)
156
+ value_states = repeat_kv(value, module.num_key_value_groups)
157
+
158
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
159
+ if attention_mask is not None:
160
+ attn_weights = attn_weights + attention_mask
161
+
162
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(
163
+ query.dtype
164
+ )
165
+ attn_weights = nn.functional.dropout(
166
+ attn_weights, p=dropout, training=module.training
167
+ )
168
+ attn_output = torch.matmul(attn_weights, value_states)
169
+ attn_output = attn_output.transpose(1, 2).contiguous()
170
+
171
+ return attn_output, attn_weights
172
+
173
+
174
+ @use_kernelized_func(apply_rotary_pos_emb)
175
+ class UltrabertAttention(nn.Module):
176
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
177
+
178
+ def __init__(self, config: UltrabertConfig, layer_idx: int):
179
+ super().__init__()
180
+ self.config = config
181
+ self.layer_idx = layer_idx
182
+ self.head_dim = getattr(
183
+ config, "head_dim", config.hidden_size // config.num_attention_heads
184
+ )
185
+ self.num_key_value_groups = (
186
+ config.num_attention_heads // config.num_key_value_heads
187
+ )
188
+ self.scaling = self.head_dim**-0.5
189
+ self.attention_dropout = config.attention_dropout
190
+ self.is_causal = False
191
+
192
+ self.q_proj = nn.Linear(
193
+ config.hidden_size,
194
+ config.num_attention_heads * self.head_dim,
195
+ bias=config.attention_bias,
196
+ )
197
+ self.k_proj = nn.Linear(
198
+ config.hidden_size,
199
+ config.num_key_value_heads * self.head_dim,
200
+ bias=config.attention_bias,
201
+ )
202
+ self.v_proj = nn.Linear(
203
+ config.hidden_size,
204
+ config.num_key_value_heads * self.head_dim,
205
+ bias=config.attention_bias,
206
+ )
207
+ self.o_proj = nn.Linear(
208
+ config.num_attention_heads * self.head_dim,
209
+ config.hidden_size,
210
+ bias=config.attention_bias,
211
+ )
212
+
213
+ def forward(
214
+ self,
215
+ hidden_states: torch.Tensor,
216
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
217
+ attention_mask: torch.Tensor | None = None,
218
+ past_key_values: Cache | None = None,
219
+ **kwargs: Unpack[TransformersKwargs],
220
+ ) -> tuple[torch.Tensor, torch.Tensor]:
221
+ input_shape = hidden_states.shape[:-1]
222
+ hidden_shape = (*input_shape, -1, self.head_dim)
223
+
224
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
225
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
226
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
227
+
228
+ cos, sin = position_embeddings
229
+ query_states, key_states = apply_rotary_pos_emb(
230
+ query_states, key_states, cos, sin
231
+ )
232
+
233
+ if past_key_values is not None:
234
+ key_states, value_states = past_key_values.update(
235
+ key_states, value_states, self.layer_idx
236
+ )
237
+
238
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
239
+ self.config._attn_implementation, eager_attention_forward
240
+ )
241
+
242
+ attn_output, attn_weights = attention_interface(
243
+ self,
244
+ query_states,
245
+ key_states,
246
+ value_states,
247
+ attention_mask,
248
+ dropout=0.0 if not self.training else self.attention_dropout,
249
+ scaling=self.scaling,
250
+ **kwargs,
251
+ )
252
+
253
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
254
+ attn_output = self.o_proj(attn_output)
255
+ return attn_output, attn_weights
256
+
257
+
258
+ @use_kernel_forward_from_hub("RMSNorm")
259
+ class UltrabertRMSNorm(nn.Module):
260
+ def __init__(self, hidden_size, eps: float = 1e-6) -> None:
261
+ """
262
+ UltrabertRMSNorm is equivalent to T5LayerNorm
263
+ """
264
+ super().__init__()
265
+ self.weight = nn.Parameter(torch.ones(hidden_size))
266
+ self.variance_epsilon = eps
267
+
268
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
269
+ input_dtype = hidden_states.dtype
270
+ hidden_states = hidden_states.to(torch.float32)
271
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
272
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
273
+ return self.weight * hidden_states.to(input_dtype)
274
+
275
+ def extra_repr(self):
276
+ return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"
277
+
278
+
279
+ class UltrabertMLP(nn.Module):
280
+ def __init__(self, config):
281
+ super().__init__()
282
+ self.config = config
283
+ self.hidden_size = config.hidden_size
284
+ self.intermediate_size = config.intermediate_size
285
+ self.gate_proj = nn.Linear(
286
+ self.hidden_size, self.intermediate_size, bias=config.mlp_bias
287
+ )
288
+ self.up_proj = nn.Linear(
289
+ self.hidden_size, self.intermediate_size, bias=config.mlp_bias
290
+ )
291
+ self.down_proj = nn.Linear(
292
+ self.intermediate_size, self.hidden_size, bias=config.mlp_bias
293
+ )
294
+ self.act_fn = ACT2FN[config.hidden_act]
295
+
296
+ def forward(self, x):
297
+ down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
298
+ return down_proj
299
+
300
+
301
+ class UltrabertLayer(GradientCheckpointingLayer):
302
+ def __init__(self, config: UltrabertConfig, layer_idx: int):
303
+ super().__init__()
304
+ self.hidden_size = config.hidden_size
305
+
306
+ self.self_attn = UltrabertAttention(config=config, layer_idx=layer_idx)
307
+
308
+ self.mlp = UltrabertMLP(config)
309
+ self.input_layernorm = UltrabertRMSNorm(
310
+ config.hidden_size, eps=config.rms_norm_eps
311
+ )
312
+ self.post_attention_layernorm = UltrabertRMSNorm(
313
+ config.hidden_size, eps=config.rms_norm_eps
314
+ )
315
+
316
+ def forward(
317
+ self,
318
+ hidden_states: torch.Tensor,
319
+ attention_mask: torch.Tensor | None = None,
320
+ position_ids: torch.LongTensor | None = None,
321
+ past_key_values: Cache | None = None,
322
+ use_cache: bool | None = False,
323
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
324
+ **kwargs: Unpack[TransformersKwargs],
325
+ ) -> torch.Tensor:
326
+ residual = hidden_states
327
+ hidden_states = self.input_layernorm(hidden_states)
328
+ # Self Attention
329
+ hidden_states, _ = self.self_attn(
330
+ hidden_states=hidden_states,
331
+ attention_mask=attention_mask,
332
+ position_ids=position_ids,
333
+ past_key_values=past_key_values,
334
+ use_cache=use_cache,
335
+ position_embeddings=position_embeddings,
336
+ **kwargs,
337
+ )
338
+ hidden_states = residual + hidden_states
339
+
340
+ # Fully Connected
341
+ residual = hidden_states
342
+ hidden_states = self.post_attention_layernorm(hidden_states)
343
+ hidden_states = self.mlp(hidden_states)
344
+ hidden_states = residual + hidden_states
345
+ return hidden_states
346
+
347
+
348
+ @auto_docstring
349
+ class UltrabertPreTrainedModel(PreTrainedModel):
350
+ config: UltrabertConfig
351
+ base_model_prefix = "ultrabert"
352
+ supports_gradient_checkpointing = True
353
+ _no_split_modules = ["UltrabertLayer"]
354
+ _skip_keys_device_placement = ["past_key_values"]
355
+ _supports_flash_attn = True
356
+ _supports_sdpa = True
357
+ _supports_flex_attn = True
358
+
359
+ _can_compile_fullgraph = True
360
+ _supports_attention_backend = True
361
+ _can_record_outputs = {
362
+ "hidden_states": UltrabertLayer,
363
+ "attentions": UltrabertAttention,
364
+ }
365
+ config_class = UltrabertConfig
366
+
367
+ def _init_weights(self, module):
368
+ super()._init_weights(module)
369
+ if isinstance(module, RotaryEmbedding):
370
+ inv_freq = torch.arange(0, module.dim, 2, dtype=torch.int64)
371
+ inv_freq = 1.0 / (
372
+ module.base
373
+ ** (
374
+ inv_freq.to(device=module.inv_freq.device, dtype=torch.float)
375
+ / module.dim
376
+ )
377
+ )
378
+ module.inv_freq.copy_(inv_freq)
379
+
380
+
381
+ def create_local_attention_mask(
382
+ seq_len: int,
383
+ sliding_window: int | None = None,
384
+ device: torch.device | None = None,
385
+ ) -> torch.Tensor:
386
+ attention_mask = torch.ones(1, seq_len, seq_len, dtype=torch.bool, device=device)
387
+ if sliding_window:
388
+ attention_mask = attention_mask.tril(sliding_window).triu(-sliding_window)
389
+ return attention_mask
390
+
391
+
392
+ @auto_docstring
393
+ class UltrabertModel(UltrabertPreTrainedModel):
394
+ def __init__(self, config: UltrabertConfig):
395
+ super().__init__(config)
396
+ self.padding_idx = config.pad_token_id
397
+ self.vocab_size = config.vocab_size
398
+
399
+ self.embed_tokens = nn.Embedding(
400
+ config.vocab_size, config.hidden_size, self.padding_idx
401
+ )
402
+
403
+ self.layers = nn.ModuleList(
404
+ [UltrabertLayer(config, i) for i in range(config.num_hidden_layers)]
405
+ )
406
+ self.norm = UltrabertRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
407
+ self.rotary_emb = nn.ModuleDict()
408
+ self.gradient_checkpointing = False
409
+ for base in set(config.rope_theta):
410
+ name = str(base).replace(".", "_")
411
+ self.rotary_emb[name] = RotaryEmbedding(base, config.head_dim)
412
+
413
+ # Initialize weights and apply final processing
414
+ self.post_init()
415
+
416
+ @merge_with_config_defaults
417
+ @capture_outputs
418
+ @auto_docstring
419
+ def forward(
420
+ self,
421
+ input_ids: torch.Tensor | None = None,
422
+ attention_mask: torch.Tensor | None = None,
423
+ position_ids: torch.Tensor | None = None,
424
+ inputs_embeds: torch.Tensor | None = None,
425
+ **kwargs: Unpack[TransformersKwargs],
426
+ ) -> BaseModelOutput:
427
+ if (input_ids is None) ^ (inputs_embeds is not None):
428
+ raise ValueError("must specify exactly one of input_ids or inputs_embeds")
429
+ if inputs_embeds is None:
430
+ inputs_embeds = self.embed_tokens(input_ids)
431
+ if position_ids is None:
432
+ position_ids = torch.arange(inputs_embeds.size(1))
433
+ position_ids = position_ids.to(inputs_embeds.device).unsqueeze(0)
434
+ if (
435
+ attention_mask is None
436
+ and self.config._attn_implementation != "flash_attention_2"
437
+ ):
438
+ attention_mask = inputs_embeds.new_ones(inputs_embeds.shape[:2])
439
+ varlen_kwargs = {
440
+ k: kwargs[k]
441
+ for k in ("cu_seq_lens_q", "cu_seq_lens_k", "max_length_q", "max_length_k")
442
+ if kwargs.get(k) is not None
443
+ }
444
+
445
+ # Create attention masks for different local window sizes and store by window.
446
+ attention_mask_dict = {}
447
+ for local_window in list(set(self.config.attention_windows)) + [None]:
448
+ if self.config._attn_implementation == "flash_attention_2":
449
+ # For FlashAttention 2, rely on the `sliding_window` keyword instead of
450
+ # constructing masks manually.
451
+ attention_mask_dict[local_window] = attention_mask
452
+ else:
453
+ window_mask = create_local_attention_mask(
454
+ seq_len=attention_mask.size(1),
455
+ sliding_window=local_window,
456
+ device=attention_mask.device,
457
+ )
458
+ window_mask = window_mask & attention_mask.bool().unsqueeze(1)
459
+ attention_mask_dict[local_window] = (
460
+ torch.where(window_mask, 0.0, torch.finfo(inputs_embeds.dtype).min)
461
+ .to(inputs_embeds.dtype)
462
+ .unsqueeze(1)
463
+ )
464
+
465
+ # Create position embeddings to be shared across the decoder layers.
466
+ hidden_states, position_embeddings = inputs_embeds, {}
467
+ for base in set(self.config.rope_theta):
468
+ rotary_emb = self.rotary_emb[str(base).replace(".", "_")]
469
+ position_embeddings[base] = rotary_emb(hidden_states, position_ids)
470
+
471
+ for i, decoder_layer in enumerate(self.layers[: self.config.num_hidden_layers]):
472
+ local_window = self.config.attention_windows[i]
473
+ hidden_states = decoder_layer(
474
+ hidden_states,
475
+ attention_mask=attention_mask_dict[local_window],
476
+ position_ids=position_ids,
477
+ position_embeddings=position_embeddings[self.config.rope_theta[i]],
478
+ sliding_window=(
479
+ local_window + 1
480
+ if local_window is not None
481
+ and self.config._attn_implementation == "flash_attention_2"
482
+ else local_window
483
+ ),
484
+ **varlen_kwargs,
485
+ )
486
+ hidden_states = self.norm(hidden_states)
487
+ return BaseModelOutput(last_hidden_state=hidden_states)
488
+
489
+
490
+ class UltrabertPredictionHead(nn.Module):
491
+ def __init__(self, config: UltrabertConfig):
492
+ super().__init__()
493
+ if (dim := config.prediction_head_size) is not None:
494
+ self.linear1 = nn.Linear(config.hidden_size, dim, bias=False)
495
+ self.linear2 = nn.Linear(dim, config.hidden_size, bias=False)
496
+ self.act_fn = ACT2FN["gelu_pytorch_tanh"]
497
+
498
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
499
+ if hasattr(self, "linear1"):
500
+ return self.act_fn(self.linear2(self.act_fn(self.linear1(x))))
501
+ return x
502
+
503
+
504
+ @auto_docstring
505
+ class UltrabertForMaskedLM(UltrabertPreTrainedModel):
506
+ _tied_weights_keys = {"cls.weight": "ultrabert.embed_tokens.weight"}
507
+
508
+ def __init__(self, config: UltrabertConfig):
509
+ super().__init__(config)
510
+ self.ultrabert = UltrabertModel(config)
511
+ self.head = UltrabertPredictionHead(config)
512
+ self.cls = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
513
+
514
+ # Initialize weights and apply final processing
515
+ self.post_init()
516
+
517
+ def get_output_embeddings(self):
518
+ return self.cls
519
+
520
+ def set_output_embeddings(self, new_embeddings):
521
+ self.cls = new_embeddings
522
+
523
+ @can_return_tuple
524
+ @auto_docstring
525
+ def forward(
526
+ self,
527
+ input_ids: torch.Tensor | None = None,
528
+ attention_mask: torch.Tensor | None = None,
529
+ token_type_ids: torch.Tensor | None = None,
530
+ position_ids: torch.Tensor | None = None,
531
+ inputs_embeds: torch.Tensor | None = None,
532
+ labels: torch.Tensor | None = None,
533
+ **kwargs: Unpack[TransformersKwargs],
534
+ ) -> tuple[torch.Tensor] | MaskedLMOutput:
535
+ r"""
536
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
537
+ Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
538
+ config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
539
+ loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
540
+ """
541
+ outputs = self.ultrabert(
542
+ input_ids,
543
+ attention_mask=attention_mask,
544
+ position_ids=position_ids,
545
+ inputs_embeds=inputs_embeds,
546
+ **kwargs,
547
+ )
548
+ prediction_scores = self.cls(self.head(outputs[0]))
549
+
550
+ masked_lm_loss = None
551
+ if labels is not None:
552
+ loss_fct = CrossEntropyLoss() # -100 index = padding token
553
+ masked_lm_loss = loss_fct(
554
+ prediction_scores.view(-1, self.config.vocab_size), labels.view(-1)
555
+ )
556
+
557
+ return MaskedLMOutput(
558
+ loss=masked_lm_loss,
559
+ logits=prediction_scores,
560
+ hidden_states=outputs.hidden_states,
561
+ attentions=outputs.attentions,
562
+ )
563
+
564
+
565
+ @auto_docstring(
566
+ custom_intro="""
567
+ Ultrabert Model transformer with a sequence classification/regression head on top (a linear layer on top of the pooled
568
+ output) e.g. for GLUE tasks.
569
+ """
570
+ )
571
+ class UltrabertForSequenceClassification(UltrabertPreTrainedModel):
572
+ def __init__(self, config: UltrabertConfig):
573
+ super().__init__(config)
574
+ self.num_labels = config.num_labels
575
+ self.config = config
576
+ self.ultrabert = UltrabertModel(config)
577
+ classifier_dropout = (
578
+ config.classifier_dropout
579
+ if config.classifier_dropout is not None
580
+ else config.hidden_dropout_prob
581
+ )
582
+ self.dropout = nn.Dropout(config.classifier_dropout)
583
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels)
584
+
585
+ # Initialize weights and apply final processing
586
+ self.post_init()
587
+
588
+ @can_return_tuple
589
+ @auto_docstring
590
+ def forward(
591
+ self,
592
+ input_ids: torch.Tensor | None = None,
593
+ attention_mask: torch.Tensor | None = None,
594
+ token_type_ids: torch.Tensor | None = None,
595
+ position_ids: torch.Tensor | None = None,
596
+ inputs_embeds: torch.Tensor | None = None,
597
+ labels: torch.Tensor | None = None,
598
+ **kwargs: Unpack[TransformersKwargs],
599
+ ) -> tuple[torch.Tensor] | SequenceClassifierOutput:
600
+ r"""
601
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
602
+ Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
603
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
604
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
605
+ """
606
+ outputs = self.ultrabert(
607
+ input_ids,
608
+ attention_mask=attention_mask,
609
+ position_ids=position_ids,
610
+ inputs_embeds=inputs_embeds,
611
+ **kwargs,
612
+ )
613
+ logits = self.classifier(self.dropout(outputs[0][:, 0]))
614
+
615
+ loss = None
616
+ if labels is not None:
617
+ if self.config.problem_type is None:
618
+ if self.num_labels == 1:
619
+ self.config.problem_type = "regression"
620
+ elif self.num_labels > 1 and (
621
+ labels.dtype == torch.long or labels.dtype == torch.int
622
+ ):
623
+ self.config.problem_type = "single_label_classification"
624
+ else:
625
+ self.config.problem_type = "multi_label_classification"
626
+
627
+ if self.config.problem_type == "regression":
628
+ loss_fct = MSELoss()
629
+ if self.num_labels == 1:
630
+ loss = loss_fct(logits.squeeze(), labels.squeeze())
631
+ else:
632
+ loss = loss_fct(logits, labels)
633
+ elif self.config.problem_type == "single_label_classification":
634
+ loss_fct = CrossEntropyLoss()
635
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
636
+ elif self.config.problem_type == "multi_label_classification":
637
+ loss_fct = BCEWithLogitsLoss()
638
+ loss = loss_fct(logits, labels)
639
+
640
+ return SequenceClassifierOutput(
641
+ loss=loss,
642
+ logits=logits,
643
+ hidden_states=outputs.hidden_states,
644
+ attentions=outputs.attentions,
645
+ )
646
+
647
+
648
+ @auto_docstring
649
+ class UltrabertForQuestionAnswering(UltrabertPreTrainedModel):
650
+ def __init__(self, config: UltrabertConfig):
651
+ super().__init__(config)
652
+ self.num_labels = config.num_labels
653
+
654
+ self.ultrabert = UltrabertModel(config)
655
+ self.qa_outputs = nn.Linear(config.hidden_size, config.num_labels)
656
+
657
+ # Initialize weights and apply final processing
658
+ self.post_init()
659
+
660
+ @can_return_tuple
661
+ @auto_docstring
662
+ def forward(
663
+ self,
664
+ input_ids: torch.Tensor | None = None,
665
+ attention_mask: torch.Tensor | None = None,
666
+ token_type_ids: torch.Tensor | None = None,
667
+ position_ids: torch.Tensor | None = None,
668
+ inputs_embeds: torch.Tensor | None = None,
669
+ start_positions: torch.Tensor | None = None,
670
+ end_positions: torch.Tensor | None = None,
671
+ **kwargs: Unpack[TransformersKwargs],
672
+ ) -> tuple[torch.Tensor] | QuestionAnsweringModelOutput:
673
+ outputs = self.ultrabert(
674
+ input_ids,
675
+ attention_mask=attention_mask,
676
+ position_ids=position_ids,
677
+ inputs_embeds=inputs_embeds,
678
+ **kwargs,
679
+ )
680
+ logits = self.qa_outputs(outputs[0])
681
+ start_logits, end_logits = logits.split(1, dim=-1)
682
+ start_logits = start_logits.squeeze(-1).contiguous()
683
+ end_logits = end_logits.squeeze(-1).contiguous()
684
+
685
+ total_loss = None
686
+ if start_positions is not None and end_positions is not None:
687
+ if len(start_positions.size()) > 1:
688
+ start_positions = start_positions.squeeze(-1)
689
+ if len(end_positions.size()) > 1:
690
+ end_positions = end_positions.squeeze(-1)
691
+
692
+ ignored_index = start_logits.size(1)
693
+ start_positions = start_positions.clamp(0, ignored_index)
694
+ end_positions = end_positions.clamp(0, ignored_index)
695
+
696
+ loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
697
+ start_loss = loss_fct(start_logits, start_positions)
698
+ end_loss = loss_fct(end_logits, end_positions)
699
+ total_loss = (start_loss + end_loss) / 2
700
+
701
+ return QuestionAnsweringModelOutput(
702
+ loss=total_loss,
703
+ start_logits=start_logits,
704
+ end_logits=end_logits,
705
+ hidden_states=outputs.hidden_states,
706
+ attentions=outputs.attentions,
707
+ )
708
+
709
+
710
+ @auto_docstring
711
+ class UltrabertForTokenClassification(UltrabertPreTrainedModel):
712
+ def __init__(self, config: UltrabertConfig):
713
+ super().__init__(config)
714
+ self.num_labels = config.num_labels
715
+ self.ultrabert = UltrabertModel(config)
716
+ classifier_dropout = (
717
+ config.classifier_dropout
718
+ if config.classifier_dropout is not None
719
+ else config.hidden_dropout_prob
720
+ )
721
+ self.dropout = nn.Dropout(config.classifier_dropout)
722
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels)
723
+
724
+ # Initialize weights and apply final processing
725
+ self.post_init()
726
+
727
+ @can_return_tuple
728
+ @auto_docstring
729
+ def forward(
730
+ self,
731
+ input_ids: torch.Tensor | None = None,
732
+ attention_mask: torch.Tensor | None = None,
733
+ token_type_ids: torch.Tensor | None = None,
734
+ position_ids: torch.Tensor | None = None,
735
+ inputs_embeds: torch.Tensor | None = None,
736
+ labels: torch.Tensor | None = None,
737
+ **kwargs: Unpack[TransformersKwargs],
738
+ ) -> tuple[torch.Tensor] | TokenClassifierOutput:
739
+ r"""
740
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
741
+ Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
742
+ """
743
+ outputs = self.ultrabert(
744
+ input_ids,
745
+ attention_mask=attention_mask,
746
+ position_ids=position_ids,
747
+ inputs_embeds=inputs_embeds,
748
+ **kwargs,
749
+ )
750
+
751
+ sequence_output = outputs[0]
752
+
753
+ sequence_output = self.dropout(sequence_output)
754
+ logits = self.classifier(sequence_output)
755
+
756
+ loss = None
757
+ if labels is not None:
758
+ loss_fct = CrossEntropyLoss()
759
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
760
+
761
+ return TokenClassifierOutput(
762
+ loss=loss,
763
+ logits=logits,
764
+ hidden_states=outputs.hidden_states,
765
+ attentions=outputs.attentions,
766
+ )
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "backend": "tokenizers",
4
+ "bos_token": "<|endoftext|>",
5
+ "clean_up_tokenization_spaces": false,
6
+ "eos_token": "<|endoftext|>",
7
+ "errors": "replace",
8
+ "extra_special_tokens": [
9
+ "<|endoftext|>",
10
+ "<|im_start|>",
11
+ "<|im_end|>",
12
+ "<repo_name>",
13
+ "<reponame>",
14
+ "<file_sep>",
15
+ "<filename>",
16
+ "<gh_stars>",
17
+ "<issue_start>",
18
+ "<issue_comment>",
19
+ "<issue_closed>",
20
+ "<jupyter_start>",
21
+ "<jupyter_text>",
22
+ "<jupyter_code>",
23
+ "<jupyter_output>",
24
+ "<|sep|>",
25
+ "<|mask|>"
26
+ ],
27
+ "is_local": false,
28
+ "local_files_only": false,
29
+ "mask_token": "<|mask|>",
30
+ "model_max_length": 32768,
31
+ "pad_token": "<|endoftext|>",
32
+ "sep_token": "<|sep|>",
33
+ "tokenizer_class": "GPT2Tokenizer",
34
+ "unk_token": "<|endoftext|>",
35
+ "vocab_size": 49152
36
+ }