Anomalib 中的 AnomalyVFM:基于视觉基础模型的零样本工业异常检测实现详解
2026/9/17 7:33:26 网站建设 项目流程

Anomalib 中的 AnomalyVFM:基于视觉基础模型的零样本工业异常检测实现详解

【免费下载链接】anomalibAn anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.项目地址: https://gitcode.com/GitHub_Trending/an/anomalib

本文以 Anomalib 官方 API 参考文档anomalyvfm.md所覆盖的两个核心类 —— Lightning 封装AnomalyVFM与 PyTorch 实现AnomalyVFMModel—— 为主线,结合仓库中的组件源码、配置文件与模型模块 README,完整讲解该零样本(zero-shot)异常检测模型的 API 用法、参数含义、内部数据流与底层实现原理。读完后,你将掌握如何用一行 CLI 命令或几行 Python 代码直接部署该模型,理解 RADIO 视觉基础模型 + DoRA 适配器 + 异常解码器的结构组成,以及该模型在精度、导出等方面的使用边界。

1. AnomalyVFM 是什么:零样本异常检测的定位

AnomalyVFM 源自论文《AnomalyVFM — Transforming Vision Foundation Models into Zero-Shot Anomaly Detectors》(CVPR 2026),是 Anomalib 图像模型族中的成员,可通过from anomalib.models.image import AnomalyVFM直接导入。据模块 README(src/anomalib/models/image/anomalyvfm/README.md)与包级文档字符串(anomalyvfm/__init__.py)描述:

  • 零样本设定:该模型构建在预训练视觉基础模型(VFM)之上,官方训练流程先用 FLUX 生成合成图像再在其上训练;Anomalib 的实现只支持零样本推理,不需要也不支持在本地再训练
  • 任务类型:属于分割(Segmentation)模型,一次前向同时输出图像级异常分数像素级异常掩码,即同时支持异常检测与异常定位两个任务;
  • 导出限制:包级 Notes 明确指出该模型因 Vision Transformer 架构需要较多 GPU 显存,且后续章节将看到源码中显式禁用了导出功能。

包级__init__.py只导出AnomalyVFM(Lightning 模型),而AnomalyVFMModel位于 torch_model.py 中,两者正是 API 参考页分别用automodule挂接的对象。

2.AnomalyVFM(Lightning 模型):API 参考逐项解读

参考页第一个automodule指令指向 anomalyvfm.lightning_model 中的AnomalyVFM类。它继承自AnomalibModule,构造签名与行为如下:

>>> from anomalib.models.image import AnomalyVFM >>> # 零样本用法:构造即完成权重加载,无需 fit >>> model = AnomalyVFM()

2.1 构造函数参数

