Image Feature Extraction
Transformers
Safetensors
English
keural_vision
vision
vision-encoder
image-text
contrastive-learning
knowledge-distillation
adaptive-tokenization
Eval Results (legacy)
Instructions to use mkd-hika/keural-vision-encoder-mid with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use mkd-hika/keural-vision-encoder-mid with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-feature-extraction", model="mkd-hika/keural-vision-encoder-mid")# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("mkd-hika/keural-vision-encoder-mid", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Update model card: training complete, full eval results, benchmark comparisons, saliency evolution, loss curves
Browse files- .gitattributes +4 -0
- README.md +46 -10
- benchmark_comparison_chart.png +3 -0
- benchmark_recall_curve_chart.png +3 -0
- saliency_evolution_9ckpt.png +3 -0
- training_loss_curves.png +3 -0
.gitattributes
CHANGED
|
@@ -34,3 +34,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
pipeline_preview.gif filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
pipeline_preview.gif filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
benchmark_comparison_chart.png filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
benchmark_recall_curve_chart.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
saliency_evolution_9ckpt.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
training_loss_curves.png filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
|
@@ -26,7 +26,7 @@ pipeline_tag: image-feature-extraction
|
|
| 26 |
<img alt="params" src="https://img.shields.io/badge/params-183.5M-blue"/>
|
| 27 |
<img alt="from scratch" src="https://img.shields.io/badge/trained-from%20scratch-success"/>
|
| 28 |
<img alt="precision" src="https://img.shields.io/badge/precision-bfloat16-informational"/>
|
| 29 |
-
<img alt="status" src="https://img.shields.io/badge/status-
|
| 30 |
</p>
|
| 31 |
|
| 32 |
> Developed by **MKD Co., Ltd.**
|
|
@@ -54,9 +54,9 @@ It introduces three mechanisms not found together in existing encoders (CLIP, Si
|
|
| 54 |
- **Research** into adaptive tokenization, hierarchical token typing, and resolution-elastic position encoding.
|
| 55 |
|
| 56 |
### Limitations
|
| 57 |
-
- **
|
| 58 |
-
- **
|
| 59 |
-
- **Domain/bias.** Trained on web image–text pairs
|
| 60 |
- **Not a safety-filtered model.** No content moderation or de-biasing has been applied.
|
| 61 |
|
| 62 |
---
|
|
@@ -85,7 +85,7 @@ image = Image.open("example.jpg").convert("RGB")
|
|
| 85 |
pixel_values = transform(image).unsqueeze(0) # (1, 3, 384, 384)
|
| 86 |
|
| 87 |
with torch.no_grad():
|
| 88 |
-
out = model(pixel_values=pixel_values)
|
| 89 |
|
| 90 |
image_embedding = torch.nn.functional.normalize(out.pooled, dim=-1) # (1, 768)
|
| 91 |
|
|
@@ -96,6 +96,13 @@ print(out.spatial_metadata.shape) # (1, 512, 4) cx, cy, scale_w, scale_h
|
|
| 96 |
print(out.saliency_scores.shape) # (1, 512) per-token importance
|
| 97 |
```
|
| 98 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
### Output fields
|
| 100 |
|
| 101 |
| Field | Shape | Description |
|
|
@@ -135,7 +142,7 @@ The `pooled` image embedding is the `[POOL]` token after the final RMSNorm (no s
|
|
| 135 |
| FFN | SwiGLU (hidden = 3072) |
|
| 136 |
| Normalization | RMSNorm |
|
| 137 |
| Position encoding | Continuous 2D-RoPE + scale bias |
|
| 138 |
-
| Token budget | 512 default, up to 2048 |
|
| 139 |
| Precision | bfloat16 |
|
| 140 |
| Input resolution | 384×384, 448×448 |
|
| 141 |
|
|
@@ -145,22 +152,45 @@ The `pooled` image embedding is the `[POOL]` token after the final RMSNorm (no s
|
|
| 145 |
|
| 146 |
| | |
|
| 147 |
|---|---|
|
| 148 |
-
| Data | ~20M image–text pairs
|
| 149 |
| Hardware | 2× NVIDIA H200 (141 GB) |
|
| 150 |
| Objective | SigLIP contrastive + HCT contrastive + saliency regularizer + dual-teacher cosine distillation |
|
| 151 |
| Teachers (frozen) | SigLIP-SO400M (1152-d) + InternViT-300M (1024-d) |
|
| 152 |
| Optimizer | AdamW, lr 5e-4, cosine schedule, 2K warmup, weight decay 0.05 |
|
| 153 |
| Effective batch | 3,072 (768 × 2 grad-accum × 2 GPUs, distributed `all_gather` negatives) |
|
| 154 |
-
| Schedule |
|
| 155 |
| Precision | bfloat16 (mixed) |
|
|
|
|
| 156 |
|
| 157 |
**Loss.** `L_total = L_primary + λ_hct·L_hct + λ_sal·β_sal·L_saliency + L_distill`, where `L_primary` and `L_hct` are sigmoid image↔text losses (on the pooled embedding and on the mean of global tokens respectively), `L_saliency` is an anti-collapse + total-variation regularizer on the saliency map, and `L_distill` is cosine distance to the two frozen teachers.
|
| 158 |
|
|
|
|
|
|
|
| 159 |
---
|
| 160 |
|
| 161 |
## Evaluation
|
| 162 |
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
|
| 165 |
---
|
| 166 |
|
|
@@ -186,6 +216,12 @@ Both teachers are frozen and used only during training; they are not required fo
|
|
| 186 |
| Position encoding | Learned absolute | Learned absolute | Learned absolute | **Continuous 2D-RoPE** |
|
| 187 |
| Saliency-aware | No | No | No | **Yes** |
|
| 188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
---
|
| 190 |
|
| 191 |
## Roadmap
|
|
@@ -193,7 +229,7 @@ Both teachers are frozen and used only during training; they are not required fo
|
|
| 193 |
| Stage | Params | Status |
|
| 194 |
|---|---|---|
|
| 195 |
| PoC | 24.7M | Complete |
|
| 196 |
-
| **Mid** | **183.5M** | **Training** |
|
| 197 |
| Large | ~1.1B | Planned |
|
| 198 |
|
| 199 |
---
|
|
|
|
| 26 |
<img alt="params" src="https://img.shields.io/badge/params-183.5M-blue"/>
|
| 27 |
<img alt="from scratch" src="https://img.shields.io/badge/trained-from%20scratch-success"/>
|
| 28 |
<img alt="precision" src="https://img.shields.io/badge/precision-bfloat16-informational"/>
|
| 29 |
+
<img alt="status" src="https://img.shields.io/badge/status-training%20complete-success"/>
|
| 30 |
</p>
|
| 31 |
|
| 32 |
> Developed by **MKD Co., Ltd.**
|
|
|
|
| 54 |
- **Research** into adaptive tokenization, hierarchical token typing, and resolution-elastic position encoding.
|
| 55 |
|
| 56 |
### Limitations
|
| 57 |
+
- **Accuracy trails same-size peers.** Zero-shot ImageNet Top-1 is 37.2%, versus 68.6% for CLIP ViT-B/16 (~86M params) and 76.7% for SigLIP ViT-B/16 (~93M params) — both smaller than this model. This is attributed to a training-budget gap (18K steps on ~20M pairs, vs. peers trained on 12M-400M+ pairs over far more steps) rather than an architecture ceiling: training loss was still declining at the final step. See [Evaluation](#evaluation).
|
| 58 |
+
- **Saliency mechanism is real but token placement is still settling.** The learned saliency map produces stable, object-tracking contours on images with a clear dominant subject. However, the *discrete* tokens it samples continued shifting meaningfully until very late in training (only ~50% overlap with the final checkpoint's token positions as of step 13-14K, reaching ~73% by step 16K) — exact token placement had not fully converged even at the final checkpoint.
|
| 59 |
+
- **Domain/bias.** Trained on web image–text pairs; it inherits the coverage and biases of that distribution and is English-text aligned.
|
| 60 |
- **Not a safety-filtered model.** No content moderation or de-biasing has been applied.
|
| 61 |
|
| 62 |
---
|
|
|
|
| 85 |
pixel_values = transform(image).unsqueeze(0) # (1, 3, 384, 384)
|
| 86 |
|
| 87 |
with torch.no_grad():
|
| 88 |
+
out = model(pixel_values=pixel_values, token_budget=512) # match training exactly
|
| 89 |
|
| 90 |
image_embedding = torch.nn.functional.normalize(out.pooled, dim=-1) # (1, 768)
|
| 91 |
|
|
|
|
| 96 |
print(out.saliency_scores.shape) # (1, 512) per-token importance
|
| 97 |
```
|
| 98 |
|
| 99 |
+
> **Note:** pass `token_budget=512` explicitly. Training always used a fixed
|
| 100 |
+
> budget of 512 tokens; leaving `token_budget` unset falls back to
|
| 101 |
+
> resolution-based auto-scaling (e.g. 1,152 tokens at 384px), which the model
|
| 102 |
+
> was not trained on. Evaluation showed this mismatch moves results by <1
|
| 103 |
+
> point, so it's a minor effect, but 512 is the methodologically correct
|
| 104 |
+
> setting to match training.
|
| 105 |
+
|
| 106 |
### Output fields
|
| 107 |
|
| 108 |
| Field | Shape | Description |
|
|
|
|
| 142 |
| FFN | SwiGLU (hidden = 3072) |
|
| 143 |
| Normalization | RMSNorm |
|
| 144 |
| Position encoding | Continuous 2D-RoPE + scale bias |
|
| 145 |
+
| Token budget | 512 default (training-matched), up to 2048 |
|
| 146 |
| Precision | bfloat16 |
|
| 147 |
| Input resolution | 384×384, 448×448 |
|
| 148 |
|
|
|
|
| 152 |
|
| 153 |
| | |
|
| 154 |
|---|---|
|
| 155 |
+
| Data | ~20M image–text pairs |
|
| 156 |
| Hardware | 2× NVIDIA H200 (141 GB) |
|
| 157 |
| Objective | SigLIP contrastive + HCT contrastive + saliency regularizer + dual-teacher cosine distillation |
|
| 158 |
| Teachers (frozen) | SigLIP-SO400M (1152-d) + InternViT-300M (1024-d) |
|
| 159 |
| Optimizer | AdamW, lr 5e-4, cosine schedule, 2K warmup, weight decay 0.05 |
|
| 160 |
| Effective batch | 3,072 (768 × 2 grad-accum × 2 GPUs, distributed `all_gather` negatives) |
|
| 161 |
+
| Schedule | 18,000 optimizer steps, complete |
|
| 162 |
| Precision | bfloat16 (mixed) |
|
| 163 |
+
| Final loss | 2.87 total (down from 21.56 at step 0), still declining at completion |
|
| 164 |
|
| 165 |
**Loss.** `L_total = L_primary + λ_hct·L_hct + λ_sal·β_sal·L_saliency + L_distill`, where `L_primary` and `L_hct` are sigmoid image↔text losses (on the pooled embedding and on the mean of global tokens respectively), `L_saliency` is an anti-collapse + total-variation regularizer on the saliency map, and `L_distill` is cosine distance to the two frozen teachers.
|
| 166 |
|
| 167 |
+

|
| 168 |
+
|
| 169 |
---
|
| 170 |
|
| 171 |
## Evaluation
|
| 172 |
|
| 173 |
+
Evaluated on the final checkpoint with `token_budget=512` (exactly matching training).
|
| 174 |
+
|
| 175 |
+
| Benchmark | Result |
|
| 176 |
+
|---|---|
|
| 177 |
+
| ImageNet zero-shot Top-1 | **37.2%** |
|
| 178 |
+
| ImageNet zero-shot Top-5 | 66.8% |
|
| 179 |
+
| Flickr30K Image→Text R@1 / R@5 / R@10 | 42.9% / 72.7% / 80.6% |
|
| 180 |
+
| Flickr30K Text→Image R@1 / R@5 / R@10 | 42.2% / 70.0% / 79.4% |
|
| 181 |
+
| CIFAR-100 linear probe Top-1 | 75.0% |
|
| 182 |
+
|
| 183 |
+

|
| 184 |
+
|
| 185 |
+

|
| 186 |
+
|
| 187 |
+
**Context.** Against its own distillation teachers, Keural Mid retains ~45% of SigLIP-SO400M's zero-shot ImageNet accuracy (83.1%) and ~48-56% of its Flickr30K retrieval R@1, after 18K steps on ~20M pairs vs. teachers trained on billions of pairs. Against same-parameter-class peers (CLIP ViT-B/16, SigLIP ViT-B/16 — both smaller than this model), accuracy trails by roughly 2x. Both gaps are consistent with a **training-budget** shortfall rather than an architecture ceiling: loss was still declining at the final step. A compute/data-matched fixed-grid baseline is the recommended next experiment to isolate the ATB architecture's own contribution from this gap.
|
| 188 |
+
|
| 189 |
+
### Adaptive tokenizer — saliency & token placement
|
| 190 |
+
|
| 191 |
+

|
| 192 |
+
|
| 193 |
+
The learned saliency map produces sharp, stable contours that track each image's dominant subject, visible from mid-training through the final checkpoint. Quantitatively, the continuous saliency map stabilizes fast (cosine similarity to the final checkpoint reaches ~0.83-0.90 within the first few thousand steps), but the *discrete* sampled token positions are considerably less stable — only ~50% overlap with the final checkpoint's tokens by step 13-14K, jumping to 73% at step 16K. Exact token placement was still moving late into training even where the saliency field itself looked converged.
|
| 194 |
|
| 195 |
---
|
| 196 |
|
|
|
|
| 216 |
| Position encoding | Learned absolute | Learned absolute | Learned absolute | **Continuous 2D-RoPE** |
|
| 217 |
| Saliency-aware | No | No | No | **Yes** |
|
| 218 |
|
| 219 |
+
| Same-parameter-class peer | Params | ImageNet Zero-shot Top-1 | Flickr30K I2T R@1 |
|
| 220 |
+
|---|---|---|---|
|
| 221 |
+
| **Keural Mid** | 183.6M | 37.2% | 42.9% |
|
| 222 |
+
| CLIP ViT-B/16 (OpenAI) | ~86M | 68.6% | 88.2% |
|
| 223 |
+
| SigLIP ViT-B/16 | ~93M | 76.7% | — |
|
| 224 |
+
|
| 225 |
---
|
| 226 |
|
| 227 |
## Roadmap
|
|
|
|
| 229 |
| Stage | Params | Status |
|
| 230 |
|---|---|---|
|
| 231 |
| PoC | 24.7M | Complete |
|
| 232 |
+
| **Mid** | **183.5M** | **Training complete — evaluation published** |
|
| 233 |
| Large | ~1.1B | Planned |
|
| 234 |
|
| 235 |
---
|
benchmark_comparison_chart.png
ADDED
|
Git LFS Details
|
benchmark_recall_curve_chart.png
ADDED
|
Git LFS Details
|
saliency_evolution_9ckpt.png
ADDED
|
Git LFS Details
|
training_loss_curves.png
ADDED
|
Git LFS Details
|