Skip to main content

LookBench: A Live and Holistic Open Benchmark for Fashion Image Retrieval

Python PyPI License arXiv Project Page Dataset Model arXiv Models ZooWork

LookBench is a live, holistic, and challenging benchmark for fashion image retrieval in real e-commerce settings. This repository provides the official evaluation code and model implementations.

📰 News

📖 Overview

LookBench addresses the limitations of existing fashion retrieval benchmarks by providing:

  • 🔄 Continuously Refreshing Samples: Mitigates data contamination with time-stamped, periodically updated test sets
  • 🎯 Diverse Retrieval Tasks: Covers single-item and multi-item retrieval across real studio, AI-generated studio, real street-look, and AI-generated street-look scenarios
  • 📊 Attribute-Supervised Evaluation: Fine-grained evaluation based on 100+ fashion attributes across categories
  • 🏆 Challenging Benchmarks: Many strong baselines achieve below 60% Recall@1

Benchmark Subsets

Dataset Image Source # Retrieval Items Difficulty # Queries / Corpus
RealStudioFlat Real studio flat-lay product photos Single Easy 1,011 / 62,226
AIGen-Studio AI-generated lifestyle studio images Single Medium 192 / 59,254
RealStreetLook Real street outfit photos Multi Hard 1,000 / 61,553
AIGen-StreetLook AI-generated street outfit compositions Multi Hard 160 / 58,846

Reranking Track: ShopRank-Bench

LookBench also hosts a text reranking track. Where the retrieval track ranks a gallery against a query image, the reranking track asks a cross-encoder which of two candidate products a shopper would prefer.

ShopRank-Bench is a contamination-limited e-commerce preference benchmark: 10,511 pairs over 2,991 queries drawn from live shopping traffic, labelled by a cross-family LLM judge panel and tiered by how many families committed a verdict (1,843 gold / 4,445 silver / 4,223 bronze). Every pair ships in two formats — the canonical structured attribute schema and a natural-language rendering — carrying the same label, so a per-format accuracy gap measures sensitivity to serialization rather than a difference in labels.

Track Task Metric Size
Image retrieval query image → gallery Recall@K, MRR, NDCG, MAP 4 subsets
ShopRank-Bench query + two candidates → preferred Pairwise accuracy, by tier 10,511 pairs / 2,991 queries
from look_bench.data import ShopRankPairs
from look_bench.models import get_model
from look_bench.metrics import PairwiseAccuracyEvaluator

# or ShopRankPairs.from_jsonl("preference.jsonl", ...) for a local copy of the release file
pairs = ShopRankPairs.from_hub(text_format="structured")
# Each ZooWork-ShopRanker repo holds the base weights and the LoRA adapter
_, reranker = get_model("qwen3-reranker").load_model(
    "srpone/zoowork-shopranker-4b", model_path="srpone/zoowork-shopranker-4b")

results = PairwiseAccuracyEvaluator().evaluate_reranker(
    reranker, list(pairs), preferred_key="preferred", rejected_key="rejected")
print(results["pairwise_accuracy"], results["pairwise_accuracy_gold"])

Reranking needs one extra dependency: pip install look-bench[reranking].

🚀 Quick Start

Installation

Option 1: Install from PyPI (Recommended)

pip install "look-bench>=0.4.0"            # retrieval
pip install "look-bench[reranking]>=0.4.0" # + ShopRank-Bench rerankers (peft)

Use 0.4.0 or later. Releases up to 0.3.0 installed top-level datasets, models, metrics and utils packages that overwrote Hugging Face datasets; everything now lives under the look_bench package (from look_bench.data import ...).

Option 2: Install from Source

# Clone the repository
git clone https://github.com/SerendipityOneInc/look-bench.git
cd look-bench

# Install in development mode
pip install -e .

# Or install dependencies only
pip install -r requirements.txt

Optional: Install with Examples Support

For running example notebooks and scripts that require matplotlib:

pip install look-bench[examples]

Load Dataset from Hugging Face

The LookBench dataset is hosted on Hugging Face and can be loaded directly:

Option 1: Using look-bench utility (Recommended)

from look_bench.utils import load_lookbench_dataset

# Load a specific config
dataset = load_lookbench_dataset("real_studio_flat")

# Access query and gallery splits
query_data = dataset['query']
gallery_data = dataset['gallery']

