COPA
Tests causal common sense: given a short statement, which of two alternatives is the more likely cause or effect.
At a glance
What it tests
COPA is the smallest benchmark in this collection and one of the cleanest. A premise ('My body cast a shadow over the grass'), a direction ('what was the cause?'), and two alternatives ('the sun was rising' / 'the grass was cut'). Everything hinges on everyday causal knowledge.
It was written by hand in 2011 and designed so that neither alternative is implausible on its own — only the pairing with the premise decides.
GPT-3 reached 92% few-shot, and it was essentially solved (99.4%, human 100%) by 2022. It remains a useful smoke test because it is tiny and unambiguous.
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 (32 examples), SuperGLUE | 92.0 acc | Zero-shot 91.0; fine-tuned SOTA then 94.8 |
State of the art
ST-MoE 99.2, PaLM 540B 99.0. Source: arxiv.org ↗ · 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
premise, choice1, choice2, question ('cause' / 'effect'), label (0 or 1)
from datasets import load_dataset ds = load_dataset("aps/super_glue", "copa", split="validation") print(ds) # columns: premise, choice1, choice2, question ('cause' / 'effect'), label (0 or 1) 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
def prompt(ex): conn = "because" if ex["question"] == "cause" else "so" return f"{ex['premise'][:-1]} {conn}" def lower_first(s): return s[0].lower() + s[1:] acc = 0 for ex in ds: s = [loglik(prompt(ex), " " + lower_first(ex[c])) for c in ("choice1", "choice2")] acc += int(s.index(max(s)) == ex["label"]) print("accuracy", acc / len(ds))
Task name(s): copa. The harness reproduces the GPT-3 prompt formats and reports the standard metric.
lm_eval --model hf --model_args pretrained=gpt2,dtype=bfloat16 \
--tasks copa --num_fewshot 0 --batch_size auto --output_path results/Pitfalls
- Connect premise and alternative with 'because' (cause) or 'so' (effect) when prompting an LM — GPT-3 did, and it matters.
- 100 dev items: ±3 points is noise.
- Lower-case the first letter of the alternative when appending it after the connective.
References
- Paper (2011)https://people.ict.usc.edu/~gordon/publications/AAAI-SPRING11A.PDF
- SuperGLUEhttps://super.gluebenchmark.com/
- Hugging Face (super_glue/copa)https://huggingface.co/datasets/aps/super_glue