sanps commited on
Commit
05571a0
·
verified ·
1 Parent(s): 6164fab

Update model card: drop POPE, correct ScienceQA to 36.0%, add inference modes table

Browse files
Files changed (1) hide show
  1. README.md +74 -7
README.md CHANGED
@@ -30,10 +30,7 @@ A compact vision-language model that uses **foveated attention** to compress eac
30
 
31
  | Benchmark | fVLM-135M | SmolVLM2-256M | SmolVLM2-500M | SmolVLM2-2.2B |
32
  |-----------|:---------:|:------------:|:------------:|:------------:|
33
- | **ScienceQA** (2017 MCQ) | 36.4% | 73.8% | 80.0% | 89.6% |
34
- | **POPE** (9000 Y/N) | 50.0%* | — | — | — |
35
-
36
- \* POPE at 50% = random baseline. The 135M model always predicts one class. Not reported by SmolVLM2.
37
 
38
  > **Key context**: fVLM-135M uses **1 visual token per frame** vs SmolVLM2's 64-256 tokens per image. fVLM-135M has 158M params total — 1.6x smaller than SmolVLM2-256M. The gap on video benchmarks (4-5%) is modest given the extreme compression.
39
 
@@ -45,7 +42,7 @@ fVLM supports three inference modes with different speed/quality tradeoffs:
45
  |-----------|:----------:|:-----------:|:--------------:|
46
  | MVBench | 27.4% | **28.0%** | 27.9% |
47
  | Video-MME | 26.2% | **29.5%** | 28.7% |
48
- | ScienceQA | **36.4%** | 35.6% | 35.4% |
49
 
50
  - **Coarse-Only**: Single static-query pass (fastest, no foveation)
51
  - **Coarse→Fine**: Two-pass parallel forward (training mode, with foveated attention)
@@ -54,7 +51,7 @@ fVLM supports three inference modes with different speed/quality tradeoffs:
54
  ### Analysis
55
 
56
  - **Foveation helps on video**: coarse→fine adds +3.3% on Video-MME over coarse-only, confirming that learned "where to look" queries improve video understanding
57
- - **ScienceQA**: Best at 36.4% with coarse-only — static images don't benefit from temporal foveation
58
  - **Scale gap**: The large gap on ScienceQA (36% vs 74%) shows the 135M backbone limits image reasoning. Video benchmarks are closer because foveated compression is highly efficient for temporal tasks
59
 
60
  ## Architecture
@@ -99,8 +96,12 @@ This enables processing **64+ frames** with the same memory as a few frames in t
99
 
100
  ## Usage
101
 
 
 
102
  ```python
103
  import torch
 
 
104
  from huggingface_hub import hf_hub_download
105
  from release.model import FoveatedVLM
106
 
@@ -119,9 +120,75 @@ model = FoveatedVLM(
119
  # Load weights
120
  state_dict = torch.load(ckpt_path, map_location="cpu")
121
  model.load_state_dict(state_dict)
122
- model.eval()
 
 
 
 
 
 
 
 
 
123
  ```
124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  ## License
126
 
127
  Apache 2.0
 
30
 
31
  | Benchmark | fVLM-135M | SmolVLM2-256M | SmolVLM2-500M | SmolVLM2-2.2B |
32
  |-----------|:---------:|:------------:|:------------:|:------------:|
33
+ | **ScienceQA** (2017 MCQ) | 36.0% | 73.8% | 80.0% | 89.6% |
 
 
 
34
 
35
  > **Key context**: fVLM-135M uses **1 visual token per frame** vs SmolVLM2's 64-256 tokens per image. fVLM-135M has 158M params total — 1.6x smaller than SmolVLM2-256M. The gap on video benchmarks (4-5%) is modest given the extreme compression.
36
 
 
42
  |-----------|:----------:|:-----------:|:--------------:|
43
  | MVBench | 27.4% | **28.0%** | 27.9% |
44
  | Video-MME | 26.2% | **29.5%** | 28.7% |
45
+ | ScienceQA | 34.7% | **36.0%** | **36.0%** |
46
 
47
  - **Coarse-Only**: Single static-query pass (fastest, no foveation)
48
  - **Coarse→Fine**: Two-pass parallel forward (training mode, with foveated attention)
 
