API¶
Run it in a notebook
T3_API_density_example.ipynb shows how we can use the _load_and_generate.py but using the API to predict structure densities using our models.
The containerised API provides REST endpoints for preprocessing, training, generation, and metrics.
First-time host setup (Linux + NVIDIA GPU required):
# Install NVIDIA Container Toolkit (Ubuntu/Debian)
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
# Quick sanity checks
docker --version
docker compose version
nvidia-smi
# Verify Docker can access your GPUs
# If successful, this will download a test image and print nvidia-smi table
docker run --rm --gpus all nvidia/cuda:12.6.3-base-ubuntu24.04 nvidia-smi
# Optional: run Docker without sudo, but you need to re-login or reboot for membership to apply
sudo usermod -aG docker $USER
Run this setup before starting the container for the first time, or after changing pyproject.toml, uv.lock, the Dockerfile or system dependencies:
# Make the env file
## In command line
### Copy the template to your local, git-ignored .env file (only edit the .env)
cp docker/.env.example docker/.env
### inject your current host machine's UID and GID into the .env file
sed -i "s/^UID=.*/UID=$(id -u)/" docker/.env
sed -i "s/^GID=.*/GID=$(id -g)/" docker/.env
## In the .env file
### pick GPUs exposed to the API container
### default in template is 0,1 (can do that or all)
NVIDIA_VISIBLE_DEVICES=0,1
DOCKER_GPUS=all
### your API keys to the .env
HF_KEY=your_hf_token_here
WANDB_KEY=your_wandb_key_here
# back in Command line
## make dirs needed for the api
mkdir -p data outputs
## OR Dev Mode
### If Docker still requires sudo:
sudo --preserve-env=HF_KEY,WANDB_KEY,UID,GID make api-up-dev-build
### else
make api-up-dev-build
## Production mode
make api-up-build
Usage Modes (CLI)¶
| Command | Mode | Description |
|---|---|---|
make api-up-dev |
Dev | Uses uvicorn --reload. Restarts on file changes. Best for rapid development. |
make api-up |
Prod | No auto-reload. More stable. Recommended for long-running generation jobs. |
# Start the API
make api-up-dev # Development mode
# OR
make api-up # Production mode
# Utilities
make api-health # Check server status (wait a couple mins before this will work)
make api-logs # Follow logs
make api-down # Stop and cleanup
Running Tests¶
With the API container running, run the test suites to verify the pipeline.
# Fast Routing Tests (Checks if endpoints respond, 10 secs)
make api-test
# Full Integration Tests (Runs generation & metrics end-to-end, ~10 mins)
make api-test-with-integration
# For Local Unit Tests activate environment
source .venv/bin/activate
# Then run tests (1 min)
python -m tests.local.suite --cpu
Quickstart Generation Examples¶
For /generate/direct, provide exactly one of output_parquet or output_cif_dir.
API generation examples (curl)
Direct generation (Explicit Z, Spacegroup targeting)
curl -X POST "http://localhost:8000/generate/direct" \
-H "Content-Type: application/json" \
-d '{
"hf_model_path": "c-bone/CrystaLLM-pi_base",
"reduced_formula_list": "TiO2",
"z_list": "2",
"spacegroups": "P4_2/mnm",
"level": "level_4",
"num_return_sequences": 5,
"max_return_attempts": 2,
"output_parquet": "/app/outputs/test_generated_structures.parquet"
}'
Direct generation (SLME, level_1 so no composition provided)
curl -X POST "http://localhost:8000/generate/direct" \
-H "Content-Type: application/json" \
-d '{
"hf_model_path": "c-bone/CrystaLLM-pi_SLME",
"condition_lists": ["25.0"],
"level": "level_1",
"num_return_sequences": 5,
"output_parquet": "/app/outputs/solar_screening.parquet"
}'
Virtualise a generated CIF (inline element pairs)
Convert an ordered CIF to a disordered virtual crystal using inline matching pairs arrays:
curl -X POST "http://localhost:8000/virtualise" \
-H "Content-Type: application/json" \
-d '{
"input_cif": "/app/outputs/Mg3ZnO4.cif",
"output_cif": "/app/outputs/Mg3ZnO4_virtual.cif",
"virtual_pairs": [["Mg", "Zn"]],
"symprec": 0.003,
"angle_tolerance": 0.5
}'
Virtualise a generated CIF (YAML config file)
Alternatively, supply a YAML config file:
API Training GPU Selection¶
- You can force behavior in requests for training:
"multi_gpu": falseforces single-process launch"multi_gpu": truerequests torchrun (only used when 2+ GPUs are visible)-
"nproc_per_node": Ncaps torchrun workers when multi-GPU is active -
For generate, all available GPUs are used
Troubleshooting (common issues I've seen)¶
- API Permission Denied: Run
chmod 644 API_keys.jsoncandchmod -R 775 outputs data. - Cache Failures:
outputs/anddata/must be owned by the current user:sudo chown -R $USER:$USER outputs data. - Docs: Visit
http://localhost:8000/docsin browser to view the interactive API schema and execute endpoints directly. (needs to be on, or linked to machine where API is running)
Cancel a job or check status¶
To cancel a running job:
To check status of a current job:
Apptainer (Production Build)¶
Use this when you want the API packaged as a portable .sif (e.g. for HPC / no-Docker environments).
1) Build the production Docker image¶
# Builds the docker image so we can make a .sif file from it, this command does not boot up the container.
make api-build
2) Build Apptainer image from Docker daemon (latest tag)¶
3) Run the API from Apptainer (GPU + mounted data/output)¶
Apptainer does not read
.envautomatically, so we export the two API keys:
# If you ran make api-up-build, the container may be up and running
# Run this command to shut it down to clear up the :8000 port for apptainer image
make api-down
# Export the keys Apptainer needs
set -a; source <(grep -E '^(HF_KEY|WANDB_KEY)=' docker/.env); set +a
# warning about api_keys.jsonc is harmless here
make api-apptainer-run
Leave this terminal open. Health checks, tests, and curl commands are identical to the Docker flow (see Running Tests).