wikillm

Paper · 2023-07-18 · cs.CV

RepViT: Revisiting Mobile CNN From ViT Perspective

RepViT modernises MobileNetV3-L with design choices from lightweight ViTs: split token and channel mixers, a 2x-expansion FFN, a convolutional stem, deeper downsampling, cross-block SE, and re-parameterised depthwise convs. Author-reported: 80.0% ImageNet top-1 at 1.0 ms on iPhone 12 (RepViT-M1.0, distilled) and 83.7% at 2.3 ms (RepViT-M2.3).

Efficient vision backbonesConvolutional neural networkVision Transformer (ViT) backbonesKnowledge distillationefficient-visionmobile-inferencecnnreparameterization

arXivPDFCodeMarkdown11 min read

AI-compiled by claude-haiku-5-5 on 2026-10-19, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.

In plain words

Small image models for phones come in two families: convolutional networks (CNNs) and Vision Transformers (ViTs). Recently, small ViTs have matched or beaten small CNNs on accuracy and speed on phones. The authors ask whether the design choices behind those ViTs can be brought back into a plain CNN.

They start from MobileNetV3, a well-known small CNN, and change it step by step. Each change borrows a layout choice from the small ViTs: the spatial mixing and the per-pixel mixing become separate steps, and the network gets a different stem, a deeper downsampling step and a simpler classifier. The result, RepViT, is a family of pure CNNs that the authors report beat small ViTs on latency and accuracy on a phone.

The main point for an engineer: how many operations a model has does not predict its speed on a phone well, so the paper measures latency on the device.

TL;DR

  • RepViT is a family of pure CNNs built from a MobileNetV3-L starting point by adopting lightweight-ViT layout choices §3.
  • The core block separates the spatial token mixer (a re-parameterised depthwise conv) from the channel mixer (an FFN with expansion 2) §3.2.
  • Author-reported ImageNet-1K top-1 with distillation: 78.7% (M0.9, 0.9 ms) to 83.7% (M2.3, 2.3 ms) on iPhone 12 with Core ML tab. 1.
  • Dense prediction and SAM results are also reported, with latencies on phone and laptop hardware §4.2 §4.3.
  • Several architecture details exist only in the supplementary material (not part of our source); the released code fills most of them in (see Paper vs code).

Problem

Lightweight ViTs beat lightweight CNNs on accuracy and latency on mobile devices, and the usual explanation is global self-attention §1 §2. The architectural differences between lightweight ViTs and lightweight CNNs, in the block structure and in the macro and micro design, were not examined closely §1. FLOPs and model size correlate poorly with measured on-device latency §3.1, so the paper measures latency directly.

Assumptions: all models are trained on ImageNet-1K at 224x224 §4.1; latency is measured on an iPhone 12 (iOS 16) compiled with Core ML Tools at batch size 1 §3.1 §4.1.

Method

The paper starts from MobileNetV3-L and changes it in five groups, each cited to the section where it is introduced §3.2–§3.5:

  1. Training recipe: align the baseline with the lightweight-ViT recipe (DeiT style, with distillation excluded for now) §3.1.
  2. Block design: split token mixer and channel mixer, re-parameterise the depthwise conv, expansion ratio 2, widths doubling per stage §3.2.
  3. Macro design: two-conv stem, deeper downsampling, a simple classifier, stage ratio change §3.3.
  4. Micro design: 3x3 kernels only, cross-block SE placement §3.4.
  5. Network family: RepViT-M0.9, M1.0, M1.1, M1.5, M2.3, where the suffix is the latency in ms on iPhone 12 §3.5.

The paper gives no numbered equations and no numbered algorithms. The pseudocode below is our reading of the layout in the text, checked against the released code repvit.py.

