More Works from Our Lab

CWI:Composite Humanoid Whole-Body Imitation System for Loco-manipulation Occupancy Reward Shaping: Improving Credit Assignment for Offline Goal-Conditioned Reinforcement Learning Bayes Adaptive Monte Carlo Tree Search for Offline Model-based Reinforcement Learning
Agentic Intelligence Lab | HKU

Offline Reinforcement Learning for Plasma Control in Nuclear Fusion

Yang Fu*,1, Haomin Bao*,1, Rohit Sonker2, Xiaoyan Hu2, Aravind Venugopal2, Jeff Schneider2, Jiayu Chen†,1
1The University of Hong Kong, 2Carnegie Mellon University

*Indicates equal contribution. †Indicates corresponding author.

NeurIPS 2026

Abstract

Offline reinforcement learning (RL) offers a promising route for developing plasma controllers from historical tokamak data, since online trial-and-error on real devices is costly and risky. However, progress in this direction remains difficult to measure due to the lack of a standardized offline RL benchmark for realistic multi-actuator, long-horizon plasma control problems in nuclear fusion. We introduce RL4F, an Offline Reinforcement Learning Benchmark for Plasma Control in Nuclear Fusion, providing closed-loop evaluation environments and baseline comparisons across four full-profile tracking tasks: rotation, density, temperature, and pressure. The dynamics function underlying the evaluation environment is built from historical discharge data from DIII-D, a real-world tokamak. We evaluate a broad set of imitation learning and offline RL baselines under a unified protocol. We find that offline model-based RL methods obtain the best average performance on most objectives, although no single method dominates all tasks, highlighting the importance of dynamics modeling in complex, long-horizon plasma control tasks. To foster further research, we open-source the codebase, datasets, and evaluation framework, providing a benchmark not only for the fusion community but also for algorithm development in offline RL. We evaluate a broad set of imitation learning and offline RL baselines under a unified protocol. We find that offline model-based RL methods obtain the best average performance on most objectives, although no single method dominates all tasks, highlighting the importance of dynamics modeling in complex, long-horizon plasma control tasks. To foster further research, we open-source the codebase, datasets, and evaluation framework, providing a benchmark not only for the fusion community but also for algorithm development in offline RL.

Simulator

RL4F benchmark workflow with DIII-D data, RPNN dynamics ensemble, and closed-loop policy evaluation

Given the limited accessibility of real tokamak devices, we train a reference dynamics model as a digital twin. The reference dynamics model is trained from historical DIII-D experimental discharges and is used to generate offline training data and to provide the closed-loop evaluation environment. As shown below, we adopt a two-stage RPNN training procedure.

1

Stage 1 Mean Optimization

The first stage optimizes the predictive mean using a mean-squared error objective.

2

Stage 2 Uncertainty Calibration

The second stage initializes from the first-stage checkpoint, freezes the predictive backbone, and trains the log-variance head using a negative log-likelihood objective, thereby calibrating uncertainty without changing the learned mean dynamics.

Two-stage RPNN training procedure with mean prediction and uncertainty calibration

Results

Profile tracking error (RMSE ↓) across radial locations. Values are reported as mean ± standard error over test shots; lower is better.

