首页
/ 使用 Transformers 与 CHMv2 进行全球树冠高度制图:基于 DINOv3 的深度估计模型实战指南

使用 Transformers 与 CHMv2 进行全球树冠高度制图:基于 DINOv3 的深度估计模型实战指南

2026-09-06 19:02:20作者:明树来

CHMv2(Canopy Height Maps v2)是 Meta 于 2026 年发布的新一代全球树冠高度制图模型,它复用 DINOv3 自监督视觉骨干网络,并结合 DPT 风格的分层特征融合与深度估计头,从高分辨率光学卫星影像中逐像素预测植被冠层高度。本指南以 docs/source/en/model_doc/chmv2.md 为骨架,结合本仓库 src/transformers/models/chmv2 下的配置、图像处理与建模源码,完整讲解 CHMv2 的原理、架构、推理用法与配置参数,读完即可用几行代码在自己的遥感影像上产出米级分辨率的冠层高度图。

模型背景:从 2024 年首版到 DINOv3 驱动的新一代

CHMv2 承接了 Meta 于 2024 年公开发布的全球高分辨率树冠高度图(Canopy Height Maps)工作,其技术路线是把高分辨率光学卫星影像输入一个建立在 DINOv3(Meta 自监督视觉模型)之上的深度估计模型,并以机载激光扫描(ALS)测得的树冠高度模型(CHM)作为训练监督信号,最终输出覆盖全球的米级分辨率冠层高度图。

相比既有产品,CHMv2 论文摘要所宣称的核心改进包括:精度显著提升、在高大森林区域偏差更小、能更好地保留林冠边缘与林隙等细粒度结构。这些收益来自更大规模的地理多样性训练数据、自动化的数据清洗与配准,以及对树冠高度分布量身定制的损失函数与数据采样策略。模型于 2026-03-06 在相关论文平台公开发表,并于 2026-03-11 合入 Hugging Face Transformers(即当前仓库)。模型与处理器使用 Meta 与 Hugging Face 共同版权,代码以 modular_chmv2.py 为唯一事实来源自动生成(configuration_chmv2.pyimage_processing_chmv2.pymodeling_chmv2.py 均标注为不可手工编辑的生成文件)。

已公开的官方检查点

本仓库文档示例与集成测试引用了官方检查点 facebook/dinov3-vitl16-chmv2-dpt-head。从命名可读出三层信息:vitl16 表示 backbone 为 DINOv3 ViT-Large 16 像素 patch 版本;chmv2 表示使用 CHMv2 的训练配置;dpt-head 表示预测头采用 DPT 风格结构。集成测试对该检查点输出了可复现的数值断言,见 tests/models/chmv2/test_modeling_chmv2.py

快速上手:单张影像的冠层高度推理

文档给出的标准推理流程如下(原样保留并在注释中补充要点):

import torch
from PIL import Image

from transformers import AutoImageProcessor, AutoModelForDepthEstimation


processor = AutoImageProcessor.from_pretrained("facebook/dinov3-vitl16-chmv2-dpt-head")
model = AutoModelForDepthEstimation.from_pretrained(
    "facebook/dinov3-vitl16-chmv2-dpt-head", device_map="auto"
)

image = Image.open("image.tif")
inputs = processor(images=image, return_tensors="pt").to(model.device)

with torch.no_grad():
    outputs = model(**inputs)

depth = processor.post_process_depth_estimation(
    outputs, target_sizes=[(image.height, image.width)]
)[0]["predicted_depth"]

代码的机制拆解如下:

  1. 自动类路由chmv2 模型类型已在自动映射中注册——auto_mappings.pyCHMv2ImageProcessor 注册到图像处理器映射、modeling_auto.pyCHMv2ForDepthEstimation 注册到深度估计模型映射,因此这里可以用 AutoImageProcessorAutoModelForDepthEstimation 直接加载,无需显式 import 具体类。
  2. 影像格式:示例直接打开 image.tif。树冠高度制图的业务输入通常是多光谱或 RGB 卫星影像的 GeoTIFF 切片,PIL 打开后即作为普通 RGB 图输入处理器;后续如需地理配准,可在后处理阶段自行把像素坐标映射回投影坐标。
  3. device_map="auto":把模型自动分配到可用设备(GPU/多卡/CPU 回退),随后 inputs.to(model.device) 保证输入与参数同设备。
  4. 预测后处理post_process_depth_estimation(outputs, target_sizes=[(height, width)]) 用双线性插值把模型原生分辨率输出缩放到输入影像原始尺寸,返回 predicted_depth 张量,其中每个像素值即该处预测的冠层高度(单位为米,见下文深度箱设计)。
  5. 若希望保留模型原生分辨率而不回缩到原图尺寸,省略 target_sizes 即可,这与集成测试中的行为一致。

