Skip to content
ImageomicsPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Bio-VQA

How Finely Can Vision–Language Models See Biology?
Bio-VQA: A Benchmark for Taxonomic, Morphological, Spatial and Individual Reasoning

S M Rayeed · Qian Ma · Charles V. Stewart · Yao Ma

Project page Dataset Lite Paper Code license

Questions Images Datasets Groups Tasks Models Params Python

🌐 Project page  |  🤗 HF Dataset  |  💻 Github Repo  |  📄 Paper: WACV 2027 (link will be added here)


News

  • 2026-11 — Camera-ready version for WACV 2027. This README, the numbers in every component README and the environment notes are updated to match the camera-ready paper.
  • 2026-11 — The full benchmark, Bio-VQA-Lite (500 questions per task, 12,000 in total), and the per-item answers of all 18 models are public on Hugging Face: imageomics/Bio-VQA.

Overview

In biodiversity monitoring, a single image raises several questions: which taxon, how many, which trait, and whether this individual has been seen before. In practice each is answered by its own specialist model, or by a field expert. Bio-VQA asks whether one generalist vision–language model (VLM) can answer all four.

Bio-VQA holds 1,861,608 questions over 216,715 images from 11 public datasets, organized into four components and 24 tasks. Every question is generated only where an existing annotation supplies the ground truth, so every answer can be checked against its source. Every task is bounded by an image-blind floor and, where one exists, by a domain-specialist ceiling. Scoring is graded, so a near miss counts for more than a distant one, and each graded score is reported next to the exact match it modifies.

Component What it asks Tasks Images Questions Source Code
C1 Hierarchical taxonomic reasoning Which taxon, at eight ranks? 9 100,000 890,000 TreeOfLife-200M 1.Hierarchical_taxonomic_reasoning/
C2 Fine-grained attribute grounding Which trait, on which part, on which side? 4 23,576 824,104 CUB-200-2011 2.Fine-grained_attribute_grounding/
C3 Quantitative spatial reasoning How many, how far, where, facing where? 8 78,139 132,504 8 datasets 3.Quantitative_spatial_reasoning/
C4 Individual re-identification Is this the same animal? 3 15,000 15,000 5 wildlife catalogs 4.Individual_reidentification/
Total 24 216,715 1,861,608 11 datasets

C3 draws on WAID, Boxes on Bees, 2018-NEON-Beetles and DePondFi, and also on four of the C4 catalogs (WhaleSharkID, HyenaID, LeopardID, GZCD) for localization and viewpoint. That is why the component sources add up to more than 11.

Where to find what

You want to… Go to
See figures, examples and the leaderboard 🌐 Project page
Download the questions, images, Lite subset or model answers 🤗 Hugging Face dataset card
Regenerate the questions, run a model, or score a model 💻 This repository (Pipeline, Quick start)
Read the method and full analysis 📄 The paper (Citation)

Table of Contents


Quick start

1. Evaluate a model on Bio-VQA-Lite (recommended first step)

Bio-VQA-Lite is a stratified sample of 500 questions per task, 12,000 in total. It is drawn with a fixed seed and is meant for cheap evaluation and for development. Details are on the dataset card.

from datasets import load_dataset

lite = load_dataset("imageomics/Bio-VQA", "lite")   # C1.csv, C2.csv, C3.csv, C4.csv
print(lite)
# Read one image that is stored inside a zip shard (C2 marker renders, C3, C4)
import io, zipfile
from huggingface_hub import hf_hub_download
from PIL import Image

def load_image(component, image_zip, image_in_zip):
    path = hf_hub_download("imageomics/Bio-VQA", f"{component}/{image_zip}", repo_type="dataset")
    with zipfile.ZipFile(path) as z:
        return Image.open(io.BytesIO(z.read(image_in_zip))).convert("RGB")

C1 images come from TreeOfLife-200M and C2 photographs come from CUB-200-2011. Neither is re-hosted. See Images on the dataset card, and Release/fetch_c1_images.py for C1.

2. Score your own model with the Bio-VQA scorers

Every scorer in this repository reads a question file that has one extra column named <model>_answer. That column holds your model's raw, unparsed reply. Parsing and normalization happen inside the scorer, and they are the same for every model.

# 1) append a column  <mymodel>_answer  to the component question file(s)
# 2) run that component's scorer
python 1.Hierarchical_taxonomic_reasoning/Evaluation/Evaluate_build_synonyms.py ...   # once, before C1 scoring
python 1.Hierarchical_taxonomic_reasoning/Evaluation/Evaluate_run.py --base_dir <dir with C1 csvs> --parquet <ToL catalog> --synonyms <synonym map>
python 2.Fine-grained_attribute_grounding/Evaluation/evaluate.py --base_dir <dir with C2 csvs>
python 3.Quantitative_spatial_reasoning/Reasoning_Tasks/<Task>/3.Evaluate/evaluate.py --results_dir <dir>
python 4.Individual_reidentification/Evaluation/Evaluate.py --base_dir <C4 root>

Each Evaluation/ or 3.Evaluate/ folder has a README with every flag spelled out. C1 note: build the synonym map first. Without it, soft match silently falls back to hard match and no error is raised.

3. Re-run the 18 models from the paper

