aacudad/AnomalyThink

Dataset

AnomalyThink: reasoning traces for explainable industrial anomaly detection

2

12 commits

1 linked in READMEs

updated Sep 18, 2026

See the code

README

AnomalyThink: reasoning traces for explainable industrial anomaly detection

AnomalyThink is a collection of structured reasoning traces for industrial anomaly detection (IAD), distilled from Gemini 2.5-Flash on Real-IAD images. Each example is a single-image inspection in which the assistant produces a <think> reasoning trace, a defect <location> and <type> (for anomalies), and a binary <answer> (defect / no defect). Research artefact from the MSc thesis Reasoning-Enhanced Vision-Language Models for Explainable Industrial Anomaly Detection (TU Delft, 2026).

Important: images are NOT included

Examples reference Real-IAD images by relative path (Real-IAD/images/...) in the images field, or by image_id and image_path in the GRPO-pool files. The image files themselves are not redistributed here. Obtain Real-IAD from its official source, place it so the relative paths resolve, and cite Real-IAD.

What Keep-Correct-Revise (KCR) means

Several folders here are products of Keep-Correct-Revise (KCR), the curation recipe of the thesis. An SFT plus GRPO policy generates its own reasoning traces on Real-IAD images. Each trace is then kept when the policy got the verdict right, corrected by a teacher model when the verdict is wrong, and revised by a teacher model when the verdict is right but the reasoning is only weakly grounded in the image. The base model is then fine-tuned from scratch on the curated result.

The arms A and B in teacher_ablation_abc are partial versions of the same loop, keep-only and keep-plus-correct. The full loop, with the revise step included, is what KCR means.

Format

Two schemas are used, and the configs above keep them apart so the viewer can load each:

  • ShareGPT (messages, images): LLaMA-Factory SFT format, a list of {"messages": [...], "images": ["Real-IAD/images/..."]}. The assistant message holds the trace: <think>...</think>, then for anomalies <location>...</location><type>...</type>, then <answer>yes|no</answer>.
  • GRPO pool (image_id, image_path, product, is_anomaly, question, answer, gt_label): one row per prompt for the reinforcement-learning stage, with the reference trace in answer.

The thesis splits and where they are

The thesis partitions the 14,472 traces into three disjoint, product-stratified, class-balanced splits. Use these files to reproduce it.

