DINOv3上手指南:改变视觉模型使用方式,一个模型搞定分割、检测、深度估计

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时计算 Flink 版,1000CU*H 3个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: DINOv3是Meta推出的自监督视觉模型,支持冻结主干、仅训练轻量任务头即可在分割、深度估计等任务上达到SOTA,极大降低训练成本。其密集特征质量优异,适用于遥感、工业检测等多领域,真正实现“一个模型走天下”。

DINOv3是Meta推出的自监督视觉骨干网络,最大的亮点是你可以把整个backbone冻住不动,只训练一个很小的任务头就能在各种密集预测任务上拿到SOTA结果。这对实际工程应用来说意义重大,因为大部分时候我们并不想重新训练一个几十亿参数的模型。

为什么现在要关注DINOv3

首先是训练数据的规模优势。DINOv3在LVD-1689M(16.89亿张图像)和卫星数据集SAT-493M(4.93亿张)上用SSL训练,这意味着你不需要等人工标注就能利用海量数据。

更重要的是,DINOv3的密集特征质量足够好,以至于backbone完全冻结的情况下,简单加个线性层或者轻量级头部就能在分割、深度估计、检索这些任务上达到很好的效果。这在以前是很难想象的,通常你都需要微调整个模型。

另外,DINOv3作者还证明了同一个backbone可以在完全不同的领域都work,而且是在不做任何微调的情况下就能超过那些专门为某个任务设计的解决方案。这基本上实现了"一个模型走天下"的理想。

相比DINOv2的技术改进

训练目标方面,DINOv3在原有的DINO自蒸馏和多裁剪基础上,加入了iBOT的掩码补丁建模、KoLeo对[CLS] token的正则化,以及一个新的Gram anchoring项。这个Gram anchoring主要是为了解决长时间训练时密集特征图会退化的问题。

对于最大的7B模型,他们设计了三阶段训练流程:先预训练,然后加入Gram anchoring,最后做高分辨率适应,确保特征在大尺寸输入下依然清晰。github仓库里有完整的SLURM命令,可以直接复现。

模型选择

Vision Transformer系列都用patch size 16和4个register token。从ViT-S的21M参数到ViT-7B的67亿参数,大模型切换到SwiGLU激活函数,全部用RoPE位置编码。需要注意输入尺寸必须是16的倍数,否则模型会自动裁剪。

还有个从ViT-7B蒸馏出来的ConvNeXt系列(29M到198M参数),在延迟和显存有限制的场景下很有用。

针对遥感应用,他们还训练了专门的卫星预训练版本,包括ViT-L蒸馏版和ViT-7B从头训练版。

在实际选择时,边缘设备或实时应用可以用ConvNeXt-Tiny/Small或ViT-B蒸馏版;服务器端平衡考虑选ViT-B/L蒸馏版;如果追求极致效果或处理超大图像,就上ViT-H+或ViT-7B,可以直接保持冻结状态,用tiling的方式处理输入。

性能表现

这里说的性能表现都是冻结backbone加轻量级头部的结果。ADE20K语义分割上,ViT-B达到51.8 mIoU,ViT-L是54.9,ViT-7B直接干到60.7。NYU深度估计任务上,ViT-L的AbsRel是0.352,ViT-7B降到0.309。

ConvNeXt蒸馏版本在分辨率提升时效果明显改善,Tiny从256px升到512px时ADE20K从52.6提升到58.7 mIoU,Large版本从59.3跳到65.2。

卫星数据的GEO-Bench测试中,ViT-7B在分类平均值上略胜ViT-L(81.1 vs 79.6),分割任务上也有小幅领先(75.0 vs 74.5)。

Token结构和特征图处理

DINOv3的输出结构是[CLS] + 4个register token + patch grid。对224×224输入(patch 16),总共是1 + 4 + 196 = 201个token。这4个register token相当于"内存槽",能减少patch token中的高范数伪影,对密集任务很有帮助。

如果输入图像尺寸不是16的倍数,DINOv3会裁剪到最接近的较小倍数。但对于需要保留细节的密集任务,你可以更愿意在预处理时做padding而不是让模型自动裁剪。