Each component has one runner script per model (Runs/, Experiment-Runs/, 2.Experiment_Runs/, Experiment_Runs/). The launch commands are written out in each runner folder's README. See Pipeline and Environment.

4. Use the paper's answers without re-running anything

The predictions/ folder on Hugging Face holds the per-item answers of all 18 models and both specialists, exactly as scored in the paper. Point a scorer at those files to regenerate any table.


The data at a glance

This is a short summary. The dataset card has the full description, file layout, column reference and licensing.

Component Task Format Questions Ground truth from
C1 phylum · class · order · family · genus · species epithet · scientific name · common name open-ended 790,000 TreeOfLife-200M lineage (GBIF Backbone)
C1 common name, 4-way multiple choice MCQ 100,000 same image and target as the open-ended common name
C2 morphological attributes (attr_bare_value) MCQ 280,433 CUB-200-2011 attributes
C2 relative salience (attr_group_value) MCQ 321,073 CUB-200-2011 attributes
C2 anatomical localization (marker_localization, visibility_partset, visibility_side) MCQ 165,032 CUB part locations, rendered markers
C2 naming (category_mcq, open_common_name, open_scientific_name, open_genus, open_kind_of) MCQ + open 57,566 CUB class labels
C3 counting integer 53,498 instance annotations, all ten subsets
C3 relative counting 1 of 4 panels 42,412 instance annotations, all ten subsets
C3 absolute distance number (cm) 14,108 NEON beetle trait + scalebar measurements
C3 relative distance 1 of 4 specimens 3,976 NEON beetle trait measurements
C3 localization 4 integers (box) 3,988 wildlife-catalog bounding boxes
C3 relative position direction 1,000 NEON beetle tray layout
C3 viewpoint 1 of 10 orientations 13,000 wildlife-catalog viewpoint labels
C3 OCR (negative control) string 522 NEON barcode labels
C4 easy · random · hard pairing, 5 species Yes / No 15,000 catalog individual IDs

C1 asks the reptiles group seven rank questions, not eight, because GBIF has no order rank for Squamata. So that group contributes 8 question types instead of 9.


Repository layout

Bio-VQA/
├── README.md                                  ← you are here
├── requirements.txt                           ← shared environment (see "Environment")
├── LICENSE                                    ← MIT, code only
│
├── 1.Hierarchical_taxonomic_reasoning/        ← C1
│   ├── README.md
│   ├── Tree-of-Life-200M/                     ← data: download.py · verify.py · generateQA.py · stat.py
│   │   └── Resolve_common_names/              ← non-English common names → English (iNaturalist, Wikidata)
│   ├── Runs/                                  ← 18 runners: run_<model>.py
│   ├── Post-run/                              ← Merge_csv_chunks.py · Fix_Llama_Answers.py · Assign_difficulty/
│   └── Evaluation/                            ← Evaluate_build_synonyms.py · Evaluate_check_synonyms.py · Evaluate_run.py
│                                                 run_pyBioCLIP.py · prefetch_pybioclip.py  (BioCLIP-2 ceiling)
│
├── 2.Fine-grained_attribute_grounding/        ← C2
│   ├── README.md
│   ├── Data-Preparation/                      ← 1.preprocess.py · 2.prepareQA.py · 3.stat.py · taxon_name_mapping.json
│   ├── Experiment-Runs/                       ← per-family runners: run_qwen.py · run_InternVL.py · run_gemma.py · …
│   └── Evaluation/                            ← evaluate.py (CAGS) · evaluate_soft.py · sensitivity_sweep.py
│       └── Human Study/                       ← 306-item, 3-annotator validation of CAGS
│
├── 3.Quantitative_spatial_reasoning/          ← C3
│   ├── README.md
│   ├── Datasets/                              ← Aerial/ (WAID) · Bees/ · Beetles/ · Fish/ (DePondFi) · Zebra/ (GZCD)
│   └── Reasoning_Tasks/
│       ├── Counting/          ├── Counting_Relative/   ├── Distance_Absolute/   ├── Distance_Relative/
│       ├── Localization/      ├── Relative_Position/   ├── Viewpoint/           └── OCR/
│       └── <task>/  1.Generate_QA/  →  2.Experiment_Runs/ (Preprocess/ + 18 runners)  →  3.Evaluate/
│
├── 4.Individual_reidentification/             ← C4
│   ├── README.md
│   ├── Data_Preparation/                      ← download.py · extract_embeddings.py (DINOv2) · generate_QA.py
│   ├── Experiment_Runs/                       ← 18 VLM runners + megadescriptor.py (specialist)
│   └── Evaluation/                            ← Evaluate.py (accuracy, d′, c, bootstrap CIs)
│
└── Release/                                   ← how the Hugging Face release was built
    ├── README.md
    ├── make_lite.py                           ← Bio-VQA-Lite (500 per task, seeded, stratified)
    ├── pack_images.py                         ← images → zip shards + image_zip / image_in_zip columns
    └── fetch_c1_images.py                     ← fetch C1 images from TreeOfLife-200M source URLs

Each component folder and most subfolders have their own README with construction details, every command, and results. No shell scripts are committed; every launch command is written out in a README.


Pipeline