print(f"Query samples: {len(query_data)}")
print(f"Gallery samples: {len(gallery_data)}")

Option 2: Using Hugging Face datasets directly

from datasets import load_dataset

# Load a specific config
dataset = load_dataset("srpone/look-bench", "real_studio_flat")

# Access query and gallery splits
query_data = dataset['query']
gallery_data = dataset['gallery']

print(f"Query samples: {len(query_data)}")
print(f"Gallery samples: {len(gallery_data)}")

Quick Evaluation

import torch
from look_bench.manager import ConfigManager, ModelManager

# Load model
config_manager = ConfigManager()  # packaged look_bench/configs/config.yaml
model_manager = ModelManager(config_manager)

model, _ = model_manager.load_model('clip')
transform = model_manager.get_transform('clip')

# Extract features from an image
sample = dataset['real_studio_flat']['query'][0]
image_tensor = transform(sample['image']).unsqueeze(0)

if torch.cuda.is_available():
    model = model.cuda()
    image_tensor = image_tensor.cuda()

with torch.no_grad():
    features = model(image_tensor)

print(f"Feature shape: {features.shape}")

Run Full Evaluation

# Run evaluation with the packaged default configuration
look-bench

# Run a specific pipeline
look-bench --pipeline evaluation

# Use your own configuration (start from look_bench/configs/config.yaml)
look-bench --config my_config.yaml

# From a source checkout, `python main.py ...` is equivalent

Example Scripts & Notebooks

We provide both Python scripts and Google Colab notebooks for easy experimentation:

📓 Colab Notebooks (Run in Browser)

🐍 Python Scripts (Run Locally)

# Run examples locally
python examples/00_data_exploration.py
python examples/01_load_grlite_model.py
python examples/02_model_evaluation.py
python examples/03_custom_model.py

🏗️ Architecture

look-bench/
├── main.py                     # Source-checkout entry point (= `look-bench` command)
└── look_bench/                 # The installed package
    ├── main.py                 # CLI (config-driven)
    ├── manager.py              # Configuration, model, and data managers; DEFAULT_CONFIG
    ├── configs/config.yaml     # Packaged default configuration
    ├── runner/                 # Pipeline execution framework
    │   ├── base_pipeline.py    # Base pipeline class
    │   ├── evaluator.py        # Core evaluation logic
    │   ├── pipeline.py         # Pipeline registry
    │   ├── evaluation_pipeline.py          # Standard evaluation pipeline
    │   └── feature_extraction_pipeline.py  # Feature extraction pipeline
    ├── models/                 # Model implementations and registry
    │   ├── base.py             # Base (embedding) model interface
    │   ├── reranker_base.py    # Base reranker interface
    │   ├── registry.py         # Model registration system
    │   ├── factory.py          # Model factory
    │   ├── clip_model.py / siglip_model.py / dinov2_model.py / grlite_model.py
    │   └── qwen3_reranker.py   # Qwen3-Reranker (optional LoRA)
    ├── data/                   # Dataset loading (BEIR-style) and ShopRank-Bench pairs
    │   ├── base.py             # Base dataset implementation
    │   ├── registry.py         # Dataset registry
    │   └── shoprank_dataset.py # ShopRankPairs
    ├── metrics/                # Evaluation metrics
    │   ├── rank.py / mrr.py / ndcg.py / map.py
    │   ├── pairwise.py         # Pairwise accuracy (reranking)
    │   └── significance.py     # Paired tests
    └── utils/                  # Utilities and logging

🎯 Supported Models

Model Architecture Input Size Embedding Dim Framework
CLIP Vision Transformer 224×224 512 PyTorch
SigLIP Vision Transformer 224×224 768 PyTorch
DINOv2 Vision Transformer 224×224 768 PyTorch
GR-Lite Vision Transformer 336×336 1024 PyTorch

Reranking models score a (query, candidate) pair directly rather than producing an embedding, so they register through BaseReranker instead of BaseModel:

Model Architecture Scoring Adapter
Qwen3-Reranker Causal LM cross-encoder P("yes") vs P("no") at final position optional LoRA

⚙️ Configuration

Edit look_bench/configs/config.yaml to configure models and evaluation settings:

# Pipeline configuration
pipeline:
  name: "evaluation"  # evaluation, feature_extraction
  model: "clip"
  dataset: "fashion200k"
  args: {}

