Skip to content

Commit eeee07c

Browse files
authored
Merge branch 'develop' into master
2 parents 938e298 + f31d1ea commit eeee07c

File tree

4 files changed

+57
-91
lines changed

4 files changed

+57
-91
lines changed

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<img src="figs/Neuromancer.png" width="250">
44
</p>
55

6-
# NeuroMANCER v1.5.5
6+
# NeuroMANCER v1.5.6
77

88
[![PyPi Version](https://img.shields.io/pypi/v/neuromancer)](https://pypi.org/project/neuromancer)
99
[![License](https://img.shields.io/badge/license-BSD-blue.svg)](https://github.com/pnnl/neuromancer/blob/master/LICENSE.md)
@@ -39,7 +39,7 @@ differentiable models and algorithms embedded with prior knowledge and physics.
3939
* **The NeuroMANCER-GPT Assistant**: We provide easy-to-use scripts to convert the contents of the NeuroMANCER library in a way that is suitable for ingestion in RAG-based "LLM-assistant" pipelines. Please see [Assistant](https://github.com/pnnl/neuromancer/blob/develop/assistant/README.md) to read more about how one can quickly spin up an LLM model to help understand and code in NeuroMANCER.
4040

4141

42-
## What's New in v1.5.5
42+
## What's New in v1.5.6
4343

4444

4545
### New Examples:
@@ -53,6 +53,10 @@ differentiable models and algorithms embedded with prior knowledge and physics.
5353
+ New class SystemPreview that acts as drop-in replacement for System class enabling preview horizon functionality
5454
+ Unit tests brought up-to-date.
5555

56+
### Fixed bug
57+
+ Fixed bug with mlflow dependency creating conflicts in Google Colab
58+
59+
5660
## Installation
5761
Simply run
5862
```

RELEASE_NOTES.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11

22
## Release notes
33

4-
### Version 1.5.5 Release Notes
4+
5+
### Version 1.5.6 Release Notes
6+
57
+ New feature: DPC with preview horizon using new class SystemPreview that acts as drop-in replacement for System class
68
+ New example: Neural DAEs via operator splitting method
79
+ New example: Mixed-Integer DPC for thermal system
810
+ New example: Grid-responsive DPC for building energy systems
11+
+ Fixed bug with mlflow dependency creating conflicts in Google Colab
12+
913

1014
### Version 1.5.4 Release Notes
1115
+ New feature: Function encoders for function approximation and zero-shot generalization in neural ODEs

pyproject.toml

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,44 @@
11
[build-system]
2-
requires = ["setuptools", "setuptools-scm"]
2+
requires = ["setuptools>=61"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "neuromancer"
7+
version = "1.5.6"
78
authors = [
89
{ name = "Jan Drgona", email = "[email protected]" },
910
{ name = "Aaron Tuor", email = "[email protected]" },
1011
{ name = "James Koch", email = "[email protected]" },
1112
{ name = "Madelyn Shapiro", email = "[email protected]"},
1213
{ name = "Rahul Birmiwal", email = "[email protected]"},
1314
{ name = "Draguna Vrabie", email = "[email protected]" },
14-
{ name = "Bruno Jacob", email = "bruno.jacbo@pnnl.gov" },
15+
{ name = "Bruno Jacob", email = "bruno.jacob@pnnl.gov" },
1516
{ name = "Reilly Raab", email = "[email protected]" }
1617
]
1718
description = "Neural Modules with Adaptive Nonlinear Constraints and Efficient Regularization"
1819
readme = "README.md"
1920
requires-python = ">=3.9"
20-
keywords = [
21-
"Deep Learning",
22-
"Pytorch",
23-
"Linear Models",
24-
"Dynamical Systems",
25-
"Data-driven control",
26-
]
27-
28-
29-
3021
license = { text = "BSD-2-Clause" }
22+
keywords = ["Deep Learning","Pytorch","Scientific Machine Learning","Dynamical Systems","Data-driven control"]
3123
classifiers = [
32-
"Programming Language :: Python :: 3.9",
33-
"Programming Language :: Python :: 3.10",
34-
"Programming Language :: Python :: 3.11",
35-
"Topic :: Scientific/Engineering :: Artificial Intelligence",
36-
"Topic :: Scientific/Engineering :: Physics",
37-
"License :: OSI Approved :: BSD License"
24+
"Programming Language :: Python :: 3.9",
25+
"Programming Language :: Python :: 3.10",
26+
"Programming Language :: Python :: 3.11",
27+
"Programming Language :: Python :: 3.12",
28+
"Operating System :: OS Independent",
29+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
30+
"Topic :: Scientific/Engineering :: Physics",
31+
"License :: OSI Approved :: BSD License"
3832
]
3933
dependencies = [
4034
"dill",
4135
"graphviz",
4236
"matplotlib",
43-
"mlflow==2.5.0",
44-
"networkx==3.0.0",
45-
"numpy==1.26.0",
37+
"networkx>=3,<4",
38+
"numpy>=1.23,<3.0",
4639
"pandas",
47-
"plum_dispatch==1.7.3",
48-
"scikit_learn",
40+
"plum-dispatch==1.7.3",
41+
"scikit-learn",
4942
"scipy",
5043
"six",
5144
"pydot==1.4.2",
@@ -56,13 +49,10 @@ dependencies = [
5649
"lightning",
5750
"cvxpy",
5851
"cvxpylayers",
59-
"casadi",
60-
"wandb",
52+
"casadi",
6153
"torchsde"
6254
]
6355

64-
version = "1.5.5"
65-
6656
[project.urls]
6757
homepage = "https://github.com/pnnl/neuromancer/"
6858
documentation = "https://github.com/pnnl/neuromancer/"
@@ -76,5 +66,6 @@ where = ["src"]
7666

7767
[project.optional-dependencies]
7868
tests = ["pytest", "hypothesis"]
79-
examples = ["casadi", "cvxpy", "imageio", "cvxpylayers"]
69+
examples = ["imageio"]
8070
docs = ["sphinx", "sphinx-rtd-theme"]
71+
tracking = ["mlflow>=2.12,<3", "wandb"]

src/neuromancer/loggers.py

Lines changed: 27 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import time
55
import os
66
import shutil
7-
8-
import mlflow
97
import torch
108
import dill
119
import numbers
@@ -132,89 +130,58 @@ def get_losses(self):
132130

133131
class MLFlowLogger(BasicLogger):
134132
def __init__(self, args=None, savedir='test', verbosity=1, id=None,
135-
stdout=('nstep_dev_loss', 'loop_dev_loss', 'best_loop_dev_loss',
136-
'nstep_dev_ref_loss', 'loop_dev_ref_loss'),
133+
stdout=('nstep_dev_loss','loop_dev_loss','best_loop_dev_loss',
134+
'nstep_dev_ref_loss','loop_dev_ref_loss'),
137135
logout=None):
138-
"""
139-
140-
:param args: (Namespace) returned by argparse.ArgumentParser.parse_args()
141-
args.location (str): path to directory on file system to store experiment results via mlflow
142-
or if 'pnl_dadaist_store' then will save to our instance of the pnl mlflow
143-
server. Must have copy of pnl_mlflow_secrets.py (containing a funtion to set
144-
necessary environment variables) located in neuromancer/neuromancer/
145-
where main modules are located.
146-
:param savedir: Unique folder name to temporarily save artifacts
147-
:param verbosity: (int) Print to stdout every verbosity steps
148-
:param id: (int) Optional unique experiment ID for hyperparameter optimization
149-
:param stdout: (list of str) Metrics to print to stdout. These should correspond to keys in the output dictionary of the Problem
150-
:param logout: (list of str) List of metric names to log via mlflow
151-
"""
136+
# Lazy import so module import works even if mlflow isn't installed
137+
try:
138+
import mlflow # noqa: F401
139+
except Exception as e:
140+
raise ImportError(
141+
"MLFlowLogger requires mlflow. Install with "
142+
"`pip install neuromancer[tracking]` or `pip install mlflow>=2.12`."
143+
) from e
144+
145+
import mlflow # use after we know it exists
146+
147+
self._mlflow = mlflow
148+
self._mlflow.set_tracking_uri(args.location)
149+
self._mlflow.set_experiment(args.exp)
150+
self._mlflow.start_run(run_name=args.run, run_id=id)
152151

153-
mlflow.set_tracking_uri(args.location)
154-
mlflow.set_experiment(args.exp)
155-
mlflow.start_run(run_name=args.run, run_id=id)
156152
super().__init__(args=args, savedir=savedir, verbosity=verbosity, stdout=stdout)
157153
self.logout = logout
158154

159155
def log_parameters(self):
160-
"""
161-
Print experiment parameters to stdout
162-
163-
"""
164156
params = {k: getattr(self.args, k) for k in vars(self.args)}
165157
print({k: type(v) for k, v in params.items()})
166-
167-
mlflow.log_params(params)
158+
self._mlflow.log_params(params)
168159

169160
def log_weights(self, model):
170-
"""
171-
172-
:param model: (nn.Module)
173-
:return: (int) Number of learnable parameters in the model.
174-
"""
175161
nweights = super().log_weights(model)
176-
mlflow.log_metric('nparams', float(nweights))
162+
self._mlflow.log_metric('nparams', float(nweights))
177163

178164
def log_metrics(self, output, step=0):
179-
"""
180-
Record metrics to mlflow
181-
182-
:param output: (dict {str: tensor}) Will only record 0d torch.Tensors (scalars)
183-
:param step: (int) Epoch of training
184-
"""
185165
super().log_metrics(output, step)
186-
_keys = {k for k in output.keys()}
166+
keys = set(output.keys())
187167
if self.logout is not None:
188-
keys = []
189-
for k in _keys:
190-
for kp in self.logout:
191-
if kp in k:
192-
keys.append(k)
193-
else:
194-
keys = _keys
168+
keys = {k for k in keys if any(p in k for p in self.logout)}
195169
for k in keys:
196170
v = output[k]
197171
if isinstance(v, torch.Tensor) and torch.numel(v) == 1:
198-
mlflow.log_metric(k, v.item())
172+
self._mlflow.log_metric(k, v.item())
199173
elif isinstance(v, np.ndarray) and v.size == 1:
200-
mlflow.log_metric(k, v.flatten())
174+
self._mlflow.log_metric(k, float(v))
201175
elif isinstance(v, numbers.Number):
202-
mlflow.log_metric(k, v)
176+
self._mlflow.log_metric(k, v)
203177

204178
def log_artifacts(self, artifacts=dict()):
205-
"""
206-
Stores artifacts created in training to mlflow.
207-
208-
:param artifacts: (dict {str: Object})
209-
"""
210179
super().log_artifacts(artifacts)
211-
mlflow.log_artifacts(self.savedir)
180+
self._mlflow.log_artifacts(self.savedir)
212181

213182
def clean_up(self):
214-
"""
215-
Remove temporary files from file system
216-
"""
217183
shutil.rmtree(self.savedir)
218-
mlflow.end_run()
184+
self._mlflow.end_run()
185+
219186

220187

0 commit comments

Comments
 (0)