solo-learn: nineteen self-supervised image methods under one PyTorch Lightning trainer
solo-learn: a library of self-supervised methods for visual representation learning powered by Pytorch Lightning
At a glance
- What is it?
- solo-learn wraps nineteen self-supervised image methods in a single PyTorch Lightning trainer, so SimCLR, DINO, MAE, SwAV and VICReg share one augmentation pipeline, one set of evaluation callbacks and one Hydra config tree. The price of that comparability is an exactly pinned Lightning version, a Dali extra frozen at the CUDA 11.0 wheel, and a roadmap that still lists regression testing as unfinished.
- Who is it for?
- Adopt solo-learn when you intend to run several self-supervised pretraining methods on the same backbone and want linear evaluation, K-NN scoring and augmentation handling to be identical across them. Do not adopt it to reproduce one paper exactly, to reach for a method newer than All4One, or on a machine whose CUDA runtime rules out the cuda110 wheel.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 26 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Four entry scripts wrap nineteen methods in one trainer
Four Python entry scripts sit at the root of the repository: `main_pretrain.py` for pretraining, `main_linear.py` for linear evaluation and backbone finetuning, `main_knn.py` for nearest neighbour scoring, and `main_umap.py` for feature-space plots. Everything they call lives in the `solo/` package, which is why the project calls itself self-contained while also stating that the models can be used outside of it.
What those four scripts share is a PyTorch Lightning trainer, and that is the entire design bet. Each of the nineteen listed methods reduces to a loss over two augmentation pipelines of the same backbone, so the training loop, the optimizer, checkpointing and the evaluation callbacks are written once and reused. Running SimCLR next to DINO then measures the methods rather than the surrounding engineering.
A `downstream/` directory holds the transfer work and `tests/` sits beside both. For a library whose stated purpose is a comparable environment, that pair of directories is where the claim either holds or does not.
Hydra owns the config tree, and Lightning is pinned exactly
Configuration moved to OmegaConf and Hydra in Sep 2022, and the dependency file shows how unevenly that choice is bounded. Everything floats except one line:
torch>=1.10.0
torchvision>=0.11.1
einops
lightning==2.1.2
torchmetrics>=0.6.0, <0.12.0`lightning==2.1.2` is the only exact pin in the file. `hydra-core`, which runs the config tree announced in that same news entry, carries no version bound at all, and `torch` is open at the bottom with nothing above it, so the resolution you get depends heavily on what is already installed beside it.
Nothing at the top level of the repository is a configuration directory, which means the Hydra files live inside the package, and no config key, override syntax or start command for a run is written down anywhere in the README. A first pretraining therefore begins with reading the package rather than with a copy-paste.
Online linear evaluation freezes the backbone between epochs
The evaluation surface is wider than a pretraining library normally offers, and it splits along one axis: whether the linear probe trains inside the pretraining loop.
Online linear evaluation attaches a head to the frozen backbone through a stop-gradient and trains it as training proceeds, which the README positions as a debugging and prototyping aid, and the same path is available for the momentum backbone. Offline evaluation is the other branch, `main_linear.py`, which is also the documented way to finetune an encoder such as the MAE backbone using mixup, cutmix and random augment. `main_knn.py` scores features with no trained head, online and offline, while `main_umap.py` plots the space.
Two mechanics make long runs survivable: auto resume for linear evaluation and wandb run resume, both added in May 2022. Neither replaces a checkpoint policy of your own. The evaluation list also stops partway through its last bullet, at the word visualiz, so the visualisation helpers are not fully enumerated by the project and the readthedocs build is where that gap has to be closed.
The Dali extra resolves to the cuda110 wheel and nothing else
`setup.py` declares three optional extras and nothing more:
EXTRA_REQUIREMENTS = {
"dali": ["nvidia-dali-cuda110"],
"umap": ["matplotlib", "seaborn", "pandas", "umap-learn"],
"h5": ["h5py"],
}The Dali extra is the one worth reading twice, because it names a single wheel: `nvidia-dali-cuda110`. The core requirements ask for `torch>=1.10.0` with no CUDA constraint and no upper bound, so a current installation on the machine is expected, yet the accelerated data path is wired to the CUDA 11.0 build. On a newer runtime the extra resolves to something you did not ask for, or you install Dali separately and the DataModule wrapper added around it in May 2022 stops being the documented path.
The data section claims processing speed improves by up to 100% using Nvidia Dali. No benchmark script, no measurement table and no configuration file for that figure appears among the top-level entries, so treat it as a claim to test on your own data rather than a reason to install.
A shadowed parser in setup.py decides what an install pulls
Packaging is where a close reading pays off. At the top of the file the dependency list is assembled while the module is still being imported, before any packaging option is set:
REQUIREMENTS_FILE = os.path.join(os.path.dirname(__file__), "requirements.txt")
with open(REQUIREMENTS_FILE) as fo:
REQUIREMENTS = [str(req) for req in parse_requirements(fo.readlines())]The `parse_requirements` used there is the one imported from `pkg_resources`. Then, below the extras dictionary, the file defines a second function under the same name and never calls it:
def parse_requirements(path):
with open(path) as f:
requirements = [p.strip().split()[-1] for p in f.readlines()]
return requirementsSo the second version is dead code that shadows an import, and what an installed copy pulls is decided by whatever requirements.txt says at build time. Edit that file and every installation of the package changes with it. The permission text at the top of the same file is the MIT notice, which requires that notice to travel with all copies, and that clause follows the code into any product that vendors it.
Multicrop, channel last and a switch for a fraction of data
The training tricks are where this library earns its keep, and the news entries name them one by one. Multicrop arrived for SwAV in Jun 2022 and for BYOL in Oct 2021, which matters because multicrop changes the number of forward passes per step and therefore the effective batch. Equalization augmentation came with the same update that added WideResNet.
Backbones are interchangeable across the whole catalogue: ResNet, WideResNet, ViT, Swin, PoolFormer and ConvNeXt, with timm in the dependency list for the last of them. Two switches are worth setting deliberately before a long run. Training on a fraction of the data was added in Apr 2022, and channel last conversion, added in Apr 2022 as well, is described as cutting training time considerably without giving a single number, so neither claim can be checked without your own measurement.
The roadmap admits methods can drift between updates
Here is the limitation the project states about itself. The roadmap lists adding performance-related testing to ensure that methods perform the same across updates as work still to do, which is an admission that a dependency bump can move a result without anyone noticing. The layout backs that reading: there is a `tests/` directory for code correctness, and nothing in the repository asserts that a method still reproduces its published number.
That gap is what makes the environment pins matter. `lightning==2.1.2` is exact, `torchmetrics>=0.6.0, <0.12.0` is a narrow window, and every other line floats. The news entry for Nov 29 2021 announces breaking changes with the instruction to update your versions, and the repository carries no marker for which pairings were tested together.
The distance between code and distribution is wide. The last push was on 2026-07-27, while the newest published tag, 1.0.8, is dated 2023-12-07, so an installation from that tag misses more than two and a half years of commits while an installation from main is untagged. The catalogue itself ends at All4One from ICCV 2023, and W-MSE has no newer neighbour beside it.
Importing one method outside the trainer, or Detectron v2 instead
The real alternative is to take one method out of the library and train it in your own loop, which the README explicitly permits, since the library is self-contained yet the models can be used outside of solo-learn. A paper-faithful single-repository implementation is the other option, and the difference is real: exact fidelity to one paper's recipe against a shared scaffold where the same training tricks are applied to every method.
What you inherit inside the trainer is the Dali DataModule, auto resume that retries an experiment which crashed or hit a timeout, wandb run resume, channel last conversion and the online linear head. Outside, you write the augmentation pipeline, the checkpoint policy and the evaluation schedule yourself, and comparability across methods is the first thing lost.
For object recognition the recorded route is Detectron v2, with transfer code living in `downstream/`. That is a bridge from a pretrained backbone into a detection stack you maintain, not a detection pipeline with its own data handling. Two tutorials cover writing a new method and a momentum variant, which points at extending the library rather than reusing it.
Editorial conclusion
Adopt solo-learn when you intend to run several self-supervised pretraining methods on the same backbone and want linear evaluation, K-NN scoring and augmentation handling to be identical across them. Do not adopt it to reproduce one paper exactly, to reach for a method newer than All4One, or on a machine whose CUDA runtime rules out the cuda110 wheel. Check three things before a long run: that lightning==2.1.2 resolves in your environment, that the Hydra config path for main_pretrain.py exists in the checkout you cloned, and that the commit you install carries the stability work dated Jan 14 2024.
Frequently asked questions
Which self-supervised methods does solo-learn include?
The catalogue lists nineteen: All4One, Barlow Twins, BYOL, DeepCluster V2, DINO, MAE, MoCo V2+, MoCo V3, NNBYOL, NNCLR, NNSiam, ReSSL, SimCLR, SimSiam, Supervised Contrastive Learning, SwAV, VIbCReg, VICReg and W-MSE.
How do I install solo-learn and what does it depend on?
The README gives no install command, and the dependency list is requirements.txt, which setup.py reads at build time. It asks for torch>=1.10.0, torchvision>=0.11.1, einops, lightning==2.1.2, torchmetrics>=0.6.0, <0.12.0, tqdm, wandb, scipy, timm, scikit-learn and hydra-core, plus three extras for Dali, UMAP plotting and H5 data.
Does solo-learn require a particular CUDA runtime?
Only the Dali extra names one: nvidia-dali-cuda110, which is the CUDA 11.0 build. The core requirements place no CUDA constraint on torch>=1.10.0, so a machine on a newer runtime can install the library and handle Dali on its own.
How do I evaluate a model that was pretrained with solo-learn?
Three routes exist: online linear evaluation through a stop-gradient during pretraining, standard offline linear evaluation with main_linear.py, and online or offline K-NN scoring with main_knn.py. main_umap.py covers the feature-space plots, and auto resume for linear evaluation plus wandb run resume are built in.
Can I use a solo-learn backbone outside the library?
Yes. The README states that the library is self-contained while the models can be used outside of solo-learn, and object recognition goes through Detectron v2 support, with transfer code kept in the downstream directory.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vturrisi-solo-learn)Was this useful?