Nawah-VL-50M-detect-ar-stage3

Arabic dense object detection in a 145M-parameter vision-language model. An image goes in; every object it finds comes out, each named in Arabic with a bounding box. There is no prompt to write โ€” the question is a constant.

input   an image
output  ู…ู†ุฒู„ 10 00 98 66
        ู†ุงูุฐุฉ 17 33 26 42
        ู†ุงูุฐุฉ 43 11 55 24
        ุดุฌุฑุฉ 80 00 99 64

Coordinates are x1 y1 x2 y2 in 0โ€“99 integer bins normalised to the image โ€” 4 tokens per box against 16 for floats, which matters at this size. Objects are emitted largest-area first.

This is a detector, not a referring model. Earlier checkpoints in this lineage answer "where is the X I named?"; this one answers "what is here, and where?", which needs the label as well as the box and so cannot be scored by geometry alone.

Part Source Params Trained here
Vision tower SigLIP2 (NaFlex) from LiquidAI/LFM2.5-VL-450M 85.8M top 4 of 12 blocks, LR 1e-5
Connector Lfm2VlMultiModalProjector, 3072โ†’2048โ†’512 7.3M yes, LR 1e-4
Language model oddadmix/50M-2048-Emhotob (Llama, hidden 512, 12 layers, 2048 ctx) 51.8M yes, LR 5e-5

145.0M total, counted from the checkpoint's own tensor shapes.

Usage

import torch
from transformers import AutoModelForImageTextToText, AutoProcessor
from PIL import Image

REPO = "oddadmix/Nawah-VL-50M-detect-ar-stage3"
model = AutoModelForImageTextToText.from_pretrained(REPO, dtype=torch.float32).eval()
proc = AutoProcessor.from_pretrained(REPO)

image = Image.open("photo.jpg").convert("RGB")
prompt = (f"{proc.tokenizer.bos_token}<image>"
          "ู…ุง ุงู„ุฃุฌุณุงู… ุงู„ู…ูˆุฌูˆุฏุฉ ููŠ ุงู„ุตูˆุฑุฉุŸ\n"
          "ุงุฐูƒุฑ ูƒู„ ุฌุณู… ู…ุน ุฅุทุงุฑู‡ ุงู„ู…ุญูŠุท.\n")

inputs = proc(text=[prompt], images=[[image]], return_tensors="pt")
out = model.generate(**inputs, max_new_tokens=128, do_sample=False)
print(proc.batch_decode(out[:, inputs["input_ids"].shape[1]:],
                        skip_special_tokens=True)[0])

The prompt is not a suggestion. Those two Arabic strings are the exact training strings. This lineage was initialised from a referring checkpoint and tells the two tasks apart from the prompt alone โ€” paraphrase it and you get referring-style output: one bare box, no name.

Feed it original image bytes where you can. The lineage is measurably sensitive to re-encoding.

Results

Measured on 2,000 held-out rows. The four source shards they come from were excluded from the training corpus before the build started, so nothing here was seen in training.

this model image-blind floor zero-shot init
det_f1@0.5 0.487 0.010 0.000
det_f1@0.25 0.558 0.056 0.000
det_f1@0.75 0.357 0.000 0.000
det_precision@0.5 / recall@0.5 0.460 / 0.518 0.009 / 0.012 0.000
label_f1 (naming only) 0.669 0.129 0.000
mean_iou_matched (geometry only) 0.830 0.587 โ€”
format_ok 1.000 1.000 0.000

Read the second column first. det_f1@0.5 counts a hit only when the Arabic name matches and IoU โ‰ฅ 0.5. The image-blind floor โ€” the 4 commonest labels (ูˆุฌู‡, ุฑุฌู„, ู…ู„ุงุจุณ, ุงู…ุฑุฃุฉ) emitted at their mean box for every image, no pixels consulted โ€” scores 0.010. Unlike referring grounding, where a fixed full-frame box already scores 0.262, there is almost nothing to win here by not looking, so this headline is close to all real signal.

label_f1 is the exception: naming alone has a 0.129 floor, because a handful of labels are very common. Quote the floor beside it or the number reads better than it is.

The zero-shot column is the referring checkpoint this lineage started from, measured on this task. It scores 0.0 across the board because it answers in the referring format โ€” a bare 00 00 99 99 with no name โ€” so format_ok is 0. Its geometry was already good; the naming behaviour and the output format are what this run bought.

By object size

Recall at IoU 0.5, bucketed by how much of the frame the gold object fills:

gold object fills count recall@0.5 floor
tiny 2,187 (38%) 0.294 0.001
small 1,638 (28%) 0.553 0.012
medium 1,130 (19%) 0.711 0.042
large 848 (15%) 0.770 0.000

Small objects are the known weak band, and attacking it is why this run unfroze the top vision blocks. Recall rose most in exactly the two bands that motivated it, and slipped slightly in the medium band, so the tower reallocated spatial capacity rather than adding it uniformly.

By how crowded the scene is

Recomputed from the 200-prediction dump in results/eval_detection_samples.json โ€” a subset of the 2,000, so treat these as indicative rather than as headline numbers:

objects in the gold gold boxes recall@0.5 precision@0.5
1 68 0.721 0.598
2โ€“3 182 0.654 0.469
4โ€“6 149 0.503 0.441
7 or more 201 0.313 0.328

