Catalyst: a PyTorch runner for reproducible deep learning experiments
Accelerated deep learning R&D
At a glance
- What is it?
- Catalyst wraps training, evaluation and inference in a Runner plus callbacks so experiments stay reproducible, but the last release is v22.04 and the last push was 2026-07-08. Here is what it does, how to install it, and when to pick something else.
- Who is it for?
- Adopt Catalyst if you already have PyTorch models and want a runner that handles the train, evaluate and predict loop plus metric callbacks without you writing a training loop. Skip it if you need a framework with a recent release cadence, or if you want a high-level API that hides the training loop entirely.
- Can I use it commercially?
- Yes. Apache-2.0 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 87 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 October 3, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Catalyst actually replaces in a PyTorch project
Every PyTorch project grows the same file: a loop over epochs, an inner loop over batches, a loss call, a backward pass, an optimizer step, and then a second copy of that loop for validation. Catalyst exists to delete that file. The README states the goal directly: it focuses on reproducibility, rapid experimentation, and codebase reuse so you can create something new rather than write yet another train loop.
The audience is research and applied teams that already know PyTorch and do not want a framework that hides tensors from them. Catalyst does not replace nn.Module or torch.optim. You still build the model, the criterion and the optimizer yourself. What it supplies is the orchestration layer around them, plus a set of callbacks for metrics, logging and checkpointing that would otherwise be copied between projects.
The topics listed on the repository point at the same audience: computer vision, NLP, recommender systems, reinforcement learning, metric learning, distributed computing. The examples directory backs that up with folders for detection, recsys, reinforcement_learning, self_supervised and engines. This is not a single-task library. It is a general harness, which also means the documentation surface is wide and the API has more than one entry point.
The Runner and callback model, and where the data flows
The central object is the Runner. In the README example the class used is dl.SupervisedRunner, constructed with four string keys that tell it how to move data between your model and the callbacks: input_key, output_key, target_key and loss_key. Those keys are the contract. Your DataLoader yields a dictionary, the runner picks the tensor under input_key, feeds it to the model, reads the tensor under output_key, compares it with target_key through the criterion, and stores the scalar under loss_key.
Training is a single call to runner.train with model, criterion, optimizer, loaders, num_epochs and a callbacks list. Validation is not a separate function you write; you pass valid_loader and a valid_metric name, and the runner decides when to run validation. The callbacks do the measuring. dl.AccuracyCallback takes input_key and target_key plus a topk tuple, and dl.PrecisionRecallF1SupportCallback takes the same two keys. Because both read from the same key names, the runner is the only place that needs to know the shape of your batch.
The same object covers the rest of the lifecycle. runner.evaluate_loader takes a loader and a callback list and returns metrics. runner.predict_loader yields prediction dictionaries, and the README asserts on prediction["logits"].shape[-1]. Post-processing is a separate module, catalyst.utils, with trace_model, quantize_model, prune_model and onnx_export. That split matters: the runner handles the loop, utils handles deployment artifacts, and neither knows about the other.
Installing Catalyst and running a first training job
The README gives one install command, and it is the only one it gives:
pip install -U catalystsetup.py states REQUIRES_PYTHON = ">=3.7.0", so a Python 3.7 or newer interpreter is the floor. The package is published on PyPI as catalyst, and the README also links a Docker Hub image under catalystteam/catalyst. Optional dependency groups are declared as extras in setup.py: cv, comet, deepspeed, dev, ml, mlflow, neptune, onnx, onnx-gpu, optuna and profiler. Each reads a file from the requirements directory, so installing an extra pulls that requirement file rather than a hardcoded list.
The README's getting started example is a complete MNIST run. The shortest useful version is the runner construction plus the train call:
import os
from torch import nn, optim
from torch.utils.data import DataLoader
from catalyst import dl
from catalyst.contrib.datasets import MNIST
model = nn.Sequential(nn.Flatten(), nn.Linear(28 * 28, 10))
loaders = {
"train": DataLoader(MNIST(os.getcwd(), train=True), batch_size=32),
"valid": DataLoader(MNIST(os.getcwd(), train=False), batch_size=32),
}
runner = dl.SupervisedRunner(
input_key="features", output_key="logits", target_key="targets", loss_key="loss"
)After that, the call to runner.train takes criterion=nn.CrossEntropyLoss(), optimizer=optim.Adam(model.parameters(), lr=0.02), the loaders dictionary, num_epochs=1, logdir="./logs", valid_loader="valid", valid_metric="loss", minimize_valid_metric=True and verbose=True. The loaders dictionary keys "train" and "valid" are what valid_loader refers to by string, so renaming a key without renaming valid_loader breaks the run silently at validation time.
Evaluation and inference reuse the same runner. runner.evaluate_loader(loader=loaders["valid"], callbacks=[...]) returns metrics, and runner.predict_loader(loader=loaders["valid"]) yields one prediction dictionary per batch. The README's post-processing block then takes the trained model, pulls one batch with next(iter(loaders["valid"]))[0], and calls utils.trace_model, utils.quantize_model, utils.prune_model with pruning_fn="l1_unstructured" and amount=0.8, and utils.onnx_export with file="./logs/mnist.onnx". Those are the exact arguments the README shows; the README does not document what happens if the batch shape differs from the traced shape.
The release gap is the first thing to check before adopting
The repository is not archived, and the last push was on 2026-07-08. The newest release listed is v22.04, published on 2022-04-29, with v22.02.1 and v22.02 before it. That is a gap of roughly four years between the last tagged release and the last push to the default branch. Whatever is on master may be ahead of the PyPI package, and the README example may describe master rather than the version pip installs.
That distinction is not academic here. The README example uses dl.SupervisedRunner and a callbacks list built from dl.AccuracyCallback and dl.PrecisionRecallF1SupportCallback. If you install from PyPI and the runner signature in that release differs from the README, the error will surface as a TypeError on keyword arguments, not as a clear version mismatch. The setup.py file reads the version from catalyst/__version__.py, so the installed version is the authority, not the README.
For a research project pinned to a known working environment, a slow release cadence is tolerable. For a team that expects security patches, PyTorch compatibility updates, or a documented deprecation path, it is a real constraint. The README does not document a support window, an LTS branch, or a migration guide between the 22.02 and 22.04 releases.
Where Catalyst is the wrong tool
If you want a framework that owns the whole training loop and you never want to see a backward call, Catalyst is the wrong layer. It hands you the model, criterion and optimizer and asks you to wire them together. That is deliberate, and it is why the framework can cover reinforcement learning, detection and recsys with one runner abstraction, but it also means a beginner gets less scaffolding than a batteries-included trainer would give.
A second case: if your project needs a single narrow pipeline, such as text classification with a pretrained transformer and nothing else, the callback and key-name machinery is overhead. You would be defining input_key, output_key, target_key and loss_key to satisfy a runner that exists to serve many task types. The examples directory shows the framework is organized around breadth, and breadth has a cost in indirection.
A third case is dependency weight. setup.py splits optional dependencies into named extras precisely because the full set is large. If you only need ONNX export, the README's post-processing block still lives in catalyst.utils, and the onnx extra is a separate requirements file. Pulling the base package plus an extra you do not need is a choice you make at install time, not something the framework decides for you.
How Catalyst differs from PyTorch Lightning
The closest comparison is PyTorch Lightning, and the difference is where the abstraction sits. Lightning asks you to subclass a LightningModule and move your training step, validation step and optimizer configuration into methods on that class. Catalyst keeps your nn.Module untouched and puts the loop in a separate Runner object that you configure with keys and callbacks.
That changes what you write. With Lightning, the batch unpacking lives in your module's training_step. With Catalyst, it lives in the input_key, output_key and target_key strings you pass to the runner, and the callbacks read from those same keys. If you have several models that share a training procedure but differ in their forward signature, the Catalyst arrangement lets you swap the runner configuration instead of editing each module. If you prefer the training procedure to be colocated with the model definition, Lightning's arrangement is more direct.
Both are in the PyTorch ecosystem, and the README links Catalyst's entry in the LF AI landscape and the PyTorch ecosystem page. Neither link tells you which one fits your team. The deciding question is whether your variation lives in the model or in the loop. Catalyst is built for the case where the loop is shared and the models vary.
Licence, upgrade cost and what to pin
Catalyst is Apache-2.0, and the LICENSE file sits at the repository root. Apache-2.0 permits commercial use and modification and includes a patent grant, which matters if you are embedding the framework in a product rather than using it for internal research. It also requires that you keep the licence and notice files. That is a summary of the licence text, not legal advice; read LICENSE and your own counsel's guidance before shipping.
Upgrade cost is the part the material cannot fully answer. The CHANGELOG.md file exists at the root, so release-to-release changes are recorded there, but the README does not describe a deprecation policy or a supported version matrix. The repository does carry a Makefile target for installing from source, which is the path to follow if you need master rather than the PyPI release:
make install-from-sourceThat target runs pip uninstall catalyst -y followed by pip install -e ./, so it removes any existing install before linking the working copy. The same Makefile defines a check target that runs catalyst-make-codestyle and catalyst-check-codestyle with line length 89, matching the line-length setting in pyproject.toml. If you fork the project, those two commands are the style gate the maintainers use. Pin the version you install and record it next to your experiment configs, because the runner API is the part most likely to shift between releases.
Editorial conclusion
Adopt Catalyst if you already have PyTorch models and want a runner that handles the train, evaluate and predict loop plus metric callbacks without you writing a training loop. Skip it if you need a framework with a recent release cadence, or if you want a high-level API that hides the training loop entirely. Before committing, check that the Runner API in your installed version matches the README example, because the newest release listed is v22.04 from 2022-04-29 while the repository was still being pushed to on 2026-07-08.
Frequently asked questions
How do you install Catalyst?
The README gives a single command, pip install -U catalyst. setup.py requires Python 3.7 or newer, and optional dependency groups such as cv, ml, onnx and optuna are declared as extras that each load a file from the requirements directory.
How do you use Catalyst to train a model?
You build your own nn.Module, criterion and optimizer, then construct a dl.SupervisedRunner with input_key, output_key, target_key and loss_key and call runner.train with the loaders, num_epochs, logdir and a callbacks list. The same runner object handles evaluate_loader and predict_loader afterwards.
What does the name Catalyst mean in this project?
The README frames it as a PyTorch framework that speeds up deep learning research and development, so the name refers to accelerating the work rather than to any chemistry or marketing sense of the word. The stated focus is reproducibility, rapid experimentation and codebase reuse.
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/catalyst-team-catalyst)