SPARC: Subspace Position-Aware Robust Few-Shot Calibration for Distribution-Shifted Industrial Anomaly Detection
Organizations: Korea University
Abstract
Vision-based industrial anomaly detectors are calibrated on one distribution but may be deployed on another that differs in illumination, fixture placement, or sensor characteristics, sharply degrading an otherwise accurate detector. Adapting to the incoming lot is a natural response, but labeled anomalies are scarce. We therefore consider calibration using only a handful of verified-normal images available before scoring the rest of the lot. Existing fixes require backpropagation, detector-specific tuning, or choices about feature directions that few calibration samples cannot justify. We present SPARC, a few-shot calibration method that intercepts patch features between encoder and detector and removes a closed-form, spatially indexed estimate of deployment-time nuisance through per-cell subspace projection. It needs only verified-normal images and uses the algebraic saturation rank on the encoder's native patch grid. The correction requires no gradient or weight updates and works with memory-bank, density, prototype, and mutual detectors. On the shift-prone benchmarks, SPARC improves pooled Image AUROC and AU-PRO for all seven detectors whose image scores depend on corrected patch features by and percentage points (pp), respectively; on benchmarks without engineered shift, the changes are small and mixed. Controls that give competing corrections the same calibration images attribute these gains to the per-cell subspace structure rather than the images alone. Further ablations support the saturation-rank choice and characterize sensitivity to backbone and calibration conditions.
Figures & tables
| MVTec AD 2 | AeBAD-S | VisA | RAD | Pooled | |||||||||||
| Backbone | Method | base | +S | base | +S | base | +S | base | +S | shift prone | shift free | ||||
| Image AUROC | |||||||||||||||
| WRN-50 | PatchCore ( Roth et al., 2022 ) | 68.7 | 83.6 | +14.8 | 64.1 | 66.3 | +2.2 | 94.3 | 93.9 | 0.3 | 92.1 | 96.2 | +4.0 | +10.6 | +0.8 |
| WRN-50 | PaDiM ( Defard et al., 2021 ) | 59.9 | 81.6 | +21.7 | 61.6 | 62.5 | +1.0 | 89.3 | 89.6 | +0.3 | 97.5 | 97.8 | +0.3 | +14.8 | +0.3 |
| WRN-50 | SPADE ( Cohen and Hoshen, 2020 ) | 53.8 | 71.0 | +17.2 | 38.3 | 43.6 | +5.2 | 83.7 | 84.2 | +0.5 | 28.9 | 34.7 | +5.8 | +13.2 | +1.8 |
| DINOv2-S/14 | AnomalyDINO ( Damm et al., 2025 ) | 71.7 | 82.0 | +10.3 | 71.7 | 73.5 | +1.8 | 95.3 | 93.7 | 1.6 | 97.2 | 97.0 | 0.2 | +7.5 | 1.3 |
| Method | base | +S | |
| PatchCore | 19.0 | 20.4 | +1.3 |
| PaDiM | 11.3 | 17.1 | +5.8 |
| SPADE | 18.4 | 19.5 | +1.1 |
| AnomalyDINO | 37.0 | 38.8 | +1.8 |
| SubspaceAD | 35.4 | 45.6 | +10.2 |
| WinCLIP | 17.1 | 17.7 | +0.7 |
| Variant | Image AUROC | AU-PRO 0.3 | MVTec AD 2 AU-PRO 0.05 |
| Shift-prone benchmarks (MVTec AD 2 and AeBAD-S) | |||
| CORAL few-shot | +1.8 0.4 | 2.8 0.1 | 2.5 0.1 |
| Calibration-only BN | 0.5 0.4 | +2.1 0.2 | +4.4 0.1 |
| Source-mixed BN | +1.5 0.2 | +4.0 0.1 | +6.1 0.2 |
| CORAL full-normal † | +3.0 0.4 | 2.7 0.0 | 2.6 0.0 |
| BN full-normal † | +0.4 0.1 | +2.3 0.0 | +4.7 0.0 |
Appendix figures & tables25 assets
Supplementary material from the paper’s appendix.
Appendix
| Node | GPU configuration | VRAM | CPU configuration | Cores/Threads | System Memory |
| A | NVIDIA L40 | 48 GB | Intel Xeon Silver 4410Y | 24/48 | 0.5 TB |
| B | NVIDIA RTX 6000 Ada Generation | 48 GB | AMD EPYC 9124 | 32/64 | 1.5 TB |
| C | NVIDIA RTX 6000 Ada Generation | 48 GB | AMD EPYC 9124 | 32/64 | 1.5 TB |
| Library or framework | Version |
| Python | 3.12.3 |
| PyTorch | 2.7.0+cu128 |
| Torchvision | 0.22.0+cu128 |
| xFormers | 0.0.30 |
| CUDA runtime/toolkit | 12.8/12.8.93 |
| cuDNN | 9.7.1 |
| MVTec AD 2 | AeBAD-S | VisA | RAD | ||||||
| Method | Image AUROC | AU-PRO 0.05 | AU-PRO 0.3 | Image AUROC | AU-PRO 0.3 | Image AUROC | AU-PRO 0.3 | Image AUROC | AU-PRO 0.3 |
| FastRef | 83.7 | 22.7 | 46.4 | 68.0 | 82.4 | 83.7 | 76.4 | 98.1 | 90.3 |
| FastRecon | 75.5 | 17.4 | 41.6 | 57.1 | 78.8 | 72.0 | 63.2 | 98.2 | 86.7 |
| SubspaceAD + SPARC | 85.8 | 45.6 | 69.3 | 88.1 | 92.7 | 98.2 | 95.9 | 96.4 | 94.6 |
| AnomalyDINO + SPARC | 82.0 | 38.8 | 63.7 | 73.5 | 86.7 | 93.7 | 92.0 | 97.0 | 90.5 |
| PaDiM + SPARC | 81.6 | 17.1 | 47.5 | 62.5 | 82.6 | 89.6 | 82.9 | 97.8 | 76.3 |
| MVTec AD 2 | AeBAD-S | VisA | RAD | ||||||||||
| Method | Budget | base | +C | base | +C | base | +C | base | +C | ||||
| Image AUROC | |||||||||||||
| SubspaceAD | CORAL-fs | 70.9 | 71.0 | +0.2 | 73.6 | 77.2 | +3.6 | 98.1 | 97.6 | -0.5 | 96.3 | 95.6 | -0.7 |
| SubspaceAD | CORAL full-normal | 70.9 | 71.1 | +0.2 | 73.6 | 77.3 | +3.7 | 98.1 | 97.6 | -0.5 | 96.3 | 95.6 | -0.7 |
| AnomalyDINO | CORAL-fs | 71.7 | 72.5 | +0.8 | 71.7 | 73.4 | +1.7 | 95.3 | 95.3 | +0.0 | 97.2 | 97.4 | +0.2 |
| AnomalyDINO | CORAL full-normal | 71.7 | 72.7 | +1.0 | 71.7 | 73.5 | +1.9 | 95.3 | 95.4 | +0.1 | 97.2 | 97.4 | +0.2 |
| Method | base | ||||
| Image AUROC | |||||
| SubspaceAD | 84.7 | +0.4 | +0.5 | +0.7 | +0.7 |
| AnomalyDINO | 84.0 | +0.5 | +0.6 | +0.7 | +0.8 |
| PaDiM | 77.1 | -2.4 | -2.2 | -2.3 | -2.3 |
| PatchCore | 79.8 | -1.0 | -0.7 | -0.4 | -0.4 |
| WinCLIP | 73.7 | +0.6 | +0.8 | +0.7 | +0.8 |
| Variant | PatchCore | PaDiM | SPADE | Anomaly DINO | Subspace AD | MuSc | Anomaly CLIP V | Anomaly CLIP M | Pooled | Pooled |
| Image AUROC | ||||||||||
| base | 82.4 | 78.1 | 60.8 | 85.5 | 86.5 | 66.6 | 72.8 | 76.7 | 76.2 | 0.0 |
| mean-only | 86.4 | 78.1 | 60.9 | 64.1 | 92.3 | 25.3 | 72.8 | 76.7 | 69.6 | 6.6 |
| SPARC (global subspace) | 84.0 | 78.9 | 63.8 | 84.5 | 88.3 | 66.5 | 72.8 | 76.7 | 76.9 | +0.8 |
| SPARC (per-cell, ours) | 87.3 | 84.6 | 67.5 | 87.9 | 92.9 | 76.2 | 72.8 | 76.7 | 80.8 | +4.6 |
| AU-PRO 0.3 | ||||||||||
| MVTec AD 2 | VisA | |||||||||||||
| Method | ||||||||||||||
| Image AUROC | ||||||||||||||
| SubspaceAD | +10.2 | +13.1 | +14.1 | +14.5 | +14.8 | +14.9 | +14.9 | +0.1 | +0.1 | +0.1 | +0.1 | +0.1 | +0.1 | +0.1 |
| AnomalyDINO | +2.7 | +5.8 | +8.0 | +9.3 | +9.9 | +10.2 | +10.3 | -0.2 | -0.6 | -1.0 | -1.2 | -1.4 | -1.5 | -1.6 |
| PaDiM | +12.3 | +18.9 | +21.1 | +21.4 | +21.6 | +21.6 | +21.7 | +0.2 | +0.2 | +0.3 | +0.3 | +0.3 | +0.3 | +0.3 |
| PatchCore | +5.0 | +10.1 | +13.7 | +14.8 | +15.3 | +15.5 | +14.8 | +0.3 | +0.0 | +0.0 | -0.2 | -0.2 | -0.1 | -0.3 |
| MVTec AD 2 | AeBAD-S | VisA | RAD | ||||||
| Variant | Image AUROC | AU-PRO 0.05 | AU-PRO 0.3 | Image AUROC | AU-PRO 0.3 | Image AUROC | AU-PRO 0.3 | Image AUROC | AU-PRO 0.3 |
| base (no correction) | 68.7 | 19.0 | 42.8 | 64.1 | 85.1 | 94.3 | 87.8 | 92.1 | 73.2 |
| SPARC (train-side only) | 60.2 | 16.9 | 39.9 | 63.8 | 85.2 | 89.0 | 84.6 | 93.2 | 73.8 |
| SPARC (test-side only) | 82.9 | 18.6 | 42.6 | 64.6 | 85.6 | 86.8 | 83.3 | 96.4 | 77.3 |
| SPARC (symmetric, ours) | 83.6 | 20.4 | 45.7 | 66.3 | 86.3 | 93.9 | 86.5 | 96.2 | 77.9 |
| MVTec AD 2 | AeBAD-S | VisA | RAD | |||||||||
| Method | ||||||||||||
| Image AUROC | ||||||||||||
| SubspaceAD | +4.9 | +9.0 | +14.9 | +8.2 | +11.7 | +14.5 | +0.0 | +0.0 | +0.1 | +0.1 | +0.2 | +0.1 |
| AnomalyDINO | +1.8 | +4.5 | +10.3 | +0.5 | +0.8 | +1.8 | -0.2 | -0.7 | -1.6 | -0.1 | -0.2 | -0.2 |
| PaDiM | +5.9 | +11.6 | +21.7 | +0.2 | +0.4 | +1.0 | +0.0 | +0.2 | +0.3 | +0.1 | +0.2 | +0.3 |
| PatchCore | +3.5 | +7.8 | +14.8 | +2.4 | +2.2 | +2.2 | -0.3 | -0.4 | -0.3 | +1.2 | +2.7 | +4.0 |
| Method | 0/8 | 1/8 | 2/8 | 3/8 | 4/8 |
| Image AUROC | |||||
| SubspaceAD | +14.9 | +11.5 | +8.5 | +3.5 | +0.5 |
| AnomalyDINO | +10.3 | +7.3 | +4.2 | +0.1 | -3.0 |
| PaDiM | +21.7 | +18.7 | +13.7 | +7.5 | +3.4 |
| PatchCore | +14.8 | +11.7 | +8.0 | +2.6 | -1.7 |
| MuSc | +33.1 | +27.9 | +22.0 | +13.3 | +6.2 |
| MVTec AD 2 | AeBAD-S | VisA | RAD | |||||||||
| Backbone | base | +S | base | +S | base | +S | base | +S | ||||
| Image AUROC | ||||||||||||
| clip_b | 64.5 | 77.7 | +13.2 | 61.5 | 60.7 | -0.8 | 90.2 | 84.1 | -6.0 | 90.5 | 74.2 | -16.3 |
| convnext_b | 61.8 | 78.3 | +16.6 | 68.3 | 67.0 | -1.4 | 83.6 | 83.5 | -0.1 | 96.6 | 96.7 | +0.1 |
| dinov2_b | 66.6 | 82.7 | +16.2 | 61.5 | 67.1 | +5.6 | 94.5 | 92.7 | -1.8 | 95.6 | 96.1 | +0.5 |
| dinov3_b | 65.2 | 83.0 | +17.8 | 76.6 | 76.6 | -0.0 | 95.4 | 94.1 | -1.3 | 96.5 | 96.9 | +0.3 |
| Center crop (main) | Full frame (control) | |||||
| Method | base | +S | base | +S | ||
| Image AUROC | ||||||
| AnomalyDINO | ||||||
| PaDiM | ||||||
| PatchCore | ||||||
| SPADE | ||||||
| Image AUROC | AU-PRO 0.05 | AU-PRO 0.3 | ||||||||
| Backbone | Method | base | +S | paired | base | +S | paired | base | +S | paired |
| WRN-50 | PatchCore ( Roth et al., 2022 ) | 68.3 2.2 | 68.9 2.2 | +0.6 2.1 | 18.9 0.1 | 20.6 0.3 | +1.7 0.2 | 42.6 0.3 | 43.0 0.2 | +0.4 0.2 |
| WRN-50 | PaDiM ( Defard et al., 2021 ) | 60.0 2.9 | 62.0 2.7 | +2.0 0.6 | 11.3 0.1 | 18.4 0.1 | +7.0 0.1 | 40.9 0.2 | 44.7 0.3 | +3.8 0.2 |
| WRN-50 | SPADE ( Cohen and Hoshen, 2020 ) | 54.3 1.0 | 57.3 2.1 | +3.1 1.3 | 18.3 0.0 | 18.2 0.3 | 0.1 0.3 | 41.9 0.3 | 42.7 0.3 | +0.8 0.2 |
| DINOv2-S/14 | AnomalyDINO ( Damm et al., 2025 ) | 71.5 0.4 | 72.2 0.8 | +0.7 0.5 | 36.8 0.0 | 38.0 0.2 | +1.2 0.2 | 59.9 0.1 | 61.7 0.7 | +1.9 0.7 |
| DINOv2-G | SubspaceAD ( Lendering et al., 2026 ) | 71.9 0.9 | 77.3 1.8 | +5.4 1.0 | 35.3 0.1 | 44.4 1.1 | +9.0 1.0 | 61.2 0.1 | 67.9 0.7 | +6.7 0.6 |
| base | mean-only | global subspace | per-cell SPARC (ours) | SPARC + mean | |||||||
| Detector | Metric | Score | Score | Score | Score | Score | |||||
| SubspaceAD | Image AUROC | 84.7 | +0.0 | 91.5 | +6.8 | 87.2 | +2.5 | 92.1 | +7.4 | 92.2 | +7.5 |
| AU-PRO 0.3 | 85.2 | +0.0 | 87.6 | +2.5 | 86.4 | +1.2 | 88.1 | +3.0 | 88.2 | +3.0 | |
| AU-PRO 0.05 | 35.4 | +0.0 | 44.5 | +9.1 | 39.0 | +3.6 | 45.6 | +10.2 | 45.7 | +10.2 | |
| AnomalyDINO | Image AUROC | 84.0 | +0.0 | 64.7 | -19.3 | 82.9 | -1.1 | 86.5 | +2.6 | 52.0 | -31.9 |
| AU-PRO 0.3 | 81.4 | +0.0 | 35.5 | -45.9 | 76.9 | -4.5 | 83.2 | +1.8 | 14.9 | -66.5 | |
| Dataset | DC energy | Subspace energy | DC fraction |
| MVTec AD 2 | 43.77 | 154.12 | 0.221 |
| AeBAD-S | 76.84 | 232.90 | 0.248 |
| VisA | 16.67 | 117.31 | 0.124 |
| RAD | 65.69 | 184.73 | 0.262 |
| Method | Deploy | Train | Difference | Raw | Holm |
| Image AUROC | |||||
| PatchCore | +10.6 | -2.5 | +13.1 | .001 ∗∗∗ | .003 ∗∗ |
| PaDiM | +14.8 | -0.0 | +14.8 | .001 ∗∗∗ | .003 ∗∗ |
| SPADE | +13.2 | +1.2 | +12.0 | .001 ∗∗∗ | .003 ∗∗ |
| AnomalyDINO | +7.5 | -0.3 | +7.7 | .001 ∗∗ | .003 ∗∗ |
| SubspaceAD | +14.8 | -0.2 | +15.0 | .001 ∗∗∗ | .003 ∗∗ |
| Anomaly–subspace alignment | Anomaly–normal contrast | |||||
| Dataset | base | SPARC | Rel. | |||
| MVTec AD 2 | 0.119 | 26.2 | 0.749 | 1.139 | +0.390 | +52.1% |
| AeBAD-S | 0.064 | 14.1 | 1.576 | 1.776 | +0.200 | +12.7% |
| VisA | 0.195 | 42.9 | 1.338 | 1.342 | +0.004 | +0.3% |
| RAD | 0.072 | 15.8 | 1.693 | 1.822 | +0.130 | +7.7% |
| Method | Mean | Median | Raw | Holm | |
| Image AUROC | |||||
| PatchCore | 12 | +10.62 | +6.86 | .001 ∗∗ | .006 ∗∗ |
| PaDiM | 12 | +14.78 | +13.22 | .001 ∗∗∗ | .003 ∗∗ |
| SPADE | 12 | +13.18 | +11.14 | .001 ∗∗∗ | .003 ∗∗ |
| AnomalyDINO | 12 | +7.47 | +6.87 | .001 ∗∗∗ | .003 ∗∗ |
| SubspaceAD | 12 | +14.77 | +13.36 | .001 ∗∗∗ | .003 ∗∗ |
| MVTec AD 2 | AeBAD-S | VisA | RAD | |||||
| Method | Mean | Seed SD | Mean | Seed SD | Mean | Seed SD | Mean | Seed SD |
| Image AUROC | ||||||||
| SubspaceAD | +14.9 | 0.8 | +14.5 | 1.0 | +0.1 | 0.1 | +0.1 | 0.1 |
| AnomalyDINO | +10.3 | 1.4 | +1.8 | 0.4 | -1.6 | 0.1 | -0.2 | 0.1 |
| PaDiM | +21.7 | 2.9 | +1.0 | 0.5 | +0.3 | 0.1 | +0.3 | 0.1 |
| PatchCore | +14.8 | 2.0 | +2.2 | 1.3 | -0.3 | 0.3 | +4.0 | 0.4 |
| Category | Image AUROC | AU-PRO 0.05 | AU-PRO 0.3 |
| MVTec AD 2 | |||
| can | 55.7/64.8 | 4.9/10.5 | 26.3/32.9 |
| fabric | 67.8/73.2 | 3.5/3.4 | 18.3/18.0 |
| fruit_jelly | 78.1/94.5 | 32.4/35.7 | 60.5/63.5 |
| rice | 75.4/81.8 | 17.9/22.0 | 40.3/43.0 |
| sheet_metal | 91.2/92.0 | 9.5/9.5 | 26.2/25.5 |
| Category | Variant | PatchCore | PaDiM | SPADE | AnomalyDINO | SubspaceAD | WinCLIP | MuSc | AnomalyCLIP V | AnomalyCLIP M |
| can | base | 49.7 | 49.7 | 50.0 | 52.5 | 50.0 | 24.2 | 53.0 | 57.2 | 55.2 |
| can | SPARC | 60.2 | 58.9 | 63.1 | 63.5 | 68.3 | 44.8 | 69.8 | 57.2 | 55.2 |
| fabric | base | 52.0 | 28.2 | 32.5 | 56.0 | 64.8 | 58.8 | 34.9 | 58.3 | 75.0 |
| fabric | SPARC | 73.2 | 65.1 | 63.9 | 70.5 | 77.4 | 86.4 | 71.4 | 58.3 | 75.0 |
| fruit_jelly | base | 89.2 | 79.2 | 70.8 | 86.5 | 83.4 | 88.1 | 38.5 | 66.1 | 67.3 |
| fruit_jelly | SPARC | 96.8 | 96.4 | 95.4 | 98.9 | 99.8 | 92.9 | 93.1 | 66.1 | 67.3 |
| Category | Variant | PatchCore | PaDiM | SPADE | AnomalyDINO | SubspaceAD | WinCLIP | MuSc | AnomalyCLIP V | AnomalyCLIP M |
| bolt | base | 79.1 | 92.5 | 13.0 | 95.1 | 95.6 | 75.2 | 75.8 | 76.1 | 87.5 |
| bolt | SPARC | 90.8 | 93.9 | 15.8 | 94.9 | 96.0 | 81.8 | 67.5 | 76.1 | 87.5 |
| ribbon | base | 96.6 | 99.2 | 77.0 | 98.2 | 96.6 | 85.1 | 81.0 | 98.7 | 92.7 |
| ribbon | SPARC | 97.4 | 99.1 | 84.8 | 97.9 | 96.7 | 86.1 | 78.7 | 98.7 | 92.7 |
| sponge | base | 95.5 | 99.2 | 7.2 | 97.2 | 96.0 | 68.1 | 55.4 | 43.8 | 36.6 |
| sponge | SPARC | 97.6 | 99.2 | 13.1 | 97.0 | 96.0 | 72.9 | 59.1 | 43.8 | 36.6 |
Industrial Anomaly Detection
Industrial anomaly detection finds defective products and abnormal equipment behavior from visual, sensor, audio, and other production data.
See all 261 papers