# MGL is a Common Lisp machine learning library built on MGL-MAT, and its author says power beats ease of use

> MGL gives Common Lisp developers backpropagation networks, Boltzmann machines and Gaussian processes on top of a BLAS and CUDA capable matrix layer. It is not trying to be friendly: the manual states the focus is on power and performance, and the API surface is wide enough to reward people who read it.

**melisgl/mgl** — Common Lisp machine learning library.

- Repository: https://github.com/melisgl/mgl
- Stars: 652 · Forks: 39
- Language: Common Lisp
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/melisgl-mgl

## A Lisp library whose stated goal is power over convenience

MGL is a Common Lisp machine learning library by Gábor Melis, with some parts originally contributed by Ravenpack International. It mainly concentrates on various forms of neural networks, including Boltzmann machines, and feed-forward and recurrent backprop nets. Most of MGL is built on top of MGL-MAT, so it has BLAS and CUDA support.

The manual is unusually direct about its philosophy: in general, the focus is on power and performance, not on ease of use. Perhaps one day there will be a cookie cutter interface with restricted functionality if a reasonable compromise is found between power and utility.

That sentence is the single most useful thing in the documentation for anyone deciding whether to use this library. It is an invitation to read the manual, and it is a warning that you should not expect the small and pleasant API that most Python machine learning users now take for granted. What you get instead is a wide surface area with real control over the numerics, which is exactly what you want if you are coming from a numerical computing tradition and exactly what you do not want if you are expecting to be productive in an afternoon.

The library itself is a Common Lisp ASDF system named mgl, version 0.1.0, licensed MIT with the terms in COPYING, authored by Gábor Melis.

The scope is broad rather than shallow. The manual has fifteen chapters covering datasets, resampling, core infrastructure, monitoring, classification, features, gradient based optimization, differentiable functions, backpropagation neural networks, Boltzmann machines, Gaussian processes, natural language processing, and logging.

## MGL-MAT does the linear algebra and decides whether you get a GPU

The dependency situation is unusual and it is the thing to get right first.

CL-CUDA and MGL-MAT are the two main dependencies, and they are also the ones not yet in quicklisp, so the instructions are to drop them into quicklisp/local-projects/. Everything else comes from quicklisp as usual. The declared dependency list also includes alexandria, array-operations, cl-reexport, closer-mop, lla, mgl-gnuplot, mgl-mat, mgl-pax, named-readtables, num-utils, pythonic-string-reader, and swank, marked optional.

There is a graceful degradation story, and it is worth understanding because it is silent. If there is no suitable GPU on the system or the CUDA SDK is not installed, MGL will simply fall back on using BLAS and Lisp code. That is friendly, but it also means a misconfigured CUDA setup produces correct results at CPU speed with no obvious complaint.

The remedy is small. Wrapping code in MGL-MAT:WITH-CUDA* is basically all that is needed to run on the GPU, and with MGL-MAT:CUDA-AVAILABLE-P one can check whether the GPU is really being used. If you are benchmarking anything, that check belongs in your code rather than in your assumptions.

On the BLAS side, MGL used to rely on LLA to interface to BLAS and LAPACK, which is mostly history now, but configuration of foreign libraries is still done via LLA. The docs point out that these days OpenBLAS is easier to set up and just as fast as ATLAS, which is practical advice since a badly configured foreign library stack is the classic way a Lisp numeric project loses an afternoon.

## Many small packages, one reexporting MGL package to smooth over them

The package layout is a deliberate design decision rather than an accident of file organisation.

MGL consists of several packages dedicated to different tasks. Package MGL-RESAMPLE is about resampling, MGL-GD is about gradient descent, and so on. The stated rationale has two halves. On one hand, having many packages makes it easier to cleanly separate API from implementation and to explore into a specific task. At other times they can be a hassle.

The compromise is the MGL package itself, which reexports every external symbol found in all the other packages that make up MGL and MGL-MAT. So you get task-scoped namespaces for reading the code, and one wide namespace for using it. The reexport mechanism is cl-reexport, which appears in the dependency list, and the symbol-visibility tool is closer-mop.

There is one exception to the reexport rule: the bundled but independent MGL-GNUPLOT library. That separation is sensible, since the plotting library has its own scope and its own upstream, and folding its symbols into the main namespace would blur where the library ends.

