whisperkey / README.md
chiruu12's picture
add demo video link to submission block
2a437b3 verified
|
Raw
History Blame Contribute Delete
6.54 kB
---
title: Whisperkey
emoji: πŸ”‘
colorFrom: green
colorTo: yellow
sdk: gradio
sdk_version: "6.18.0"
app_file: app.py
python_version: "3.11"
pinned: false
license: mit
thumbnail: thumbnail.png
short_description: Outwit a small AI guardian past Unplug's defenses
models:
- Unplug-AI/unplug-tiny-v1
- nvidia/Nemotron-Mini-4B-Instruct
- openbmb/MiniCPM4-8B
tags:
- track:wood
- sponsor:openbmb
- sponsor:nvidia
- sponsor:modal
- achievement:fieldnotes
- achievement:offbrand
- achievement:llama
- achievement:welltuned
- achievement:offgrid
---
# πŸ”‘ Whisperkey
**Other prompt-injection games are a black box. This one is an X-ray.**
Built for the **[Build Small Hackathon](https://huggingface.co/build-small-hackathon)** (πŸ„ *An Adventure
in Thousand Token Wood*). Whisper a secret key out of a small AI guardian while a **real, open-source
firewall** - [Unplug](https://github.com/UnplugAI/Unplug) - defends it. The twist: when a shield stops
you, the game shows you **exactly which layer fired and why**. You're not guessing against a black box -
you're *reading the firewall as you attack it*. Five levels = five live layers of the defense stack.
> A small model (≀ 8B) holds the secret; **Unplug** is the firewall. Every attempt is logged
> (PII-stripped) as labeled red-team data - the bypasses that beat the shields are Unplug's exact blind
> spots, fed back to a public Hugging Face Dataset. **You're red-teaming a real firewall.**
### Built small, the whole way down
Every model in the loop is tiny, and the **entire game runs on models ≀ 4B**:
- **Guardian:** `nvidia/Nemotron-Mini-4B-Instruct` (**4B**) or `openbmb/MiniCPM4-8B` (8B) - pick in the UI.
- **Firewall shield:** [`Unplug-AI/unplug-tiny-v1`](https://huggingface.co/Unplug-AI/unplug-tiny-v1) -
a fine-tuned DeBERTa-v3-xsmall (**~22M non-embedding params**) that runs on **CPU**.
Pick the **Nemotron-4B** guardian and the whole thing - guardian *and* firewall - is a sub-4B stack.
That's the **Tiny Titan** story: a 4B model defended by a 22M-param model, no large model anywhere.
## How it plays
Chat with the guardian to extract clues, then **submit your guess**. Each level adds a defense:
| Level | Guardian | Defense added |
|-------|----------|---------------|
| 1 | Pip the Naive Sprite | none - just charm it |
| 2 | Bramblewattle the Hedge | Unplug regex injection shield |
| 3 | Sable the Warded Owl | + a hardened guardian (won't encode / spell / translate) |
| 4 | The Output Warden | + Unplug output redaction - the key gets scrubbed on the way out |
| 5 | The Heart of the Wood | + the `unplug-tiny` ML classifier - every defense at once |
The Wood darkens as you descend. At Level 4+ you must leak the key *in disguise*, because Unplug scrubs
the verbatim key - then decode it and submit your guess.
**Pick your guardian model** in the UI: `openbmb/MiniCPM4-8B` (OpenBMB) or `nvidia/Nemotron-Mini-4B-Instruct` (NVIDIA).
## Does the firewall actually work? (eval)
Not vibes - measured. `benchmarks/eval_shields.py` runs a fixed corpus of 18 injection attacks + 12
benign messages through the shields (no model needed) and reports detection per layer:
| Input shields | Attacks blocked (recall) | Benign blocked (false-positive) |
|---------------|--------------------------|---------------------------------|
| none (L1) | 0% | 0% |
| regex (L2-L4) | 39% | 0% |
| regex + `unplug-tiny` ML (L5) | **83%** | **0%** |
The ML scanner **more than doubles attack detection (39% β†’ 83%) at a 0% false-positive rate.** The
~17% that still slip through are the disguised/novel bypasses the game exists to surface - the exact
labeled red-team data the flywheel feeds back to Unplug. Reproduce: `uv run python benchmarks/eval_shields.py`.
## Stack
- **Gradio** frontend, deployed as this **Hugging Face Space** (CPU - the model runs on Modal GPU).
- **Guardians (pick one in UI):** MiniCPM4-8B (OpenBMB) or Nemotron-Mini-4B (NVIDIA) on Modal L4 endpoints.
- **Offline mode:** local **llama.cpp** GGUF fallback (Llama Champion / Off the Grid path).
- **Defenses:** the [Unplug](https://github.com/UnplugAI/Unplug) security SDK - `scan()` blocks attacks
(and explains why), `scan_output()` redacts a leaked key. The L5 ML shield is
[`Unplug-AI/unplug-tiny-v1`](https://huggingface.co/Unplug-AI/unplug-tiny-v1) - our fine-tuned
DeBERTa-v3-xsmall span-injection model, published on the Hub.
- **Leaderboard + attack corpus:** Hugging Face Datasets.
- **Field notes:** [docs/field-notes.md](docs/field-notes.md) Β· eval: [benchmarks/results.md](benchmarks/results.md)
## Merit badges & awards
- 🎯 **Well-Tuned** - the L5 shield, [`Unplug-AI/unplug-tiny-v1`](https://huggingface.co/Unplug-AI/unplug-tiny-v1),
is our own fine-tuned span-injection model, published on the Hub.
- 🎨 **Off-Brand** - the entire frontend is a hand-built HTML/JS shell on Gradio 6 `gr.Server`, not default Blocks.
- πŸ¦™ **Llama Champion** / πŸ”Œ **Off the Grid** - offline mode runs the *whole* loop (guardian + firewall +
corpus) locally on a **llama.cpp** GGUF with **zero cloud APIs** - see [docs/field-notes.md](docs/field-notes.md).
- 🐣 **Tiny Titan (≀4B)** - pick `nvidia/Nemotron-Mini-4B-Instruct` (4B) as the guardian and the *entire*
stack is sub-4B: a 4B guardian defended by the ~22M-param [`unplug-tiny-v1`](https://huggingface.co/Unplug-AI/unplug-tiny-v1) shield, no large model anywhere.
- πŸ““ **Field Notes** - the build write-up: [docs/field-notes.md](docs/field-notes.md).
## Demo & submission
- **Live app:** https://build-small-hackathon-whisperkey.hf.space
- **Demo video:** https://drive.google.com/file/d/1BdDbHts-s1al7iKKDLN17UI4lEjp1TqM/view
- **Local demo prep:** [docs/local-demo-prep.md](docs/local-demo-prep.md)
- **Social post (LinkedIn):** https://www.linkedin.com/posts/chiruu12_buildsmall-huggingface-llm-share-7471918332175220737-6bJk
- **Social post (Reddit):** https://www.reddit.com/r/ArtificialInteligence/comments/1u5l7z3/every_successful_jailbreak_of_this_game_becomes/
## Run it locally
```bash
uv sync
cp .env.example .env # add HF_TOKEN; set MODAL_ENDPOINT + MODAL_API_KEY
make run
```
## Layout
```
app.py # Space entry point (thin)
modal_app.py # Modal GPU guardian endpoints (deploy separately per model)
config/levels.toml # the 5 levels as data
src/jailbreak_dojo/ # engine Β· guardian Β· shields Β· levels Β· corpus Β· leaderboard Β· ui
tests/ # pytest suite (incl. live Unplug shields)
```
MIT licensed.