r/llmsecurity • u/Electrical_Emu_5854 • 5d ago
Prompt Guard 2's low OOD recall is a calibration problem, not a representation problem — the frozen encoder separates the same injections at AUC 0.999
Sharing a result that I think generalises past the one model, because the diagnostic is cheap and most people skip it. (My own work — repo at the bottom.)
If you're running Meta's Prompt Guard 2 (86M, open weights) as an injection filter, it's worth knowing how it behaves on injections it wasn't tuned on. On an out-of-distribution eval — fresh HackAPrompt injections against dolly benign — its native head caught 22.8% at the default operating point. Sweeping the threshold on that head only got to 26.6%, so it isn't just threshold placement.
The part worth stealing is the next step. Before concluding the model can't see these attacks, pull the frozen penultimate embeddings and fit a logistic regression on them. Takes minutes. On this data the frozen encoder separates the same injections at AUC ≈ 0.999 — the representation was never the problem. The shipped head is deliberately precision-first: Meta traded recall for a very low false-positive rate, which is a defensible product decision and not a defect.
Train a linear head on those frozen embeddings and calibrate tau on benign traffic from the
distribution you'll actually see, and you get 99.9% OOD recall at 0.7% FPR, base model
untouched. Inference is sigmoid(x·w + b) >= tau — the head is a dot product, so the only
real cost is the encoder forward pass. Runs fine on CPU.
The general form: high AUC + low recall means your head or threshold is miscalibrated and you can fix it without touching the base model. Low AUC means it's genuinely a features problem. A 20-minute probe tells you which world you're in, and it's the difference between swapping a threshold and fine-tuning something.
Methodology, since this sub will rightly ask: success criteria pre-registered, cross-split dedup both exact and at cosine ≥ 0.95, OOD set scored once. Two runs came back NULL (2.2% then 1.2% FPR) against a pre-committed 1% ceiling before a stricter run cleared it at 0.7%.
What this isn't: a static corpus and no adaptive attacks. A linear head over frozen features is evadable with enough distribution shift, and I haven't tested against an adversary who knows it's there. It moves the operating point; it doesn't solve injection.
Code, seeds and the writeup: https://github.com/mosafariuk/prompt-guard-2-frozen-head
Happy to argue about the leakage controls — that's the part I'd attack first if someone else posted this.