mkd-hika commited on
Commit
77e9a50
·
0 Parent(s):

Duplicate from mkd-hika/keural-vision-encoder-mid

Browse files
.gitattributes ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip 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
41
+ architecture_block_diagram.png filter=lfs diff=lfs merge=lfs -text
42
+ benchmark_radar_chart.png filter=lfs diff=lfs merge=lfs -text
43
+ benchmark_recall_at10_chart.png filter=lfs diff=lfs merge=lfs -text
44
+ benchmark_recall_at5_chart.png filter=lfs diff=lfs merge=lfs -text
45
+ keural_mid_architecture.png filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,367 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language: en
3
+ license: other
4
+ license_name: proprietary
5
+ license_link: LICENSE
6
+ tags:
7
+ - vision
8
+ - vision-encoder
9
+ - image-text
10
+ - contrastive-learning
11
+ - knowledge-distillation
12
+ - adaptive-tokenization
13
+ library_name: transformers
14
+ pipeline_tag: image-feature-extraction
15
+ model-index:
16
+ - name: keural-vision-encoder-mid
17
+ results:
18
+ - task:
19
+ type: zero-shot-image-classification
20
+ name: Zero-Shot Image Classification
21
+ dataset:
22
+ type: imagenet-1k
23
+ name: ImageNet-1k (validation)
24
+ metrics:
25
+ - type: accuracy
26
+ value: 37.2
27
+ name: Top-1 accuracy
28
+ - type: accuracy
29
+ value: 66.8
30
+ name: Top-5 accuracy
31
+ - task:
32
+ type: image-to-text
33
+ name: Image-to-Text Retrieval
34
+ dataset:
35
+ type: nlphuji/flickr30k
36
+ name: Flickr30K
37
+ metrics:
38
+ - type: recall
39
+ value: 42.9
40
+ name: Image-to-Text R@1
41
+ - type: recall
42
+ value: 80.6
43
+ name: Image-to-Text R@10
44
+ - type: recall
45
+ value: 42.2
46
+ name: Text-to-Image R@1
47
+ - type: recall
48
+ value: 79.4
49
+ name: Text-to-Image R@10
50
+ - task:
51
+ type: image-classification
52
+ name: Linear Probe
53
+ dataset:
54
+ type: cifar100
55
+ name: CIFAR-100
56
+ metrics:
57
+ - type: accuracy
58
+ value: 75.0
59
+ name: Linear probe Top-1
60
+ ---
61
+
62
+ # Keural Mid-Level Vision Encoder
63
+
64
+ *A 183.5M-parameter image encoder built from scratch — adaptive tokenization, hierarchical concept tokens, and continuous 2D positional encoding. Not a CLIP/ViT fine-tune.*
65
+
66
+ ![Keural Mid architecture](keural_mid_architecture.png)
67
+
68
+ <p>
69
+ <img alt="params" src="https://img.shields.io/badge/params-183.6M-blue"/>
70
+ <img alt="from scratch" src="https://img.shields.io/badge/trained-from%20scratch-success"/>
71
+ <img alt="precision" src="https://img.shields.io/badge/precision-bfloat16-informational"/>
72
+ <img alt="status" src="https://img.shields.io/badge/status-training%20complete-success"/>
73
+ <img alt="pope" src="https://img.shields.io/badge/downstream%20POPE%20vs%20blind-%2B25.95-brightgreen"/>
74
+ <img alt="mme" src="https://img.shields.io/badge/downstream%20MME%20vs%20blind-%2B446.9-brightgreen"/>
75
+ </p>
76
+
77
+ > Developed by **MKD Co., Ltd.** · Code: [github.com/mkd-hika/Keural-Vision-Encoder-Mid-level](https://github.com/mkd-hika/Keural-Vision-Encoder-Mid-level)
78
+
79
+ ---
80
+
81
+ ## At a Glance
82
+
83
+ | | |
84
+ |---|---|
85
+ | **Parameters** | 183,575,297 (183.6M) |
86
+ | **Input** | RGB image, 384×384 (any multiple of 16 supported natively) |
87
+ | **Output** | 512 adaptive tokens (768-dim) + one pooled 768-dim image embedding |
88
+ | **Trained** | From random init on ~20M image–text pairs, 18,000 steps, 2× H200 |
89
+ | **Precision** | bfloat16 |
90
+
91
+ | Benchmark | Result |
92
+ |---|---|
93
+ | ImageNet zero-shot Top-1 / Top-5 | 37.2% / 66.8% |
94
+ | Flickr30K Image→Text R@1 / R@5 / R@10 | 42.9% / 72.7% / 80.6% |
95
+ | Flickr30K Text→Image R@1 / R@5 / R@10 | 42.2% / 70.0% / 79.4% |
96
+ | CIFAR-100 linear probe | 75.0% |
97
+
98
+ Measured at 384×384 with `token_budget=512`, matching training. Accuracy trails
99
+ same-size peers — see [Limitations](#limitations) and [Evaluation](#evaluation)
100
+ for why, and for the higher-k retrieval results where the gap closes.
101
+
102
+ ---
103
+
104
+ ## Downstream Results — Vision-Language Model
105
+
106
+ The encoder is **frozen** and used as-is inside a bilingual (English + Korean)
107
+ vision-language model: [`mkd-hika/keural-mid-vlm-bilingual`](https://huggingface.co/mkd-hika/keural-mid-vlm-bilingual).
108
+ Only a projector (8.9M) and LoRA adapters (5.0M) are trained on top; the decoder is
109
+ Qwen2.5-7B-Instruct.
110
+
111
+ A vision-language model can score respectably while barely using the image, because
112
+ many questions are answerable from language priors alone. Each benchmark below is
113
+ therefore run **twice** — once normally, once with the visual tokens removed and
114
+ everything else held constant. **The difference is what this encoder contributes**,
115
+ and it is the only figure the language model cannot produce on its own.
116
+
117
+ | Benchmark | With this encoder | Blind | **Encoder contributes** |
118
+ |---|---|---|---|
119
+ | POPE accuracy (n=2,000) | **70.50%** | 44.55% | **+25.95** |
120
+ | POPE F1 (n=2,000) | **70.59%** | 23.46% | **+47.13** |
121
+ | VQAv2 strict (n=5,000) | **53.04%** | 39.83% | **+13.21** |
122
+ | MME total, 14 categories (n=2,374) | **1258.9** | 812.0 | **+446.9** |
123
+ | MMBench (n=4,377) | 60.20% | — | — |
124
+ | Held-out perplexity (KO / EN) | 2.15 / 2.99 | — | — |
125
+
126
+ The POPE yes-ratio is **0.492 against a gold ratio of 0.500**, so the model genuinely
127
+ discriminates on object-existence questions rather than defaulting to one answer —
128
+ accuracy alone is not interpretable without that check. The blind VQAv2 score of
129
+ 39.83% lands where language-prior performance is expected to, which is corroborating
130
+ evidence that the measurement is sound.
131
+
132
+ Notably, the encoder reaches these numbers while scoring 37.2% zero-shot on ImageNet.
133
+ Zero-shot accuracy measures image–text *alignment*; the 75.0% CIFAR-100 linear probe
134
+ is the better indicator of representation quality for downstream use, because a
135
+ trained projector relearns the alignment from scratch.
136
+
137
+ ---
138
+
139
+ ## Model Description
140
+
141
+ **Keural Mid** is a mid-scale vision encoder that maps an image to a single 768-dim embedding aligned to a text embedding space, plus a variable-length sequence of semantically-typed tokens. It is trained from random initialization (no CLIP/ViT/DINO backbone) with a combination of sigmoid contrastive learning, hierarchical concept alignment, saliency regularization, and dual-teacher knowledge distillation.
142
+
143
+ It introduces three mechanisms not found together in existing encoders (CLIP, SigLIP, DINOv2):
144
+
145
+ | Innovation | What it does |
146
+ |---|---|
147
+ | **ATB — Adaptive Token Budget** | Content-aware token allocation. A learned saliency map drives a differentiable Gumbel-Top-K sampler, spending more tokens on complex regions and fewer on simple backgrounds. |
148
+ | **HCT — Hierarchical Concept Tokenization** | Every token carries a semantic level — `global`, `region`, or `detail` — via learned level embeddings and level-specific constructors. |
149
+ | **Continuous 2D-RoPE** | Rotary position encoding from actual normalized `(cx, cy)` coordinates plus a log-area scale bias, so variable resolutions and token scales are handled natively. |
150
+
151
+ ---
152
+
153
+ ## Intended Uses & Limitations
154
+
155
+ ### Intended uses
156
+ - **Image feature extraction** — a global `pooled` embedding for retrieval, clustering, or as a frozen backbone for downstream heads (e.g. linear probing, detection, captioning front-ends).
157
+ - **Research** into adaptive tokenization, hierarchical token typing, and resolution-elastic position encoding.
158
+
159
+ ### Limitations
160
+ - **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).
161
+ - **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.
162
+ - **Domain/bias.** Trained on web image–text pairs; it inherits the coverage and biases of that distribution and is English-text aligned.
163
+ - **Not a safety-filtered model.** No content moderation or de-biasing has been applied.
164
+
165
+ ---
166
+
167
+ ## How to Use
168
+
169
+ ```python
170
+ import torch
171
+ from PIL import Image
172
+ from torchvision import transforms
173
+ from transformers import AutoModel
174
+
175
+ model = AutoModel.from_pretrained(
176
+ "mkd-hika/keural-vision-encoder-mid",
177
+ trust_remote_code=True,
178
+ ).eval()
179
+
180
+ transform = transforms.Compose([
181
+ transforms.Resize(384, interpolation=transforms.InterpolationMode.BICUBIC),
182
+ transforms.CenterCrop(384),
183
+ transforms.ToTensor(),
184
+ transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
185
+ ])
186
+
187
+ image = Image.open("example.jpg").convert("RGB")
188
+ pixel_values = transform(image).unsqueeze(0) # (1, 3, 384, 384)
189
+
190
+ with torch.no_grad():
191
+ out = model(pixel_values=pixel_values, token_budget=512) # match training exactly
192
+
193
+ image_embedding = torch.nn.functional.normalize(out.pooled, dim=-1) # (1, 768)
194
+
195
+ print(out.tokens.shape) # (1, 512, 768) per-token features
196
+ print(out.pooled.shape) # (1, 768) global image embedding
197
+ print(out.level_ids.shape) # (1, 512) 0=global, 1=region, 2=detail
198
+ print(out.spatial_metadata.shape) # (1, 512, 4) cx, cy, scale_w, scale_h
199
+ print(out.saliency_scores.shape) # (1, 512) per-token importance
200
+ ```
201
+
202
+ > **Checkpoints.** The repo root holds the final model (step 18,000). Earlier
203
+ > checkpoints are available as subfolders for studying training dynamics:
204
+ > `checkpoint-9000`, `checkpoint-10000`, `checkpoint-15000`, `checkpoint-18000`
205
+ > — load one with `AutoModel.from_pretrained(..., subfolder="checkpoint-15000")`.
206
+
207
+ > **Note:** pass `token_budget=512` explicitly. Training always used a fixed
208
+ > budget of 512 tokens; leaving `token_budget` unset falls back to
209
+ > resolution-based auto-scaling (e.g. 1,152 tokens at 384px), which the model
210
+ > was not trained on. Evaluation showed this mismatch moves results by <1
211
+ > point, so it's a minor effect, but 512 is the methodologically correct
212
+ > setting to match training.
213
+
214
+ ### Output fields
215
+
216
+ | Field | Shape | Description |
217
+ |---|---|---|
218
+ | `pooled` | `(B, 768)` | Global image embedding (`[POOL]` token output). |
219
+ | `tokens` | `(B, N, 768)` | Per-token feature vectors (`N` = allocated token budget). |
220
+ | `level_ids` | `(B, N)` | Semantic level per token: `0`=global, `1`=region, `2`=detail. |
221
+ | `spatial_metadata` | `(B, N, 4)` | `(cx, cy, scale_w, scale_h)`, normalized to `[0, 1]`. |
222
+ | `saliency_scores` | `(B, N)` | Per-token importance in `[0, 1]`. |
223
+ | `attention_mask` | `(B, N)` | Valid-token mask. |
224
+
225
+ ---
226
+
227
+ ## Architecture
228
+
229
+ The figure above is the complete specification: **(a)** the tokenizer stack
230
+ (CNN stem → saliency → ATB → HCT), **(b)** the spatial transformer block and
231
+ continuous 2D-RoPE, **(c)** the output contract, dual-teacher distillation, and
232
+ the training objective.
233
+
234
+
235
+ The `pooled` image embedding is the `[POOL]` token after the final RMSNorm (no separate projection head). For contrastive training it is aligned against a trainable projection of a frozen CLIP text encoder.
236
+
237
+ ### Model specifications
238
+
239
+ | | |
240
+ |---|---|
241
+ | Parameters | 183,575,297 (183.5M) |
242
+ | Embedding dimension | 768 |
243
+ | Transformer depth | 24 blocks |
244
+ | Attention heads | 12 (head_dim = 64) |
245
+ | FFN | SwiGLU (hidden = 3072) |
246
+ | Normalization | RMSNorm |
247
+ | Position encoding | Continuous 2D-RoPE + scale bias |
248
+ | Token budget | 512 default (training-matched), up to 2048 |
249
+ | Precision | bfloat16 |
250
+ | Input resolution | 384×384, 448×448 |
251
+
252
+ ---
253
+
254
+ ## Training
255
+
256
+ | | |
257
+ |---|---|
258
+ | Data | ~20M image–text pairs |
259
+ | Hardware | 2× NVIDIA H200 (141 GB) |
260
+ | Objective | SigLIP contrastive + HCT contrastive + saliency regularizer + dual-teacher cosine distillation |
261
+ | Teachers (frozen) | SigLIP-SO400M (1152-d) + InternViT-300M (1024-d) |
262
+ | Optimizer | AdamW, lr 5e-4, cosine schedule, 2K warmup, weight decay 0.05 |
263
+ | Effective batch | 3,072 (768 × 2 grad-accum × 2 GPUs, distributed `all_gather` negatives) |
264
+ | Schedule | 18,000 optimizer steps, complete |
265
+ | Precision | bfloat16 (mixed) |
266
+ | Final loss | 2.87 total (down from 21.56 at step 0), still declining at completion |
267
+
268
+ **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.
269
+
270
+ ![Training loss curves](training_loss_curves.png)
271
+
272
+ ---
273
+
274
+ ## Distillation Teachers
275
+
276
+ | Teacher | Params | Embed dim | Projection to 768 |
277
+ |---|---|---|---|
278
+ | SigLIP-SO400M | 400M | 1152 | `Linear(1152 → 768)` |
279
+ | InternViT-300M | 300M | 1024 | `Linear(1024 → 768)` |
280
+
281
+ Both teachers are frozen and used only during training; they are not required for inference.
282
+
283
+ ---
284
+
285
+ ## Evaluation
286
+
287
+ Evaluated on the final checkpoint with `token_budget=512` (exactly matching training).
288
+
289
+ | Benchmark | Result |
290
+ |---|---|
291
+ | ImageNet zero-shot Top-1 | **37.2%** |
292
+ | ImageNet zero-shot Top-5 | 66.8% |
293
+ | Flickr30K Image→Text R@1 / R@5 / R@10 | 42.9% / 72.7% / 80.6% |
294
+ | Flickr30K Text→Image R@1 / R@5 / R@10 | 42.2% / 70.0% / 79.4% |
295
+ | CIFAR-100 linear probe Top-1 | 75.0% |
296
+
297
+ ![Benchmark comparison](benchmark_comparison_chart.png)
298
+
299
+ ![Flickr30K Recall@k](benchmark_recall_curve_chart.png)
300
+
301
+ ![Multi-axis comparison](benchmark_radar_chart.png)
302
+
303
+ **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.
304
+
305
+ #### The R@1 gap narrows sharply at higher k
306
+
307
+ The headline R@1 numbers understate retrieval quality. Broken out by k:
308
+
309
+ ![Flickr30K Recall@5](benchmark_recall_at5_chart.png)
310
+
311
+ ![Flickr30K Recall@10](benchmark_recall_at10_chart.png)
312
+
313
+ On **Text→Image R@5, Keural Mid (70.0%) outperforms CLIP ViT-B/16 trained on WIT-400M (57.2%)**, and at R@10 it leads 79.4% vs. 68.0% — despite that baseline having seen ~20x more training data. The correct-image is usually retrieved within the top few results even when it isn't ranked first, which suggests the embedding space is broadly well-organized and that the R@1 shortfall is largely a ranking-precision issue rather than a representation-quality one. (Note the CC12M-trained CLIP variant still leads at these k, so this is not a uniform win — it is specific to the WIT-400M baseline on the text→image direction.)
314
+
315
+ ### Adaptive tokenizer — saliency & token placement
316
+
317
+ ![Saliency evolution across training](saliency_evolution_9ckpt.png)
318
+
319
+ 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.
320
+
321
+ ---
322
+
323
+ ---
324
+
325
+ ## Comparison with Existing Encoders
326
+
327
+ | Feature | CLIP ViT-L | SigLIP-SO400M | DINOv2-L | **Keural Mid** |
328
+ |---|---|---|---|---|
329
+ | Parameters | 307M | 400M | 307M | **183.5M** |
330
+ | Tokenization | Fixed patches | Fixed patches | Fixed patches | **Adaptive (ATB)** |
331
+ | Token count | Fixed | Fixed | Fixed | **Variable (512–2048)** |
332
+ | Semantic token levels | — | — | — | **3-level (HCT)** |
333
+ | Position encoding | Learned absolute | Learned absolute | Learned absolute | **Continuous 2D-RoPE** |
334
+ | Saliency-aware | No | No | No | **Yes** |
335
+
336
+ | Same-parameter-class peer | Params | ImageNet Zero-shot Top-1 | Flickr30K I2T R@1 |
337
+ |---|---|---|---|
338
+ | **Keural Mid** | 183.6M | 37.2% | 42.9% |
339
+ | CLIP ViT-B/16 (OpenAI) | ~86M | 68.6% | 88.2% |
340
+ | SigLIP ViT-B/16 | ~93M | 76.7% | — |
341
+
342
+ ---
343
+
344
+ ## Roadmap
345
+
346
+ | Stage | Params | Status |
347
+ |---|---|---|
348
+ | PoC | 24.7M | Complete |
349
+ | **Mid** | **183.6M** | **Stage 1 complete; Stage 2 VLM published — [keural-mid-vlm-bilingual](https://huggingface.co/mkd-hika/keural-mid-vlm-bilingual)** |
350
+ | Large | ~1.1B | Planned |
351
+
352
+ ---
353
+
354
+ ## Citation
355
+
356
+ ```bibtex
357
+ @misc{keural-mid-2026,
358
+ title = {Keural Mid-Level Vision Encoder},
359
+ author = {MKD Co., Ltd.},
360
+ year = {2026},
361
+ url = {https://huggingface.co/mkd-hika/keural-vision-encoder-mid}
362
+ }
363
+ ```
364
+
365
+ ## License
366
+
367
+ Copyright © 2026 MKD Co., Ltd. All Rights Reserved. Proprietary — see `LICENSE`.
alignment_state.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:10c8ef42816f2f2dab26de3295ef8ffb651c515feba37fde5785caabdba5d99a
3
+ size 9050229
benchmark_comparison_chart.png ADDED

Git LFS Details

  • SHA256: 521a525e1a2a2ce5b40c6f845260931e603323254130079d78fd9e59428585d8
  • Pointer size: 131 Bytes
  • Size of remote file: 273 kB
benchmark_radar_chart.png ADDED

Git LFS Details

  • SHA256: 9c915550422be8efcdaf16ecdb35c3002ccfbb2f06e273a7ce8754a47c089378
  • Pointer size: 131 Bytes
  • Size of remote file: 374 kB
benchmark_recall_at10_chart.png ADDED

Git LFS Details

  • SHA256: 7c3fc9f3d5da5002a4eff43694e4e11dce5d86bd178cfa699697cb8dd31843e0
  • Pointer size: 131 Bytes
  • Size of remote file: 227 kB
benchmark_recall_at5_chart.png ADDED

Git LFS Details

  • SHA256: 821f653da750827b5c8cc97710e5c907ec5544052bfc5ddd239d3f913fe34909
  • Pointer size: 131 Bytes
  • Size of remote file: 226 kB
benchmark_recall_curve_chart.png ADDED

Git LFS Details

  • SHA256: 3bf31e0cd78d77dcd7d9d0291d7096a6535f6385b34fad4219890f3c0edc8c45
  • Pointer size: 131 Bytes
  • Size of remote file: 254 kB
checkpoint-10000/config.json ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "KeuralVisionModel"
4
+ ],
5
+ "default_token_budget": 512,
6
+ "depth": 24,
7
+ "dtype": "float32",
8
+ "embed_dim": 768,
9
+ "keural_config": {
10
+ "data": {
11
+ "captions_path": "/home/work/keural-model/vision-encoder-dataset/indexes/datacomp_train.tsv",
12
+ "dataset_name": "cc3m",
13
+ "extra_sources": [],
14
+ "image_buckets": [
15
+ [
16
+ 384,
17
+ 384
18
+ ],
19
+ [
20
+ 448,
21
+ 448
22
+ ]
23
+ ],
24
+ "images_root": "/home/work/keural-model/vision-encoder-dataset/datacomp_medium",
25
+ "max_caption_length": 77,
26
+ "num_workers": 4,
27
+ "pixel_mean": [
28
+ 0.485,
29
+ 0.456,
30
+ 0.406
31
+ ],
32
+ "pixel_std": [
33
+ 0.229,
34
+ 0.224,
35
+ 0.225
36
+ ],
37
+ "text_encoder_name": "openai/clip-vit-large-patch14"
38
+ },
39
+ "distillation": {
40
+ "enabled": true,
41
+ "internvit_embed_dim": 1024,
42
+ "internvit_model": "OpenGVLab/InternViT-300M-448px",
43
+ "lambda_internvit": 0.5,
44
+ "lambda_siglip": 0.5,
45
+ "siglip_embed_dim": 1152,
46
+ "siglip_model": "google/siglip-so400m-patch14-384"
47
+ },
48
+ "loss": {
49
+ "hct_alpha": 0.5,
50
+ "lambda_distill": 0.5,
51
+ "lambda_hct": 1.0,
52
+ "lambda_sal": 0.5,
53
+ "learnable_bias_init": -10.0,
54
+ "learnable_temperature_init": 2.3,
55
+ "primary": "sigmoid_siglip",
56
+ "saliency_beta": 0.005,
57
+ "saliency_lambda_smooth": 4.0
58
+ },
59
+ "name": "keural-mid",
60
+ "saliency": {
61
+ "hidden_channels": 192
62
+ },
63
+ "spatial": {
64
+ "depth": 24,
65
+ "embed_dim": 768,
66
+ "head_dim": 64,
67
+ "mlp_ratio": 4,
68
+ "norm_eps": 1e-06,
69
+ "num_heads": 12,
70
+ "rope_base": 10000.0,
71
+ "use_pool_token": true
72
+ },
73
+ "stem": {
74
+ "activation": "gelu",
75
+ "channels": [
76
+ 128,
77
+ 256,
78
+ 512,
79
+ 768
80
+ ],
81
+ "kernel_size": 3
82
+ },
83
+ "tokenizer": {
84
+ "budget_floors": {
85
+ "detail": 0,
86
+ "global": 8,
87
+ "region": 16
88
+ },
89
+ "budget_split": {
90
+ "detail": 0.7,
91
+ "global": 0.05,
92
+ "region": 0.25
93
+ },
94
+ "default_token_budget": 512,
95
+ "gumbel_temperature_end": 0.05,
96
+ "gumbel_temperature_start": 1.0,
97
+ "max_token_budget": 2048,
98
+ "nms_radius": {
99
+ "detail": 1,
100
+ "region": 3
101
+ },
102
+ "roi_align_size": 4,
103
+ "saliency_smooth_kernel": {
104
+ "detail": 3,
105
+ "region": 7
106
+ },
107
+ "temperature_anneal_steps": 50000,
108
+ "warmup_steps_fixed_grid": 10000
109
+ },
110
+ "training": {
111
+ "batch_size_per_device": 576,
112
+ "betas": [
113
+ 0.9,
114
+ 0.95
115
+ ],
116
+ "gradient_accumulation": 2,
117
+ "gradient_checkpointing": true,
118
+ "log_every": 100,
119
+ "lr": 0.0005,
120
+ "lr_schedule": "cosine_with_warmup",
121
+ "max_steps": 18000,
122
+ "optimizer": "adamw",
123
+ "precision": "bfloat16",
124
+ "save_every": 1000,
125
+ "seed": 42,
126
+ "warmup_steps": 2000,
127
+ "weight_decay": 0.05
128
+ }
129
+ },
130
+ "max_token_budget": 2048,
131
+ "model_type": "keural_vision",
132
+ "num_heads": 12,
133
+ "transformers_version": "4.57.6"
134
+ }
checkpoint-10000/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1a9de63c772a8096a3d2e4e73696c661228cc71e8e017f7a5a1108a591c05114
3
+ size 734331916
checkpoint-10000/training_state.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aa3bf0d4507e4fa1b77512472752e1002710dc62c7a7ed246dff76fcfa427973
3
+ size 1486944344
checkpoint-15000/alignment_state.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:39450b6d5f939b0d48739ebe96daff82588132ef924c928e6c1ab8ae0485b6d2
3
+ size 9050229
checkpoint-15000/config.json ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "KeuralVisionModel"
4
+ ],
5
+ "default_token_budget": 512,
6
+ "depth": 24,
7
+ "dtype": "float32",
8
+ "embed_dim": 768,
9
+ "keural_config": {
10
+ "data": {
11
+ "captions_path": "/home/work/keural-model/vision-encoder-dataset/indexes/datacomp_train.tsv",
12
+ "dataset_name": "cc3m",
13
+ "extra_sources": [],
14
+ "image_buckets": [
15
+ [
16
+ 384,
17
+ 384
18
+ ],
19
+ [
20
+ 448,
21
+ 448
22
+ ]
23
+ ],
24
+ "images_root": "/home/work/keural-model/vision-encoder-dataset/datacomp_medium",
25
+ "max_caption_length": 77,
26
+ "num_workers": 6,
27
+ "pixel_mean": [
28
+ 0.485,
29
+ 0.456,
30
+ 0.406
31
+ ],
32
+ "pixel_std": [
33
+ 0.229,
34
+ 0.224,
35
+ 0.225
36
+ ],
37
+ "text_encoder_name": "openai/clip-vit-large-patch14"
38
+ },
39
+ "distillation": {
40
+ "enabled": true,
41
+ "internvit_embed_dim": 1024,
42
+ "internvit_model": "OpenGVLab/InternViT-300M-448px",
43
+ "lambda_internvit": 0.5,
44
+ "lambda_siglip": 0.5,
45
+ "siglip_embed_dim": 1152,
46
+ "siglip_model": "google/siglip-so400m-patch14-384"
47
+ },
48
+ "loss": {
49
+ "lambda_distill": 0.5,
50
+ "lambda_hct": 1.0,
51
+ "lambda_sal": 0.5,
52
+ "learnable_bias_init": -10.0,
53
+ "learnable_temperature_init": 2.3,
54
+ "primary": "sigmoid_siglip",
55
+ "saliency_beta": 0.005,
56
+ "saliency_lambda_smooth": 4.0
57
+ },
58
+ "name": "keural-mid",
59
+ "saliency": {
60
+ "hidden_channels": 192
61
+ },
62
+ "spatial": {
63
+ "depth": 24,
64
+ "embed_dim": 768,
65
+ "head_dim": 64,
66
+ "mlp_ratio": 4,
67
+ "norm_eps": 1e-06,
68
+ "num_heads": 12,
69
+ "rope_base": 10000.0
70
+ },
71
+ "stem": {
72
+ "activation": "gelu",
73
+ "channels": [
74
+ 128,
75
+ 256,
76
+ 512,
77
+ 768
78
+ ],
79
+ "kernel_size": 3
80
+ },
81
+ "tokenizer": {
82
+ "budget_floors": {
83
+ "detail": 0,
84
+ "global": 8,
85
+ "region": 16
86
+ },
87
+ "budget_split": {
88
+ "detail": 0.7,
89
+ "global": 0.05,
90
+ "region": 0.25
91
+ },
92
+ "default_token_budget": 512,
93
+ "gumbel_temperature_end": 0.05,
94
+ "gumbel_temperature_start": 1.0,
95
+ "max_token_budget": 2048,
96
+ "nms_radius": {
97
+ "detail": 1,
98
+ "region": 3
99
+ },
100
+ "saliency_smooth_kernel": {
101
+ "detail": 3,
102
+ "region": 7
103
+ },
104
+ "temperature_anneal_steps": 10000,
105
+ "warmup_steps_fixed_grid": 4000
106
+ },
107
+ "training": {
108
+ "batch_size_per_device": 768,
109
+ "betas": [
110
+ 0.9,
111
+ 0.95
112
+ ],
113
+ "gradient_accumulation": 2,
114
+ "gradient_checkpointing": true,
115
+ "log_every": 100,
116
+ "lr": 0.0005,
117
+ "lr_schedule": "cosine_with_warmup",
118
+ "max_steps": 18000,
119
+ "optimizer": "adamw",
120
+ "precision": "bfloat16",
121
+ "save_every": 1000,
122
+ "seed": 42,
123
+ "warmup_steps": 2000,
124
+ "weight_decay": 0.05
125
+ }
126
+ },
127
+ "max_token_budget": 2048,
128
+ "model_type": "keural_vision",
129
+ "num_heads": 12,
130
+ "transformers_version": "4.57.6"
131
+ }
checkpoint-15000/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cc636995d6aa5a7c3de8d0a4148183d5953a58f50d4bd60ad8cd32c1324ae44e
3
+ size 734331916
checkpoint-15000/training_state.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:71d58899aa3f4cc3359dbc7d9c043e822949fc9f51595e49757ddfffa403a279
3
+ size 1486944344
checkpoint-18000/alignment_state.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:10c8ef42816f2f2dab26de3295ef8ffb651c515feba37fde5785caabdba5d99a
3
+ size 9050229
checkpoint-18000/config.json ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "KeuralVisionModel"
4
+ ],
5
+ "default_token_budget": 512,
6
+ "depth": 24,
7
+ "dtype": "float32",
8
+ "embed_dim": 768,
9
+ "keural_config": {
10
+ "data": {
11
+ "captions_path": "/home/work/keural-model/vision-encoder-dataset/indexes/datacomp_train.tsv",
12
+ "dataset_name": "cc3m",
13
+ "extra_sources": [],
14
+ "image_buckets": [
15
+ [
16
+ 384,
17
+ 384
18
+ ],
19
+ [
20
+ 448,
21
+ 448
22
+ ]
23
+ ],
24
+ "images_root": "/home/work/keural-model/vision-encoder-dataset/datacomp_medium",
25
+ "max_caption_length": 77,
26
+ "num_workers": 6,
27
+ "pixel_mean": [
28
+ 0.485,
29
+ 0.456,
30
+ 0.406
31
+ ],
32
+ "pixel_std": [
33
+ 0.229,
34
+ 0.224,
35
+ 0.225
36
+ ],
37
+ "text_encoder_name": "openai/clip-vit-large-patch14"
38
+ },
39
+ "distillation": {
40
+ "enabled": true,
41
+ "internvit_embed_dim": 1024,
42
+ "internvit_model": "OpenGVLab/InternViT-300M-448px",
43
+ "lambda_internvit": 0.5,
44
+ "lambda_siglip": 0.5,
45
+ "siglip_embed_dim": 1152,
46
+ "siglip_model": "google/siglip-so400m-patch14-384"
47
+ },
48
+ "loss": {
49
+ "lambda_distill": 0.5,
50
+ "lambda_hct": 1.0,
51
+ "lambda_sal": 0.5,
52
+ "learnable_bias_init": -10.0,
53
+ "learnable_temperature_init": 2.3,
54
+ "primary": "sigmoid_siglip",
55
+ "saliency_beta": 0.005,
56
+ "saliency_lambda_smooth": 4.0
57
+ },
58
+ "name": "keural-mid",
59
+ "saliency": {
60
+ "hidden_channels": 192
61
+ },
62
+ "spatial": {
63
+ "depth": 24,
64
+ "embed_dim": 768,
65
+ "head_dim": 64,
66
+ "mlp_ratio": 4,
67
+ "norm_eps": 1e-06,
68
+ "num_heads": 12,
69
+ "rope_base": 10000.0
70
+ },
71
+ "stem": {
72
+ "activation": "gelu",
73
+ "channels": [
74
+ 128,
75
+ 256,
76
+ 512,
77
+ 768
78
+ ],
79
+ "kernel_size": 3
80
+ },
81
+ "tokenizer": {
82
+ "budget_floors": {
83
+ "detail": 0,
84
+ "global": 8,
85
+ "region": 16
86
+ },
87
+ "budget_split": {
88
+ "detail": 0.7,
89
+ "global": 0.05,
90
+ "region": 0.25
91
+ },
92
+ "default_token_budget": 512,
93
+ "gumbel_temperature_end": 0.05,
94
+ "gumbel_temperature_start": 1.0,
95
+ "max_token_budget": 2048,
96
+ "nms_radius": {
97
+ "detail": 1,
98
+ "region": 3
99
+ },
100
+ "saliency_smooth_kernel": {
101
+ "detail": 3,
102
+ "region": 7
103
+ },
104
+ "temperature_anneal_steps": 10000,
105
+ "warmup_steps_fixed_grid": 4000
106
+ },
107
+ "training": {
108
+ "batch_size_per_device": 768,
109
+ "betas": [
110
+ 0.9,
111
+ 0.95
112
+ ],
113
+ "gradient_accumulation": 2,
114
+ "gradient_checkpointing": true,
115
+ "log_every": 100,
116
+ "lr": 0.0005,
117
+ "lr_schedule": "cosine_with_warmup",
118
+ "max_steps": 18000,
119
+ "optimizer": "adamw",
120
+ "precision": "bfloat16",
121
+ "save_every": 1000,
122
+ "seed": 42,
123
+ "warmup_steps": 2000,
124
+ "weight_decay": 0.05
125
+ }
126
+ },
127
+ "max_token_budget": 2048,
128
+ "model_type": "keural_vision",
129
+ "num_heads": 12,
130
+ "transformers_version": "4.57.6"
131
+ }
checkpoint-18000/eval_results.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "checkpoint": "outputs/run/final",
3
+ "imagenet_top1": 36.858,
4
+ "imagenet_top5": 66.484,
5
+ "i2t_R@1": 41.999998688697815,
6
+ "i2t_R@5": 71.79999947547913,
7
+ "i2t_R@10": 80.29999732971191,
8
+ "t2i_R@1": 42.30000078678131,
9
+ "t2i_R@5": 69.70000267028809,
10
+ "t2i_R@10": 79.19999957084656,
11
+ "cifar100_linear_top1": 74.6999979019165,
12
+ "eval_time_s": 1375.6
13
+ }
checkpoint-18000/eval_results_budget512.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "checkpoint": "outputs/run/final",
3
+ "token_budget": 512,
4
+ "imagenet_top1": 37.196,
5
+ "imagenet_top5": 66.832,
6
+ "i2t_R@1": 42.899999022483826,
7
+ "i2t_R@5": 72.69999980926514,
8
+ "i2t_R@10": 80.59999942779541,
9
+ "t2i_R@1": 42.1999990940094,
10
+ "t2i_R@5": 69.9999988079071,
11
+ "t2i_R@10": 79.40000295639038,
12
+ "cifar100_linear_top1": 74.95999932289124,
13
+ "eval_time_s": 1389.3
14
+ }
checkpoint-18000/eval_results_budget576.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "checkpoint": "outputs/run/final",
3
+ "token_budget": 576,
4
+ "imagenet_top1": 37.176,
5
+ "imagenet_top5": 66.802,
6
+ "i2t_R@1": 42.69999861717224,
7
+ "i2t_R@5": 72.69999980926514,
8
+ "i2t_R@10": 80.80000281333923,
9
+ "t2i_R@1": 42.30000078678131,
10
+ "t2i_R@5": 70.09999752044678,
11
+ "t2i_R@10": 79.40000295639038,
12
+ "cifar100_linear_top1": 74.87000226974487,
13
+ "eval_time_s": 5492.6
14
+ }
checkpoint-18000/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:93ccb1eb1365d81e7d2fde2b783100d991611ab7e1d4c23010bbcfd656738853
3
+ size 734331916
checkpoint-9000/config.json ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "KeuralVisionModel"
4
+ ],
5
+ "default_token_budget": 512,
6
+ "depth": 24,
7
+ "dtype": "float32",
8
+ "embed_dim": 768,
9
+ "keural_config": {
10
+ "data": {
11
+ "captions_path": "/home/work/keural-model/vision-encoder-dataset/indexes/datacomp_train.tsv",
12
+ "dataset_name": "cc3m",
13
+ "extra_sources": [],
14
+ "image_buckets": [
15
+ [
16
+ 384,
17
+ 384
18
+ ],
19
+ [
20
+ 448,
21
+ 448
22
+ ]
23
+ ],
24
+ "images_root": "/home/work/keural-model/vision-encoder-dataset/datacomp_medium",
25
+ "max_caption_length": 77,
26
+ "num_workers": 4,
27
+ "pixel_mean": [
28
+ 0.485,
29
+ 0.456,
30
+ 0.406
31
+ ],
32
+ "pixel_std": [
33
+ 0.229,
34
+ 0.224,
35
+ 0.225
36
+ ],
37
+ "text_encoder_name": "openai/clip-vit-large-patch14"
38
+ },
39
+ "distillation": {
40
+ "enabled": true,
41
+ "internvit_embed_dim": 1024,
42
+ "internvit_model": "OpenGVLab/InternViT-300M-448px",
43
+ "lambda_internvit": 0.5,
44
+ "lambda_siglip": 0.5,
45
+ "siglip_embed_dim": 1152,
46
+ "siglip_model": "google/siglip-so400m-patch14-384"
47
+ },
48
+ "loss": {
49
+ "hct_alpha": 0.5,
50
+ "lambda_distill": 0.5,
51
+ "lambda_hct": 1.0,
52
+ "lambda_sal": 0.5,
53
+ "learnable_bias_init": -10.0,
54
+ "learnable_temperature_init": 2.3,
55
+ "primary": "sigmoid_siglip",
56
+ "saliency_beta": 0.005,
57
+ "saliency_lambda_smooth": 4.0
58
+ },
59
+ "name": "keural-mid",
60
+ "saliency": {
61
+ "hidden_channels": 192
62
+ },
63
+ "spatial": {
64
+ "depth": 24,
65
+ "embed_dim": 768,
66
+ "head_dim": 64,
67
+ "mlp_ratio": 4,
68
+ "norm_eps": 1e-06,
69
+ "num_heads": 12,
70
+ "rope_base": 10000.0,
71
+ "use_pool_token": true
72
+ },
73
+ "stem": {
74
+ "activation": "gelu",
75
+ "channels": [
76
+ 128,
77
+ 256,
78
+ 512,
79
+ 768
80
+ ],
81
+ "kernel_size": 3
82
+ },
83
+ "tokenizer": {
84
+ "budget_floors": {
85
+ "detail": 0,
86
+ "global": 8,
87
+ "region": 16
88
+ },
89
+ "budget_split": {
90
+ "detail": 0.7,
91
+ "global": 0.05,
92
+ "region": 0.25
93
+ },
94
+ "default_token_budget": 512,
95
+ "gumbel_temperature_end": 0.05,
96
+ "gumbel_temperature_start": 1.0,
97
+ "max_token_budget": 2048,
98
+ "nms_radius": {
99
+ "detail": 1,
100
+ "region": 3
101
+ },
102
+ "roi_align_size": 4,
103
+ "saliency_smooth_kernel": {
104
+ "detail": 3,
105
+ "region": 7
106
+ },
107
+ "temperature_anneal_steps": 50000,
108
+ "warmup_steps_fixed_grid": 10000
109
+ },
110
+ "training": {
111
+ "batch_size_per_device": 576,
112
+ "betas": [
113
+ 0.9,
114
+ 0.95
115
+ ],
116
+ "gradient_accumulation": 2,
117
+ "gradient_checkpointing": true,
118
+ "log_every": 100,
119
+ "lr": 0.0005,
120
+ "lr_schedule": "cosine_with_warmup",
121
+ "max_steps": 18000,
122
+ "optimizer": "adamw",
123
+ "precision": "bfloat16",
124
+ "save_every": 1000,
125
+ "seed": 42,
126
+ "warmup_steps": 2000,
127
+ "weight_decay": 0.05
128
+ }
129
+ },
130
+ "max_token_budget": 2048,
131
+ "model_type": "keural_vision",
132
+ "num_heads": 12,
133
+ "transformers_version": "4.57.6"
134
+ }
checkpoint-9000/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:879f1701b490c4bec8835d0975a1517ced32a47d3fae887aed5f3b3c91361f34
3
+ size 734331916
checkpoint-9000/training_state.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:139f29da5cacb8eb912e18cfcdc1e2cf9dc503e8b42f4c9dc68d1c2dc607b667
3
+ size 1486944344
config.json ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "KeuralVisionModel"
4
+ ],
5
+ "default_token_budget": 512,
6
+ "depth": 24,
7
+ "dtype": "float32",
8
+ "embed_dim": 768,
9
+ "keural_config": {
10
+ "data": {
11
+ "captions_path": "/home/work/keural-model/vision-encoder-dataset/indexes/datacomp_train.tsv",
12
+ "dataset_name": "cc3m",
13
+ "extra_sources": [],
14
+ "image_buckets": [
15
+ [
16
+ 384,
17
+ 384
18
+ ],
19
+ [
20
+ 448,
21
+ 448
22
+ ]
23
+ ],
24
+ "images_root": "/home/work/keural-model/vision-encoder-dataset/datacomp_medium",
25
+ "max_caption_length": 77,
26
+ "num_workers": 6,
27
+ "pixel_mean": [
28
+ 0.485,
29
+ 0.456,
30
+ 0.406
31
+ ],
32
+ "pixel_std": [
33
+ 0.229,
34
+ 0.224,
35
+ 0.225
36
+ ],
37
+ "text_encoder_name": "openai/clip-vit-large-patch14"
38
+ },
39
+ "distillation": {
40
+ "enabled": true,
41
+ "internvit_embed_dim": 1024,
42
+ "internvit_model": "OpenGVLab/InternViT-300M-448px",
43
+ "lambda_internvit": 0.5,
44
+ "lambda_siglip": 0.5,
45
+ "siglip_embed_dim": 1152,
46
+ "siglip_model": "google/siglip-so400m-patch14-384"
47
+ },
48
+ "loss": {
49
+ "lambda_distill": 0.5,
50
+ "lambda_hct": 1.0,
51
+ "lambda_sal": 0.5,
52
+ "learnable_bias_init": -10.0,
53
+ "learnable_temperature_init": 2.3,
54
+ "primary": "sigmoid_siglip",
55
+ "saliency_beta": 0.005,
56
+ "saliency_lambda_smooth": 4.0
57
+ },
58
+ "name": "keural-mid",
59
+ "saliency": {
60
+ "hidden_channels": 192
61
+ },
62
+ "spatial": {
63
+ "depth": 24,
64
+ "embed_dim": 768,
65
+ "head_dim": 64,
66
+ "mlp_ratio": 4,
67
+ "norm_eps": 1e-06,
68
+ "num_heads": 12,
69
+ "rope_base": 10000.0
70
+ },
71
+ "stem": {
72
+ "activation": "gelu",
73
+ "channels": [
74
+ 128,
75
+ 256,
76
+ 512,
77
+ 768
78
+ ],
79
+ "kernel_size": 3
80
+ },
81
+ "tokenizer": {
82
+ "budget_floors": {
83
+ "detail": 0,
84
+ "global": 8,
85
+ "region": 16
86
+ },
87
+ "budget_split": {
88
+ "detail": 0.7,
89
+ "global": 0.05,
90
+ "region": 0.25
91
+ },
92
+ "default_token_budget": 512,
93
+ "gumbel_temperature_end": 0.05,
94
+ "gumbel_temperature_start": 1.0,
95
+ "max_token_budget": 2048,
96
+ "nms_radius": {
97
+ "detail": 1,
98
+ "region": 3
99
+ },
100
+ "saliency_smooth_kernel": {
101
+ "detail": 3,
102
+ "region": 7
103
+ },
104
+ "temperature_anneal_steps": 10000,
105
+ "warmup_steps_fixed_grid": 4000
106
+ },
107
+ "training": {
108
+ "batch_size_per_device": 768,
109
+ "betas": [
110
+ 0.9,
111
+ 0.95
112
+ ],
113
+ "gradient_accumulation": 2,
114
+ "gradient_checkpointing": true,
115
+ "log_every": 100,
116
+ "lr": 0.0005,
117
+ "lr_schedule": "cosine_with_warmup",
118
+ "max_steps": 18000,
119
+ "optimizer": "adamw",
120
+ "precision": "bfloat16",
121
+ "save_every": 1000,
122
+ "seed": 42,
123
+ "warmup_steps": 2000,
124
+ "weight_decay": 0.05
125
+ }
126
+ },
127
+ "max_token_budget": 2048,
128
+ "model_type": "keural_vision",
129
+ "num_heads": 12,
130
+ "transformers_version": "4.57.6"
131
+ }
keural_mid_architecture.png ADDED

Git LFS Details

  • SHA256: 42a1c75bb2abe7e0079d3be61a3a9a7a259e4dd4dfed90e567d2ca64562944fe
  • Pointer size: 132 Bytes
  • Size of remote file: 1.15 MB
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:93ccb1eb1365d81e7d2fde2b783100d991611ab7e1d4c23010bbcfd656738853
3
+ size 734331916
saliency_evolution_9ckpt.png ADDED

Git LFS Details

  • SHA256: dc6b4b2807ed6798b8d30deb169d21f11a49fdee69dd7529398e15f6a0ae54fb
  • Pointer size: 132 Bytes
  • Size of remote file: 2.22 MB
training_loss_curves.png ADDED

Git LFS Details

  • SHA256: 9dd413f2eb5ff34f904c4e051a9d4c387f1c9de036523892ae3cc00cea283771
  • Pointer size: 131 Bytes
  • Size of remote file: 277 kB