Instructions to use TheGarageDev/Minus-v0.2 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use TheGarageDev/Minus-v0.2 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="TheGarageDev/Minus-v0.2") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("TheGarageDev/Minus-v0.2") model = AutoModelForMultimodalLM.from_pretrained("TheGarageDev/Minus-v0.2", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use TheGarageDev/Minus-v0.2 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "TheGarageDev/Minus-v0.2" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "TheGarageDev/Minus-v0.2", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/TheGarageDev/Minus-v0.2
- SGLang
How to use TheGarageDev/Minus-v0.2 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "TheGarageDev/Minus-v0.2" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "TheGarageDev/Minus-v0.2", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "TheGarageDev/Minus-v0.2" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "TheGarageDev/Minus-v0.2", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use TheGarageDev/Minus-v0.2 with Docker Model Runner:
docker model run hf.co/TheGarageDev/Minus-v0.2
Minus-v0.2: a TV ad detector that sees what the box sees
Minus-v0.2 is the vision model in Minus, an HDMI box that blocks TV ads by looking at the picture. It is a 450M-parameter vision-language model (LFM2.5-VL-450M) fine-tuned to answer two questions about a TV frame:
- "Is this an advertisement? Answer Yes or No." (blocks ads)
- "Classify this TV screen: PLAYING, PAUSED, DIALOG, MENU, or SCREENSAVER?" (lets autonomous mode drive the TV)
It replaces Minus-v0.1 on the box. Same size, same speed, same files, so it is a drop-in swap. All numbers below were measured on the box's AX650 NPU, not on a server.
What changed
On the 800-image held-out set every Minus model has been judged on, v0.2 misses 1 ad in 400 where v0.1 missed 25, and wrongly blocks 6 non-ads where v0.1 blocked 10. Accuracy goes from 95.6% to 99.1%.
The biggest gains are on the frames that confused the box in real use: frames where v0.1 flip-flopped between ad and not-ad, was unsure (P(ad) between 0.1 and 0.9), or disagreed with the box's OCR. On 328 of these, all labeled by hand and none used in training, missed ads fall from 46 to 11.
v0.1 answered MENU for every screen it was ever shown (29,974 of 29,979 times on a real box). v0.2 reads the screen correctly 95.9% of the time, and on the 135 frames of video playing it never answers anything that would make the box act (no false SCREENSAVER, PAUSED or DIALOG).
| on the box (AX650 NPU) | Minus-v0.1 | Minus-v0.2 |
|---|---|---|
| 800-image test: accuracy | 95.6% | 99.1% |
| ad recall / non-ad recall | 93.8% / 97.5% | 99.8% / 98.5% |
| 328 hard frames: accuracy | 83.2% | 95.1% |
| screen-state check (193 frames) | 13.5% | 95.9% |
| time per frame | ~360 ms | ~365 ms |
Why it is better
- It was trained on the picture the box actually sends it. The box shrinks every frame straight to 512ร512 (it squashes 16:9 into a square). Every earlier Minus model was trained on images resized the "proper" way, which keeps the aspect ratio. Fed squashed frames, v0.1's own server copy dropped from 99.1% to 96.5% on the 800-image set, which is almost exactly what the box measured. v0.2 trains on squashed frames, and that gap is gone.
- Two more months of the box's own footage. 19,133 frames the box saved from 2026-10-07 to 10-26. Every label was checked: two independent models scored every frame, and every frame where they disagreed with each other or with the box was reviewed by eye (2,056 frames). The box's own folder labels were wrong often enough to matter: 203 "ad" frames were show content (lyrics with the word "skip", "Includes paid promotion" badges), and of the frames the box flip-flopped on, 342 of 440 were show content, not ads.
- A real screen-state head. 3,251 frames were labeled by screen state by eye. Real screensavers are rare, and the ambient YouTube videos that look like them (space loops, sleep stories) are exactly what a model gets wrong. So 207 extra training frames are those ambient videos with a Fire TV style date and clock drawn on, labeled SCREENSAVER, next to the same frames without the clock, labeled PLAYING: the clock is the cue, not the scenery. These synthetic frames are training-only; every test frame is real.
- A better NPU build. The 16 decoder layers keep their running hidden state (the residual stream) at full precision, not only the RMSNorm steps. Rounding it to 16 bits cost the screen check 17 points on the NPU (78.2% vs 95.9%) and the ad check 5 false positives.
How it was trained
- Base: LiquidAI/LFM2.5-VL-450M. LoRA (r=16, ฮฑ=32, dropout 0.05) on the language-model layers only, so the vision tower and projector are untouched and identical to v0.1's; lr 2e-4, 3 epochs, effective batch 32, merged after training. Trained on one NVIDIA Jetson AGX Thor.
- Input: every training image is resized straight to 512ร512 (bilinear), the way the box does it.
- Data (not released): 101,080 samples. The Minus-v0.1 training set (streaming-TV frames plus web ad and hard-negative sets), the 13,820 checked October frames, and 5,670 screen-state examples (rare classes repeated up to 3ร, half with the box's system message).
- Held out: the 800-image set, a 1,956-frame streaming set, an 863-frame October set carved out by whole hours before training, and 947 frames captured after training.
Using it
On the box (Axera AX650N / AX8850, e.g. Radxa AICore AX-M1)
The axera/ folder is what the Minus box downloads. Files, how it runs and on-device numbers are
in its README.
hf download TheGarageDev/Minus-v0.2 --include "axera/*" --local-dir minus-v0.2
cd minus-v0.2/axera && python3 infer_vlm_fused.py frame.png
Transformers (server-side)
import torch
from PIL import Image
from transformers import AutoModelForImageTextToText, AutoProcessor
model = AutoModelForImageTextToText.from_pretrained("TheGarageDev/Minus-v0.2", dtype=torch.float32)
proc = AutoProcessor.from_pretrained("TheGarageDev/Minus-v0.2")
img = Image.open("frame.png").convert("RGB").resize((512, 512), Image.BILINEAR) # squash, like the box
msgs = [{"role": "system", "content": [{"type": "text", "text": "You are a helpful multimodal assistant by Liquid AI."}]},
{"role": "user", "content": [{"type": "image", "image": img},
{"type": "text", "text": "Is this an advertisement? Answer Yes or No."}]}]
inputs = proc.apply_chat_template(msgs, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt")
logits = model(**inputs).logits[0, -1]
yes = logits[[12948, 12184, 18051, 18672]].max(); no = logits[[5048, 2744, 3253, 1295]].max()
print("ad" if yes > no else "not an ad")
For the screen check, use the prompt Classify this TV screen: PLAYING, PAUSED, DIALOG, MENU, or SCREENSAVER? and
take the class whose first token scores highest (token ids are in axera/README.md).
Squash the image to 512ร512 first. v0.2 was trained on squashed frames; aspect-preserving resizes work, but not as well.
Limitations
- TV only. v0.2 is tuned for streaming-TV frames and the box's input. For web pages, the Minus Chrome extension keeps using its own model.
- Screen-state test sets are small for the rare classes (18 screensavers, 11 dialogs, 3 paused frames). The important property, never mistaking playing video for a screen that needs action, held on all 135 playing frames.
- Mostly YouTube on Fire TV, often music videos (the box's autonomous mode). Other apps and countries will be less accurate.
- Three kinds of screen were left out of training until there is a product decision on whether they count as ads: a pirate cartoon site's "Get PREMIUM" pop-up, Fire TV's full-screen sponsored screens ("Press to learn more"), and ad panels over paused video.
- Measured on held-out frames. A live soak on a TV with the new model was still pending at publication.
- Downloads last month
- 31
Model tree for TheGarageDev/Minus-v0.2
Base model
LiquidAI/LFM2.5-350M-Base