代码实现

特征提取

 # pip install torch torchvision transformers pillow  
from transformers import AutoModel, AutoImageProcessor  
from transformers.image_utils import load_image  
import torch  

model_id = "facebook/dinov3-vitb16-pretrain-lvd1689m"  # 如果你有访问权限,可以换成vitl/7b
processor = AutoImageProcessor.from_pretrained(model_id)  
model = AutoModel.from_pretrained(model_id, device_map="auto")  
img = load_image("http://images.cocodataset.org/val2017/000000039769.jpg")  
inputs = processor(images=img, return_tensors="pt").to(model.device)  
with torch.inference_mode():  
    outputs = model(**inputs)  
cls = outputs.last_hidden_state[:, 0]  # 全局([CLS])
num_regs = model.config.num_register_tokens  
patch_flat = outputs.last_hidden_state[:, 1 + num_regs:, :]  
# 重塑为[B, C, H, W],步长=16
B, N, C = patch_flat.shape  
H = W = int((N) ** 0.5)  
 feat_map = patch_flat.reshape(B, H, W, C).permute(0, 3, 1, 2)

这段代码完全按照官方文档的token layout来处理,包括register token的处理和patch=16的设定。

分割头实现

 import torch.nn as nn  

class LinearSegHead(nn.Module):  
    def __init__(self, in_ch, n_classes):  
        super().__init__()  
        self.proj = nn.Conv2d(in_ch, n_classes, 1)  
        self.up = nn.Upsample(scale_factor=16, mode="bilinear", align_corners=False)  
    def forward(self, fmap):  # fmap: [B, C, H, W](步长16)
        return self.up(self.proj(fmap))  # 输入分辨率的logits
head = LinearSegHead(in_ch=feat_map.shape[1], n_classes=150).to(model.device)  
 for p in model.parameters(): p.requires_grad_(False)  # 保持骨干网络冻结

这就是冻结backbone的经典用法。你可以从最简单的线性层开始,只有在效果遇到瓶颈时才考虑加更复杂的decoder。

官方仓库还提供了预训练好的分类、深度估计、分割头,可以通过torch.hub直接加载。对于高分辨率图像,他们也给出了tiling和滑动窗口推理的示例代码,这些对于处理地图和城市场景时是可以拿来直接用的。

实际应用场景

DINOv3最适合的场景是那些需要"零微调"的应用。比如图像检索用最近邻搜索,分类任务直接在[CLS] token上跑k-NN或者逻辑回归,语义分割和深度估计在密集特征上加线性层,还有无监督的对象发现、几何语义匹配、视频分割跟踪等等。视频分类只需要一个4层的attention probe就够了。

一个很好的案例是世界资源研究所(WRI)用DINOv3来做树木计数和高度估计。他们用高分辨率卫星和无人机图像来监测森林恢复项目,为环保融资提供数据支持。据他们的报告,DINOv3基本上是开箱即用的,而且在不同传感器之间的泛化能力很强。

在GEO-Bench这个遥感基准测试上,用SAT-493M预训练的DINOv3确实表现不错,ViT-7B在分类和分割任务上都略胜ViT-L。如果你做农业、森林或灾害监测相关的工作,这个信号还是很有参考价值的。

训练细节

对于7B模型的完整训练流程,仓库里有具体的命令,包括预训练到Gram anchoring再到高分辨率适应的三个阶段。他们还提供了一个快速demo,可以在32张H100上用ViT-L对ImageNet-1k进行14小时训练

技术栈方面,用的是DINO loss + multi-crop,patch token上跑iBOT,[CLS]上用KoLeo正则化,再加上Gram anchoring。底层是FSDP2,bf16和fp8的matmul优化。

训练的透明度也是非常哇塞,他们公开了ViT-7B大概需要61,440 GPU小时,碳排放约18 tCO₂e。这种transparency在学术界还是比较少见的,对工业界做预算规划很有帮助。

部署时的注意事项

