首页
/ Hiera 分层视觉 Transformer 使用与实现解析:从无冗余架构到 MAE 预训练、图像分类与 Backbone 应用(🤗 Transformers)

Hiera 分层视觉 Transformer 使用与实现解析:从无冗余架构到 MAE 预训练、图像分类与 Backbone 应用(🤗 Transformers)

2026-09-07 18:56:40作者:仰钰奇

本文以 docs/source/en/model_doc/hiera.md 官方文档为骨架,结合仓库中的 配置定义模型实现测试用例,系统讲解 Hiera 在 Transformers 库中的完整用法:从配置参数、前向调用,到 MAE 预训练、图像分类微调与多尺度特征抽取(Backbone)三种典型场景,帮助你在实际项目中快速完成加载、推理与二次开发。

Hiera 是什么:剥离 "Bells-and-Whistles" 的分层视觉 Transformer

Hiera 于 2023 年 6 月 1 日发表论文(Hiera: A Hierarchical Vision Transformer without the Bells-and-Whistles),并于 2024 年 7 月 12 日合入 Hugging Face Transformers(文档由社区成员 EduardoPacheconamangarg110 联合贡献)。

论文的核心观点是:现代分层视觉 Transformer 为了在监督分类任务上刷精度,叠加了大量"视觉专用组件"(如相对位置偏置、卷积下采样、局部注意力窗口等,即所谓的 bells-and-whistles)。这些组件虽带来了漂亮的准确率与 FLOPs 数字,却让模型实际推理比同规模的 vanilla ViT 更慢。Hiera 的作者认为这些额外复杂度并非必要——只要用强视觉前置任务(MAE,掩码自编码)做预训练,空间先验就可以被"学"出来,从而可以把一个当时 SOTA 的多阶段视觉 Transformer 中所有花哨组件剥离掉而不损失精度。最终得到的是一个极其简单、但在图像与视频识别上更准、推理和训练都显著更快的层级视觉 Transformer。

官方模型权重已上传至 Hugging Face Hub(如 facebook/hiera-base-224),原始代码见 Meta 的 facebookresearch/hiera 仓库。

Hiera 架构中的两大机制:Mask Unit Attention 与 Query Pooling

在 Transformers 库的实现(modeling_hiera.py)中,Hiera 摆脱了此前 Swin、FocalNet 等分层模型常见的"移窗注意力 + 显式卷积下采样"范式,仅保留两个核心算子,所有"花哨"之处都收敛于此:

  1. Mask Unit Attention(掩码单元注意力):在 MAE 预训练阶段,被掩码的掩码单元(mask unit)之间不产生信息交互。HieraMaskUnitAttentionL315-L375)通过配置项 use_mask_unit_attn 决定计算掩码单元内注意力还是全局注意力,其中 window_sizequery_stride 控制每个注意力窗口的 token 规模,掩码与可见 token 严格隔离,防止信息泄漏。

  2. Query Pooling(查询池化):这是 Hiera 用来替代显式空间下采样的关键操作。实现上借助 unroll 函数(L692-L743)对 token 序列做重排,使相邻的 query_stride 个 patch 在内存中连续,然后用 max-pooling 对 query 做降采样。相比卷积下采样,这种"重排 + max"方式更快,且天然支持任意空间维度与 patch 稀疏性。

此外,隐藏状态在阶段之间以掩码单元窗口形式组织,各阶段结束后通过 rerollL602-L646)与 undo_windowingL525-L548)还原为规则的 (height, width, hidden_size) 空间排布,因此我们可以像使用 Swin 一样读取多尺度特征图。

HieraConfig:掌握全部 22 项配置参数

从源码结构看,文档中的 HieraConfig 类(configuration_hiera.py)为每个配置项给出了 dataclass 默认值,其 model_type"hiera"。官方文档中挂载的配置参数与默认值、含义对应如下(以 hiera-base-patch16-224 风格为基准):

配置参数 默认值 说明
embed_dim 96 Patch Embedding 的初始维度
image_size (224, 224) 输入图像尺寸
patch_size (7, 7) 卷积核大小(patch 提取窗口)
patch_stride (4, 4) Patch 卷积步长
patch_padding (3, 3) Patch 卷积填充
mlp_ratio 4.0 MLP 隐藏层相对维度比例
depths (2, 3, 16, 3) 每个阶段中 Transformer 层数(四阶段)
num_heads (1, 2, 4, 8) 各阶段注意力头数
embed_dim_multiplier 2.0 每阶段通道数增长倍率
num_query_pool 3 执行 Query Pooling 的阶段数量(即金字塔下采样次数)
query_stride (2, 2) Query Pooling 的空间步长
masked_unit_size (8, 8) 掩码单元空间尺寸
masked_unit_attention (True, True, False, False) 各阶段是否启用掩码单元注意力
drop_path_rate 0.0 随机深度(Stochastic Depth)概率
num_channels 3 输入通道数
hidden_act "gelu" MLP 激活函数
initializer_range 0.02 权重初始化标准差
layer_norm_init 1.0 LayerNorm 初始权重值
layer_norm_eps 1e-6 LayerNorm epsilon
decoder_hidden_size None MAE 解码器隐藏维度
decoder_depth None MAE 解码器深度
decoder_num_heads None MAE 解码器注意力头数
normalize_pixel_loss True 像素损失是否按像素数归一化
mask_ratio 0.6 输入中被掩码 token 的比例

