Instructions to use davebulaval/MeaningBERT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use davebulaval/MeaningBERT with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="davebulaval/MeaningBERT")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForSequenceClassification tokenizer = AutoTokenizer.from_pretrained("davebulaval/MeaningBERT") model = AutoModelForSequenceClassification.from_pretrained("davebulaval/MeaningBERT", device_map="auto") - Inference
- Notebooks
- Google Colab
- Kaggle
align the card with the repository: symmetry check, and examples that load the v2 checkpoint
Browse files
README.md
CHANGED
|
@@ -104,17 +104,44 @@ irrelevant sentence mainly composed of irrelevant words (also known as word soup
|
|
| 104 |
Again, to account for computer floating-point inaccuracy, we round the ratings to the nearest integer and do not use
|
| 105 |
a threshold value of 0%.
|
| 106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
## Use MeaningBERT
|
| 108 |
|
| 109 |
You can use MeaningBERT as a [model](https://huggingface.co/davebulaval/MeaningBERT) that you can retrain or use for
|
| 110 |
inference using the following with HuggingFace
|
| 111 |
|
| 112 |
```python
|
| 113 |
-
# Load model directly
|
| 114 |
from transformers import AutoTokenizer, AutoModelForSequenceClassification
|
| 115 |
|
| 116 |
-
tokenizer = AutoTokenizer.from_pretrained("davebulaval/MeaningBERT")
|
| 117 |
-
model = AutoModelForSequenceClassification.from_pretrained("davebulaval/MeaningBERT")
|
| 118 |
```
|
| 119 |
|
| 120 |
or you can use MeaningBERT as a metric for evaluation (no retrain) using the following with HuggingFace
|
|
@@ -124,8 +151,8 @@ import torch
|
|
| 124 |
|
| 125 |
from transformers import AutoTokenizer, AutoModelForSequenceClassification
|
| 126 |
|
| 127 |
-
tokenizer = AutoTokenizer.from_pretrained("davebulaval/MeaningBERT")
|
| 128 |
-
scorer = AutoModelForSequenceClassification.from_pretrained("davebulaval/MeaningBERT")
|
| 129 |
scorer.eval()
|
| 130 |
|
| 131 |
documents = ["He wanted to make them pay.", "This sandwich looks delicious.", "He wants to eat."]
|
|
@@ -139,9 +166,23 @@ with torch.no_grad():
|
|
| 139 |
# We process the text
|
| 140 |
scores = scorer(**tokenize_text)
|
| 141 |
|
| 142 |
-
|
|
|
|
|
|
|
| 143 |
```
|
| 144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
or using our HuggingFace Metric module
|
| 146 |
|
| 147 |
```python
|
|
@@ -151,11 +192,47 @@ documents = ["He wanted to make them pay.", "This sandwich looks delicious.", "H
|
|
| 151 |
simplifications = ["He wanted to make them pay.", "This sandwich looks delicious.",
|
| 152 |
"Whatever, whenever, this is a sentence."]
|
| 153 |
|
|
|
|
|
|
|
| 154 |
meaning_bert = evaluate.load("davebulaval/meaningbert")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
|
| 156 |
print(meaning_bert.compute(references=documents, predictions=simplifications))
|
| 157 |
```
|
| 158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
|
| 160 |
------------------
|
| 161 |
|
|
|
|
| 104 |
Again, to account for computer floating-point inaccuracy, we round the ratings to the nearest integer and do not use
|
| 105 |
a threshold value of 0%.
|
| 106 |
|
| 107 |
+
### Symmetry
|
| 108 |
+
|
| 109 |
+
Our third test evaluates a property of the metric rather than of a sentence pair. `meaning(A, B)` and `meaning(B, A)`
|
| 110 |
+
ask the same question, how much of the meaning is shared, and the position of a sentence in the call carries no semantic
|
| 111 |
+
information. The two calls should therefore return the same number. Unlike the two tests above, this one needs no
|
| 112 |
+
generated data at all: it re-scores the evaluation pairs in the reverse order and measures the absolute difference,
|
| 113 |
+
which has an expected value of exactly 0.
|
| 114 |
+
|
| 115 |
+
A metric can pass the first two tests and fail this one. It is worth measuring because the failure is silent: two
|
| 116 |
+
studies using the same metric, one calling `meaning(source, simplification)` and the other `meaning(simplification,
|
| 117 |
+
source)`, would report different numbers with nothing signalling the discrepancy.
|
| 118 |
+
|
| 119 |
+
Measured on 1652 test pairs, mean absolute difference between the two orders:
|
| 120 |
+
|
| 121 |
+
| model | mean | median | pairs differing by more than 10 points |
|
| 122 |
+
|---|---|---|---|
|
| 123 |
+
| MeaningBERT v1, as published | 6.12 | 3.12 | **20.8 %** |
|
| 124 |
+
| v2 trained without mirrored pairs | 7.79 | 4.88 | 31.1 % |
|
| 125 |
+
| **v2 as released** | **1.48** | **0.74** | **0.6 %** |
|
| 126 |
+
|
| 127 |
+
The property is taught, not enforced: the training corpus contains the mirror of every non-identical pair, with the
|
| 128 |
+
label carried over unchanged. That brings the violation down by a factor of five, and it does not remove it. The scorer
|
| 129 |
+
deliberately runs a single direction, the one you pass, rather than averaging both: averaging would make the property
|
| 130 |
+
exact at twice the inference cost, and would hide in the wrapper a residual violation that belongs in the results. Pass
|
| 131 |
+
your pairs in a consistent order.
|
| 132 |
+
|
| 133 |
+
|
| 134 |
## Use MeaningBERT
|
| 135 |
|
| 136 |
You can use MeaningBERT as a [model](https://huggingface.co/davebulaval/MeaningBERT) that you can retrain or use for
|
| 137 |
inference using the following with HuggingFace
|
| 138 |
|
| 139 |
```python
|
| 140 |
+
# Load model directly. subfolder="large" is the v2 checkpoint; without it you get v1.
|
| 141 |
from transformers import AutoTokenizer, AutoModelForSequenceClassification
|
| 142 |
|
| 143 |
+
tokenizer = AutoTokenizer.from_pretrained("davebulaval/MeaningBERT", subfolder="large")
|
| 144 |
+
model = AutoModelForSequenceClassification.from_pretrained("davebulaval/MeaningBERT", subfolder="large")
|
| 145 |
```
|
| 146 |
|
| 147 |
or you can use MeaningBERT as a metric for evaluation (no retrain) using the following with HuggingFace
|
|
|
|
| 151 |
|
| 152 |
from transformers import AutoTokenizer, AutoModelForSequenceClassification
|
| 153 |
|
| 154 |
+
tokenizer = AutoTokenizer.from_pretrained("davebulaval/MeaningBERT", subfolder="large")
|
| 155 |
+
scorer = AutoModelForSequenceClassification.from_pretrained("davebulaval/MeaningBERT", subfolder="large")
|
| 156 |
scorer.eval()
|
| 157 |
|
| 158 |
documents = ["He wanted to make them pay.", "This sandwich looks delicious.", "He wants to eat."]
|
|
|
|
| 166 |
# We process the text
|
| 167 |
scores = scorer(**tokenize_text)
|
| 168 |
|
| 169 |
+
# The output head is applied OUTSIDE the model, so the logits are NOT the score.
|
| 170 |
+
# config.meaningbert_output_head says which one: "clamped" for the v2 checkpoints.
|
| 171 |
+
print((scores.logits.squeeze(-1).clamp(0, 1) * 100).tolist())
|
| 172 |
```
|
| 173 |
|
| 174 |
+
> **The v1 snippet does not carry over.** v1 was trained with a linear head whose logit *is* the score, so its model card
|
| 175 |
+
> prints `scores.logits.tolist()` directly. The v2 checkpoints apply a bounded head outside the model: printing the raw
|
| 176 |
+
> logits returns unit-scale values such as `0.83`, silently, with no error. Read `config.meaningbert_output_head` and map
|
| 177 |
+
> accordingly, or use `meaningbert.scorer.MeaningBERTScorer`, which reads it for you and always returns 0-100.
|
| 178 |
+
|
| 179 |
+
```python
|
| 180 |
+
# The same thing, without having to know which head the checkpoint uses
|
| 181 |
+
from meaningbert import MeaningBERTScorer
|
| 182 |
+
|
| 183 |
+
scorer = MeaningBERTScorer("davebulaval/MeaningBERT", subfolder="large")
|
| 184 |
+
print(scorer.score(documents, simplifications))
|
| 185 |
+
```
|
| 186 |
or using our HuggingFace Metric module
|
| 187 |
|
| 188 |
```python
|
|
|
|
| 192 |
simplifications = ["He wanted to make them pay.", "This sandwich looks delicious.",
|
| 193 |
"Whatever, whenever, this is a sentence."]
|
| 194 |
|
| 195 |
+
# Three checkpoints, named as the second argument of evaluate.load.
|
| 196 |
+
# "large" is the default: deberta-v3-large, the recommended one.
|
| 197 |
meaning_bert = evaluate.load("davebulaval/meaningbert")
|
| 198 |
+
meaning_bert = evaluate.load("davebulaval/meaningbert", "large") # the same thing
|
| 199 |
+
|
| 200 |
+
# "base" is bert-base-uncased: 3.2x faster on GPU, 4.8x on CPU, a quarter of the memory.
|
| 201 |
+
meaning_bert_base = evaluate.load("davebulaval/meaningbert", "base")
|
| 202 |
+
|
| 203 |
+
# "v1" is the model published with the 2023 article, unchanged.
|
| 204 |
+
meaning_bert_v1 = evaluate.load("davebulaval/meaningbert", "v1")
|
| 205 |
|
| 206 |
print(meaning_bert.compute(references=documents, predictions=simplifications))
|
| 207 |
```
|
| 208 |
|
| 209 |
+
### Which checkpoint to load
|
| 210 |
+
|
| 211 |
+
The two v2 checkpoints are **subfolders of the same repository**,
|
| 212 |
+
[davebulaval/MeaningBERT](https://huggingface.co/davebulaval/MeaningBERT), whose root is still the v1 model. Nothing
|
| 213 |
+
already loading that repository changes behaviour.
|
| 214 |
+
|
| 215 |
+
```python
|
| 216 |
+
from transformers import AutoModelForSequenceClassification
|
| 217 |
+
|
| 218 |
+
model = AutoModelForSequenceClassification.from_pretrained("davebulaval/MeaningBERT", subfolder="large")
|
| 219 |
+
```
|
| 220 |
+
|
| 221 |
+
| name | encoder | Pearson *r* | identical pairs above 95 | 100 pairs, GPU / CPU | weights |
|
| 222 |
+
|---|---|---|---|---|---|
|
| 223 |
+
| **`large`** (default) | `deberta-v3-large` | **0.704 ± 0.009** | **97.1 % ± 1.4** | 1.16 s / 9.49 s | 1740 MB |
|
| 224 |
+
| `base`<sup>†</sup> | `bert-base-uncased` | 0.637 | 70.4 % | **0.36 s / 1.99 s** | **438 MB** |
|
| 225 |
+
| `v1` | `bert-base-uncased` | 0.323 | 0 % | 0.36 s / 1.99 s | 438 MB |
|
| 226 |
+
|
| 227 |
+
<sup>†</sup> `base` is **not published yet**: its figures come from a single seed, against ten for `large`, and loading it
|
| 228 |
+
raises rather than falling back on another checkpoint. A name that does not exist raises too, so a typo cannot silently
|
| 229 |
+
swap the model under you.
|
| 230 |
+
|
| 231 |
+
Load `base` when you score at volume or have no GPU, `large` when a wrong score costs you something. On a GPU the speed
|
| 232 |
+
argument is weak, see [A middle option worth knowing about](#a-middle-option-worth-knowing-about).
|
| 233 |
+
|
| 234 |
+
The numbers are detailed in [MeaningBERT v2: which checkpoint to use](#meaningbert-v2-which-checkpoint-to-use).
|
| 235 |
+
|
| 236 |
|
| 237 |
------------------
|
| 238 |
|