Official PyTorch implementation of MePo++, a unified post-training framework for pretrained-model-based General Continual Learning (GCL).
MePo++ addresses two gaps that arise when pretrained models (PTMs) are deployed on online, blurry, evolving data streams:
- Upstream–downstream misalignment — generic pretrained representations are optimized for static recognition and are not inherently prepared for continual adaptation.
- Downstream alignment gap — conventional output alignment relies on task-wise statistics that become unreliable when old and new concepts are temporally mixed.
It resolves them with two complementary stages:
| Stage | Module | What it does |
|---|---|---|
| 1 — before deployment | MetaPrep | Clusters unlabeled upstream features into pseudo classes, arranges them into pseudo continual sequences, and runs a Reptile bi-level meta-refinement to produce a GCL-oriented initializationθ* and a stable geometry prior Σ_pre. |
| 2 — during deployment | StreamAlign | Reconstructs each transient online feature towardΣ_pre via a Cholesky covariance transport, blends it with the plastic feature (weight α), and applies a supervised contrastive loss to keep the two views semantically consistent. |
MePo++ requires no task identities, no task boundaries, and no replay buffer, and plugs into existing prompt-based continual learners (L2P, DualPrompt, CODA-P, MISA).
conda env create -f environment.yml
conda activate mepo
# or, with pip:
pip install -r requirements_pip.txtKey dependencies: torch, timm, faiss-gpu (CPU fallback supported),
scikit-learn, numpy. safetensors is only needed for the DINOv2 backbone.
All machine-specific paths live in configs/config.py. Edit it once, or export
the corresponding environment variables:
export MEPO_DATA_ROOT=/your/datasets # ImageNet, CIFAR, ImageNet-R, CUB-200
export MEPO_PRETRAIN_DIR=/your/pretrained # ViT-B_16.npz, dinov2_base.safetensors
export MEPO_OUTPUT_DIR=/your/output # checkpoints + covariance matricesExpected dataset layout under MEPO_DATA_ROOT:
CIFAR/ # torchvision auto-downloads
ImageNet/train, /val # used by MetaPrep as the unlabeled upstream set
imagenet-r/train, /test
CUB_200_2011/
Supported backbones (-model): sup (ViT-B/16 IN-21k), sup1k (ViT-B/16 IN-21k/1k),
dinov2 (ViT-B/14), ibot.
Extracts features on unlabeled ImageNet, clusters them into M pseudo classes,
builds T' pseudo continual tasks, and runs Reptile meta-refinement:
python metaprep/meta_train.py \
-gpu_ids 0,1 \
-model sup \
-epochs 150 \ # K meta-epochs (150 / 100 / 150 for sup / sup1k / dinov2)
-num_tasks 10 \ # T' pseudo tasks
-num_clusters 1000 \ # M pseudo classes
-meta_lr 0.01 \ # eta_meta
-num_inner_steps 4 \
-inner_bb_lr 5e-5 \
-inner_head_lr 1e-3 \
-samples 200 \
-save_dir outputCheckpoints are written to
output/self_R100_noW_<model>_sample_.../meta_epoch_<k>.pth.
The final one is θ*.
Re-clusters the refined features, forms pseudo-class prototypes, and takes their covariance (a ridge term keeps it positive-definite for the Cholesky transport):
python metaprep/compute_covariance.py \
--gpu_ids 0 \
--model sup \
--model_dir output/self_R100_noW_sup_sample_200_lr_0.01_numtask_10_steps_4 \
--epoch 150 \
--num_clusters 1000This saves cov_matrix_backbone150.npy next to the checkpoint.
Run the online continual learner with the meta-trained backbone and the geometry prior:
cd GCL
python -W ignore main.py \
--mode DualPrompt --model_name DualPrompt \
--dataset cifar100 --n_tasks 5 --m 50 --n 10 \
--meta_path <...>/meta_epoch_150.pth \
--cor_path <...>/cov_matrix_backbone150.npy \
--cor_coef 0.5 \
--transform_aux_contrast \
--transform_aux_contrast_weight 0.002 \
--transform_aux_contrast_temp 0.05 \
--data_dir $MEPO_DATA_ROOT| Flag | Paper symbol | Meaning | Suggested |
|---|---|---|---|
--meta_path |
θ* |
MetaPrep backbone checkpoint | — |
--cor_path |
Σ_pre |
geometry prior.npy |
— |
--cor_coef |
α |
geometric alignment weight | 0.3–0.5 |
--transform_aux_contrast |
— | enable semantic reconciliation | on |
--transform_aux_contrast_weight |
λ |
contrastive loss weight | 2e-3–5e-3 |
--transform_aux_contrast_temp |
τ |
contrastive temperature | 0.05 |
Setting α = 1 replaces the online feature entirely with its aligned counterpart and
degrades performance — the plastic feature must be retained.
configs/run_dualprompt_streamalign.sh runs all three steps in sequence.
Ready-made per-dataset launchers live in GCL/scripts/.
MePo++/
├── configs/
│ ├── config.py # all machine-specific paths
│ └── run_dualprompt_streamalign.sh # end-to-end example
├── metaprep/ # Stage 1
│ ├── meta_train.py # Reptile meta-refinement -> θ*
│ └── compute_covariance.py # prototypes -> Σ_pre
├── GCL/ # Stage 2: online GCL framework
│ ├── main.py
│ ├── methods/ # trainers (DualPrompt, L2P, MISA, MVP, ...)
│ ├── models/ # models incl. StreamAlign transform + contrastive loss
│ └── scripts/ # launch scripts
├── utils/ # data manager, DINOv2 loading helpers
└── environment.yml
StreamAlign lives in GCL/models/dualprompt.py and GCL/models/L2P.py
(transform_to_target_covariance, _supervised_contrastive_loss); the loss is
assembled in the matching GCL/methods/*.py model_forward.
- Covariance conditioning. With ViT-B (
d=768) and batch size 64 the online covariance is rank-deficient by construction;stable_choleskyadds an adaptive jitter and falls back to an eigenvalue-clamped PSD projection. - faiss. GPU KMeans is attempted first and falls back to CPU automatically.
- Reproducibility. Downstream runs sweep seeds
1–5(seeGCL/main.py); reported numbers are mean ± std over the five runs.
todoThe preliminary conference version:
@inproceedings{sun2026mepo,
title = {MePo: Meta Post-Refinement for Rehearsal-Free General Continual Learning},
author = {Sun, Guanglong and Yan, Hongwei and Wang, Liyuan and Kang, Zhiqi and Cui, Shuang and Su, Hang and Zhu, Jun and Zhong, Yi},
booktitle = {Forty-third International Conference on Machine Learning},
year = {2026}
}The downstream GCL framework builds on MVP and MISA; the meta-refinement follows Reptile.