图像尺寸一定要是16的倍数,否则模型会自动裁剪。对于医学影像、地图这种细节很重要的场景,你最好在预处理时做padding,或者用带重叠的tiling推理。

构建密集预测的头部时,记得把[CLS]和register token丢掉,只用patch token来reshape特征图。

如果要压缩模型,官方文档里有int4 TorchAO的示例,对ViT-7B的推理压缩很有用,不过记得在你的具体任务上验证一下数值精度。

最后还有个问题,模型提到了地域和收入水平的差异。如果你要在国家级别部署(比如跨印度不同邦的不同地貌),可能需要考虑小的domain adapter或者平衡采样。

完整的训练示例

 """  
train_seg_head.py — 在冻结DINOv3特征上的最小训练循环。
用ADE20K/Cityscapes等替换`YourDataset`(图像、掩码)。
"""  
import torch, torch.nn as nn, torch.optim as optim  
from torch.utils.data import DataLoader  
from transformers import AutoModel, AutoImageProcessor  

MODEL_ID = "facebook/dinov3-vitb16-pretrain-lvd1689m"  
N_CLASSES = 150  
class LinearSegHead(nn.Module):  
    def __init__(self, in_ch, n_classes):  
        super().__init__()  
        self.proj = nn.Conv2d(in_ch, n_classes, 1)  
        self.up = nn.Upsample(scale_factor=16, mode="bilinear", align_corners=False)  
    def forward(self, fmap): return self.up(self.proj(fmap))  
def extract_fmap(model, proc, image):  
    inputs = proc(images=image, return_tensors="pt").to(model.device)  
    with torch.inference_mode():  
        out = model(**inputs)  
    num_regs = model.config.num_register_tokens  
    grid = out.last_hidden_state[:, 1 + num_regs:, :]  # 丢弃CLS+寄存器
    B, N, C = grid.shape  
    H = W = int(N ** 0.5)  
    return grid.reshape(B, H, W, C).permute(0,3,1,2)  
def main(train_set, val_set, epochs=10, lr=1e-3):  
    proc = AutoImageProcessor.from_pretrained(MODEL_ID)  
    model = AutoModel.from_pretrained(MODEL_ID, device_map="auto")  
    for p in model.parameters(): p.requires_grad_(False)  
    # 推断通道数一次
    x0, _ = train_set[0]  
    fmap0 = extract_fmap(model, proc, x0)  
    head = LinearSegHead(fmap0.shape[1], N_CLASSES).to(model.device)  
    opt = optim.AdamW(head.parameters(), lr=lr)  
    loss = nn.CrossEntropyLoss()  
    train = DataLoader(train_set, batch_size=4, shuffle=True)  
    val = DataLoader(val_set, batch_size=4)  
    for ep in range(epochs):  
        head.train()  
        for img, mask in train:  
            fmap = extract_fmap(model, proc, img)  
            logits = head(fmap)  
            L = loss(logits, mask.to(logits.device).long())  
            opt.zero_grad(); L.backward(); opt.step()  
        # TODO: 在`val`上添加简单的mIoU
     torch.save(head.state_dict(), "dinov3_seg_head.pth")

这个示例严格按照官方的token layout和冻结特征的使用方式来写。

总结

对于做地理空间分析、工业检测、零售货架规划、交通智能或智慧城市平台的团队来说,DINOv3提供了一个很实用的方案:用一个backbone应对多种任务,保持冻结状态,只加很小的头部,对高分辨率输入做tiling处理就能部署,不用陷入不断重新微调大模型的循环里。这才是DINOv3真正超模的地方。

https://avoid.overfit.cn/post/7057f31255554ac1af8e743c39731e6b

