news 2026/10/24 1:15:09

Depth Anything 3 长视频流式推理实战:DA3-Streaming 分块(Chunk)流处理管线全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Depth Anything 3 长视频流式推理实战:DA3-Streaming 分块(Chunk)流处理管线全解析
  • 人工智能
  • 计算机视觉
  • 深度学习

【免费下载链接】Depth-Anything-3

Depth Anything 3

项目地址:https://gitcode.com/gh_mirrors/de/Depth-Anything-3
点击查看免费下载

导读:DA3-Streaming 是 Depth Anything 3 仓库中面向长视频序列与超大场景的流式推理管线,它通过把输入帧切分为带重叠(overlap)的 chunk 进行分段推理、跨 chunk 传递状态(Sim(3) 相对位姿与尺度),从而在紧俏的 CPU/GPU 显存预算下完成近乎实时的在线视频深度与相机轨迹估计。本文以 da3_streaming/README.md 为主线,结合 da3_streaming.py、base_config.yaml 等源码与配置,完整讲解安装部署、命令行运行、全部配置参数、输出产物解读以及底层分块与回环优化原理,读完即可在自己的视频序列上复现并调优该管线。

一、为什么需要 DA3-Streaming:长视频与超大场景的显存难题

直接对整段长视频调用 Depth Anything 3 做推理,会一次性把全部帧的深度图、置信度、内外参与中间特征同时驻留显存,序列稍长便会 OOM。DA3-Streaming 的思路非常直接:

  • 按 chunk 切分:把整段视频帧切成长度固定、相邻 chunk 之间带重叠的片段,一次只让一个 chunk 进显存;
  • 跨 chunk 传递状态:相邻 chunk 依靠重叠帧的深度点云与置信度做两两对齐,估计出相对 Sim(3)(尺度 + 旋转 + 平移)变换,再逐段累加得到全局一致轨迹;
  • 回环检测与优化:使用 SALAD 视觉地点识别描述子找出远距离相似帧,构造回环约束并用 Levenberg-Marquardt(L-M)算法在 Sim(3) 流形上全局优化,消除长序列累积漂移。

从源码结构看,该设计继承了 VGGT-Long 的分块流式思路(da3_streaming.py 顶部标注 "Adapted from VGGT-Long"),并面向 Depth Anything 3 重新组织了代码、用 GPU 技术做了加速。它本身不是完整 SLAM 系统,但提供了一套可复用的"深度 + 位姿 + 回环"在线推理骨架。

二、安装与部署

2.1 克隆仓库(含子模块)

仓库中 da3_streaming/loop_utils/salad 以子模块方式引入 SALAD 模型代码,因此克隆时必须带--recursive:

git clone --recursive https://github.com/ByteDance-Seed/Depth-Anything-3.git

若此前克隆时忘记加--recursive,可在仓库根目录补拉子模块:

cd <your_dir>/Depth-Anything-3/ git submodule update --init --recursive .

2.2 安装 Python 依赖

先安装 Depth Anything 3 的主依赖,再补装流式管线所需依赖:

pip install -r requirements.txt pip install -r da3_streaming/requirements.txt

da3_streaming/requirements.txt 中列出了流式管线特有的关键包:faiss-gpu(回环检索的向量索引)、pandas、prettytable、einops(Jacobian 计算)、safetensors(权重加载)、numba(CPU 对齐加速)、pypose(Sim(3) 流形优化)。

2.3 下载预训练权重

在da3_streaming 目录下执行(脚本中的权重路径均相对于该目录):

bash ./scripts/download_weights.sh

download_weights.sh 会下载三份权重到weights/目录:

文件内容用途
weights/model.safetensors(约 6.76 GiB)DA3NESTED-GIANT-LARGE-1.1 模型权重深度/位姿推理主模型
weights/config.json(约 3.1 KiB)上述模型的架构配置构造DepthAnything3实例
weights/dino_salad.ckpt(约 340 MiB)SALAD 视觉地点识别权重回环检测描述子提取

配置文件中三者的默认路径即./weights/...(见 base_config.yaml 的Weights段),也可自行修改指向实际位置。

2.4 系统级依赖(可选)

如果因opencv-python报出libGL.so.1缺失错误,需要安装系统图形库:

