HellaSwag
Tests whether a model can pick the most sensible continuation of an everyday scene from four options written to fool it.
At a glance
What it tests
HellaSwag gives a short description of an everyday situation ('A woman is outside with a bucket and a dog. The dog is running around trying to avoid a bath. She…') and four ways the sentence could continue. One is the real continuation; three were written by a model.
The trick is adversarial filtering: generated endings that BERT could identify as fake were thrown away and regenerated, until what remained were endings that read naturally to a model but are obviously wrong to a person (humans score ~95%).
GPT-3 reached 79.3% few-shot, and the benchmark stayed in every model report from then until it saturated around 2024 (Claude 3 Opus 95.4%, GPT-4 95.3%).
Examples
Items from the dataset (or representative items where the originals are not freely redistributable).
Reported results
Scores reported on this benchmark, with the evaluation setting each one used.
| Setting | Reported | Context |
|---|---|---|
| Few-shot (20 examples), log-likelihood of each ending | 79.3 acc | Zero-shot 78.9; fine-tuned SOTA then 85.6 (ALUM) |
State of the art
GPT-4 95.3 (10-shot). Frontier models stopped reporting it in 2025. Source: www-cdn.anthropic.com ↗ · checked October 2026.
Quickstart
Load the benchmark and score a Hugging Face causal LM on it in a few lines.
pip install -U datasets transformers evaluate lm-eval sacrebleu rouge-score scikit-learn
ctx, endings (list of 4), label (string '0'–'3'), activity_label. Test labels hidden; use validation.
from datasets import load_dataset ds = load_dataset("Rowan/hellaswag", split="validation") print(ds) # columns: ctx, endings (list of 4), label (string '0'–'3'), activity_label print(ds[0])
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.
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
# Multiple choice by length-normalised log-likelihood of each ending (acc_norm) def choices(ex): if "endings" in ex: return ex["ctx"], ex["endings"], int(ex["label"]) # HellaSwag if "sol1" in ex: return ex["goal"], [ex["sol1"], ex["sol2"]], ex["label"] # PIQA story = " ".join(ex[f"input_sentence_{i}"] for i in range(1, 5)) # Story Cloze return story, [ex["sentence_quiz1"], ex["sentence_quiz2"]], ex["answer_right_ending"] - 1 acc = 0 for ex in ds: ctx, ends, gold = choices(ex) s = [loglik(ctx, " " + e) / max(1, len(e)) for e in ends] acc += int(s.index(max(s)) == gold) print("acc_norm", acc / len(ds))
Task name(s): hellaswag. The harness reproduces the GPT-3 prompt formats and reports the standard metric.
lm_eval --model hf --model_args pretrained=gpt2,dtype=bfloat16 \
--tasks hellaswag --num_fewshot 0 --batch_size auto --output_path results/Pitfalls
- Score endings by length-normalised log-likelihood (acc_norm); raw log-likelihood favours short endings.
- The text contains artefacts like '[header]' and '[title]' from WikiHow; lm-eval strips them with a preprocess function.
- Label is a string in the HF version; cast to int.
References
- Paper (arXiv 1905.07830)https://arxiv.org/abs/1905.07830
- Dataset pagehttps://rowanzellers.com/hellaswag/
- Hugging Facehttps://huggingface.co/datasets/Rowan/hellaswag