GigScan — Fine-tuned MiniCPM-V 4.6 for Gig Poster Extraction
GigScan is a fine-tuned version of
MiniCPM-V 4.6 trained to extract structured event information from live music gig posters.
Point your phone at a gig poster pinned to a wall, and this model returns structured JSON with the event name, venue, date, start time, and a short description — ready to turn into a calendar invite.
Built for the Build Small Hackathon (June 2026), GigScan competes in the Backyard AI track.
Model description
- Base model:
openbmb/MiniCPM-V-4.6 (1.3B parameters, multimodal vision-language)
- Fine-tuning method: LoRA (all linear layers) via LLaMA-Factory
- Training data: 276 labeled gig poster images + 110 non-poster negatives
- Format: Q4_K_M quantized GGUF for local CPU/GPU inference with llama.cpp
Intended use
GigScan is designed to be deployed in a mobile-friendly web app where users photograph gig posters and receive structured event data. The intended output is:
1{
2 "is_live_music_poster": true,
3 "event_name": "The Chats",
4 "venue": "The Tote",
5 "date": "06-06",
6 "time_start": "20:00",
7 "description": "Live at The Tote with Leatherman. Tickets $20."
8}
Non-poster images return:
1{
2 "is_live_music_poster": false,
3 "event_name": "",
4 "venue": null,
5 "date": null,
6 "time_start": null,
7 "description": ""
8}
Performance
Evaluated on a held-out test set of 70 images (47 positives, 23 negatives):
| Metric | Base Model | Fine-tuned |
|---|
| Valid JSON output | 92.9% | 100% |
| All fields present | 92.9% | 100% |
| Date format (DD-MM) | 34.3% | 100% |
| Time format (HH:MM) | 81.4% | 100% |
| Poster detection accuracy | 78.6% | 100% |
| Hallucination on negatives | Yes | None |
The fine-tuned model eliminated date formatting errors, poster misclassification, and hallucinated events on non-poster images entirely on the test set.
Training procedure
Training data
The dataset consists of 386 labeled images:
- Positives (276): Scraped gig posters from Instagram and other sources, labeled automatically by GPT-5-nano with the target JSON schema, then manually reviewed.
- Negatives (110): Non-poster images sampled from Food101 and Places365 datasets.
The dataset is available at
kieranadair/gigscan-training.
Training configuration
| Parameter | Value |
|---|
| Framework | LLaMA-Factory |
| Method | LoRA (all linear layers) |
| Epochs | 3 |
| Batch size (effective) | 8 |
| Learning rate | 5e-5 |
| Warmup | 10% of total steps |
| Precision | BF16 |
| GPU | NVIDIA A10G (24 GB) |
| Training time | ~45 minutes |
Conversion to GGUF
The merged LoRA model was converted to GGUF using llama.cpp's convert_hf_to_gguf.py (release b9049+) then quantized to Q4_K_M:
1python convert_hf_to_gguf.py /merged-model --outfile gigscan-f16.gguf --outtype f16
2python convert_hf_to_gguf.py /merged-model --mmproj --outfile mmproj-gigscan-f16.gguf
3./llama-quantize gigscan-f16.gguf gigscan-q4_k_m.gguf Q4_K_M
The vision projector (mmproj) is kept at F16 precision. The language model is quantized to approximately 900 MB.
How to use
With llama.cpp server
1./llama-server \
2 -m gigscan-q4_k_m.gguf \
3 --mmproj mmproj-gigscan-f16.gguf \
4 -c 4096 \
5 -ngl 999 \
6 --reasoning-budget 0 \
7 --host 127.0.0.1 \
8 --port 8080
Then send requests to http://127.0.0.1:8080/v1/chat/completions:
1import requests
2
3response = requests.post("http://127.0.0.1:8080/v1/chat/completions", json={
4 "model": "gigscan-minicpm-v",
5 "temperature": 0,
6 "max_tokens": 300,
7 "messages": [
8 {"role": "system", "content": "Return only the answer."},
9 {"role": "user", "content": [
10 {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}},
11 {"type": "text", "text": "Extract gig poster details. Return JSON."}
12 ]}
13 ]
14})
15
16print(response.json()["choices"][0]["message"]["content"])
Recommended prompt
For best results, use a prompt that explicitly lists the expected keys and allows null for missing fields. The fine-tuned model was trained on "Extract gig poster details from this image." but benefits from a more detailed prompt at inference time that specifies the JSON contract and null behavior.
Limitations
- Poster format: Trained primarily on clean digital poster images. Performance may degrade on blurry, angled, or poorly lit real-world photos.
- Single event assumption: Designed for single-event posters. Multi-date tour posters or festival lineups may produce unreliable results.
- Language: Training data is English-language posters only.
- Date inference: The model returns
DD-MM format. Year inference is handled by application logic, not the model.
- Venue and time extraction: Can be conservative — missing venue or time is returned as
null rather than guessed. This is intentional.
Deployment
GigScan is deployed as a Hugging Face Space at
kieranadair/gigscan. The Space runs the quantized model locally via llama.cpp server on a T4 GPU.
Acknowledgements
- Built with MiniCPM-V 4.6 by OpenBMB
- Fine-tuned with LLaMA-Factory
- Inference powered by llama.cpp
- Training infrastructure provided by Modal
- Built for the Build Small Hackathon