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

发布时间:2026/9/17 21:00:37

在 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),仅供参考
延伸阅读

更多相关文章

2026/9/17 21:00:37

使用IronPython实现ASP.NET应用实时监控与诊断

1. 项目背景与核心价值在ASP.NET应用程序的运维和开发过程中,实时监控程序运行状态是个永恒的话题。传统做法往往需要重新编译部署监控代码,或者依赖第三方监控工具。而IronPython作为.NET平台上的动态语言,为我们提供了一种轻量级、无需编译…

2026/9/17 21:00:37

用Multisim仿真设计5W音频功放:从电路搭建到演示视频全流程

1. 为什么先用Multisim把音频功放跑通我在电子爱好者的群里看了太多次类似的求助了:照着网上的音频功率放大器原理图画PCB,结果焊好一上电,要么没声音,要么管子烫得能煎鸡蛋。Multisim这个软件在国内电子类专业几乎人手一份&#…

2026/9/17 20:55:36

Ice 快速上手:5 分钟整理 macOS 拥挤菜单栏,刘海也能救

Ice 快速上手:5 分钟整理 macOS 拥挤菜单栏,刘海也能救 【免费下载链接】Ice Powerful menu bar manager for macOS 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice Ice 是一款免费的 macOS 菜单栏管理开源工具,专治菜单栏图…

2026/9/17 21:50:50

SonarQube代码质量平台落地实践:从部署到CI流水线集成

接手这类“项目简介”性质的分享,其实是最考验功力的。光看“SOF”三个字母,很多人可能会觉得陌生,但你只要在代码质量治理这个圈子混过,立刻就明白了——这就是团队内部的一次静态代码扫描平台落地专项。我当时的项目代号就叫SOF…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码