sudo apt-get install -y libgl1-mesa-glx

三、运行:从视频到结果

3.1 输入准备

管线直接消费图片序列目录。若输入是视频,先用 ffmpeg 抽帧为按序命名的 PNG:

mkdir ./extract_images ffmpeg -i your_video.mp4 -vf "fps=5,scale=640:-1" ./extract_images/frame_%06d.png

示例中fps=5表示每秒抽 5 帧、scale=640:-1保持宽高比缩放到宽 640,frame_%06d.png生成从 000001 开始的零填充序号帧名。源码中图片目录的识别逻辑见 da3_streaming.py:只匹配*.jpg与*.png,并按文件名排序后处理;目录为空会直接抛错[DIR EMPTY]。

3.2 最小启动命令

python da3_streaming.py --image_dir ./path_of_images

此时--config默认取./configs/base_config.yaml,--output_dir未指定时会自动创建./exps/<图片目录名>/<时间戳>/作为输出目录(见 da3_streaming.py),并会把所用配置 YAML 拷贝一份到输出目录,方便追溯实验参数。

3.3 完整命令行参数

python da3_streaming.py --image_dir ./path_of_images \ --config ./configs/base_config.yaml \ --output_dir ${OUTPUT_DIR}

三个参数的作用(见 da3_streaming.py):

