Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Lispyn

PyPI version Python versions PyPI downloads CI License

Write complex experiments. Make them easy to understand, reuse, and share.

Great experiments deserve to be understood—not just executed. Whether you're exploring new AI models, fine-tuning neural networks, or running advanced training pipelines, you often need to show others what you built, how it works, and what you learned.

Lispyn uses Lisp-based Hy macros to turn repetitive steps into concise, reusable building blocks. Prepare datasets, train with PyTorch, document your choices in Markdown, and generate plots—all from a readable Lisp source that becomes a standard Python Jupyter notebook.

Spend less time rewriting boilerplate and more time experimenting. When your dataset, model, or training strategy changes, adapt the macro and reuse the workflow. Lisp for expressive experiments. Python for the ecosystem. Jupyter for sharing results.

Quick installation

Install Lispyn directly from PyPI:

python -m pip install lispyn

# Recommended for notebooks and Matplotlib plots
python -m pip install "lispyn[notebook,plots]"

# Check your current Python and available dependencies
lispyn doctor

Lispyn needs Python 3.10+. Basic installation includes Hy, so you can import and use standard Python modules immediately. PyTorch, TorchVision, and GPU-specific libraries are optional; install compatible versions for your hardware before running AI training examples.

Your first Lispyn notebook

Create a file named hello.hy:

(require lispyn.macros [md])
(md "# My first Lispyn experiment"
    "Synthetic training curves, generated with reusable Lisp macros.")

(require lispyn.macros [defcurve])
(setv history {"train_loss" [1.4 1.0 0.7 0.5]
               "val_loss" [1.5 1.2 0.9 0.75]})
(defcurve my-style :theme "docusaurus-dark"
  :palette "turquoise-spectrum")
(my-style history :metric "loss"
  :title "Training curves" :save "training.png")

Then run:

# Translate Lispyn/Hy into ordinary Python Jupyter cells
lispyn build hello.hy

# Execute the notebook, keeping its real outputs
lispyn execute hello.hy

# Or run a Hy file directly (without creating a notebook)
lispyn run hello.hy

hello.ipynb is a standard Jupyter notebook with real Markdown and Python cells. The synthetic graph is written to training.png. All plots are generated with Matplotlib; no new language interpreter or special kernel is needed. After a Markdown cell, repeat (require lispyn.macros [...]) for any macros used in a later cell because Hy code cells compile independently.

Developing Lispyn itself? Clone the repository and use python -m pip install -e ".[dev,notebook,plots]" instead. See the technical guide and release instructions.

Matplotlib with reusable Lisp macros

Define a design once and apply it to any recorded history. This short example uses a dark gray background inspired by Docusaurus and the seven-color turquoise-spectrum palette:

(require lispyn.macros [defcurve compare-curves])
(setv history {"train_loss" [1.5 1.1 0.8 0.55]
               "val_loss" [1.6 1.2 0.95 0.76]})
(defcurve turquoise-dark
  :theme "docusaurus-dark"
  :palette "turquoise-spectrum"
  :train-color "#40E0D0" :val-color "#8CF0EB"
  :title-size 18 :line-width 2.8 :fill-alpha 0.08)
(turquoise-dark history
  :metric "loss" :title "Training dynamics"
  :subtitle "Synthetic example · 4 epochs"
  :save "training.png")

Generated from Lispyn + Matplotlib using synthetic values, not a trained model.

Turquoise training and validation lines on a Docusaurus-like dark gray background

The same Lisp file can compare several named runs, automatically assigning distinct colors from the palette:

Three synthetic validation curves in turquoise on a dark gray background

Full reproducible source: synthetic_curves.hy · generated Jupyter notebook. Regenerate the figures with lispyn run examples/synthetic_curves.hy.

Classification reports are equally concise: the new defconfusion macro creates a reusable dark-themed confusion matrix from actual and predicted labels. See the Lisp example and its generated figure. The example uses synthetic class labels, not real model predictions.

Train smarter with one Lisp macro

Long PyTorch experiments can stop when a selected validation metric stops improving. The new train-until macro handles this policy while keeping checkpoints, histories, and the exact number of completed epochs:

