Image-Text-to-Text
Transformers
Safetensors
English
qwen2_5_vl
vision-language-model
anomaly-detection
industrial-inspection
reasoning
grpo
research-preview
conversational
text-generation-inference
Instructions to use aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO") 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("aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO") model = AutoModelForMultimodalLM.from_pretrained("aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO", 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 aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO", "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/aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO
- SGLang
How to use aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO 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 "aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO" \ --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": "aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO", "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 "aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO" \ --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": "aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO", "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 aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO with Docker Model Runner:
docker model run hf.co/aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO
File size: 5,138 Bytes
ae1726f f9599bc ae1726f f9599bc ae1726f f9599bc ae1726f f9599bc ae1726f f9599bc ae1726f f9599bc ae1726f f9599bc ae1726f f9599bc ae1726f f9599bc ae1726f 080d1e2 ae1726f f9599bc ae1726f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | ---
license: apache-2.0
base_model: Qwen/Qwen2.5-VL-7B-Instruct
pipeline_tag: image-text-to-text
library_name: transformers
language:
- en
tags:
- vision-language-model
- anomaly-detection
- industrial-inspection
- reasoning
- grpo
- research-preview
datasets:
- aacudad/AnomalyThink
---
# AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO
> **This is a research-preview checkpoint and is NOT the thesis headline model.** It is released
> for completeness alongside the AnomalyThink family. The headline model of the thesis is
> [`aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR`](https://huggingface.co/aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR)
> (DS-MVTec 82.80 / VisA 72.07), which is SFT only. The GRPO run below is discussed only as **future work**.
A reasoning-enhanced vision-language model for **explainable industrial anomaly detection**. It takes the
Keep-Correct-Revise model as its starting point and then trains it further with **GRPO**, with the RL
training prompt **aligned to the evaluation prompt** (KL penalty β = 0.1, 3 epochs, reward = accuracy +
format). This is `checkpoint-954` of that run.
## What Keep-Correct-Revise (KCR) means
**Keep-Correct-Revise (KCR)** is the data recipe behind the model this run starts from. An SFT plus GRPO
policy generates its own reasoning traces on Real-IAD images. Each trace is then **kept** when the verdict
is correct, **corrected** by a teacher model when the verdict is wrong, and **revised** by a teacher model
when the verdict is correct but the reasoning is only weakly grounded in the image. The **base** model is
then fine-tuned from scratch on the curated 6,000-trace result. That fine-tune is the KCR model.
This model is one more GRPO stage stacked on top of that KCR model.
## Why "future work" and not a result
GRPO on the already-strong KCR init *edges* the SFT ceiling on average but the trajectory bounces
across epoch 3 rather than climbing monotonically, so the gain is small and not yet clearly stable.
The thesis therefore reports the KCR SFT model as the headline and holds this run as future work.
Do not read these numbers as "GRPO beat SFT".
## Balanced accuracy (checkpoint-954)
Balanced accuracy `BA = 0.5 * (TP/(TP+FN) + TN/(TN+FP))`, recomputed from the raw `tp/tn/fp/fn` of
each eval JSON (shipped in the code repo).
| Benchmark | BA | tp | tn | fp | fn | n |
|---|---:|---:|---:|---:|---:|---:|
| DS-MVTec | **82.95** | 1004 | 373 | 71 | 222 | 1670 |
| VisA | **72.62** | 719 | 804 | 140 | 478 | 2141 |
Average **77.78**, versus the KCR init's 77.44 (82.80 / 72.07).
### The AnomalyThink Qwen family for context
| Model | DS-MVTec | VisA | Note |
|---|---:|---:|---|
| [`…-7B-KCR`](https://huggingface.co/aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR) | 82.80 | 72.07 | **thesis headline** |
| [`…-7B-SFT`](https://huggingface.co/aacudad/AnomalyThink-Qwen2.5-VL-7B-SFT) | 80.16 | 64.78 | plain SFT baseline |
| [`…-7B-SFT-GRPO`](https://huggingface.co/aacudad/AnomalyThink-Qwen2.5-VL-7B-SFT-GRPO) | 82.73 | 70.39 | released RL model, the policy KCR rolls out from |
| **this model** (GRPO on KCR, ckpt-954) | **82.95** | **72.62** | **research preview / future work** |
## Usage
```python
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
from qwen_vl_utils import process_vision_info
model_id = "aacudad/AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO"
model = Qwen2_5_VLForConditionalGeneration.from_pretrained(model_id, torch_dtype="auto", device_map="auto")
processor = AutoProcessor.from_pretrained(model_id)
messages = [{"role": "user", "content": [
{"type": "image", "image": "file:///path/to/part.png"},
{"type": "text", "text": "Is there a defect in this product? Analyze and answer yes or no."},
]}]
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
imgs, vids = process_vision_info(messages)
inputs = processor(text=[text], images=imgs, videos=vids, padding=True, return_tensors="pt").to(model.device)
out = model.generate(**inputs, max_new_tokens=512)
print(processor.batch_decode(out[:, inputs.input_ids.shape[1]:], skip_special_tokens=True)[0])
```
## Links
- Code, training/eval scripts, and the exact `checkpoint-954` eval JSONs: https://github.com/aacudad/IAD-VLMs
- Dataset: https://huggingface.co/datasets/aacudad/AnomalyThink
- MSc thesis (TU Delft, 2026): *Reasoning-Enhanced Vision-Language Models for Explainable Industrial Anomaly Detection*, Adnane Acudad
## Citation
```bibtex
@mastersthesis{acudad2026reasoning,
author = {Acudad, A.},
title = {Reasoning-Enhanced Vision-Language Models for Explainable Industrial Anomaly Detection},
school = {Delft University of Technology},
year = {2026},
type = {Master's thesis},
url = {https://resolver.tudelft.nl/uuid:65c62420-79c0-447f-b095-7fb11d4474fc}
}
```
Thesis: <https://resolver.tudelft.nl/uuid:65c62420-79c0-447f-b095-7fb11d4474fc>. Code and evaluation files: <https://github.com/aacudad/IAD-VLMs>.
## License
Derived from Qwen2.5-VL-7B-Instruct (Apache-2.0). Evaluated on DS-MVTec and VisA (MMAD protocol),
trained on AnomalyThink traces distilled from Gemini-2.5-Flash over Real-IAD.
|