Paper · 2022-10-13 · cs.CV
RTFormer: Efficient Design for Real-Time Semantic Segmentation with Transformer
RTFormer is a dual-resolution real-time segmentation network. Its low-resolution branch uses GPU-Friendly Attention, a linear attention without the multi-head split, and its high-resolution branch uses cross-resolution attention over pooled low-resolution tokens. Author-reported: 79.3 mIoU (val) on Cityscapes at 39.1 FPS (Base) and 76.3 at 110.0 FPS (Slim).
Semantic segmentationCNN-Transformer hybridLinear attentionMulti-scale feature fusionsemantic-segmentationreal-timetransformerlinear-attentioncross-attentiondual-resolutioncityscapescamvidade20kcocostuff
arXivPDFCodeMarkdown17 min read
AI-compiled by claude-haiku-5-5 on 2026-11-08, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
Real-time segmentation labels every pixel of a video frame fast enough for a car or a phone. The fastest systems are convolutional networks. Transformers see far across an image, which helps, but their usual attention is slow on the graphics chips that run these systems.
RTFormer keeps two copies of the picture in its middle layers: a detailed high-resolution copy and a coarse, low-resolution copy. The coarse copy gets a cheap attention step that is friendly to graphics chips. The detailed copy then looks up the big-picture summary from the coarse copy, so each detailed pixel knows about the whole scene without a costly full attention. The early layers are plain convolutions. The authors report that this gives a better speed-accuracy trade-off than earlier real-time models on the benchmarks they test.
TL;DR
- RTFormer is a real-time semantic segmentation network with two resolution branches. Its building block combines a linear-cost attention on the low-resolution branch with cross-resolution attention that feeds global context to the high-resolution branch §3.1.
- Early stages are convolutional. The last two stages use the RTFormer block §3.2.
- Author-reported: RTFormer-Base reaches 79.3% val mIoU on Cityscapes at 39.1 FPS, and RTFormer-Slim 76.3% at 110.0 FPS, on one RTX 2080Ti tab. 2.
- The released PaddleSeg code differs from the paper in several training details, and the cross-attention scale differs from the paper's equation rtformer.py. See Paper vs code.
Problem
Transformers capture long-range context, which semantic segmentation needs §1. But the quadratic cost of standard self-attention, and the multi-head split that breaks a large matrix product into many small ones, both slow inference on GPU-like hardware §1. Earlier segmentation transformers reduce keys and values, or work only at high resolution, and still keep these costs §1 §2. The paper argues that, for real-time use on such devices, CNNs still dominate the state of the art §1.
Method
The network has two parts: a block that runs two resolution branches in a stepped layout §3.1, and a backbone built from that block with a segmentation head §3.2.
Stages and branches. The stem is two 3×3 convolutions §3.2. Stages 1 and 2 are residual blocks. From stage 3 on, the network runs a high-resolution branch at stride 8 next to a low-resolution branch at stride 16, then 32, and the two exchange features §3.2. The paper says stage 3 is still built from residual blocks, while stages 4 and 5 use the RTFormer block §3.2 fig. 4.
RTFormer block. The low-resolution branch runs GPU-Friendly Attention, then an FFN §3.1. The result is added, after compression and upsampling, into the high-resolution branch. The high-resolution branch then runs cross-resolution attention, whose keys and values come from the low-resolution branch, followed by its own FFN §3.1 fig. 2. The paper calls this a stepped layout: the low branch is computed first so that its output can feed the high branch §3.1. When the injection flag is on, the released code also feeds high-resolution features back into the low branch after each block; the paper does not describe this step (see Paper vs code). The pseudocode follows the code's order. The paper gives the stepped order only in outline rtformer.py.
# RTFormer block: one stage with two branches [§3.1] [fig. 2]
# Input: x_h (B, C_h, H, W) at stride 8; x_l (B, C_l, H/16, W/16)
# Output: x_h at stride 8; x_l at stride 16 or 32
# Order follows the code [code: paddleseg/models/rtformer.py#L544-L577]
def rtformer_block(x_h, x_l):
# 1. Low branch: GPU-Friendly Attention, with residual [§3.1] [eq. 3]
x_l = x_l + gfa(x_l) # (B, C_l, h, w)
# 2. Low branch: FFN of two 3x3 convs, no width expansion [§3.1]
x_l = x_l + ffn(x_l)
# 3. Stepped layout: add upsampled low branch into high branch [§3.1]
x_h = x_h + upsample(compress(x_l)) # 1x1 conv, then bilinear
# 4. High branch: cross-resolution attention [§3.1] [eq. 4]
cross_keys, cross_values = cross_kv(x_l) # pool to s x s, then 1x1 conv
x_h = x_h + cross_attention(x_h, cross_keys, cross_values)
# 5. High branch: FFN [§3.1]
x_h = x_h + ffn(x_h)
# 6. Feed high-resolution features back to the low branch [code only]
x_l = x_l + inject(x_h) # two stride-2 3x3 convs
return x_h, x_lGPU-Friendly Attention (GFA). It starts from external attention, which applies a double normalization to the product of tokens and learned keys, then multiplies by learned values §3.1 eq. 1. Multi-head external attention splits its matrix products into groups; GFA removes that split §3.1 fig. 3. It keeps one large product, enlarges the set of learned keys and values, and replaces the second normalization by a grouped one that splits the keys into groups §3.1 eq. 3.
# GPU-Friendly Attention (low branch) [§3.1] [eq. 3]
# Input: x (B, N, d), N = h*w tokens
# Learned keys and values: (M_g, d); the groups count is set per branch
def gfa(x, keys, values, groups):
# 1. Similarity of every token with every learned key [eq. 3]
scores = x @ keys.T # (B, N, M_g)
# 2. First normalization: softmax over the tokens [§3.1]
attn = softmax(scores, axis_tokens) # (B, N, M_g)
# 3. Second normalization: per token, sum over the keys of each group
attn = attn / (group_sum(attn, groups) + 1e-6) # eps: code only
# 4. Weighted sum of the learned values [eq. 3]
return attn @ values # (B, N, d)Cross-resolution attention (CA). The high-resolution tokens are the queries. The keys and values are computed from the low-resolution features, which are pooled to a fixed spatial size and projected §3.1 eq. 4. CA uses a single softmax over the pooled tokens and no multi-head split, because the keys and values are not learned parameters §3.1. The pooled size is the main knob: 8×8 for Slim and 12×12 for Base tab. 1.
# Cross-resolution attention (high branch) [§3.1] [eq. 4]
# x_h: (B, N_h, C_h) queries from the high branch
# cross_keys, cross_values: (B, s*s, C_h) from the pooled low branch
def cross_attention(x_h, cross_keys, cross_values):
# 1. Similarity of every high-resolution token with every pooled token
scores = x_h @ cross_keys.transpose(0, 2, 1) # (B, N_h, s*s)
# 2. Scale. The paper divides by sqrt(d_h); the code divides by
# sqrt(s*s) instead. See Paper vs code.
scores = scores / sqrt(C_h)
# 3. Softmax over the pooled tokens; no multi-head split [§3.1]
attn = softmax(scores, axis_pooled_tokens)
# 4. Weighted sum of the pooled values
return attn @ cross_values # (B, N_h, C_h)FFN. The FFN is two 3×3 convolutions with no expansion of the hidden width. A typical transformer FFN uses two MLP layers with a 2× or 4× expansion plus a depth-wise 3×3 convolution. The paper reports that its FFN is both faster and more accurate in its ablation §3.1 tab. 5.
Segmentation head. The low-resolution output goes through a DAPPM module, a pyramid-pooling module borrowed from DDRNet §3.2. Its output is fused with the high-resolution feature to give a stride-8 map. A classification head with a 3×3 convolution and a 1×1 convolution then predicts the labels, with the hidden width equal to the input width §3.2. The release also adds an auxiliary head on the stride-8 stage-3 feature, which the paper does not mention rtformer.py rtformer.py.
Variants. RTFormer-Slim and RTFormer-Base differ in the base width (32 vs 64 channels) and the pooled size, as in tab. 1 §3.2. The architecture description is given in §3.2; the released configs set the head widths and the injection flags per dataset (see Hyperparameters).
Key equations. External attention, multi-head external attention, GFA and CA, as printed eq. 1 eq. 2 eq. 3 eq. 4:
EA(X, K, V) = DN(X \cdot K^{T}) \cdot V eq. 1
MHEA(X) = Concat(h_1, \dots, h_H), \quad h_i = EA(X_i, K', V') eq. 2
GFA(X, K_g, V_g) = GDN(X \cdot K_g^{T}) \cdot V_g eq. 3
CA(X_h, K_c, V_c) = Softmax\left(\frac{X_h \cdot K_c^{T}}{\sqrt{d_h}}\right) \cdot V_c eq. 4
K_c, V_c = \phi(X_c), \quad X_c = \theta(X_l) eq. 4
Here X is an N×d input with N elements, K and V are learned M×d matrices, DN is double normalization, and H is the head count §3.1 eq. 1 eq. 2. K_g and V_g have M_g rows, with GDN as the grouped version of DN §3.1 eq. 3. φ is a set of splits, permutations and reshapes, θ is pooling and convolution, and d_h is the high-branch width §3.1 eq. 4. The paper states M_g = M×H in the main text §3.1 and M_g = d in the appendix app. B.1. The released code follows the second (see Paper vs code).
Hyperparameters
Paper defaults are in the first table; the released configuration values are cited to code. Where the two differ, both are listed and the conflict is in Paper vs code.
Architecture
| Name | Value | Where | Notes |
|---|---|---|---|
| Stem | two 3×3 convs, stride 2 each | §3.2 rtformer.py | |
| Stages | 5; RTFormer block in stages 4 and 5 | §3.2 fig. 4 | stage 3 keeps residual blocks |
| Blocks per stage (high, low) | [2, 2, 1/2, 1, 1] | tab. 1 | the last two are RTFormer blocks |
| Channels, Slim | [32, 64, 64/128, 64/256, 64/256] | tab. 1 rtformer_slim_cityscapes_1024x512_120k.yml | high/low branch widths |
| Channels, Base | [64, 128, 128/256, 128/512, 128/512] | tab. 1 rtformer_base_cityscapes_1024x512_120k.yml | |
| Pooled cross size, Slim | 8×8 (64 tokens) | tab. 1 §3.2 | Slim Cityscapes config does not set it (code default 12) |
| Pooled cross size, Base | 12×12 (144 tokens) | tab. 1 §3.2 rtformer.py | |
| Head width | 2× head_channels (= 4C in the configs) | rtformer.py | paper: hidden width equals input width §3.2 |
| Head channels, Base / Slim | 128 / 64 | rtformer_base_cityscapes_1024x512_120k.yml rtformer_slim_cityscapes_1024x512_120k.yml | |
| Injection high→low, Cityscapes | Base [True, False]; Slim [True, True] | rtformer_base_cityscapes_1024x512_120k.yml rtformer_slim_cityscapes_1024x512_120k.yml | not in paper |
| Injection high→low, ADE20K | Base and Slim [True, False] | rtformer_base_ade20k_512x512_160k.yml rtformer_slim_ade20k_512x512_160k.yml | not in paper |
| Attention groups, low branch | 8 | app. B.1 rtformer.py | no config overrides it |
| High-branch groups | 2 in the ablation's GFA+GFA setting; no split in CA | app. B.1 §3.1 | the main model uses CA only |
| Drop path | not stated for segmentation | rtformer.py | code default 0.2; ADE20K configs 0.1 |
| DAPPM pooling | not stated | rtformer.py | code: average pools with kernel/stride 5/2, 9/4, 17/8, and global |
| DAPPM width | not stated | rtformer.py | code: 128 |
| Auxiliary head | not stated | rtformer.py | code: loss weight 0.4 |
Cityscapes training (paper §4.1; configs in configs/rtformer/)
| Name | Value | Where | Notes |
|---|---|---|---|
| Optimizer | AdamW, β1 0.9, β2 0.999 | §4.1 rtformer_base_cityscapes_1024x512_120k.yml | paper names AdamW only |
| Learning rate | 4e-4 | §4.1 rtformer_base_cityscapes_1024x512_120k.yml | |
| Weight decay | 0.0125 | §4.1 rtformer_base_cityscapes_1024x512_120k.yml | |
| Poly power | 0.9 (paper) / 1.0 (code) | §4.1 rtformer_base_cityscapes_1024x512_120k.yml | conflict |
| LR end | not stated (paper) / 1e-6 (code) | rtformer_base_cityscapes_1024x512_120k.yml | |
| Warmup | not stated (paper) / 1500 iters from 1e-6 (code) | rtformer_base_cityscapes_1024x512_120k.yml | warmup shape not checked |
| Iterations | about 120K (484 epochs) | §4.1 rtformer_base_cityscapes_1024x512_120k.yml | |
| Batch size | 12 total on four V100 (paper); 3 per GPU × 4 (code) | §4.1 rtformer_base_cityscapes_1024x512_120k.yml | |
| Sync BN | yes | §4.1 train.py | |
| Crop | 512×1024 (paper); [1024, 512] (code) | §4.1 rtformer_base_cityscapes_1024x512_120k.yml | code order is width×height (inferred, see Pitfalls) |
| Random scale | 0.5 to 2.0 | §4.1 rtformer_base_cityscapes_1024x512_120k.yml | |
| Horizontal flip | yes | §4.1 rtformer_base_cityscapes_1024x512_120k.yml | |
| Colour jitter | not stated for Cityscapes (paper); brightness, contrast and saturation 0.4 (code) | rtformer_base_cityscapes_1024x512_120k.yml | |
| OHEM | not used | §4.1 | |
| Loss | cross-entropy; auxiliary weight 0.4 | rtformer_base_cityscapes_1024x512_120k.yml | auxiliary head not in paper |
| Pretraining | ImageNet backbone | §4.1 rtformer_base_cityscapes_1024x512_120k.yml | weights fetched from a URL |
CamVid training (paper only; no RTFormer CamVid config in the repository) §4.1
| Name | Value | Notes |
|---|---|---|
| Learning rate | 0.001 | |
| Weight decay | 0.05 | |
| Poly power | 1.0 | |
| Epochs | 968 | |
| Training data | train and validation merged (367 + 101 frames) | test: 233 frames at 720×960 |
| Crop | 720×960 | scale range [288, 1152] |
| Augmentation | colour jitter, horizontal flip, random crop and scale | no Cityscapes pretraining |
ADE20K training (paper §4.1; configs rtformer_*_ade20k_512x512_160k.yml)
| Name | Value | Where | Notes |
|---|---|---|---|
| Batch size | 16 total (paper); 4 per GPU × 4 (code) | §4.1 rtformer_base_ade20k_512x512_160k.yml | |
| Iterations | 160K | §4.1 rtformer_base_ade20k_512x512_160k.yml | |
| Learning rate | 1e-4 | §4.1 rtformer_base_ade20k_512x512_160k.yml | |
| Weight decay | 0.05 | §4.1 rtformer_base_ade20k_512x512_160k.yml | |
| Crop | "identical to Cityscapes" (paper) vs [512, 512] (code) | rtformer_base_ade20k_512x512_160k.yml | conflict |
| Poly power, end LR | 1.0 and 1e-7 (code) | rtformer_base_ade20k_512x512_160k.yml | paper says power follows Cityscapes (0.9) |
| Validation resize | 2048×512, keep ratio, divisor 32 | rtformer_base_ade20k_512x512_160k.yml | |
| Drop path | not stated (paper) / 0.1 (code) | rtformer_base_ade20k_512x512_160k.yml | |
| Slim cross size | 8 (code) | rtformer_slim_ade20k_512x512_160k.yml | matches tab. 1 |
COCOStuff training (paper only; no RTFormer config in the repository) §4.1
| Name | Value |
|---|---|
| Epochs | 110 |
| Optimizer | AdamW |
| Learning rate, weight decay | 1e-4, 0.05 |
| Train resize and crop | short side 640, random 640×640 crop |
| Test resize | 640×640 |
Ablation training (paper only) §4.4 app. B.1: RTFormer-Slim trained from scratch with learning rate 0.001, other settings as on ADE20K. No ablation configs in the repository.
ImageNet pretraining (paper, appendix only; the recipe is not in this repository) app. A tab. 6
| Name | Value |
|---|---|
| Optimizer | AdamW, β 0.9 / 0.999 |
| Base learning rate, weight decay | 5e-4, 0.04 |
| Batch size, epochs | 1024, 300 |
| Schedule | cosine decay to 5e-6; 5 warmup epochs from 5e-7 |
| Augmentation | RandAugment(9, 0.5), colour jitter 0.4, mixup 0.2, cutmix 1.0, random erasing 0.25 |
| Drop path, EMA | 0.0, 0.9999 |
Results
Author-reported. Setup: semantic segmentation on Cityscapes (val, single crop 1024×2048), CamVid (test, 720×960), ADE20K (val, 512×2048 for FLOPs and FPS), and COCOStuff (test, 640×640) tab. 2 tab. 3 tab. 4. FPS is measured on one RTX 2080Ti without TensorRT by default §4.1. Baselines are taken from their papers unless marked, with * for retrained models and † for FPS measured by the authors tab. 2 tab. 3.
Headline numbers
| Dataset | Model | Metric | Value | Source |
|---|---|---|---|---|
| Cityscapes val | RTFormer-Base | mIoU / FPS | 79.3 / 39.1 | tab. 2 |
| Cityscapes val | RTFormer-Slim | mIoU / FPS | 76.3 / 110.0 | tab. 2 |
| CamVid test | RTFormer-Base | mIoU / FPS | 82.5 / 94.0 | tab. 2 |
| CamVid test | RTFormer-Slim | mIoU / FPS | 81.4 / 190.7 | tab. 2 |
| ADE20K val | RTFormer-Base | mIoU / FPS | 42.1 / 71.4 | tab. 3 |
| ADE20K val | RTFormer-Slim | mIoU / FPS | 36.7 / 187.9 | tab. 3 |
| COCOStuff test | RTFormer-Base | mIoU / FPS | 35.3 / 143.3 | tab. 4 |
| ImageNet val, 224 px | RTFormer-Base / Slim | top-1 | 77.4 / 72.3 | app. A tab. 7 |
Table 2: Cityscapes and CamVid tab. 2. Columns: Cityscapes FPS and val mIoU; CamVid FPS and test mIoU. Blank cells are not reported. † FPS measured by the authors on one RTX 2080Ti. * retrained by the authors.
| Method | Encoder | Params | GPU | Cityscapes FPS | Cityscapes val | CamVid FPS | CamVid test |
|---|---|---|---|---|---|---|---|
| ICNet | - | - | TitanX M | 30.3 | 67.7 | 27.8 | 67.1 |
| DFANet A | Xception A | 7.8M | TitanX | 100.0 | - | 120.0 | 64.7 |
| DFANet B | Xception B | 4.8M | TitanX | 120.0 | - | 160.0 | 59.3 |
| CAS | - | - | TitanX | 108.0 | 71.6 | 169.0 | 71.2 |
| GAS | - | - | TitanX | 108.4 | 72.4 | 153.1 | 72.8 |
| DF1-Seg-d8 | DF1 | - | GTX 1080Ti | 136.9 | 72.4 | - | - |
| DF1-Seg | DF1 | - | GTX 1080Ti | 106.4 | 74.1 | - | - |
| DF2-Seg1 | DF2 | - | GTX 1080Ti | 67.2 | 75.9 | - | - |
| DF2-Seg2 | DF2 | - | GTX 1080Ti | 56.3 | 76.9 | - | - |
| BiSeNet1 | Xception39 | 5.8M | GTX 1080Ti | 105.8 | 69.0 | 175.0 | 65.6 |
| BiSeNet2 | ResNet18 | 49.0M | GTX 1080Ti | 65.5 | 74.8 | 116.3 | 68.7 |
| BiSeNetV2 | - | - | GTX 1080Ti | 156.0 | 73.4 | 124.5 | 72.4 |
| BiSeNetV2-L | - | - | GTX 1080Ti | 47.3 | 75.8 | 32.7 | 73.2 |
| SFNet | ResNet18 | 12.9M | RTX 2080Ti | - | - | 62.9† | 73.8 |
| FasterSeg | - | 4.4M | RTX 2080Ti | 136.2† | 73.1 | - | 71.1 |
| STDC1-Seg75 | STDC1 | 14.2M | RTX 2080Ti | 74.6† | 74.5 | - | - |
| STDC2-Seg75 | STDC2 | 22.2M | RTX 2080Ti | 73.5† | 77.0 | - | - |
| STDC1-Seg | STDC1 | 14.2M | RTX 2080Ti | - | - | 125.6† | 73.0 |
| STDC2-Seg | STDC2 | 22.2M | RTX 2080Ti | - | - | 100.5† | 73.9 |
| DDRNet-23-Slim | - | 5.7M | RTX 2080Ti | 101.0† | 76.1 | 217.0† | 74.7 |
| DDRNet-23 | - | 20.1M | RTX 2080Ti | 38.3† | 78.9* | 97.1† | 76.3 |
| RTFormer-Slim | - | 4.8M | RTX 2080Ti | 110.0† | 76.3 | 190.7† | 81.4 |
| RTFormer-Base | - | 16.8M | RTX 2080Ti | 39.1† | 79.3 | 94.0† | 82.5 |
Table 3: ADE20K tab. 3. Params, FLOPs and FPS at 512×2048. † FPS on one RTX 2080Ti; * retrained by the authors.
| Method | Encoder | Params | FLOPs | FPS | val mIoU |
|---|---|---|---|---|---|
| FCN | MobileNetV2 | 9.8M | 39.0G | 64.4 | 19.7 |
| PSPNet | MobileNetV2 | 13.7M | 52.9G | 57.7 | 29.6 |
| DeepLabV3+ | MobileNetV2 | 15.4M | 69.4G | 43.1 | 34.0 |
| SegFormer | MiT-B0 | 3.8M | 8.4G | 50.5 | 37.4 |
| DDRNet-23-Slim | - | 5.6M | 18.2G | 189.1† | 33.3* |
| DDRNet-23 | - | 20.1M | 71.6G | 71.2† | 38.8* |
| RTFormer-Slim | - | 4.8M | 17.5G | 187.9 | 36.7 |
| RTFormer-Base | - | 16.8M | 67.4G | 71.4 | 42.1 |
Table 4: COCOStuff tab. 4. Params, FLOPs and FPS at 640×640.
| Method | GPU | Params | FLOPs | FPS | test mIoU |
|---|---|---|---|---|---|
| PSPNet50 | - | - | - | 6.6 | 32.6 |
| ICNet | TitanX M | - | - | 35.7 | 29.1 |
| BiSeNetV2 | GTX 1080Ti | - | - | 87.9 | 25.2 |
| BiSeNetV2-L | GTX 1080Ti | - | - | 42.5 | 28.7 |
| DDRNet-23 | RTX 2080Ti | 20.1M | 28.1G | 146.1 | 32.1 |
| RTFormer-Base | RTX 2080Ti | 16.8M | 26.6G | 143.3 | 35.3 |
Table 5: ablations on ADE20K, RTFormer-Slim tab. 5 §4.4. Each row gives FPS and mIoU (%), as the paper reports them.
| Part | Setting | FPS | mIoU |
|---|---|---|---|
| (a) attention | SA+SA | 97.4 | 32.7 |
| (a) attention | EA+EA (r=1) | 180.8 | 32.2 |
| (a) attention | EA+EA (r=0.125) | 196.9 | 31.9 |
| (a) attention | EA+EA (r=0.25) | 189.6 | 32.0 |
| (a) attention | GFA+GFA | 189.8 | 32.8 |
| (a) attention | GFA+CA | 187.9 | 33.0 |
| (b) FFN | typical FFN | 178.5 | 32.15 |
| (b) FFN | two 3×3 convs (paper's FFN) | 187.9 | 33.0 |
| (c) groups (low, high) | 1, 1 | 189.8 | 32.2 |
| (c) groups (low, high) | 4, 1 | 189.8 | 32.3 |
| (c) groups (low, high) | 8, 2 | 189.8 | 32.8 |
| (d) cross size | 6×6 | 191.6 | 32.85 |
| (d) cross size | 8×8 | 189.8 | 33.00 |
| (d) cross size | 12×12 | 175.6 | 32.94 |
Table 6: ImageNet pretraining settings app. A. See Hyperparameters.
Table 7: ImageNet classification, 224 px single crop app. A. Params and FLOPs at 224 px.
| Method | Params | FLOPs | Top-1 |
|---|---|---|---|
| ResNet-18 | 11.2M | 1.8G | 69.0 |
| ResNet-50 | 23.5M | 3.7G | 75.3 |
| DF1 | 8.0M | 0.7G | 69.8 |
| DF2 | 17.5M | 1.7G | 73.9 |
| MobileNetV2 | 3.4M | 0.3G | 72.0 |
| MobileNetV3 | 5.4M | 0.2G | 75.2 |
| EfficientNet-B0 | 5.3M | 0.4G | 76.3 |
| STDC1 | 8.4M | 0.8G | 73.9 |
| STDC2 | 12.5M | 1.4G | 76.4 |
| DDRNet-23-slim | 7.6M | 1.0G | 70.2 |
| DDRNet-23 | 28.2M | 3.9G | 75.9 |
| RTFormer-Slim | 5.3M | 0.8G | 72.3 |
| RTFormer-Base | 20.5M | 3.0G | 77.4 |
Table 8: attention types on ADE20K app. B.1. Appendix table with more variants. All on RTX 2080Ti. SA multi-head self-attention, EA multi-head external attention, LA Linformer, NA Nyströmformer, and the number is the landmark count.
| Attention | FPS | val mIoU |
|---|---|---|
| SA+SA | 97.4 | 32.7 |
| EA+EA (r=0.125) | 196.9 | 31.9 |
| EA+EA (r=0.25) | 189.6 | 32.0 |
| EA+EA (r=1) | 180.8 | 32.2 |
| EA+EA (r=1, C=36) | 134.8 | 32.8 |
| LA+LA | 167.6 | 32.4 |
| NA(32)+NA(32) | 77.6 | 32.9 |
| NA(64)+NA(64) | 72.2 | 33.0 |
| GFA+GFA | 189.8 | 32.8 |
| GFA+CA | 187.9 | 33.0 |
Paper vs code
Official code: the paper links PaddleSeg (github.com/PaddlePaddle/PaddleSeg) [abstract], which is the PaddlePaddle organisation and the authors are from Baidu. The clone is at commit 3c4db66de1d9d59d0628ed87590b6308a2f4aa2a, Apache-2.0 LICENSE. The model is paddleseg/models/rtformer.py, and the configs are in configs/rtformer/.
Discrepancies found:
- Cross-attention scale. Paper: softmax of the scores divided by sqrt(d_h), the high-branch width eq. 4. Code: the scores are multiplied by the inverse square root of the number of pooled tokens, cross size squared, before the softmax rtformer.py rtformer.py. With the configured sizes, the code uses 1/12 for Base (12×12, 144 tokens) and for Slim on Cityscapes (default 12), and 1/8 for Slim on ADE20K (8×8, 64 tokens). The paper's d_h gives 1/sqrt(128) ≈ 1/11.3 for Base and 1/sqrt(64) = 1/8 for Slim, since the high-branch width at stage 5 is 128 for Base and 64 for Slim. The paper does not say which form its reported numbers used.
- Poly power, Cityscapes. Paper: power 0.9 §4.1. Code: power 1.0 in both Cityscapes configs rtformer_base_cityscapes_1024x512_120k.yml rtformer_slim_cityscapes_1024x512_120k.yml.
- Poly power and crop, ADE20K. Paper: other settings "identical to Cityscapes", which implies power 0.9 and a 512×1024 crop §4.1. Code: power 1.0 rtformer_base_ade20k_512x512_160k.yml and a 512×512 crop rtformer_base_ade20k_512x512_160k.yml.
- Cross size, Slim. Table 1 gives 8×8 for Slim tab. 1. The Slim Cityscapes config leaves it at the code default of 12 rtformer.py. Only the Slim ADE20K config sets 8 rtformer_slim_ade20k_512x512_160k.yml.
- Low-branch width M_g. Main text: M_g = M×H §3.1. Appendix: M_g = d app. B.1. Code: the learned key count equals the low-branch output width rtformer.py, which matches the appendix.
- Feedback from high to low branch. The paper does not describe it. The code injects high-resolution features into the low branch after each block, and the flag is on in stage 4 for all configs and in stage 5 only for Slim Cityscapes rtformer.py rtformer_slim_cityscapes_1024x512_120k.yml. This changes what stage 5 receives.
- Auxiliary head. Not in the paper. The code adds a head on the stride-8 stage-3 feature, weighted 0.4 in the loss, during training rtformer.py rtformer.py rtformer_base_cityscapes_1024x512_120k.yml.
- Drop path. Not stated for segmentation. The code default is 0.2 rtformer.py, and the ADE20K configs set 0.1 rtformer_base_ade20k_512x512_160k.yml.
- Cross-feature pooling. Paper: "pooling", type not stated §3.1. Code: adaptive max pooling rtformer.py.
- ADE20K Base result. Paper: 42.1 tab. 3. The repository README reports 42.02 for the same model [README: configs/rtformer/README.md]. Cityscapes: paper 79.3 and 76.3 against README 79.24 and 76.31, rounding only.
- Missing from the repository. No CamVid or COCOStuff RTFormer config, no ablation configs, and no ImageNet training code. Pretrained backbones are downloaded from URLs in the configs rtformer_base_cityscapes_1024x512_120k.yml.
- Stage-4 attention stride. The first projection of the stage-4 low-branch attention has stride 2, so that attention runs on the 1/32 grid rtformer.py. The paper does not say this.
Pitfalls
- Scale of the cross-attention scores. The paper's d_h and the code's pooled-token count give different scales (see Paper vs code). The paper reports no ablation of this scale, so either choice is untested by the authors' own experiments.
- Crop order. The paper writes 512×1024. The code writes
[1024, 512]. The code's convention (width first) is inferred from the 2048×1024 validation resize written the same way; the transform was not checked. Confirm before training. - Stage 4 and 5 timing. The low-branch attention in stage 4 runs on a grid downsampled by a stride-2 projection, so the attention and its shortcut work at stride 32 rtformer.py. Stage 5 runs at stride 32 without the projection rtformer.py.
- ReLU placement. The inputs to the stage-4 and stage-5 blocks pass through ReLU first, on both branches rtformer.py. The paper says nothing about ReLU placement.
- FFN details the paper omits. The released FFN is BatchNorm (epsilon 1e-6), then a 3×3 conv, GELU, dropout, and a second 3×3 conv rtformer.py. The paper specifies only two 3×3 convs with no expansion §3.1.
- Normalization epsilon. The second normalization in GFA adds 1e-6 to the denominator rtformer.py. The paper gives no epsilon.
- Pooling and max vs average. The cross-attention pooling is max in the code rtformer.py. The paper does not name the pooling type.
- DAPPM sizes. The paper borrows DAPPM from DDRNet without its pool sizes. The code uses DDRNet-style pool kernels of 5, 9 and 17 with strides 2, 4 and 8, plus a global pool rtformer.py.
- Groups in high-resolution branch. The paper's ablations vary groups in both branches tab. 5(c), but the main model uses CA on the high branch, where the group count does not apply rtformer.py. The reported group effect is for the GFA+GFA variant only.
- Cost of the high-resolution branch. The high-resolution branch stays at stride 8 through the network. The paper reports FPS and parameters, but no memory numbers.
- Speed numbers. FPS is measured on one RTX 2080Ti without TensorRT by default §4.1. Table 2 mixes GPUs, and its FPS values come from different sources, so the speed ranking is not a controlled comparison tab. 2.
- Single-scale results. Table 2 reports single-crop numbers, while the README also lists flip and multi-scale test results [README: configs/rtformer/README.md]. Do not compare those with single-scale numbers in the paper.
- Pretraining dependence. Results rely on ImageNet-pretrained backbones. The ImageNet recipe is only in the appendix app. A, and the released code does not include it.
- CamVid and COCOStuff. Those results come only from the paper, with no released config to check them against.
Lineage
- Builds on: external attention, arXiv:2105.02358 [guo2021beyond] (GFA is derived from it §3.1). Dual-resolution design from DDRNet, arXiv:2101.06085 [hong2021deep] (DAPPM and the dual-branch fusion §3.2).
- Compared against: the Cityscapes, CamVid, ADE20K and COCOStuff baselines in tab. 2 to tab. 4, including DDRNet-23 and -Slim, STDC, BiSeNet and SegFormer.
- Superseded by: not known from content already in this wiki.
Source and license
Adapted from “RTFormer: Efficient Design for Real-Time Semantic Segmentation with Transformer” by Jian Wang, Chenhui Gou, Qiman Wu, Haocheng Feng, Junyu Han, Errui Ding, Jingdong Wang (arXiv:2210.07124), 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/PaddlePaddle/PaddleSeg at commit 3c4db66de1d9 (Apache-2.0). Any quoted code is shown under that license.