NeurIPS 2026
Kang Yang, Mani Srivastava — University of California, Los Angeles
RxGS synthesizes RF data (RSSI, spatial spectrum, CSI) at any transmitter and any receiver in a scene with a single model. Stage I learns receiver-independent 3D Gaussian geometry; Stage II freezes it and learns directional radiance conditioned on the receiver position through a global and a local conditioning branch.
This repository contains the code to train and evaluate RxGS on the three datasets in the paper.
python3.10 -m venv .venv && source .venv/bin/activate
pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cu121
pip install \
-e submodules/simple-knn \
-e submodules/complex-gaussian-tracer \
-e submodules/complex-gaussian-tracer-csi \
-e submodules/complex-gaussian-tracer-multirx \
-e submodules/fused-ssim
pip install tqdm plyfile matplotlib lpips pyyaml pandas scipy imageio "numpy<2"The spatial spectrum dataset is on 🤗 kyang73/RxGS-data (pip install -U huggingface_hub provides the hf command):
hf download kyang73/RxGS-data spectrum_multirx.tar --repo-type dataset --local-dir data
tar -xf data/spectrum_multirx.tar -C data && rm data/spectrum_multirx.tarThis gives data/spectrum_multirx/ — 90×360 spatial spectra (5,089 TXs × 21 RXs, simulated with Sionna RT).
The BLE RSSI dataset (6,000 TXs × 21 gateways) comes from NeRF²: download BLE/rssi-dataset-1.tar.gz from the NeRF² dataset link and place its gateway_rssi.csv, tx_pos.csv and gateway_position.yml under data/ble_rssi/.
The CSI dataset is built from the KU Leuven Ultra-Dense Indoor MaMIMO CSI dataset (free IEEE DataPort account required). Download ultra_dense.zip, extract the distributed-antenna scenario, and preprocess it:
unzip ultra_dense.zip "ultra_dense/DIS_lab_LoS/*"
python -m scripts.preprocess_kuleuven_csi --data_dir ultra_dense/DIS_lab_LoSThis writes data/csi/ — 52-channel complex CSI (6,000 TXs × 8 distributed RXs).
Checkpoints for the three RxGS models are on 🤗 kyang73/RxGS-pretrained:
| File | Dataset | Iterations (Stage I + II) | Config |
|---|---|---|---|
ble_rssi.pth |
BLE RSSI | 30k + 100k | exp_ble_multirx_main.yaml |
spectrum_multirx.pth |
Spatial spectrum | 30k + 60k | exp_spectrum_multirx_main.yaml |
csi.pth |
WiFi CSI | 30k + 100k | exp_csi_multirx_main.yaml |
To evaluate them without training:
hf download kyang73/RxGS-pretrained --include "*.pth" --local-dir pretrained
python -m scripts.inference_ble_multirx --config arguments/configs/exp_ble_multirx_main.yaml --checkpoint pretrained/ble_rssi.pth
python -m scripts.inference_spectrum_multirx --config arguments/configs/exp_spectrum_multirx_main.yaml --checkpoint pretrained/spectrum_multirx.pth
python -m scripts.inference_csi_multirx --config arguments/configs/exp_csi_multirx_main.yaml --checkpoint pretrained/csi.pthEach modality has one training + inference wrapper. All wrappers accept --gpu N and --config <path>. The Python scripts they call live in scripts/ and run from the repository root as modules (e.g. python -m scripts.train_ble_multirx --config arguments/configs/exp_ble_multirx_main.yaml). Inference uses the latest checkpoint by default (--iter N on the inference script to override).
bash run_ble_multirx.sh --gpu 0
bash run_spectrum_multirx.sh --gpu 0
bash run_csi_multirx.sh --gpu 0Stage I geometry (Phase 1 in the code) is saved to a dataset-level shared path (logs/<dataset>/geometry.pth), and later runs on the same dataset reuse it (pass --retrain_geometry to train it again). Stage II (Phase 2) saves two checkpoints per run: chkpnt{film_iters/2}.pth (halfway) and chkpnt{film_iters}.pth (final).
Each script writes outputs to:
logs/<dataset>/<exp_name>/— training checkpoints and configlogs/<dataset>/<exp_name>/inference/— inference outputs
The single-RX scripts train one GSRF model per receiver without receiver conditioning:
bash run_ble_singlerx.sh --gpu 0
bash run_spectrum_singlerx.sh --gpu 0
bash run_csi_singlerx.sh --gpu 0Each receiver's model is saved to logs/<dataset>/singlerx_main/<rx>/. scripts/train_spectrum_singlerx.py and scripts/train_csi_singlerx.py accept --rx_idx N to train a single receiver (e.g. python -m scripts.train_spectrum_singlerx --rx_idx 0). For BLE, the first gateway is trained in full and the remaining gateways reuse its geometry and train only their FLE coefficients.
@inproceedings{yang2026rxgs,
title = {RxGS: Receiver-Generalizable 3D Gaussian Splatting for Radio-Frequency Data Synthesis},
author = {Yang, Kang and Srivastava, Mani},
booktitle = {Advances in Neural Information Processing Systems (NeurIPS)},
year = {2026}
}RxGS builds on GSRF and 3D Gaussian Splatting. The BLE RSSI data comes from NeRF², the CSI data from the KU Leuven Ultra-Dense Indoor MaMIMO CSI dataset, and the spatial spectrum data was simulated with Sionna RT.
This code is released under the BSD 3-Clause License. The CUDA rasterizer submodules (submodules/simple-knn, submodules/complex-gaussian-tracer*) are derived from 3D Gaussian Splatting and remain subject to the Gaussian-Splatting License in their LICENSE.md files, which permits non-commercial research and evaluation use only. submodules/fused-ssim is fused-ssim under its MIT License. The spatial spectrum dataset on 🤗 RxGS-data is released under CC BY 4.0.