File size: 10,869 Bytes
b2ebfa6
b43c522
b2ebfa6
 
32e0771
9f98f96
b2ebfa6
181dd78
b2ebfa6
181dd78
 
 
 
 
 
 
 
 
f9f4f9a
 
 
 
181dd78
 
 
 
c33e98e
f9f4f9a
 
b2ebfa6
 
181dd78
b2ebfa6
181dd78
 
b2ebfa6
181dd78
b2ebfa6
181dd78
b2ebfa6
f9f4f9a
 
 
181dd78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0446dcd
181dd78
 
80dfdac
181dd78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b2ebfa6
181dd78
 
 
b43c522
181dd78
 
0446dcd
f9f4f9a
 
181dd78
 
 
b43c522
f9f4f9a
b2ebfa6
181dd78
b2ebfa6
181dd78
b2ebfa6
181dd78
 
 
 
 
 
 
 
b2ebfa6
181dd78
b2ebfa6
181dd78
b2ebfa6
181dd78
 
 
 
f9f4f9a
 
181dd78
 
b2ebfa6
181dd78
b2ebfa6
b43c522
181dd78
 
b43c522
181dd78
0446dcd
181dd78
 
0446dcd
 
 
181dd78
 
 
 
b43c522
b2ebfa6
181dd78
 
 
 
 
 
 
 
 
 
0446dcd
 
181dd78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f9f4f9a
181dd78
 
 
 
 
 
 
 
 
f9f4f9a
181dd78
b2ebfa6
 
181dd78
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
---
title: PawMap
emoji: 🐾
colorFrom: green
colorTo: green
sdk: docker
app_file: app.py
pinned: true
license: mit
short_description: Collaborative stray animal mapping with AI
tags:
  - stray-animals
  - animal-welfare
  - maps
  - computer-vision
  - small-models
  - gradio
  - build-small-hackathon
  - track:backyard
  - sponsor:nvidia
  - achievement:offbrand
  - achievement:sharing
  - backyard-ai
  - leaflet
  - cosine-similarity
models:
  - meta-llama/Llama-3.2-11B-Vision-Instruct
  - nvidia/Nemotron-Mini-4B-Instruct
  - sentence-transformers/all-MiniLM-L6-v2
---

# PawMap 🐾 β€” Collaborative stray animal mapping with AI

Take a photo of the stray animal you just spotted. The AI identifies species, breed and color β€” and checks if it's already been registered before.  
Over time, the map tells each animal's story: where it shows up, who helped, whether it's doing okay.

