Browse by type
A Fully-Open, Cost-Effective Family of Advanced Vision Encoders for Multimodal Learning
A Family of Generative Pretrained Visual Encoders for Multimodal Learning
A Unified Visual Encoder for Both Understanding and Generation
🌐 OpenVision Project Page
•
Arxiv
• 💻 Code
•
OpenVision Collection
🌐 OpenVision 2 Project Page
•
Arxiv
• 💻 Code
•
OpenVision 2 Collection
🌐 OpenVision 3 Project Page
•
Arxiv
• 💻 Code
•
OpenVision 3 Collection
This repository contains the code for training and fine-tuning vision-language models based on the OpenVision framework. It now supports both the original contrastive + generative training (OpenVision), the simplified caption-only generative training (OpenVision 2), providing efficient and scalable approaches to multimodal learning on TPU infrastructure.
*-vision-only repo now also
ships the jointly-trained decoder, so encoder + decoder form the full image→caption model.
See Generate Captions and caption.py.

| Method | Vision Encoder | Params | Res | TextVQA | ChartQA | OCR | MME | SEED | SQA | GQA | POPE |
|---|---|---|---|---|---|---|---|---|---|---|---|
| OpenVision | L/14 | 304M | 224 | 57.7 | 13.9 | 315 | 1487 | 69.5 | 73.6 | 62.9 | 86.4 |
| OpenVision 2 | L/14 | 304M | 224 | 59.0 | 13.7 | 327 | 1460 | 69.3 | 76.5 | 62.6 | 87.1 |
| OpenVision | L/14 | 304M | 336 | 61.2 | 15.7 | 339 | 1525 | 70.5 | 75.1 | 63.7 | 87.2 |
| OpenVision 2 | L/14 | 304M | 336 | 63.0 | 14.5 | 357 | 1486 | 70.1 | 77.5 | 63.0 | 87.7 |
| OpenVision | SoViT-400M/14 | 400M | 384 | 62.4 | 16.1 | 357 | 1493 | 70.4 | 72.4 | 63.8 | 88.0 |
| OpenVision 2 | SoViT-400M/14 | 400M | 384 | 64.3 | 15.0 | 387 | 1472 | 70.7 | 74.9 | 63.5 | 87.5 |
| OpenVision 2 | H/14 | 632M | 224 | 60.2 | 13.5 | 340 | 1470 | 69.3 | 75.4 | 62.5 | 87.2 |
| OpenVision 2 | H/14 | 632M | 336 | 63.4 | 16.3 | 391 | 1470 | 70.6 | 76.4 | 63.1 | 88.4 |
| OpenVision 2 | H/14 | 632M | 448 | 65.6 | 18.1 | 416 | 1499 | 70.6 | 75.6 | 63.1 | 88.7 |
| OpenVision 2 | g/14 | 1.01B | 224 | 60.2 | 13.7 | 338 | 1469 | 69.3 | 75.0 | 62.6 | 86.9 |
Full collection: Hugging Face – OpenVision 2
Note:
OpenVision2 checkpoints require the custom open_clip version included in this repository.
The upstream open_clip pip package is not compatible.
import torch
# Use the OpenVision2 version of open_clip
from src.convert_upload.open_clip.factory import create_vision_encoder_and_transforms
hf_repo = "UCSC-VLAA/openvision2-vit-large-patch14-224-vision-only"
vision_encoder = create_vision_encoder_and_transforms(
model_name=f"hf-hub:{hf_repo}"
)
vision_encoder.eval()
dummy_image = torch.ones((1, 3, 224, 224))
with torch.no_grad():
_, patch_features = vision_encoder(dummy_image)
print("Patch feature shape:", patch_features.shape)
Every OpenVision 2 *-vision-only repo now also ships the caption text decoder it was
jointly trained with, so the encoder + decoder together form the full image→caption model.
The decoder is a concat / prefix-LM autoregressive transformer (the image patch tokens are
prepended as a bidirectional prefix; text is generated causally). Each repo contains
caption_decoder.safetensors, text_decoder_config.json, and modeling_openvision2_decoder.py.
One-command demo (downloads encoder + decoder from the Hub; resolution is read automatically):
python caption.py --repo UCSC-VLAA/openvision2-vit-large-patch14-224-vision-only --image your.jpg
Or in code:
import json, torch, numpy as np
from PIL import Image
from huggingface_hub import hf_hub_download
from safetensors.torch import load_file
from src.convert_upload.open_clip.factory import create_vision_encoder_and_transforms
from src.convert_upload.modeling_openvision2_decoder import (
OpenVision2TextDecoder, OpenVision2TextDecoderConfig)
repo = "UCSC-VLAA/openvision2-vit-large-patch14-224-vision-only"
enc = create_vision_encoder_and_transforms(model_name=f"hf-hub:{repo}").eval()
d = json.load(open(hf_hub_download(repo, "text_decoder_config.json")))
dec = OpenVision2TextDecoder(OpenVision2TextDecoderConfig(
width=d["width"], depth=d["depth"], num_heads=d["num_heads"], mlp_dim=d["mlp_dim"],
vocab_size=d["vocab_size"], vision_width=d["vision_width"]))
dec.load_state_dict(load_file(hf_hub_download(repo, "caption_decoder.safetensors"))); dec.eval()
# image (ImageNet-normalized, NCHW) -> patch tokens -> caption ids
img = torch.randn(1, 3, 224, 224) # replace with a preprocessed image; see caption.py
with torch.no_grad():
_, patch_tokens = enc(img)
ids = dec.generate(patch_tokens, bos_id=1, eos_id=2, max_len=64)[0].tolist()
# decode ids with assets/bert_base_vocab_bos_eos.txt (see caption.py: detokenize)
See caption.py for image preprocessing and WordPiece detokenization.
| Model | Size | Patch Size | Resolution | IN-1K Top-1 | JAX Weight | PyTorch Weight |
|---|---|---|---|---|---|---|
| OpenVision-ViT-Tiny | 5M | 16 | 160 | 46.9% | Available | Available |
| OpenVision-ViT-Tiny | 5M | 16 | 224 | 49.6% | Available | Available |
| OpenVision-ViT-Tiny | 5M | 16 | 384 | 51.5% | Available | Available |
| OpenVision-ViT-Tiny | 5M | 8 | 160 | 51.9% | Available | Available |
| OpenVision-ViT-Tiny | 5M | 8 | 224 | 53.5% | Available | Available |
| OpenVision-ViT-Tiny | 5M | 8 | 384 | 53.9% | Available | Available |
| OpenVision-ViT-Small | 22M | 16 | 160 | 63.5% | Available | Available |
| OpenVision-ViT-Small | 22M | 16 | 224 | 65.9% | Available | Available |
| OpenVision-ViT-Small | 22M | 16 | 384 | 67.1% | Available | Available |
| OpenVision-ViT-Small | 22M | 8 | 160 | 67.3% | Available | Available |
| OpenVision-ViT-Small | 22M | 8 | 224 | 68.6% | Available | Available |
| OpenVision-ViT-Small | 22M | 8 | 384 | 68.5% | Available | Available |
| OpenVision-ViT-Base | 86M | 16 | 160 | 72.4% | Available | Available |
| OpenVision-ViT-Base | 86M | 16 | 224 | 73.9% | Available | Available |
| OpenVision-ViT-Base | 86M | 16 | 384 | 74.5% | Available | Available |
| OpenVision-ViT-Base | 86M | 8 | 160 | 74.8% | Available | Available |
| OpenVision-ViT-Base | 86M | 8 | 224 | 75.4% | [Available](https://huggingface.co/UCSC-VLAA/openvision |
$ claude mcp add OpenVision \
-- python -m otcore.mcp_server <graph>