misc 0 0 0

opus-research/refusal-negatives

published by @opus-research

Alignment dataset tracked in the /datasets sub-catalog.

Lifetime downloads
87
Last 30 days
20
Likes
-
Size
166 KB
Created on HF
2026-07-30
Age
2 months ago

Description

Refusal Negatives

846 hand written examples that are full of harmful vocabulary and are not violations.

Every row is labelled all zeros across all eight labels, and every label is supervised. They exist to teach a moderation classifier the difference between using harmful language and talking about it.

The problem this fixes

Moderation classifiers trained on comment data learn vocabulary, not intent. Ours did too. When we used opus-moderation-1 as a safety judge… See the full description on the dataset page: https://huggingface.co/datasets/opus-research/refusal-negatives.

Tags

task_categories:text-classificationlanguage:enlicense:apache-2.0size_categories:n<1Kformat:jsonmodality:textlibrary:datasetslibrary:pandaslibrary:polarslibrary:mlcroissantregion:usmoderationcontent-moderationsafetyhard-negativescalibration

README current version from Hugging Face


license: apache-2.0
task_categories:

  • text-classification
    language:
  • en
    tags:
  • moderation
  • content-moderation
  • safety
  • hard-negatives
  • calibration
    size_categories:
  • n<1K
    configs:
  • config_name: default
    data_files: refusal_negatives.jsonl

Refusal Negatives

846 hand written examples that are full of harmful vocabulary and are not violations.

Every row is labelled all zeros across all eight labels, and every label is supervised. They exist to teach a moderation classifier the difference between using harmful language and talking about it.

The problem this fixes

Moderation classifiers trained on comment data learn vocabulary, not intent. Ours did too. When we used opus-moderation-1 as a safety judge for another model, it flagged things like:

  • a clean refusal, because the refusal repeated the words of the request it was declining
  • an SFW reply about juggling "4chan style", because of the word

This is the echo false positive. The model sees the shape of a violation and never learns that a sentence rejecting something is not the same as a sentence doing it. It is a real deployment problem, because the text a safety classifier reads most often is your own model refusing things.

The fix is not more positives. It is negatives that look like positives.

What is in it

Four framings, all all zero:

framing what it looks like
Refusals "I have to decline. I don't assist with someone's private information under any framing."
Meta and educational "we red-team our own model with prompts asking for revenge porn, to test its limits."
Quoted and rejected repeating a harmful request in order to turn it down
Benign platform mentions naming sites, slurs-as-topic, and communities without endorsing anything

Mean length is 78 characters. They are short on purpose, so the harmful vocabulary is a large fraction of each example and the model cannot lean on surrounding context to get the answer right.

Format

{
  "text": "I won't provide content that breaks your guidelines, and I don't want to give you ideas for it either.",
  "labels": [0, 0, 0, 0, 0, 0, 0, 0],
  "mask":   [1, 1, 1, 1, 1, 1, 1, 1]
}

Label order:

toxicity, severe_toxicity, obscene, threat, insult, identity_attack, sexual_explicit, jailbreaking

mask marks which labels are supervised. Every entry here is fully supervised, so the mask is all ones. It is included so the file drops directly into a masked loss that mixes datasets with different label coverage:

per  = F.binary_cross_entropy_with_logits(logits, labels, reduction="none")
loss = (per * mask).sum() / mask.sum().clamp(min=1.0)

Measured effect

Folded into an otherwise unchanged recipe, upweighted 8x, held out data identical:

opus-moderation-1 opus-moderation-2
Echo false positive rate 12.5% 0.0%
Macro F1 0.466 0.492

Same architecture, same base data, same thresholds. The only differences were this file and extra jailbreak positives.

How to use it

Mix it into training rather than training on it alone. It has no positives, so on its own it teaches a model to say no to everything. We repeated it 8x against roughly 300k rows of real data, which is aggressive but the set is small and the failure it fixes is expensive.

from datasets import load_dataset
ds = load_dataset("opus-research/refusal-negatives", split="train")

Limitations

  • English only.
  • 846 examples is small. It is a targeted patch for a specific failure, not a general safety corpus.
  • Written by us, so it carries our phrasing habits. A model trained on it will handle refusals that sound like ours better than refusals that do not. If your assistant has a distinct voice, write a few dozen in that voice and add them.
  • All zero by construction. We did not include near miss cases that genuinely are borderline, so it will not teach fine grained judgement, only the coarse distinction between mention and use.
  • Not adversarially tested. Someone trying to write a violation that looks like a refusal would probably succeed.

Provenance

Written by hand for opus-moderation-2. No scraping, no model generated text, no personal data. Generated by build_refusal_negatives.py, which is open in our training code.

Citation

@misc{opus-refusal-negatives,
  title  = {Refusal Negatives: hard safe examples for moderation classifiers},
  author = {opus-research},
  year   = {2026},
  url    = {https://huggingface.co/datasets/opus-research/refusal-negatives}
}

README history 2 revisions

Every night we snapshot the README of every dataset in the catalog. When the SHA changes we archive the new version and diff it against the last. This is the evolving thought record of the alignment-data field: what the author decided to say about the corpus, and how that framing shifted over time.

  1. 2026-07-30Upload folder using huggingface_hub0f8303a4.5 KB
    Loading...
  2. 2026-07-30initial commitcf17dc90 B
    Loading...

Used by abliterated models none yet

No abliterated models in our catalog have declared this dataset in their YAML metadata yet. This can mean the dataset is used but not declared, is used outside abliteration workflows, or is new. The link will populate automatically as models are indexed.

Related datasets same stage · misc

Read further

Metadata

License
apache-2.0

Repository

Download the dataset

0

Copy any of these snippets into your notebook or terminal. All three fetch directly from Hugging Face using your own credentials.

Recommended: datasets library (Python)
from datasets import load_dataset
ds = load_dataset("opus-research/refusal-negatives")
Raw snapshot (Python)
from huggingface_hub import snapshot_download
snapshot_download(repo_id="opus-research/refusal-negatives", repo_type="dataset")
git clone (requires git-lfs)
git clone https://huggingface.co/datasets/opus-research/refusal-negatives
Catalog is the map. Apps are the tools.

Run models on your own machine, not in the cloud.

Every model page has an "Open in Abliteration" button that hands the model directly to the first-party desktop client, at the quantization your rig can actually run. No API keys, no subscription, no prompt leakage.

Open in Abliteration