Built for the [**Build Small Hackathon 2026**](https://huggingface.co/build-small-hackathon) · **Backyard AI** track 🏑

**Try it:** [live Space](https://huggingface.co/spaces/build-small-hackathon/viralata-mapper) Β· **Traces:** [dataset on the Hub](https://huggingface.co/datasets/build-small-hackathon/viralata-mapper-storage)

> 🎬 **Demo video:** `TODO β€” paste your YouTube / Vimeo / Loom link here before submitting`
> πŸ“£ **Social post:** `TODO β€” paste your X / LinkedIn / Bluesky / Mastodon post link here before submitting`

---

## The Problem

BrasΓ­lia, DF β€” the capital of Brazil β€” has thousands of stray dogs and cats scattered across its residential wings, parking lots and green areas. Independent rescuers know each animal by nickname, by street, by habit. But that knowledge lives in WhatsApp groups, in individual memory, nowhere persistent.

The friend who inspired this app has been feeding a colony of cats near the Asa Norte commercial strip for years. She knows exactly which ones have been neutered, which ones have a history of injury, which one vanished last month. But when someone new wants to help β€” or when she needs backing to request food donations β€” there's nothing to show. No map, no timeline, no proof that a specific animal has been living on that block for two years.

**PawMap is that record.** Anyone takes a photo of a stray animal with their phone. The AI identifies it, GPS pins the location, and the app checks whether that animal has been seen before β€” linking all sightings to its profile. The map is public. The animal's trail becomes visible. Anyone who wants to help knows exactly where to go.

---

## How it works

There are two AI-powered flows: **registering a sighting** and **recording help**.

### Sighting flow

```mermaid
flowchart TD
    A["πŸ“· Photo from phone"] --> B["πŸ€– Vision AI\nLlama-3.2-11B-Vision\n(NVIDIA NIM / HF)"]
    B -->|"is it an animal?"| C{Animal detected?}
    C -->|"No"| ERR["❌ Error message\n'No dog or cat identified'"]
    C -->|"Yes"| D["πŸ“ Structured JSON\nNemotron Mini 4B Instruct structures\nspecies Β· breed Β· color Β· condition Β· marks"]
    D --> E["πŸ”’ Semantic embedding\nall-MiniLM-L6-v2 Β· 384 dim\n(local, 22M params)"]
    E --> F{Cosine similarity\nβ‰₯ 0.80?}
    F -->|"Yes β€” known animal"| G["βž• New sighting\nadded to existing animal"]
    F -->|"No β€” new animal"| H["πŸ†• New animal\nregistered in the database"]
    G --> I["πŸ’Ύ SQLite"]
    H --> I
    I --> J["πŸ—ΊοΈ Leaflet map\nprofiles Β· trail Β· gallery"]
```

Before confirming, the user sees the top 3 most similar animals already in the database β€” they can edit what the AI detected, give the animal a name, and note its condition. Only then is the sighting saved.

### Help flow

When someone wants to help an animal, they can submit a **help proof** β€” a photo showing they fed it, treated a wound, or got it to a vet. The AI does two things with that photo:

```mermaid
flowchart TD
    A["πŸ“· Help proof photo\n(optional)"] --> B["πŸ€– Vision AI\nanalyzes the new photo"]
    B --> C["πŸ”’ New embedding\ngenerated from description"]
    C --> D{Cosine similarity\nagainst registered animal?}
    D -->|"Match β‰₯ 0.80\nsame animal ID"| E["βœ… AI-verified\nmatch score shown"]
    D -->|"No match"| F["⚠️ Unverified\nstill recorded"]
    B --> G{Condition improved?}
    G -->|"e.g. injured β†’ healthy"| H["πŸ“ˆ Condition update\nlogged on profile"]
    G -->|"same or worse"| I["No change"]
    E --> J["πŸ’Ύ Help event saved\nto sightings table"]
    F --> J
    H --> J
    I --> J
```

The profile page shows the full help history with photos, help type (fed / treated / rescued / other), AI verification status and any detected condition improvement.

The map uses color to signal urgency: **🟒 green** = dog Β· **🟠 orange** = cat Β· **πŸ”΄ red** = not seen in +30 days.

---

## What's inside

| Component | Model / Library | Where it runs |
|---|---|---|
| Visual identification | **Llama-3.2-11B-Vision-Instruct** (11B) via NVIDIA NIM (or HF Serverless) | remote API |
| Text reasoning / JSON | **Nemotron Mini 4B Instruct** via NVIDIA NIM | remote API |
| Semantic embedding | **all-MiniLM-L6-v2** (384 dim, 22M params) | CPU, local |
| Animal matching | Cosine similarity (threshold 0.80) | CPU, local |
| Database | SQLite | local / persistent |
| Frontend | SPA via `gradio.Server` + Leaflet.js + Lucide Icons | browser |

**Total parameters running locally: ~22M** (MiniLM). The vision and reasoning models run via serverless API β€” nothing heavy on the Space machine. **Every model used is well under the 32B hackathon cap:** Llama-3.2-11B-Vision (11B), Nemotron Mini 4B Instruct (4B) and MiniLM-L6-v2 (22M).

---

## Screens

| Screen | Description |
|---|---|
| πŸ—ΊοΈ **Map** | Color-coded pins by species/urgency, floating card with "View profile" |
| πŸ“· **Register** | Photo upload + automatic GPS + AI analysis |
| πŸ€– **Analysis** | Auto-identification with editable fields + top 3 similar animals |
| βœ… **Confirm** | Sighting summary before saving |
| πŸ‘οΈ **Spotted** | List of all registered animals |
| 🐾 **Profile** | Full animal card with gallery, map trail and help history |

---

## Badges

This submission earns the following hackathon bonus quests:

- 🎨 **Off-Brand** β€” Fully custom interface via `gradio.Server`, no default Gradio components visible. SPA frontend with Leaflet.js for the map, Lucide Icons, and custom design.
- πŸ“‘ **Sharing is Caring** β€” Full traces of every sighting (photo β†’ AI analysis β†’ embedding β†’ matching result) are automatically published as a dataset on the Hub via `/admin/push-traces`.
- 🀏 **Tiny Titan** β€” The only on-device model is `all-MiniLM-L6-v2` (22M params, far under 4B): all animal matching runs locally on a tiny embedding model.
- 🟩 **NVIDIA / Nemotron** β€” Structured identification is normalized by `Nemotron-Mini-4B-Instruct` via NVIDIA NIM β€” small (4B), well under the 32B cap.

---

## Running locally

```bash
git clone https://huggingface.co/spaces/build-small-hackathon/viralata-mapper
cd viralata-mapper
pip install -r requirements.txt

# Recommended: NVIDIA NIM powers both vision (Llama-3.2-11B-Vision) and Nemotron Mini 4B
NVIDIA_API_KEY=nvapi_... python app.py

# Alternative: vision via HuggingFace Serverless
HF_TOKEN=hf_... python app.py

# no key β€” runs in fallback mode without AI identification
python app.py

# open http://localhost:7860
```

On first run the app seeds the database with demo animals around BrasΓ­lia so the map isn't empty.

---

## Space configuration

### Secrets

| Secret | Description |
|---|---|
| `NVIDIA_API_KEY` | NVIDIA NIM key β€” powers **both** vision (Llama-3.2-11B-Vision) and Nemotron Mini 4B normalization. A single key is enough. |
| `HF_TOKEN` | Optional β€” vision via HF Serverless if you don't use NVIDIA NIM |
| `MATCH_THRESHOLD` | Optional. Similarity threshold. Default: `0.80` |
| `HF_DATASET_ID` | Optional. Hub dataset for trace publishing (e.g. `org/dataset-name`) |

> Without a Vision AI key the app runs in fallback mode β€” registration and matching still work, but automatic breed/color/condition identification is disabled.

### Persistent Storage

Set up a **Persistent Storage Bucket** in the Space and mount it at `/data/` so photos and the database survive restarts. Without it, all data is wiped on each deploy.

---

## Repository structure

```
.
β”œβ”€β”€ app.py                  # Entrypoint β€” FastAPI routes + Gradio Server
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ index.html              # SPA frontend
β”œβ”€β”€ static/
β”‚   β”œβ”€β”€ app.js              # Client logic (map, camera, registration flow)
β”‚   β”œβ”€β”€ style.css
β”‚   └── lottie/             # Loading animations
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ ai.py               # Vision AI (HF or NVIDIA NIM) + embeddings
β”‚   β”œβ”€β”€ database.py         # SQLite β€” animals and sightings
β”‚   β”œβ”€β”€ matcher.py          # Cosine similarity for animal matching
β”‚   β”œβ”€β”€ seed.py             # Demo data for the initial map (BrasΓ­lia, DF)
β”‚   └── tracer.py           # Trace logging + push to HF Hub
β”œβ”€β”€ db/
β”‚   └── schema.sql          # Database schema
└── data/                   # Runtime β€” SQLite database + photos + traces
    β”œβ”€β”€ viralata.db
    β”œβ”€β”€ photos/
    └── traces.jsonl
```

---

## Limitations

- **Vision AI via API** β€” breed identification requires `HF_TOKEN` or `NVIDIA_API_KEY`. Without a key, registrations use generic data (breed "SRD / Domestic Shorthair").
- **GPS on mobile** β€” accuracy depends on the device. Indoors or with weak signal, coordinates may be imprecise.
- **Matching is not foolproof** β€” the 0.80 threshold is conservative to avoid false positives, but two very similar animals (e.g. two caramel SRDs) may get grouped together. The user reviews the candidates before confirming and can correct.
- **Portuguese / English only** β€” the interface is in Portuguese; the AI generates descriptions in English for embedding consistency.

---

## Credits

- **[Meta](https://ai.meta.com/llama/)** β€” Llama 3.2 11B Vision Instruct (Llama 3.2 Community License).
- **[NVIDIA](https://build.nvidia.com/)** β€” Nemotron Mini 4B Instruct via NVIDIA NIM.
- **[Hugging Face](https://huggingface.co/)** β€” `sentence-transformers/all-MiniLM-L6-v2`, Serverless Inference, Space hosting.
- **[Leaflet.js](https://leafletjs.com/)** β€” interactive map.
- **[Gradio](https://gradio.app/)** β€” `gradio.Server` for the custom frontend.
- **[Lucide Icons](https://lucide.dev/)** β€” UI icons.

---

## License

MIT for the application code. Models follow their own licenses β€” see the Meta (Llama 3.2) and NVIDIA (Nemotron Mini 4B Instruct) model cards for full terms.

---

*Built for BrasΓ­lia, DF β€” capital of Brazil β€” and any city that wants to map its stray animals.* 🐾