DINOv3 零样本分割完整指南:dino.txt 三步跑通像素级掩码
【免费下载链接】dinov3Reference PyTorch implementation and models for DINOv3项目地址: https://gitcode.com/GitHub_Trending/di/dinov3
DINOv3 是 Meta 发布的视觉基础模型,它的 dino.txt 变体可以直接做零样本分割:不用像素标注、不用训练,给一组类别文本描述,就能输出逐像素的分类掩码。本文先讲清背后的机制,再走通从环境到 Cityscapes 街景评估的完整流程。
为什么需要零样本分割
传统语义分割有三个固定成本:标注贵、训练慢、类别集被训练数据锁死。一个在 19 类街景数据上训练好的模型,换个场景就要重新收集标注、重新训练。零样本分割把"能分割什么"的边界从训练数据挪到了文本描述上——新增类别只需要多写一句话,不用动训练管线。DINOv3 的 dino.txt 模型提供的正是这种能力:视觉特征与文本特征对齐,对任意类别直接出分割结果,属于典型的无需训练的语义分割方案。
原理一句话:特征对齐后算相似度
整套方法的核心可以压缩成一句话:把图像 patch 特征和文本特征拉到同一个空间,逐 patch 与逐类别算余弦相似度,相似度就是该像素的类别概率。具体流程是:图像过 DINOv3 ViT 骨干后,再经两个附加 head block 提取按 16×16 patch 排布的密集特征;文本走 24 层、维度 1280 的 Transformer 文本塔编码,L2 归一化后对多个提示模板取平均。最后做一次"归一化 + 内积",得到 [类别数, 网格高, 网格宽] 的相似度图,即可上采样到任意目标分辨率。整个推理链路里没有可学习的分割头。
零样本分割三步跑通
这一节把环境、模型、推理合并成三步,完成第一次分割。
第一步,装环境。克隆仓库后按 conda 清单建环境即可,PyTorch 建议装 CUDA 版本:
git clone https://gitcode.com/GitHub_Trending/di/dinov3 cd dinov3 micromamba env create -f conda.yaml && micromamba activate dinov3第二步,加载模型。hub 入口dinov3_vitl16_dinotxt_tet1280d20h24l()返回模型和分词器一对对象,默认下载预训练权重:
from dinov3.hub.dinotxt import dinov3_vitl16_dinotxt_tet1280d20h24l model, tokenizer = dinov3_vitl16_dinotxt_tet1280d20h24l() # 默认加载预训练权重 model.to("cuda").eval()第三步,执行推理。文本侧:把每个类别名套进一批提示模板,用encode_text编码后在模板维度上取平均再归一化,得到每个类别一个向量。图像侧:示例代码里的encode_image会先把图像拉伸到 patch 尺寸的整数倍,再取出 head block 的密集特征。两边对齐后算余弦相似度,取类别维 argmax 就是掩码:
text_feats = F.normalize(text_feats.mean(dim=0), p=2, dim=-1) # 模板取平均 cos = torch.einsum("cd,hwd->chw", text_feats, F.normalize(blocks_feats, p=2)) mask = cos.argmax(dim=0) # 每个 patch 取相似度最高的类别whole 还是 slide:推理模式怎么选
示例代码提供两种推理模式:whole 是整图一次前向;slide 是滑动窗口,按固定边长裁窗口、按 stride 平移,每个窗口算一次相似度,再上采样回窗口分辨率,按"该像素被几个窗口覆盖"累加平均拼回整图。
| 模式 | 输入方式 | 适用场景 | 特点 |
|---|---|---|---|
| whole | 整图单次前向 | 中等分辨率(短边 1024 以内) | 快、前向次数少;大图细节被压缩,显存随像素数平方增长 |
| slide | 固定边长窗口 + 步长滑动 | 高分辨率街景、遥感大图 | 细节保留好、单窗口显存恒定;总耗时与窗口数成正比 |
示例的默认配置是短边 resize 到 512,slide 窗口 side=384、stride=192。经验法则:图像缩到默认分辨率后仍看得清主体就用 whole;需要保住小目标细节、原图又很大,就切 slide,窗口数和重叠量决定耗时。
把精度做上去:两个实操技巧
技巧一,提示模板。单个 "a photo of a car." 给出的特征向量很窄,对长尾外观或低质量图像容易失配。示例代码沿用 CLIP 社区惯例,内置约 80 条模板(模糊照片、渲染图、特写、涂鸦等表述变体),每类编码全部模板后对嵌入取平均,让文本侧表征更稳。自建类别表时保持模板集不动、只改类别名即可复用。
技巧二,分辨率取舍。短边 resize 值决定分割图的粒度:越大,小目标边界越清晰,但显存和耗时同步上升。调参时建议先用 whole 模式在小批代表图上定方向,再逐步提高分辨率或改 slide 验证边界是否变好,不要一上来就顶格分辨率。
实战:Cityscapes 街景分割
示例 notebook 用 Cityscapes 的 19 个类别做现成基准:类别名是 road、sidewalk、building、person、car 这样的英文短语,直接以常量元组形式写在数据集类里。有两个设计点值得借鉴:一是类别名与数据加载逻辑解耦,换类别集只改那个元组和对应的标签映射,推理代码零改动;二是基类里内置了 ignore 标签处理(ADE20K 分支把背景 0 映射成 255 再平移其余标签),说明"忽略背景"是评估侧的一等公民。
评估指标是 mIoU(MulticlassJaccardIndex,macro 平均),ignore_index=255 把背景排除在统计之外。定性地说,dino.txt 的零样本输出在 Cityscapes 这类标准评测集上已达到可用水平,与监督方法的差距主要体现在边界贴合度和小目标(如交通灯、交通标志)上。自己做评测时,保持指标、忽略规则、类别顺序与 notebook 一致,数字才可对比。
常见问题与部署建议
显存占用多少?推理显存主要由图像分辨率决定,且近似随像素数平方增长。短边 512 的默认配置在 24GB 级别的消费级显卡上可以跑;分辨率再往上顶时,先切 slide 模式而不是继续加 whole 的输入尺寸。
能不能批量推理?当前示例 notebook 按单图顺序处理,批处理位置在代码里仍是 TODO。想提吞吐,合理做法是:文本特征一次性编码完全批复用(文本特征与图像无关),图像侧再逐图前向,避免重复编码。
要不要开混合精度?推荐开。推理不回传梯度,半精度前向能直接省显存、提速度;相似度图在 argmax 前可先转回 float,避免半精度下两类分数差太小时的不稳定。
类别表怎么改?唯一入口是数据集类的CLASS_NAMES元组:加一个名字,相似度图就自动多一行对应通道。注意两件事:英文措辞要贴近目标语义;掩码通道顺序由元组顺序决定,标签映射必须同步调整。
相关资源
- 视觉骨干定义:dinov3/models/vision_transformer.py
- dino.txt hub 入口:dinov3/hub/dinotxt.py
- 零样本分割推理示例:notebooks/dinotxt_segmentation_inference.ipynb
- 文本塔:dinov3/eval/text/text_tower.py
- 视觉塔:dinov3/eval/text/vision_tower.py
- 分割评估配置:dinov3/eval/segmentation/configs/
【免费下载链接】dinov3Reference PyTorch implementation and models for DINOv3项目地址: https://gitcode.com/GitHub_Trending/di/dinov3
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考