The manual's own chapter structure mirrors this packaging. Gradient descent gets a chapter with subsections for batch based optimizers, a segmented GD optimizer, per-weight optimization, utilities, conjugate gradient, and an extension API with separate sections for implementing optimizers, implementing gradient sources, and implementing gradient sinks. That last trio is the shape of the library's extension story, and it is worth reading before you commit to it.

## Backprop nets are built from lumps, and the extension API is the point

The backpropagation chapter is the heart of the library, and its vocabulary is unusual enough that you will need the manual open.

The chapter has a backprop overview, a Clump API, and a section on BPNs with subsections for training, monitoring, feed-forward nets, and recurrent neural nets. Under that sits the Lumps section, which breaks the network down into a lump base class, inputs, a weight lump, activations, activation functions, losses, stochasticity, arithmetic, and operations for RNNs.

A lump is a unit of computation that a network is assembled from. A weight lump holds the parameters, activation lumps apply activation functions, a loss lump defines the objective, and the arithmetic and stochasticity lumps sit between them. A network is then a wiring of these pieces, which is why a feed-forward net and a recurrent net differ mainly in how lumps are connected rather than in being separate implementations.

The clump structure is also why the extension API section exists. Implementing optimizers, gradient sources, and gradient sinks is a documented activity rather than something you have to reverse engineer, and for a library at version 0.1.0 that kind of documented seam matters more than usual.

Monitoring is not an afterthought either. There is a whole chapter for it, with monitors, measurers, and counters, including counter attributes and counter classes. The classification chapter mirrors that structure with classification monitors, measurers, and counters, including confusion matrices. Counters with attributes are what make it possible to watch a training run rather than guess at it.

## Resampling, features, and the batch processing core

The supporting machinery is what turns a set of network definitions into a workflow.

Resampling gets its own chapter with shuffling, partitions, cross-validation, bagging, CV bagging, and a section of miscellaneous operations. Cross-validation and bagging being first-class items, rather than something you write yourself for each experiment, is the kind of decision that saves weeks on a real project.

Features get a chapter too, split into feature selection and feature encoding. Feature encoding in particular is a recurring source of bugs in machine learning pipelines, and having it handled consistently matters more than it sounds.

The core chapter covers persistence, batch processing, and executors, with a subsection on a parameterized executor cache. Persistence is how you save a fitted model, batch processing is how you run many parameter settings, and executors are how the work is dispatched. The parameterized executor cache is the interesting piece: it caches executors keyed by their parameters, so a sweep that reuses the same configuration does not rebuild the same machinery over and over.

Datasets and samplers are handled separately, with a function sampler as the example. The glossary at the start of the manual fixes the vocabulary that the rest of the document relies on: instances are also known as examples or samples, sets of instances are datasets, and the results of applying a model to instances are called results when predictions is too specific a word.

## Running the tests, and accepting that most of them are stochastic

The manual gives you the command for the built in tests, which is worth quoting because it is short and easy to miss:

```
    (ASDF:OOS 'ASDF:TEST-OP '#:MGL)
```

Then it adds a caveat that matters more than the command: most of the tests are rather stochastic and can fail once in a while.

That is an unusual thing for a project's own documentation to say, and it is a positive sign about the honesty of the document. Random initialisation, stochastic gradient descent, and dropout all produce occasional failures, and a test suite that never flakes is often a test suite that is not testing much. The practical consequence is that a red test run is not automatically a regression, and you need to re-run before you file anything.

The repository layout backs up the manual's claims about coverage. There is a test directory, a src directory, an example directory with a digit-fnn.lisp file, a gaussian-process.lisp file, an mnist.lisp file, an sgd.lisp file, a sum-sign-rnn.lisp file, and a util.lisp file, plus a mnist-save directory and a baseline directory. There is also a visuals directory and a gnuplot directory for the bundled plotting library, and a separate mgl-example.asd file so the examples load as their own system.

## Gaussian processes, Boltzmann machines, and a bag of words for text

Beyond neural networks, three other areas are worth checking against your needs.

