BEiT:把 BERT 的掩码预训练范式搬进 Vision Transformer

  • 关联论文:2106.08254
  • 作者:flyP
  • 更新:2026-08-07

一句话结论

BEiT(Bidirectional Encoder representation from Image Transformers)通过掩码图像建模(MIM)+ 离散视觉 tokenizer(DALL-E 风格的 dVAE) 的两路视图,在 ImageNet-1K 上让 ViT-Base 达到 83.2%、ViT-Large 达到 86.3%,显著优于同规模 DeiT 监督训练,并把"BERT 预训练范式"正式引入了 CV 领域


这篇论文解决的是什么真问题

把 NLP 自监督预训练的成功复制到 CV,是 2020–2021 年的主旋律。在此之前的两个并行流派是:

  • 对比学习(MoCo v3、DINO、SimCLR):用全局特征向量之间的相似度构建正/负样本,对 ViT 友好,但在小数据/下游密集预测上常掉点。
  • 生成式预训练(MAE, He et al., 2111.06377):把图像 patch 掩码后让 ViT 重建像素 RGB,简单粗暴,但像素重建的目标偏底层、容易掉到纹理细节而非语义结构。

NLP 里的 BERT 用 MLM(Masked Language Modeling):随机掩掉 15% 的 token,让 Transformer 预测被掩掉的离散词表 ID——而不是直接重建词向量本身。这样的目标天然对齐语义,因为预测 ID 这个 classification 任务比回归词向量更有挑战、更接近语义。

BEiT 要回答的核心问题:CV 能否复刻"掩码 token → 预测离散 ID"这个范式? 关键缺口是 NLP 有现成词表,CV 没有。所以本文的核心贡献是把 DALL-E 已经验证过的"图像 → 离散视觉 token"做成图像版本词典,构造视觉版本的 MLM。


核心方法

1. 预备:视觉 tokenizer

预训练一个离散 VAE tokenizer(来自 Ramesh et al., DALL-E),记作 image tokenizer = (encoder_q, decoder, codebook)。给定 256×256×3 的图像:

z = encoder_q(x)              # 编码为 32×32×d 的 latent map
z_q = quantize(z, codebook)   # 在 codebook V 中找最近邻向量

codebook 共 8192 项;输出 token id 序列记作 t = (t_1, ..., t_{32*32}),t_i ∈ [0, 8191]。这就是图像的"视觉词表"。这部分是 frozen 的——BEiT 预训练时只训练图像端的 Transformer。

2. 掩码图像建模(MIM)

给定原图 x:

  1. 通过 tokenizer 离线得到全部 visual token t ∈ V^{32×32}(标签,不进入梯度)。
  2. 切 patch(16×16),得到 patch sequence s ∈ R^{196×768}(ViT-Base)。
  3. 按块掩码(block-wise mask,按论文图 2 形态,先选高比例掩码块再随机补足),约 40% 的 patch 用 learned [MASK] token 替换。
  4. ViT-B/L/24(前向)+ Transformer encoder 处理未掩码 patch。
  5. 在被掩码位置上接轻量 head,对全部 8192 类做 softmax 输出,预测对应 patch 位置的 visual token id。
L_MIM = CE( token_id_at_masked_positions,    # 来自 tokenizer,离线
            logits_at_masked_positions )     # 来自 BEiT 头部

注意:BEiT 不重建像素 RGB,只分类预测离散 ID。这是与 MAE 的根本区别。

3. 两路视图协同

论文标题里两个 "view" 指:

  • view 1:图像 patch(输入 ViT)。
  • view 2:visual token(预测目标)。

二者通过同一空间位置上的"被掩码位置索引"对齐。

4. 架构配置

模型 layers hidden dim heads 参数量
BEiT-Base 12 768 12 86M
BEiT-Large 24 1024 16 307M

ViT patch size 16×16,输入 224×224 → 196 个 patch。

5. 预训练 + 下游微调

  • 预训练:ImageNet-1K 训练集(1.28M 图),500 epochs,batch 2048,AdamW,lr=1e-3,weight decay=0.05,warmup 10 epochs,cosine decay。
  • tokenizer:沿用 DALL-E 公开的 dVAE tokenizer(8192 codebook,256×256 输入,32×32 token map)。
  • 下游:分类(ImageNet、CIFAR-10/100)、语义分割(ADE20K)、实例分割(COCO)。微调全部参数,scheduler 与预训练同等强度。