Stage overview

 public dataset ──► 1. acquire & filter ──► 2. generate QA ──► 3. preprocess / shard ──► 4. inference (18 VLMs + specialist)
 (annotations)        (download, verify,      (seeded; only      (manifest, row_id,         (greedy, one attempt,
                       resolve names)          where GT exists)   pre-run audit)             raw string stored)
                                                                                                  │
                    6. tables & figures ◄── 5. score (one scorer per component; floors, graded metrics, CIs) ◄┘

Every component follows these six stages. The folder names differ a little between components (shown below), but what each stage does is the same.

Stage C1 C2 C3 (per task) C4
1 Acquire Tree-of-Life-200M/download.py, verify.py, Resolve_common_names/ CUB-200-2011 official release Datasets/<corpus>/download.py, preprocess.py Data_Preparation/download.py
2 Generate QA Tree-of-Life-200M/generateQA.py Data-Preparation/1.preprocess.py → 2.prepareQA.py 1.Generate_QA/generateQA*.py extract_embeddings.py → generate_QA.py
3 Preprocess chunked manifests — 2.Experiment_Runs/Preprocess/split_qa.py, stats.py —
4 Inference Runs/run_<model>.py Experiment-Runs/run_<family>.py 2.Experiment_Runs/<model>.py Experiment_Runs/<model>.py, megadescriptor.py
4b Specialist Evaluation/run_pyBioCLIP.py (BioCLIP-2: tol · kingdom · group) 3-annotator human study image-blind floors (in the scorer) Experiment_Runs/megadescriptor.py
5 Post-run Post-run/Merge_csv_chunks.py, Fix_Llama_Answers.py, Assign_difficulty/ run_llama3.2_fix_answers.py 3.Evaluate/merge_results.py —
6 Score Evaluation/Evaluate_build_synonyms.py → Evaluate_run.py Evaluation/evaluate.py, sensitivity_sweep.py 3.Evaluate/evaluate.py Evaluation/Evaluate.py

C1 — Hierarchical taxonomic reasoning