# Model configuration
clip:
  enabled: true
  model_name: "openai/clip-vit-base-patch16"
  input_size: 224
  embedding_dim: 512
  device: "cuda"

# Evaluation settings
evaluation:
  metric: "recall"
  top_k: [1, 5, 10, 20]
  l2norm: true

📊 Evaluation Metrics

LookBench supports multiple evaluation metrics:

  • Recall@K: Top-K retrieval accuracy (K=1, 5, 10, 20)
  • MRR: Mean Reciprocal Rank
  • NDCG@K: Normalized Discounted Cumulative Gain
  • MAP: Mean Average Precision

Fine-Grained Evaluation

All metrics are computed with attribute-level matching:

  • Fine Recall@1: Requires exact category and all attributes to match
  • Coarse Recall@1: Only requires category to match
  • nDCG@K: Graded relevance based on attribute overlap

🔧 Advanced Usage

Custom Model Integration

LookBench makes it easy to integrate your own models using the registry pattern. Here's a quick example:

from look_bench.models.base import BaseModel
from look_bench.models.registry import register_model
import torch.nn as nn
from torchvision import models, transforms

@register_model("resnet50", metadata={
    "description": "ResNet-50 for fashion retrieval",
    "framework": "PyTorch",
    "input_size": 224,
    "embedding_dim": 2048
})
class ResNet50Model(BaseModel):
    @classmethod
    def load_model(cls, model_name: str, model_path: str = None):
        model = models.resnet50(pretrained=True)
        model = nn.Sequential(*list(model.children())[:-1])  # Remove FC layer
        
        # Wrapper to flatten output
        class Wrapper(nn.Module):
            def __init__(self, backbone):
                super().__init__()
                self.backbone = backbone
            def forward(self, x):
                return self.backbone(x).squeeze(-1).squeeze(-1)
        
        return Wrapper(model), cls()
    
    @classmethod
    def get_transform(cls, input_size: int = 224):
        return transforms.Compose([
            transforms.Resize((input_size, input_size)),
            transforms.ToTensor(),
            transforms.Normalize(mean=[0.485, 0.456, 0.406],
                               std=[0.229, 0.224, 0.225])
        ])

Then add your model to look_bench/configs/config.yaml:

resnet50:
  enabled: true
  model_name: "resnet50"
  model_path: null  # or path to your weights
  input_size: 224
  embedding_dim: 2048
  device: "cuda"

For complete examples, see examples/03_custom_model.py

Custom Pipeline

Create custom evaluation pipelines:

from look_bench.runner.base_pipeline import BasePipeline
from look_bench.runner.pipeline import register_pipeline

@register_pipeline("custom_pipeline")
class CustomPipeline(BasePipeline):
    def get_pipeline_name(self) -> str:
        return "custom_pipeline"
    
    def run(self, **kwargs):
        # Your custom logic here
        model_name = kwargs.get('model_name', 'clip')
        dataset_type = kwargs.get('dataset_type', 'fashion200k')
        
        # Load model and data
        model, _ = self.model_manager.load_model(model_name)
        # ... your evaluation logic
        
        return {"status": "success", "results": results}

📈 Results

Fine Recall@1 Performance

Our GR-Lite model achieves state-of-the-art performance on LookBench. Fine Recall@1 requires exact category and all attributes to match:

Model Resolution / Emb. AIGen-StreetLook AIGen-Studio RealStreetLook RealStudioFlat Overall
GR-Pro (Ours) 336 / 1024 63.67 54.88 44.75 51.55 49.80
GR-Lite (Ours, Open) 336 / 1024 62.47 52.08 43.84 51.70 49.18
Marqo-FashionSigLIP 224 / 768 66.27 58.53 42.43 51.86 49.44
Marqo-FashionCLIP 224 / 512 63.22 54.93 41.87 51.68 48.63
SigLIP2-B/16 384 / 768 57.83 54.97 39.35 49.12 46.10
SigLIP2-L/16 384 / 1024 51.89 48.57 35.91 44.78 41.86
PP-ShiTuV2 224 / 512 30.06 33.69 32.77 43.22 37.17
DINOv3-ViT-L 224 / 1024 20.24 27.66 26.27 39.85 31.83
DINOv2-ViT-L 224 / 1024 24.29 25.05 22.99 37.66 29.57
CLIP-L/14 336 / 768 25.28 25.95 21.09 40.35 30.08
CLIP-B/16 224 / 512 17.86 13.75 16.80 34.75 24.36

