jflows 0.5.3__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.
- jflows/__init__.py +93 -0
- jflows/artifacts.py +46 -0
- jflows/boltzmann/__init__.py +1069 -0
- jflows/boltzmann/load.py +188 -0
- jflows/boltzmann/write.py +142 -0
- jflows/core/__init__.py +13 -0
- jflows/core/flows.py +507 -0
- jflows/core/nn.py +231 -0
- jflows/core/numerics.py +228 -0
- jflows/core/otflow.py +357 -0
- jflows/core/transforms.py +861 -0
- jflows/flow.py +735 -0
- jflows/loss.py +167 -0
- jflows/potential.py +538 -0
- jflows/train.py +608 -0
- jflows/utils/__init__.py +95 -0
- jflows/utils/anneal.py +299 -0
- jflows/utils/metrics.py +334 -0
- jflows/utils/optimization.py +447 -0
- jflows/utils/quench.py +91 -0
- jflows/utils/rejuvenation.py +404 -0
- jflows/version.py +3 -0
- jflows-0.5.3.dist-info/METADATA +254 -0
- jflows-0.5.3.dist-info/RECORD +27 -0
- jflows-0.5.3.dist-info/WHEEL +5 -0
- jflows-0.5.3.dist-info/licenses/LICENSE +21 -0
- jflows-0.5.3.dist-info/top_level.txt +1 -0
jflows/__init__.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""jflows — JAX normalizing flows for unconditional energy-based sampling.
|
|
2
|
+
|
|
3
|
+
Built on JAX and equinox.
|
|
4
|
+
|
|
5
|
+
Public surface:
|
|
6
|
+
|
|
7
|
+
jflows.flow : Flow, NSF, NCSF, CNF, OTFlow, RealNVP, ComposedTransform
|
|
8
|
+
jflows.potential : Potential, potential_from, Nlog_Uniform, Nlog_Gaussian,
|
|
9
|
+
Nlog_Gaussian_Mixture, linear_combination (+ the operator
|
|
10
|
+
algebra c*U, U+V, U-V, -U, U/c, sum([...]))
|
|
11
|
+
jflows.loss : reverse_KL_F, forward_KL_G, forward_KLX_G,
|
|
12
|
+
forward_X_G
|
|
13
|
+
jflows.train : Monitor and all train_* stage drivers
|
|
14
|
+
jflows.boltzmann : adaptive-staging and fixed-schedule boltzmann_* generators
|
|
15
|
+
jflows.artifacts : save and load medium-level training outputs
|
|
16
|
+
jflows.backend : selected/available JAX backends and accelerator model
|
|
17
|
+
jflows.utils : metrics / optimization / rejuvenation / anneal / quench
|
|
18
|
+
|
|
19
|
+
Internals (`jflows.core.*`) adapt zuko's clean flow and transform design.
|
|
20
|
+
The public computation API uses explicit PRNG keys and takes `Flow` objects
|
|
21
|
+
directly for losses, importance weights, AIS, and training.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from importlib.metadata import entry_points
|
|
25
|
+
from importlib.util import find_spec
|
|
26
|
+
import os
|
|
27
|
+
from shutil import which
|
|
28
|
+
import subprocess
|
|
29
|
+
|
|
30
|
+
import equinox
|
|
31
|
+
import jax
|
|
32
|
+
|
|
33
|
+
from . import artifacts, boltzmann, flow, loss, potential, train, utils
|
|
34
|
+
from .version import __version__
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def backend():
|
|
38
|
+
"""Print the available JAX backends and selected accelerator."""
|
|
39
|
+
plugins = tuple(item.name.lower() for item in entry_points(group="jax_plugins"))
|
|
40
|
+
available = ["CPU"]
|
|
41
|
+
details = ["- CPU — cpu"]
|
|
42
|
+
|
|
43
|
+
cuda_visible = os.environ.get("CUDA_VISIBLE_DEVICES") not in ("", "-1")
|
|
44
|
+
if cuda_visible and any("cuda" in name for name in plugins) and which("nvidia-smi"):
|
|
45
|
+
result = subprocess.run(
|
|
46
|
+
["nvidia-smi", "--query-gpu=name", "--format=csv,noheader"],
|
|
47
|
+
capture_output=True,
|
|
48
|
+
text=True,
|
|
49
|
+
)
|
|
50
|
+
models = tuple(
|
|
51
|
+
dict.fromkeys(line for line in result.stdout.splitlines() if line)
|
|
52
|
+
)
|
|
53
|
+
if result.returncode == 0 and models:
|
|
54
|
+
available.append("CUDA")
|
|
55
|
+
details.append(f"- CUDA — {', '.join(models)}")
|
|
56
|
+
|
|
57
|
+
rocm_visible = os.environ.get("ROCR_VISIBLE_DEVICES") not in ("", "-1")
|
|
58
|
+
if rocm_visible and any("rocm" in name for name in plugins) and which("rocm-smi"):
|
|
59
|
+
available.append("ROCm")
|
|
60
|
+
details.append("- ROCm")
|
|
61
|
+
|
|
62
|
+
if find_spec("libtpu"):
|
|
63
|
+
available.append("TPU")
|
|
64
|
+
details.append("- TPU")
|
|
65
|
+
|
|
66
|
+
configured = os.environ.get("JAX_PLATFORMS", "").split(",")[0].lower()
|
|
67
|
+
selected = {"cpu": "CPU", "cuda": "CUDA", "rocm": "ROCm", "tpu": "TPU"}.get(
|
|
68
|
+
configured
|
|
69
|
+
)
|
|
70
|
+
if selected not in available:
|
|
71
|
+
selected = next(
|
|
72
|
+
name for name in ("CUDA", "ROCm", "TPU", "CPU") if name in available
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
print(f"JAX {jax.__version__}")
|
|
76
|
+
print(f"Equinox {equinox.__version__}")
|
|
77
|
+
print(f"Selected backend: {selected}")
|
|
78
|
+
print(f"Available backends: {', '.join(available)}")
|
|
79
|
+
for detail in details:
|
|
80
|
+
print(detail)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
__all__ = [
|
|
84
|
+
"__version__",
|
|
85
|
+
"artifacts",
|
|
86
|
+
"backend",
|
|
87
|
+
"boltzmann",
|
|
88
|
+
"flow",
|
|
89
|
+
"loss",
|
|
90
|
+
"potential",
|
|
91
|
+
"train",
|
|
92
|
+
"utils",
|
|
93
|
+
]
|
jflows/artifacts.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Save and load medium-level training outputs."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import equinox as eqx
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"load_flow",
|
|
10
|
+
"load_history",
|
|
11
|
+
"load_samples",
|
|
12
|
+
"save_flow",
|
|
13
|
+
"save_history",
|
|
14
|
+
"save_samples",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def save_flow(path, flow) -> None:
|
|
19
|
+
"""Save one flow's array leaves."""
|
|
20
|
+
eqx.tree_serialise_leaves(Path(path), flow)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def load_flow(path, template):
|
|
24
|
+
"""Load flow leaves into a matching template."""
|
|
25
|
+
return eqx.tree_deserialise_leaves(Path(path), template)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def save_samples(path, samples) -> None:
|
|
29
|
+
"""Save one sample array."""
|
|
30
|
+
np.save(Path(path), np.asarray(samples), allow_pickle=False)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def load_samples(path):
|
|
34
|
+
"""Load one sample array."""
|
|
35
|
+
return np.load(Path(path), allow_pickle=False)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def save_history(path, **history) -> None:
|
|
39
|
+
"""Save named training-history arrays."""
|
|
40
|
+
np.savez(Path(path), **history)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def load_history(path) -> dict:
|
|
44
|
+
"""Load named training-history arrays."""
|
|
45
|
+
with np.load(Path(path), allow_pickle=False) as history:
|
|
46
|
+
return {name: history[name].copy() for name in history.files}
|