An open-source multi-modal toolbox for extracting structured synthesis procedures and performance data from materials science literature — at scale.
Documentation · Quickstart · Tutorials · Dataset · Paper
Give LeMat-Synth a paper — PDF or text — and it returns machine-readable science:
- Synthesized materials, identified by chemical formula
- Step-by-step synthesis procedures, structured into a controlled Pydantic ontology
- Quantitative performance data, read off the paper's plots and linked back to the material it belongs to
- A quality score per extraction, from an LLM judge benchmarked against human annotators
This repository is the reference implementation of LeMat-Synth v1.0 (NeurIPS AI4Mat 2025), plus an extensible codebase for building your own domain-specific extraction studies.
Requires Python 3.11+ and uv.
git clone https://github.com/LeMaterial/lematerial-llm-synthesis.git
cd lematerial-llm-synthesis
uv venv -p 3.11 --seed
uv sync && uv pip install -e .
uv run python -c "import llm_synthesis" # prints nothing if it workedThen add your API keys to .env:
cp .env.example .env
echo "GEMINI_API_KEY=your_key_here" >> .envA free Gemini API key is enough for the
default pipeline. Add ANTHROPIC_API_KEY for reading data off plots, and
MISTRAL_API_KEY for OCR on scanned PDFs.
Tip
The lemat-synth CLI and the notebooks load .env themselves — there is
nothing to source. Full options, including Windows and OpenRouter setups, are in
the Installation guide.
# One paper
lemat-synth extract paper.pdf
# A whole folder, with performance curves read from the figures
lemat-synth batch papers/ output_dir=results/ domain=catalysis with_performance=trueResults land in results/<paper_id>/<material>.json:
What a result file looks like
{
"material": "Ru/MgO(110)",
"synthesis": {
"target_compound": "Ru/MgO(110)",
"target_compound_type": "functional materials & catalysts",
"synthesis_method": "wet impregnation",
"starting_materials": [
{"name": "RuCl3·xH2O", "amount": 0.21, "unit": "g", "purity": "99.9%"}
],
"steps": [
{"step_number": 1, "action": "dissolve",
"conditions": {"temperature": 25, "temp_unit": "C"}},
{"step_number": 2, "action": "calcine",
"conditions": {"temperature": 500, "temp_unit": "C",
"duration": 4, "time_unit": "h", "atmosphere": "Ar"}}
]
},
"performance": {
"plot_data": [{
"series_name": "Ru/MgO(110)",
"coordinates": [[350, 12.4], [400, 41.9], [450, 78.2]],
"x_axis_label": "Temperature", "x_axis_unit": "°C",
"y_axis_label": "NH3 conversion", "y_axis_unit": "%"
}]
},
"evaluation": {
"scores": {"overall_score": 4.2, "structural_completeness_score": 4.5},
"confidence_level": "high"
}
}Every field is explained in Output Format.
Important
Always do a max_papers=5 run first. Cost scales with the number of
materials, not papers — a folder of catalysis papers can be several times
more expensive than the same number of single-material papers.
The extracted data is already published. If someone has already run the pipeline over the papers you care about, reading the dataset costs nothing and needs no API key:
from datasets import load_dataset
synth = load_dataset("LeMaterial/LeMat-Synth", split="train")Both datasets are gated on HuggingFace — request access once, then
hf auth login. See Dataset Access.
Seven runnable notebooks in
examples/notebooks/tutorials/, each stating
its API keys and cost up front. Every one runs locally or on Google Colab —
same file, no edited cells.
| # | Tutorial | Track | API keys | Cost |
|---|---|---|---|---|
| 1 | Explore the LeMat-Synth dataset | Use the data | HuggingFace only | Free |
| 2 | Finding papers | Use the data | HuggingFace only | Free |
| 3 | Batch extraction with the CLI | Extract | Gemini or OpenRouter | Fractions of a cent |
| 4 | Synthesis + performance from a paper | Extract | Gemini + Anthropic, or OpenRouter | $0.10–0.40 |
| 5 | Evaluating extraction quality | Extract | Gemini or OpenRouter | ~Free |
| 6 | Customizing the ontology | Extend | None | Free |
| 7 | Building a custom case study | Extend | Gemini or OpenRouter | Under $0.01 |
uv run jupyter lab examples/notebooks/tutorials/Every tutorial that calls a model has a USE_OPENROUTER flag — set it to True
to route all its calls through a single OPENROUTER_API_KEY instead of
per-provider keys. Prerequisites and the full .env reference are in the
Tutorials documentation.
Three domain-specific studies ship with the repository, each a thin script over
the shared DomainConfig + BatchRunner pair:
| Domain | Extracts | Guide |
|---|---|---|
| Thermocatalysis | Synthesis + NH₃-conversion curves, with a multi-VLM benchmark against human ground truth | Docs |
| Superconductors | Synthesis + Tc, read from text and geometrically from ρ(T) plots | Docs |
| Porous materials | Synthesis + adsorption isotherms for MOFs, zeolites and COFs | Docs |
Building a fourth — electrochemistry, battery cycling, thermoelectrics — means
assembling four pieces and handing them to BatchRunner; you never edit the
pipeline. Tutorial 7
builds one from scratch in a notebook, and the
Building your own case study
guide is the matching API reference.
Note
data/ is git-ignored, so no PDFs or ground-truth files ship with the
repository. Tutorial 2 shows how to assemble a corpus of your own.
| I want to… | Go to |
|---|---|
| Install and run my first extraction | Quickstart |
| Use the published data instead of extracting | Dataset Access |
| See every CLI setting | CLI Reference |
| Understand a result file | Output Format |
| Build a pipeline in Python | Python API |
| Switch LLMs, or run dataset-scale jobs | Configuration & Models |
| Change what gets extracted | Architecture · Tutorial 6 |
| Contribute or use ground-truth annotations | Annotations |
| Fix something that broke | Troubleshooting |
Build the docs locally with uv run mkdocs serve.
Contributions are welcome — new extractors, new domains, and especially new human annotations, which are what make quality measurable.
Read CONTRIBUTING.md for the workflow. In short: branch off
main, use Conventional Commits
(feat:, fix:, docs:), run uvx pre-commit install once so ruff and
nbstripout run on every commit, and open a PR.
To contribute an annotation, run the annotator app and submit the result:
streamlit run examples/scripts/data_curation/annotator_app.pySee the Annotations guide for the full workflow.
If you use LeMat-Synth in your research, please cite:
@misc{lederbauer2026lematsynthmultimodaltoolboxcurate,
title={LeMat-Synth: a multi-modal toolbox to curate broad synthesis procedure databases from scientific literature},
author={Magdalena Lederbauer and Siddharth Betala and Valerie Gentzke and Anamaria Leonescu and Amine Sehaba and Faris Flaifil and Ayush Jain and Alfonso Amayuelas and Nikhil Yelamarthy and Xiyao Li and Grégoire Germain and Stefano Ribes and Stefan P. Schmid and Alexandre Nozadze and Anna Kelmanson and Sudheesh Kumar Ethirajan and Mohd Zaki and Elton Pan and Georgia Channing and Connor W. Coley and Philippe Schwaller and Rocío Mercado and Alexandre Duval and Mathilde L. D. Franckel and Samuel P. Gleason},
year={2026},
eprint={2510.26824},
archivePrefix={arXiv},
primaryClass={cs.DL},
url={https://arxiv.org/abs/2510.26824},
}Apache License 2.0 — see LICENSE.