📁 1.Hierarchical_taxonomic_reasoning/  ·  🤗 config C1_taxonomy

  1. Sample. download.py runs DuckDB queries over the TreeOfLife-200M catalog. It takes 10,000 images from each of 10 organismal groups (amphibians, angiosperms, arachnids, birds, bryophytes, fish, gymnosperms, insects, mammals, reptiles). Three constraints apply: (a) the lineage must be complete from phylum to species, with a common name; (b) the image must meet a minimum resolution (--min_size_kb); (c) there is a per-species cap (--images_per_species), so abundant species do not take over a group. The sample spans 626 families, 2,311 genera and 3,403 species — 6× VLM4Bio's genus coverage and 4× its species coverage.
  2. Verify. verify.py checks that a manifest row exists if and only if its image is on disk and every rank the generator needs is non-null.
  3. Resolve names. GBIF vernacular names are not filtered by language. They include Swedish, Danish and Norwegian names. Resolve_common_names/ resolves every non-English common name to English against iNaturalist and Wikidata.
  4. Generate QA. generateQA.py asks each image for its phylum, class, order, family, genus, species epithet, scientific name and common name. It also asks the common name a second time as 4-way multiple choice, with distractors drawn uniformly from taxa in the same class as the target.
  5. Run. There are 18 runners in Runs/. The BioCLIP-2 ceiling is Evaluation/run_pyBioCLIP.py, in three label-set configurations: tol (the full TreeOfLife-200M label set, used in the paper's main table), kingdom and group.
  6. Post-run. Merge chunks, repair Llama-3.2 answer formatting, and assign Easy / Medium / Hard tiers by how common the target taxon is in TreeOfLife-200M (top third, middle third and bottom third by image count at each rank).
  7. Score. Exact match, soft exact match (any GBIF Backbone synonym of the target counts as correct, so Felis concolor = Puma concolor), Wu–Palmer, Lin similarity, and error severity.

C2 — Fine-grained attribute grounding

📁 2.Fine-grained_attribute_grounding/  ·  🤗 config C2_attributes

  1. Invert the attributes. CUB-200-2011 stores 312 binary attributes per image as part · property · value (has_wing_color::brown). Asking 312 sparse yes/no questions per image would be uninformative, since a constant no scores well. So 1.preprocess.py and 2.prepareQA.py merge each part and property into one question (What is the wing color?) and take the marked value as the answer. Annotator certainty is used to select and filter candidate traits.
  2. Distractors. These are other values attested for the same part and property. Any value that is also true of the image is excluded, so exactly one option is correct.
  3. Marker localization. A marker is rendered onto each of the 11,788 images, and the question asks which body part it marks. Two controlled distractors are added: one shares the marker's color but not its shape, the other shares its shape but not its color. The model has to bind both cues to answer. The renders double the image count to 23,576.
  4. Ten question families in four categories. See the data at a glance.
  5. Score. CAGS (chance-adjusted graded score), using CIEDE2000 color distance for colors and annotation co-occurrence for parts. It is 0 at chance and 1 at perfect for any number of options. sensitivity_sweep.py reruns the ranking under 11 kernel and hyperparameter settings. Human Study/ holds the 306-item, 3-annotator validation.

C3 — Quantitative spatial reasoning

📁 3.Quantitative_spatial_reasoning/  ·  🤗 config C3_spatial

The tasks follow AVA-Bench's decomposition of spatial reasoning into atomic skills, so a failure can be traced to a specific ability. The source datasets are aggregated into ten 500-image subsets. These are count-stratified, so sparse and dense scenes are balanced, and images whose annotation completeness cannot be verified are dropped. Each task runs only where its ground truth exists:

Task Folder Runs on Answer form Metric Floor (image-blind)
Counting Reasoning_Tasks/Counting/ all ten subsets; Easy / Medium / Hard canvas tiers integer CAS, macro-averaged over subsets modal count
Relative counting Reasoning_Tasks/Counting_Relative/ all ten subsets; same- and different-dataset panels 1 of 4 balanced accuracy chance
Absolute distance Reasoning_Tasks/Distance_Absolute/ NEON beetles (scalebar) cm share within 20% one constant per measurement type
Relative distance Reasoning_Tasks/Distance_Relative/ NEON beetles 1 of 4 balanced accuracy chance
Localization Reasoning_Tasks/Localization/ wildlife catalogs (Easy tier) box mean IoU (unparsed = 0) mean gold box
Relative position Reasoning_Tasks/Relative_Position/ NEON beetle trays direction balanced accuracy chance (.250)
Viewpoint Reasoning_Tasks/Viewpoint/ wildlife catalogs 1 of 10 agreement over gold labels majority class
OCR (control) Reasoning_Tasks/OCR/ NEON barcode labels string exact match —

Every task folder has the same three stages: 1.Generate_QA/ → 2.Experiment_Runs/ (with Preprocess/split_qa.py and the 18 runners) → 3.Evaluate/ (merge_results.py, evaluate.py). Within each task, the block marked # HARNESS is byte-identical across the 18 runners. You can check this:

cd 3.Quantitative_spatial_reasoning/Reasoning_Tasks/Counting/2.Experiment_Runs
for f in *.py; do sed -n '/^# HARNESS/,$p' "$f" | md5sum; done | sort -u | wc -l     # prints 1

Counting tiers. Every counting canvas has the same pixel budget. Easy fills the canvas with one image. Medium splits it into two panels from different datasets. Hard splits it into two panels from the same dataset. OCR is a designed negative control: locating the label is spatial, but the answer depends on transcription.

C4 — Individual re-identification

📁 4.Individual_reidentification/  ·  🤗 config C4_reidentification

  1. Catalogs. WhaleSharkID (spot pattern), BelugaID (scarring, dorsal ridge), HyenaID (spot pattern), LeopardID (rosettes) and GZCD Grevy's zebra (stripes).
  2. Embed. extract_embeddings.py computes DINOv2 embeddings. Retrieval runs within viewpoint groups, because viewpoint dominates the embedding space.
  3. Pair (generate_QA.py, seeded). Each catalog gives 1,000 balanced pairs per condition (500 same and 500 different), and same-individual pairs are drawn first because they are scarce.
    • Easy: a same pair is an animal with its nearest match; a different pair is two animals that look nothing alike. Appearance and identity agree.
    • Random: both pairs are drawn without using appearance, so appearance carries no signal.
    • Hard (adversarial): a different pair is two nearest neighbors; a same pair is an animal with its furthest sighting. Appearance and identity disagree.
  4. Ask. The two photographs are placed side by side on one canvas, and the question is: "This image shows two images placed side by side. Is the main subject in the left image the very same individual animal as the main subject in the right image?" The runner adds "Answer with one word: Yes or No. Do not explain." The prompt never reveals that the set is balanced.
  5. Specialist. megadescriptor.py runs MegaDescriptor on Grevy's zebra.
  6. Score. Evaluate.py reports accuracy and d′ / criterion c from signal detection theory, with a log-linear correction, plus 95% bootstrap CIs (2,000 resamples per cell), balanced accuracy, MCC and Cohen's κ.

Release tooling (Hugging Face and Lite)

📁 Release/ — the scripts that built the Hugging Face release:

Script What it does
make_lite.py Builds Bio-VQA-Lite: 500 questions per task (24 tasks, 12,000 total). Strata: organismal group (C1), question family (C2), source dataset × tier × subset (C3), species × answer (C4). Seeded; model-answer columns are dropped.
pack_images.py Packs the images a question file refers to into zip shards, and adds image_zip / image_in_zip columns. With --rename, C4 images get neutral names (img_000001.png, …), because the original names encode the label.
fetch_c1_images.py Downloads the C1 images from the TreeOfLife-200M source_url of each row and saves them as <uuid>.<ext>.

Environment

All 18 models run in one shared Python 3.12 environment (requirements.txt). The one exception is Molmo2-8B: AI2 ships Molmo2 as custom code pinned to transformers==4.57.1, so it has its own environment.

# shared environment (17 models, data preparation, scoring)
python3.12 -m venv bio-vqa && source bio-vqa/bin/activate
pip install -r requirements.txt

# Molmo2-8B only
python3.12 -m venv bio-vqa-molmo2 && source bio-vqa-molmo2/bin/activate
pip install -r requirements.txt "transformers==4.57.1"

Hardware. C1 image download is network- and I/O-bound, so use CPU nodes. Inference needs one H100-class GPU per job; the 30B–38B models need two. Some runner READMEs show SLURM launch lines that build a per-job virtual environment in $TMPDIR. That is a scheduling convenience; it installs the same packages.

The exact checkpoint of each model is listed in the supplementary material (Table S2) and in each runner's MODEL BLOCK. Examples: Qwen/Qwen3-VL-32B-Instruct, OpenGVLab/InternVL3-38B-Instruct, google/gemma-3-12b-it, allenai/Molmo2-8B, mistral-community/pixtral-12b, microsoft/Phi-3.5-vision-instruct, meta-llama/Llama-3.2-11B-Vision-Instruct, llava-hf/llava-v1.6-vicuna-7b-hf, llava-hf/llava-v1.6-mistral-7b-hf.


Evaluation protocol

Setting Value
Decoding greedy (do_sample=False)
Attempts per item one
Chain-of-thought / reasoning mode none
Few-shot demonstrations none
Question and answer-format instruction the same for every model within a question family
Example answer in the format instruction yes for C1 and for six of the eight C3 tasks (counting, absolute distance, localization, relative position, viewpoint, OCR) — e.g. "e.g., Arthropoda", "If you count seven, respond: 7". The exact strings are in the supplement, §S10.
Model-specific wrapping each model's own chat template; Gemma receives the instruction as a system message; InternVL adds an English-answer prefix
Scoring one scorer per component, the same for every model
Reported alongside parse rate and letter–text mismatch rate, so a formatting failure is never read as a knowledge error

The 18 models span 3.75B–38.4B parameters across eleven families: Qwen2.5-VL (3B, 7B), Qwen3-VL (8B, 30B-A3B MoE, 32B), InternVL3 (8B, 38B), InternVL3.5 (8B, 30B-A3B MoE, 38B), Gemma-3-12B, Gemma-4-12B, Molmo2-8B, Pixtral-12B, Phi-3.5-Vision, Llama-3.2-11B-Vision, and LLaVA-NeXT (Vicuna-7B, Mistral-7B).

Specialists. BioCLIP-2 for C1, which is trained on TreeOfLife-200M and ranks a closed label set, so treat it as an optimistic upper bound. MegaDescriptor for C4, on Grevy's zebra.


Metrics

Exact match is reported for every task. Every graded metric is reported next to the exact match it modifies, so no claim rests on the graded score alone.

Component Graded metric What it fixes
C1 Wu–Palmer, Lin, soft EM (synonyms), severity On a warbler, Turdidae is a near miss and Fungi is wrong by far; exact match scores them the same.
C2 CAGS: $\frac{\mathbb{E}[s(\hat y,y)]-\mathbb{E}_0[s]}{1-\mathbb{E}_0[s]}$ Answer spaces have structure (red is closer to brown than green is) and uneven size (3 options for bill length, 15 for color).
C3 CAS: $\max(0,,1-\lvert\hat n-n\rvert/n)$; lift $\frac{S-\phi}{1-\phi}$ over the image-blind floor $\phi$ 14 beetles for 15 beats 20 for 15; and a score means nothing without knowing what a blind guess gets.
C4 d′ $= z(H)-z(F)$ and criterion $c=-\tfrac12[z(H)+z(F)]$ A model answering yes to everything scores 50% accuracy.

A lift of 0 means the model does no better than an image-blind rule; negative lift means it does worse. Two C3 tasks (localization and absolute distance) have field means below their floors.


Results

Full results table

18 models × 24 tasks (Table 2 of the paper). Bold marks the best of the 18 models in each column.

# Model phy cls ord fam gen spc sci com sal mrp loc nam cnt rcnt adst rdst lcl rpos view ocr d′ acc
BioCLIP-2 (tol) ¹ .925 .874 .821 .775 .691 .545 .544 .500 — — — — — — — — — — — — — —
MegaDescriptor ² — — — — — — — — — — — — — — — — — — — — .733 .683
1 Qwen3-VL-32B .831 .615 .712 .612 .444 .066 .244 .078 .584 .644 .475 .731 .789 .555 .622 .443 .866 .550 .427 .900 .696 .636
2 Qwen3-VL-30B-A3B .864 .731 .757 .612 .417 .072 .221 .107 .558 .631 .453 .658 .795 .483 .528 .423 .861 .355 .391 .979 .518 .602
3 InternVL3-38B .911 .683 .638 .484 .355 .054 .189 .044 .562 .645 .413 .669 .799 .567 .367 .363 .744 .205 .373 .105 .463 .581
4 Gemma-4-12B .880 .686 .578 .363 .183 .021 .065 .043 .592 .621 .431 .374 .753 .563 .385 .443 .589 .495 .331 .345 .351 .567
5 Qwen3-VL-8B .887 .680 .720 .589 .406 .046 .202 .065 .531 .624 .441 .643 .739 .414 .303 .345 .862 .421 .373 .711 .492 .572
6 InternVL3.5-38B .746 .636 .624 .363 .271 .038 .128 .025 .559 .638 .375 .536 .765 .504 .503 .360 .412 .219 .340 .192 .258 .542
7 Molmo2-8B .823 .563 .469 .286 .137 .021 .038 .016 .503 .643 .474 .330 .623 .416 .290 .358 .055 .457 .483 .692 .491 .578
8 Qwen2.5-VL-7B .763 .504 .673 .541 .420 .047 .269 .062 .541 .580 .356 .713 .724 .410 .334 .337 .308 .213 .395 .916 .442 .541
9 InternVL3.5-30B-A3B .486 .469 .545 .310 .240 .034 .118 .024 .537 .609 .350 .539 .727 .489 .378 .333 .289 .252 .309 .188 .568 .612
10 InternVL3-8B .827 .497 .478 .322 .262 .032 .124 .020 .508 .584 .346 .581 .738 .320 .297 .304 .246 .203 .335 .314 .684 .601
11 InternVL3.5-8B .819 .531 .421 .266 .191 .023 .077 .015 .495 .603 .372 .457 .747 .408 .263 .299 .236 .224 .264 .460 .236 .544
12 Gemma-3-12B .790 .688 .626 .429 .225 .048 .093 .047 .466 .551 .410 .511 .606 .415 .352 .280 .329 .145 .235 .352 .120 .505
13 Qwen2.5-VL-3B .416 .457 .477 .454 .358 .040 .206 .064 .427 .500 .389 .661 .640 .321 .194 .300 .307 .110 .230 .904 .655 .559
14 Pixtral-12B .688 .501 .530 .349 .187 .029 .079 .027 .447 .495 .320 .465 .599 .352 .307 .304 .229 .266 .246 .065 .119 .519
15 LLaVA-NeXT-Vicuna .662 .343 .290 .100 .028 .003 .015 .003 .457 .454 .364 .198 .510 .250 .217 .250 .701 .125 .187 .000 .000 .500
16 Phi-3.5-Vision .748 .359 .267 .191 .066 .013 .023 .009 .454 .533 .154 .217 .613 .316 .198 .256 .030 .160 .221 .044 .562 .576
17 Llama-3.2-Vision .545 .482 .518 .434 .234 .031 .104 .054 .317 .483 .286 .520 .724 .286 .260 .317 .061 .125 .250 .722 .000 .500
18 LLaVA-NeXT-Mistral .364 .392 .408 .162 .029 .005 .015 .004 .372 .484 .259 .238 .616 .259 .332 .250 .089 .131 .173 .000 .476 .508
Mean .725 .545 .541 .382 .247 .035 .123 .039 .495 .574 .370 .502 .695 .407 .341 .331 .401 .259 .309 .438 .396 .558
Floor .500 .100 .111 .060 .035 .005 .001 .011 .000 .000 .000 .000 .501 .250 .410 .250 .415 .250 .170 .000 .000 .500

Columns. C1 (exact match): phylum, class, order, family, genus, species epithet, scientific name, common name (open-ended). C2 (CAGS): relative salience, morphological attributes, anatomical localization, naming. C3: counting (CAS), relative counting, absolute distance (share within 20%), relative distance, localization (mean IoU), relative position, viewpoint, ocr (exact match). C4: d′ and accuracy under random pairing. Floor is the score an image-blind rule reaches; for C1 it is the most frequent taxon at each rank. CAGS and d′ are chance-corrected, so their floors are zero. ¹ Domain specialist for taxonomy, full TreeOfLife-200M label set. ² Domain specialist for re-identification, on Grevy's zebra only.

Per-item answers for every cell are in predictions/ on Hugging Face. Leaderboards with confidence intervals, per-group, per-tier and per-dataset breakdowns are in each component README and in the supplement.

Findings by component

General visual capabilities do not transfer to biological organisms, and scale does not close the gap. The failures below hold across a tenfold range of model size (3.75B → 38.4B).

C1 — VLMs fail at finer ranks

Finding Number
Exact match, mean of 18 models: phylum → class → family → genus → scientific name .725 → .545 → .382 → .247 → .123 (falls to one sixth)
Best model vs BioCLIP-2 (tol), class .731 vs .874 (1.2×)
Best model vs BioCLIP-2 (tol), scientific name .269 vs .544 (2.0×)
Common name, open-ended vs 4-way MCQ, same images and targets .039 vs .645 (16.4×): models recognize names they cannot recall
InternVL3 8B → 38B gain, class vs scientific name +18.7 vs +6.5 points (InternVL3.5: +10.5 vs +5.0)
Exception to the scaling pattern Qwen3-VL 8B → 32B: class .680 → .615, scientific name .202 → .244
Models below the image-blind floor at phylum (Chordata for everything = .500) 3 (InternVL3.5-30B .486, Qwen2.5-VL-3B .416, LLaVA-NeXT-Mistral .364)

C2 — VLMs see traits but cannot localize

Finding Number
Mean CAGS: morphological · naming · relative salience · anatomical localization .574 · .502 · .495 · .370
Hardest families part-set visibility .341, laterality .411
Laterality, given the correct part 17 of 18 models at or below chance; 9 significantly below
Mirror confusion 21.8% – 54.0% vs a 20% baseline; rises with model strength (ρ = .75)
The one exception Molmo2-8B (pointing-supervised): laterality .746, +.220 over the next model
CAGS robustness ρ ≥ .996 across the base grid of 11 settings; human agreement .908 of the inter-annotator rate; AUC .676 on EM = 0 items

C3 — VLMs see objects but not their geometry

Finding Number
Localization: mean IoU vs mean-gold-box floor .401 vs .415; 12 of 18 below the floor; only Qwen3-VL-32B / 8B / 30B (.866 / .862 / .861) find the animal reliably
Absolute distance: models below a one-constant-per-type floor (.410) 15 of 18; only Qwen3-VL-32B (.622), Qwen3-VL-30B (.528), InternVL3.5-38B (.503) beat it
Counting: CAS mean vs floor .695 vs .501 (best InternVL3-38B .799); exact match never exceeds .242
Counting, everyday vs biological, same 2–10 range Qwen3-VL-32B 94.9% exact on CountBench vs 41.7% on single-image Bio-VQA items (2.3× lower)
Relative tasks vs floor relative counting .407 vs .250; relative distance .331 vs .250; relative position .259 vs .250 (chance)
OCR as negative control the 7 spatial tasks inter-correlate at mean ρ = +.703; none correlates with OCR

C4 — VLMs answer from resemblance

Finding Number
MegaDescriptor vs VLM mean, Grevy's zebra, random pairing d′ .733 vs .391 (1.9×); easy pairing 2.055 vs 1.346 (1.5×). The two strongest VLMs, Qwen3-VL-30B (1.088) and Qwen3-VL-32B (.931), exceed it on this dataset.
Hard (adversarial) pairing 17 of 18 models have negative d′ (−.932 to −.091); MegaDescriptor −.969
Difficulty ordering easy ≥ random ≥ hard holds in 77 of 90 model × dataset cells (chance of a monotone order: 1/6)
Response bias criterion c < 0 for 17 of 18 models, and it grows more negative as pairs get harder: models say yes more as the task gets harder

Cross-component structure

Spearman ρ (18 models) C1 C2 C3 C4
C1 (α .981) — .689 .787 .433†
C2 (α .901) — .927 .514†
C3 (α .925) — .610
C4 (α .889) —

† not significant after Holm correction. At n = 18 the confidence intervals are wide (median width .66).

  • Tasks agree more within a component than across components: mean ρ .749 vs .534 (label permutation, p = .0005). Internal agreement is .841 for C1, .662 for C3, .645 for C2 and .617 for C4.
  • C4 stands alone. Knowing how well a model names an organism says nothing about whether it can tell two individuals of that organism apart.
  • C2 and C3 overlap (ρ = .927). Both ask a model to find something fine-grained. They are reported separately because they diagnose different failures, but they should not be treated as independent evidence.
  • A strong model is strong everywhere; below the top, rankings reorder. One factor explains 62.2% of the variance. InternVL3-38B, Qwen3-VL-30B and Qwen3-VL-32B are top five in every component. The median model moves 5.5 of 18 places between components (Phi-3.5-Vision: 8th percentile on C1, 64th on C4).

Reproducibility

Stage Deterministic? Mechanism
C1 image download ❌ Thread interleaving decides which concurrent downloads fill the per-group budget. The released manifests (TreeOfLife-200M uuid per row) are the artifact of record.
QA generation ✅ Seeded per component
Manifest sharding ✅ --seed 42, applied after row_id assignment
Inference ✅ Greedy decoding, one attempt per item
Difficulty tiers ✅ Deterministic; ties broken by taxon name
Scoring ✅ A pure function of the merged prediction files; bootstraps use fixed seeds
Bio-VQA-Lite ✅ Release/make_lite.py --seed 0

Given a manifest, everything downstream reproduces exactly. Use the released question files rather than expecting to regenerate the C1 image set byte for byte.


Limitations

  • Open-weight models only; we cannot say whether proprietary models (e.g. GPT-5) behave the same way.
  • One decoding protocol (zero-shot, greedy, no chain-of-thought). Reasoning modes may score higher.
  • Images come from public datasets that a model may have seen in pretraining, including BioCLIP-2's training corpus for C1.
  • No human performance reference. Human raters validate C2 scoring only; C1, C3 and C4 ground truth have no human audit.
  • Floors are rule-based; a text-only VLM may set a higher one.
  • Two models (Molmo2-8B, Phi-3.5-Vision) mostly copy the example box on localization.
  • Species-epithet answers are truncated in the released runs, so species results are analyzed using the scientific name.
  • The CAGS anatomy kernel over-credits laterality confusions.
  • Localization is evaluated on the Easy tier (3,988 items).

License

  • Code in this repository: MIT.
  • Benchmark annotations (questions, answers, Lite, predictions) on Hugging Face: CC BY-NC 4.0.
  • Images keep the license of their source dataset. See the dataset card for per-source terms. Check them before redistributing any image.

Citation

If you use Bio-VQA, please cite:

@inproceedings{rayeed2027biovqa,
  title     = {How Finely Can Vision--Language Models See Biology? {Bio-VQA}: A Benchmark for Taxonomic, Morphological, Spatial and Individual Reasoning},
  author    = {Rayeed, S M and Ma, Qian and Stewart, Charles V. and Ma, Yao},
  booktitle = {Proceedings of the IEEE/CVF Winter Conference on Applications of Computer Vision (WACV)},
  year      = {2027}
}

Links: 🌐 Project page · 🤗 Dataset · 💻 Code


References

Every source dataset, baseline, model, metric and benchmark referenced by Bio-VQA or by any component README. The key column is the BibTeX key used in the paper, so entries can be cross-referenced against the manuscript's .bib directly.

All source imagery retains its original license. This repository distributes code only; the benchmark data are on Hugging Face. Verify licensing before redistributing any downloaded imagery.

Source datasets

Eleven public datasets supply every image and every ground-truth annotation. A question is generated only where an existing annotation supplies the answer.

Dataset Key Used by
TreeOfLife-200M stevens2025bioclip2 C1 — 100K image subset, 10 organismal groups
CUB-200-2011 wah2011caltech C2 — 11,788 images, 312 binary attributes
WAID waid2023 C3 — aerial wildlife: camel, cattle, kiang, seal, sheep, zebra
Boxes on Bees and Pollen boxesonbees C3 — dense hive frames
2018-NEON-beetles neonbeetles C3 — specimen trays with scalebars
DePondFi depondfi C3 — pond fish
GZCD gzcd C3 + C4 — Grevy's zebra
WhaleSharkID whalesharkid C3 + C4 — spot pattern
BelugaID belugaid C4 — scarring, dorsal ridge
HyenaID hyenaid C3 + C4 — spot pattern
LeopardID leopardid C3 + C4 — rosette pattern

Specialist baselines and encoders

BioCLIP-2 and MegaDescriptor are the measured ceilings for C1 and C4. DINOv2 is used for C4 pair mining, not as a baseline. The remaining entries are the re-identification literature the component situates itself against.

Model Key Role
BioCLIP-2 stevens2025bioclip2 C1 taxonomic ceiling
BioCLIP stevens2024bioclip predecessor; tree-of-life scale contrastive
BioTrove-CLIP biotrove2024 alternative biological encoder
MegaDescriptor cermak2024wildlifedatasets C4 specialist baseline
DINOv2 oquab2024dinov2 C4 pair mining by embedding similarity
MiewID otarashvili2024miewid multi-species re-ID descriptor
HotSpotter crall2013hotspotter hand-crafted local features for re-ID
PIE moskvyak2019pie learned re-ID embeddings
ALFReID nepovinnykh2024alfreid learned re-ID embeddings
TransReID he2021transreid transformer re-ID

Evaluated models

Eighteen open-weight models from 3.75B to 38.4B parameters. Two of the 30B models are mixture-of-experts activating 3B parameters per token.

Family Key Sizes evaluated
Qwen2.5-VL qwen25vl 3.75B, 8.3B
Qwen3-VL qwen3vl 8.8B, 30.5B MoE, 32.8B
InternVL3 internvl3 8.1B, 38.4B
InternVL3.5 internvl35 8.1B, 30.5B MoE, 38.4B
Gemma-3 gemma3 12.2B
Gemma-4 gemma4 12.2B
Molmo 2 molmo2 8.0B, pointing-supervised
Pixtral pixtral 12.4B
Phi-3.5-Vision phi35 4.2B
Llama-3.2-Vision llama32 10.7B
LLaVA-NeXT llavanext 7.1B Vicuna, 7.6B Mistral

Metrics and statistical methods

Every graded metric is reported alongside the exact match it modifies.

Method Key Used for
Wu–Palmer similarity wu1994verb C1 — depth of the lowest common ancestor
Lin similarity lin1998information C1 — information-content weighted
Open-ended taxonomic evaluation ging2024openended C1 — hierarchical scoring precedent
Cohen's kappa cohen1960coefficient C2/C3 — chance correction
Signal detection theory green1966signal C4 — d-prime and criterion
Detection theory macmillan2004detection C4 — d-prime and criterion
Log-linear correction hautus1995 C4 — required when H or F reaches 0 or 1
Labeled Faces in the Wild lfw2007 C4 — the verification protocol

Evaluation protocol

Element Key Setting
Greedy decoding holtzman2020 no sampling
Prompt sensitivity sclar2024 same question and format instruction for every model within a family
Chain-of-thought wei2022cot explicitly NOT used
Few-shot prompting brown2020few explicitly NOT used

Related benchmarks

Benchmark Key Relevance
VLM4Bio vlm4bio2024 closest prior biological VQA
PlantExpertVQA plantexpertvqa2025 crop diseases
J-EDI QA jediqa2024 100 deep-sea images
AgroCoT agrocot2025 agricultural chain-of-thought
AVA-Bench avabench2026 atomic visual skills — the decomposition precedent
MMBench liu2024mmbench general multi-task
SEED-Bench li2023seedbench general multi-task
BLINK fu2024blink general perception
MMVP tong2024eyes visual patterns
CV-Bench / Cambrian tong2024cambrian counting comparison
MM-Spatial mmspatial2025 spatial reasoning; blind-baseline result
ScienceQA lu2022scienceqa expert-domain VQA
MMMU yue2024mmmu expert ceilings
MicroVQA burgess2025microvqa microscopy
TallyQA tallyqa2019 counting
CountBench paiss2023countbench counting
VSR liu2023vsr spatial relations
SpatialVLM chen2024spatialvlm spatial reasoning
INQUIRE vendrow2024inquire biodiversity retrieval
IUCN LLM evaluation iucnllm2026 biodiversity, no imagery
Animal re-ID survey animalreid2026 no VLMs reported

Taxonomic infrastructure

Resource Key Used for
GBIF Backbone gbif2024 versioned snapshot; synonym map, accepted names
iNaturalist inaturalist2024 common-name resolution to English
Wikidata wikidata common-name resolution to English

Bio-VQA · project page · dataset · images retain their original licenses

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages