Transformers 文档
VidEoMT
并获得增强的文档体验
开始使用
该模型于 2026 年 2 月 19 日在 HF 论文中发布,并于 2026 年 3 月 25 日贡献给 Hugging Face Transformers。
VidEoMT
概述
VidEoMT 模型由 Narges Norouzi, Idil Esen Zulfikar, Niccolò Cavagnero, Tommie Kerssies, Bastian Leibe, Gijs Dubbelman, Daan de Geus 在论文 Your ViT is Secretly Also a Video Segmentation Model 中提出。视频仅编码器掩码 Transformer (VidEoMT) 是一个基于普通 Vision Transformer (ViT) 构建的轻量级仅编码器在线视频分割模型。它是 EoMT 针对视频任务的最小化扩展,在 ViT 编码器内部执行空间和时间推理,无需依赖专门的跟踪模块或繁重的任务特定头部。
论文摘要如下:
现有的在线视频分割模型通常将单帧分割器与复杂的专用跟踪模块相结合。虽然有效,但这些模块引入了显著的架构复杂性和计算开销。最近的研究表明,普通的 Vision Transformer (ViT) 编码器在具备足够容量和大规模预训练的情况下,无需专用模块即可进行精确的图像分割。受此观察启发,我们提出了视频仅编码器掩码 Transformer (VidEoMT),这是一个简单的仅编码器视频分割模型,消除了对专用跟踪模块的需求。为了在仅编码器的 ViT 中实现时间建模,VidEoMT 引入了一种轻量级的查询传播机制,通过重用前一帧的查询在帧间传递信息。为了平衡这一点与对新内容的适应性,它采用了查询融合策略,将传播的查询与一组时间无关的学习查询相结合。因此,VidEoMT 在不增加复杂性的情况下获得了跟踪器的优势,在实现竞争精度的同时速度提高了 5 到 10 倍,并使用 ViT-L 主干网在最高 160 FPS 的速度下运行。
技巧
- VidEoMT 目前仅支持 DINOv2 主干(带有寄存器标记 tokens)。可用的模型尺寸有 ViT-S、ViT-B 和 ViT-L。
- 该模型接受 5D 张量形式的视频输入,形状为
(batch_size, num_frames, 3, height, width)。 - VidEoMT 支持三种视频分割任务:实例、语义和全景分割,每种任务在视频处理器上都有专门的后处理方法。
架构信息
VidEoMT 构建于 EoMT 之上,后者将带有寄存器标记 (register tokens) 的普通 DINOv2 预训练 Vision Transformer 重新用作分割模型。EoMT 在 ViT 编码器内直接引入了学习到的目标查询 (object queries) 和一个轻量级的掩码预测头,从而消除了对任务特定解码器的需求。
VidEoMT 通过两个关键添加将其扩展到视频领域:
- 查询传播 (Query propagation):来自前一帧的对象查询通过线性投影 (
query_updater) 传递到下一帧,从而无需专用跟踪器即可实现时间推理。 - 查询融合 (Query fusion):传播的查询被添加进一组时间无关的学习查询中,允许模型适应视频中出现的新对象。
早期编码器层独立(并行)处理所有帧,而最终的块则使用融合后的查询按帧操作,从而产生每帧的掩码和类别预测。
用法示例
使用 VidEoMT 的 Hugging Face 实现来对预训练模型进行推理。下面的示例复用了公共的 tue-mps/videomt-dinov2-small-ytvis2019 检查点,演示了样本视频上的视频实例、语义和全景后处理。
视频实例分割
import matplotlib.pyplot as plt
import numpy as np
import torch
from transformers import AutoModelForUniversalSegmentation, AutoVideoProcessor
from transformers.video_utils import load_video
model_id = "tue-mps/videomt-dinov2-small-ytvis2019"
processor = AutoVideoProcessor.from_pretrained(model_id)
model = AutoModelForUniversalSegmentation.from_pretrained(model_id, device_map="auto")
video_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/videos/pexels-allan-mas-5362370.mp4"
# Sample 8 frames to keep the example lightweight.
video_frames, _ = load_video(video_url, num_frames=8)
inputs = processor(videos=[video_frames], return_tensors="pt").to(model.device)
with torch.inference_mode():
outputs = model(**inputs)
original_height, original_width = video_frames[0].shape[:2]
target_sizes = [(original_height, original_width)] * len(video_frames)
results = processor.post_process_instance_segmentation(
outputs,
target_sizes=target_sizes,
)
fig, axes = plt.subplots(2, 4, figsize=(16, 8))
for idx, (ax, frame, result) in enumerate(zip(axes.flatten(), video_frames, results)):
ax.imshow(frame)
seg = result["segmentation"].cpu().numpy()
masked = np.ma.masked_where(seg == -1, seg)
ax.imshow(masked, alpha=0.6, cmap="tab20")
ax.set_title(f"Frame {idx}")
ax.axis("off")
plt.suptitle("Video Instance Segmentation")
plt.tight_layout()
plt.show()视频语义分割
import matplotlib.pyplot as plt
import torch
from transformers import AutoModelForUniversalSegmentation, AutoVideoProcessor
from transformers.video_utils import load_video
model_id = "tue-mps/videomt-dinov2-small-ytvis2019"
processor = AutoVideoProcessor.from_pretrained(model_id)
model = AutoModelForUniversalSegmentation.from_pretrained(model_id, device_map="auto")
video_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/videos/pexels-allan-mas-5362370.mp4"
# Sample 8 frames to keep the example lightweight.
video_frames, _ = load_video(video_url, num_frames=8)
inputs = processor(videos=[video_frames], return_tensors="pt").to(model.device)
with torch.inference_mode():
outputs = model(**inputs)
original_height, original_width = video_frames[0].shape[:2]
target_sizes = [(original_height, original_width)] * len(video_frames)
preds = processor.post_process_semantic_segmentation(
outputs,
target_sizes=target_sizes,
)
fig, axes = plt.subplots(2, 4, figsize=(16, 8))
for idx, (ax, frame, seg_map) in enumerate(zip(axes.flatten(), video_frames, preds)):
ax.imshow(frame)
ax.imshow(seg_map.cpu().numpy(), alpha=0.6, cmap="tab20")
ax.set_title(f"Frame {idx}")
ax.axis("off")
plt.suptitle("Video Semantic Segmentation")
plt.tight_layout()
plt.show()视频全景分割
import matplotlib.pyplot as plt
import numpy as np
import torch
from transformers import AutoModelForUniversalSegmentation, AutoVideoProcessor
from transformers.video_utils import load_video
model_id = "tue-mps/videomt-dinov2-small-ytvis2019"
processor = AutoVideoProcessor.from_pretrained(model_id)
model = AutoModelForUniversalSegmentation.from_pretrained(model_id, device_map="auto")
video_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/videos/pexels-allan-mas-5362370.mp4"
# Sample 8 frames to keep the example lightweight.
video_frames, _ = load_video(video_url, num_frames=8)
inputs = processor(videos=[video_frames], return_tensors="pt").to(model.device)
with torch.inference_mode():
outputs = model(**inputs)
original_height, original_width = video_frames[0].shape[:2]
target_sizes = [(original_height, original_width)] * len(video_frames)
results = processor.post_process_panoptic_segmentation(
outputs,
target_sizes=target_sizes,
)
fig, axes = plt.subplots(2, 4, figsize=(16, 8))
for idx, (ax, frame, result) in enumerate(zip(axes.flatten(), video_frames, results)):
ax.imshow(frame)
seg = result["segmentation"].cpu().numpy()
masked = np.ma.masked_where(seg == -1, seg)
ax.imshow(masked, alpha=0.6, cmap="tab20")
ax.set_title(f"Frame {idx}")
ax.axis("off")
plt.suptitle("Video Panoptic Segmentation")
plt.tight_layout()
plt.show()VideomtVideoProcessor
class transformers.VideomtVideoProcessor
< 源代码 >( **kwargs: typing_extensions.Unpack[transformers.processing_utils.VideosKwargs] )
post_process_semantic_segmentation
< 源代码 >( outputs target_sizes: list ) → list[torch.Tensor]
将 VideomtForUniversalSegmentation 的输出转换为语义分割预测。
post_process_instance_segmentation
< 源代码 >( outputs target_sizes: list threshold: float = 0.5 ) → list[dict]
参数
- outputs (
VideomtForUniversalSegmentationOutput) — 模型的原始输出。 - target_sizes (
list[tuple[int, int]]) — 对应于每个预测所需最终大小的(height, width)元组列表。长度应与输出中的帧数匹配。 - threshold (
float, 可选, 默认为 0.5) — 保留实例的最小组合分数。
返回
list[dict]
字典列表(每帧一个),每个包含:
"segmentation"— 一个形状为(height, width)的torch.Tensor,包含实例 ID(背景为 -1)。"segments_info"— 一个字典列表,包含每个实例的"id"、"label_id"和"score"。
将 VideomtForUniversalSegmentation 的输出转换为实例分割预测。
post_process_panoptic_segmentation
< 源代码 >( outputs target_sizes: list threshold: float = 0.8 mask_threshold: float = 0.5 overlap_mask_area_threshold: float = 0.8 label_ids_to_fuse: set[int] | None = None ) → list[dict]
参数
- outputs (
VideomtForUniversalSegmentationOutput) — 模型的原始输出。 - target_sizes (
list[tuple[int, int]]) — 对应于每个预测所需最终大小的(height, width)元组列表。长度应与输出中的帧数匹配。 - threshold (
float, 可选, 默认为 0.8) — 保留预测分割的最小分数。 - mask_threshold (
float, 可选, 默认为 0.5) — 用于将掩码概率二值化的阈值。 - overlap_mask_area_threshold (
float, 可选, 默认为 0.8) — 将掩码合并为单个分割区域的重叠阈值。 - label_ids_to_fuse (
set[int], 可选) — 应在断开区域上进行融合的标签 ID。
返回
list[dict]
字典列表(每帧一个),每个包含:
"segmentation"— 一个形状为(height, width)的torch.Tensor,包含分割 ID(背景为 -1)。"segments_info"— 一个字典列表,包含每个分割的"id"、"label_id"和"score"。
将 VideomtForUniversalSegmentation 的输出转换为全景分割预测。
VideomtConfig
class transformers.VideomtConfig
< 源代码 >( transformers_version: str | None = None architectures: list[str] | None = None output_hidden_states: bool | None = False return_dict: bool | None = True dtype: typing.Union[str, ForwardRef('torch.dtype'), NoneType] = None chunk_size_feed_forward: int = 0 is_encoder_decoder: bool = False id2label: dict[int, str] | dict[str, str] | None = None label2id: dict[str, int] | dict[str, str] | None = None problem_type: typing.Optional[typing.Literal['regression', 'single_label_classification', 'multi_label_classification']] = None hidden_size: int = 1024 num_hidden_layers: int = 24 num_attention_heads: int = 16 hidden_act: str = 'gelu' hidden_dropout_prob: float | int = 0.0 initializer_range: float = 0.02 layer_norm_eps: float = 1e-06 image_size: int | list[int] | tuple[int, int] = 640 patch_size: int | list[int] | tuple[int, int] = 16 num_channels: int = 3 mlp_ratio: int = 4 layerscale_value: float = 1.0 drop_path_rate: float | int = 0.0 num_upscale_blocks: int = 2 attention_dropout: float | int = 0.0 use_swiglu_ffn: bool = False num_blocks: int = 4 no_object_weight: float = 0.1 class_weight: float = 2.0 mask_weight: float = 5.0 dice_weight: float = 5.0 train_num_points: int = 12544 oversample_ratio: float = 3.0 importance_sample_ratio: float = 0.75 num_queries: int = 200 num_register_tokens: int = 4 )
参数
- hidden_size (
int, 可选, 默认为1024) — 隐藏表示的维度。 - num_hidden_layers (
int, 可选, 默认为24) — Transformer 解码器中的隐藏层数量。 - num_attention_heads (
int, 可选, 默认为16) — Transformer 解码器中每个注意力层的注意力头数量。 - hidden_act (
str, 可选, 默认为gelu) — 解码器中的非线性激活函数(函数或字符串)。例如:"gelu"、"relu"、"silu"等。 - hidden_dropout_prob (
Union[float, int], 可选, 默认为0.0) — 嵌入层、编码器和池化层中所有全连接层的丢弃概率。 - initializer_range (
float, 可选, 默认为0.02) — 用于初始化所有权重矩阵的 truncated_normal_initializer 的标准差。 - layer_norm_eps (
float, 可选, 默认为1e-06) — 层归一化层使用的 epsilon 值。 - image_size (
Union[int, list[int], tuple[int, int]], 可选, 默认为640) — 每张图像的大小(分辨率)。 - patch_size (
Union[int, list[int], tuple[int, int]], 可选, 默认为16) — 每个补丁的大小(分辨率)。 - num_channels (
int, 可选, 默认为3) — 输入通道的数量。 - mlp_ratio (
int, 可选, 默认为4) — MLP 隐藏维度与嵌入维度的比率。 - layerscale_value (
float, 可选, 默认为 1.0) — LayerScale 参数的初始值。 - drop_path_rate (
Union[float, int], 可选, 默认为0.0) — 补丁融合的路径丢失率(drop path rate)。 - num_upscale_blocks (
int, 可选, 默认为 2) — 解码器或分割头中使用的上采样块数量。 - attention_dropout (
Union[float, int], 可选, 默认为0.0) — 注意力概率的丢弃比率。 - use_swiglu_ffn (
bool, 可选, 默认为False) — 是否使用 SwiGLU 前馈神经网络。 - num_blocks (
int, 可选, 默认为 4) — 架构中的特征块或阶段数量。 - no_object_weight (
float, 可选, 默认为 0.1) — 全景/实例分割中“无对象”类别的损失权重。 - class_weight (
float, 可选, 默认为 2.0) — 分类目标的损失权重。 - mask_weight (
float, 可选, 默认为 5.0) — 掩码预测的损失权重。 - dice_weight (
float, 可选, 默认为5.0) — 全景分割损失中 Dice 损失的相对权重。 - train_num_points (
int, 可选, 默认为 12544) — 训练期间用于计算掩码损失的采样点数。 - oversample_ratio (
float, 可选, 默认为 3.0) — 用于掩码训练的点采样过采样率。 - importance_sample_ratio (
float, 可选, 默认为 0.75) — 训练期间基于重要性进行采样的点的比率。 - num_queries (
int, 可选, 默认为 200) — Transformer 中的对象查询数量。 - num_register_tokens (
int, 可选, 默认为 4) — 添加到 transformer 输入中的可学习寄存器 token 的数量。
这是用于存储 VideomtModel 配置的配置类。它根据指定的参数实例化 Videomt 模型,从而定义模型架构。使用默认值实例化配置将生成与 tue-mps/videomt-dinov2-small-ytvis2019 类似的配置。
配置对象继承自 PreTrainedConfig,可用于控制模型输出。阅读 PreTrainedConfig 的文档以获取更多信息。
VideomtPreTrainedModel
class transformers.VideomtPreTrainedModel
< 源代码 >( config: PreTrainedConfig *inputs **kwargs )
参数
- config (PreTrainedConfig) — 包含模型所有参数的模型配置类。使用配置文件进行初始化不会加载与模型相关的权重,仅加载配置。请查看 from_pretrained() 方法以加载模型权重。
该模型继承自 PreTrainedModel。请查看超类文档以了解该库为所有模型实现的通用方法(例如下载或保存、调整输入嵌入大小、剪枝头部等)。
此模型也是一个 PyTorch torch.nn.Module 子类。像普通的 PyTorch Module 一样使用它,并参考 PyTorch 文档了解一般用法和行为的所有相关信息。
定义每次调用时执行的计算。
应由所有子类覆盖。
尽管前向传播的配方需要在该函数中定义,但之后应该调用
Module实例而不是它,因为前者负责运行注册的钩子,而后者则默默地忽略它们。
VideomtForUniversalSegmentation
class transformers.VideomtForUniversalSegmentation
< 源代码 >( config: VideomtConfig )
参数
- config (VideomtConfig) — 包含模型所有参数的模型配置类。使用配置文件进行初始化不会加载与模型相关的权重,仅加载配置。请查看 from_pretrained() 方法以加载模型权重。
带有顶部预测头(head)的 Videomt 模型,用于实例/语义/全景分割。
该模型继承自 PreTrainedModel。请查看超类文档以了解该库为所有模型实现的通用方法(例如下载或保存、调整输入嵌入大小、剪枝头部等)。
此模型也是一个 PyTorch torch.nn.Module 子类。像普通的 PyTorch Module 一样使用它,并参考 PyTorch 文档了解一般用法和行为的所有相关信息。
forward
< 源代码 >( pixel_values_videos: torch.Tensor | None = None mask_labels: list[torch.Tensor] | None = None class_labels: list[torch.Tensor] | None = None patch_offsets: list[torch.Tensor] | None = None **kwargs: typing_extensions.Unpack[transformers.utils.generic.TransformersKwargs] ) → VideomtForUniversalSegmentationOutput 或 tuple(torch.FloatTensor)
参数
- pixel_values_videos (
torch.Tensor, 可选) — 形状为(batch_size, num_frames, num_channels, height, width)的视频输入。 - mask_labels (
list[torch.Tensor], 可选) — 5D 视频输入不支持此参数。 - class_labels (
list[torch.LongTensor], 可选) — 5D 视频输入不支持此参数。 - patch_offsets (
list[torch.Tensor], 可选) — 视频输入不使用此参数,仅为模块兼容性而保留。
返回
VideomtForUniversalSegmentationOutput 或 tuple(torch.FloatTensor)
VideomtForUniversalSegmentationOutput 或一个 torch.FloatTensor 元组(如果传入 return_dict=False 或当 config.return_dict=False 时),根据配置(VideomtConfig)和输入,包含各种元素。
VideomtForUniversalSegmentation 的前向传播方法,覆盖了 __call__ 特殊方法。
虽然 forward pass 的实现需要在此函数中定义,但你应该在之后调用
Module实例而不是这个,因为前者负责运行预处理和后处理步骤,而后者会静默地忽略它们。
- loss (
torch.Tensor, 可选) — 计算出的损失,当存在标签时返回。 - class_queries_logits (
torch.FloatTensor,可选,默认为None) — 形状为(batch_size, num_queries, num_labels + 1)的张量,表示每个查询(query)的候选类别。注意,之所以需要+ 1,是因为我们合并了空类别(null class)。 - masks_queries_logits (
torch.FloatTensor, 可选, 默认为None) — 形状为(batch_size, num_queries, height, width)的张量,表示每个查询的建议掩码。 - last_hidden_state (
torch.FloatTensor,形状为(batch_size, num_channels, height, width)) — 最后一层的隐藏状态(最终特征图)。 - hidden_states (
tuple(torch.FloatTensor), 可选, 当传入output_hidden_states=True或config.output_hidden_states=True时返回) — 形状为(batch_size, sequence_length, hidden_size)的torch.FloatTensor元组(一个用于嵌入层的输出 + 每个阶段的输出)。模型每一层的隐藏状态。 - attentions (
tuple(tuple(torch.FloatTensor)), 可选, 当传递output_attentions=True或config.output_attentions=True时返回) —tuple(torch.FloatTensor)元组(每层一个),形状为(batch_size, num_heads, sequence_length, sequence_length)。来自 transformer 解码器的自注意力和交叉注意力权重。