--- title: Parry emoji: ⚔️ colorFrom: red colorTo: gray sdk: gradio sdk_version: 6.10.0 app_file: app.py pinned: false license: mit models: - Qwen/Qwen2.5-1.5B-Instruct short_description: Duel a 1.5B model running live in your browser — 0ms network tags: - track:wood - sponsor:modal - achievement:offgrid - achievement:welltuned - achievement:offbrand - achievement:llama - achievement:sharing - achievement:fieldnotes --- # ⚔️ Parry ▶️ **60-second demo:** https://youtu.be/UuyPw8azFg0 📣 **Write-up / social post:** https://www.linkedin.com/posts/jainamshahh_buildsmallhackathon-huggingface-gradio-share-7472337823358955520-ZwOU 📦 **All artifacts (collection):** https://huggingface.co/collections/build-small-hackathon/parry-duel-a-15b-model-running-in-your-browser-6a2b049b9c90574ca2f9a25a Duel a small language model that runs **entirely in your browser** (WebGPU), reads your patterns mid-match, **tells you what it learned about you**, and adapts — inside a real-time reaction loop no cloud API can physically serve. - **🥊 Fight it with your body:** allow the camera and BOX it — punch to strike, both hands up to parry, lean to advance/retreat. Pose tracking runs on your CPU (the GPU belongs to the model). Keyboard always works too. - **Local-first:** the opponent's brain is a Qwen2.5-1.5B decoding one grammar-constrained intent token per decision on YOUR GPU. Pull your Wi-Fi out mid-match — nothing changes. - **Observable adaptation:** the Analyst's live read of you is rendered on screen, and the judge panel (B) lets you EDIT its read and watch the Tactician's play shift in real time. > **⚠️ Browser note (for reviewers):** the opponent's brain runs **in your browser via > WebGPU** — please use a WebGPU-enabled browser (Chrome or Edge on desktop). First load > downloads ~900MB of model weights once, then they're cached. No WebGPU available? > The 60-second demo shows the full experience: https://youtu.be/UuyPw8azFg0 Controls: 🎥 camera = punch/guard/lean · ←/→ move · J strike · K feint · L parry · V toggle camera · F face mask (a Dalí mask hides your face — on by default, safe to record) · B judge panel · 1–5 sparring bots · 7 the Masher · 8 the Executioner · 9 the LLM · Enter rematch · M mute. *(This Space is a `gradio.Server` app — Gradio's engine serves the custom canvas at `/`, and the `trace_digest` endpoint runs through Gradio's queue, callable with `gradio_client`.)* ## ⚡ Built with Modal The entire model program ran on **[Modal](https://modal.com)**: all six fine-tune generations (TRL behavior-cloning on A100s), every evaluation and the classifier-free-guidance sweep, the GGUF conversion (llama.cpp), and the vLLM CFG inference gateway. The published fine-tune that ships in this app was trained, evaluated, and converted end-to-end on Modal — comfortably inside the $250 credit grant. Recipe + reproduce commands: [model card](https://huggingface.co/Jainamshahhh/parry-tactician-1.5b-merged). ## 🎖️ Badge artifacts (everything is public) | Badge | Evidence | |---|---| | 🔌 Off the Grid | All inference in YOUR browser: Tactician + imagination on WebGPU (WebLLM), the tuned Analyst on llama.cpp/WASM. `GET /healthz` → `"inference": "in-browser"` | | 🎯 Well-Tuned | The published fine-tune **runs in this app** as the Analyst — [parry-tactician-1.5b-merged](https://huggingface.co/Jainamshahhh/parry-tactician-1.5b-merged) (model card has the recipe, the six-generation honest eval arc, and `evals/` holds all 18 raw report JSONs) + [-lora](https://huggingface.co/Jainamshahhh/parry-tactician-1.5b-lora) | | 🦙 Llama Champion | [parry-tactician-1.5b-gguf](https://huggingface.co/Jainamshahhh/parry-tactician-1.5b-gguf) (Q4_K_M) runs through **llama.cpp's WASM runtime (wllama)** in-browser — look for "✦ tuned analyst (llama.cpp)" in the HUD | | 🎨 Off-Brand | The custom canvas you're looking at, served by `gr.Server` | | 📡 Sharing is Caring | [parry-traces](https://huggingface.co/datasets/Jainamshahhh/parry-traces) — real decision-by-decision agent traces; export your own with **B → Export trace**, validate via the `trace_digest` API | | 📓 Field Notes | [The full build report](https://huggingface.co/datasets/Jainamshahhh/parry-field-notes) — six model generations, three honestly-failed pre-registered gates, the engine-physics bug a playtest found, the imagination architecture, and the pose-mode saga | NOTE deploy: copy the built client (`npm run build` → `dist/`) into `static/` before pushing; `app.py` serves `static/index.html` at `/`.