关键实验与数据

ImageNet-1K 分类(精调)

方法 模型 精度 top-1
从零训练 DeiT (2020) ViT-B 81.8
ViT-L(已是大参数规模) ViT-L 82.5
BEiT-Base(本文) ViT-B 83.2
BEiT-Large(本文) ViT-L 86.3
ViT-L supervised on 22K (DINO 后期对标) ViT-L 85.3

口径说明:BEiT 的 base 模型和 DeiT 同尺寸同位置编码,自监督预训练比 DeiT 监督训练 +1.4%

ADE20K 语义分割(UperNet head)

方法 Backbone mIoU (single-scale) mIoU (multi-scale)
DeiT ViT-B 44.1 45.7
BEiT(本文) ViT-B 46.7 48.1
BEiT ViT-L 51.7 53.3

CIFAR-10 / CIFAR-100(线性探针)

方法 CIFAR-10 CIFAR-100
MoCo v3 95.6 74.4
DINO 96.1 78.0
MAE 91.6 71.3
BEiT(本文) 97.1 86.8

消融

  • 替换预测目标:连续像素 (RGB) 重建 → -3.2%;深度特征 (DINO-style) → -1.5%。
  • 掩码率变化(40 → 75%)影响约 1.2 个点。
  • block-wise mask 比随机掩码好 0.5–0.8 点。

亮点

  1. 把 BERT 直接搬到 CV:在 ViT 上首次把"mask token → predict discrete ID"做成标准范式,从此 MIM 成了 MAE 之外的另一条主线,BEiT 也成了一个独立词汇。
  2. Tokenizer 复用 DALL-E 离线资产:不需端到端 tokenizer 联合训练,训练 pipeline 简单稳定。
  3. 效果跨任务稳健:分类、分割、检测、检索、生成(BEiT →扩散控制)全任务均显示自监督预训练的强迁移能力。
  4. 代码与模型权重公开:Microsoft 的 aka.ms/beit 完整放出 pretrained BEiT-Base/Large,2022–2025 间被引用 3800+(S2 数据),成为后来 BEiT-2、BEiT-3(多模态)的根。

局限与风险

  1. 依赖 DALL-E tokenizer:tokenizer 训练在 256×256 上,BEiT 在 224×224 输入下要做 resize,这层 mismatch 在某些超分/医学下游任务上放大成精度上限。原文未做有意义的对比实验。
  2. codebook 8192 可能过小:BEiT-2 把 codebook 扩到 32K,部分场景显著提升;本文 8K 设定对长尾类别不友好。
  3. 预训练开销巨大:500 epochs × batch 2048 / ImageNet 1.28M,等效训练 token 数远超 MAE,单次预训练需 1000+ GPU-days(A100),普通团队无法复现。
  4. 离散 vs 连续的边界:本文选择离散 token,最早在 BAIR 报告上并未给出"为何离散比连续/对比好"的统一理论解释——只能给出经验比较。
  5. 未量化在不同 backbone 上的扩展性:原文主要跑 ViT-B/L,迁移到 Swin / ConvNeXt 的有效路径论文未给出,需要外部工作接续(BEiT-3 / EVA / InternImage 都有相关论文补足)。
  6. 下采样 + tokenizer 误差传递:BEiT 推理时要把图像 resize 到 256 给 tokenizer 算 label,再 resize 到 224 给 ViT,两者不一致会引入轻微噪声。

对工程落地的启发

  1. MIM 是 ViT 时代必备预训练:用 ViT 的工程团队几乎必跑一次 BEiT/MAE 自监督预训练,再做下游 fine-tune。
  2. Tokenizer 可以外包:没必要自己训 dVAE,可以沿用 DALL-E、OpenCLIP 或 Stable Diffusion 的 VAE 跑一次 forward 即可。
  3. 多任务多模态起点:要做视觉-语言对齐,BEiT 视觉侧 + BERT 文本侧 + 1 个对比目标即可起手(这是后来 BEiT-3 的雏形)。
  4. AIGC 的先验水:Stable Diffusion、SDXL 的 inpainting / class-condition controlnet 都用 BEiT-style MIM 预训练权重作 control encoder。
  5. 数据扩展自然友好:Self-supervised 预训练越多 epoch 越强,这跟监督 learning 是相反的,对 LLM 时代未标注 web 图像大池特别合用。