集成测试对输出形状的验证

慢速集成测试 tests/models/chmv2/test_modeling_chmv2.py 以一张官方示例 TIFF 为输入(加载后转 RGB),断言了如下事实,可作为自测基线:

  • 原生推理输出 predicted_depth 形状为 [1, 448, 448],即分辨率与输入预处理后的张量一致,而非 384×384——因为推理尺寸由预处理填充结果决定;
  • 输出前三行前三列与期望切片 [[0.1028, 0.0562, 0.0575], [0.4136, 0.5476, 0.4333], [1.8045, 2.3640, 1.6928]]atol=5e-3, rtol=5e-3 内一致;
  • 不经 target_sizes 的后处理保持 448×448,传入 target_sizes=[(原图高, 原图宽)] 后则恢复原图分辨率。

推理环境约束

CHMv2ImageProcessor.post_process_depth_estimation 内部通过 requires_backends(self, "torch") 校验 PyTorch 可用性,即后处理只支持 PyTorch 后端,见 image_processing_chmv2.py。推理前请确保环境安装了 torchtransformers 与 PIL 兼容的图像栈。

架构拆解:DINOv3 骨干 + DPT 式头

CHMv2 没有独立的基础模型(无 CHMv2Model),只有一个带深度估计头的组合模型 CHMv2ForDepthEstimation,其前向逻辑(见 modeling_chmv2.py)分为四个阶段:

  1. DINOv3 骨干提取多尺度特征:模型通过 load_backbone(config) 加载 backbone(见 backbone_utils.py 同目录依赖),默认配置指向 dinov3_vit。骨干在 out_indices=[6, 12, 18, 24] 四层分别取出特征图,并与各层 CLS token 一起返回(return_class_token=True),形成 list(zip(feature_maps, cls_tokens))
  2. Reassemble 阶段CHMv2ReassembleStagemodeling_chmv2.py)把每层带 CLS 的序列特征重塑回 2D 特征图,按 readout_type(默认 "project")把 CLS token 信息注入每个 patch 位置,再由 CHMv2ReassembleLayer 做 1×1 投影并按 reassemble_factors 进行上/下采样:factor > 1ConvTranspose2d 上采样,factor == 1 恒等,factor < 1 用 stride 卷积下采样。
  3. RefineNet 式自底向上融合:4 个尺度的特征先各自经 3×3 卷积统一到 fusion_hidden_size 通道(默认 256),再由 CHMv2FeatureFusionLayer 自最深尺度开始逐级与更浅尺度残差相加并 2× 双线性上采样,逐级恢复高分辨率细节。残差单元 CHMv2PreActResidualLayer 采用预激活结构(ReLU→Conv→ReLU→Conv 后加残差)。该设计来自 DPT/DepthAnything 一脉(modular_chmv2.py 直接从 dpt 模块复用 DPTReassembleLayer、从 depth_anything 复用 DepthAnythingPreActResidualLayer)。
  4. 深度头与深度箱解码:融合结果经 CHMv2UpsampleConvHead(Conv3×3 → 2× 双线性上采样 → Conv3×3 → ReLU → Conv1×1)输出 number_output_channels=256 个通道,即 256 个“深度箱”(depth bin)的 logits,最后由 CHMv2FeaturesToDepth 把 logits 换算成连续深度值。

CHMv2ForDepthEstimation 继承的 CHMv2PreTrainedModelmodeling_chmv2.py)声明了关键能力:支持 gradient checkpointing、支持 SDPA / Flash Attention / Flex Attention 多种注意力后端(_supports_sdpa/_supports_flash_attn/_supports_flex_attn/_supports_attention_backend 均为 True),主输入名为 pixel_values,输入模态为图像。权重初始化对 Linear/Conv2d/ConvTranspose2d 使用截断正态分布、偏置置零(initializer_range 默认 0.02)。

