Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks
Paper • 1908.10084 • Published • 17
How to use aynaval2003/echo-sbert-domain with Transformers:
# Load model directly
from transformers import AutoTokenizer, AutoModel
tokenizer = AutoTokenizer.from_pretrained("aynaval2003/echo-sbert-domain")
model = AutoModel.from_pretrained("aynaval2003/echo-sbert-domain", device_map="auto")How to use aynaval2003/echo-sbert-domain with sentence-transformers:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("aynaval2003/echo-sbert-domain")
sentences = [
"That is a happy person",
"That is a happy dog",
"That is a very happy person",
"Today is a sunny day"
]
embeddings = model.encode(sentences)
similarities = model.similarity(embeddings, embeddings)
print(similarities.shape)
# [4, 4]A sentence embedding model for short, messy, real-world app-store reviews.
Built for Echo, which turns 100,000 Swiggy Google Play reviews into tracked themes. Trained in two stages:
distilroberta-base on 300,000 SNLI +
MultiNLI pairs, siamese, mean pooling, classifier on (u, v, |u-v|) — written
by hand in raw PyTorch, reproducing
Reimers & Gurevych (2019).MultipleNegativesRankingLoss on 53,061
pairs mined from the reviews themselves, where TF-IDF and the stage-1 encoder
independently agree, plus SimCSE dropout self-pairs.| benchmark | score |
|---|---|
| STS average (7 datasets) after stage 1 | 72.17 |
| STS average after stage 2 | 74.54 |
| Review retrieval, Precision@10 | 61.15 |
| Review retrieval, + cross-encoder rerank | 75.77 |
| Theme assignment, blind hand-audit | 82.4% |
Stage 2 improved generic STS by +2.37 while adapting to the domain, which was predicted to degrade and did not. Note that 74.54 is not "beating the paper's 74.21": that number comes from NLI training alone, this adds a second stage.
from transformers import AutoModel, AutoTokenizer
import torch
tok = AutoTokenizer.from_pretrained("aynaval2003/echo-sbert-domain")
model = AutoModel.from_pretrained("aynaval2003/echo-sbert-domain").eval()
def embed(sentences):
x = tok(sentences, padding=True, truncation=True, max_length=128,
return_tensors="pt")
with torch.no_grad():
h = model(**x).last_hidden_state
mask = x["attention_mask"].unsqueeze(-1).float() # mean pooling,
v = (h * mask).sum(1) / mask.sum(1).clamp(min=1e-9) # ignoring padding
return torch.nn.functional.normalize(v, dim=1)
Mean pooling, and it matters — this model was trained with it. CLS pooling scores 5.1 points lower in the ablation.