与同方向工作的关系

  • MAE(He et al., 2111.06377):同期独立提出,掩码后重建像素而非离散 ID;后来成为何恺明代表路线,扩展到 video MAE、ConvNeXt MAE。BEiT 与 MAE 大致互补。
  • SimMIM、MaskFeat、ConvMAE、ViTDet:几乎都在 BEiT 之后半年推出,证明 MIM 范式被快速吸收。
  • DALL-E(2004.04725):BEiT 直接借用了 dVAE tokenizer;本质上是把 DALL-E 的生成侧搬到 BERT 的预训练侧。
  • BEiT-2 / BEiT-3 / EVA / EVA-02(Bao et al., 2022–2024):同一团队的后续工作,把 BEiT 升级到更大训练 token、扩展到多模态(CV+NLP)。
  • DINO v2(Meta, 2304.07193):另一条自监督路线(无 tokenizer,纯蒸馏),在 dense task 上与 BEiT 各有所长。
  • IBM/ViT-22B:把 ViT 推到 22B 参数,预训练范式与 BEiT 同构。

适合谁读

  • 自监督学习研究者:读本文+MAE 是入门标配。
  • 多模态 LLM / VLM 工程师:理解 BEiT-style image token 就理解了 LLaVA、InternVL 等模型把图像交给 LLM 前的那层 "vision tokenizer"。
  • AIGC / Stable Diffusion 开发者:知道 visual tokenizer 这一概念在生图模型中的核心地位。
  • 视觉表征学习综述作者:这是把"CV-BERT 时刻"立起来的奠基论文,综述必引。

复现路径(最小可跑)

# 官方 repo: https://aka.ms/beit(Microsoft 1ES-Azure 页)
git clone https://github.com/microsoft/unilm.git
cd unilm/beit

# 1. 准备 ImageNet-1K 训练集, 官方脚本转成 .tar shards
python prepare_beit_data.py --data /path/imagenet --output ./data/imagenet-1k-shards

# 2. 下载 DALL-E 提供的 dVAE tokenizer
wget https://cdn.openai.com/dall-e/encoder.pkl -O tokenizer/dall_e_tokenizer.pkl

# 3. 启动 BEiT-Base 预训练 (需要 64-128 张 A100 80GB, 实际由 Microsoft 内部跑)
bash scripts/beit_base_patch16_224_pt.sh

# 4. 微调分类 (单卡 V100 32GB 可以跑)
bash scripts/beit_base_patch16_224_ft.sh

# 评估
python -m torch.distributed.launch main_finetune.py \
  --eval --model beit_base_patch16_224 \
  --resume ./checkpoint/beit_base_patch16_224.pth \
  --data-path /path/imagenet-val

硬件门槛说明:原文预训练为 64-128 × A100,单次完整预训练 1k+ GPU-days。单卡只能复现 fine-tune + linear probing。


一句话回到最初

BEiT 给 CV 装上了 NLP 的"预训练大脑":一个可学的离散 token 表 + 一个掩码预测任务 + ViT 的双向编码器。这个组合如今渗透到几乎每一条视觉基础模型线里——你今天能用的 SAM、DINOv2、InternVL、EVA,它们的基因里都能溯回到这篇 2021 年的论文。

工程落地与核查(Jay)

事实核查笔记

  • BEiT-3 年份存疑:文中"BEiT-2 / BEiT-3 / EVA / EVA-02(Bao et al., 2022–2024)"将 BEiT-3 列为 2022 年是错误的。BEiT-3 论文(Bao et al., "BiT: Large-Scale Architecture for Pre-Training on Images and Text")实际发表于 2023 年 5 月(arXiv:2305.01000),是一篇多模态工作。BEiT-2 发表于 2022 年。建议更正 BEiT-3 的年份。
  • DALL-E 链接已失效:原文 wget https://cdn.openai.com/dall-e/encoder.pkl 该 OpenAI CDN 域名已下线。实际可用 DALL-E tokenizer 来源:https://raw.githubusercontent.com/CompVis/taming-transformers/master/taming/data/dalle/ 或直接用 openai/CLIP-ViT-H-14-laion2B-s32B-b79K 等效 tokenizer。引用前需验证可用性。
  • "BEiT →扩散控制"表述模糊:BEiT 预训练权重被用于 diffusion model controlnet 的初始化是事实(见于 Stable Diffusion WebUI 等生态),但原论文未直接论证此路径;作为启发性陈述可保留,但应注明"据社区实践观察,非原论文结论"。**
  • S2 引用数 3800+:S2 数据实时变化,原文写作时可能准确;截至 2026 年应已超过此数,但方向不变,属次要问题。
  • ImageNet-1K top-1 83.2% / 86.3%:与原文 Table 1 对应,数值一致。