深度箱策略与“高度即深度”的设计

CHMv2FeaturesToDepthmodeling_chmv2.py)是 CHMv2 区别于普通单值回归深度模型的算法核心:

  • 深度箱(bins):头输出 256 个 bin 的 logits,每个 bin 对应一个预定义的深度值;min_depth=0.001max_depth=96.0(单位米)界定了可预测范围。这正是论文所述“针对树冠高度分布设计 bin 分布”的落地:把测距问题变成对 256 个高度区间的加权聚合。
  • 三种 bin 分布策略bins_strategy):
    • linear:在 [min_depth, max_depth] 等距取 bin;
    • log:在对数空间等距再取指数,使近处(低矮/裸地)有更细区分;
    • chmv2_mixlog(默认):_create_mixlog_bins 在 linear 与 log 之间按线性衰减权重插值,且内部先把 max_depth 除以 8.0,再用 _create_outputs_with_mixlog_norm 在输出端乘回 8.0——这一缩放实现细节使 bin 在近端对齐线性(分辨率更高),远端偏向对数。
  • 四种归一化策略norm_strategy):
    • linearrelu(x) + eps(0.1) 后按通道归一化为权重;
    • softmax:直接 softmax 得到权重;
    • sigmoid:sigmoid 后按通道归一化;
    • chmv2_mixlog(默认):对 logits 先做 relu,对每个样本取通道最小值做裁剪移位(移位上限 1e-4、额外偏移 1e-8),分母用 nan_to_numclamp_min(1e-12) 保证数值稳定,得到权重后用 bin 加权求和再乘 8.0。

任何一条分支最终都用 torch.einsum("ikmn,k->imn", ...) 做 bin 加权求和,产出单通道的连续“深度”(此处语义为冠层高度)图。另外,若某输入只有 1 个 bin,则直接 relu(x) + min_depth

CHMv2Config 配置参数全表

CHMv2Config(定义于 configuration_chmv2.py)的 model_type"chmv2",并声明了 sub_configs = {"backbone_config": AutoConfig},即 backbone 配置以子配置形式内嵌。各参数含义、默认值与取值范围整理如下:

参数 默认值 说明与取值范围
backbone_config None 骨干网络的配置,dict 或 PreTrainedConfig 均可;当前只支持 DINOv3ViTConfig。为 None 时按下方默认 kwargs 自动构造
patch_size 16 backbone ViT 的 patch 尺寸(模型前向用它计算 patch 网格 patch_height/patch_width
reassemble_factors [4, 2, 1, 0.5] Reassemble 各层的上/下采样因子(>1 上采样,1 恒等,<1 下采样),长度须与特征层级数一致
post_process_channels [128, 256, 512, 1024] 每个 backbone 特征层级经 reassemble 后的输出通道数
fusion_hidden_size 256 融合阶段(统一卷积 + 预激活残差单元)的通道数
head_hidden_size 128 深度头隐藏层通道数
number_output_channels 256 CHMv2 头输出通道数,即深度箱(bin)数量
readout_type "project" CLS token 的 readout 方式:"ignore" / "add" / "project"
min_depth 0.001 深度箱计算的最小深度(米)
max_depth 96.0 深度箱计算的最大深度(米)
bins_strategy "chmv2_mixlog" 深度箱分布策略:"linear" / "log" / "chmv2_mixlog"
norm_strategy "chmv2_mixlog" 深度预测归一化策略:"linear" / "softmax" / "sigmoid" / "chmv2_mixlog"

当未显式传入 backbone_config 时,__post_init__ 经由 consolidate_backbone_kwargs_to_configdefault_config_type="dinov3_vit" 构造默认骨干配置,默认 kwargs 为:image_size=416hidden_size=1024intermediate_size=4096num_attention_heads=16num_hidden_layers=24(即 ViT-Large 规模)、num_register_tokens=4key_bias=Trueout_indices=[6, 12, 18, 24]reshape_hidden_states=Trueapply_layernorm=Truelayer_norm_eps=1e-6return_class_token=True。其中 num_register_tokens=4 对应 DINOv3 的 register token 机制,return_class_token 是 reassemble 阶段 readout 所需的数据前提。这些中间参数同样可以以平铺 kwargs 形式传入 CHMv2Config,由 consolidate_backbone_kwargs_to_config 收敛进 backbone_config

CHMv2Config 采用 @strict 数据类约束并带 @auto_docstring,支持标准用法:实例化后可作为 CHMv2ForDepthEstimation(configuration) 的骨架创建随机初始化模型。

CHMv2ImageProcessor:面向 DPT 风格推理的图像预处理

CHMv2ImageProcessorimage_processing_chmv2.py)继承 Torchvision 后端(在 modular 定义中继承自 DPTImageProcessor),类级默认值体现了针对树冠高度模型训练的固定预处理协议:

  • 归一化统计量image_mean=[0.420, 0.411, 0.296]image_std=[0.213, 0.156, 0.143]rescale_factor=1/255,与 2024 首版 CHM 处理管线保持一致;
  • 目标尺寸size={"height": 384, "width": 384}default_to_square=True
  • 关键标志do_resize=False(实际不强制缩放到正方形目标)、do_pad=Truesize_divisor=16ensure_multiple_of=16keep_aspect_ratio=True