几点值得注意的细节:

  • num_hidden_layers 会通过 attribute_map 自动映射为 num_layers
  • hidden_size 会在 __post_init__ 中被自动计算为最末阶段的通道数 embed_dim * embed_dim_multiplier ** (len(depths) - 1),目的是让 Hiera 能够配合 VisionEncoderDecoderModel 使用;
  • 配置类继承 BackboneConfigMixin,并支持传入 out_features / out_indices,用于控制作为 Backbone 时输出的阶段;
  • 配置内置了架构合法性校验 validate_architectureL108-L119):要求 masked_unit_size[0] 能被 query_stride[0] ** (len(depths) - 1) 整除,且 num_query_pool 必须小于阶段总数,否则抛出 ValueError

直接构造配置与模型的示例如下:

>>> from transformers import HieraConfig, HieraModel

>>> # Initializing a Hiera hiera-base-patch16-224 style configuration
>>> configuration = HieraConfig()

>>> # Initializing a model (with random weights) from the hiera-base-patch16-224 style configuration
>>> model = HieraModel(configuration)

>>> # Accessing the model configuration
>>> configuration = model.config

可用的模型类与官方 Chekpoint

Hiera 代码遵循标准命名规范,model_type = "hiera",可直接通过 AutoModelAutoModelForImageClassificationAutoBackbone 等自动类加载。文档明确的模型类包括:

HieraModel(裸编码器)

裸 Hiera 编码器输出每个 token 的隐藏状态,行为由输出 dataclass HieraModelOutput 定义(L70-L92):

  • last_hidden_state:最后一层输出;
  • pooler_output:当 add_pooling_layer=True 时,对最后隐藏状态做平均池化并经 LayerNorm 得到(维度 (batch, hidden_size),实现见 HieraPoolerL777-L789);
  • bool_masked_pos:每个 patch 是否保留的掩码标记(MAE 模式下返回);
  • ids_restore:用于还原打乱顺序的索引(MAE 模式下返回);
  • reshaped_hidden_states:被 reroll 还原回空间形状的各阶段特征。

加载官方权重做特征抽取,并配合 interpolate_pos_encoding=True 在更高分辨率图像上推理:

>>> from transformers import AutoImageProcessor, AutoModel
>>> import torch
>>> from PIL import Image
>>> import httpx
>>> from io import BytesIO

>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> with httpx.stream("GET", url) as response:
...     image = Image.open(BytesIO(response.read()))

>>> image_processor = AutoImageProcessor.from_pretrained("facebook/hiera-tiny-224-hf")
>>> model = AutoModel.from_pretrained("facebook/hiera-tiny-224-hf")

>>> inputs = image_processor(images=image, return_tensors="pt")
>>> with torch.no_grad():
...     outputs = model(**inputs, interpolate_pos_encoding=True)
>>> outputs.last_hidden_state.shape
torch.Size([1, 196, 96])

测试代码(test_modeling_hiera.py#L563-L578)中通过 size={"shortest_edge": 448} 构造更高分辨率输入验证了 last_hidden_state 形状与数值一致性,这说明官方权重对该能力有明确支撑。

HieraForImageClassification(图像分类)

HieraForImageClassificationL1207-L1271)在带池化头的 HieraModel 之上接一个线性分类头(平均池化后接 nn.Linear)。当 config.num_labels == 1 时计算 MSE 回归损失,否则计算交叉熵损失;传入 labelsforward 会自动返回 loss,这正是文档中 <PipelineTag pipeline="image-classification"/> 所标注的能力。

典型推理用法(支持任意分辨率,通过 interpolate_pos_encoding=True 插值位置编码):

>>> from transformers import AutoImageProcessor, HieraForImageClassification
>>> import torch
>>> from PIL import Image
>>> import httpx
>>> from io import BytesIO

>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> with httpx.stream("GET", url) as response:
...     image = Image.open(BytesIO(response.read()))

>>> image_processor = AutoImageProcessor.from_pretrained("facebook/hiera-tiny-224-in1k-hf")
>>> model = HieraForImageClassification.from_pretrained("facebook/hiera-tiny-224-in1k-hf")

>>> inputs = image_processor(images=image, return_tensors="pt")
>>> outputs = model(**inputs)
>>> logits = outputs.logits
>>> # model predicts one of the 1000 ImageNet classes
>>> predicted_class_idx = logits.argmax(-1).item()
>>> print("Predicted class:", model.config.id2label[predicted_class_idx])