参数必填默认值说明
--image_dir是无输入图片目录,含*.jpg/*.png帧
--config否./configs/base_config.yamlYAML 配置文件路径
--output_dir否./exps/<dir>/<时间戳>所有输出的根目录

配置加载由 config_utils.py 的load_config完成:支持inherit_from字段继承另一份配置并递归合并,即"先继承默认配置、再用场景特化配置覆盖"的模式。

四、核心配置逐项精讲

base_config.yaml 是管线的"总开关"。仓库同时提供 kitti.yaml 与 tum.yaml,两者与 base 结构一致(分别以middle/saddle_balanced作为ref_view_strategy的差异示例),可直接作为不同场景的模板。

4.1 Weights:权重路径

Weights: DA3: './weights/model.safetensors' DA3_CONFIG: './weights/config.json' SALAD: './weights/dino_salad.ckpt'
  • DA3_CONFIG是 JSON 格式的模型架构配置,被读取后以DepthAnything3(**config)构造模型,再load_state_dict加载DA3权重(da3_streaming.py);
  • SALAD供回环检测器LoopDetector使用。

4.2 Model:分块与对齐主参数

Model: chunk_size: 120 overlap: 60 loop_chunk_size: 20 # imgs of loop chunk = 2 * loop_chunk_size loop_enable: True useDBoW: False delete_temp_files: True align_lib: 'triton' # 'triton' (GPU), 'torch' (GPU), 'numba' (CPU), 'numpy' (CPU) align_method: 'sim3' # 'sim3', 'se3', 'scale+se3' scale_compute_method: 'auto' # 'auto', 'ransac', 'weighted';仅 align_method == 'scale+se3' 时使用 align_type: 'dense' # 'dense' 或 'sparse'(sparse 仍在构建中) ref_view_strategy: 'saddle_balanced' # 'middle', 'saddle_balanced', 'first', 'saddle_sim_range' ref_view_strategy_loop: 'saddle_balanced' depth_threshold: 15.0 save_depth_conf_result: True save_debug_info: False Sparse_Align: keypoint_select: 'orb' # 'orb', 'fast', 'disk' keypoint_num: 5000 IRLS: delta: 0.1 max_iters: 5 tol: 1e-9 Pointcloud_Save: sample_ratio: 0.015 conf_threshold_coef: 0.75 # conf_threshold = np.mean(confs) * conf_threshold_coef

逐项解读:

  • chunk_size/overlap:每个 chunk 推理的帧数,以及相邻 chunk 共享的重叠帧数。重叠帧是跨 chunk 对齐的"公共锚点",既用于估计相对 Sim(3),也用于剔除重叠区以拼接无重复轨迹。必须满足overlap < chunk_size,否则 process_long_sequence 直接抛[SETTING ERROR]。分块索引的计算逻辑见 get_chunk_indices:步长为chunk_size - overlap,末尾不足一块时截断。
  • loop_chunk_size:回环候选帧对处理时使用的局部窗口大小,注释明确"回环 chunk 的图片数 = 2 × loop_chunk_size",即取回环两侧各loop_chunk_size/2帧组成联合 chunk 重新推理(见 process_long_sequence 的half_window)。
  • loop_enable:是否启用回环检测 + Sim(3) 全局优化。开启时会在__init__中加载LoopDetector(da3_streaming.py),并把回环对写入${OUTPUT_DIR}/loop_closures.txt。
  • align_lib:两 chunk 点云对齐时 Sim(3) 估计的后端实现,可选triton/torch(GPU)或numba/numpy(CPU)。若选numba,主程序在启动前会先warmup_numba()预热 JIT(da3_streaming.py)。
  • align_method:对齐变换类型。sim3直接估计尺度+旋转+平移;se3不考虑尺度;scale+se3先用深度信息预计算尺度因子再解 SE(3),此时scale_compute_method决定尺度来源(auto/ransac/weighted),实现位于 sim3utils.py 的precompute_scale_chunks_with_depth。
  • align_type:dense为稠密点云对齐;注释提示sparse(稀疏)对齐仍在构建中,暂不可用。
  • ref_view_strategy/ref_view_strategy_loop:Depth Anything 3 推理时参考视图的选择策略,可选middle(取中间帧)、saddle_balanced(鞍点平衡采样)、first、saddle_sim_range。该参数在 process_single_chunk 中按"普通 chunk / 回环 chunk"分别取值并透传给model.inference,相关策略细节可参考 docs/funcs/ref_view_strategy.md。
  • depth_threshold:深度截断阈值(米),用于过滤异常深度点。
  • save_depth_conf_result:为 True 时逐帧保存 rgb/depth/conf/intrinsic 到results_output/(见下文输出章节)。
  • save_debug_info:为 True 时在保存的 npz 中额外附带extrinsics与对齐的s/R/T(见 save_depth_conf_result)。
  • Sparse_Align:稀疏对齐的候选关键点配置(orb/fast/disk与数量),配合尚未可用的 sparse 对齐使用。
  • IRLS:迭代重加权最小二乘的停止条件(delta、max_iters、tol)。
  • Pointcloud_Save:点云落盘策略。sample_ratio为下采样比例(默认 0.015);conf_threshold_coef用于计算置信度阈值,公式固定为conf_threshold = np.mean(confs) * conf_threshold_coef(见 da3_streaming.py),低于阈值的低置信度点会被剔除。

4.3 Loop:回环检测与优化参数

Loop: SALAD: image_size: [336, 336] batch_size: 32 similarity_threshold: 0.85 top_k: 5 use_nms: True nms_threshold: 25 SIM3_Optimizer: lang_version: 'cpp' # 'cpp' 或 'python';未安装 C++ 版时自动降级为 'python' max_iterations: 30 lambda_init: 1e-6
  • SALAD.image_size:SALAD 描述子提取时的输入分辨率(高×宽)。从 loop_detector.py 可见,图像先 resize 到该尺寸、再按 ImageNet 的 MEAN/STD 归一化。
  • SALAD.batch_size:描述子提取的批大小,按批做torch.autocast半精度前向(loop_detector.py)。
  • SALAD.similarity_threshold:判定回环的余弦相似度下限;top_k:每帧取相似度最高的前 K 个近邻(faiss 检索时取top_k + 1以跳过与自身最相似的帧,见 loop_detector.py);且要求帧间距abs(i - neighbor_idx) > 10才视为回环。
  • SALAD.use_nms/nms_threshold:对候选回环对做非极大值抑制,抑制窗口为nms_threshold帧,避免同一区域产生大量冗余回环(实现见 loop_detector.py)。
  • SIM3_Optimizer.lang_version:L-M 线性方程组求解器用 C++(sim3solve,在 fastloop 目录编译)还是 Python(solve_python.py)。C++ 版本导入失败时自动回退 Python(见 sim3loop.py)。
  • SIM3_Optimizer.max_iterations/lambda_init:L-M 最大迭代次数与阻尼初值。lambda_init在 optimize 中通过eval解析(支持如1e-6的字面量)。优化在pypose的 Sim(3) 流形上进行,收敛判定为成本低于1e-5且最近 5 次迭代改善比 < 1.5(sim3loop.py)。

五、输出产物解读

5.1 基础输出(始终生成)

运行结束后,${OUTPUT_DIR}下包含:

  • camera_poses.txt:逐行记录每帧相机外参。行内容为4×4 相机到世界(C2W)矩阵展平后的 16 个数(每行 16 个浮点数),由 save_camera_poses 生成——先把 chunk 内的 w2c 外参求逆为 c2w,再左乘累积 Sim(3) 变换S并对旋转部分除以尺度s做归一化。
  • intrinsic.txt:逐行记录每帧内参的fx fy cx cy四个数。
  • pcd/combined_pcd.ply:合并所有帧点云后的总点云文件,由merge_ply_files把各 chunk 的pcd/<chunk>_pcd.ply合并而成(da3_streaming.py)。

另有两个可视化/记录副产品:

  • camera_poses.ply:以不同颜色区分 chunk 的相机轨迹点云可视化(颜色循环见 save_camera_poses);
  • sim3_opt_result.png:回环优化前后的轨迹对比图("Before Optimization / After Optimization" 以及回环连线,见 plot_loop_closure);
  • loop_closures.txt:回环对列表(index1, index2, similarity)及 NMS 参数、图像路径索引(在启用loop_enable时生成)。

5.2 附加输出:逐帧深度与置信度

当配置中save_depth_conf_result: True时,额外生成results_output/目录,内含每帧一个frame_<全局帧号>.npz,字段包括:

键形状/类型说明
image[H, W, 3]uint8处理后 RGB 帧
depth[H, W]float32单目深度(经对齐尺度修正)
conf[H, W]float32置信度,最小值固定为 0(源码中对预测置信度做了conf -= 1.0平移,见 process_single_chunk)
intrinsics[3, 3]float32帧内参
extrinsics、s、R、T附加字段仅当save_debug_info: True时写入

需要说明的是,重叠区帧只会在首个覆盖它的 chunk 中保存一次,避免轨迹重复(保存区间裁剪逻辑见 save_depth_conf_result)。

5.3 用 npz 重新融合点云以验证结果

results_output与camera_poses.txt已足够离线重建整段点云,验证用命令:

python npz_output_process.py \ --npz_folder ${OUTPUT_DIR}/results_output \ --pose_file ${OUTPUT_DIR}/camera_poses.txt \ --output_file ${OUTPUT_DIR}/output.ply

npz_output_process.py 会把 npz 中的深度按保存的内参与 c2w 位姿反投影为世界点云,再用conf_threshold_coef(默认 0.5)与sample_ratio(默认 0.015)过滤、下采样后写出output.ply。若--npz_folder与--pose_file路径不存在,脚本会给出明确错误提示。

5.4 磁盘空间注意事项

管线处理过程中会在输出目录下生成三个中间目录_tmp_results_unaligned、_tmp_results_aligned、_tmp_results_loop以及各 chunk 的pcd文件,占用很大:

  • 约50 GiB(KITTI 00,4500 帧);
  • 约35 GiB(KITTI 05,2700 帧);
  • 约5 GiB(300 帧短序列)。

因此运行前务必确认磁盘余量充足。当delete_temp_files: True(默认)时,close 会在结束时删除这三类临时文件并打印回收空间大小;若想保留中间结果排查问题,可把该配置改为False。

六、源码视角:流式管线的工作原理

6.1 推理精度与内存策略

模型在__init__阶段完成加载,并以bfloat16(计算能力 ≥ 8 的 GPU)或float16精度做autocast推理(da3_streaming.py)。每个 chunk 推理后:

  • 预测结果立即np.save落盘,只保留上一 chunk 用于对齐,从而把显存占用压到"一个 chunk + 一个重叠窗"的量级;
  • 每次推理前后都调用torch.cuda.empty_cache()释放碎片显存(process_single_chunk)。

6.2 两两 chunk 对齐:Sim(3) 估计

相邻 chunk 的对齐在 process_long_sequence 中完成:

  1. 取前一 chunk 末尾overlap帧与后一 chunk 开头overlap帧,分别反投影为世界点云;
  2. 用置信度掩码筛选可靠对应点(conf > min(median(conf1), median(conf2)) * 0.1,见 align_2pcds);
  3. 调用weighted_align_point_maps(sim3utils.py)估计(s, R, t),其中稠密对齐默认走 triton 实现robust_weighted_estimate_sim3_triton(alignment_triton.py),并有对应的 torch 版robust_weighted_estimate_sim3_torch(alignment_torch.py)。

6.3 回环检测与全局优化

  1. 检测:LoopDetector 用 SALAD(DINOv2 ViT-B/14 backbone + SALAD 聚合器)为每帧提取 768 维描述子,写入 faissIndexFlatIP做内积检索,按similarity_threshold、top_k、NMS 过滤得到回环对;
  2. 约束构建:每个回环对会触发一次process_single_chunk(..., is_loop=True),把两侧窗口帧拼成一个联合 chunk 重新推理,再分别与两侧原始 chunk 对齐,合成回环相对变换S_ab(get_loop_sim3_from_loop_predict);
  3. 优化:Sim3LoopOptimizer.optimize 以顺序相邻变换为约束、回环对为附加约束,用 L-M 在 Sim(3) 流形上迭代求解(求解器分 C++/Python 两个版本),输出优化后的相对变换序列;
  4. 应用:优化结果经accumulate_sim3_transforms(sim3utils.py)累加为"从第 0 chunk 到各 chunk"的累积变换,再对后续各 chunk 的点云、深度与相机轨迹逐块施加变换(da3_streaming.py)。

sim3loop.py 还内置了"旋转环"测试代码(create_ring_transforms+example_usage),可单独运行观察 L-M 优化收敛与轨迹修正效果,是理解优化器行为的便捷入口。

七、实验结果:精度、速度与显存

README 提供了三组自评实验(均在启用回环、相似度阈值 0.85、分辨率约 500px 宽度、overlap 为 chunk 一半的条件下测得),整理如下。

7.1 KITTI Odometry 的 ATE RMSE(米)

方法chunk sizeAVGAVG(不含 01)0001020304050607080910
帧数—21092210454211014661801271276111011101407115911201
VGGT-Long12025.6022.8116.1353.4351.984.372.1512.6911.333.6070.2934.5521.05
Pi-Long12021.1711.815.55114.8350.291.631.113.482.883.9224.257.3817.61
DA3-Streaming12018.6310.424.48100.7733.413.582.393.957.592.0931.208.067.44
VGGT-Long6026.3619.308.0696.9634.166.834.169.154.682.6863.1532.2427.87
Pi-Long6030.6317.107.82165.9273.593.670.915.163.893.5733.9717.0121.41
DA3-Streaming6016.8310.645.1378.7635.645.383.183.042.832.3226.558.8613.42

在 chunk=120 时,DA3-Streaming 的 AVG(不含序列 01)取得三者中最低的 10.42 m;chunk=60 时 AVG 进一步降到 16.83 m(原文标注为三者最优)。

7.2 推理速度(NVIDIA A100,KITTI 00/05/08 共 11373 帧)

方法总耗时FPS
VGGT-Long65 min 08 sec2.91
Pi-Long60 min 09 sec3.15
DA3-Streaming22 min 17 sec8.51

测试排除了 warm-up、模型加载与 ply 保存耗时;若进一步启用 Keyframe 策略,README 声称可接近 10 FPS(该数字为项目自报,未在本仓库内提供可复现脚本)。

7.3 TUM RGB-D 对比(chunk=120,overlap=60,含回环)

方法AVG360deskdesk2floorplantroomrpyteddyxyz
Droid-SLAM(未标定)0.1630.2020.0320.0910.0640.0450.9180.0560.0450.012
Mast3r-SLAM(未标定)0.0600.0700.0350.0550.0560.0350.1180.0410.1140.020
VGGT-Long0.1100.1180.0580.1110.1180.0710.1550.1400.1200.099
Pi-Long0.0940.1150.0470.0520.1600.0850.1140.1430.0810.052
DA3-Streaming0.0870.0590.0340.0420.1070.0600.1050.2060.1260.044

DA3-Streaming 的 AVG 0.087 优于 Droid-SLAM 未标定版与两条长视频基线,虽低于 Mast3r-SLAM 未标定版,但已具备一定精度参考价值——README 也明确提示:当前管线并非 SLAM 系统,此表仅用于横向参照。

7.4 chunk 大小:显存与精度的权衡

数据集(分辨率)指标chunk=120chunk=90chunk=60chunk=30
KITTI(504×154)Peak VRAM [GB]15.914.312.711.5
ATE RMSE [m]10.429.3810.6419.39
TUM RGB-D(504×378)Peak VRAM [GB]28.325.121.218.7
ATE RMSE [m]0.0870.0910.1270.227

可以观察到:chunk 越小,峰值显存越低(KITTI 从 15.9 GB 降到 11.5 GB,TUM 从 28.3 GB 降到 18.7 GB),但轨迹精度通常随之下降(chunk=30 时 ATE 明显恶化);chunk=90 在两组数据上是显存与精度的折中甜点。这正是"用重叠分块换显存、用足够大的 chunk 保精度"这一设计哲学的直接体现。

八、实战调优建议与延伸阅读

结合配置与实验数据,针对自己的序列可参考以下调优路线:

  1. 先定分辨率与 chunk:显存紧张时优先调小image_size相关输入或chunk_size;追求精度且显存足够时用 90~120。
  2. 控制重叠:保持overlap为 chunk 一半左右,既保证对齐有足够公共点,又不至于让有效新帧过少。
  3. 回环开关:长序列、绕行场景务必保持loop_enable: True;短直行序列可关闭以省去 SALAD 推理开销。
  4. 后端选择:有 GPU 时用align_lib: triton(或torch),纯 CPU 环境用numba/numpy,并在lang_version上优先安装 C++ 求解器(见 fastloop/solve.cpp)。
  5. 点云质量控制:通过Pointcloud_Save.conf_threshold_coef(默认 0.75)与sample_ratio(默认 0.015)平衡点云密度与噪点。
  6. 注意磁盘:处理前确认临时中间文件所需的数十 GiB 空间,默认会在结束自动清理。

相关资源:参考视图选择策略见 docs/funcs/ref_view_strategy.md;主模型 API 与整体用法见 README.md 与 docs/API.md。DA3-Streaming 基于 VGGT-Long 与 Depth Anything 3 构建,感谢两个上游项目的工作。

  • 人工智能
  • 计算机视觉
  • 深度学习

【免费下载链接】Depth-Anything-3

Depth Anything 3

项目地址:https://gitcode.com/gh_mirrors/de/Depth-Anything-3
点击查看免费下载

相关推荐

上一篇:profile-summary-for-github代码审查:质量保证与最佳实践传播
下一篇:2025最新Vulhub使用教程:从安装到漏洞演示全流程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 13:53:16

多Agent协同编程:Git Worktree隔离与状态看板编排实践

1. 项目概述&#xff1a;当多个AI程序员开始“坐同一张工位”时&#xff0c;我们到底在解决什么问题&#xff1f;你有没有试过让两个AI助手同时修改同一个代码文件&#xff1f;一个在修登录页的按钮样式&#xff0c;另一个在重写用户权限校验逻辑——结果是Git冲突满天飞&#…

作者头像 李华
网站建设 2026/10/16 5:12:04

Claude API上下文管理实战:构建外置记忆层与滚动摘要系统

不止一个接入了Claude API的朋友问过我&#xff1a;明明每次请求都是按文档发的&#xff0c;为什么机器人聊多了还是像失忆一样&#xff1f;我一般直接甩一个项目链接过去&#xff0c;里面是一个叫claude-mem的小工具。它的全部工作就一句话&#xff1a;给无状态的对话接口套一…

作者头像 李华
网站建设 2026/10/16 11:57:08

让OmniBot自动干活:定时任务与Subagent后台执行完整玩法

让OmniBot自动干活&#xff1a;定时任务与Subagent后台执行完整玩法 【免费下载链接】OmniBot Your on-phone / mobile AI Agent / Claw, capable of operating terminals and performing a wide range of tasks in the Android world || 你的手机 AI 代理&#xff0c;她可以操…

作者头像 李华