parry / README.md
Jainamshahhh's picture
frontmatter: submission tags (track/sponsor/achievements)
0f20aa8 verified
|
Raw
History Blame Contribute Delete
4.63 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade
metadata
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: 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.

🎖️ 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 (model card has the recipe, the six-generation honest eval arc, and evals/ holds all 18 raw report JSONs) + -lora
🦙 Llama Champion 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 — 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 — 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 builddist/) into static/ before pushing; app.py serves static/index.html at /.