Table 1: Rotation profile tracking error (RMSE ↓).
Algorithmψ0.06ψ0.15ψ0.36ψ0.55ψ0.76ψ0.85Average
MeanSEMeanSEMeanSEMeanSEMeanSEMeanSEMeanSE
GCIL32.450.37628.460.33620.730.24015.720.18011.760.13510.280.11617.760.047
TD3BC25.100.31820.990.27414.810.18911.350.1418.690.1047.790.09213.130.038
CQL24.880.36421.090.31915.480.24112.130.1929.280.1438.230.12013.580.044
IQL29.640.43925.720.39118.850.27514.470.20310.870.1499.480.12916.230.051
EDAC26.300.42720.780.35914.430.26111.410.2109.100.1578.310.12913.300.048
MCQ28.450.34424.080.31017.190.22413.220.16710.100.1208.900.10215.100.043
PPO13.960.15910.410.1389.810.1209.850.1248.510.1127.790.1039.360.023
COMBO17.670.30912.850.2528.020.1606.290.1185.290.0855.430.0748.090.032
MOPO18.210.24113.470.2139.190.1637.320.1305.620.0935.200.0768.660.030
MOBILE48.070.72941.590.62030.980.43824.500.33818.930.25816.370.22126.860.083
RAMBO17.220.28012.170.2167.560.1396.330.1065.730.0825.930.0788.030.029
BAMCTS43.470.48838.650.43328.920.31822.240.24416.280.18113.690.15724.380.063
Table 2: Density profile tracking error (RMSE ↓).
Algorithmψ0.06ψ0.15ψ0.36ψ0.55ψ0.76ψ0.85Average
MeanSEMeanSEMeanSEMeanSEMeanSEMeanSEMeanSE
GCIL1.1200.01351.0310.01280.9200.01210.8640.01170.7920.01150.7600.01130.8600.0021
TD3BC1.0930.01321.0090.01260.9000.01170.8400.01130.7610.01090.7270.01070.8360.0021
CQL1.1270.01401.0330.01320.9220.01230.8680.01200.8070.01200.7750.0120.8650.0022
IQL1.0880.01300.9980.01240.8850.01180.8300.01170.7680.01170.7380.01160.8310.0021
EDAC1.2810.01571.1970.01511.0990.01441.0510.01420.9980.01450.9690.01451.0370.0026
MCQ1.0590.01190.9830.01150.8910.01090.8400.01060.7680.01040.7350.01020.8280.0019
PPO1.0480.01310.9140.01250.7700.01150.7170.01080.6610.01000.6300.00960.7330.0020
COMBO0.9660.01150.8700.01070.7450.00980.6760.00940.6020.00910.5780.00880.6910.0017
MOPO0.9880.01080.8980.01050.7840.01030.7230.01020.6480.00960.6210.00930.7270.0018
MOBILE1.3250.01441.2730.01391.2250.01351.2060.01371.1950.01431.1970.01451.1840.0025
RAMBO1.5760.01471.5960.01381.6710.01321.6990.01271.6380.01151.6000.01091.5830.0024
BAMCTS1.2200.01431.1650.01421.1010.01391.0580.01350.9750.01280.9380.01251.0230.0024
Table 3: Temperature profile tracking error (RMSE ↓).
Algorithmψ0.06ψ0.15ψ0.36ψ0.55ψ0.76ψ0.85Average
MeanSEMeanSEMeanSEMeanSEMeanSEMeanSEMeanSE
GCIL0.4920.00550.4610.00520.3930.00450.3250.00370.2380.00280.2060.00250.3230.0008
TD3BC0.4680.00510.4290.00470.3600.00390.2980.00330.2230.00260.1950.00240.3010.0007
CQL0.5630.00540.5260.00490.4430.00410.3600.00340.2590.00260.2230.00230.3620.0008
IQL0.4650.00520.4290.00490.3620.00410.3010.00340.2250.00270.1960.00250.3020.0007
EDAC0.7350.00760.7090.00700.6240.00610.5180.00530.3760.00430.3300.00410.5070.0011
MCQ0.3820.00460.3490.00430.2930.00370.2410.00300.1780.00230.1570.00210.2440.0006
PPO0.4440.00400.3620.00340.2450.00290.2040.00260.1870.00250.1790.00260.2400.0006
COMBO0.4080.00380.3710.00350.3100.00300.2610.00260.2030.00220.1800.00210.2640.0006
MOPO0.2760.00320.2460.00310.2120.00300.1900.00300.1630.00300.1560.00300.1930.0005
MOBILE0.6230.00660.5800.00620.4880.00540.4030.00440.3040.00330.2730.00300.4080.0009
RAMBO1.0440.01051.0040.01000.8480.00870.6520.00710.4060.00480.3320.00410.6550.0016
BAMCTS0.8140.01150.7700.01070.6580.00890.5370.00720.3830.00520.3300.00460.5340.0015
Table 4: Pressure profile tracking error (RMSE ↓).
Algorithmψ0.06ψ0.15ψ0.36ψ0.55ψ0.76ψ0.85Average
MeanSEMeanSEMeanSEMeanSEMeanSEMeanSEMeanSE
GCIL17346.5177.215502.4160.010897.1129.68174.0103.54943.764.23300.242.88775.325.4
TD3BC15496.3154.013049.8133.29079.8108.56998.292.64558.261.63138.142.17628.921.8
CQL13685.7144.811030.1123.66921.792.85275.774.23614.548.42544.533.16162.219.1
IQL15518.4171.713089.6153.79041.5126.16788.6104.74312.766.92951.445.07525.823.8
EDAC12405.6139.39868.5114.96624.981.45648.268.94114.248.92922.334.46016.817.2
MCQ14885.6149.012482.0129.08536.6101.26457.983.54155.554.12852.536.87174.320.8
PPO14511.3143.511680.0117.87149.080.15178.863.53511.941.12482.228.26333.218.8
COMBO14014.7135.611379.7110.57002.473.74959.256.63215.536.82242.725.56095.918.0
MOPO12706.3131.59894.5105.45534.066.73997.452.92892.637.42094.526.55198.616.5
MOBILE15342.5150.712692.0125.88178.690.75738.475.33464.551.92353.136.16854.920.7
RAMBO12437.8133.29786.2109.95790.477.24391.863.43171.143.22276.130.05358.217.0
BAMCTS18697.5180.616093.4152.611559.1119.08715.9103.05420.369.63673.547.79411.525.6
Table 5: Q profile tracking error (RMSE ↓).
Algorithmψ0.06ψ0.15ψ0.36ψ0.55ψ0.76ψ0.85Average
MeanSEMeanSEMeanSEMeanSEMeanSEMeanSEMeanSE
GCIL0.16510.00180.14290.00160.09250.00100.05530.00060.02450.00030.01940.00020.07230.0002
TD3BC0.14550.00160.12630.00140.08290.00090.05570.00060.02430.00030.01970.00020.06520.0002
CQL0.16170.00170.13990.00140.09040.00090.05410.00050.02500.00030.01930.00020.07120.0002
IQL0.16620.00200.14370.00170.09280.00110.05520.00060.02410.00030.01910.00020.07240.0002
EDAC0.17580.00180.15130.00150.09610.00100.05630.00060.02610.00030.02240.00020.07630.0002
MCQ0.18720.00220.16170.00190.10380.00120.06090.00070.02510.00030.01950.00020.08050.0003
PPO0.14070.00170.12230.00150.08120.00100.05190.00070.02910.00040.02350.00030.06580.0002
COMBO0.11590.00170.10160.00150.06930.00100.04580.00070.02700.00040.02340.00030.05620.0002
MOPO0.11510.00180.10100.00160.06940.00110.05000.00080.02980.00040.02380.00030.05640.0002
MOBILE0.16660.00190.14800.00170.10620.00120.07530.00080.04800.00050.04190.00050.08710.0002
RAMBO0.17340.00190.15050.00160.09870.00110.06080.00070.03000.00040.02480.00030.07810.0002
BAMCTS0.15880.00180.13860.00150.09280.00100.05850.00070.02870.00030.02290.00030.07280.0002
Table 6: βN tracking error (RMSE ↓).
AlgorithmMeanSE
GCIL0.41450.0044
TD3BC0.36410.0032
CQL0.33360.0033
IQL0.31390.0039
EDAC0.27850.0028
MCQ0.30010.0035
PPO0.28490.0026
COMBO0.25310.0025
MOPO0.23990.0028
MOBILE0.26600.0027
RAMBO0.20410.0025
BAMCTS0.45390.0036