Pseudocode
# RepViT block, stride 1  [§3.2]
# Input x: (B, C, H, W); channel mixer expansion 2  [§3.2]
def repvit_block_stride1(x, use_se):
    # Token mixer: depthwise 3x3 and depthwise 1x1 branches plus the
    # identity, summed then batch-normalised  [§3.2]
    # [code: model/repvit.py#L83-L92]
    mixed = batch_norm(dw_3x3(x) + dw_1x1(x) + x)
    # Optional squeeze-and-excitation, placed after the token mixer  [§3.4]
    # [code: model/repvit.py#L149]
    if use_se:
        mixed = squeeze_excite(mixed)
    # Channel mixer: pointwise expand to 2C, GELU, pointwise back to C,
    # residual add  [§3.2]  [code: model/repvit.py#L151-L157]
    hidden = gelu(conv1x1_bn(mixed, out_channels=2 * C))
    return mixed + conv1x1_bn(hidden, out_channels=C, init_gamma=0)
Pseudocode
# RepViT block, stride 2 (downsampling)  [§3.3]
# Depthwise stride-2 conv changes resolution, then a 1x1 conv changes channels
def repvit_block_stride2(x, out_channels, use_se):
    # Depthwise 3x3, stride 2, with BN  [§3.3]
    # [code: model/repvit.py#L133-L136]
    x = batch_norm(dw_3x3_stride2(x))
    # Optional squeeze-and-excitation  [code: model/repvit.py#L135]
    if use_se:
        x = squeeze_excite(x)
    # Pointwise 1x1 conv sets the new channel count  [§3.3]
    x = conv1x1_bn(x, out_channels=out_channels)
    # FFN with expansion 2 after the 1x1, residual  [§3.3]
    # [code: model/repvit.py#L138-L143]
    hidden = gelu(conv1x1_bn(x, out_channels=2 * out_channels))
    return x + conv1x1_bn(hidden, out_channels=out_channels, init_gamma=0)