这些标志组合成一条“保宽高比 + 补边对齐 16”的特殊管线,体现在 _preprocessimage_processing_chmv2.py)中:

  1. 按形状分批 resize:借助 group_images_by_shape / reorder_images 按输入形状分组;若需 resize,resize() 依据 ensure_multiple_of(16)把新尺寸约束为 16 的倍数,并在 keep_aspect_ratio=True 时以“改动更小的一边”为基准等比缩放(见 get_resize_output_image_size);
  2. 融合 rescale + normalize:像素值乘 1/255,再用上述均值/方差标准化;
  3. 中心补边pad_image 把宽高用中间对称补零扩展到 ceil(size/16)*16(上下左右均分,余数归右侧/下侧)。这一步解释了集成测试里输入 384 切块经模型后得到 448×448 分辨率的现象——实际推理张量边长是某个 16 的倍数,而输出即该张量分辨率。

对后处理,post_process_depth_estimationDepthEstimatorOutput.predicted_depth 逐样本地用双线性插值(align_corners=True)缩放到 target_sizes 指定的 (height, width),返回 [{"predicted_depth": tensor}] 形式的列表。

另外该类还继承了语义分割后处理接口 post_process_semantic_segmentation 与可选的 do_reduce_labels 标签归约逻辑(把 0 换成 255 再整体减 1),这是为与 DPT/语义分割生态保持接口兼容的产物,并非 CHMv2 深度估计主流程的必需部分。

模型能力与当前限制(务必先读)

基于源码可确认以下边界条件:

  • 只支持推理,训练未实现CHMv2ForDepthEstimation.forward 中一旦传入 labels 即抛出 NotImplementedError("Training is not implemented yet")modeling_chmv2.py)。测试套件也显式 skip 了训练相关用例(test_trainingtest_model_get_set_embeddings 中相关项被跳过/改写)。
  • 无独立 base 模型与 token 嵌入CHMv2ForDepthEstimation 是唯一模型类,get_input_embeddings 透传 backbone 的 patch 卷积嵌入(是 nn.Module 而非 nn.Embedding),因此没有 input_embeds 这类文本式输入路径。
  • 注意力后端:支持 SDPA/Flash/Flex Attention 切换,FlashAttention 徽标亦出现在模型文档页,适配大分辨率影像时可用 attn_implementation 选择相应后端降低显存。
  • 输出语义predicted_depth 的“深度”在业务上即冠层高度(米),量程由 min_depth/max_depth(0.001–96.0 米)界定,超出该范围的极端值会被 bin 加权机制压向边界附近,解读结果时应结合本地 ALS 样本做标定。

从原始权重转换 CHMv2 检查点

仓库提供了一站式转换脚本 convert_chmv2_to_hf.py,支持把原始训练仓库产出的 head-only 或 “backbone + head” 合并检查点转换为 HF 格式并保存,其模块级 docstring 给出两种用法:

