kicky-ai / README.md
dcrey7's picture
Add YouTube demo video link to README
2f5aba7
|
Raw
History Blame Contribute Delete
5.36 kB
---
title: Kicky AI
emoji:
colorFrom: green
colorTo: yellow
sdk: gradio
sdk_version: 6.18.0
python_version: '3.12'
app_file: server.py
pinned: false
license: apache-2.0
short_description: check if you have the skill to make it the worldcup
tags:
- track:backyard
- sponsor:openbmb
- sponsor:openai
- sponsor:nvidia
- sponsor:modal
- achievement:offgrid
- achievement:welltuned
- achievement:offbrand
- achievement:llama
- achievement:sharing
- achievement:fieldnotes
---
# ⚽ Kicky AI — Football Shot Analysis
**They measure your shot. You fix it.**
🎥 **Demo video:** https://www.youtube.com/watch?v=knL8shghyBU ·
📰 **Blog:** https://dcrey7.substack.com/p/world-fut-coach ·
🐦 **X thread:** https://x.com/dcrey77/status/2066331088331358643
Upload a shot clip (or pick a held-out test example). From a single clip, **one small model +
pure geometry/physics** produce:
| Output | How |
|---|---|
| **Goal / no-goal + timestamp** | ball ∩ goal + shot physics (kick → flight → settle-in-net vs rebound / over-the-bar) |
| **Who shot it** | ball ∩ player possession over time (last touch before the ball reaches goal) |
| **Shooting foot (L/R)** | MediaPipe (BlazePose) on the shooter at the kick frame |
| **Shot speed (km/h)** | the ball's apparent diameter (real ball = 22 cm) as a px→m scale |
| **AI coaching** | a vision-LLM grades the shot: Verdict → Fix → Fix → Drill |
The video shows **player segmentation masks** (with `P1`/`P2`/`P3` labels that flip to
`P# BALL` on possession), a **green goal mask**, a smooth **ball trail**, and a red
**goal-spot marker** — plus a separate **Result** table, **Shot-speed** card and
**Pose-Detection** card.
## The approach — foundation-model labelling → real-time distillation
The interesting part isn't one model, it's a **pipeline that needs zero manual labels**:
1. **Auto-label** every clip with **SAM3** ("ball" / "person" / "goal post"); where SAM3
misses the small/blurred/tilted ball, **NVIDIA LocateAnything-3B** fills the gap.
2. **Derive events geometrically** — ball∩player → possession; ball∩goal + trajectory
physics → goal (the rest-in-net vs rebound vs over-the-bar rules handle 2D depth
ambiguity).
3. **Distil** those auto-labels into one fast **RF-DETR-Seg** model (ball / player / goal)
— replacing the slow SAM3 + LA stack at inference.
The distilled detector runs live on **ZeroGPU**; everything else is CPU geometry.
## The AI coach — two vision models, one toggle
After the geometry, a **vision-LLM looks at the strike frame** and grades the shot, grounded on
the measured stats (goal / foot / speed + pose angles). It streams in separately so the results
never wait on it:
-**Offline****MiniCPM-V-4.6** (OpenBMB, ~1.3B) runs **fully on this Space's own ZeroGPU**,
no external call.
- ☁️ **Online****NVIDIA Nemotron-Nano-12B-v2-VL** (GGUF Q4_K_M + mmproj) served through a
**llama.cpp** server on **Modal** (A10G GPU).
## Built with — sponsors, models & badges
-**Modal** *(sponsor)* — runtime for the **online Nemotron coach** (llama.cpp server); see
`modal_coach.py`.
- 🟣 **NVIDIA** *(sponsor)***Nemotron-Nano-12B-v2-VL** powers the online coach; **LocateAnything-3B**
rescues the tiny/tilted ball during auto-labelling.
- 🟢 **OpenBMB** *(sponsor)***MiniCPM-V-4.6** is the **offline, on-device coach**.
- 🤖 **OpenAI Codex** *(sponsor)* — built the browser **annotation tools** (Codex-attributed
commits in this Space's git history).
- 🔗 **Shared agent trace** *(Sharing is Caring)* — the sanitized Codex build trace is on the Hub:
[`kicky-ai-codex-trace`](https://huggingface.co/datasets/build-small-hackathon/kicky-ai-codex-trace).
- 🦙 **llama.cpp** *(Llama Champion)* — runtime for the Nemotron GGUF (Q4_K_M) coach.
- 🎨 **Custom UI** *(Off-Brand)* — a bespoke football-stadium frontend on **`gradio.Server`**
(hand-written HTML/JS + SVG pitch, not default Gradio Blocks).
- 🛠️ **Fine-tuned model** *(Well-Tuned)* — RF-DETR-Seg, distilled and published at
[`kicky-ai-rfdetr-seg`](https://huggingface.co/build-small-hackathon/kicky-ai-rfdetr-seg).
- 📴 **Runs offline** *(Off the Grid)* — choose **Offline** and the whole pipeline + coach run
**on-device with no cloud API**.
- 📝 **Write-up** *(Field Notes)* — full blog on
[Substack](https://dcrey7.substack.com/p/world-fut-coach) + `docs/blog.md`.
## Results (held-out 12-clip test set)
| Detector | Goal | Leg | Pose-capture |
|---|---|---|---|
| SAM3 + LA (teacher, zero-shot) | 83 % | 82 % | 92 % |
| **RF-DETR-Seg-Small** (student, distilled) | 75 % | 75 % | **100 %** |
> Honest note: goal detection on monocular 2D tops out in the low-to-mid 80s % — a ball
> *in front of* the goal and a ball *in the net* are the same pixels (depth ambiguity).
Model → [`build-small-hackathon/kicky-ai-rfdetr-seg`](https://huggingface.co/build-small-hackathon/kicky-ai-rfdetr-seg) ·
Dataset → [`build-small-hackathon/kicky-ai-spf`](https://huggingface.co/datasets/build-small-hackathon/kicky-ai-spf)
Every model is small (RF-DETR-Seg-Small · MiniCPM-V-4.6 1.3B · Nemotron-Nano-12B), well under
the 32B cap. Built for the **Build Small Hackathon** by a Sunday-league player who wanted to
know if his strikes have World Cup form.