Hiera 分层视觉 Transformer 使用与实现解析:从无冗余架构到 MAE 预训练、图像分类与 Backbone 应用(🤗 Transformers)
本文以 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(文档由社区成员 EduardoPacheco 与 namangarg110 联合贡献)。
论文的核心观点是:现代分层视觉 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 等分层模型常见的"移窗注意力 + 显式卷积下采样"范式,仅保留两个核心算子,所有"花哨"之处都收敛于此:
-
Mask Unit Attention(掩码单元注意力):在 MAE 预训练阶段,被掩码的掩码单元(mask unit)之间不产生信息交互。
HieraMaskUnitAttention(L315-L375)通过配置项use_mask_unit_attn决定计算掩码单元内注意力还是全局注意力,其中window_size与query_stride控制每个注意力窗口的 token 规模,掩码与可见 token 严格隔离,防止信息泄漏。 -
Query Pooling(查询池化):这是 Hiera 用来替代显式空间下采样的关键操作。实现上借助
unroll函数(L692-L743)对 token 序列做重排,使相邻的query_stride个 patch 在内存中连续,然后用 max-pooling 对 query 做降采样。相比卷积下采样,这种"重排 + max"方式更快,且天然支持任意空间维度与 patch 稀疏性。
此外,隐藏状态在阶段之间以掩码单元窗口形式组织,各阶段结束后通过 reroll(L602-L646)与 undo_windowing(L525-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_architecture(L108-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",可直接通过 AutoModel、AutoModelForImageClassification、AutoBackbone 等自动类加载。文档明确的模型类包括:
HieraModel(裸编码器)
裸 Hiera 编码器输出每个 token 的隐藏状态,行为由输出 dataclass HieraModelOutput 定义(L70-L92):
last_hidden_state:最后一层输出;pooler_output:当add_pooling_layer=True时,对最后隐藏状态做平均池化并经 LayerNorm 得到(维度(batch, hidden_size),实现见HieraPooler,L777-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(图像分类)
HieraForImageClassification(L1207-L1271)在带池化头的 HieraModel 之上接一个线性分类头(平均池化后接 nn.Linear)。当 config.num_labels == 1 时计算 MSE 回归损失,否则计算交叉熵损失;传入 labels 时 forward 会自动返回 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_values、labels、output_hidden_states、output_attentions、interpolate_pos_encoding、return_dict)与源码签名一一对应,可直接放心使用。
HieraForPreTraining(MAE 自监督预训练)
HieraForPreTraining(L1061-L1190)由四部分组成:
HieraModel(..., is_mae=True):在 MAE 模式下,输入 patch 前先在掩码单元粒度执行随机掩码(比例由mask_ratio=0.6控制,见random_masking,L190-L222),并用masked_conv将掩码区域的像素清零,防止重叠卷积造成信息泄漏;encoder_norm:对编码器输出做归一化;HieraMultiScaleHead(L993-L1046):将各 query-pooled 阶段的特征图融合成一个统一分辨率的多尺度表示;HieraDecoder(L891-L990):与标准 MAE 一致——用mask_token填补被掩码的 patch、叠加可学习的位置编码、经解码器(decoder_depth层)还原像素。
损失函数 forward_loss(L1091-L1100)对掩码区域重建结果与归一化后的真实像素计算 MSE,输出 dataclass HieraForPreTrainingOutput 提供 loss、logits、bool_masked_pos、ids_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(供检测 / 分割框架使用的骨干网络)
除了文档中列出的三个类外,源码还额外提供了 HieraBackbone(L1279-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_encoding(L256-L292)会用 bicubic 插值把预训练位置编码拉伸到目标分辨率,且该实现兼容 torch.jit 追踪场景(torchscript 导出时总是执行插值以保证动态输入尺寸)。因此,微调时把 image_size 从 224 提升到 448/512 等比尺寸是官方支持的标准做法。
权重转换与训练配置辅助
若需要从 facebookresearch/hiera 官方仓库把 PyTorch 权重迁移到 Transformers 格式,可参考 convert_hiera_to_hf.py。测试目录还提供了 HieraModelTester 与 HieraModelTest,覆盖了前向形状、隐藏状态/注意力输出数量、输出等价性、Backbone 行为等契约,可作为理解模型 API 边界的"活文档"。
进一步学习资源
- 官方文档确认的入门资源:图像分类训练示例脚本见 examples/pytorch/image-classification,任务级教程参见 图像分类任务指南(对应原文档
tasks/image_classification链接,已转换为仓库全局路径); - 原始论文:Hiera: A Hierarchical Vision Transformer without the Bells-and-Whistles;
- 官方权重:
facebook/hiera-tiny-224-hf、facebook/hiera-tiny-224-in1k-hf、facebook/hiera-tiny-224-mae-hf、facebook/hiera-base-224等均可在 Hub 上直接通过AutoXxx.from_pretrained加载; - MAE 预训练脚本见 examples/pytorch/image-pretraining。
结语
本文基于 hiera.md,把 Hiera 从"论文模型"还原为"可落地的 Transformers 模块":它用 Mask Unit Attention 与 Query Pooling 两个算子替换掉现代分层 ViT 中繁复的视觉专用组件,在 MAE 强预训练支撑下同时获得精度与速度。配合官方 Hub 权重,你可以用不到十行代码完成特征抽取、ImageNet 分类、MAE 像素重建,也可以借助 HieraBackbone 将其无缝接入检测与分割框架——这正是其"去掉花哨、保留实用"设计哲学在工程侧的直接体现。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00