Gaussian processes have their own chapter, and there is a matching example file, example/gaussian-process.lisp. Boltzmann machines have a chapter as well. Both are unusual to find bundled in a general library, and both are the kind of model where the API surface decides whether you will actually use them.

Natural language processing is represented by a single subsection, bag of words. Read that as a scope boundary rather than a feature. There is no transformer, no attention mechanism, no tokeniser beyond the obvious, and no pretrained anything. If your work involves modern language models, this library will not carry you, and the fact that the NLP chapter has one subsection under it tells you that before you spend an evening on it.

Logging has its own chapter, and MGL-GNUPLOT handles the plotting side as a bundled but independent library. That combination, a logging chapter plus a plotting library, tells you what kind of project this is: one where you watch a training run and plot the curves, rather than one where you call fit and print accuracy.

Differentiable functions are a chapter of their own, which is the piece that supports the gradient sources and gradient sinks in the extension API. If you want to add your own differentiable operation rather than compose existing ones, that is where you look.

## Maintenance state and the upgrade cost of a 0.1.0 library

The maintenance picture deserves a straight reading rather than a reassuring one.

The last push to the repository was on 2026-06-27, and the repository has no GitHub releases. There is no version history to consult and no changelog to diff, so an upgrade is effectively a pull of the working tree. That is a real cost when you are pinning a research codebase against a specific result.

The system version is 0.1.0, which is the number that matters for API stability. A library at 0.1.0 signals that interfaces may move, and the manual's own section list, with its named subsections for each optimizer and each lump type, is the kind of surface that will move. The API extension sections for implementing optimizers, gradient sources, and gradient sinks are the parts most likely to shift under you.

The licence is MIT, with the terms in COPYING, which is the permissive choice and appropriate for both commercial and research use. The copyright file at the top of the repository sits alongside a TODO file and two README files, which suggests an active working state rather than a curated release.

There is also a naming wrinkle worth knowing about before you start: the homepage listed in the manual points at melisgl.github.io/mgl while the repository lives under github.com/melisgl/mgl, and the manual states it is also available in various formats on fixnum.com for the latest version. So the canonical copy of the documentation is not necessarily the copy sitting in the repository you cloned, which is another reason to pin a commit rather than track a branch.

## Conclusion

MGL fits a Common Lisp developer with a numeric background who wants GPU capable matrix code and network definitions in the same language, and who is willing to learn the manual rather than guess an API. It does not fit a beginner, since the project itself states the focus is on power and performance instead of ease of use, and it does not fit a team that needs a broad selection of pretrained models or a large community around the library. Before adopting it, install MGL-MAT and CL-CUDA into quicklisp/local-projects/ as the docs require, and check MGL-MAT:CUDA-AVAILABLE-P, because without a GPU or the CUDA SDK the library silently falls back to BLAS and Lisp code.

## FAQ

### What is the MGL Common Lisp library used for?

MGL is a machine learning library for backpropagation neural networks, Boltzmann machines, Gaussian processes and more. Most of it is built on top of MGL-MAT, so it has BLAS and CUDA support.

### How do I install MGL and its dependencies in Common Lisp?

CL-CUDA and MGL-MAT are the two main dependencies and are not yet in quicklisp, so drop them into quicklisp/local-projects/. The other dependencies come from quicklisp, and BLAS setup is done through LLA, where OpenBLAS is now the easier option.

### Does MGL require a GPU to work?

No. If there is no suitable GPU or the CUDA SDK is not installed, MGL falls back on BLAS and Lisp code. Wrapping code in MGL-MAT:WITH-CUDA* enables the GPU path, and MGL-MAT:CUDA-AVAILABLE-P checks whether the GPU is really being used.

### How do I run the MGL test suite?

The built in tests are run with (ASDF:OOS 'ASDF:TEST-OP '#:MGL). The manual notes that most of the tests are rather stochastic and can fail once in a while.

### What licence is MGL released under?

MGL is released under the MIT licence, with the terms in the COPYING file at the top of the repository.

## Sources

- [Issues](https://github.com/melisgl/mgl/issues)
- [License: MIT](https://github.com/melisgl/mgl/blob/master/LICENSE)
- [melisgl/mgl on GitHub](https://github.com/melisgl/mgl)
- [README](https://github.com/melisgl/mgl/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/melisgl-mgl