thesis splitcount (anomalous / normal)fileconfig
full corpus, all three splits14,472 (7,247 / 7,225)anomalythink_15k/combined_sft_train.jsonanomalythink_full_14k
AnomalyThink-6K, SFT split6,000 (3,000 / 3,000)anomalythink_6k/combined_6k_train.jsonthesis_sft_6k
GRPO split4,236 (2,118 / 2,118)anomalythink_15k/c1_only_fixed/grpo_train.jsonthesis_grpo_4k
held-out split (SFT format, never used for training in the thesis)4,236 (2,129 / 2,107)anomalythink_15k/c1_only_fixed/new_sft_c1_train.jsonthesis_heldout_4k
KCR corpus, Qwen2.5-VL (Arm C, thesis headline)6,000 (3,000 / 3,000)iter2/sft_iter2_train.jsonkcr_qwen_6k
teacher ablation, Arm A (keep only)2,978teacher_ablation_abc/sft_A_kept_balanced.jsonteacher_ablation_arm_a
teacher ablation, Arm B (keep + correct)4,369teacher_ablation_abc/sft_B_kept_corrected.jsonteacher_ablation_arm_b
KCR corpus, LLaVA-OneVision (A, B, C)8,998 / 9,124 / 6,000llava_kcr/*.jsonkcr_llava

The "15K" model of the thesis (7B-frozen-15K) was trained on the full 14,472-trace file, that is the SFT split plus the GRPO and held-out splits folded in as SFT data. Note on iter2/sft_iter2_train.json: this is the corpus as trained on. A version with 316 <location> strings normalised to the nine grid names is in the GitHub repository (traces/iter2/sft_iter2_train.json), same images and verdicts.

Other files (alternative assemblies, kept for reproducibility)

filescontents
anomalythink_6k/sft_train.json, anomalythink_6k/grpo_train.jsonthe 6K images re-split 3,000 SFT + 3,000 GRPO, an earlier configuration, not the thesis split
anomalythink_6k/iad_sft_6k_bareprompt_train.jsonthe 6K SFT split with the bare question as prompt
anomalythink_15k/sft_train.json, anomalythink_15k/grpo_train.json10,236 SFT (6K plus held-out) and a 4,236 GRPO pool, an earlier configuration
anomalythink_15k/c1_only_fixed/combined_sft_c1_train.jsonGRPO split in SFT format plus the KCR corpus, 10,236 rows
iter2/heldout_4236_disjoint.json, iter2/sft_iter2_heldout_train.json, iter2/iter2_v2_sft_train.jsonfiles of the iterative SFT-RL experiment (thesis 6.5 and 6.7)
teacher_ablation_abc/sft_10k_max_polish_train.jsonthe full 10,236-image rollout pool after correction, unbalanced
variety_star_6k/Real-IAD Variety STaR corpus (6,000) and its pools, future work in the thesis, not a thesis result

Models trained on this data

The same KCR recipe was run on two backbones. Both families are released.

Qwen2.5-VL-7B backbone

ModelDS-MVTecVisANote
AnomalyThink-Qwen2.5-VL-7B-KCR82.8072.07thesis headline, SFT only
AnomalyThink-Qwen2.5-VL-7B-SFT80.1664.78plain SFT baseline
AnomalyThink-Qwen2.5-VL-7B-SFT-GRPO82.7370.39the policy KCR rolls out from
AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO82.9572.62research preview, not a thesis result

Balanced accuracy on the MMAD DS-MVTec (1,670) and VisA (2,141) subsets, one common harness.

LLaVA-OneVision-7B-SI backbone

Cross-architecture replication of the same recipe, on the backbone IAD-R1 uses. Traces in llava_kcr: sft_llava_C_train.json is the first KCR build (the released LLaVA KCR weights, 88.45 / 74.25, corpus drawn from the whole rollout pool and 45 % anomalous) and sft_llava_C_corrected_train.json is the corrected build the thesis reports (all 6,000 images inside the SFT split, 3,000 / 3,000 by verdict, 87.32 / 72.65 at epoch 2 and 74.29 on VisA at epoch 4). The SFT then GRPO model scores 87.66 / 72.38 under strict scoring.

Note on DS-MVTec numbers for this backbone: the LLaVA-OneVision pretraining mix contains MVTec-derived rows, so DS-MVTec results on any LLaVA-OneVision model carry a contamination caveat. VisA is unaffected.

Qwen3-VL-8B backbone (post-submission, September 2026)

The thesis reports this backbone only as a corpus-transfer check (base 78.68 / 64.45, trained on the Qwen2.5-VL KCR corpus 85.82 / 76.45). After submission the full recipe was run on it. These are not thesis results.

ModelDS-MVTecVisANote
AnomalyThink-Qwen3-VL-8B-SFT80.3167.32SFT on anomalythink_6k, epoch 1
AnomalyThink-Qwen3-VL-8B-SFT-GRPO87.1472.39GRPO from the SFT model, epoch 1, training prompt
AnomalyThink-Qwen3-VL-8B-KCR84.3976.63SFT from base on qwen3_kcr/sft_qwen3_C_train.json, epoch 2

qwen3_kcr/sft_qwen3_C_train.json holds the 5,998-trace corpus built from the Qwen3 GRPO policy's own rollouts (8,988 kept, 1,248 corrected, 2,464 rewritten at pool level, assembled on the 6,000 SFT images, 2,999 anomalous).

Citation

@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

Apache-2.0 for the reasoning traces. Real-IAD images are under their own licence and are not included.

chain-of-thought
industrial-anomaly-detection
reasoning
vision-language-model

aacudad/AnomalyThink

Dataset

AnomalyThink: reasoning traces for explainable industrial anomaly detection

2

12 commits

1 linked in READMEs

updated Sep 18, 2026

See the code

README

AnomalyThink: reasoning traces for explainable industrial anomaly detection

AnomalyThink is a collection of structured reasoning traces for industrial anomaly detection (IAD), distilled from Gemini 2.5-Flash on Real-IAD images. Each example is a single-image inspection in which the assistant produces a <think> reasoning trace, a defect <location> and <type> (for anomalies), and a binary <answer> (defect / no defect). Research artefact from the MSc thesis Reasoning-Enhanced Vision-Language Models for Explainable Industrial Anomaly Detection (TU Delft, 2026).

Important: images are NOT included

Examples reference Real-IAD images by relative path (Real-IAD/images/...) in the images field, or by image_id and image_path in the GRPO-pool files. The image files themselves are not redistributed here. Obtain Real-IAD from its official source, place it so the relative paths resolve, and cite Real-IAD.

What Keep-Correct-Revise (KCR) means

Several folders here are products of Keep-Correct-Revise (KCR), the curation recipe of the thesis. An SFT plus GRPO policy generates its own reasoning traces on Real-IAD images. Each trace is then kept when the policy got the verdict right, corrected by a teacher model when the verdict is wrong, and revised by a teacher model when the verdict is right but the reasoning is only weakly grounded in the image. The base model is then fine-tuned from scratch on the curated result.

The arms A and B in teacher_ablation_abc are partial versions of the same loop, keep-only and keep-plus-correct. The full loop, with the revise step included, is what KCR means.

Format

Two schemas are used, and the configs above keep them apart so the viewer can load each:

  • ShareGPT (messages, images): LLaMA-Factory SFT format, a list of {"messages": [...], "images": ["Real-IAD/images/..."]}. The assistant message holds the trace: <think>...</think>, then for anomalies <location>...</location><type>...</type>, then <answer>yes|no</answer>.
  • GRPO pool (image_id, image_path, product, is_anomaly, question, answer, gt_label): one row per prompt for the reinforcement-learning stage, with the reference trace in answer.

The thesis splits and where they are

The thesis partitions the 14,472 traces into three disjoint, product-stratified, class-balanced splits. Use these files to reproduce it.

thesis splitcount (anomalous / normal)fileconfig
full corpus, all three splits14,472 (7,247 / 7,225)anomalythink_15k/combined_sft_train.jsonanomalythink_full_14k
AnomalyThink-6K, SFT split6,000 (3,000 / 3,000)anomalythink_6k/combined_6k_train.jsonthesis_sft_6k
GRPO split4,236 (2,118 / 2,118)anomalythink_15k/c1_only_fixed/grpo_train.jsonthesis_grpo_4k
held-out split (SFT format, never used for training in the thesis)4,236 (2,129 / 2,107)anomalythink_15k/c1_only_fixed/new_sft_c1_train.jsonthesis_heldout_4k
KCR corpus, Qwen2.5-VL (Arm C, thesis headline)6,000 (3,000 / 3,000)iter2/sft_iter2_train.jsonkcr_qwen_6k
teacher ablation, Arm A (keep only)2,978teacher_ablation_abc/sft_A_kept_balanced.jsonteacher_ablation_arm_a
teacher ablation, Arm B (keep + correct)4,369teacher_ablation_abc/sft_B_kept_corrected.jsonteacher_ablation_arm_b
KCR corpus, LLaVA-OneVision (A, B, C)8,998 / 9,124 / 6,000llava_kcr/*.jsonkcr_llava

The "15K" model of the thesis (7B-frozen-15K) was trained on the full 14,472-trace file, that is the SFT split plus the GRPO and held-out splits folded in as SFT data. Note on iter2/sft_iter2_train.json: this is the corpus as trained on. A version with 316 <location> strings normalised to the nine grid names is in the GitHub repository (traces/iter2/sft_iter2_train.json), same images and verdicts.

Other files (alternative assemblies, kept for reproducibility)

filescontents
anomalythink_6k/sft_train.json, anomalythink_6k/grpo_train.jsonthe 6K images re-split 3,000 SFT + 3,000 GRPO, an earlier configuration, not the thesis split
anomalythink_6k/iad_sft_6k_bareprompt_train.jsonthe 6K SFT split with the bare question as prompt
anomalythink_15k/sft_train.json, anomalythink_15k/grpo_train.json10,236 SFT (6K plus held-out) and a 4,236 GRPO pool, an earlier configuration
anomalythink_15k/c1_only_fixed/combined_sft_c1_train.jsonGRPO split in SFT format plus the KCR corpus, 10,236 rows
iter2/heldout_4236_disjoint.json, iter2/sft_iter2_heldout_train.json, iter2/iter2_v2_sft_train.jsonfiles of the iterative SFT-RL experiment (thesis 6.5 and 6.7)
teacher_ablation_abc/sft_10k_max_polish_train.jsonthe full 10,236-image rollout pool after correction, unbalanced
variety_star_6k/Real-IAD Variety STaR corpus (6,000) and its pools, future work in the thesis, not a thesis result

Models trained on this data

The same KCR recipe was run on two backbones. Both families are released.

Qwen2.5-VL-7B backbone

ModelDS-MVTecVisANote
AnomalyThink-Qwen2.5-VL-7B-KCR82.8072.07thesis headline, SFT only
AnomalyThink-Qwen2.5-VL-7B-SFT80.1664.78plain SFT baseline
AnomalyThink-Qwen2.5-VL-7B-SFT-GRPO82.7370.39the policy KCR rolls out from
AnomalyThink-Qwen2.5-VL-7B-KCR-GRPO82.9572.62research preview, not a thesis result

Balanced accuracy on the MMAD DS-MVTec (1,670) and VisA (2,141) subsets, one common harness.

LLaVA-OneVision-7B-SI backbone

Cross-architecture replication of the same recipe, on the backbone IAD-R1 uses. Traces in llava_kcr: sft_llava_C_train.json is the first KCR build (the released LLaVA KCR weights, 88.45 / 74.25, corpus drawn from the whole rollout pool and 45 % anomalous) and sft_llava_C_corrected_train.json is the corrected build the thesis reports (all 6,000 images inside the SFT split, 3,000 / 3,000 by verdict, 87.32 / 72.65 at epoch 2 and 74.29 on VisA at epoch 4). The SFT then GRPO model scores 87.66 / 72.38 under strict scoring.

Note on DS-MVTec numbers for this backbone: the LLaVA-OneVision pretraining mix contains MVTec-derived rows, so DS-MVTec results on any LLaVA-OneVision model carry a contamination caveat. VisA is unaffected.

Qwen3-VL-8B backbone (post-submission, September 2026)

The thesis reports this backbone only as a corpus-transfer check (base 78.68 / 64.45, trained on the Qwen2.5-VL KCR corpus 85.82 / 76.45). After submission the full recipe was run on it. These are not thesis results.

ModelDS-MVTecVisANote
AnomalyThink-Qwen3-VL-8B-SFT80.3167.32SFT on anomalythink_6k, epoch 1
AnomalyThink-Qwen3-VL-8B-SFT-GRPO87.1472.39GRPO from the SFT model, epoch 1, training prompt
AnomalyThink-Qwen3-VL-8B-KCR84.3976.63SFT from base on qwen3_kcr/sft_qwen3_C_train.json, epoch 2

qwen3_kcr/sft_qwen3_C_train.json holds the 5,998-trace corpus built from the Qwen3 GRPO policy's own rollouts (8,988 kept, 1,248 corrected, 2,464 rewritten at pool level, assembled on the 6,000 SFT images, 2,999 anomalous).

Citation

@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

Apache-2.0 for the reasoning traces. Real-IAD images are under their own licence and are not included.

chain-of-thought
industrial-anomaly-detection
reasoning
vision-language-model