ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

在 MLX 上使用 Video Depth Anything 进行视频深度估计:架构、推理与源码解析

在 MLX 上使用 Video Depth Anything 进行视频深度估计:架构、推理与源码解析 在 MLX 上使用 Video Depth Anything 进行视频深度估计架构、推理与源码解析【免费下载链接】mlx-vlmMLX-VLM is a package for inference and fine-tuning of Vision Language Models (VLMs) on your Mac using MLX.项目地址: https://gitcode.com/GitHub_Trending/ml/mlx-vlm本指南以mlx-vlm仓库中的 video_depth_anything 模型文档 为核心系统讲解如何在 Apple Silicon Mac 上通过 MLX 运行 ByteDance 提出的 Video Depth Anything 模型CVPR 2025 highlight完成对任意长度视频的时序一致的单目深度估计。读完本文你将掌握该模型的整体架构DINOv2 骨干 DPT 时序头、官方支持的六种检查点与加载方式、两种推理路径参考滑窗流水线与单片段直调、输入预处理约束以及配套的精度验证与单元测试。模型是什么输出深度图而非文本的非典型 VLMVideo Depth Anything 是 Depth Anything 团队 发布的视频单目深度估计模型其核心目标是解决单帧深度估计在视频上逐帧独立推理时出现的时间闪烁与不一致问题为任意长度的视频生成时序连贯的深度序列。与 mlx-vlm 中绝大多数模型不同该模型不产出任何文本——它的输出是逐帧的深度图。在mlx-vlm的实现中这一点在 模型主文件 里被明确标注Model接收通道在最后的视频帧张量(B, T, H, W, 3)返回形状为(B, T, H, W)的深度图数值为相对relative或公制metric当config.metric为真时的类视差disparity-like值。整体架构由三部分构成DINOv2 骨干网络提供 vits / vitb / vitl 三种规模的特征提取器DPT 头Dense Prediction Transformer head将多尺度特征融合为稠密深度AnimateDiff 风格的时序运动模块temporal motion modules沿时间轴做自注意力把时序一致性注入特征融合过程。其中Model类直接复用了仓库中独立的 DINOv2 实现并通过self.pretrained.get_intermediate_layers取指定中间层特征再交给DPTHeadTemporal处理见 video_depth_anything.py。支持的检查点与加载方式MLX 移植版官方支持以下六种检查点对应原版 PyTorch 仓库的六个版本来源与 MLX 仓库一一对应| 变体 | MLX 仓库 | 原始来源 | |:-|:-|:-| | Small |mlx-community/Video-Depth-Anything-Small-MLX|depth-anything/Video-Depth-Anything-Small| | Base |mlx-community/Video-Depth-Anything-Base-MLX|depth-anything/Video-Depth-Anything-Base| | Large |mlx-community/Video-Depth-Anything-Large-MLX|depth-anything/Video-Depth-Anything-Large| | Small metric |mlx-community/Metric-Video-Depth-Anything-Small-MLX|depth-anything/Metric-Video-Depth-Anything-Small| | Base metric |mlx-community/Metric-Video-Depth-Anything-Base-MLX|depth-anything/Metric-Video-Depth-Anything-Base| | Large metric |mlx-community/Metric-Video-Depth-Anything-Large-MLX|depth-anything/Metric-Video-Depth-Anything-Large|三种规模 Small / Base / Large 分别对应vits/vitb/vitl编码器带metric字样的版本输出绝对尺度的深度公制深度推理时不做窗口间的尺度/偏移对齐。加载时无需任何转换步骤——权重由加载器直接从 Hugging Face Hub 下载。标准的加载入口是mlx_vlm.loadfrom mlx_vlm import load model, processor load(mlx-community/Video-Depth-Anything-Small-MLX)加载后返回的processor实际是 VideoDepthProcessor它通过preprocessor_config.json自动读取input_size与ensure_multiple_of参数__init__.py中的install_auto_processor_patch调用则确保框架能够自动为该模型类型装配正确的处理器。快速上手滑窗推理流水线官方推荐的推理路径是使用VideoDepthPredictor它完整移植了参考实现infer_video_depth的循环逻辑重叠的 32 帧滑窗、关键帧条件注入、窗口间的尺度/偏移对齐metric 模型跳过对齐。对于任意长度的视频这是保证全局时序一致性的推荐做法。from mlx_vlm import load from mlx_vlm.models.video_depth_anything.generate import ( VideoDepthPredictor, read_video_frames, ) model, processor load(mlx-community/Video-Depth-Anything-Small-MLX) predictor VideoDepthPredictor(model, processor) frames, fps read_video_frames(input.mp4, max_len300, target_fps15) depths predictor.infer(frames) # (T, H, W) float32, input resolution其中read_video_frames(video_path, max_len-1, target_fps-1)依赖 OpenCVcv2读取视频当target_fps 0且原视频帧率更高时按round(original_fps / target_fps)的步长抽帧max_len限制读取的最大帧数返回(T, H, W, 3)的 uint8 RGB 帧数组与降采样后的实际帧率见 generate.py。predictor.infer(frames, progressTrue)接受(T, H, W, 3)uint8 RGB 输入返回(T, H, W)的 float32 深度图分辨率与输入视频一致progressTrue时用 tqdm 显示进度条。直接调用模型处理单个短视频片段如果只是处理一个不超过 32 帧的短视频片段可以跳过滑窗对齐逻辑直接调用模型本身import numpy as np frames ... # (T, H, W, 3) uint8 RGB pixel_values processor(frames)[pixel_values] # (T, H, W, 3) normalized depth model.predict_depth(pixel_values) # (T, H, W)processor的__call__会依次对每帧执行preprocess_frame缩放到 14 的倍数双三次插值并做 ImageNet 归一化mean[0.485, 0.456, 0.406]std[0.229, 0.224, 0.225]见 processing_video_depth_anything.py。model.predict_depth是Model.__call__的单片段便捷封装内部将(T, H, W, 3)补成 batch 维为 1 的(1, T, H, W, 3)前向计算后取回(T, H, W)的深度图见 video_depth_anything.py。前向过程会执行双线性上采样回输入分辨率并施加 ReLU 非线性确保输出非负。底层原理从配置到前向的一次完整追溯配置预设三种编码器如何决定模型规模config.py 中定义了ENCODER_PRESETS在共享 DINOv2 维度之上为每种编码器指定 DPT 头的宽度与通道数| 编码器 | 特征宽度 (features) | 各层输出通道 (out_channels) | 中间层索引 (intermediate_layer_idx) | |:-|:-|:-|:-| |vits| 64 |[48, 96, 192, 384]|[2, 5, 8, 11]| |vitb| 128 |[96, 192, 384, 768]|[2, 5, 8, 11]| |vitl| 256 |[256, 512, 1024, 1024]|[4, 11, 17, 23]|ModelConfig的__post_init__会在构造时根据encoder自动回填所有为None的骨干参数例如默认vitl会得到embed_dim1024、depth24。这在 单元测试 test_config_presets 中得到验证。时序模块相关的可配置项包括num_frames32位置表的时间长度、peape位置编码类型当前仅支持绝对正弦位置编码、num_attention_heads8、num_transformer_block1、num_attention_blocks2、norm_num_groups32。此外ModelConfig还通过TextConfig VisionConfig ModelConfig别名保持与 mlx-vlm 框架的update_module_configs兼容见 config.py。时序运动模块沿时间轴的注意力时序模块 是 AnimateDiff 风格的TemporalModule核心组件TemporalTransformer3DModel的输入是通道在最后的(B, T, H, W, C)张量。其内部流程为重塑为(B*T, H, W, C)后做 GroupNorm 归一化将空间维度展平并通过proj_in投影到注意力维度经过若干TemporalTransformerBlock——每个 block 内部包含多个TemporalAttention沿时间轴 T 做自注意力配合 LayerNorm 残差与一个 GEGLU 前馈网络proj_out投影回原通道数并与残差相加。TemporalAttention采用绝对正弦位置编码sinusoidal_table生成的位置表在 QKV 投影之前加到输入上注意力通过mx.fast.scaled_dot_product_attention计算见 motion.py。测试 test_temporal_module_zero_proj_is_identity 验证了一个有趣的属性当proj_out权重为零时时序模块退化为恒等映射。DPT 头多尺度特征融合DPTHeadTemporal 从 DINOv2 的四个中间层取出特征依次经过 1×1 投影、resize_layers两个ConvTranspose2d上采样 一个Identity 一个步长 2 的Conv2d再送入Scratch融合模块。融合过程中motion(0)与motion(1)分别在 layer_3、layer_4 路径上做时序建模motion(2)与motion(3)作用于 refinenet 路径——这正是时序一致性被注入多尺度空间特征的关键位置。输出头在**全精度float32**下运行与参考实现一致并支持micro_batch_size4的分块执行以控制峰值内存。滑窗推理的对齐细节VideoDepthPredictor.infer完整复刻参考实现的关键超参见 generate.py| 常量 | 值 | 含义 | |:-|:-|:-| |INFER_LEN| 32 | 每个滑窗的帧数 | |OVERLAP| 10 | 相邻窗口的重叠帧数 | |KEYFRAMES|[0, 12, 24, 25, 26, 27, 28, 29, 30, 31]| 关键帧索引用于窗口间条件注入与对齐 | |INTERP_LEN| 8 | 重叠区线性插值帧数 |推理流程为按frame_step INFER_LEN - OVERLAP 22滑动对于非首个窗口用前一窗口的关键帧pre_input[:, KEYFRAMES]拼接当前窗口的后续帧作为模型输入关键帧条件注入每个窗口的深度图被双线性上采样回原始分辨率。全部窗口推理完后通过最小二乘compute_scale_and_shift计算相邻窗口在共享关键帧上的尺度/偏移先对重叠区做插值混合get_interpolate_frames线性混合再对后续帧施加同一组尺度/偏移并裁剪到非负metric 模型使用恒等变换scale1, shift0。最后np.stack(depth_list_aligned[:org_video_len])截断掉为凑齐窗口数而追加的尾部帧见 generate.py。输入约束与数值精度说明使用该模型时必须注意以下几点原文档 Notes 部分的完整内容张量布局输入为通道在最后的(B, T, H, W, 3)即每个维度分别是 batch、时间帧数、高、宽、通道尺寸约束H 和 W 必须是 14 的倍数对应patch_size 14。VideoDepthProcessor的target_size方法会保持宽高比并将尺寸吸附到 14 的倍数当视频长宽比大于 1.78约 16:9时会按input_size * 1.777 / ratio缩小输入尺寸以节省显存见 processing_video_depth_anything.py数值精度在默认的 GPU 设备上输出与 PyTorch 参考实现相对误差约 1%源于 Metal fast-math 矩阵乘法在 CPU 上mx.set_default_device(mx.cpu)包括滑窗流水线在内的完整推理相对误差约 1e-5未移植功能参考实现中的流式推理模式video_depth_stream.py不在本移植范围内。源码级验证单元测试与形状契约仓库在 test_models.py 中为 Video Depth Anything 提供了完整的TestVideoDepthAnything测试套件可帮助理解实现契约test_vision_backbone验证 DINOv2 骨干按请求的层索引返回 patch/cls token且形状正确test_model_forward_shapes验证完整模型将(1, 4, H, W, 3)映射为(1, 4, H, W)深度图且输出非负test_sanitize_conv_layouts验证Model.sanitize将 PyTorch 权重的(out, in, kh, kw)布局正确转置为 MLX 的通道在最后布局ConvTranspose2d 例外地转置为(out, kh, kw, in)见 video_depth_anything.pytest_processor_target_size验证处理器保持宽高比、输出为 14 的倍数且最短边不小于 294即 518 的 14 倍数下限。小结与延伸阅读Video Depth Anything 的 MLX 移植版将视频深度估计这一视觉任务完整地引入了 Apple Silicon 生态无需转换即可从 Hub 加载权重滑窗推理在 GPU 上与原版约 1% 相对误差、CPU 上约 1e-5 相对误差且输出非负深度图。其实现复用了仓库中独立的 DINOv2 骨干而时序一致性则由 motion.py 中的 AnimateDiff 风格时序模块提供。想进一步了解本仓库如何组织模型实现可参考 models 目录 的通用约定模型类 config processing generate 的模块划分对 DINOv2 骨干细节感兴趣的读者可阅读 dinov2 模型文档。若需要将深度图用于下游任务如 3D 重建、避障、视频编辑可基于本文的VideoDepthPredictor.infer输出进行后处理——深度图分辨率与输入视频一致可直接逐帧映射。【免费下载链接】mlx-vlmMLX-VLM is a package for inference and fine-tuning of Vision Language Models (VLMs) on your Mac using MLX.项目地址: https://gitcode.com/GitHub_Trending/ml/mlx-vlm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表