Get started¶
nefi needs Python ≥ 3.10 and PyTorch ≥ 2.1. A CPU is enough for every tutorial, every smoke run and the whole test suite; paper-scale runs go to a CUDA machine.
Install¶
Installs the library and the nefi command with its core dependencies (torch, numpy,
scipy, pyyaml, tqdm). Extras add figures, the richer command line, or the development tools:
git clone https://github.com/CAB-Lab-Princeton/NEFI.git && cd NEFI
pip install -e ".[dev]" # + pytest, ruff, mypy, scikit-image, matplotlib, typer, rich
make test # fast CPU suite: python -m pytest -q -m "not slow"
This is the setup for contributing and for the examples under examples/.
git clone https://github.com/CAB-Lab-Princeton/NEFI.git && cd NEFI
conda env create -f environment.yml && conda activate nefi # python 3.11, torch, nefi[dev]
python -c "import torch; print(torch.__version__, torch.cuda.is_available())"
The pip torch wheel on Linux bundles its CUDA runtime; to pin a CUDA version install
torch from the matching index before the package. See
Running on GPU servers.
Check the installation:
nefi --version
nefi list instances # the registered problems
nefi run toy1d --smoke # generate → invert → evaluate, a few seconds on a CPU
Devices
device="auto" (the default everywhere) uses $NEFI_DEVICE when set, else CUDA when
available, else the CPU. Apple MPS is used only when requested explicitly (--device mps):
it lacks float64 and some FFT and grid_sample kernels that several operators need.
A first inversion¶
toy1d recovers a non-negative 1-D signal from its blurred, noisy observation. It exercises
every core mechanism — a neural field with annealed Fourier features, a softplus head, an FFT
convolution rebuilt at every resolution, a two-stage multiscale curriculum, TV regularization,
and an inverse-crime-safe data generator — and finishes in seconds.
import torch
import nefi
k = torch.tensor([1.0, 4.0, 6.0, 4.0, 1.0])
k = (k[:, None] * k[None]) / 256
def forward(x): # a blurred, saturating camera
blurred = torch.nn.functional.conv2d(x[None, None], k[None, None], padding=2)[0, 0]
return torch.tanh(1.5 * blurred)
x_true = torch.zeros(64, 64); x_true[20:44, 16:40] = 1.0
y = forward(x_true) + 0.01 * torch.randn(64, 64)
problem = nefi.from_forward(forward, y, shape=(64, 64),
prior="nonnegative + piecewise_constant")
result = nefi.invert(problem)
print(nefi.quick_report(result, problem, gt=x_true))
The quickstart tutorial walks through the output line by line,
and Bring your own problem explains every automatic decision of from_forward.
Where next¶
-
Learn the recipe
Quickstart → Anatomy of a problem → Core concepts. Seven pieces, one contract.
-
Invert your own physics
Bring your own problem with
from_forwardand the prior DSL, then the zoo of operators, representations and losses. -
See what it does
The gallery of all registered systems, the 3-D showcase with interactive viewers, and the instance catalogue.
-
Reproduce the papers
The papers, the paper → code map and the server runbook with exact commands and costs.
The tutorials¶
| # | tutorial | what you learn |
|---|---|---|
| 1 | Quickstart | toy1d end to end, from Python and from the CLI; what a run writes |
| 2 | Anatomy of a problem | Domain, Field, Operator, Losses, Curriculum, Solver, post-processing — built by hand |
| 3 | A new forward operator | an operator, an inverse-crime-safe data generator, at_resolution for multiscale |
| 4 | A new instance | the Instance protocol, the registry, config YAML and the CLI |
| 5 | Diagnostics | what each diagnostic tells you, with the papers' numbers as reference points |
| 6 | Benchmarking | protocol, confidence intervals, ablations, sweeps; cross-fidelity vs matched operator |
| 7 | Running on GPU servers | scripts, SLURM, memory and time expectations, torch.compile, checkpoints |
| 8 | Robustness and adaptivity | safety features, noise-aware stopping, nuisance parameters, ensembles, robust fidelities |