Skip to content

project-numina/kimina-lean-server

Repository files navigation

Kimina Lean Server

Check Lean 4 code at scale ⚡️

Project Numina PyPI version CI

This project serves the Lean REPL using FastAPI. It supports parallelization to check Lean 4 proofs at scale.

A Python SDK simplifies interaction with the server's API.

Read the Technical Report for more details.

Table of Contents

This repository contains the source code for:

  • the Kimina server
  • the Kimina client to interact with it

Server

From source with requirements.txt (option to use uv, see Contributing):

cp .env.template .env # Optional
bash setup.sh # Installs Lean, repl and mathlib4
pip install -r requirements.txt
pip install .
prisma generate
python -m server

Note

Make sure mathlib4 and repl exist in the workspace directory before launching the server from source.

Or with docker compose up (pulls from Docker Hub).
Equivalent run command is:

docker run -d \
  --name server \
  --restart unless-stopped \
  --env-file .env \
  -p 80:${LEAN_SERVER_PORT} \
  projectnumina/kimina-lean-server:2.0.0

To shut down the container / view logs:

docker compose down
docker compose logs -f

Build your own image with specific Lean version with:

docker build --build-arg=LEAN_SERVER_LEAN_VERSION=v4.21.0 .

Test it works with a request:

curl --request POST \
  --url http://localhost/verify \
  --header 'Content-Type: application/json' \
  --data '{
    "codes": [
      {
        "custom_id": "1234",
        "proof": "#check Nat"
      }
    ],
    "infotree_type": "original"
}' | jq

Or use the client below.

Client

From PyPI:

pip install kimina-client

Example use:

from kimina_client import KiminaClient
client = KiminaClient() # Defaults to "http://localhost:8000", no API key
client.check("#check Nat")

Or from source with pip install -e .

⚙️ Environment Variables

Variable Default Description
LEAN_SERVER_HOST 0.0.0.0 Host address to bind the server
LEAN_SERVER_PORT 8000 Port number for the server
LEAN_SERVER_LOG_LEVEL INFO Logging level (DEBUG, INFO, ERROR, etc.)
LEAN_SERVER_ENVIRONMENT dev Environment dev or prod
LEAN_SERVER_LEAN_VERSION v4.15.0 Lean version
LEAN_SERVER_MAX_REPLS CPU count - 1 Maximum number of REPLs
LEAN_SERVER_MAX_REPL_USES -1 Maximum number of uses per REPL (-1 is no limit)
LEAN_SERVER_MAX_REPL_MEM 8G Maximum memory limit for each REPL (Linux-only)
LEAN_SERVER_MAX_WAIT 60 Maximum wait time to wait for a REPL (in seconds)
LEAN_SERVER_INIT_REPLS {} Map of header to REPL count to initialize with
LEAN_SERVER_API_KEY None Optional API key for authentication
LEAN_SERVER_REPL_PATH repl/.lake/build/bin/repl Path to REPL directory, relative to workspace
LEAN_SERVER_PROJECT_DIR mathlib4 Path to Lean 4 project directory, relative to workspace
LEAN_SERVER_DATABASE_URL URL for the database (if using one)

LEAN_SERVER_MAX_REPL_MEM can help avoid certain OOM issues (see Issue #25) The server also runs all commands with "gc": true to automatically discard environments which helps limit memory usage.

🚀 Performance Benchmarks

You can run benchmarks with the Kimina client on any HuggingFace dataset: the benchmark run expects id and code columns in the dataset, but you can select your own column names.

Example with Goedel-LM/Lean-workbook-proofs:

from kimina_client import KiminaClient

client = KiminaClient()
client.run_benchmark(dataset_name="Goedel-LM/Lean-workbook-proofs", 
                     n=1000,
                     batch_size=8,
                     max_workers=10)

If running benchmarks using the synchronous client (KiminaClient instead of AsyncKiminaClient) from an end-user computer, you may face the following error:

tenacity.before_sleep:log_it:65 - Retrying main.Lean4Client._query..query_with_retries in 10.0 seconds as it raised ClientConnectorError: Cannot connect to host 127.0.0.1:80 ssl:default [Too many open files].

This happens when you set a number of max_workers greater than the allowed number of TCP connections on your machine. The synchronous client could not reliably make use of the same connection across threads, so each worker has its session.

You can check the maximum number of open files on your machine with ulimit -n (256 on a MacBook Pro). It may be smaller than what's needed to run the benchmark: increase it with ulimit -n 4096.

Alternatively, you can use the asynchronous client AsyncKiminaClient which uses a single session and can handle more workers without running into this issue.

Benchmark reports

Without REPL reuse: Benchmark Results without REPL reuse

With REPL reuse: Benchmark Results with REPL reuse

Note:

The benchmarks were run on a machine with 10 CPUs (MacBook Pro M2) with the above command and default parameters. The dataset is available at Goedel-LM/Lean-workbook-proofs.

To reproduce:

  • Server command: python -m server (no .env file)
  • Client (from ipython / Jupyter notebook or python -m asyncio):
from kimina_client import AsyncKiminaClient
client = AsyncKiminaClient() # defaults to "http://localhost:8000", no API key

# Add `reuse=False` to prevent REPL reuse across requests
await client.run_benchmark(dataset_name="Goedel-LM/Lean-workbook-proofs", n=1000)

Contributing

Contributions are welcome 🤗, just open an issue or submit a pull request.

To contribute, ensure you have Astral's uv installed and:

uv run pre-commit install

On commit, the hooks:

mypy was slow against the client directory, so I excluded it in the pre-commit config, therefore also on the CI. You can still run mypy manually to check.

An additional hook runs basic tests on push.

Tip

Use --no-verify to skip hooks on commit / push (but the CI runs them).

Install Lean 4 and build the repl and mathlib4:

bash setup.sh

Run tests with (reads your LEAN_SERVER_API_KEY so make sure that line is commented):

pytest

# Performance tests on first rows of Goedel (ensures less than 10s average check time per proof)
pytest -m perfs

# Tests on 100 first Goedel rows to validate API backward-compatibility
pytest -m match # Use -n auto to use all cores.

To release the client:

  • bump the version in pyproject.toml and run uv lock
  • run the "Publish to PyPI" action on Github

To release the server:

  • bump the version in compose-prod.yaml and in Dockerfile
  • run the "Deploy to Google Cloud" action on Github
  • run the "Publish to Docker" action on Github (doesn't exist yet)

If you change dependencies (uv.lock), make sure to generate requirements.txt again with:

uv export --extra server --no-dev --no-emit-project --no-hashes > requirements.txt

License

This project is licensed under the MIT License. You are free to use, modify, and distribute this software with proper attribution. See the LICENSE file for full details.

Citation

@misc{santos2025kiminaleanservertechnical,
      title={Kimina Lean Server: Technical Report}, 
      author={Marco Dos Santos and Haiming Wang and Hugues de Saxcé and Ran Wang and Mantas Baksys and Mert Unsal and Junqi Liu and Zhengying Liu and Jia Li},
      year={2025},
      eprint={2504.21230},
      archivePrefix={arXiv},
      primaryClass={cs.LO},
      url={https://arxiv.org/abs/2504.21230}, 
}

About

Kimina Lean server (+ client SDK)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 7

Languages