whatbird / README.md
greatx's picture
Update submission links in README
995003e
|
Raw
History Blame Contribute Delete
4.33 kB
---
title: WhatBird
emoji: 🐦
colorFrom: green
colorTo: blue
sdk: gradio
sdk_version: 6.17.3
python_version: "3.12"
app_file: app.py
pinned: false
license: apache-2.0
short_description: Bird ID β€” fast classifier + 1B vision-language model
tags:
- build-small-hackathon
- backyard-ai
- tiny-titan
- small-models
- track:backyard
- sponsor:openbmb
- achievement:offgrid
---
# 🐦 WhatBird
[![REDnote](https://img.shields.io/badge/REDnote-whatbird-ff2442?style=flat-square)](http://xhslink.com/o/9AHjKKUQ1B)
[![Demo video](https://img.shields.io/badge/Demo-video-2f855a?style=flat-square)](http://xhslink.com/o/2jdfwxk4IDj)
Identify a bird from a photo with a two-stage pipeline: a fast on-device
classifier proposes the species, then a compact vision-language model confirms
the call and explains it from visible field marks.
- **Specialist classifier β€” fast & on-device.** A YOLO26-x image classifier
(exported to ONNX, runs on CPU) trained on CUB-200-2011 + Birdsnap +
iNaturalist-2021 merged into **1,532 species** (78.3% top-1 / 91.9% top-5). It
narrows 1,532 classes to a handful of candidates in milliseconds.
- **Vision-language model β€” visual reasoning.** [MiniCPM-V 4.6](https://huggingface.co/openbmb/MiniCPM-V-4.6)
(just **1B** parameters) looks at the photo together with the shortlist,
confirms the species (or flags a mismatch), and explains *why* from visible
field marks β€” exactly the call a narrow classifier struggles with on
look-alikes (e.g. Alder vs. Least Flycatcher).
Both models are small (≀4B) β€” the point is the division of labour, not raw
scale: the specialist is cheap and covers the long tail of 1,532 species; the
vision-language model is invoked only on the shortlist, where its reasoning adds
the most value.
## How the two models collaborate
They don't just run in sequence β€” control is handed to whichever model is more
reliable, gated on the classifier's top-1 confidence:
| Classifier top-1 | Who leads | Behavior |
|------------------|-----------|----------|
| **β‰₯ 0.80** (confident) | the **specialist classifier** | The VLM only *confirms and explains* β€” it cannot overturn a confident, in-domain call. (Stops a 1B VLM from "correcting" a correct 94% answer into a look-alike.) |
| **0.50 – 0.80** (unsure) | the **VLM, within the shortlist** | Re-ranks the top-5 from what it sees. |
| **< 0.50** (lost) | the **VLM, open-vocabulary** | The shortlist is a weak hint; the VLM may name a species *not in the 1,532* and the result is flagged "not in shortlist". |
In practice that means: a clear shot (`samples/sample_2.jpg`, Acorn Woodpecker,
100%) sits in the top tier β€” the classifier is sure and the VLM only confirms. A
look-alike *Empidonax* flycatcher (`samples/sample_1.jpg`) drops the classifier
to ~40%, below the threshold, so the VLM reasons over the shortlist from visible
field marks β€” exactly where a 1B vision model earns its keep. For a bird beyond
all 1,532 classes, the open-vocabulary tier lets the VLM name it directly,
flagged "not in shortlist".
The 1,532-class set is now **global**, not just North-American β€” it merges
iNaturalist-2021 on top of CUB + Birdsnap. So the **European Robin**
(`samples/robin.jpg`), which the earlier 562-species model couldn't place, is now
identified directly by the classifier. Small model covers an ever-wider base;
large model reasons over what's left.
## Running it
```bash
pip install -r requirements.txt
python app.py
```
The large-model backend needs no configuration: MiniCPM-V switches on
automatically wherever a GPU can serve it (an HF ZeroGPU Space, or a local CUDA
box). Without a GPU the app falls back to a lightweight templated explanation and
stays fully functional. (`WHATBIRD_DESCRIBER=stub|minicpm` or
`WHATBIRD_MODEL_ID=...` override the auto-detection.)
## Models
| Model | Role | Size | Score | Notes |
|-------|------|------|-------|-------|
| yolo26x_v2 (ONNX) | specialist classifier | 116 MB | 78.3% top-1 / 91.9% top-5 | shipped, CPU, 1,532 classes |
| yolo26s_v2 | specialist classifier (light) | 15 MB (.pt) | 70.9% top-1 / 87.4% top-5 | smaller/faster alternative |
| MiniCPM-V 4.6 | re-ranker / explainer | **1B** | β€” | 2.6 GB, Apache-2.0 |
Built for the [Build Small Hackathon](https://huggingface.co/spaces/build-small-hackathon).