Visualisation Results

Closed-loop tracking rollouts with actuator signals shown side by side.

Quick Tutorial

Set up RL4F, train a controller, and inspect its tracking performance.

Follow the steps below from the source checkout. For the full configuration and API reference, see the repository README.

  1. Install the environment

    Clone the repository and create the Conda environment. These commands follow the README's PyTorch 2.1.0 / CUDA 11.8 setup.

    git clone --branch release_v1 https://github.com/LucasCJYSDL/Offline-RL-Kit-for-Nuclear-Fusion.git
    cd Offline-RL-Kit-for-Nuclear-Fusion
    conda env create -f environment.yml
    conda activate offline-rl-fusion
    pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 \
      --index-url https://download.pytorch.org/whl/cu118
    pip install -e .

    Install the dynamics dependency, then return to the RL4F source checkout:

    git clone https://github.com/IanChar/dynamics-toolbox.git
    cd dynamics-toolbox
    git checkout rohit-tm
    pip install -e .
    cd ..
  2. Prepare the data and models

    Download and extract the processed datasets into data/processed/. Place the pre-trained dynamics models in models/train/ and models/val/.

    Expected directory layout
    Offline-RL-Kit-for-Nuclear-Fusion/
    ├── data/
    │   └── processed/
    │       ├── full.hdf5
    │       ├── il_data.h5
    │       ├── info.pkl
    │       ├── rl_data.h5
    │       ├── tracking_test.h5
    │       ├── tracking_val.h5
    │       └── used_shots_info.txt
    └── models/
        ├── train/
        │   ├── 0/
        │   ├── 1/
        │   └── …
        └── val/
    Using custom data or model locations

    Set the relevant environment variables before training: OFFLINERLKIT_DATA_ROOT, OFFLINERLKIT_RAW_DATA_DIR, OFFLINERLKIT_PROCESSED_DATA_DIR, OFFLINERLKIT_MODEL_ROOT, OFFLINERLKIT_TRAINING_MODEL_DIR, and OFFLINERLKIT_EVALUATION_MODEL_DIR.

  3. Train a policy

    Start with the README's temperature-control example:

    python scripts/run_ppo.py --env profile_control_new --task temp

    Choose a task matching your data: temp, rotation, dens, pres, q, or betan. Other training entry points include run_cql.py, run_iql.py, run_edac.py, run_td3bc.py, run_combo.py, run_mobile.py, and run_mopo.py.

    Each script loads its task and algorithm defaults from offlinerlkit/configs/benchmark_configs.json; command-line flags override these defaults. Return plots and policy checkpoints are saved in logs/.

    Goal-conditioned imitation learning example
    python scripts/run_gcil.py --env profile_control --task rotation
  4. Evaluate and visualize tracking

    Replace /path/to/your_run_dir with your trained policy's run directory. The visualization script detects the algorithm and saves actuator choices, profile-tracking outputs, and tracking-error summaries.

    python -m visualization.profile_tracking_save --actor_path /path/to/your_run_dir

    Add --test to evaluate on the test split:

    python -m visualization.profile_tracking_save --actor_path /path/to/your_run_dir --test

    Results are written to results/<task>/<algo>/<val|test>/<run>/<seed>/.

Optional: train your own dynamics models

Update data_path and save_path in dynamics/cfgs/rpnn_noshape_gas_benchmark1.yaml and rpnn_noshape_gas_benchmark2.yaml. Before stage two, set its model.load_dir to the model directory produced by stage one.

python dynamics/launch_dynamics.py --cn rpnn_noshape_gas_benchmark1
python dynamics/launch_dynamics.py --cn rpnn_noshape_gas_benchmark2

Evaluate the resulting model:

python dynamics/reevaluate_dynamics.py --model_dir /path/to/trained_model

Q&A

Join our Slack community to ask questions about RL4F, get help with setup and usage, and discuss the benchmark with other researchers.

BibTeX

@misc{fu2026offline,
  title={Offline Reinforcement Learning for Plasma Control in Nuclear Fusion: Codebase and Benchmark},
  author={Fu, Yang and Bao, Haomin and Sonker, Rohit and Hu, Xiaoyan and Venugopal, Aravind and Schneider, Jeff and Chen, Jiayu},
  year={2026},
  eprint={2606.07550},
  archivePrefix={arXiv},
  primaryClass={cs.LG},
  url={https://arxiv.org/abs/2606.07550}
}