Pseudocode
# RepViT network  [§3.3] [§3.5]  [code: model/repvit.py#L218-L243]
# image: (B, 3, 224, 224); configs: one row per block (kernel, expansion,
# channels, SE flag, activation flag, stride)
def repvit(image, configs, channels):
    # Stem: two stride-2 3x3 convs with GELU between  [§3.3]
    # first conv has channels/2 filters (24 for M0.9)  [§3.3]
    x = conv3x3_bn_stride2(image, channels // 2)
    x = gelu(x)
    x = conv3x3_bn_stride2(x, channels)
    # Stacked blocks, stride-1 blocks and stride-2 blocks  [§3.2] [§3.3]
    for block_config in configs:
        x = repvit_block(x, block_config)
    # Head: global average pool, then batch norm and linear  [§3.3]
    # (the paper says linear only; the code adds a BN first)
    # [code: model/repvit.py#L163-L186]
    pooled = global_average_pool(x)
    return bn_linear(pooled)

Re-parameterisation: during training the depthwise branches and the identity are separate; at inference they fold into one 3x3 depthwise conv §3.2 repvit.py. The paper says the skip connection cost is removed at inference §3.2.

Distillation (used for the headline numbers): the student gets two heads, one for the labels and one for the teacher. The loss mixes both with weight alpha losses.py. The paper states the teacher only §4.1.

L = (1 - \alpha)\, L_{\text{base}} + \alpha\, L_{\text{kd}} losses.py, with alpha = 0.5 and, for the hard variant, L_kd = cross-entropy against the teacher's argmax losses.py main.py. This formula is not in the paper.

Hyperparameters

Values marked "paper" are stated in the paper. Values marked "code" are the defaults of the released training script; the paper defers the full recipe to its supplementary material, which is not in our source. Code values were not confirmed against the paper.

NameValueWhereNotes
input resolution224 x 224, train and test§4.1paper
epochs300 or 450§4.1 tab. 1paper; 450 is the second column of tab. 1
optimizerAdamW§3.1 main.pypaper states AdamW for the DeiT-style recipe; code default
LR schedulecosine§3.1 main.pypaper; code default
base learning rate1e-3, scaled as lr x batch x GPUs / 512main.py main.pycode only; not stated in paper
warmup5 epochsmain.pycode only
minimum LR1e-5main.pycode only
weight decay0.025main.pycode only
batch size256 (per process)main.pycode only; global size under 8 GPUs not stated
EMA of weightson, decay 0.99996main.pycode only
gradient clippingAGC, 0.02main.pycode only
label smoothing0.1main.pycode only; paper names label smoothing §3.1
mixup / cutmix alpha0.8 / 1.0; switch prob 0.5main.pycode only
random erasingp = 0.25, pixel modemain.pycode only
auto-augmentrand-m9-mstd0.5-inc1main.pycode only; paper names auto-augment §3.1
colour jitter0.4main.pycode only
interpolationbicubicmain.pycode only
distillation teacherRegNetY-16GF, 82.9% top-1§4.1paper
teacher in coderegnety_160main.pycode default; not the same name as the paper
distillation typehard, alpha 0.5main.pycode only; paper does not say hard or soft
stem3x3 stride-2 convs, 24 and 48 filters (M0.9)§3.3 repvit.pypaper and code agree
channel-mixer expansion2§3.2paper; code uses t = 2 in every config
stage widths (M0.9)48, 96, 192, 384§3.2 repvit.pypaper and code agree
kernel size3x3 in all blocks§3.4paper
SE reduction ratio0.25repvit.py repvit.pycode only; not stated in paper
stage ratio1:1:7:1; depth 2:2:14:2§3.3paper; conflicts with code, see Paper vs code
latency deviceiPhone 12, iOS 16, Core ML Tools, batch 1§3.1 §4.1paper
throughput deviceRTX 3090, largest power-of-two batch that fitstab. 1 captionpaper
SAM encoder trainingRepViT-M2.3, 8 epochs, 1% of SA-1B§4.2paper
detection / segmentationMask R-CNN on COCO 2017; Semantic FPN on ADE20K§4.3paper; schedules not stated in the paper body

Model configs (per block: kernel, expansion, channels, SE, activation, stride) are in repvit.py for M0.9, repvit.py for M1.0, repvit.py for M1.1, repvit.py for M1.5 and repvit.py for M2.3. The paper refers to its supplementary for these tables §3.5; the supplementary is not in our source.

Results

Author-reported. ImageNet-1K, 224 x 224, latency on iPhone 12 with Core ML §4.1. Table 1 reports the models trained with distillation; Table 2 reports them without §4.1.

ModelLatency (ms)Top-1 (300 / 450 ep)Params (M)GMACsSource
RepViT-M0.90.978.7 / 79.15.10.8tab. 1
RepViT-M1.01.080.0 / 80.36.81.1tab. 1
RepViT-M1.11.180.7 / 81.28.21.3tab. 1
RepViT-M1.51.582.3 / 82.514.02.3tab. 1
RepViT-M2.32.383.3 / 83.722.94.5tab. 1
FastViT-T8 (baseline)0.976.7 (300)3.60.7tab. 1
EfficientFormerV2-S0 (baseline)0.975.7 / 76.23.50.4tab. 1
EfficientFormerV2-S1 (baseline)1.179.0 / 79.76.10.7tab. 1
EfficientFormerV2-S2 (baseline)1.681.6 / 82.012.61.3tab. 1
EfficientFormerV2-L (baseline)2.783.3 / 83.526.12.6tab. 1

Without distillation (300 epochs) tab. 2: RepViT-M0.9 77.4% at 0.9 ms, M1.0 78.6% at 1.0 ms, M1.1 79.4% at 1.1 ms, M1.5 81.2% at 1.5 ms, M2.3 82.5% at 2.3 ms. The paper reports, at similar latency, MobileOne-S1 75.9% (0.9 ms), FastViT-T8 75.6% (0.9 ms) and EfficientFormerV2-S0 73.7% (0.9 ms) tab. 2.

Step-by-step ablation on ImageNet-1K, each row adding one change to the previous one. Values are as stated in the text; the row for the classifier gives only the drop §3.1–§3.4 fig. 2:

ChangeTop-1 (%)Latency (ms)Source
MobileNetV3-L with the aligned recipe71.51.01§3.1
RepViT block (split mixers, reparam DW)68.30.81§3.2
Expansion 2 and doubling widths73.50.89§3.2
Early convolutions as stem73.90.86§3.3
Deeper downsampling75.40.96§3.3
Simple classifier-0.6 (from previous)0.77§3.3
Stage ratio 1:1:7:1, depth 2:2:14:276.90.91§3.3
3x3 convs only76.90.89§3.4
Cross-block SE placement (= RepViT)77.40.87§3.4

Ablations on the RepViT block tab. 6 tab. 7:

SettingResultSource
Without structural re-parameterisation, M0.9 / M1.5 / M2.378.47 / 82.09 / 83.10 %tab. 6
With structural re-parameterisation78.74 / 82.29 / 83.30 %tab. 6
SE removed, M0.9 top-1 / latency77.92% / 0.83 mstab. 7
SE in every block, M0.9 top-1 / latency78.75% / 0.92 mstab. 7
SE cross-block (ours), M0.9 top-1 / latency78.74% / 0.87 mstab. 7

Downstream, backbone latency at 512 x 512 on iPhone 12 tab. 5: RepViT-M1.1 (4.9 ms) gives 39.8 AP-box, 37.2 AP-mask and 40.6 mIoU, against EfficientFormer-L1 (5.4 ms) at 37.9, 35.4 and 38.9. RepViT-M2.3 (9.9 ms, with 450-epoch ImageNet init) gives 44.6, 40.8 and 46.1, against EfficientFormerV2-L (18.2 ms) at 44.7, 40.4 and 45.2 tab. 5.

RepViT-SAM (RepViT-M2.3 as the SAM image encoder) §4.2 tab. 3 tab. 4:

SettingRepViT-SAMMobileSAMViT-B-SAMSource
Encoder latency, iPhone 12 (1024 x 1024)48.9 msOOMOOMtab. 3
Encoder latency, MacBook M1 Pro44.8 ms482.2 ms6249.5 mstab. 3
Zero-shot edge ODS / OIS / AP.764 / .786 / .773.756 / .768 / .746.743 / .764 / .726tab. 4
Zero-shot instance AP / SegInW mean AP44.4 / 46.142.7 / 43.942.5 / 44.8tab. 4

The paper calls RepViT-SAM "nearly 10x faster" than MobileSAM on MacBook M1 Pro §4.2; the table ratio is 482.2 / 44.8 = 10.8.

Paper vs code

Repository: the link is in the abstract, so no further search was needed. The owner is THU-MIG, and the README lists the paper's five authors. Code read at commit 298f42075eda5d2e6102559fad260c970769d34e. The main code paths are model/repvit.py, main.py, losses.py, logs/ and README.md. The detection, segmentation and SAM sub-projects were not checked against the paper in this card.

  • Stage depth. Paper: stage ratio 1:1:7:1, depth 2:2:14:2 §3.3. Code: the M0.9 config has 3, 4, 16 and 3 blocks per stage, where each stage after the first starts with its stride-2 block repvit.py. How the paper counts depth is not stated, so this is unresolved.
  • Head. Paper: global average pooling and a linear layer §3.3. Code: a BatchNorm1d before the linear layer repvit.py. For the distillation model, the two heads' logits are averaged at evaluation repvit.py.
  • SE placement. Paper: SE in the 1st, 3rd, 5th... block of each stage §3.4. Code: the M1.5 first stage has SE on blocks 1 and 3 [code: model/repvit.py#L391-L395], which matches; the M0.9 first stage has SE on block 1 only repvit.py, which does not.
  • Activation flag. The config's HS column selects between two identical nn.GELU() calls, so it has no effect repvit.py [code: model/repvit.py#L154]. The paper says GELU is used throughout §3.1.
  • Distillation. Paper: teacher RegNetY-16GF §4.1. Code default: regnety_160 main.py. Code also uses hard-label distillation [code: main.py#L137-L140] losses.py; the paper does not say which.
  • Learning rate. Paper: not stated. Code: 1e-3 scaled by batch x GPUs / 512 main.py. The shipped 300-epoch M0.9 log peaks at about 3.0e-3 repvit_m0_9_distill_300e.txt. Under the scaling rule that corresponds to 6 GPUs, not the 8 in the README README.md — the reason is not stated.
  • Reported accuracy. Table 1 gives 78.7% for M0.9 at 300 epochs tab. 1. The shipped log's final evaluation (epoch 299) gives 78.58% [code: logs/repvit_m0_9_distill_300e.txt#L300].
  • Parameter count. Table 1 gives 5.1M for M0.9 tab. 1. The shipped log reports n_parameters = 5,489,328 for the training model, which includes the distillation head repvit_m0_9_distill_300e.txt. The 5.1M figure is presumably the fused inference model; the paper does not say.
  • Extra variant. The code defines RepViT-M0.6, which is not in this paper repvit.py. The README reports it separately README.md.

Pitfalls

  • Missing supplementary. The architecture tables and full training details are in the supplementary material §3.5, which is not in our source. The configs and recipe here come from the code, so they carry the code's status, not the paper's.
  • Latency is device- and toolchain-specific. Numbers come from Core ML on iPhone 12 with iOS 16 and Xcode's tool §3.1 README.md. Other devices, runtimes or Core ML versions may rank models differently.
  • Throughput is a separate metric. Table 1 throughput uses an RTX 3090 with the largest power-of-two batch that fits tab. 1 caption. It is not latency.
  • Distillation changes the headline. Table 1 numbers use distillation from a RegNet teacher. Table 2 gives the no-distillation numbers, which are 1 to 2 points lower for the same model tab. 2.
  • Re-parameterisation is a deployment step. The training form has separate depthwise branches and BN; the inference form is a single depthwise conv. The latency numbers assume the inference form §3.2. The code has fuse() methods for it repvit.py repvit.py.
  • Last FFN norm starts at zero. The last BN of each FFN is initialised to zero, so each residual branch starts as identity repvit.py repvit.py. The paper does not mention this.
  • Ambiguous SE pattern. "1st, 3rd, 5th" is the paper's wording §3.4, but the released configs vary by variant and stage. Copy the config table from the code, not the rule in the text.
  • Speed claims are relative. The "10x" SAM claim compares against MobileSAM on a laptop §4.2. On a phone, only RepViT-SAM ran at all, since the other two returned OOM tab. 3.
  • Ablation noise. Re-parameterisation gains are 0.1 to 0.3 points on single runs tab. 6. No variance across seeds is reported.

Lineage

  • Builds on: MobileNetV3-L as the starting point §3; the separated token and channel mixers from MetaFormer-style designs §3.2; structural re-parameterisation from RepVGG §3.2. None of these has a card in this wiki.
  • Compared against: EfficientFormerV2 (in this wiki) and EfficientFormer, FastViT, MobileOne and MobileSAM, which have no cards tab. 1 tab. 3.
  • Superseded by: none known from content in this wiki.

Source and license

Adapted from “RepViT: Revisiting Mobile CNN From ViT Perspective” by Ao Wang, Hui Chen, Zijia Lin, Jungong Han, Guiguang Ding (arXiv:2307.09283), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/THU-MIG/RepViT at commit 298f42075eda (Apache-2.0). Any quoted code is shown under that license.