# 用法 1:head 检查点内含 backbone 权重
python -m transformers.models.chmv2.convert_chmv2_to_hf \
    --head_checkpoint_path /path/to/checkpoint.pth \
    --pytorch_dump_folder_path /path/to/output \
    --model_name chmv2

# 用法 2:head 检查点 + 已有 HF 格式 DINOv3 骨干
python -m transformers.models.chmv2.convert_chmv2_to_hf \
    --head_checkpoint_path /path/to/head_checkpoint.pth \
    --backbone_repo_id facebook/dinov3-vitl16-pretrain-lvd1689m \
    --pytorch_dump_folder_path /path/to/output \
    --model_name chmv2

命令行还提供 --backbone_checkpoint_path(独立 DINOv3 backbone 原始权重)、--verify_image_path(转换后用示例图前向并打印深度 shape/均值/极值)、--push_to_hub 等选项。转换内部机制可作为理解模型结构映射的窗口:

  • 头部键名通过正则映射(HEAD_ORIGINAL_TO_CONVERTED_KEY_MAPPING)把原始 reassemble_blocks.projects/resize_layers/batchnorm_layersfusion_blocks.res_conv_unit{1,2}conv_depth.head 等键翻译到 HF 侧 head.reassemble_stage.*head.fusion_layers.* 命名(convert_chmv2_to_hf.py),这与前面架构剖析中每个子模块一一对应;
  • backbone 部分复用 DINOv3 的转换函数(split_qkvconvert_old_keys_to_new_keys),并过滤掉 inv_freqmask_token 等非必要键;
  • 校验环节用 load_state_dict(strict=False) 报告 missing/unexpected 键(inv_freq 类键允许缺失);
  • 转换配置硬编码为 min_depth=0.001max_depth=96.0bins_strategy="chmv2_mixlog"norm_strategy="chmv2_mixlog",与官方检查点一致。

测试与质量保障

模型的正确性由两层测试背书(tests/models/chmv2/test_modeling_chmv2.py):

  • 通用建模测试CHMv2ModelTester 用极小配置(2 层骨干、16 通道等)跑 ModelTesterMixin 全套通用测试与 ConfigTester,并断言 CHMv2ForDepthEstimation 输出的 predicted_depth 形状恰为 (batch, image_size, image_size)pipeline_model_mapping 将模型映射到 "depth-estimation" pipeline,说明其可直接挂载进 Transformers 的深度估计 pipeline 生态;
  • 慢速集成测试:加载真实检查点与官方 TIFF 样本,做数值对齐断言(前文已述)。

若想在本仓库内复现,可运行针对该模型目录的测试,例如(需 GPU/网络并设置 RUN_SLOW=1 以包含集成测试):

RUN_SLOW=1 pytest tests/models/chmv2/test_modeling_chmv2.py -k "chmv2"

小结与实践建议

CHMv2 展示了“自监督骨干 + 面向分布的离散深度箱解码”这一组合在遥感稠密预测任务上的工程化范式。实操要点总结如下:

  1. 官方入口用 AutoModelForDepthEstimation + AutoImageProcessor 加载 facebook/dinov3-vitl16-chmv2-dpt-head,输入直接读 TIFF/RGB 切块即可,无需任何自定义预处理;
  2. 预测结果经 post_process_depth_estimation(outputs, target_sizes=[(h, w)]) 还原到原图分辨率,像素值即米制冠层高度,量程默认 0.001–96 米;
  3. 处理大区域影像时建议按 16 的倍数切块、用 device_map="auto" 并把 batch 控制到显存可承受范围,推理分辨率由输入决定(示例管线实际以较大边长运行,如 448);
  4. 目前模型仅用于推理(训练未实现),需要微调或自训时应等待后续版本,或在 Transformers 之外实现标签监督训练路径;
  5. 想深挖结构细节,推荐对照阅读 modeling_chmv2.py(架构)、configuration_chmv2.py(全部默认值)、image_processing_chmv2.py(预处理管线)以及 convert_chmv2_to_hf.py(权重命名映射)。
登录后查看全文
热门项目推荐
相关项目推荐