aetherscan 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aetherscan/__init__.py +45 -0
- aetherscan/benchmark.py +179 -0
- aetherscan/candidate_figures.py +328 -0
- aetherscan/cli.py +3032 -0
- aetherscan/config.py +1002 -0
- aetherscan/dashboard.py +709 -0
- aetherscan/dashboard_cli.py +51 -0
- aetherscan/dashboard_launcher.py +194 -0
- aetherscan/data_generation.py +1448 -0
- aetherscan/db/__init__.py +21 -0
- aetherscan/db/db.py +2789 -0
- aetherscan/hf_hub.py +547 -0
- aetherscan/inference.py +912 -0
- aetherscan/inference_viz.py +1494 -0
- aetherscan/latent_gif.py +512 -0
- aetherscan/latent_variants.py +352 -0
- aetherscan/logger/__init__.py +21 -0
- aetherscan/logger/logger.py +467 -0
- aetherscan/logger/slack_handler.py +760 -0
- aetherscan/main.py +1269 -0
- aetherscan/manager/__init__.py +21 -0
- aetherscan/manager/manager.py +781 -0
- aetherscan/models/__init__.py +21 -0
- aetherscan/models/random_forest.py +171 -0
- aetherscan/models/vae.py +849 -0
- aetherscan/monitor/__init__.py +19 -0
- aetherscan/monitor/monitor.py +935 -0
- aetherscan/pfb.py +161 -0
- aetherscan/preprocessing.py +2718 -0
- aetherscan/rf_metrics.py +100 -0
- aetherscan/round_data.py +932 -0
- aetherscan/run_state.py +277 -0
- aetherscan/seeding.py +160 -0
- aetherscan/shap_parallel.py +238 -0
- aetherscan/tag_guards.py +206 -0
- aetherscan/train.py +7681 -0
- aetherscan-1.0.0.dist-info/METADATA +1187 -0
- aetherscan-1.0.0.dist-info/RECORD +41 -0
- aetherscan-1.0.0.dist-info/WHEEL +4 -0
- aetherscan-1.0.0.dist-info/entry_points.txt +2 -0
- aetherscan-1.0.0.dist-info/licenses/LICENSE +13 -0
|
@@ -0,0 +1,1187 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aetherscan
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Breakthrough Listen's first end-to-end production-grade DL pipeline for SETI @ scale
|
|
5
|
+
Project-URL: Homepage, https://github.com/zachtheyek/Aetherscan
|
|
6
|
+
Project-URL: Issues, https://github.com/zachtheyek/Aetherscan/issues
|
|
7
|
+
Author-email: Zach Yek <xiaoxiyek1.5@gmail.com>
|
|
8
|
+
Maintainer-email: Zach Yek <xiaoxiyek1.5@gmail.com>
|
|
9
|
+
License-Expression: BSD-3-Clause
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: Anomaly Detection,Data Methods,Deep Learning,Machine Learning,Radio Astronomy,SETI,Signal Processing,Technosignatures
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Environment :: GPU :: NVIDIA CUDA :: 12
|
|
14
|
+
Classifier: Environment :: GPU :: NVIDIA CUDA :: 12 :: 12.4
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
17
|
+
Classifier: Natural Language :: English
|
|
18
|
+
Classifier: Operating System :: Unix
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
24
|
+
Requires-Python: <3.13,>=3.10
|
|
25
|
+
Requires-Dist: astropy<7,>=6.1
|
|
26
|
+
Requires-Dist: h5py<3.12,>=3.11
|
|
27
|
+
Requires-Dist: hdf5plugin
|
|
28
|
+
Requires-Dist: huggingface-hub<1.22,>=1.21
|
|
29
|
+
Requires-Dist: imageio<3,>=2.34
|
|
30
|
+
Requires-Dist: joblib<2,>=1.4
|
|
31
|
+
Requires-Dist: matplotlib<3.10,>=3.9
|
|
32
|
+
Requires-Dist: numpy<2.0,>=1.26
|
|
33
|
+
Requires-Dist: psutil<6.1,>=6.0
|
|
34
|
+
Requires-Dist: python-dotenv<2,>=1.2.2
|
|
35
|
+
Requires-Dist: scikit-image<0.25,>=0.24
|
|
36
|
+
Requires-Dist: scikit-learn<1.6,>=1.5
|
|
37
|
+
Requires-Dist: scipy<1.14,>=1.13
|
|
38
|
+
Requires-Dist: setigen<3,>=2.6
|
|
39
|
+
Requires-Dist: setuptools<81,>=78.1.1
|
|
40
|
+
Requires-Dist: shap<0.47,>=0.46.0
|
|
41
|
+
Requires-Dist: slack-sdk<4,>=3.31.0
|
|
42
|
+
Requires-Dist: tensorflow[and-cuda]==2.17.*
|
|
43
|
+
Requires-Dist: umap-learn<0.6,>=0.5.6
|
|
44
|
+
Provides-Extra: dashboard
|
|
45
|
+
Requires-Dist: pandas<3,>=2.0; extra == 'dashboard'
|
|
46
|
+
Requires-Dist: plotly<6,>=5.24; extra == 'dashboard'
|
|
47
|
+
Requires-Dist: streamlit<1.41,>=1.39; extra == 'dashboard'
|
|
48
|
+
Provides-Extra: dev
|
|
49
|
+
Requires-Dist: pre-commit; extra == 'dev'
|
|
50
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
51
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
52
|
+
Description-Content-Type: text/markdown
|
|
53
|
+
|
|
54
|
+
<h1 align="center">📡 Aetherscan 📡</h1>
|
|
55
|
+
<p align="center">
|
|
56
|
+
<img src="docs/assets/aetherscan-banner.png" alt="Aetherscan">
|
|
57
|
+
</p>
|
|
58
|
+
<p align="center">
|
|
59
|
+
Breakthrough Listen's first end-to-end production-grade deep learning pipeline for SETI @ scale
|
|
60
|
+
<br />
|
|
61
|
+
<br />
|
|
62
|
+
<a href="https://github.com/zachtheyek/Aetherscan/actions/workflows/tests.yml"><img src="https://github.com/zachtheyek/Aetherscan/actions/workflows/tests.yml/badge.svg" alt="Tests"></a>
|
|
63
|
+
<a href="https://pypi.org/project/aetherscan/"><img src="https://img.shields.io/pypi/v/aetherscan.svg" alt="PyPI"></a>
|
|
64
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-BSD_3--Clause-blue.svg" alt="License"></a>
|
|
65
|
+
<a href="https://www.python.org/"><img src="https://img.shields.io/badge/Python-3.10%E2%80%933.12-blue.svg" alt="Python"></a>
|
|
66
|
+
<a href="https://www.tensorflow.org/"><img src="https://img.shields.io/badge/TensorFlow-2.17-orange.svg" alt="TensorFlow"></a>
|
|
67
|
+
<a href="https://developer.nvidia.com/cuda-toolkit"><img src="https://img.shields.io/badge/CUDA-12.4%E2%80%9312.8-green.svg" alt="CUDA"></a>
|
|
68
|
+
</p>
|
|
69
|
+
</p>
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Overview
|
|
74
|
+
|
|
75
|
+
Aetherscan is a deep learning pipeline for detecting anomalies in radio spectrograms with technosignature-like characteristics. It combines a beta-VAE (for dimensionality reduction/feature extraction) with a Random Forest ensemble (for candidate detection), trained on ~30m unique cadence snippets using a composite loss that balances reconstruction, KL divergence, and true/false clustering. The pipeline is designed with performance in mind, by default running single-node distributed training & inference, using zero-copy parallelism during pre- and post-processing.
|
|
76
|
+
|
|
77
|
+
The model architecture is based on [Ma et al. 2023](https://arxiv.org/abs/2301.12670) ("_A deep-learning search for technosignatures from 820 unique stars_"), extending the research prototype into a production-ready system capable of near real-time inference.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Installation
|
|
82
|
+
|
|
83
|
+
### System Requirements
|
|
84
|
+
|
|
85
|
+
Aetherscan supports two install paths off the same source tree. The NGC container is the canonical runtime on both clusters; the conda env is kept as an alternative for users who can't or don't want to use containers on Ampere.
|
|
86
|
+
|
|
87
|
+
**NGC container (canonical, runs on both clusters)**
|
|
88
|
+
|
|
89
|
+
- Ubuntu 24.04
|
|
90
|
+
- ≥1x NVIDIA GPU:
|
|
91
|
+
- Blackwell (sm_120, e.g. RTX PRO 6000) — driver ≥570 (native CUDA 12.8)
|
|
92
|
+
- Ampere (sm_86, e.g. RTX A4000) — driver ≥550 (host CUDA 12.3) via CUDA forward compatibility
|
|
93
|
+
- VRAM: **≥8 GB per GPU** recommended — measured peaks ~6 GB/GPU (training) and ~2.5 GB/GPU (inference) on the v1.0.0 release runs; gradient accumulation keeps per-GPU VRAM low
|
|
94
|
+
- RAM: **≥288 GB** for full-scale training and default catalog-scale inference (measured peaks ~260 GB training / ~200 GB inference, plus headroom — a strict-256 GB host sits too close to the training peak and risks OOM under page-cache pressure). Means are much lower (~150 GB training / ~36 GB inference); inference RAM scales with `--prefetch-depth` × the largest in-flight cadence, so lower `--prefetch-depth` for smaller-RAM hosts or small catalogs
|
|
95
|
+
- Disk: full-scale training round data ~150 GB per retained round (float16 default), up to ~3 TB with `--keep-round-data`; inference stamps are auto-pruned by default (~1 MB/cadence metadata retained + a transient ~5–20 GB/cadence × `--prefetch-depth` during extraction)
|
|
96
|
+
- Apptainer 1.4+ or SingularityCE 4.1+ (Python 3.12 / TF 2.17 / CUDA 12.8 live inside the container)
|
|
97
|
+
- See [`docs/GPU_RUNTIME_GUIDE.md`](docs/GPU_RUNTIME_GUIDE.md) for the full runbook
|
|
98
|
+
|
|
99
|
+
**Conda env (alternative, Ampere only)**
|
|
100
|
+
|
|
101
|
+
- Ubuntu 24.04
|
|
102
|
+
- ≥1x NVIDIA GPU:
|
|
103
|
+
- Ampere with CUDA 12.3+ driver
|
|
104
|
+
- VRAM / RAM same as above
|
|
105
|
+
- Python 3.10 / TF 2.17 (managed by conda)
|
|
106
|
+
|
|
107
|
+
> [!NOTE]
|
|
108
|
+
> There are no plans to support non-Nvidia GPUs
|
|
109
|
+
|
|
110
|
+
> [!NOTE]
|
|
111
|
+
> The figures above are measured from the v1.0.0 release runs — training on 6× RTX A4000 (16 GB) + 503 GB RAM (tag `train_20260729_152426`) and inference on 5× RTX PRO 6000 (96 GB) + 503 GB RAM over a 350-cadence `/datag` catalog subset (tag `inf_20260731_182011`) — via the always-on resource instrumentation (`system_resources` DB rows). They characterize full-scale runs; small runs need substantially less.
|
|
112
|
+
|
|
113
|
+
### Run From Container
|
|
114
|
+
|
|
115
|
+
> [!NOTE]
|
|
116
|
+
> This is the canonical install path, and the only option for Blackwell clusters
|
|
117
|
+
|
|
118
|
+
**1. Clone the repository**
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
git clone https://github.com/zachtheyek/Aetherscan.git
|
|
122
|
+
cd Aetherscan
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**2. Build the `.sif` image**
|
|
126
|
+
|
|
127
|
+
The same [`aetherscan.def`](aetherscan.def) recipe builds with either runtime — use whichever is installed on the host. Build on the cluster you intend to run on so the resulting `.sif` is produced by that cluster's native runtime:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# SingularityCE (e.g. Blackwell cluster running 4.1.1)
|
|
131
|
+
singularity build aetherscan-ngc25.02.sif aetherscan.def
|
|
132
|
+
|
|
133
|
+
# Apptainer (e.g. Ampere cluster running v1.4.5)
|
|
134
|
+
apptainer build aetherscan-ngc25.02.sif aetherscan.def
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Build takes ~9 minutes and produces a ~9 GB image. On hardened HPC nodes you may also need the `--fakeroot` flag, and to redirect `SINGULARITY_TMPDIR` / `APPTAINER_TMPDIR` and `SINGULARITY_CACHEDIR` / `APPTAINER_CACHEDIR` to scratch storage; the full troubleshooting walkthrough lives in [`docs/GPU_RUNTIME_GUIDE.md`](docs/GPU_RUNTIME_GUIDE.md).
|
|
138
|
+
|
|
139
|
+
**3. Set up monitoring dashboards in tmux (optional)**
|
|
140
|
+
|
|
141
|
+
> [!Tip]
|
|
142
|
+
> Subsequent pipeline runs may proceed from the current step (3) onward
|
|
143
|
+
|
|
144
|
+
The repo ships a convenience script that instantiates a four-window tmux session for monitoring system resources (`htop` + a CPU/MEM ticker), GPU state (`watch nvidia-smi`), shared memory buffers (`watch ls /dev/shm`), and models/outputs dirs (`watch tree`):
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
./utils/start_tmux_session.sh
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Idempotent — re-running attaches to the existing session instead of recreating it.
|
|
151
|
+
|
|
152
|
+
**4. Configure secrets and paths (optional)**
|
|
153
|
+
|
|
154
|
+
Aetherscan reads secrets and path overrides from a `.env` file at the repo root. [`utils/run_container.sh`](utils/run_container.sh) auto-loads `<repo>/.env` into its own environment before launching the container and forwards the relevant keys via `--env`, so no `source .env` or inline prefix is needed.
|
|
155
|
+
|
|
156
|
+
```ini
|
|
157
|
+
# .env example
|
|
158
|
+
|
|
159
|
+
# If none specified, defaults to /datax/scratch/zachy/{data|models|outputs}/aetherscan
|
|
160
|
+
# Note, CLI flags (--data-path, --model-path, --output-path) override these
|
|
161
|
+
AETHERSCAN_DATA_PATH=/path/to/data
|
|
162
|
+
AETHERSCAN_MODEL_PATH=/path/to/models
|
|
163
|
+
AETHERSCAN_OUTPUT_PATH=/path/to/outputs
|
|
164
|
+
|
|
165
|
+
# Optional: comma-separated extra host paths for run_container.sh to bind 1:1, for
|
|
166
|
+
# data outside the standard dirs (e.g. parent dir with raw .h5 files for inference)
|
|
167
|
+
AETHERSCAN_EXTRA_BINDS=/extra/host/paths
|
|
168
|
+
|
|
169
|
+
# If none specified, Slack integration is automatically disabled
|
|
170
|
+
SLACK_BOT_TOKEN=your-slack-bot-token
|
|
171
|
+
SLACK_CHANNEL=your-slack-channel
|
|
172
|
+
|
|
173
|
+
# Only needed for uploading model weights to the HuggingFace Hub (train --hf-upload);
|
|
174
|
+
# downloads (the inference default) hit a public repo and need no token
|
|
175
|
+
HF_TOKEN=your-huggingface-write-token
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
> [!TIP]
|
|
179
|
+
> See [`SECURITY.md`](SECURITY.md) for best practices on managing `.env` files.
|
|
180
|
+
|
|
181
|
+
If you'd rather set them directly in your shell (skipping `.env`), `export` works equivalently and takes precedence over `.env` for any keys it sets — useful for one-off overrides:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
export SLACK_BOT_TOKEN="your-slack-bot-token"
|
|
185
|
+
export SLACK_CHANNEL="your-slack-channel"
|
|
186
|
+
...
|
|
187
|
+
|
|
188
|
+
./utils/run_container.sh python -m aetherscan.main train ...
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
The `AETHERSCAN_*` paths are bind-mounted 1:1 between host and container, so they must already exist on the host before the pipeline starts. The `utils/run_container.sh` wrapper forwards `SLACK_*`, `AETHERSCAN_*`, and `HF_TOKEN` into the container explicitly; if you need additional env vars on the container side, extend the wrapper's `--env` list.
|
|
192
|
+
|
|
193
|
+
**5. Run pipeline**
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
./utils/run_container.sh python -m aetherscan.main {train|inference} \
|
|
197
|
+
--save-tag train
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
The `utils/run_container.sh` wrapper auto-detects whether `apptainer` or `singularity` is on PATH (Apptainer wins when both are present), sets `--nv` for GPU passthrough, and binds the repo + `AETHERSCAN_{DATA,MODEL,OUTPUT}_PATH` 1:1 between host and container so absolute paths persisted in the DB stay valid across both. `PYTHONPATH` is set automatically inside the container — no inline prefix needed.
|
|
201
|
+
|
|
202
|
+
See the [Usage Examples](#usage-examples) section below for further ways to invoke the Aetherscan pipeline.
|
|
203
|
+
|
|
204
|
+
### Run From Source
|
|
205
|
+
|
|
206
|
+
> [!NOTE]
|
|
207
|
+
> This is an alternative install path for Ampere clusters
|
|
208
|
+
|
|
209
|
+
**1. Clone the repository**
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
git clone https://github.com/zachtheyek/Aetherscan.git
|
|
213
|
+
cd Aetherscan
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**2. Create conda environment**
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
conda env create -f environment.yml
|
|
220
|
+
conda activate aetherscan
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**3. Set up monitoring dashboards in tmux (optional)**
|
|
224
|
+
|
|
225
|
+
> [!Tip]
|
|
226
|
+
> Subsequent pipeline runs may proceed from the current step (3) onward
|
|
227
|
+
|
|
228
|
+
The repo ships a convenience script that instantiates a four-window tmux session for monitoring system resources (`htop` + a CPU/MEM ticker), GPU state (`watch nvidia-smi`), shared memory buffers (`watch ls /dev/shm`), and models/outputs dirs (`watch tree`):
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
./utils/start_tmux_session.sh
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Idempotent — re-running attaches to the existing session instead of recreating it.
|
|
235
|
+
|
|
236
|
+
> [!Note]
|
|
237
|
+
> If you skip the tmux helper, it's recommended to run these two exports manually before launching the pipeline — the script's pipeline pane sets them for you, and without them you may hit TF library-loading issues or noisy startup logs:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$CONDA_PREFIX/lib:$LD_LIBRARY_PATH
|
|
241
|
+
export TF_CPP_MIN_LOG_LEVEL=1
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**4. Configure secrets and paths (optional)**
|
|
245
|
+
|
|
246
|
+
Same `.env` file format and precedence rules as [Run From Container](#run-from-container) step 4. Two differences on this path:
|
|
247
|
+
|
|
248
|
+
- `<repo>/.env` is loaded directly into `os.environ` at the top of `main.py` via [python-dotenv](https://pypi.org/project/python-dotenv/) — no wrapper script in the loop — so **every** key in `.env` is visible to the pipeline, not just the subset the container wrapper forwards via `--env`.
|
|
249
|
+
- No host→container bind mounts, so `AETHERSCAN_*` paths only need to exist when the pipeline actually accesses them, not at startup.
|
|
250
|
+
|
|
251
|
+
Multiprocess worker pools inherit the values via `os.environ` as usual.
|
|
252
|
+
|
|
253
|
+
**5. Run pipeline**
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
PYTHONPATH=src python -m aetherscan.main {train|inference} \
|
|
257
|
+
--save-tag train
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
`PYTHONPATH=src` makes the `aetherscan` package importable from `src/` without a `pip install -e .` step. No inline `KEY=VALUE` prefix is needed for Slack credentials — the `.env` auto-load runs before any worker process is spawned, so `os.environ` inheritance to multiprocess pools is automatic.
|
|
261
|
+
|
|
262
|
+
See the [Usage Examples](#usage-examples) section below for further ways to invoke the Aetherscan pipeline.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Usage Examples
|
|
267
|
+
|
|
268
|
+
> [!NOTE]
|
|
269
|
+
> `main.py` is the designated pipeline entry point.
|
|
270
|
+
> Non-development workflows should avoid directly calling other scripts/modules.
|
|
271
|
+
|
|
272
|
+
> [!NOTE]
|
|
273
|
+
> Each scenario below is shown twice — first with the container wrapper (canonical), then with the conda-env source invocation (alternative). CLI flags are identical between the two; only the launcher differs.
|
|
274
|
+
|
|
275
|
+
### Training
|
|
276
|
+
|
|
277
|
+
> [!TIP]
|
|
278
|
+
> The examples below cover a small number of scenarios. For the full set of available flags, see [Train Command Help](#train-command-help).
|
|
279
|
+
|
|
280
|
+
**Default training run**
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
# Container (canonical)
|
|
284
|
+
./utils/run_container.sh python -m aetherscan.main train
|
|
285
|
+
|
|
286
|
+
# Source (Ampere conda env)
|
|
287
|
+
PYTHONPATH=src python -m aetherscan.main train
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Training with custom parameters**
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Container
|
|
294
|
+
./utils/run_container.sh python -m aetherscan.main train \
|
|
295
|
+
--train-files real_filtered_LARGE_HIP110750.npy real_filtered_LARGE_HIP13402.npy real_filtered_LARGE_HIP8497.npy \
|
|
296
|
+
--num-training-rounds 20 \
|
|
297
|
+
--epochs-per-round 100 \
|
|
298
|
+
--curriculum-schedule exponential \
|
|
299
|
+
--save-tag test
|
|
300
|
+
|
|
301
|
+
# Source
|
|
302
|
+
PYTHONPATH=src python -m aetherscan.main train \
|
|
303
|
+
--train-files real_filtered_LARGE_HIP110750.npy real_filtered_LARGE_HIP13402.npy real_filtered_LARGE_HIP8497.npy \
|
|
304
|
+
--num-training-rounds 20 \
|
|
305
|
+
--epochs-per-round 100 \
|
|
306
|
+
--curriculum-schedule exponential \
|
|
307
|
+
--save-tag test
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**Resume from checkpoint**
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# Container
|
|
314
|
+
./utils/run_container.sh python -m aetherscan.main train \
|
|
315
|
+
--load-dir checkpoints \
|
|
316
|
+
--load-tag round_10 \
|
|
317
|
+
--save-tag test
|
|
318
|
+
|
|
319
|
+
# Source
|
|
320
|
+
PYTHONPATH=src python -m aetherscan.main train \
|
|
321
|
+
--load-dir checkpoints \
|
|
322
|
+
--load-tag round_10 \
|
|
323
|
+
--save-tag test
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
> [!WARNING]
|
|
327
|
+
> Per-round checkpoints live under `checkpoints/` — `--load-tag round_XX` without `--load-dir checkpoints` is rejected at validation (it used to silently resume from the newest stale model in the models root instead).
|
|
328
|
+
|
|
329
|
+
**Training with an explicit per-GPU memory cap (e.g. on an older Ampere GPU with lower VRAM)**
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
# Container
|
|
333
|
+
./utils/run_container.sh python -m aetherscan.main train \
|
|
334
|
+
--gpu-memory-limit-mb 14000 \
|
|
335
|
+
--save-tag test
|
|
336
|
+
|
|
337
|
+
# Source
|
|
338
|
+
PYTHONPATH=src python -m aetherscan.main train \
|
|
339
|
+
--gpu-memory-limit-mb 14000 \
|
|
340
|
+
--save-tag test
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Watching the live dashboard from your local browser (SSH port forwarding)**
|
|
344
|
+
|
|
345
|
+
Each `train`/`inference` run auto-launches a Streamlit dashboard on the cluster node (enabled by
|
|
346
|
+
default), served on that node's `localhost:8501` (`config.monitor.dashboard_port`, default `8501`).
|
|
347
|
+
It reads the run's live SQLite DB, so it updates as the pipeline progresses. Because it binds to the
|
|
348
|
+
node's loopback interface, view it locally by opening an SSH tunnel that forwards the port, then
|
|
349
|
+
browsing to the forwarded address:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# From your local machine — forward the dashboard port from the cluster node running the pipeline:
|
|
353
|
+
ssh -L 8501:localhost:8501 <cluster-host>
|
|
354
|
+
# ...then open http://localhost:8501 in your local browser. Keep the tunnel open while you watch.
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
If you launched the run on a non-default port, forward that port instead. The pipeline also logs the
|
|
358
|
+
exact `ssh -L …` command when it starts the dashboard.
|
|
359
|
+
|
|
360
|
+
### Inference
|
|
361
|
+
|
|
362
|
+
> [!TIP]
|
|
363
|
+
> The examples below cover a small number of scenarios. For the full set of available flags, see [Inference Command Help](#inference-command-help).
|
|
364
|
+
|
|
365
|
+
**Default inference run**
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
# Container (canonical)
|
|
369
|
+
./utils/run_container.sh python -m aetherscan.main inference
|
|
370
|
+
|
|
371
|
+
# Source (Ampere conda env)
|
|
372
|
+
PYTHONPATH=src python -m aetherscan.main inference
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
**Inference on a pre-processed `.npy` file**
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
# Container
|
|
379
|
+
./utils/run_container.sh python -m aetherscan.main inference \
|
|
380
|
+
--test-files real_filtered_LARGE_test_HIP15638.npy \
|
|
381
|
+
--encoder-path /datax/scratch/zachy/models/aetherscan/vae_encoder_train_20260101_120000.keras \
|
|
382
|
+
--rf-path /datax/scratch/zachy/models/aetherscan/random_forest_train_20260101_120000.joblib \
|
|
383
|
+
--config-path /datax/scratch/zachy/models/aetherscan/config_train_20260101_120000.json \
|
|
384
|
+
--classification-threshold 0.99
|
|
385
|
+
|
|
386
|
+
# Source
|
|
387
|
+
PYTHONPATH=src python -m aetherscan.main inference \
|
|
388
|
+
--test-files real_filtered_LARGE_test_HIP15638.npy \
|
|
389
|
+
--encoder-path /datax/scratch/zachy/models/aetherscan/vae_encoder_train_20260101_120000.keras \
|
|
390
|
+
--rf-path /datax/scratch/zachy/models/aetherscan/random_forest_train_20260101_120000.joblib \
|
|
391
|
+
--config-path /datax/scratch/zachy/models/aetherscan/config_train_20260101_120000.json \
|
|
392
|
+
--classification-threshold 0.99
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**Inference from raw `.h5` files (invokes energy detection preprocessing)**
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
# Container — if the raw .h5 paths in the CSV live outside the standard bind
|
|
399
|
+
# mounts (e.g. under /datag), then we bind them via AETHERSCAN_EXTRA_BINDS
|
|
400
|
+
AETHERSCAN_EXTRA_BINDS=/datag ./utils/run_container.sh python -m aetherscan.main inference \
|
|
401
|
+
--inference-files complete_cadences_catalog.csv \
|
|
402
|
+
--encoder-path /path/to/vae_encoder.keras \
|
|
403
|
+
--rf-path /path/to/random_forest.joblib \
|
|
404
|
+
--config-path /path/to/config.json \
|
|
405
|
+
--save-tag inf
|
|
406
|
+
|
|
407
|
+
# Source
|
|
408
|
+
PYTHONPATH=src python -m aetherscan.main inference \
|
|
409
|
+
--inference-files complete_cadences_catalog.csv \
|
|
410
|
+
--encoder-path /path/to/vae_encoder.keras \
|
|
411
|
+
--rf-path /path/to/random_forest.joblib \
|
|
412
|
+
--config-path /path/to/config.json \
|
|
413
|
+
--save-tag inf
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**Inference with async-allocator fallbacks (e.g. on a 5-GPU Blackwell topology)**
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
# Container
|
|
420
|
+
./utils/run_container.sh python -m aetherscan.main inference \
|
|
421
|
+
--no-async-allocator \
|
|
422
|
+
--save-tag inf
|
|
423
|
+
|
|
424
|
+
# Source
|
|
425
|
+
PYTHONPATH=src python -m aetherscan.main inference \
|
|
426
|
+
--no-async-allocator \
|
|
427
|
+
--save-tag inf
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## CLI Reference
|
|
433
|
+
|
|
434
|
+
Aetherscan uses a hierarchical configuration system with dataclass-based configs, whose state can be modified both at command time and runtime. At command time, the user can specify values via:
|
|
435
|
+
|
|
436
|
+
1. **Defaults** - Defined in `src/aetherscan/config.py`
|
|
437
|
+
2. **Environment variables** - For paths and secrets
|
|
438
|
+
3. **CLI flags** - Override defaults & environment variables on startup
|
|
439
|
+
|
|
440
|
+
At runtime, the singleton `Config` instance can be accessed via `get_config()` and modified programmatically.
|
|
441
|
+
|
|
442
|
+
Read [docs/CONFIG_AND_CLI.md](/docs/CONFIG_AND_CLI.md) to learn more.
|
|
443
|
+
|
|
444
|
+
### Top-Level Help
|
|
445
|
+
|
|
446
|
+
Aetherscan dispatches to one of two subcommands via the first positional argument. Regenerate this output with `./utils/run_container.sh python utils/print_cli_help.py top` (container) or `PYTHONPATH=src python utils/print_cli_help.py top` (source).
|
|
447
|
+
|
|
448
|
+
```
|
|
449
|
+
usage: [-h] {train,inference} ...
|
|
450
|
+
|
|
451
|
+
Aetherscan Pipeline -- Breakthrough Listen's first end-to-end production-grade
|
|
452
|
+
DL pipeline for SETI @ scale
|
|
453
|
+
|
|
454
|
+
positional arguments:
|
|
455
|
+
{train,inference} Command to execute
|
|
456
|
+
train Execute training pipeline
|
|
457
|
+
inference Execute inference pipeline
|
|
458
|
+
|
|
459
|
+
options:
|
|
460
|
+
-h, --help show this help message and exit
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Train Command Help
|
|
464
|
+
|
|
465
|
+
The Aetherscan training pipeline exposes the following CLI flags to the user. Regenerate this output with `./utils/run_container.sh python utils/print_cli_help.py train` (container) or `PYTHONPATH=src python utils/print_cli_help.py train` (source).
|
|
466
|
+
|
|
467
|
+
```
|
|
468
|
+
usage: train [-h] [--seed SEED] [--unseeded]
|
|
469
|
+
[--tf-deterministic-ops | --no-tf-deterministic-ops]
|
|
470
|
+
[--n-processes N_PROCESSES] [--data-path DATA_PATH]
|
|
471
|
+
[--model-path MODEL_PATH] [--output-path OUTPUT_PATH]
|
|
472
|
+
[--dashboard | --no-dashboard] [--dashboard-port DASHBOARD_PORT]
|
|
473
|
+
[--benchmark-report | --no-benchmark-report]
|
|
474
|
+
[--vae-latent-dim VAE_LATENT_DIM]
|
|
475
|
+
[--vae-dense-layer-size VAE_DENSE_LAYER_SIZE]
|
|
476
|
+
[--vae-kernel-size VAE_KERNEL_SIZE VAE_KERNEL_SIZE]
|
|
477
|
+
[--vae-beta VAE_BETA] [--vae-alpha VAE_ALPHA]
|
|
478
|
+
[--rf-n-estimators RF_N_ESTIMATORS] [--rf-bootstrap RF_BOOTSTRAP]
|
|
479
|
+
[--rf-max-features RF_MAX_FEATURES] [--rf-n-jobs RF_N_JOBS]
|
|
480
|
+
[--rf-seed RF_SEED] [--num-replicas NUM_REPLICAS]
|
|
481
|
+
[--gpu-memory-limit-mb GPU_MEMORY_LIMIT_MB]
|
|
482
|
+
[--nccl-num-packs NCCL_NUM_PACKS]
|
|
483
|
+
[--async-allocator | --no-async-allocator]
|
|
484
|
+
[--num-observations NUM_OBSERVATIONS] [--width-bin WIDTH_BIN]
|
|
485
|
+
[--downsample-factor DOWNSAMPLE_FACTOR] [--time-bins TIME_BINS]
|
|
486
|
+
[--freq-resolution FREQ_RESOLUTION]
|
|
487
|
+
[--time-resolution TIME_RESOLUTION]
|
|
488
|
+
[--num-target-backgrounds NUM_TARGET_BACKGROUNDS]
|
|
489
|
+
[--background-load-chunk-size BACKGROUND_LOAD_CHUNK_SIZE]
|
|
490
|
+
[--max-chunks-per-file MAX_CHUNKS_PER_FILE]
|
|
491
|
+
[--train-files TRAIN_FILES [TRAIN_FILES ...]]
|
|
492
|
+
[--num-training-rounds NUM_TRAINING_ROUNDS]
|
|
493
|
+
[--epochs-per-round EPOCHS_PER_ROUND]
|
|
494
|
+
[--num-samples-beta-vae NUM_SAMPLES_BETA_VAE]
|
|
495
|
+
[--num-samples-rf NUM_SAMPLES_RF]
|
|
496
|
+
[--train-val-split TRAIN_VAL_SPLIT]
|
|
497
|
+
[--per-replica-batch-size PER_REPLICA_BATCH_SIZE]
|
|
498
|
+
[--effective-batch-size EFFECTIVE_BATCH_SIZE]
|
|
499
|
+
[--per-replica-val-batch-size PER_REPLICA_VAL_BATCH_SIZE]
|
|
500
|
+
[--signal-injection-chunk-size SIGNAL_INJECTION_CHUNK_SIZE]
|
|
501
|
+
[--data-gen-task-size DATA_GEN_TASK_SIZE]
|
|
502
|
+
[--round-data-dir ROUND_DATA_DIR]
|
|
503
|
+
[--overlap-data-generation | --no-overlap-data-generation]
|
|
504
|
+
[--keep-round-data | --no-keep-round-data]
|
|
505
|
+
[--plot-injection-subsampling-count PLOT_INJECTION_SUBSAMPLING_COUNT]
|
|
506
|
+
[--plot-injection-outlier-percentile PLOT_INJECTION_OUTLIER_PERCENTILE]
|
|
507
|
+
[--latent-viz-num-cadences-per-type LATENT_VIZ_NUM_CADENCES_PER_TYPE]
|
|
508
|
+
[--latent-viz-step-interval LATENT_VIZ_STEP_INTERVAL]
|
|
509
|
+
[--latent-viz-umap-fit-max-samples LATENT_VIZ_UMAP_FIT_MAX_SAMPLES]
|
|
510
|
+
[--latent-viz-umap-n-neighbors LATENT_VIZ_UMAP_N_NEIGHBORS [LATENT_VIZ_UMAP_N_NEIGHBORS ...]]
|
|
511
|
+
[--latent-viz-umap-min-dist LATENT_VIZ_UMAP_MIN_DIST [LATENT_VIZ_UMAP_MIN_DIST ...]]
|
|
512
|
+
[--latent-viz-gif-max-frames LATENT_VIZ_GIF_MAX_FRAMES]
|
|
513
|
+
[--latent-viz-gif-duration-ms LATENT_VIZ_GIF_DURATION_MS]
|
|
514
|
+
[--latent-traversal-every-round | --no-latent-traversal-every-round]
|
|
515
|
+
[--latent-traversal-num-steps LATENT_TRAVERSAL_NUM_STEPS]
|
|
516
|
+
[--latent-traversal-max-sigma LATENT_TRAVERSAL_MAX_SIGMA]
|
|
517
|
+
[--snr-base SNR_BASE] [--initial-snr-range INITIAL_SNR_RANGE]
|
|
518
|
+
[--final-snr-range FINAL_SNR_RANGE]
|
|
519
|
+
[--curriculum-schedule CURRICULUM_SCHEDULE]
|
|
520
|
+
[--exponential-decay-rate EXPONENTIAL_DECAY_RATE]
|
|
521
|
+
[--step-easy-rounds STEP_EASY_ROUNDS]
|
|
522
|
+
[--step-hard-rounds STEP_HARD_ROUNDS]
|
|
523
|
+
[--base-learning-rate BASE_LEARNING_RATE]
|
|
524
|
+
[--min-learning-rate MIN_LEARNING_RATE]
|
|
525
|
+
[--min-pct-improvement MIN_PCT_IMPROVEMENT]
|
|
526
|
+
[--patience-threshold PATIENCE_THRESHOLD]
|
|
527
|
+
[--lr-reduction-factor LR_REDUCTION_FACTOR]
|
|
528
|
+
[--max-retries MAX_RETRIES] [--retry-delay RETRY_DELAY]
|
|
529
|
+
[--hf-upload | --no-hf-upload] [--hf-repo-id HF_REPO_ID]
|
|
530
|
+
[--load-dir LOAD_DIR] [--load-tag LOAD_TAG]
|
|
531
|
+
[--start-round START_ROUND] [--save-tag SAVE_TAG]
|
|
532
|
+
[--force-tag | --no-force-tag]
|
|
533
|
+
|
|
534
|
+
options:
|
|
535
|
+
-h, --help show this help message and exit
|
|
536
|
+
--seed SEED Root random seed for reproducible runs: every random
|
|
537
|
+
stream derives from it — data generation, dataset
|
|
538
|
+
split/shuffles, TF weight init, the VAE sampling layer
|
|
539
|
+
(training AND inference), the random forest,
|
|
540
|
+
UMAP/KMeans plot fits, and plot subsampling. Defaults
|
|
541
|
+
to a concrete value (reproducible out of the box);
|
|
542
|
+
must be >= 0. To run unseeded, pass --unseeded
|
|
543
|
+
--unseeded Opt OUT of the seeded default: draw every random
|
|
544
|
+
stream from OS entropy (non-reproducible). Mutually
|
|
545
|
+
exclusive with --seed
|
|
546
|
+
--tf-deterministic-ops, --no-tf-deterministic-ops
|
|
547
|
+
Force deterministic TensorFlow/cuDNN op
|
|
548
|
+
implementations
|
|
549
|
+
(tf.config.experimental.enable_op_determinism) for
|
|
550
|
+
bit-exact GPU reproducibility at some speed cost.
|
|
551
|
+
Default: enabled — without it, cuDNN autotune noise
|
|
552
|
+
can flip near-threshold candidates between identical
|
|
553
|
+
runs; opt out with --no-tf-deterministic-ops
|
|
554
|
+
--n-processes N_PROCESSES
|
|
555
|
+
Worker-process count for the multiprocessing pools
|
|
556
|
+
(energy detection + stamp extraction at inference;
|
|
557
|
+
data generation at training). Default: all cores. Host
|
|
558
|
+
tuning: never layered from a saved --config-path, so a
|
|
559
|
+
config recorded on a bigger host cannot oversubscribe
|
|
560
|
+
this one (must be >= 1)
|
|
561
|
+
--data-path DATA_PATH
|
|
562
|
+
Path to data directory (overrides AETHERSCAN_DATA_PATH
|
|
563
|
+
environment variable)
|
|
564
|
+
--model-path MODEL_PATH
|
|
565
|
+
Path to model directory (overrides
|
|
566
|
+
AETHERSCAN_MODEL_PATH environment variable)
|
|
567
|
+
--output-path OUTPUT_PATH
|
|
568
|
+
Path to output directory (overrides
|
|
569
|
+
AETHERSCAN_OUTPUT_PATH environment variable)
|
|
570
|
+
--dashboard, --no-dashboard
|
|
571
|
+
Auto-launch the live monitoring Streamlit dashboard
|
|
572
|
+
for this run; SSH-forward the port to view it
|
|
573
|
+
(default: on). Use --no-dashboard to disable
|
|
574
|
+
--dashboard-port DASHBOARD_PORT
|
|
575
|
+
Port for the auto-launched live dashboard (default:
|
|
576
|
+
8501)
|
|
577
|
+
--benchmark-report, --no-benchmark-report
|
|
578
|
+
Render the end-of-run benchmark report (stage timeline
|
|
579
|
+
+ bottleneck suggestions) and post it to Slack
|
|
580
|
+
(default: on). Use --no-benchmark-report to disable
|
|
581
|
+
--vae-latent-dim VAE_LATENT_DIM
|
|
582
|
+
Dimensionality of the VAE latent space (bottleneck
|
|
583
|
+
size)
|
|
584
|
+
--vae-dense-layer-size VAE_DENSE_LAYER_SIZE
|
|
585
|
+
Size of dense layer in VAE architecture (should match
|
|
586
|
+
frequency bins after downsampling)
|
|
587
|
+
--vae-kernel-size VAE_KERNEL_SIZE VAE_KERNEL_SIZE
|
|
588
|
+
Kernel size for Conv2D layers as two integers (e.g.,
|
|
589
|
+
--vae-kernel-size 3 3)
|
|
590
|
+
--vae-beta VAE_BETA Beta coefficient for KL divergence loss term in beta-
|
|
591
|
+
VAE (controls disentanglement)
|
|
592
|
+
--vae-alpha VAE_ALPHA
|
|
593
|
+
Alpha coefficient for clustering loss term in VAE
|
|
594
|
+
(controls cluster separation)
|
|
595
|
+
--rf-n-estimators RF_N_ESTIMATORS
|
|
596
|
+
Number of decision trees in the random forest ensemble
|
|
597
|
+
--rf-bootstrap RF_BOOTSTRAP
|
|
598
|
+
Whether to use bootstrap sampling when building trees
|
|
599
|
+
(enables bagging)
|
|
600
|
+
--rf-max-features RF_MAX_FEATURES
|
|
601
|
+
Number of features to consider for splits: 'sqrt',
|
|
602
|
+
'log2', or a float (fraction of features)
|
|
603
|
+
--rf-n-jobs RF_N_JOBS
|
|
604
|
+
Number of parallel jobs for random forest training (-1
|
|
605
|
+
uses all CPU cores)
|
|
606
|
+
--rf-seed RF_SEED DEPRECATED: explicit random forest seed override. The
|
|
607
|
+
RF seed now derives from the root --seed (#279); this
|
|
608
|
+
alias remains for existing scripts and logs a
|
|
609
|
+
deprecation warning when used.
|
|
610
|
+
--num-replicas NUM_REPLICAS
|
|
611
|
+
Number of GPUs to use for the distributed strategy. If
|
|
612
|
+
omitted, the strategy uses every GPU visible to TF;
|
|
613
|
+
otherwise it is restricted to the first N physical
|
|
614
|
+
GPUs and the rest are left untouched. Must be >= 1 and
|
|
615
|
+
<= the number of physical GPUs on your machine.
|
|
616
|
+
--gpu-memory-limit-mb GPU_MEMORY_LIMIT_MB
|
|
617
|
+
Per-GPU memory cap in MiB. Omit to use memory-growth-
|
|
618
|
+
only (recommended on Blackwell). Set for TF to
|
|
619
|
+
allocate a fixed logical device of a given size per
|
|
620
|
+
physical GPU (e.g. 14000)
|
|
621
|
+
--nccl-num-packs NCCL_NUM_PACKS
|
|
622
|
+
num_packs for NCCL/HierarchicalCopy all-reduce. Lower
|
|
623
|
+
values (e.g. 1) reduces tiny-tensor latency; higher
|
|
624
|
+
values (e.g. >=4) can help bandwidth on >4-GPU
|
|
625
|
+
topologies.
|
|
626
|
+
--async-allocator, --no-async-allocator
|
|
627
|
+
Toggle TF_GPU_ALLOCATOR=cuda_malloc_async (default:
|
|
628
|
+
enabled). Pass --no-async-allocator as a workaround
|
|
629
|
+
for NGC 25.02 multi-GPU OOM bugs.
|
|
630
|
+
--num-observations NUM_OBSERVATIONS
|
|
631
|
+
Number of observations per cadence snippet (e.g., 6
|
|
632
|
+
for 3 ON + 3 OFF)
|
|
633
|
+
--width-bin WIDTH_BIN
|
|
634
|
+
Number of frequency bins per observation (spectral
|
|
635
|
+
resolution)
|
|
636
|
+
--downsample-factor DOWNSAMPLE_FACTOR
|
|
637
|
+
Downsampling factor for frequency bins (reduces
|
|
638
|
+
spectral dimension)
|
|
639
|
+
--time-bins TIME_BINS
|
|
640
|
+
Number of time bins per observation (temporal
|
|
641
|
+
resolution)
|
|
642
|
+
--freq-resolution FREQ_RESOLUTION
|
|
643
|
+
Frequency resolution in Hz (determined by instrument)
|
|
644
|
+
--time-resolution TIME_RESOLUTION
|
|
645
|
+
Time resolution in seconds (determined by instrument)
|
|
646
|
+
--num-target-backgrounds NUM_TARGET_BACKGROUNDS
|
|
647
|
+
Number of background (noise-only) cadences to load for
|
|
648
|
+
training data generation
|
|
649
|
+
--background-load-chunk-size BACKGROUND_LOAD_CHUNK_SIZE
|
|
650
|
+
Maximum number of background cadences to process at
|
|
651
|
+
once during loading (memory management)
|
|
652
|
+
--max-chunks-per-file MAX_CHUNKS_PER_FILE
|
|
653
|
+
Maximum number of chunks to load from a single data
|
|
654
|
+
file (limits per-file contribution)
|
|
655
|
+
--train-files TRAIN_FILES [TRAIN_FILES ...]
|
|
656
|
+
Space-separated list of training data file names
|
|
657
|
+
(e.g., real_filtered_LARGE_HIP110750.npy)
|
|
658
|
+
--num-training-rounds NUM_TRAINING_ROUNDS
|
|
659
|
+
Total number of training rounds in curriculum learning
|
|
660
|
+
schedule
|
|
661
|
+
--epochs-per-round EPOCHS_PER_ROUND
|
|
662
|
+
Number of epochs to train the VAE per curriculum
|
|
663
|
+
learning round
|
|
664
|
+
--num-samples-beta-vae NUM_SAMPLES_BETA_VAE
|
|
665
|
+
Number of training samples to generate for beta-VAE
|
|
666
|
+
per round (must be divisible by 4)
|
|
667
|
+
--num-samples-rf NUM_SAMPLES_RF
|
|
668
|
+
Number of training samples to generate for random
|
|
669
|
+
forest (must be divisible by 4)
|
|
670
|
+
--train-val-split TRAIN_VAL_SPLIT
|
|
671
|
+
Fraction of data to use for training vs validation
|
|
672
|
+
(e.g., 0.8 = 80% train, 20% val)
|
|
673
|
+
--per-replica-batch-size PER_REPLICA_BATCH_SIZE
|
|
674
|
+
Batch size per GPU/device replica during training
|
|
675
|
+
--effective-batch-size EFFECTIVE_BATCH_SIZE
|
|
676
|
+
Effective batch size for gradient accumulation across
|
|
677
|
+
all replicas
|
|
678
|
+
--per-replica-val-batch-size PER_REPLICA_VAL_BATCH_SIZE
|
|
679
|
+
Batch size per GPU/device replica during validation
|
|
680
|
+
--signal-injection-chunk-size SIGNAL_INJECTION_CHUNK_SIZE
|
|
681
|
+
Maximum cadences to process at once during synthetic
|
|
682
|
+
signal injection (must be divisible by 4)
|
|
683
|
+
--data-gen-task-size DATA_GEN_TASK_SIZE
|
|
684
|
+
Cadences per batched signal-injection worker task
|
|
685
|
+
(workers write results straight into the round's on-
|
|
686
|
+
disk memmap; must be >= 1)
|
|
687
|
+
--round-data-dir ROUND_DATA_DIR
|
|
688
|
+
Directory for disk-backed per-round training datasets
|
|
689
|
+
(defaults to <data-path>/training/round_data; needs
|
|
690
|
+
~2.2x one round's size free when data-generation
|
|
691
|
+
overlap is enabled, ~1.1x otherwise)
|
|
692
|
+
--overlap-data-generation, --no-overlap-data-generation
|
|
693
|
+
Generate round k+1's training data in a background
|
|
694
|
+
producer process while round k trains (default:
|
|
695
|
+
enabled). Pass --no-overlap-data-generation to fall
|
|
696
|
+
back to sequential in-process generation for debugging
|
|
697
|
+
--keep-round-data, --no-keep-round-data
|
|
698
|
+
Retain each round's on-disk training data after that
|
|
699
|
+
round finishes (default: disabled — round k's data
|
|
700
|
+
directory is deleted as soon as round k's training
|
|
701
|
+
completes). Enable for debugging
|
|
702
|
+
--plot-injection-subsampling-count PLOT_INJECTION_SUBSAMPLING_COUNT
|
|
703
|
+
Max points per stat name, per signal type, for A→B
|
|
704
|
+
intensity bias scatter plots. Outliers are
|
|
705
|
+
prioritized, with the difference made up from randomly
|
|
706
|
+
sampling without replacement the remaining points
|
|
707
|
+
--plot-injection-outlier-percentile PLOT_INJECTION_OUTLIER_PERCENTILE
|
|
708
|
+
Threshold for points to always be included in A→B
|
|
709
|
+
intensity bias scatter plots
|
|
710
|
+
--latent-viz-num-cadences-per-type LATENT_VIZ_NUM_CADENCES_PER_TYPE
|
|
711
|
+
Number of cadences per signal type for latent space
|
|
712
|
+
visualization batch (total points = 4× this value × 6
|
|
713
|
+
observations per cadence)
|
|
714
|
+
--latent-viz-step-interval LATENT_VIZ_STEP_INTERVAL
|
|
715
|
+
Capture a latent space snapshot every N training steps
|
|
716
|
+
(lower = more snapshots, more DB writes, and larger
|
|
717
|
+
storage costs)
|
|
718
|
+
--latent-viz-umap-fit-max-samples LATENT_VIZ_UMAP_FIT_MAX_SAMPLES
|
|
719
|
+
Maximum number of pooled latent vectors used to fit
|
|
720
|
+
the UMAP model (remaining vectors are projected via
|
|
721
|
+
transform; lower = faster, higher = more faithful
|
|
722
|
+
embedding)
|
|
723
|
+
--latent-viz-umap-n-neighbors LATENT_VIZ_UMAP_N_NEIGHBORS [LATENT_VIZ_UMAP_N_NEIGHBORS ...]
|
|
724
|
+
UMAP n_neighbors values to sweep for latent space
|
|
725
|
+
visualization (e.g., --latent-viz-umap-n-neighbors 5
|
|
726
|
+
15 30 50)
|
|
727
|
+
--latent-viz-umap-min-dist LATENT_VIZ_UMAP_MIN_DIST [LATENT_VIZ_UMAP_MIN_DIST ...]
|
|
728
|
+
UMAP min_dist values to sweep for latent space
|
|
729
|
+
visualization (e.g., --latent-viz-umap-min-dist 0.0
|
|
730
|
+
0.1 0.5)
|
|
731
|
+
--latent-viz-gif-max-frames LATENT_VIZ_GIF_MAX_FRAMES
|
|
732
|
+
Maximum number of frames in latent space GIF output
|
|
733
|
+
(snapshots beyond this limit are log-subsampled,
|
|
734
|
+
prioritizing earlier training steps)
|
|
735
|
+
--latent-viz-gif-duration-ms LATENT_VIZ_GIF_DURATION_MS
|
|
736
|
+
Milliseconds per frame in latent space GIF output
|
|
737
|
+
--latent-traversal-every-round, --no-latent-traversal-every-round
|
|
738
|
+
Render latent-dimension traversal figures at the end
|
|
739
|
+
of every training round, in addition to the end-of-
|
|
740
|
+
training set (default: disabled)
|
|
741
|
+
--latent-traversal-num-steps LATENT_TRAVERSAL_NUM_STEPS
|
|
742
|
+
Number of traversal steps per latent dimension (must
|
|
743
|
+
be odd and >= 3 so the center column is the
|
|
744
|
+
unperturbed class-mean decode)
|
|
745
|
+
--latent-traversal-max-sigma LATENT_TRAVERSAL_MAX_SIGMA
|
|
746
|
+
Latent traversal range in per-dimension standard
|
|
747
|
+
deviations: steps span [-max_sigma, +max_sigma] (must
|
|
748
|
+
be > 0)
|
|
749
|
+
--snr-base SNR_BASE Base signal-to-noise ratio for curriculum learning
|
|
750
|
+
(minimum SNR difficulty level)
|
|
751
|
+
--initial-snr-range INITIAL_SNR_RANGE
|
|
752
|
+
SNR range for initial (easiest) training rounds
|
|
753
|
+
(signals sampled from snr_base to snr_base +
|
|
754
|
+
initial_snr_range)
|
|
755
|
+
--final-snr-range FINAL_SNR_RANGE
|
|
756
|
+
SNR range for final (hardest) training rounds (signals
|
|
757
|
+
sampled from snr_base to snr_base + final_snr_range).
|
|
758
|
+
Ignored if only training for 1 round
|
|
759
|
+
--curriculum-schedule CURRICULUM_SCHEDULE
|
|
760
|
+
Curriculum difficulty progression schedule: 'linear',
|
|
761
|
+
'exponential', or 'step'
|
|
762
|
+
--exponential-decay-rate EXPONENTIAL_DECAY_RATE
|
|
763
|
+
Decay rate for exponential curriculum schedule (must
|
|
764
|
+
be negative; more negative = faster difficulty
|
|
765
|
+
increase)
|
|
766
|
+
--step-easy-rounds STEP_EASY_ROUNDS
|
|
767
|
+
Number of rounds with easy signals when using step
|
|
768
|
+
curriculum schedule
|
|
769
|
+
--step-hard-rounds STEP_HARD_ROUNDS
|
|
770
|
+
Number of rounds with hard signals when using step
|
|
771
|
+
curriculum schedule
|
|
772
|
+
--base-learning-rate BASE_LEARNING_RATE
|
|
773
|
+
Initial learning rate for Adam optimizer
|
|
774
|
+
--min-learning-rate MIN_LEARNING_RATE
|
|
775
|
+
Learning rate floor for adaptive learning rate
|
|
776
|
+
reduction
|
|
777
|
+
--min-pct-improvement MIN_PCT_IMPROVEMENT
|
|
778
|
+
Minimum fractional validation loss improvement to
|
|
779
|
+
avoid LR reduction (e.g., 0.001 = 0.1%)
|
|
780
|
+
--patience-threshold PATIENCE_THRESHOLD
|
|
781
|
+
Number of consecutive epochs without minimum
|
|
782
|
+
improvement before reducing learning rate
|
|
783
|
+
--lr-reduction-factor LR_REDUCTION_FACTOR
|
|
784
|
+
Multiplicative factor for learning rate reduction
|
|
785
|
+
(e.g., 0.2 reduces LR by 20%)
|
|
786
|
+
--max-retries MAX_RETRIES
|
|
787
|
+
Maximum number of retry attempts when training fails
|
|
788
|
+
due to errors
|
|
789
|
+
--retry-delay RETRY_DELAY
|
|
790
|
+
Delay in seconds between retry attempts after training
|
|
791
|
+
failure
|
|
792
|
+
--hf-upload, --no-hf-upload
|
|
793
|
+
Upload the final model artifacts (encoder, decoder,
|
|
794
|
+
random forest, config) plus a generated model card to
|
|
795
|
+
the HuggingFace Hub after training completes, tagging
|
|
796
|
+
the commit with --save-tag (default: disabled = local-
|
|
797
|
+
only). Requires HF_TOKEN in the environment (via .env)
|
|
798
|
+
--hf-repo-id HF_REPO_ID
|
|
799
|
+
HuggingFace model repo id (namespace/name) for weight
|
|
800
|
+
upload/download (default: zachtheyek/aetherscan)
|
|
801
|
+
--load-dir LOAD_DIR Subdirectory for checkpoint loading (relative to
|
|
802
|
+
--model-path)
|
|
803
|
+
--load-tag LOAD_TAG Checkpoint to load. A full run tag
|
|
804
|
+
({command}_YYYYMMDD_HHMMSS) resumes that run in place
|
|
805
|
+
(its tag is adopted, so the resumed attempt writes
|
|
806
|
+
under the same run). round_XX (requires --load-dir
|
|
807
|
+
checkpoints) seeds a fresh run from that per-round
|
|
808
|
+
checkpoint, resuming from round XX+1 unless --start-
|
|
809
|
+
round is given.
|
|
810
|
+
--start-round START_ROUND
|
|
811
|
+
Round to begin/resume training from
|
|
812
|
+
--save-tag SAVE_TAG Run label prefix: one of test, train, inf, bench. The
|
|
813
|
+
datetime is appended automatically at runtime (e.g.
|
|
814
|
+
train_20260101_120000). Defaults to the subcommand
|
|
815
|
+
(train->train, inference->inf) if omitted.
|
|
816
|
+
--force-tag, --no-force-tag
|
|
817
|
+
Override the fail-early save-tag collision guard:
|
|
818
|
+
proceed even when an explicitly-provided --save-tag
|
|
819
|
+
matches existing artifacts, DB rows, or (with --hf-
|
|
820
|
+
upload) an existing HuggingFace tag (default:
|
|
821
|
+
disabled)
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
### Inference Command Help
|
|
825
|
+
|
|
826
|
+
The Aetherscan inference pipeline exposes the following CLI flags to the user. Regenerate this output with `./utils/run_container.sh python utils/print_cli_help.py inference` (container) or `PYTHONPATH=src python utils/print_cli_help.py inference` (source).
|
|
827
|
+
|
|
828
|
+
```
|
|
829
|
+
usage: inference [-h] [--seed SEED] [--unseeded]
|
|
830
|
+
[--tf-deterministic-ops | --no-tf-deterministic-ops]
|
|
831
|
+
[--n-processes N_PROCESSES] [--data-path DATA_PATH]
|
|
832
|
+
[--model-path MODEL_PATH] [--output-path OUTPUT_PATH]
|
|
833
|
+
[--dashboard | --no-dashboard]
|
|
834
|
+
[--dashboard-port DASHBOARD_PORT]
|
|
835
|
+
[--benchmark-report | --no-benchmark-report]
|
|
836
|
+
[--num-replicas NUM_REPLICAS]
|
|
837
|
+
[--gpu-memory-limit-mb GPU_MEMORY_LIMIT_MB]
|
|
838
|
+
[--async-allocator | --no-async-allocator]
|
|
839
|
+
[--test-files TEST_FILES [TEST_FILES ...]]
|
|
840
|
+
[--inference-files INFERENCE_FILES [INFERENCE_FILES ...]]
|
|
841
|
+
[--encoder-path ENCODER_PATH] [--rf-path RF_PATH]
|
|
842
|
+
[--config-path CONFIG_PATH]
|
|
843
|
+
[--per-replica-batch-size PER_REPLICA_BATCH_SIZE]
|
|
844
|
+
[--classification-threshold CLASSIFICATION_THRESHOLD]
|
|
845
|
+
[--screening-threshold SCREENING_THRESHOLD]
|
|
846
|
+
[--mc-draws MC_DRAWS]
|
|
847
|
+
[--reference-cloud-size REFERENCE_CLOUD_SIZE]
|
|
848
|
+
[--prefetch-depth PREFETCH_DEPTH]
|
|
849
|
+
[--cadence-group-by-cols CADENCE_GROUP_BY_COLS [CADENCE_GROUP_BY_COLS ...]]
|
|
850
|
+
[--cadence-h5-path-col CADENCE_H5_PATH_COL]
|
|
851
|
+
[--cadence-expected-obs CADENCE_EXPECTED_OBS]
|
|
852
|
+
[--coarse-channel-width COARSE_CHANNEL_WIDTH]
|
|
853
|
+
[--coarse-channel-log-interval COARSE_CHANNEL_LOG_INTERVAL]
|
|
854
|
+
[--bandpass-method BANDPASS_METHOD]
|
|
855
|
+
[--pfb-taps-per-channel PFB_TAPS_PER_CHANNEL]
|
|
856
|
+
[--bandpass-debug-plot | --no-bandpass-debug-plot]
|
|
857
|
+
[--spline-order SPLINE_ORDER]
|
|
858
|
+
[--detection-window-size DETECTION_WINDOW_SIZE]
|
|
859
|
+
[--detection-step-size DETECTION_STEP_SIZE]
|
|
860
|
+
[--stat-threshold STAT_THRESHOLD] [--stamp-width STAMP_WIDTH]
|
|
861
|
+
[--store-downsampled-stamps | --no-store-downsampled-stamps]
|
|
862
|
+
[--overlap-search | --no-overlap-search]
|
|
863
|
+
[--overlap-fraction OVERLAP_FRACTION]
|
|
864
|
+
[--preprocess-output-dir PREPROCESS_OUTPUT_DIR]
|
|
865
|
+
[--prune-stamps | --no-prune-stamps]
|
|
866
|
+
[--inference-viz | --no-inference-viz]
|
|
867
|
+
[--inference-viz-scope {full,new}]
|
|
868
|
+
[--stamp-gallery-top-k STAMP_GALLERY_TOP_K]
|
|
869
|
+
[--max-candidate-plots MAX_CANDIDATE_PLOTS]
|
|
870
|
+
[--max-retries MAX_RETRIES] [--retry-delay RETRY_DELAY]
|
|
871
|
+
[--hf-repo-id HF_REPO_ID] [--hf-revision HF_REVISION]
|
|
872
|
+
[--save-tag SAVE_TAG] [--force-tag | --no-force-tag]
|
|
873
|
+
|
|
874
|
+
options:
|
|
875
|
+
-h, --help show this help message and exit
|
|
876
|
+
--seed SEED Root random seed for reproducible runs: every random
|
|
877
|
+
stream derives from it — data generation, dataset
|
|
878
|
+
split/shuffles, TF weight init, the VAE sampling layer
|
|
879
|
+
(training AND inference), the random forest,
|
|
880
|
+
UMAP/KMeans plot fits, and plot subsampling. Defaults
|
|
881
|
+
to a concrete value (reproducible out of the box);
|
|
882
|
+
must be >= 0. To run unseeded, pass --unseeded
|
|
883
|
+
--unseeded Opt OUT of the seeded default: draw every random
|
|
884
|
+
stream from OS entropy (non-reproducible). Mutually
|
|
885
|
+
exclusive with --seed
|
|
886
|
+
--tf-deterministic-ops, --no-tf-deterministic-ops
|
|
887
|
+
Force deterministic TensorFlow/cuDNN op
|
|
888
|
+
implementations
|
|
889
|
+
(tf.config.experimental.enable_op_determinism) for
|
|
890
|
+
bit-exact GPU reproducibility at some speed cost.
|
|
891
|
+
Default: enabled — without it, cuDNN autotune noise
|
|
892
|
+
can flip near-threshold candidates between identical
|
|
893
|
+
runs; opt out with --no-tf-deterministic-ops
|
|
894
|
+
--n-processes N_PROCESSES
|
|
895
|
+
Worker-process count for the multiprocessing pools
|
|
896
|
+
(energy detection + stamp extraction at inference;
|
|
897
|
+
data generation at training). Default: all cores. Host
|
|
898
|
+
tuning: never layered from a saved --config-path, so a
|
|
899
|
+
config recorded on a bigger host cannot oversubscribe
|
|
900
|
+
this one (must be >= 1)
|
|
901
|
+
--data-path DATA_PATH
|
|
902
|
+
Path to data directory (overrides AETHERSCAN_DATA_PATH
|
|
903
|
+
environment variable)
|
|
904
|
+
--model-path MODEL_PATH
|
|
905
|
+
Path to model directory (overrides
|
|
906
|
+
AETHERSCAN_MODEL_PATH environment variable)
|
|
907
|
+
--output-path OUTPUT_PATH
|
|
908
|
+
Path to output directory (overrides
|
|
909
|
+
AETHERSCAN_OUTPUT_PATH environment variable)
|
|
910
|
+
--dashboard, --no-dashboard
|
|
911
|
+
Auto-launch the live monitoring Streamlit dashboard
|
|
912
|
+
for this run; SSH-forward the port to view it
|
|
913
|
+
(default: on). Use --no-dashboard to disable
|
|
914
|
+
--dashboard-port DASHBOARD_PORT
|
|
915
|
+
Port for the auto-launched live dashboard (default:
|
|
916
|
+
8501)
|
|
917
|
+
--benchmark-report, --no-benchmark-report
|
|
918
|
+
Render the end-of-run benchmark report (stage timeline
|
|
919
|
+
+ bottleneck suggestions) and post it to Slack
|
|
920
|
+
(default: on). Use --no-benchmark-report to disable
|
|
921
|
+
--num-replicas NUM_REPLICAS
|
|
922
|
+
Number of GPUs to use for the distributed strategy. If
|
|
923
|
+
omitted, the strategy uses every GPU visible to TF;
|
|
924
|
+
otherwise it is restricted to the first N physical
|
|
925
|
+
GPUs and the rest are left untouched. Must be >= 1 and
|
|
926
|
+
<= the number of physical GPUs on your machine.
|
|
927
|
+
--gpu-memory-limit-mb GPU_MEMORY_LIMIT_MB
|
|
928
|
+
Per-GPU memory cap in MiB. Omit to use memory-growth-
|
|
929
|
+
only (recommended on Blackwell). Set for TF to
|
|
930
|
+
allocate a fixed logical device of a given size per
|
|
931
|
+
physical GPU (e.g. 14000)
|
|
932
|
+
--async-allocator, --no-async-allocator
|
|
933
|
+
Toggle TF_GPU_ALLOCATOR=cuda_malloc_async (default:
|
|
934
|
+
enabled). Pass --no-async-allocator as a workaround
|
|
935
|
+
for NGC 25.02 multi-GPU OOM bugs.
|
|
936
|
+
--test-files TEST_FILES [TEST_FILES ...]
|
|
937
|
+
Space-separated list of testing data file names (e.g.,
|
|
938
|
+
real_filtered_LARGE_test_HIP15638.npy)
|
|
939
|
+
--inference-files INFERENCE_FILES [INFERENCE_FILES ...]
|
|
940
|
+
Space-separated list of inference catalog file names
|
|
941
|
+
(e.g. complete_cadences_catalog.csv). Expects .h5
|
|
942
|
+
filepaths to individual observations, and sufficient
|
|
943
|
+
metadata for recovering cadence groupings. If
|
|
944
|
+
provided, triggers the energy detection preprocessing
|
|
945
|
+
pipeline and takes precedence over --test-files
|
|
946
|
+
--encoder-path ENCODER_PATH
|
|
947
|
+
Path to trained VAE encoder model file (.keras).
|
|
948
|
+
Optional: when none of --encoder-path/--rf-
|
|
949
|
+
path/--config-path are given, the artifacts are
|
|
950
|
+
downloaded from the HuggingFace Hub (see --hf-repo-
|
|
951
|
+
id/--hf-revision); provide either all three local
|
|
952
|
+
paths or none
|
|
953
|
+
--rf-path RF_PATH Path to trained Random Forest model file (.joblib).
|
|
954
|
+
Optional: see --encoder-path for the all-three-or-none
|
|
955
|
+
rule
|
|
956
|
+
--config-path CONFIG_PATH
|
|
957
|
+
Path to config file from corresponding training run
|
|
958
|
+
(.json). Optional: see --encoder-path for the all-
|
|
959
|
+
three-or-none rule
|
|
960
|
+
--per-replica-batch-size PER_REPLICA_BATCH_SIZE
|
|
961
|
+
Batch size per GPU/device replica during inference
|
|
962
|
+
--classification-threshold CLASSIFICATION_THRESHOLD
|
|
963
|
+
Science threshold for candidate detection, applied to
|
|
964
|
+
the pass-2 MC mean probability (the two-pass cascade's
|
|
965
|
+
final score)
|
|
966
|
+
--screening-threshold SCREENING_THRESHOLD
|
|
967
|
+
Permissive pass-1 screening threshold of the two-pass
|
|
968
|
+
cascade (tuned for recall; must not exceed
|
|
969
|
+
--classification-threshold). Snippets below it are
|
|
970
|
+
rejected without MC scoring
|
|
971
|
+
--mc-draws MC_DRAWS Seeded Monte-Carlo latent draws per pass-2 survivor
|
|
972
|
+
(mean carries the science threshold; std is the
|
|
973
|
+
reported uncertainty spread)
|
|
974
|
+
--reference-cloud-size REFERENCE_CLOUD_SIZE
|
|
975
|
+
Size of the seeded uniform reservoir of pass-1 rejects
|
|
976
|
+
MC-scored as the candidate uncertainty plot's survey
|
|
977
|
+
background (0 disables)
|
|
978
|
+
--prefetch-depth PREFETCH_DEPTH
|
|
979
|
+
Cadences preprocessed+loaded ahead of the GPU stage in
|
|
980
|
+
the streaming loop (>= 1). Each unit of depth overlaps
|
|
981
|
+
energy-detection reads with stamp extraction and the
|
|
982
|
+
serial per-cadence sections, costing one in-flight
|
|
983
|
+
cadence of RAM (up to ~65 GB for RFI-dense C-band
|
|
984
|
+
cadences); outputs are identical at any depth
|
|
985
|
+
(default: 3 per the on-cluster A/B)
|
|
986
|
+
--cadence-group-by-cols CADENCE_GROUP_BY_COLS [CADENCE_GROUP_BY_COLS ...]
|
|
987
|
+
Space-separated list of CSV column names whose joint
|
|
988
|
+
value defines cadence membership (e.g., Target Session
|
|
989
|
+
Band 'Cadence ID' Frequency)
|
|
990
|
+
--cadence-h5-path-col CADENCE_H5_PATH_COL
|
|
991
|
+
CSV column containing the .h5 file path for each
|
|
992
|
+
observation (default: '.h5 path')
|
|
993
|
+
--cadence-expected-obs CADENCE_EXPECTED_OBS
|
|
994
|
+
Required number of observations per cadence (default:
|
|
995
|
+
6 for ABACAD)
|
|
996
|
+
--coarse-channel-width COARSE_CHANNEL_WIDTH
|
|
997
|
+
Number of fine channels per coarse channel (default:
|
|
998
|
+
1048576)
|
|
999
|
+
--coarse-channel-log-interval COARSE_CHANNEL_LOG_INTERVAL
|
|
1000
|
+
Progress-logging cadence for energy detection, in
|
|
1001
|
+
coarse channels per log line. Default: ~25% milestone
|
|
1002
|
+
lines per ON file (the per-channel lines were 62% of a
|
|
1003
|
+
run's Slack-bound log volume); pass an explicit N to
|
|
1004
|
+
restore every-N-channels lines. Parallelism itself
|
|
1005
|
+
comes from the persistent worker pool, not this knob.
|
|
1006
|
+
--bandpass-method BANDPASS_METHOD
|
|
1007
|
+
Bandpass flattening method for energy detection: 'pfb'
|
|
1008
|
+
(default) divides each coarse channel by the
|
|
1009
|
+
instrument's static polyphase-filterbank response;
|
|
1010
|
+
'spline' fits and subtracts a per-channel spline
|
|
1011
|
+
--pfb-taps-per-channel PFB_TAPS_PER_CHANNEL
|
|
1012
|
+
PFB prototype-filter taps per coarse channel for
|
|
1013
|
+
--bandpass-method pfb (default: 12, the
|
|
1014
|
+
GBT/Breakthrough Listen backend value). INSTRUMENT-
|
|
1015
|
+
DEPENDENT: must match the backend that produced the
|
|
1016
|
+
.h5 files
|
|
1017
|
+
--bandpass-debug-plot, --no-bandpass-debug-plot
|
|
1018
|
+
Save a per-cadence bandpass-flattening overlay debug
|
|
1019
|
+
plot (raw vs flattened integrated spectrum for a few
|
|
1020
|
+
sampled coarse channels) under plots/inference/{save-
|
|
1021
|
+
tag}/ (default: off)
|
|
1022
|
+
--spline-order SPLINE_ORDER
|
|
1023
|
+
Spline order for bandpass fitting with --bandpass-
|
|
1024
|
+
method spline (default: 16)
|
|
1025
|
+
--detection-window-size DETECTION_WINDOW_SIZE
|
|
1026
|
+
Sliding window size in fine channels for normality
|
|
1027
|
+
test (default: 256)
|
|
1028
|
+
--detection-step-size DETECTION_STEP_SIZE
|
|
1029
|
+
Step size in fine channels for sliding window
|
|
1030
|
+
(default: 128)
|
|
1031
|
+
--stat-threshold STAT_THRESHOLD
|
|
1032
|
+
D'Agostino-Pearson statistic threshold for hit
|
|
1033
|
+
detection (default: 2048.0)
|
|
1034
|
+
--stamp-width STAMP_WIDTH
|
|
1035
|
+
Width in fine channels of the extracted stamp around
|
|
1036
|
+
each hit (default: 4096; must equal --width-bin)
|
|
1037
|
+
--store-downsampled-stamps, --no-store-downsampled-stamps
|
|
1038
|
+
Downsample stamps along frequency (by --downsample-
|
|
1039
|
+
factor) at extraction time, storing stamp_width //
|
|
1040
|
+
downsample_factor bins per stamp (~8x smaller at
|
|
1041
|
+
defaults; default: enabled). Pass --no-store-
|
|
1042
|
+
downsampled-stamps to archive raw-resolution stamps;
|
|
1043
|
+
loading handles both layouts.
|
|
1044
|
+
--overlap-search, --no-overlap-search
|
|
1045
|
+
Additionally extract stamps offset by
|
|
1046
|
+
±overlap_fraction*stamp_width around each hit. Pass
|
|
1047
|
+
--no-overlap-search to disable when the config default
|
|
1048
|
+
is True.
|
|
1049
|
+
--overlap-fraction OVERLAP_FRACTION
|
|
1050
|
+
Fractional offset (relative to stamp_width) for
|
|
1051
|
+
overlap-search stamps (default: 0.5)
|
|
1052
|
+
--preprocess-output-dir PREPROCESS_OUTPUT_DIR
|
|
1053
|
+
Directory for per-cadence .npy outputs from
|
|
1054
|
+
preprocessing. Default: a per-CSV directory {data_path
|
|
1055
|
+
}/inference/preprocessed/<csv_stem>_ed<hash>/ keyed on
|
|
1056
|
+
the energy-detection config fingerprint — runs sharing
|
|
1057
|
+
an ED config reuse each other's stamps automatically,
|
|
1058
|
+
and any ED-config change resolves to a fresh
|
|
1059
|
+
directory. Pass a directory explicitly to pin/share
|
|
1060
|
+
one location (reuse is still guarded by the sidecar's
|
|
1061
|
+
recorded h5 paths and ED fingerprint)
|
|
1062
|
+
--prune-stamps, --no-prune-stamps
|
|
1063
|
+
Delete each cadence's stamp .npy right after its
|
|
1064
|
+
'inferred' manifest row lands, keeping the metadata
|
|
1065
|
+
.json plus a ~196 KB snippet sidecar per candidate —
|
|
1066
|
+
resume rides the DB row, and only stamps this run
|
|
1067
|
+
freshly extracted are ever pruned. Without pruning a
|
|
1068
|
+
full catalog writes ~30-90 TB of stamps. Default: AUTO
|
|
1069
|
+
— enabled for the fingerprint-scoped default cache
|
|
1070
|
+
directory, disabled when --preprocess-output-dir is
|
|
1071
|
+
set explicitly. Pass --no-prune-stamps to keep every
|
|
1072
|
+
stamp (slice-scale runs wanting the cross-run rerun
|
|
1073
|
+
cache).
|
|
1074
|
+
--inference-viz, --no-inference-viz
|
|
1075
|
+
Render the inference visualization suite (energy
|
|
1076
|
+
detection distributions, hit spectrum, bandpass
|
|
1077
|
+
overlay, stamp/candidate galleries, confidence
|
|
1078
|
+
distribution, latent projection, summary card) at the
|
|
1079
|
+
end of a CSV inference run, saved under
|
|
1080
|
+
plots/inference/{save_tag}/ and uploaded to Slack
|
|
1081
|
+
(default: enabled). Pass --no-inference-viz to
|
|
1082
|
+
disable.
|
|
1083
|
+
--inference-viz-scope {full,new}
|
|
1084
|
+
Which cadences the metadata-driven viz figures cover:
|
|
1085
|
+
'full' (default) renders the whole accumulated tag
|
|
1086
|
+
every successful pass; 'new' renders only cadences
|
|
1087
|
+
inferred this pass — recommended for resumed multi-
|
|
1088
|
+
pass catalog campaigns, where 'full' re-pays the
|
|
1089
|
+
entire catalog's viz tail on every pass. DB-sourced
|
|
1090
|
+
candidate figures always cover the full tag either
|
|
1091
|
+
way.
|
|
1092
|
+
--stamp-gallery-top-k STAMP_GALLERY_TOP_K
|
|
1093
|
+
Number of top-statistic stamps shown in the stamp
|
|
1094
|
+
gallery figure, each as a 6-observation waterfall grid
|
|
1095
|
+
(default: 12)
|
|
1096
|
+
--max-candidate-plots MAX_CANDIDATE_PLOTS
|
|
1097
|
+
Maximum number of per-candidate figures rendered per
|
|
1098
|
+
run, highest confidence first (default: 50; the
|
|
1099
|
+
candidate gallery is unaffected)
|
|
1100
|
+
--max-retries MAX_RETRIES
|
|
1101
|
+
Maximum number of retry attempts for inference
|
|
1102
|
+
(including preprocessing) on failure
|
|
1103
|
+
--retry-delay RETRY_DELAY
|
|
1104
|
+
Delay in seconds between inference retry attempts
|
|
1105
|
+
--hf-repo-id HF_REPO_ID
|
|
1106
|
+
HuggingFace model repo id (namespace/name) for weight
|
|
1107
|
+
upload/download (default: zachtheyek/aetherscan)
|
|
1108
|
+
--hf-revision HF_REVISION
|
|
1109
|
+
HuggingFace revision (tag, branch, or commit hash) to
|
|
1110
|
+
pin the model download to when no local artifact paths
|
|
1111
|
+
are given (default: v{package version} when running as
|
|
1112
|
+
an installed release, else the repo's latest release
|
|
1113
|
+
tag — highest semver vX.Y.Z tag; a release tag is
|
|
1114
|
+
required for a no-artifact download)
|
|
1115
|
+
--save-tag SAVE_TAG Run label prefix: one of test, train, inf, bench. The
|
|
1116
|
+
datetime is appended automatically at runtime (e.g.
|
|
1117
|
+
inf_20260101_120000). Defaults to the subcommand
|
|
1118
|
+
(train->train, inference->inf) if omitted.
|
|
1119
|
+
--force-tag, --no-force-tag
|
|
1120
|
+
Override the fail-early save-tag collision guard:
|
|
1121
|
+
proceed even when an explicitly-provided --save-tag
|
|
1122
|
+
matches a previous run's saved config or DB rows
|
|
1123
|
+
(default: disabled)
|
|
1124
|
+
```
|
|
1125
|
+
|
|
1126
|
+
---
|
|
1127
|
+
|
|
1128
|
+
## Known Issues
|
|
1129
|
+
|
|
1130
|
+
For a list of known issues, limitations, and workarounds, see [`KNOWN_ISSUES.md`](/KNOWN_ISSUES.md).
|
|
1131
|
+
|
|
1132
|
+
---
|
|
1133
|
+
|
|
1134
|
+
## Contributing To Aetherscan
|
|
1135
|
+
|
|
1136
|
+
Contributions are welcome! Quick start:
|
|
1137
|
+
|
|
1138
|
+
```bash
|
|
1139
|
+
git clone https://github.com/zachtheyek/Aetherscan.git
|
|
1140
|
+
cd Aetherscan
|
|
1141
|
+
|
|
1142
|
+
singularity build aetherscan-ngc25.02.sif aetherscan.def
|
|
1143
|
+
# or:
|
|
1144
|
+
apptainer build aetherscan-ngc25.02.sif aetherscan.def
|
|
1145
|
+
|
|
1146
|
+
./utils/start_tmux_session.sh
|
|
1147
|
+
|
|
1148
|
+
pre-commit install
|
|
1149
|
+
```
|
|
1150
|
+
|
|
1151
|
+
- PRs: Must be linked to an existing issue and pass all hooks
|
|
1152
|
+
- Commits: Must carry a verified GPG signature — see [Commit Signing (GPG)](CONTRIBUTING.md#commit-signing-gpg)
|
|
1153
|
+
- Branches: Use `feature/`, `hotfix/`, or `misc/` prefixes
|
|
1154
|
+
- Code style: PEP-8 with minor relaxations, enforced via [ruff](https://docs.astral.sh/ruff/) (see [pyproject.toml](pyproject.toml))
|
|
1155
|
+
|
|
1156
|
+
See [`CONTRIBUTING.md`](/CONTRIBUTING.md) for full guidelines on workflow, project structure, and testing.
|
|
1157
|
+
|
|
1158
|
+
---
|
|
1159
|
+
|
|
1160
|
+
## Citations
|
|
1161
|
+
|
|
1162
|
+
If you use Aetherscan in your research, please cite it using GitHub's citations feature.
|
|
1163
|
+
|
|
1164
|
+
<p align="center">
|
|
1165
|
+
<img src="docs/assets/github-citation-button.png" alt="Citations">
|
|
1166
|
+
</p>
|
|
1167
|
+
|
|
1168
|
+
See [`CITATION.cff`](CITATION.cff) for details
|
|
1169
|
+
|
|
1170
|
+
---
|
|
1171
|
+
|
|
1172
|
+
## Security
|
|
1173
|
+
|
|
1174
|
+
Aetherscan is committed to responsible disclosure. Quick reference:
|
|
1175
|
+
|
|
1176
|
+
- **Report vulnerabilities:** Open a [GitHub Discussion](https://github.com/zachtheyek/Aetherscan/discussions) with the "security" label (non-critical) or contact [@zachtheyek](https://breakthroughlisten.slack.com/archives/D01SJG0L0TE) on Slack (critical; expect a response within 48-72h)
|
|
1177
|
+
- **Incident response:** Contain compromised credentials immediately, then assess scope, notify affected parties, remediate, and document
|
|
1178
|
+
- **Secrets:** Never commit tokens; use `.env` files (gitignored). Rotate immediately if compromised
|
|
1179
|
+
- **Automated scanning:** [gitleaks](https://github.com/gitleaks/gitleaks) pre-commit hook blocks accidental secret commits; GitHub Dependabot monitors for vulnerable dependencies
|
|
1180
|
+
|
|
1181
|
+
See [`SECURITY.md`](SECURITY.md) for more details.
|
|
1182
|
+
|
|
1183
|
+
---
|
|
1184
|
+
|
|
1185
|
+
## License
|
|
1186
|
+
|
|
1187
|
+
Aetherscan is distributed under the BSD-3-Clause license, a permissive license that allows commercial use, modification, and distribution with minimal restrictions. See [LICENSE](LICENSE) for details. All contributions to the project are assumed to be licensed under the same terms.
|