目录
相关文章
|
监控 PyTorch 算法框架/工具
Qwen-VL怎么用自己的数据集微调
Qwen-VL怎么用自己的数据集微调
1740 0
|
3月前
|
缓存 负载均衡 算法
合理选择任务调度的路由策略,可以帮助降本 50%
任务调度系统在处理短周期任务时,路由策略对执行器负载均衡至关重要。不同策略适用于不同场景:轮询确保平均分配,随机依赖概率,LFU/LRU基于使用频率或时间,一致性哈希保障节点变化时的稳定性,而负载最低优先与任务权重策略则更智能地应对资源消耗差异。合理选择路由策略可显著提升系统性能与资源利用率。
385 34
合理选择任务调度的路由策略,可以帮助降本 50%
|
8月前
|
机器学习/深度学习 编解码 自然语言处理
SigLIP 2:多语言语义理解、定位和密集特征的视觉语言编码器
SigLIP 2 是一种改进的多语言视觉-语言编码器系列,通过字幕预训练、自监督学习和在线数据管理优化性能。它在零样本分类、图像-文本检索及视觉表示提取中表现卓越,支持多分辨率处理并保持图像纵横比。模型提供 ViT-B 至 g 四种规格,采用 WebLI 数据集训练,结合 Sigmoid 损失与自蒸馏等技术提升效果。实验表明,SigLIP 2 在密集预测、定位任务及多模态应用中显著优于前代和其他基线模型。
642 9
SigLIP 2:多语言语义理解、定位和密集特征的视觉语言编码器
|
11月前
|
数据采集 前端开发 物联网
【项目实战】通过LLaMaFactory+Qwen2-VL-2B微调一个多模态医疗大模型
本文介绍了一个基于多模态大模型的医疗图像诊断项目。项目旨在通过训练一个医疗领域的多模态大模型,提高医生处理医学图像的效率,辅助诊断和治疗。作者以家中老人的脑部CT为例,展示了如何利用MedTrinity-25M数据集训练模型,经过数据准备、环境搭建、模型训练及微调、最终验证等步骤,成功使模型能够识别CT图像并给出具体的诊断意见,与专业医生的诊断结果高度吻合。
20004 162
【项目实战】通过LLaMaFactory+Qwen2-VL-2B微调一个多模态医疗大模型
|
6月前
|
机器学习/深度学习 人工智能 算法
Python+YOLO v8 实战:手把手教你打造专属 AI 视觉目标检测模型
本文介绍了如何使用 Python 和 YOLO v8 开发专属的 AI 视觉目标检测模型。首先讲解了 YOLO 的基本概念及其高效精准的特点,接着详细说明了环境搭建步骤,包括安装 Python、PyCharm 和 Ultralytics 库。随后引导读者加载预训练模型进行图片验证,并准备数据集以训练自定义模型。最后,展示了如何验证训练好的模型并提供示例代码。通过本文,你将学会从零开始打造自己的目标检测系统,满足实际场景需求。
4752 0
Python+YOLO v8 实战:手把手教你打造专属 AI 视觉目标检测模型
|
JSON 人工智能 数据格式
AI计算机视觉笔记二十六:YOLOV8自训练关键点检测
本文档详细记录了使用YOLOv8训练关键点检测模型的过程。首先通过清华源安装YOLOv8,并验证安装。接着通过示例权重文件与测试图片`bus.jpg`演示预测流程。为准备训练数据,文档介绍了如何使用`labelme`标注工具进行关键点标注,并提供了一个Python脚本`labelme2yolo.py`将标注结果从JSON格式转换为YOLO所需的TXT格式。随后,通过Jupyter Notebook可视化标注结果确保准确性。最后,文档展示了如何组织数据集目录结构,并提供了训练与测试代码示例,包括配置文件`smoke.yaml`及训练脚本`train.py`,帮助读者完成自定义模型的训练与评估。
3395 2
|
9月前
|
机器学习/深度学习
YOLOv11改进策略【损失函数篇】| 替换激活函数为Mish、PReLU、Hardswish、LeakyReLU、ReLU6
YOLOv11改进策略【损失函数篇】| 替换激活函数为Mish、PReLU、Hardswish、LeakyReLU、ReLU6
2162 4
|
9月前
|
编解码 算法 计算机视觉
YOLOv11改进策略【小目标改进】| 添加专用于小目标的检测层 附YOLOv1~YOLOv11的检测头变化详解
YOLOv11改进策略【小目标改进】| 添加专用于小目标的检测层 附YOLOv1~YOLOv11的检测头变化详解
1634 11