__init__(lightning_model.py#L44-L63)接收五个参数:

参数默认值说明
pre_processorTrue预处理配置;传True时使用configure_pre_processor返回的默认配置
post_processorTrue后处理配置;默认由configure_post_processor返回PostProcessor()
evaluatorTrue评估器配置,用于计算验证/测试指标
visualizerTrue可视化配置
precisionPrecisionType.FLOAT32推理精度,接受PrecisionType枚举或字符串(如"float32");字符串会被.lower()后转换为枚举,并写入内部AnomalyVFMModel.precision

构造时先创建内部AnomalyVFMModel(),再根据precision的类型(枚举或字符串)设置self.model.precision。这解释了官方配置文件中precision: float32字段的最终去向(见第 4 节)。

2.2 预处理器:768×768 默认尺寸

configure_pre_processor(lightning_model.py#L65-L83)使用torchvisionCompose([Resize(image_size, antialias=True)]),默认目标尺寸为DEFAULT_IMAGE_SIZE = 768,即768×768。这是 RADIO 骨干(patch size 16)下的空间特征网格基础:768/16 = 48×48 个 patch token。

值得注意的一个实现细节:configure_transforms(lightning_model.py#L131-L140)会忽略外部传入的image_size并打印警告,因为该模型自带固定的变换管线——也就是说,该模型并不遵循 Anomalib 全局image_size配置的通用约定。

2.3 推理路径:validation/test/predict 三合一

validation_step(lightning_model.py#L85-L103)是唯一的实质推理逻辑:

anomaly_scores, anomaly_maps = self.model(batch.image) predictions = InferenceBatch(pred_score=anomaly_scores, anomaly_map=anomaly_maps) return batch.update(**predictions._asdict())

test_steppredict_step均直接重定向到validation_step,因此anomalib testanomalib predict走的完全是同一套推理代码。

2.4 零样本属性与导出限制

两个属性与方法明确了该模型的边界:

  • learning_type恒返回LearningType.ZERO_SHOT(lightning_model.py#L113-L120);
  • trainer_arguments返回空字典——不需要训练超参,这也意味着不应调用anomalib train
  • to_torch/to_onnx/to_openvino三个导出入口全部被覆写为空操作,仅打印警告 "Exporting the model is not supported for AnomalyVFM model. Skipping..."(lightning_model.py#L152-L165)。因此该模型无法像其他模型那样部署到 OpenVINO/ONNX 边缘推理路径,只能在 PyTorch 运行时内使用。

3.AnomalyVFMModel(PyTorch 模型):权重加载与前向流程

参考页第二个automodule指令指向 anomalyvfm.torch_model 中的AnomalyVFMModel。其 docstring 概括了整体集成:"RADIO 基础 VFM + PEFT 适配器 + 简单解码器(像素级掩码)+ 简单预测器(图像级分数)"。

3.1 依赖与权重下载

构造函数(torch_model.py#L40-L65)做了三件事:

  1. 硬依赖检查:若缺少huggingface_hubsafetensors,抛出ImportError并提示pip install anomalib[huggingface]
  2. 挂载 PEFTself.model.add_peft(),默认秩r=64(见 3.3 节);
  3. 下载预训练权重:通过hf_hub_download从 Hugging Face Hub 仓库MaticFuc/anomalyvfm_radio拉取model.safetensors,并固定到 revision17654e763c8fae5ae1c44e2ec421a427783d6196以保证可复现,随后load_state_dict完成加载。

因此首次实例化需要联网(local_files_only=False),且权重会进入 HF 缓存目录;后续实例化命中缓存。

3.2 前向传播:双输出结构

forward(torch_model.py#L67-L107)在torch.autocast + torch.no_grad()下执行(推理模型,全程不建图),流程为:

summary, ftrs = self.model(img) # RADIO 输出 summary 与空间特征 ftrs = ftrs.permute(0, 2, 1).reshape(b, -1, h//16, w//16) # 还原为特征图 anomaly_score = self.predictor(summary).sigmoid() # 图像级分数 anomaly_maps, _ = self.decoder(ftrs) # 解码器输出 (mask, conf) anomaly_maps = anomaly_maps.sigmoid() anomaly_maps = self.mean_kernel(anomaly_maps) # 5×5 平均池化平滑 anomaly_maps = functional.interpolate(anomaly_maps, size=(h, w), mode="bilinear", ...)

关键实现细节:

  • 精度策略precisionNonefloat32时用torch.float32;否则 CPU 上自动回退到bfloat16,GPU 上用float16(torch_model.py#L82-L87);
  • 空间对齐:特征图按h // patch_size, w // patch_size重建(patch_size = 16,定义于 BaseModel),这要求输入分辨率能被 16 整除——默认 768×768 满足该条件;
  • 平滑与上采样:掩码先过 5×5AvgPool2dmean_kernel)抑制锯齿噪声,再双线性插值回原图尺寸。

3.3BaseModel:RADIO 骨干 + DoRA

BaseModel(torch_model.py#L110-L143)封装RADIOModel,固定feature_dim = 1024patch_size = 16add_peft(r=64)调用 dora.py 中的add_peft,递归遍历 RADIO 的每个子模块,将名字为qkv的线性层替换为DoRAQKVWrapper、名字为proj的替换为DoRAWrapper

从 dora.py 的源码看,这些包装器实现了 DoRA(Weight-Decomposed Low-Rank Adaptation):

  • 普通线性层(DoRAWrapper):在冻结原权重基础上学习低秩增量delta_w = (B @ A) * (alpha / r),然后对W + delta_w幅值/方向分解——magnitude(初始化为原权重逐行范数)乘以上单位方向,得到最终权重参与前向;
  • QKV 融合层(DoRAQKVWrapper):只对 Q 与 V 两个子块做低秩适配与幅值分解,K 保持原始权重,最后torch.cat([final_q, base_k, final_v])重组;
  • r=0时所有包装器退化为直通原始层,因此该参数也可理解为"适配器开关"。

这个设计与 AnomalyVFM 论文的设定一致:只在预训练 VFM 上附加少量可训练参数,主干特征保持不变。

3.4 RADIO 骨干内部结构

RADIOModel 由 radio.py 定义,要点:

  • 输入归一化InputConditioner使用 CLIP 风格的 mean/std(radio.py#L399-L416)对 0~1 图像做归一化;
  • Patch 化ViTPatchGenerator(radio.py#L88-L129)以patch_size=16embed_dim=1024将图像 unfold 成 patch token,经768→1024线性投影,并前置num_prefix_tokens=8个可学习前缀 token(相当于扩展版 [CLS]);
  • 动态分辨率位置编码:基础位置编码按 128×128 网格(16384 个 token)初始化,_interpolate_pos_encoding(radio.py#L323-L375)在输入分辨率对应网格不等于 128×128 时用双三次插值重采样空间位置编码,前缀 token 位置编码不足/超出时补零或截断——这让同一套权重可处理不同尺寸的输入;
  • 双输出forward返回summary(取前 3 个前缀 token 特征、压平为 1024×3 维向量,summary_idxs = [0, 1, 2])与spatial_features(第 8 个 token 之后的全部 patch 特征)。

3.5 解码器与预测器

decoder.py 提供两个轻量头部:

  • SimplePredictor:单个nn.Linear(dim, 1),输入summary(1024×3,即feat_dim * 3),输出图像级 logit,经sigmoid得到异常分数;
  • SimpleDecoder(decoder.py#L70-L106):一个BottleNeck(3×3 卷积 + GroupNorm×2)后接upsample_blocks=2DecoderBlockBilinear(每次上采样 2 倍并将通道减半,1024→512→256),最后两个 1×1 卷积分别输出mask logitconf logitforward返回二元组,但AnomalyVFMModel.forward只取第一个);
  • AnomalyVFMModel初始化时按feat_dim = 1024实例化SimpleDecoder(1024, 1, 1)SimplePredictor(3072)(torch_model.py#L52-L54)。

此外,模块 README 说明 ICPR 与 JIMS 两个论文版本的差异仅在于adapt_cls_features(分类头特征是否做适配,JIMS 版为默认的 False);当前仓库源码未暴露该开关,可理解为默认按 JIMS 版本实现。

4. 配置与命令行用法

4.1 模型配置文件

官方提供的模型配置 examples/configs/model/anomalyvfm.yaml 全文仅两项:

model: class_path: anomalib.models.AnomalyVFM init_args: precision: float32

class_path通过 Anomalib 的anomalib.models命名空间解析到AnomalyVFM(image/__init__.py 中from .anomalyvfm import AnomalyVFM);precision字符串在构造时被转换为PrecisionType并注入内部 torch 模型。由于trainer_arguments返回空字典,该配置不需要(也无法)追加max_stepsbatch_size等训练项。

4.2 CLI:直接零样本评测

模块 README 给出的标准评测命令为:

anomalib test --model AnomalyVFM --data MVTecAD --data.category <category>

例如对 MVTec AD 的bottle类别跑零样本评测:

anomalib test --model AnomalyVFM --data MVTecAD --data.category bottle

由于predict_stepvalidation_step共用同一实现,推理侧命令同理:

anomalib predict --model AnomalyVFM --data <path-or-dataset>

4.3 Python API 示例

from anomalib.models import AnomalyVFM model = AnomalyVFM() # 首次运行自动从 HF Hub 下载 RADIO + DoRA 权重 model.test() # 在配置的数据集上零样本评测 # 或单图推理 prediction = model.predict("path/to/image.jpg") prediction.visualize(save_path="anomaly_result.png")

注意两个前提:其一,需要安装anomalib[huggingface]额外依赖组(huggingface_hubsafetensors),否则构造时抛ImportError;其二,该模型不能fit,也不能导出 ONNX/OpenVINO/TorchScript(调用to_onnx等只会得到跳过警告)。

5. 参考性能:MVTec AD 零样本结果

据模块 README(anomalyvfm/README.md#L28-L49)记载,该 Anomalib 实现在 MVTec AD 上的零样本结果如下:

categoryI-AUROCI-F1MaxP-AUROCP-F1MaxAUPRO
bottle98.3797.6494.9269.8590.11
cable91.9288.1487.5418.8056.55
capsule96.4795.2497.8642.3193.57
carpet99.8498.8999.6575.4798.69
grid99.9299.1397.4243.1690.91
hazelnut99.1497.1496.7055.7192.93
leather99.9799.4699.5657.7299.01
metal_nut98.1997.3066.2828.8483.53
pill95.4095.2787.6338.5591.75
screw97.9495.5599.3647.9196.55
tile99.4298.8296.2474.4893.44
toothbrush91.8193.1092.6536.2691.68
transistor78.8772.2268.7515.4554.03
wood100.00100.0096.2370.3878.82
zipper98.8497.1498.3662.5794.36
average96.4195.0091.9449.1687.06

这些数据表明该实现完全复现了论文报告的零样本水平:图像级指标(I-AUROC/I-F1Max)普遍高于 90,而像素级指标(P-F1Max 平均 49.16)与图像级存在明显差距,这是零样本掩码预测的常见特征,复现或调参时应以 AUPRO(平均 87.06)作为定位质量的综合参考。

6. 小结与使用边界

回到 API 参考页覆盖的两个类,可以这样概括anomalyvfm.md的完整技术图景:

  • AnomalyVFM是面向anomalib test/predict流水线的 Lightning 封装:固定 768×768 预处理、零样本学习类型、空训练参数、不支持导出;
  • AnomalyVFMModel是推理核心:RADIO VFM 骨干(1024 维、patch 16、8 前缀 token、可插值位置编码)+ 秩 64 的 DoRA 适配器 + 双分支轻量头(分数预测器与掩码解码器),权重固定 revision 从 HF Hub 加载;
  • 使用门槛只有两点:安装anomalib[huggingface]依赖组、确保输入分辨率可被 16 整除(默认预处理已满足)。

仓库中未包含针对 AnomalyVFM 的专属单元测试文件,其正确性主要由模块 README 的 MVTec AD 评测表与上述固定权重 revision 共同约束。若需要评估其他数据集(VisA、Real-IAD、MPDD 等)的表现,模块 README 指引参考原论文或官方实现。

【免费下载链接】anomalibAn anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.项目地址: https://gitcode.com/GitHub_Trending/an/anomalib

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询