(require lispyn.macros [train-until])
(setv run
  (train-until model training-data 8
    :validation validation-data
    :loss-fn loss-function
    :epochs 300
    :min-delta 0.0005
    :experiment-dir "runs/experiment"))

300 is the maximum: if the monitored loss does not improve by more than min-delta for eight consecutive epochs, training stops early. With an experiment directory, the run records best.pt, last.pt, history.json, and a summary of the completed epochs in manifest.json. The model returned by the run remains at the last epoch; the best weights can be restored explicitly with load_checkpoint.

Try the offline early-stopping notebook or its Lisp source.

Full experiment — ResNet18, two-stage fine-tuning

The following is the complete source of examples/resnet_finetune_300.hy, including its Markdown cells. Put your images in examples/data/resnet_images/<class_name>/*.jpg (or .png); each class needs multiple images. The first stage trains the classifier for 10 epochs, then the second unfreezes all layers for 300 epochs.

; ResNet18 experiment: all results are Python/Jupyter notebook cells.
; Required actual images: examples/data/resnet_images/class_name/*.jpg or *.png
; This source is NOT executed in CI (300 epochs need a real dataset/GPU).
(require lispyn.macros [md])

(md "# ResNet18 — transfer learning + full fine-tuning"
    "An end-to-end **PyTorch** experiment written in Lispyn. It loads labeled images, splits by class, runs head-only tuning, then unfreezes the backbone for **300 epochs**, and produces publication-ready curves."
    "**Author:** Eduardo J. Barrios · **Source:** Lispyn.")

(md "## Install required libraries"
    "The **pip-install** macro generates a dedicated Python notebook setup cell. Already available packages report *Requirement already installed in this environment*; only missing packages are installed in the current kernel."
    "Python standard-library modules such as `math` need no installation. For CUDA/accelerator setups, install matching PyTorch/TorchVision builds beforehand. Installing native packages may require a kernel restart.")

(require lispyn.macros [pip-install])
(pip-install "torch" "torchvision" "matplotlib>=3.8")

(require lispyn.macros [use-package])
(setv math (use-package "math" :install False))
(print "math.sqrt(16):" (math.sqrt 16))

(md "## Load and split the image dataset"
    "Use the original TorchVision preprocessing for the pretrained ResNet18 weights. Classes come from your own image folders; samples are split reproducibly into training and validation.")
(import torch)
(import torchvision)
(import lispyn.media [image-folder])
(import lispyn.data [split-dataset])
(import lispyn.reproducibility [seed-all])

(seed-all 42)
(setv weights torchvision.models.ResNet18_Weights.DEFAULT)
(setv dataset (image-folder "data/resnet_images" :transform (weights.transforms)))
(setv groups (split-dataset dataset :stratify True :validation-fraction 0.2 :seed 42))
(setv training (get groups 0))
(setv validation (get groups 1))
(setv model (torchvision.models.resnet18 :weights weights))
(setv model.fc (torch.nn.Linear model.fc.in_features (len dataset.classes)))
(print "Classes:" dataset.classes)
(print "Train/validation:" (len training) (len validation))

(md "## Phase 1 — classifier fine-tuning"
    "Freeze the pretrained ResNet18 backbone and optimize only `model.fc` for **10 epochs**. The class split is reproducible and separate from the training set."
    "**Note:** This example needs at least two labeled images per class. For correlated images from the same subject, use a *group-aware split* instead.")

(require lispyn.macros [head-tune])
(setv head-run
  (head-tune model training "fc"
    :validation validation
    :loss-fn (torch.nn.CrossEntropyLoss)
    :epochs 10
    :batch-size 16
    :lr 0.001
    :seed 42
    :metrics "accuracy"
    :experiment-dir "runs/resnet/head"))
(print "Head validation accuracy:" (get head-run.history "val_accuracy"))

(md "## Phase 2 — deep/full fine-tuning: 300 epochs"
    "Unfreeze **every ResNet18 layer**, create a new optimizer with a smaller learning rate, and train for **300 epochs**. This is full fine-tuning of pretrained weights, **not** training from scratch."
    "A real 300-epoch run may take hours and require a GPU. Run it only with your own dataset and appropriate resources.")

(require lispyn.macros [full-tune])
(setv deep-run
  (full-tune head-run.model training
    :validation validation
    :loss-fn (torch.nn.CrossEntropyLoss)
    :epochs 300
    :batch-size 16
    :lr 0.00001
    :seed 42
    :metrics "accuracy"
    :experiment-dir "runs/resnet/deep"))
(print "Full tuning best accuracy:" (max (get deep-run.history "val_accuracy")))

(md "## Curves and export"
    "Use one Lisp macro to define a consistent Matplotlib style for **both** training curves. The best checkpoints and JSON histories are saved under `runs/resnet/`.")

(require lispyn.macros [defcurve])
(defcurve resnet-curve
  :theme "paper"
  :train-color "#2563EB"
  :val-color "#D97706"
  :xlabel "Epoch"
  :train-label "Train"
  :val-label "Validation"
  :figsize [9 4])

(resnet-curve deep-run :metric "loss"
  :title "ResNet18 — 300-epoch loss"
  :ylabel "Cross-entropy loss"
  :save "runs/resnet/deep/loss.png")

(resnet-curve deep-run :metric "accuracy"
  :title "ResNet18 — 300-epoch accuracy"
  :ylabel "Top-1 accuracy"
  :save "runs/resnet/deep/accuracy.png")
(print "Saved ResNet18 plots, histories, and best checkpoints.")

Generated notebook

Open the generated ResNet18 notebook in example_generated_notebooks/. It contains real Markdown and translated Python code cells, but no simulated losses or training outputs. Use lispyn gallery to regenerate the examples without running training.

To install Lispyn from this repository, use python -m pip install -e ".[notebook,plots]". Run lispyn build examples/resnet_finetune_300.hy to regenerate the notebook, or lispyn execute examples/resnet_finetune_300.hy -o example_generated_notebooks/resnet_finetune_300.ipynb to actually train and save the outputs.

The pip-install macro creates a dedicated dependency cell that checks availability when the notebook runs, not when it compiles. Available packages print Requirement already installed in this environment. Missing named packages can be installed through the notebook kernel’s Python interpreter. Python's standard-library math module requires no pip install. GPU-compatible PyTorch builds should normally be installed separately in advance; installing packages into a running kernel may require a restart.

This experiment has not been trained for 300 epochs in CI. It needs an image dataset and may require substantial compute. Stratified sample-level splitting is not group-aware; use a grouped split when images come from the same subjects, patients or sessions.

More capabilities, examples and package options are in the technical guide. Created by Eduardo J. Barrios. Apache-2.0 licensed; see LICENSE and NOTICE.

Metadata

Release files for lispyn 0.17.0a1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lispyn 0.17.0a1
File Size Uploaded Provenance Actions
lispyn-0.17.0a1.tar.gz 64.7 kB With provenance Details for lispyn-0.17.0a1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for lispyn 0.17.0a1
File Interpreter ABI Platform Actions
lispyn-0.17.0a1-py3-none-any.whl Python 3 none any Details for lispyn-0.17.0a1-py3-none-any.whl

Total release size: 111.2 kB

Release files / lispyn-0.17.0a1.tar.gz

Download URL lispyn-0.17.0a1.tar.gz
Size 64.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f29bdde3f4184dcd215c7f445ad0803eea503945141a255e2e649f7471f3f6cc
BLAKE2b-256 checksum
How to use checksums
d81190a88054377b3383c4aaaf6a7828315aeeaf4a1fc0a4767fb72485847154
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 13, 2026.

Transparency log

Release files / lispyn-0.17.0a1-py3-none-any.whl

Download URL lispyn-0.17.0a1-py3-none-any.whl
Size 46.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
49498bde991018391f603cc9cec6606406fa4d41c3b7c71c26b19eb2697701bf
BLAKE2b-256 checksum
How to use checksums
51375c4c4d698d516d0489cf9ec18743b736f8351d97ea6f3c2b674370f4aa91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 13, 2026.

Transparency log

Security for lispyn 0.17.0a1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for lispyn-0.17.0a1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 13, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page