集成测试(test_modeling_hiera.py#L528-L560)确认了 facebook/hiera-tiny-224-in1k-hf 在 224 分辨率下输出 (1, 1000) 的 logits。由于文档正文中 [[autodoc]] 由 doc-builder 自动展开,这里整理出的 forward 参数(pixel_valueslabelsoutput_hidden_statesoutput_attentionsinterpolate_pos_encodingreturn_dict)与源码签名一一对应,可直接放心使用。

HieraForPreTraining(MAE 自监督预训练)

HieraForPreTrainingL1061-L1190)由四部分组成:

  1. HieraModel(..., is_mae=True):在 MAE 模式下,输入 patch 前先在掩码单元粒度执行随机掩码(比例由 mask_ratio=0.6 控制,见 random_maskingL190-L222),并用 masked_conv 将掩码区域的像素清零,防止重叠卷积造成信息泄漏;
  2. encoder_norm:对编码器输出做归一化;
  3. HieraMultiScaleHeadL993-L1046):将各 query-pooled 阶段的特征图融合成一个统一分辨率的多尺度表示;
  4. HieraDecoderL891-L990):与标准 MAE 一致——用 mask_token 填补被掩码的 patch、叠加可学习的位置编码、经解码器(decoder_depth 层)还原像素。

损失函数 forward_lossL1091-L1100)对掩码区域重建结果与归一化后的真实像素计算 MSE,输出 dataclass HieraForPreTrainingOutput 提供 losslogitsbool_masked_posids_restore 等字段。

文档附带的官方示例代码为自监督预训练推理:

>>> from transformers import AutoImageProcessor, HieraForPreTraining
>>> import torch
>>> from PIL import Image
>>> import httpx
>>> from io import BytesIO

>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> with httpx.stream("GET", url) as response:
...     image = Image.open(BytesIO(response.read()))

>>> image_processor = AutoImageProcessor.from_pretrained("facebook/hiera-tiny-224-mae-hf")
>>> model = HieraForPreTraining.from_pretrained("facebook/hiera-tiny-224-mae-hf")

>>> inputs = image_processor(images=image, return_tensors="pt")

>>> outputs = model(**inputs)
>>> logits = outputs.logits
>>> loss = outputs.loss
>>> print(list(logits.shape))
[1, 196, 768]

从 logits 形状 (1, 196, 768) 可以反推出该 MAE 配置:224×224 输入经 patch_stride=4 得到 56×56 的 token 网格,3 次 query_stride=2 的 Query Pooling 之后分辨率为 7×7,即 49 个掩码单元、每个单元 4×4 token,总计 196 个重建 token,最终隐藏维度为 768。这一数值与集成测试的断言完全一致(test_modeling_hiera.py#L612-L613)。

如需在自有数据上预训练,仓库在 examples/pytorch/image-pretraining 中提供了完整脚本。需要注意的是:Hiera 文档与实现均强调先预训练再微调的范式——直接用随机初始化权重做监督分类无法体现架构优势,MAE 预训练才是其高性能的来源。

HieraBackbone(供检测 / 分割框架使用的骨干网络)

除了文档中列出的三个类外,源码还额外提供了 HieraBackboneL1279-L1377),用于与 DETR、MaskFormer 等框架集成:它会按 out_features 选取各阶段输出并施加独立的 LayerNorm,最终返回 BackboneOutput.feature_maps(格式 (batch, channels, height, width))。该类的 docstring 示例同样验证了 224 输入下 stage4 输出的形状为 [1, 768, 7, 7],对应 4 次下采样后的 1/32 分辨率。

位置编码插值:让 Hiera 处理更高分辨率输入

Hiera 采用可学习的一维位置编码,但针对金字塔下采样做了一定适配。当 interpolate_pos_encoding=True 时,HieraEmbeddings.interpolate_pos_encodingL256-L292)会用 bicubic 插值把预训练位置编码拉伸到目标分辨率,且该实现兼容 torch.jit 追踪场景(torchscript 导出时总是执行插值以保证动态输入尺寸)。因此,微调时把 image_size 从 224 提升到 448/512 等比尺寸是官方支持的标准做法。

权重转换与训练配置辅助

若需要从 facebookresearch/hiera 官方仓库把 PyTorch 权重迁移到 Transformers 格式,可参考 convert_hiera_to_hf.py。测试目录还提供了 HieraModelTesterHieraModelTest,覆盖了前向形状、隐藏状态/注意力输出数量、输出等价性、Backbone 行为等契约,可作为理解模型 API 边界的"活文档"。

进一步学习资源

结语

本文基于 hiera.md,把 Hiera 从"论文模型"还原为"可落地的 Transformers 模块":它用 Mask Unit Attention 与 Query Pooling 两个算子替换掉现代分层 ViT 中繁复的视觉专用组件,在 MAE 强预训练支撑下同时获得精度与速度。配合官方 Hub 权重,你可以用不到十行代码完成特征抽取、ImageNet 分类、MAE 像素重建,也可以借助 HieraBackbone 将其无缝接入检测与分割框架——这正是其"去掉花哨、保留实用"设计哲学在工程侧的直接体现。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395