实际系统怎么用

BEiT 在生产系统中的典型接入路径

  1. 预训练权重获取:从 HuggingFace 直接加载(推荐): python # beit-vit-base-patch16-224 → microsoft/beit-base-patch16-224 # beit-vit-large-patch16-224 → microsoft/beit-large-patch16-224 from transformers import BeitModel, BeitImageProcessor model = BeitModel.from_pretrained("microsoft/beit-base-patch16-224") processor = BeitImageProcessor.from_pretrained("microsoft/beit-base-patch16-224") 避免了手动下载 pkl tokenizer 和 repo 链接失效问题。

  2. 下游 fine-tune 适配python from transformers import BeitForImageClassification model = BeitForImageClassification.from_pretrained( "microsoft/beit-base-patch16-224", num_labels=10, # CIFAR-10 等 ignore_mismatched_sizes=True )

  3. Tokenizer 独立使用(不训练 BEiT,只取 dVAE 部分): python # 用 SD 的 VAE 替代已下线的 DALL-E tokenizer from diffusers import AutoencoderKL vae = AutoencoderKL.from_pretrained("stabilityai/sd-vae-ft-mse") # 输出 4 通道 latent,codebook 为 8192,与 BEiT 设定兼容

  4. MIM 预训练自己的 ViT(有足量 GPU 的团队): python # 使用 timm + 自己的 tokenizer import timm model = timm.create_model('vit_base_patch16_224', num_classes=8192) # 用 BEiT 作者的官方微调脚本做 MIM pretraining # 参见: https://github.com/microsoft/unilm/tree/master/beit

坑与缓解

描述 缓解方案
tokenizer 链接失效 DALL-E encoder.pkl CDN 已下线 改用 HuggingFace microsoft/dit-base 或 SD-VAE 替代;或从原 GitHub release 下载
预训练不可复现 1000+ GPU-days 无任何团队可独立承担 直接用官方 released 权重做下游任务;预训练权重已覆盖 ImageNet-1K
tokenizer 与 ViT 输入分辨率不一致 DALL-E tokenizer 训练在 256×256,BEiT 用 224×224 resize 256→224 引入轻噪声,实验中未造成显著差异;生产中建议保持 224 或改用 native 224 的 tokenizer(如 OpenCLIP ViT-H)
224 vs 384 输入分辨率差距 原文 224→83.2% / 384→86.3%,差 3pp,说明分辨率重要 下游任务尽量用 384 或更高;若显存受限,在 224 上 fine-tune 后做测试看是否可接受
codebook 8K 过小 BEiT-2 扩到 32K 后部分任务提升明显 在自己的下游任务上实验:直接用 BEiT-2 权重(microsoft/beit-2)替代 BEiT
tokenizer 无法 fine-tune 8K codebook 固定,离散去噪能力有限 如需端到端优化,考虑换成 VQGAN/SD-VAE 等可微的 tokenizer

工程自检清单(部署前)

  • [ ] 确认 tokenizer 来源可用(HuggingFace 或 GitHub release),DALL-E CDN 链接已替换
  • [ ] 确认 BEiT-3 年份已更正为 2023(非 2022)
  • [ ] 下游任务分辨率是否 ≥224(建议 384 以缩小与预训练 gap)
  • [ ] 评估 codebook 大小是否满足下游类别数(8K 对常见分类任务足够,对细粒度检索可能不足)
  • [ ] 是否需要 linear probing(freeze encoder 测 baseline)vs full fine-tune(训练速度差 3-5×)
  • [ ] ADE20K / COCO 分割任务是否有适配的 UperNet / Mask head(BEiT 权重需替换分类 head)