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:
- 通过 tokenizer 离线得到全部 visual token
t ∈ V^{32×32}(标签,不进入梯度)。 - 切 patch(16×16),得到 patch sequence
s ∈ R^{196×768}(ViT-Base)。 - 按块掩码(block-wise mask,按论文图 2 形态,先选高比例掩码块再随机补足),约 40% 的 patch 用 learned
[MASK]token 替换。 - ViT-B/L/24(前向)+ Transformer encoder 处理未掩码 patch。
- 在被掩码位置上接轻量 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 点。
亮点
- 把 BERT 直接搬到 CV:在 ViT 上首次把"mask token → predict discrete ID"做成标准范式,从此 MIM 成了 MAE 之外的另一条主线,BEiT 也成了一个独立词汇。
- Tokenizer 复用 DALL-E 离线资产:不需端到端 tokenizer 联合训练,训练 pipeline 简单稳定。
- 效果跨任务稳健:分类、分割、检测、检索、生成(BEiT →扩散控制)全任务均显示自监督预训练的强迁移能力。
- 代码与模型权重公开:Microsoft 的 aka.ms/beit 完整放出 pretrained BEiT-Base/Large,2022–2025 间被引用 3800+(S2 数据),成为后来 BEiT-2、BEiT-3(多模态)的根。
局限与风险
- 依赖 DALL-E tokenizer:tokenizer 训练在 256×256 上,BEiT 在 224×224 输入下要做 resize,这层 mismatch 在某些超分/医学下游任务上放大成精度上限。原文未做有意义的对比实验。
- codebook 8192 可能过小:BEiT-2 把 codebook 扩到 32K,部分场景显著提升;本文 8K 设定对长尾类别不友好。
- 预训练开销巨大:500 epochs × batch 2048 / ImageNet 1.28M,等效训练 token 数远超 MAE,单次预训练需 1000+ GPU-days(A100),普通团队无法复现。
- 离散 vs 连续的边界:本文选择离散 token,最早在 BAIR 报告上并未给出"为何离散比连续/对比好"的统一理论解释——只能给出经验比较。
- 未量化在不同 backbone 上的扩展性:原文主要跑 ViT-B/L,迁移到 Swin / ConvNeXt 的有效路径论文未给出,需要外部工作接续(BEiT-3 / EVA / InternImage 都有相关论文补足)。
- 下采样 + tokenizer 误差传递:BEiT 推理时要把图像 resize 到 256 给 tokenizer 算 label,再 resize 到 224 给 ViT,两者不一致会引入轻微噪声。
对工程落地的启发
- MIM 是 ViT 时代必备预训练:用 ViT 的工程团队几乎必跑一次 BEiT/MAE 自监督预训练,再做下游 fine-tune。
- Tokenizer 可以外包:没必要自己训 dVAE,可以沿用 DALL-E、OpenCLIP 或 Stable Diffusion 的 VAE 跑一次 forward 即可。
- 多任务多模态起点:要做视觉-语言对齐,BEiT 视觉侧 + BERT 文本侧 + 1 个对比目标即可起手(这是后来 BEiT-3 的雏形)。
- AIGC 的先验水:Stable Diffusion、SDXL 的 inpainting / class-condition controlnet 都用 BEiT-style MIM 预训练权重作 control encoder。
- 数据扩展自然友好: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 在生产系统中的典型接入路径:
-
预训练权重获取:从 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 链接失效问题。 -
下游 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 ) -
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 设定兼容 -
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)