ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

如何在 ComfyUI ControlNet Aux 中用好 Depth Anything V2:深度估计预处理器的完整实现指南

2026/8/18 21:01:47 拓冰建站 浏览量
如何在 ComfyUI ControlNet Aux 中用好 Depth Anything V2:深度估计预处理器的完整实现指南 如何在 ComfyUI ControlNet Aux 中用好 Depth Anything V2深度估计预处理器的完整实现指南【免费下载链接】comfyui_controlnet_auxComfyUIs ControlNet Auxiliary Preprocessors项目地址: https://gitcode.com/gh_mirrors/co/comfyui_controlnet_aux一个差点劝退我的深夜调参现场你大概率也遇到过这个场景ComfyUI 里拖进一张照片接上 ControlNet想用深度图锁住画面构图结果生成的图要么前景糊成一片、要么背景完全穿帮。折腾半天问题往往不在 ControlNet 本身而在预处理阶段就埋下了隐患——深度图里花朵和背景混成一个灰块ControlNet 拿什么去理解远近关系这类问题的根源通常是预处理器选型或参数配置不当。在 ComfyUI ControlNet AuxComfyUI 的 ControlNet 辅助预处理器工具集里Depth Anything V2是当前性价比最高的一把深度钥匙它把单目深度估计Monocular Depth Estimation即用一张 RGB 图直接推断每个像素离相机多远的技术做到了开箱即用的水平。本文不打算复述 README而是带你从节点源码出发把它的加载流程、推理链路、参数语义和工程化姿势一次讲透。Depth Anything V2 在生态中的位置ComfyUI ControlNet Aux 的预处理器主要分几大家族线条类Canny、Lineart、Scribble、姿态类OpenPose、DWPose、语义类OneFormer、Segment Anything以及深度/法线类。深度家族里同时住着 Midas、Zoe、LeReS、Metric3D、Depth Anything 一代和 V2 等成员各自的侧重点差异很大预处理器特点典型用途Midas老牌稳健速度尚可通用场景深度引导Zoe深度法线双输出需要法线信息的场景LeReS相对深度边缘清晰强调几何轮廓的构图Depth Anything V1泛化能力强依赖 transformers 管线通用深度适配广Depth Anything V2精度/速度平衡最佳ViT 骨干本文主角V2 相比 V1 最直观的差异藏在实现方式上V1 在src/custom_controlnet_aux/depth_anything/transformers.py里走的是 HuggingFacepipeline(taskdepth-estimation)封装而 V2 在src/custom_controlnet_aux/depth_anything_v2/下自己实现了 DINOv2 骨干 DPT 解码头不依赖 transformers 的模型装配加载路径更可控、推理更轻快。上图是 Depth Anything V2 预处理器在 ComfyUI 中的典型接法Load Image → Depth Anything V2 - Relative → Preview Image右端输出黑白灰的深度图白色代表近景如花朵灰黑渐变代表纵深。最小可运行示例十分钟跑通第一张深度图第一步安装如果你还没有把插件放进 ComfyUI先克隆项目仓库到 ComfyUI 的custom_nodes目录git clone https://gitcode.com/gh_mirrors/co/comfyui_controlnet_aux然后在项目根目录安装依赖建议使用与 ComfyUI 相同的 Python 虚拟环境cd comfyui_controlnet_aux pip install -r requirements.txt重启 ComfyUI 后在添加节点面板里搜索Depth Anything V2就能看到Depth Anything V2 - Relative节点它位于ControlNet Preprocessors/Normal and Depth Estimators分类下。第二步搭最小工作流Load Image加载一张有明确前后景的照片人像、静物、街景都行。接Depth Anything V2 - Relative。接Preview Image直接查看深度图。再接ControlNet到你的生成主链路。第三步不依赖 UI 的命令行验证如果你更喜欢脚本验证src/custom_controlnet_aux/depth_anything_v2/__init__.py里的DepthAnythingV2Detector可以直接在 Python 里调用import cv2 import numpy as np from PIL import Image from custom_controlnet_aux.depth_anything_v2 import DepthAnythingV2Detector # 1. 加载模型filename 决定从哪个 HuggingFace 仓库拉权重 detector DepthAnythingV2Detector.from_pretrained(filenamedepth_anything_v2_vitl.pth) # 2. 读取图像numpy HWC 格式 img np.array(Image.open(photo.jpg).convert(RGB)) # 3. 推理detect_resolution 是输出深度图的目标边长512 起步 depth detector(img, detect_resolution512, output_typenp) # 4. 保存结果 Image.fromarray(depth).save(depth_output.png) print(深度图输出形状:, depth.shape)第一次运行会自动从 HuggingFace 下载权重到本地缓存VitL 权重约 300MB耐心等一两分钟即可。看到黑白灰的深度图你的最小闭环就通了。原理分层拆解从一次调用到一张深度图理解 V2 的关键在于把node_wrappers/depth_anything_v2.py的execute方法当作一条流水线的总入口逐层往下钻。第一层节点壳执行入口node_wrappers/depth_anything_v2.py第 20 行开始是节点核心逻辑def execute(self, image, ckpt_namedepth_anything_v2_vitl.pth, resolution512, **kwargs): from custom_controlnet_aux.depth_anything_v2 import DepthAnythingV2Detector model DepthAnythingV2Detector.from_pretrained(filenameckpt_name).to(model_management.get_torch_device()) out common_annotator_call(model, image, resolutionresolution, max_depth1) del model return (out, )三个关键动作from_pretrained(filenameckpt_name)按节点下拉框选中的权重文件名去拉模型.to(model_management.get_torch_device())把模型搬上 ComfyUI 自动选择的设备CUDA / MPS / CPUcommon_annotator_call(...)utils.py中的通用批处理函数内部把 ComfyUI 的张量图像逐张转成numpy uint8再调用检测器最后归一化回[0,1]张量同时带进度条。注意这里传入了max_depth1意味着相对深度版本输出的深度值被缩放到了 1 的范围内。第二层模型装配与权重解析src/custom_controlnet_aux/depth_anything_v2/__init__.py里维护了一张模型配置表model_configs { depth_anything_v2_vits.pth: {encoder: vits, features: 64, out_channels: [48, 96, 192, 384]}, depth_anything_v2_vitb.pth: {encoder: vitb, features: 128, out_channels: [96, 192, 384, 768]}, depth_anything_v2_vitl.pth: {encoder: vitl, features: 256, out_channels: [256, 512, 1024, 1024]}, depth_anything_v2_vitg.pth: {encoder: vitg, features: 384, out_channels: [1536, 1536, 1536, 1536]}, }from_pretrained的加载逻辑很简洁先用util.py中的DEPTH_ANYTHING_V2_MODEL_NAME_DICT把文件名映射到 HuggingFace 仓库名再走custom_hf_download下载支持断点续传与本地缓存最后load_state_dict载入权重并切到eval()模式classmethod def from_pretrained(cls, pretrained_model_or_pathNone, filenamedepth_anything_v2_vits.pth): if pretrained_model_or_path is None: pretrained_model_or_path DEPTH_ANYTHING_V2_MODEL_NAME_DICT[filename] model_path custom_hf_download(pretrained_model_or_path, filename) model DepthAnythingV2(**model_configs[filename]) model.load_state_dict(torch.load(model_path, map_locationcpu)) model model.eval() return cls(model, filename)第三层推理数据流DINOv2 DPT 双引擎src/custom_controlnet_aux/depth_anything_v2/dpt.py中的DepthAnythingV2是真正的推理核心整条数据流可以画成五段原始图 → image2tensor 预处理 → DINOv2 特征提取 → DPTHead 多尺度融合 → 逆归一化输出深度图预处理image2tensor无论输入多大都会等比缩放到边长 518 的方图input_size518并要求边长是 14 的整数倍ensure_multiple_of14随后做 ImageNet 标准归一化mean0.485/0.456/0.406。骨干特征提取DINOv2 按intermediate_layer_idx取出 4 层中间特征——V2 官方在dpt.py第 164 行给出了各规模模型的特征层索引self.intermediate_layer_idx { vits: [2, 5, 8, 11], vitb: [2, 5, 8, 11], vitl: [4, 11, 17, 23], vitg: [9, 19, 29, 39] }解码融合DPTHead4 层特征经过projects1×1 卷积投影、resize_layers转置卷积/池化对齐分辨率再进入 refinenet 金字塔逐级融合最终通过output_conv输出单通道深度图。最后把深度图插值回原始分辨率depth self.forward(image, max_depth) depth F.interpolate(depth[:, None], (h, w), modebilinear, align_cornersTrue)[0, 0]输出归一化__init__.py第 45 行做了 min-max 归一化到 0~255depth (depth - depth.min()) / (depth.max() - depth.min()) * 255.0值得一提的是 metric度量权重如 Hypersim / VKITTI 训练的版本会额外执行depth 255 - depth做亮度反转以匹配 ControlNet 深度模型的习惯配色。参数与配置精读每个旋钮都对应什么Depth Anything V2 节点暴露的参数不多但每个都值得较真参数可选值 / 默认值作用调优建议ckpt_namevits / vitb / vitl / vitg默认vitl选择骨干网络规模与对应权重追求速度用vits精度优先用vitlvitg参数达 13 亿仅显存 16G 时考虑resolution64~16384步长 64默认 512输出深度图的目标短边长度与最终生成图分辨率匹配过小丢失细节过大会拖慢速度并增加显存max_depth相对版本固定为 1相对深度为 1度量深度可达 20深度值缩放上限影响明暗对比强度相对深度模式下无需手动调度量版本按场景室内/室外选择 10~30环境级配置config.yaml项目根目录的config.example.yaml提供三个与下载和存储相关的开关annotator_ckpts_path权重落地目录默认./ckpts建议换成空间充足的绝对路径USE_SYMLINKS若你已通过 HuggingFace Hub 下载过相同权重设True用符号链接复用缓存能省下大量磁盘空间custom_temp_path下载临时目录路径长度过长的 Windows 用户强烈建议配置。这三个值也会通过环境变量AUX_ANNOTATOR_CKPTS_PATH、AUX_USE_SYMLINKS、AUX_TEMP_DIR被util.py读取所以脚本化使用时同样生效。实战案例从入门到进阶的完整应用链路场景一人像构图锁定入门对一张半身人像用 V2vitl resolution512出深度图再接 ControlNet 深度模型。关键技巧背景要退后。因为相对深度图里人物会呈现为亮色前景、背景为暗色渐变ControlNet 会把这种亮度关系翻译成近大远小重绘时保持人物的空间占位背景细节则可以自由发挥。场景二室内场景布局迁移进阶把 VitL 换成 Metric 权重V2 代码中预留了depth_anything_v2_metric_hypersim_vitl.pth的映射可在__init__.py的model_configs与util.py的DEPTH_ANYTHING_V2_MODEL_NAME_DICT中找到对应入口在__call__里传入max_depth20得到带真实尺度信息的深度图。相比相对深度度量深度能约束沙发到墙的距离是 3 米而不是 0.3 米更适合做室内布局改版——比如把客厅改造成电竞房时保持家具相对位置。场景三批量离线预处理脚本化结合processor.py的Processor门面或直接循环调用检测器可以批量生成深度图数据集用于训练 LoRA 或做数据增强import os import numpy as np from PIL import Image from custom_controlnet_aux.depth_anything_v2 import DepthAnythingV2Detector detector DepthAnythingV2Detector.from_pretrained(filenamedepth_anything_v2_vitb.pth) for name in os.listdir(inputs): path os.path.join(inputs, name) img np.array(Image.open(path).convert(RGB)) depth detector(img, detect_resolution768, output_typenp) Image.fromarray(depth).save(os.path.join(outputs, name)) print(f{name} - {depth.shape})性能调优与工程化实践显存与速度按骨干规模对号入座四个骨干的体量差异极大实测经验大致如下FP32 推理骨干参数量级单张 512 推理耗时RTX 4090 量级适用显存vits约 25M最快4G 可跑vitb约 90M快6G 可跑vitl约 300M中等8G 舒适vitg约 1.3B明显变慢建议 16G工程化建议生产链路默认 vitb质量敏感场景上 vitl。vitg 在 ControlNet 深度引导场景下的收益边际递减但成本翻倍谨慎选用。内存三板斧用完即删节点代码里del model已经做了第一步长流程里可再配合torch.cuda.empty_cache()在关键节点回收碎片显存。分辨率自适应把resolution与生成图尺寸解耦深度图短边保持 512~768 即可满足 ControlNet 引导需求不必跟随 2K 生成分辨率。缓存复用多轮测试同一权重时模型加载是一次性的若重启频繁考虑把检测器做成模块级单例避免重复下载与重复load_state_dict。下载链路优化custom_hf_download支持断点续传但首次拉取 vitg 的 1.3B 权重仍需较长时间。三个实用技巧提前用AUX_ANNOTATOR_CKPTS_PATH指向已手动下载过权重的目录跳过重复下载内网/受限环境可预先把权重放到 ckpts 目录检测到文件存在时util.py会直接跳过下载见if not os.path.exists(model_path)分支多机共享权重时开启USE_SYMLINKS让各节点符号链接同一份 HuggingFace 缓存。并发与批处理common_annotator_call默认逐张处理input_batchFalse。高吞吐离线任务可用多进程并行每个进程持有独立的 vitb 检测器吞吐接近线性扩展注意进程数不要超过 CPU/GPU 并发上限避免显存换页抖动。常见问题排查现象、根因、解法对照表问题现象根因解决方案首次运行时卡在Downloading进度条不动HuggingFace 网络受限或超时配置代理或手动下载权重放入annotator_ckpts_path对应子目录让custom_hf_download命中本地文件显存不足OOM骨干过大或resolution过高换vits/vitb降低resolution到 384关闭其他占用显存的后台进程深度图整体发灰、层次感弱相对深度被max_depth1压缩或输入图本身对比度低确认用的是相对版本尝试不同分辨率重建对低对比度输入先做亮度/对比度增强输出图出现奇怪的边缘伪影预处理ensure_multiple_of14的缩放与resize_image_with_pad的补边叠加保持resolution为 64 的倍数节点默认已约束避免输入超长条图像生成的图不受深度控制深度图与生成分辨率不匹配检查 ControlNet 侧的pixel_perfect选项参考utils.py中的pixel_perfect_resolution计算逻辑让深度图短边与生成图对齐metric 权重结果明暗颠倒度量深度模型输出的是真实距离近处反而更暗这是正常行为代码已对 metric 权重自动执行255 - depth反转若使用自己的脚本接入记得复刻该逻辑总结与最佳实践清单Depth Anything V2 是 ComfyUI ControlNet Aux 深度家族里性价比之王用 DINOv2 骨干 DPT 解码头的自研实现替代了 V1 的 transformers 管线封装加载更快、可控性更强。掌握它的关键就三件事选对骨干vitb/vitl、对齐分辨率512 起步、理解相对深度与度量深度的差异。最后给你一张可直接抄作业的清单✅ 首次部署前先配置config.yaml的annotator_ckpts_path避免默认./ckpts被清空导致重复下载✅ 默认链路选vitl生产批量任务降级到vitbvitg留给离线高精度场景✅resolution与生成图短边保持一致无需盲目拉高✅ 深度图与 ControlNet 不匹配时优先检查pixel_perfect与预处理分辨率而不是怀疑模型✅ 离线/内网环境提前手动放置权重绕过网络下载✅ 需要真实尺度如室内改造、3D 应用时从model_configs与DEPTH_ANYTHING_V2_MODEL_NAME_DICT切换到 metric 权重并设置合适的max_depth。深度图是 ControlNet 构图引导里最稳的一类条件输入而 Depth Anything V2 让这条链路变得又快又准。按本文的路径把节点源码和参数语义过一遍下次再遇到深度图糊成一团的深夜你就能一眼定位问题所在了。【免费下载链接】comfyui_controlnet_auxComfyUIs ControlNet Auxiliary Preprocessors项目地址: https://gitcode.com/gh_mirrors/co/comfyui_controlnet_aux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考