Coarse Recall@1 Performance

Coarse Recall@1 only requires category match (more lenient):

Model Resolution / Emb. AIGen-StreetLook AIGen-Studio RealStreetLook RealStudioFlat Overall
GR-Pro (Ours) 336 / 1024 92.50 92.75 79.82 94.16 87.93
GR-Lite (Ours, Open) 336 / 1024 88.75 90.16 76.76 92.68 85.54
Marqo-FashionSigLIP 224 / 768 90.00 93.78 73.39 88.63 82.77
Marqo-FashionCLIP 224 / 512 84.38 87.05 75.33 88.72 82.68
SigLIP2-B/16 384 / 768 86.25 90.67 72.17 88.33 81.62
SigLIP2-L/16 384 / 1024 80.62 90.67 68.20 84.97 78.12
CLIP-L/14 336 / 768 46.88 56.48 45.26 76.85 59.91
CLIP-B/16 224 / 512 35.62 32.12 33.54 67.26 48.11

nDCG@5 Performance

nDCG@5 evaluates ranking quality with graded relevance based on attribute overlap:

Model Resolution / Emb. AIGen-StreetLook AIGen-Studio RealStreetLook RealStudioFlat Overall
GR-Pro (Ours) 336 / 1024 63.67 54.88 44.75 51.55 49.80
GR-Lite (Ours, Open) 336 / 1024 62.47 52.08 43.84 51.70 49.18
Marqo-FashionSigLIP 224 / 768 66.27 58.53 42.43 51.86 49.44
Marqo-FashionCLIP 224 / 512 63.22 54.93 41.87 51.68 48.63
SigLIP2-B/16 384 / 768 57.83 54.97 39.35 49.12 46.10

See our paper for complete results including MRR and additional models.

📄 Citation

If you use LookBench in your research, please cite:

@article{gao2026lookbench,
  title={LookBench: A Live and Holistic Open Benchmark for Fashion Image Retrieval}, 
  author={Chao Gao and Siqiao Xue and Yimin Peng and Jiwen Fu and Tingyi Gu and Shanshan Li and Fan Zhou},
  year={2026},
  url={https://arxiv.org/abs/2601.14706}, 
  journal={arXiv preprint arXiv:2601.14706},
}

If you use the ShopRank-Bench reranking track or the ZooWork-ShopRanker models, please also cite:

@article{xue2026zooworkshopranker,
  title   = {ZooWork-ShopRanker: An Open, Preference-Aligned E-Commerce Reranker},
  author  = {Xue, Siqiao and Liu, Shuxuan and Hu, Ning},
  journal = {arXiv preprint arXiv:2609.31002},
  year    = {2026},
  url     = {https://arxiv.org/abs/2609.31002}
}

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

The GR-Lite model weights are distributed under the DINOv3 License as they are derived from Meta's DINOv3 model.

Metadata

Release files for look-bench 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for look-bench 0.4.0
File Size Uploaded Provenance Actions
look_bench-0.4.0.tar.gz 57.8 kB With provenance Details for look_bench-0.4.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for look-bench 0.4.0
File Interpreter ABI Platform Actions
look_bench-0.4.0-py3-none-any.whl Python 3 none any Details for look_bench-0.4.0-py3-none-any.whl

Total release size: 126.6 kB

Release files / look_bench-0.4.0.tar.gz

Download URL look_bench-0.4.0.tar.gz
Size 57.8 kB
Tags Source
SHA-256 checksum
How to use checksums
9e885c6d2d50b7aa9f79ff0f6b9de14e672a0e226b65684805e10bdcb5fdd846
BLAKE2b-256 checksum
How to use checksums
69d41b59fb7df76ad9243c5da50d7ae32d7698ff6460e929dbc783c68c80ee0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release files / look_bench-0.4.0-py3-none-any.whl

Download URL look_bench-0.4.0-py3-none-any.whl
Size 68.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f3bf480aba0d27e08d4e7f55a336b23e7c330b1a17835d80d5c15185fc9231b2
BLAKE2b-256 checksum
How to use checksums
0b137c8fbb9a2ee521ed9f335451b56d34097ffe52dc09084eb1071047d37180
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Security for look-bench 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for look_bench-0.4.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page