STS-B

Semantic Textual Similarity Benchmark

Tests whether a model can rate how similar two sentences are in meaning, on a scale from 0 (unrelated) to 5 (identical).

Released Aug 2017 Metric GLUE test SOTA 93.7 Pearson / 93.3 Spearman · Turing NLR v5 (2022)
01

At a glance

Task
Regression: predict a 0–5 similarity score
Size
5.7k train / 1.5k dev / 1.4k test
Metric
Pearson and Spearman correlation with human scores
Source
News headlines, image captions, forum posts from SemEval STS 2012–2017
Part of
GLUE
SemEval-2017 Task 1: Semantic Textual Similarity Multilingual and Crosslingual Focused Evaluation
Cer, Diab, Agirre, Lopez-Gazpio, Specia · SemEval 2017
Read the paper ↗ Hugging Face ↗
02

What it tests

STS-B asks for a number instead of a label. Humans rated how similar two sentences are on a 0 (unrelated) to 5 (equivalent) scale, and a model is scored by how well its predictions correlate with those ratings.

Because it is graded, STS-B is the standard check for sentence-embedding models: cosine similarity of two embeddings should track the human score. Pearson rewards getting the magnitude right; Spearman only the ranking.

GPT-1 reached 82.0 Pearson by adding a linear regression head on the pooled representation.

03

Examples

Items from the dataset (or representative items where the originals are not freely redistributable).

Sentence 1
A plane is taking off.
Sentence 2
An air plane is taking off.
Answer5.00
Sentence 1
A man is playing a large flute.
Sentence 2
A man is playing a flute.
Answer3.80
Sentence 1
Three men are playing chess.
Sentence 2
Two men are playing chess.
Answer2.60
Sentence 1
A woman is dancing.
Sentence 2
A man is talking.
Answer0.00
04

Reported results

Scores reported on this benchmark, with the evaluation setting each one used.

SettingReportedContext
Fine-tuned with a regression head82.0 PearsonPrior best 81.0
05

State of the art

Best known · GLUE test
93.7 Pearson / 93.3 Spearman
✓ saturated · at or above human level
Model
Turing NLR v5
2022
Human baseline
92.7 / 92.6

Source: arxiv.org ↗ · checked October 2026.

06

Quickstart

Load the benchmark and score a Hugging Face causal LM on it in a few lines.

1Install
shell
pip install -U datasets transformers evaluate lm-eval sacrebleu rouge-score scikit-learn
2Load the data

sentence1, sentence2, label (float 0–5)

python · load
from datasets import load_dataset

ds = load_dataset("nyu-mll/glue", "stsb", split="validation")
print(ds)            # columns: sentence1, sentence2, label (float 0–5)
print(ds[0])
3Score a model

Two helpers cover every benchmark in this collection: loglik for anything multiple-choice (score each option, pick the highest) and generate for anything free-form. Swap MODEL for whatever you are evaluating.

python · helpers
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

MODEL = "gpt2"                                   # or "Qwen/Qwen2.5-1.5B", "meta-llama/Llama-3.2-1B", …
tok = AutoTokenizer.from_pretrained(MODEL); model = AutoModelForCausalLM.from_pretrained(MODEL, torch_dtype=torch.bfloat16).eval().to("cuda")

@torch.no_grad()
def loglik(context, continuation):
    """Sum of log-probs of `continuation` tokens given `context` — the standard multiple-choice scorer."""
    ids = tok(context + continuation, return_tensors="pt").input_ids.to(model.device)
    n_ctx = len(tok(context).input_ids)
    logp = model(ids).logits.log_softmax(-1)[0, :-1]
    return logp.gather(1, ids[0, 1:, None])[n_ctx - 1:].sum().item()

@torch.no_grad()
def generate(prompt, max_new_tokens=32, stop=None):
    ids = tok(prompt, return_tensors="pt").input_ids.to(model.device)
    out = model.generate(ids, max_new_tokens=max_new_tokens, do_sample=False, pad_token_id=tok.eos_token_id)
    text = tok.decode(out[0, ids.shape[1]:], skip_special_tokens=True)
    return text.split(stop)[0] if stop else text
python · evaluate
import re
from scipy.stats import pearsonr, spearmanr
preds, golds = [], []
for ex in ds:
    p = f"On a scale of 0 to 5, how similar are these sentences?\n1: {ex['sentence1']}\n2: {ex['sentence2']}\nScore:"
    m = re.search(r"\d+(\.\d+)?", generate(p, max_new_tokens=4)); preds.append(float(m.group()) if m else 2.5); golds.append(ex["label"])
print("pearson", pearsonr(preds, golds)[0], "spearman", spearmanr(preds, golds)[0])
07

Pitfalls

  • Report both Pearson and Spearman; embedding papers usually quote Spearman×100.
  • For a generative LLM, prompt for a number and parse it — or score with cosine similarity of hidden states; the two give different results.
  • The Hub's `sentence-transformers/stsb` copy normalises scores to 0–1.
08

References