51
  ### Analysis
52
 
53
  - **Foveation helps on video**: coarse→fine adds +3.3% on Video-MME over coarse-only, confirming that learned "where to look" queries improve video understanding
54
+ - **ScienceQA**: Best at 36.0% with coarse_fine/autoregressive modes foveated attention provides a small benefit even on static images when replicated to 8 frames
55
  - **Scale gap**: The large gap on ScienceQA (36% vs 74%) shows the 135M backbone limits image reasoning. Video benchmarks are closer because foveated compression is highly efficient for temporal tasks
56
 
57
  ## Architecture
 
96
 
97
  ## Usage
98
 
99
+ ### Setup
100
+
101
  ```python
102
  import torch
103
+ from torchvision import transforms
104
+ from transformers import AutoTokenizer
105
  from huggingface_hub import hf_hub_download
106
  from release.model import FoveatedVLM
107
 
 
120
  # Load weights
121
  state_dict = torch.load(ckpt_path, map_location="cpu")
122
  model.load_state_dict(state_dict)
123
+ model = model.to("cuda").to(torch.bfloat16).eval()
124
+
125
+ tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM2-135M-Instruct")
126
+
127
+ # Standard DINO preprocessing
128
+ frame_transform = transforms.Compose([
129
+ transforms.Resize((224, 224)),
130
+ transforms.ToTensor(),
131
+ transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
132
+ ])
133
  ```
134
 
135
+ ### Image Input
136
+
137
+ **Important**: fVLM treats all inputs as video. Static images must be **replicated to 8 frames** to match training distribution (Stage 2 and 3 used `replicate_image_frames: 8`). Passing a single frame for an image will produce degraded results.
138
+
139
+ ```python
140
+ from PIL import Image
141
+
142
+ img = Image.open("photo.jpg").convert("RGB")
143
+ frame_tensor = frame_transform(img) # [3, 224, 224]
144
+ frames = frame_tensor.unsqueeze(0).repeat(8, 1, 1, 1) # [8, 3, 224, 224] — replicate to 8
145
+ frames = frames.unsqueeze(0).to("cuda", dtype=torch.bfloat16) # [1, 8, 3, 224, 224]
146
+ ```
147
+
148
+ ### Video Input
149
+
150
+ For video, sample up to 64 frames uniformly. No replication needed.
151
+
152
+ ```python
153
+ # video_frames: list of PIL Images (sampled from video)
154
+ tensors = [frame_transform(f) for f in video_frames]
155
+ frames = torch.stack(tensors).unsqueeze(0).to("cuda", dtype=torch.bfloat16)
156
+ # frames shape: [1, T, 3, 224, 224] where T = number of frames (1-64)
157
+ ```
158
+
159
+ ### Inference
160
+
161
+ ```python
162
+ # Tokenize prompt
163
+ messages = [
164
+ {"role": "user", "content": "Describe what is happening in this image."},
165
+ ]
166
+ text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
167
+ input_ids = tokenizer.encode(text, return_tensors="pt").to("cuda")
168
+ attention_mask = torch.ones_like(input_ids)
169
+ loss_mask = torch.ones_like(input_ids, dtype=torch.float32)
170
+
171
+ # Forward pass (coarse_fine mode recommended for best quality)
172
+ with torch.no_grad(), torch.amp.autocast("cuda", dtype=torch.bfloat16):
173
+ result = model(
174
+ frames=frames,
175
+ input_ids=input_ids,
176
+ attention_mask=attention_mask,
177
+ loss_mask=loss_mask,
178
+ mode="coarse_fine",
179
+ )
180
+ # result["logits"]: [B, S, V] text logits
181
+ # result["loss"]: scalar cross-entropy loss
182
+ ```
183
+
184
+ ### Inference Modes
185
+
186
+ | Mode | Description | Use Case |
187
+ |------|-------------|----------|
188
+ | `coarse_only` | Single static-query pass | Fastest; good for images |
189
+ | `coarse_fine` | Two-pass parallel forward | Best overall; uses foveated attention |
190
+ | `autoregressive` | Sequential with KV cache | Highest quality for video |
191
+
192
  ## License
193
 
194
  Apache 2.0