Crowding and object size are not independent โ€” a picture with nine things in it has small things in it โ€” but the drop is steep and it is the single most useful thing to know before pointing this at an image.

Counting and repetition

mean objects predicted 3.267
mean objects in the gold 2.901
count MAE 0.968
duplicate-line rate 0.082
det_f1@0.5 with duplicates collapsed 0.509

Emitting the same (name, box) twice is this model's characteristic failure โ€” it learns the line format long before it learns to stop. Training targets can never contain a duplicate, so every one is an error the model could filter itself. The dedup row is what it would score with a one-line post-filter.

Training

This is stage 3 of a detection run, on top of a chain of earlier Nawah-VL-50M finetunes: captioning โ†’ VQA โ†’ referring grounding โ†’ detection stage 2 (frozen vision tower) โ†’ this. The intermediate checkpoints are internal and are not published; the two published ancestors are oddadmix/Nawah-VL-50M and, under it, oddadmix/50M-2048-Emhotob.

data oddadmix/laion-coco-5m-arabic-labels, the oi_yolo_pred_ar column
rows 838,863 over 794 shards, 2.90 objects/row mean
stage 3 โ€” projector + language model + the top 4 SigLIP2 blocks
updates 3,277 (one epoch) at batch 64 ร— 4 accum, 256 effective
LR projector 1e-4, LM 5e-5, vision 1e-5, cosine with 3% warmup
final eval loss 1.3713
hardware one RTX A6000, ~75 samples/s

Targets were built by filtering the YOLO detections at confidence โ‰ฅ 0.40, capping at 10 objects per image, sorting the survivors largest-area-first, and dropping rows where nothing survived โ€” 23.7% of them. Images were capped at 512 px on the long side and rows with an aspect ratio worse than 5:1 were dropped.

Against stage 2 on the identical pinned rows: det_f1@0.5 0.4722 โ†’ 0.4870, label_f1 0.6656 โ†’ 0.6694, mean_iou_matched 0.826 โ†’ 0.830, eval loss 1.4113 โ†’ 1.3713. Recall by band moved tiny 0.273 โ†’ 0.294 and small 0.523 โ†’ 0.553, while medium slipped 0.723 โ†’ 0.711. The margin is modest and has not been tested for significance, and the eval loss was flat over the last 277 updates as the cosine decayed, which is not the same as convergence.

Limitations

The labels are model-generated. The supervision comes from yolov8x-oiv7, a detector, not from human annotation. This model inherits that detector's blind spots, its closed 601-class Open Images vocabulary, and any artefact in the Arabic glossary those class names were mapped through. It cannot name an object that vocabulary has no word for, and "the gold is wrong" is a real explanation for a share of its misses.

Crowded scenes are where it falls apart. Recall roughly halves between a single-object image and one with seven or more, on the dump measured above. Small objects are the other weak band, at 0.294 recall for the tiny quartile against 0.770 for large.

It repeats itself. 8.2% of output lines duplicate an earlier one. A three-line post-filter recovers about 2 points of F1.

It is rigid about the prompt. Anything other than the two exact training strings gets referring-format output, not detection.

It does not read text in images, and inherits the coarse Arabic of a 51.8M-parameter language model. Boxes are quantised to a 100ร—100 grid, so sub-1% localisation is not representable at all.

Everything reported above is measured on held-out rows from the same corpus the model trained on. There is no evaluation on an independent benchmark, no human-annotated test set, and no COCO-mAP number โ€” this card deliberately does not quote one, because none was computed.

Reproducing

code/ in this repo carries the training loop, the evaluator and the corpus builder that produced these numbers; results/ carries the raw eval JSON, the 200-prediction dump against gold, and the floor and zero-shot baselines. The corpus is public, so the build is repeatable end to end.

Attribution

The language model is oddadmix/50M-2048-Emhotob, trained from scratch on Arabic. The vision tower is SigLIP2 as distributed in LiquidAI/LFM2.5-VL-450M, used unmodified except for its top 4 blocks; those weights remain LiquidAI's and their licence terms apply to that component. Box supervision comes from Ultralytics yolov8x-oiv7 over the Open Images V7 vocabulary, via oddadmix/laion-coco-5m-arabic-labels, which is itself derived from CaptionEmporium/laion-coco-13m-molmo-d-7b and LAION.

License

cc-by-nc-4.0 โ€” non-commercial use only. The detection corpus is CC-BY-SA-4.0, but these weights descend from oddadmix/Nawah-VL-50M, whose captioning data (visheratin/laion-coco-nllb) is CC-BY-NC-4.0, so the non-commercial restriction carries through the initialisation and is the binding term.

Demo

oddadmix/Nawah-VL-50M-Detection-Demo โ€” drop an image in, get boxes with Arabic labels. Six held-out examples included, one of them a crowded scene picked to show the failure above.

Downloads last month
70
Safetensors
Model size
0.1B params
Tensor type
BF16
ยท
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for oddadmix/Nawah-VL-50M-detect-ar-stage3

Finetuned
(16)
this model

Dataset used to train oddadmix/Nawah-VL-50M-detect-ar-stage3

Space using oddadmix/Nawah-VL-50M-detect-ar-stage3 1