This repo explains the concept of learning-to-optimize with a couple of simple demonstrations.
Formally, an optimization task is a pair
Let
An optimizer
where
In L2O,
For task
The learned optimizer is a parametric stateful map
where
The meta-objective is a functional of the induced inner trajectory, typically a weighted sum of per-step losses:
Since
This repo implements meta-training of neural optimizers (OptimizerNeural* in l2o/models.py) on batches of problem-specific optimizee tasks (problems/*/optimizee.py). To this end, it uses a mean inner loss over unrolled steps with truncated backpropagation through time (BPTT).
See (Andrychowicz et al.) for more details.
Let us look at the Adam optimizer to see how it fits into the framework introduced above. Adam maintains moment estimates
with
With the notation above, the update rule for the optimized parameters
Adam uses optimizer state
In L2O, in contrast,
A central design question in L2O is how to represent
A coordinate-wise architecture applies the same network to each coordinate
This repo uses stacked LSTM cells with log-encoded gradients l2o/models.py (OptimizerNeuralCoordinatewiseGradEnc).
For each task, let
Meta-training samples random
We compare Adam (with learning rate chosen on a separate random quadratic) to the meta-trained learned optimizer.
The trajectory plot shows
See l2o_example.ipynb for a playground.
Inverse Lithography Technology (ILT) is a photomask optimization technique in semiconductor manufacturing that calculates mask shapes needed to produce a desired wafer pattern.
The forward lithography chain is often written schematically as
with
During this process, the high-frequency components of the diffracted mask image are lost, causing a blurred version of the mask image at the imaging (wafer) plane.
Classical ILT seeks a mask whose forward lithography response matches a target layout
There is generally no closed-form solution for
Under the Hopkins approximation, partially coherent imaging can be written as a sum of coherent systems (SOCS): a quadratic form in the mask spectrum. In the spatial domain, a common scalar abstraction is a sum of squared convolutions or a weighted sum of blurred mask intensities:
where
Process conditions (e.g. nominal / max / min defocus) use slightly different kernels
A simple sigmoid resist model maps aerial intensity to a printed value in
with gain
Given a target layout image
ILTOptimizee in problems/ilt/optimizee.py flattens mask logits SimplifiedLitho (Gaussian kernels + sigmoid resist), and returns per-batch mean squared error plus a PV penalty.
A recent line of work combines L2O with ILT. The L2O-ILT framework from (Zhu et al.) unrolls the iterative ILT optimization into a learnable neural network, motivated by the general L2O paradigm.
L2O-ILT adopts ILT-specific structure in the network so that it can output a high-quality initial mask amenable to fast refinement, improving both mask printability and runtime relative to hand-crafted algorithms, such as gradient descent.
The present codebase is a minimal L2O demo, and not a reimplementation of the solution from the paper.
Note: This repo uses a toy SOCS litho in ILTOptimizee, not full industrial simulation.
Main trainer: scripts/train_ilt_l2o.py meta-trains on synthetic ICCAD-style .glp files under data/synthetic_glp_train/ by default (see Quick-start to generate them).
ICCAD eval clips are stored only under benchmarks/iccad2013/ (not under data/).
Architecture: scripts/train_ilt_l2o.py uses gradenc only - OptimizerNeuralCoordinatewiseGradEnc (two LSTM layers per coordinate) in l2o/models.py.
The eval script tunes AdaGrad, RMSprop, and Adam learning rates on a small subset of training layouts, then runs the same inner-step budget for every optimizer on each ICCAD clip. Reported L2 and PVB follow the LithoBench protocol: bilinear upsampling to 2048x2048 and binarization at 0.5.
Columns are binarized L2 / PVB at eval_size (LithoBench-style), not the smooth training-time MSE. Numbers below match checkpoints/ilt_l2o.pt from default scripts/train_ilt_l2o.py (synthetic .glp training), with LR tuning on data/synthetic_glp_train via --tune-glp-dir.
| Optimizer | Mean total |
Mean L2 (bin., |
Mean PVB (bin.) |
|---|---|---|---|
| AdaGrad (tuned lr) | 0.044 | 0.041 | 0.039 |
| RMSprop (tuned lr) | 0.040 | 0.037 | 0.039 |
| Adam (tuned lr) | 0.043 | 0.040 | 0.038 |
| Learned optimizer | 0.037 | 0.034 | 0.040 |
Here ilt/eval/metrics.py, with the same ILTOptimizee in problems/ilt/optimizee.py.
On these mean ICCAD benchmark numbers (L2O meta-trained on synthetic ICCAD-style .glp, ICCAD-only eval), the README checkpoint improves total scripts/train_ilt_l2o.py.
Environment setup
python -m pip install -r requirements.txtDownload ICCAD .glp eval clips (stored under benchmarks/iccad2013/)
get_benchmarks.shGenerate synthetic ILT training clips (ICCAD-style .glp; default input directory for scripts/train_ilt_l2o.py)
python scripts/prepare_ilt_training_data.py synthetic --n 256 --out data/synthetic_glp_train --seed 42Skip this if data/synthetic_glp_train/ already has enough synth_train_*.glp files for training.
Train a learned optimizer on quadratic objectives
python scripts/train_quadratic_l2o.pyTrain a learned optimizer on ILT (synthetic .glp by default; writes checkpoints/ilt_l2o.pt)
python scripts/train_ilt_l2o.py --out checkpoints/ilt_l2o.ptEvaluate on the ICCAD benchmark (use --grid 32 to match the default checkpoint)
python scripts/eval_ilt_benchmark_table.py --checkpoint checkpoints/ilt_l2o.pt --tune-glp-dir data/synthetic_glp_train --grid 32 --inner-steps 512 --eval-size 2048 --device cudaRegenerate README figures (optional): python scripts/gen_readme_figures.py or python scripts/gen_readme_figures.py --only-ilt for the ILT comparison panel.



