wandb 0.18.7__py3-none-win_amd64.whl → 0.19.0rc1__py3-none-win_amd64.whl
Sign up to get free protection for your applications and to get access to all the features.
- package_readme.md +8 -0
- wandb/__init__.py +5 -7
- wandb/__init__.pyi +51 -30
- wandb/analytics/sentry.py +4 -10
- wandb/apis/importers/internals/internal.py +6 -6
- wandb/apis/importers/internals/protocols.py +11 -7
- wandb/apis/public/jobs.py +1 -7
- wandb/apis/public/reports.py +6 -17
- wandb/apis/public/runs.py +12 -10
- wandb/bin/gpu_stats.exe +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +9 -45
- wandb/env.py +3 -5
- wandb/errors/links.py +1 -1
- wandb/errors/term.py +1 -6
- wandb/filesync/dir_watcher.py +3 -3
- wandb/filesync/step_upload.py +2 -5
- wandb/integration/fastai/__init__.py +1 -6
- wandb/integration/gym/__init__.py +1 -7
- wandb/integration/keras/callbacks/metrics_logger.py +1 -8
- wandb/integration/keras/callbacks/model_checkpoint.py +1 -8
- wandb/integration/keras/keras.py +3 -5
- wandb/integration/lightgbm/__init__.py +1 -1
- wandb/integration/sb3/sb3.py +1 -7
- wandb/integration/sklearn/utils.py +1 -1
- wandb/integration/tensorboard/log.py +1 -2
- wandb/integration/torch/wandb_torch.py +1 -1
- wandb/integration/ultralytics/bbox_utils.py +9 -2
- wandb/jupyter.py +4 -4
- wandb/proto/v3/wandb_internal_pb2.py +31 -31
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_internal_pb2.py +31 -31
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v5/wandb_internal_pb2.py +31 -31
- wandb/proto/v5/wandb_settings_pb2.py +2 -2
- wandb/proto/wandb_deprecated.py +1 -11
- wandb/proto/wandb_generate_deprecated.py +3 -7
- wandb/sdk/artifacts/artifact.py +2 -10
- wandb/sdk/artifacts/artifact_file_cache.py +2 -5
- wandb/sdk/artifacts/artifact_saver.py +2 -6
- wandb/sdk/artifacts/storage_handlers/gcs_handler.py +2 -4
- wandb/sdk/artifacts/storage_handlers/local_file_handler.py +2 -4
- wandb/sdk/artifacts/storage_handlers/s3_handler.py +2 -4
- wandb/sdk/backend/backend.py +1 -1
- wandb/sdk/data_types/histogram.py +1 -3
- wandb/sdk/data_types/object_3d.py +2 -6
- wandb/sdk/data_types/table.py +1 -1
- wandb/sdk/data_types/utils.py +1 -2
- wandb/sdk/data_types/video.py +15 -4
- wandb/sdk/integration_utils/auto_logging.py +1 -8
- wandb/sdk/interface/interface.py +12 -5
- wandb/sdk/interface/interface_shared.py +9 -0
- wandb/sdk/internal/file_stream.py +1 -4
- wandb/sdk/internal/flow_control.py +1 -1
- wandb/sdk/internal/handler.py +7 -2
- wandb/sdk/internal/internal.py +3 -3
- wandb/sdk/internal/internal_api.py +3 -10
- wandb/sdk/internal/job_builder.py +20 -12
- wandb/sdk/internal/progress.py +1 -5
- wandb/sdk/internal/sender.py +9 -13
- wandb/sdk/internal/settings_static.py +4 -10
- wandb/sdk/internal/system/assets/cpu.py +2 -2
- wandb/sdk/internal/system/assets/disk.py +3 -3
- wandb/sdk/internal/system/assets/gpu.py +7 -7
- wandb/sdk/internal/system/assets/gpu_amd.py +1 -7
- wandb/sdk/internal/system/assets/interfaces.py +11 -13
- wandb/sdk/internal/system/assets/ipu.py +1 -1
- wandb/sdk/internal/system/assets/memory.py +2 -2
- wandb/sdk/internal/system/assets/open_metrics.py +2 -8
- wandb/sdk/internal/system/assets/trainium.py +3 -9
- wandb/sdk/internal/system/system_info.py +14 -13
- wandb/sdk/internal/system/system_monitor.py +5 -12
- wandb/sdk/internal/tb_watcher.py +1 -1
- wandb/sdk/internal/writer.py +1 -1
- wandb/sdk/launch/agent/run_queue_item_file_saver.py +1 -7
- wandb/sdk/launch/create_job.py +2 -3
- wandb/sdk/launch/runner/abstract.py +1 -6
- wandb/sdk/launch/runner/kubernetes_monitor.py +2 -4
- wandb/sdk/lib/apikey.py +2 -6
- wandb/sdk/lib/fsm.py +12 -6
- wandb/sdk/lib/ipython.py +1 -6
- wandb/sdk/lib/module.py +0 -3
- wandb/sdk/lib/progress.py +2 -3
- wandb/sdk/lib/run_moment.py +1 -7
- wandb/sdk/lib/server.py +10 -24
- wandb/sdk/service/server.py +1 -1
- wandb/sdk/service/service.py +5 -5
- wandb/sdk/wandb_init.py +215 -166
- wandb/sdk/wandb_login.py +17 -27
- wandb/sdk/wandb_run.py +90 -116
- wandb/sdk/wandb_settings.py +978 -1778
- wandb/sdk/wandb_setup.py +86 -89
- wandb/sdk/wandb_watch.py +1 -1
- wandb/sync/sync.py +1 -2
- wandb/util.py +6 -39
- wandb/wandb_controller.py +10 -12
- {wandb-0.18.7.dist-info → wandb-0.19.0rc1.dist-info}/METADATA +14 -4
- {wandb-0.18.7.dist-info → wandb-0.19.0rc1.dist-info}/RECORD +101 -106
- {wandb-0.18.7.dist-info → wandb-0.19.0rc1.dist-info}/WHEEL +1 -1
- wandb/integration/magic.py +0 -556
- wandb/magic.py +0 -3
- wandb/sdk/lib/_settings_toposort_generate.py +0 -159
- wandb/sdk/lib/_settings_toposort_generated.py +0 -251
- wandb/sdk/lib/reporting.py +0 -99
- {wandb-0.18.7.dist-info → wandb-0.19.0rc1.dist-info}/entry_points.txt +0 -0
- {wandb-0.18.7.dist-info → wandb-0.19.0rc1.dist-info}/licenses/LICENSE +0 -0
wandb/integration/magic.py
DELETED
@@ -1,556 +0,0 @@
|
|
1
|
-
import argparse
|
2
|
-
import copy
|
3
|
-
import json
|
4
|
-
import os
|
5
|
-
import re
|
6
|
-
import sys
|
7
|
-
|
8
|
-
import yaml
|
9
|
-
|
10
|
-
import wandb
|
11
|
-
from wandb import trigger
|
12
|
-
from wandb.sdk.lib import ipython
|
13
|
-
from wandb.util import add_import_hook, get_optional_module
|
14
|
-
|
15
|
-
_import_hook = None
|
16
|
-
_run_once = False
|
17
|
-
_args_argparse = None
|
18
|
-
_args_system = None
|
19
|
-
_args_absl = None
|
20
|
-
_magic_init_seen = False
|
21
|
-
_magic_config = {}
|
22
|
-
|
23
|
-
|
24
|
-
class ArgumentException(Exception):
|
25
|
-
pass
|
26
|
-
|
27
|
-
|
28
|
-
class SafeArgumentParser(argparse.ArgumentParser):
|
29
|
-
def error(self, message):
|
30
|
-
raise ArgumentException()
|
31
|
-
|
32
|
-
|
33
|
-
def _merge_dicts(source, destination):
|
34
|
-
for key, value in source.items():
|
35
|
-
if isinstance(value, dict):
|
36
|
-
node = destination.setdefault(key, {})
|
37
|
-
_merge_dicts(value, node)
|
38
|
-
else:
|
39
|
-
destination[key] = value
|
40
|
-
return destination
|
41
|
-
|
42
|
-
|
43
|
-
def _dict_from_keyval(k, v, json_parse=True):
|
44
|
-
d = ret = {}
|
45
|
-
keys = k.split(".")
|
46
|
-
for k in keys[:-1]:
|
47
|
-
d = d.setdefault(k, {})
|
48
|
-
if json_parse:
|
49
|
-
try:
|
50
|
-
v = json.loads(v.strip('"'))
|
51
|
-
except ValueError:
|
52
|
-
pass
|
53
|
-
d[keys[-1]] = v
|
54
|
-
return ret
|
55
|
-
|
56
|
-
|
57
|
-
def _magic_get_config(k, default):
|
58
|
-
d = _magic_config
|
59
|
-
keys = k.split(".")
|
60
|
-
for k in keys[:-1]:
|
61
|
-
d = d.get(k, {})
|
62
|
-
return d.get(keys[-1], default)
|
63
|
-
|
64
|
-
|
65
|
-
_magic_defaults = {
|
66
|
-
"enable": None,
|
67
|
-
#'wandb': {
|
68
|
-
# 'disable': None,
|
69
|
-
# },
|
70
|
-
"keras": {
|
71
|
-
"fit": {
|
72
|
-
"callbacks": {
|
73
|
-
"tensorboard": {
|
74
|
-
"enable": True,
|
75
|
-
"duplicate": False,
|
76
|
-
"overwrite": False,
|
77
|
-
"write_graph": None,
|
78
|
-
"histogram_freq": None,
|
79
|
-
"update_freq": None,
|
80
|
-
"write_grads": None,
|
81
|
-
"write_images": None,
|
82
|
-
"batch_size": None,
|
83
|
-
},
|
84
|
-
"wandb": {
|
85
|
-
"enable": True,
|
86
|
-
"duplicate": False,
|
87
|
-
"overwrite": False,
|
88
|
-
"log_gradients": None,
|
89
|
-
"log_weights": None,
|
90
|
-
"data_type": "auto",
|
91
|
-
"input_type": None,
|
92
|
-
"output_type": None,
|
93
|
-
"log_evaluation": None,
|
94
|
-
"labels": None,
|
95
|
-
"predictions": None,
|
96
|
-
"save_model": None,
|
97
|
-
"save_weights_only": None,
|
98
|
-
"monitor": None,
|
99
|
-
"mode": None,
|
100
|
-
"verbose": None,
|
101
|
-
},
|
102
|
-
"epochs": None,
|
103
|
-
"batch_size": None,
|
104
|
-
}
|
105
|
-
},
|
106
|
-
#'compile': {
|
107
|
-
# 'optimizer': {
|
108
|
-
# 'name': False,
|
109
|
-
# },
|
110
|
-
# 'loss': None,
|
111
|
-
# },
|
112
|
-
},
|
113
|
-
"args": {
|
114
|
-
"absl": None,
|
115
|
-
"argparse": None,
|
116
|
-
"sys": None,
|
117
|
-
},
|
118
|
-
}
|
119
|
-
|
120
|
-
|
121
|
-
def _parse_magic(val):
|
122
|
-
# attempt to treat string as a json
|
123
|
-
not_set = {}
|
124
|
-
if val is None:
|
125
|
-
return _magic_defaults, not_set
|
126
|
-
if val.startswith("{"):
|
127
|
-
try:
|
128
|
-
val = json.loads(val)
|
129
|
-
except ValueError:
|
130
|
-
wandb.termwarn("Unable to parse magic json", repeat=False)
|
131
|
-
return _magic_defaults, not_set
|
132
|
-
conf = _merge_dicts(_magic_defaults, {})
|
133
|
-
return _merge_dicts(val, conf), val
|
134
|
-
if os.path.isfile(val):
|
135
|
-
try:
|
136
|
-
with open(val) as stream:
|
137
|
-
val = yaml.safe_load(stream)
|
138
|
-
except OSError as e:
|
139
|
-
wandb.termwarn("Unable to read magic config file", repeat=False)
|
140
|
-
return _magic_defaults, not_set
|
141
|
-
except yaml.YAMLError as e:
|
142
|
-
wandb.termwarn("Unable to parse magic yaml file", repeat=False)
|
143
|
-
return _magic_defaults, not_set
|
144
|
-
conf = _merge_dicts(_magic_defaults, {})
|
145
|
-
return _merge_dicts(val, conf), val
|
146
|
-
# parse as a list of key value pairs
|
147
|
-
if val.find("=") > 0:
|
148
|
-
# split on commas but ignore commas inside quotes
|
149
|
-
# Using this re allows env variable parsing like:
|
150
|
-
# WANDB_MAGIC=key1='"["cat","dog","pizza"]"',key2=true
|
151
|
-
items = re.findall(r'(?:[^\s,"]|"(?:\\.|[^"])*")+', val)
|
152
|
-
conf_set = {}
|
153
|
-
for kv in items:
|
154
|
-
kv = kv.split("=")
|
155
|
-
if len(kv) != 2:
|
156
|
-
wandb.termwarn("Unable to parse magic key value pair", repeat=False)
|
157
|
-
continue
|
158
|
-
d = _dict_from_keyval(*kv)
|
159
|
-
_merge_dicts(d, conf_set)
|
160
|
-
conf = _merge_dicts(_magic_defaults, {})
|
161
|
-
return _merge_dicts(conf_set, conf), conf_set
|
162
|
-
wandb.termwarn("Unable to parse magic parameter", repeat=False)
|
163
|
-
return _magic_defaults, not_set
|
164
|
-
|
165
|
-
|
166
|
-
def set_entity(value, env=None):
|
167
|
-
if env is None:
|
168
|
-
env = os.environ
|
169
|
-
|
170
|
-
|
171
|
-
def _fit_wrapper(self, fn, generator=None, *args, **kwargs):
|
172
|
-
trigger.call("on_fit")
|
173
|
-
keras = sys.modules.get("keras", None)
|
174
|
-
tfkeras = sys.modules.get("tensorflow.python.keras", None)
|
175
|
-
epochs = kwargs.pop("epochs", None)
|
176
|
-
batch_size = kwargs.pop("batch_size", None)
|
177
|
-
|
178
|
-
magic_epochs = _magic_get_config("keras.fit.epochs", None)
|
179
|
-
if magic_epochs is not None:
|
180
|
-
epochs = magic_epochs
|
181
|
-
magic_batch_size = _magic_get_config("keras.fit.batch_size", None)
|
182
|
-
if magic_batch_size is not None:
|
183
|
-
batch_size = magic_batch_size
|
184
|
-
callbacks = kwargs.pop("callbacks", [])
|
185
|
-
|
186
|
-
tb_enabled = _magic_get_config("keras.fit.callbacks.tensorboard.enable", None)
|
187
|
-
if tb_enabled:
|
188
|
-
k = getattr(self, "_keras_or_tfkeras", None)
|
189
|
-
if k:
|
190
|
-
tb_duplicate = _magic_get_config(
|
191
|
-
"keras.fit.callbacks.tensorboard.duplicate", None
|
192
|
-
)
|
193
|
-
tb_overwrite = _magic_get_config(
|
194
|
-
"keras.fit.callbacks.tensorboard.overwrite", None
|
195
|
-
)
|
196
|
-
tb_present = any(
|
197
|
-
[isinstance(cb, k.callbacks.TensorBoard) for cb in callbacks]
|
198
|
-
)
|
199
|
-
if tb_present and tb_overwrite:
|
200
|
-
callbacks = [
|
201
|
-
cb
|
202
|
-
for cb in callbacks
|
203
|
-
if not isinstance(cb, k.callbacks.TensorBoard)
|
204
|
-
]
|
205
|
-
if tb_overwrite or tb_duplicate or not tb_present:
|
206
|
-
tb_callback_kwargs = {"log_dir": wandb.run.dir}
|
207
|
-
cb_args = (
|
208
|
-
"write_graph",
|
209
|
-
"histogram_freq",
|
210
|
-
"update_freq",
|
211
|
-
"write_grads",
|
212
|
-
"write_images",
|
213
|
-
"batch_size",
|
214
|
-
)
|
215
|
-
for cb_arg in cb_args:
|
216
|
-
v = _magic_get_config(
|
217
|
-
"keras.fit.callbacks.tensorboard." + cb_arg, None
|
218
|
-
)
|
219
|
-
if v is not None:
|
220
|
-
tb_callback_kwargs[cb_arg] = v
|
221
|
-
tb_callback = k.callbacks.TensorBoard(**tb_callback_kwargs)
|
222
|
-
callbacks.append(tb_callback)
|
223
|
-
|
224
|
-
wandb_enabled = _magic_get_config("keras.fit.callbacks.wandb.enable", None)
|
225
|
-
if wandb_enabled:
|
226
|
-
wandb_duplicate = _magic_get_config("keras.fit.callbacks.wandb.duplicate", None)
|
227
|
-
wandb_overwrite = _magic_get_config("keras.fit.callbacks.wandb.overwrite", None)
|
228
|
-
wandb_present = any(
|
229
|
-
[isinstance(cb, wandb.keras.WandbCallback) for cb in callbacks]
|
230
|
-
)
|
231
|
-
if wandb_present and wandb_overwrite:
|
232
|
-
callbacks = [
|
233
|
-
cb for cb in callbacks if not isinstance(cb, wandb.keras.WandbCallback)
|
234
|
-
]
|
235
|
-
if wandb_overwrite or wandb_duplicate or not wandb_present:
|
236
|
-
wandb_callback_kwargs = {}
|
237
|
-
log_gradients = _magic_get_config(
|
238
|
-
"keras.fit.callbacks.wandb.log_gradients", None
|
239
|
-
)
|
240
|
-
if log_gradients and kwargs.get("x") and kwargs.get("y"):
|
241
|
-
wandb_callback_kwargs["log_gradients"] = log_gradients
|
242
|
-
cb_args = (
|
243
|
-
"predictions",
|
244
|
-
"log_weights",
|
245
|
-
"data_type",
|
246
|
-
"save_model",
|
247
|
-
"save_weights_only",
|
248
|
-
"monitor",
|
249
|
-
"mode",
|
250
|
-
"verbose",
|
251
|
-
"input_type",
|
252
|
-
"output_type",
|
253
|
-
"log_evaluation",
|
254
|
-
"labels",
|
255
|
-
)
|
256
|
-
for cb_arg in cb_args:
|
257
|
-
v = _magic_get_config("keras.fit.callbacks.wandb." + cb_arg, None)
|
258
|
-
if v is not None:
|
259
|
-
wandb_callback_kwargs[cb_arg] = v
|
260
|
-
wandb_callback = wandb.keras.WandbCallback(**wandb_callback_kwargs)
|
261
|
-
callbacks.append(wandb_callback)
|
262
|
-
|
263
|
-
kwargs["callbacks"] = callbacks
|
264
|
-
if epochs is not None:
|
265
|
-
kwargs["epochs"] = epochs
|
266
|
-
if batch_size is not None:
|
267
|
-
kwargs["batch_size"] = batch_size
|
268
|
-
if generator:
|
269
|
-
return fn(generator, *args, **kwargs)
|
270
|
-
return fn(*args, **kwargs)
|
271
|
-
|
272
|
-
|
273
|
-
# NOTE(jhr): need to spell out all usable args so that users who inspect can see args
|
274
|
-
def _magic_fit(
|
275
|
-
self,
|
276
|
-
x=None,
|
277
|
-
y=None,
|
278
|
-
batch_size=None,
|
279
|
-
epochs=1,
|
280
|
-
# FIXME: there is more
|
281
|
-
# verbose=1,
|
282
|
-
# callbacks=None,
|
283
|
-
# validation_split=0.,
|
284
|
-
# validation_data=None,
|
285
|
-
# shuffle=True,
|
286
|
-
# class_weight=None,
|
287
|
-
# sample_weight=None,
|
288
|
-
# initial_epoch=0,
|
289
|
-
# steps_per_epoch=None,
|
290
|
-
# validation_steps=None,
|
291
|
-
# validation_freq=1,
|
292
|
-
# max_queue_size=10,
|
293
|
-
# workers=1,
|
294
|
-
# use_multiprocessing=False,
|
295
|
-
*args,
|
296
|
-
**kwargs,
|
297
|
-
):
|
298
|
-
if hasattr(self, "_wandb_internal_model"):
|
299
|
-
return self._fit(
|
300
|
-
x=x, y=y, batch_size=batch_size, epochs=epochs, *args, **kwargs
|
301
|
-
)
|
302
|
-
return _fit_wrapper(
|
303
|
-
self, self._fit, x=x, y=y, batch_size=batch_size, epochs=epochs, *args, **kwargs
|
304
|
-
)
|
305
|
-
|
306
|
-
|
307
|
-
def _magic_fit_generator(
|
308
|
-
self,
|
309
|
-
generator,
|
310
|
-
steps_per_epoch=None,
|
311
|
-
epochs=1,
|
312
|
-
# FIXME: there is more
|
313
|
-
# verbose=1,
|
314
|
-
# verbose=1,
|
315
|
-
# callbacks=None,
|
316
|
-
# validation_data=None,
|
317
|
-
# validation_steps=None,
|
318
|
-
# validation_freq=1,
|
319
|
-
# class_weight=None,
|
320
|
-
# max_queue_size=10,
|
321
|
-
# workers=1,
|
322
|
-
##use_multiprocessing=False,
|
323
|
-
# shuffle=True,
|
324
|
-
# initial_epoch=0,
|
325
|
-
*args,
|
326
|
-
**kwargs,
|
327
|
-
):
|
328
|
-
return _fit_wrapper(
|
329
|
-
self,
|
330
|
-
self._fit_generator,
|
331
|
-
generator=generator,
|
332
|
-
steps_per_epoch=steps_per_epoch,
|
333
|
-
epochs=epochs,
|
334
|
-
*args,
|
335
|
-
**kwargs,
|
336
|
-
)
|
337
|
-
|
338
|
-
|
339
|
-
def _monkey_tfkeras():
|
340
|
-
from tensorflow import keras as tfkeras
|
341
|
-
|
342
|
-
from wandb.integration.keras import WandbCallback # add keras import hooks first
|
343
|
-
|
344
|
-
models = getattr(tfkeras, "models", None)
|
345
|
-
if not models:
|
346
|
-
return
|
347
|
-
models.Model._keras_or_tfkeras = tfkeras
|
348
|
-
if models.Model.fit == _magic_fit:
|
349
|
-
return
|
350
|
-
models.Model._fit = models.Model.fit
|
351
|
-
models.Model.fit = _magic_fit
|
352
|
-
models.Model._fit_generator = models.Model.fit_generator
|
353
|
-
models.Model.fit_generator = _magic_fit_generator
|
354
|
-
|
355
|
-
|
356
|
-
def _monkey_absl():
|
357
|
-
from absl import app as absl_app
|
358
|
-
|
359
|
-
def _absl_callback():
|
360
|
-
absl_flags = sys.modules.get("absl.flags")
|
361
|
-
if not absl_flags:
|
362
|
-
return
|
363
|
-
_flags = getattr(absl_flags, "FLAGS", None)
|
364
|
-
if not _flags:
|
365
|
-
return
|
366
|
-
_flags_as_dict = getattr(_flags, "flag_values_dict", None)
|
367
|
-
if not _flags_as_dict:
|
368
|
-
return
|
369
|
-
_flags_module = getattr(_flags, "find_module_defining_flag", None)
|
370
|
-
if not _flags_module:
|
371
|
-
return
|
372
|
-
flags_dict = {}
|
373
|
-
for f, v in _flags_as_dict().items():
|
374
|
-
m = _flags_module(f)
|
375
|
-
if not m or m.startswith("absl."):
|
376
|
-
continue
|
377
|
-
flags_dict[f] = v
|
378
|
-
global _args_absl
|
379
|
-
_args_absl = flags_dict
|
380
|
-
|
381
|
-
call_after_init = getattr(absl_app, "call_after_init", None)
|
382
|
-
if not call_after_init:
|
383
|
-
return
|
384
|
-
call_after_init(_absl_callback)
|
385
|
-
|
386
|
-
|
387
|
-
def _process_system_args():
|
388
|
-
global _args_system
|
389
|
-
# try using argparse
|
390
|
-
parser = SafeArgumentParser(add_help=False)
|
391
|
-
for num, arg in enumerate(sys.argv):
|
392
|
-
try:
|
393
|
-
next_arg = sys.argv[num + 1]
|
394
|
-
except IndexError:
|
395
|
-
next_arg = ""
|
396
|
-
if arg.startswith(("-", "--")) and not next_arg.startswith(("-", "--")):
|
397
|
-
try:
|
398
|
-
parser.add_argument(arg)
|
399
|
-
except ValueError:
|
400
|
-
pass
|
401
|
-
try:
|
402
|
-
parsed, unknown = parser.parse_known_args()
|
403
|
-
except ArgumentException:
|
404
|
-
pass
|
405
|
-
else:
|
406
|
-
_args_system = vars(parsed)
|
407
|
-
|
408
|
-
|
409
|
-
def _monkey_argparse():
|
410
|
-
argparse._ArgumentParser = argparse.ArgumentParser
|
411
|
-
|
412
|
-
def _install():
|
413
|
-
argparse.ArgumentParser = MonitoredArgumentParser
|
414
|
-
|
415
|
-
def _uninstall():
|
416
|
-
argparse.ArgumentParser = argparse._ArgumentParser
|
417
|
-
|
418
|
-
def monitored(self, args, unknown=None):
|
419
|
-
global _args_argparse
|
420
|
-
_args_argparse = copy.deepcopy(vars(args))
|
421
|
-
|
422
|
-
class MonitoredArgumentParser(argparse._ArgumentParser):
|
423
|
-
def __init__(self, *args, **kwargs):
|
424
|
-
_uninstall()
|
425
|
-
super().__init__(*args, **kwargs)
|
426
|
-
_install()
|
427
|
-
|
428
|
-
def parse_args(self, *args, **kwargs):
|
429
|
-
args = super().parse_args(*args, **kwargs)
|
430
|
-
return args
|
431
|
-
|
432
|
-
def parse_known_args(self, *args, **kwargs):
|
433
|
-
args, unknown = super().parse_known_args(*args, **kwargs)
|
434
|
-
if self._callback:
|
435
|
-
self._callback(args, unknown=unknown)
|
436
|
-
return args, unknown
|
437
|
-
|
438
|
-
_install()
|
439
|
-
argparse.ArgumentParser._callback = monitored
|
440
|
-
|
441
|
-
|
442
|
-
def _magic_update_config():
|
443
|
-
# if we already have config set, don't add anymore
|
444
|
-
if wandb.run and wandb.run.config:
|
445
|
-
c = wandb.run.config
|
446
|
-
user_config = dict(c.items())
|
447
|
-
# ignore keys set by magic integration when checking
|
448
|
-
# if user added any keys
|
449
|
-
if set(user_config).difference({"magic"}):
|
450
|
-
return
|
451
|
-
if _magic_get_config("args.absl", None) is False:
|
452
|
-
global _args_absl
|
453
|
-
_args_absl = None
|
454
|
-
if _magic_get_config("args.argparse", None) is False:
|
455
|
-
global _args_argparse
|
456
|
-
_args_argparse = None
|
457
|
-
if _magic_get_config("args.sys", None) is False:
|
458
|
-
global _args_system
|
459
|
-
_args_system = None
|
460
|
-
# prefer absl, then argparse values, fallback to parsed system args
|
461
|
-
args = _args_absl or _args_argparse or _args_system
|
462
|
-
if args and wandb.run and wandb.run.config:
|
463
|
-
wandb.run.config.update(args)
|
464
|
-
|
465
|
-
|
466
|
-
def _magic_init(**kwargs):
|
467
|
-
magic_arg = kwargs.get("magic", None)
|
468
|
-
if magic_arg is not None and magic_arg is not False:
|
469
|
-
global _magic_init_seen
|
470
|
-
if _magic_init_seen and magic_arg is not True:
|
471
|
-
wandb.termwarn(
|
472
|
-
"wandb.init() magic argument ignored because wandb magic has already been initialized",
|
473
|
-
repeat=False,
|
474
|
-
)
|
475
|
-
_magic_init_seen = True
|
476
|
-
else:
|
477
|
-
wandb.termwarn(
|
478
|
-
"wandb.init() arguments ignored because wandb magic has already been initialized",
|
479
|
-
repeat=False,
|
480
|
-
)
|
481
|
-
|
482
|
-
|
483
|
-
def magic_install(init_args=None):
|
484
|
-
if wandb.setup().settings._noop:
|
485
|
-
return
|
486
|
-
global _run_once
|
487
|
-
if _run_once:
|
488
|
-
return
|
489
|
-
_run_once = True
|
490
|
-
|
491
|
-
global _magic_config
|
492
|
-
global _import_hook
|
493
|
-
|
494
|
-
# parse config early, before we have wandb.config overrides
|
495
|
-
_magic_config, magic_set = _parse_magic(wandb.env.get_magic())
|
496
|
-
|
497
|
-
# we are implicitly enabling magic
|
498
|
-
if _magic_config.get("enable") is None:
|
499
|
-
_magic_config["enable"] = True
|
500
|
-
magic_set["enable"] = True
|
501
|
-
|
502
|
-
# allow early config to disable magic
|
503
|
-
if not _magic_config.get("enable"):
|
504
|
-
return
|
505
|
-
|
506
|
-
# process system args
|
507
|
-
_process_system_args()
|
508
|
-
# install argparse wrapper
|
509
|
-
if not ipython.in_notebook():
|
510
|
-
_monkey_argparse()
|
511
|
-
|
512
|
-
# track init calls
|
513
|
-
trigger.register("on_init", _magic_init)
|
514
|
-
|
515
|
-
# if wandb.init has already been called, this call is ignored
|
516
|
-
init_args = init_args or {}
|
517
|
-
init_args["magic"] = True
|
518
|
-
wandb.init(**init_args)
|
519
|
-
|
520
|
-
# parse magic from wandb.config (from flattened to dict)
|
521
|
-
magic_from_config = {}
|
522
|
-
MAGIC_KEY = "wandb_magic"
|
523
|
-
for k in wandb.config.keys():
|
524
|
-
if not k.startswith(MAGIC_KEY + "."):
|
525
|
-
continue
|
526
|
-
d = _dict_from_keyval(k, wandb.config[k], json_parse=False)
|
527
|
-
_merge_dicts(d, magic_from_config)
|
528
|
-
magic_from_config = magic_from_config.get(MAGIC_KEY, {})
|
529
|
-
_merge_dicts(magic_from_config, _magic_config)
|
530
|
-
|
531
|
-
# allow late config to disable magic
|
532
|
-
if not _magic_config.get("enable"):
|
533
|
-
return
|
534
|
-
|
535
|
-
# store magic_set into config
|
536
|
-
if magic_set:
|
537
|
-
wandb.config["magic"] = magic_set
|
538
|
-
wandb.config.persist()
|
539
|
-
|
540
|
-
# Monkey patch tf.keras
|
541
|
-
if get_optional_module("tensorflow"):
|
542
|
-
if "tensorflow.python.keras" in sys.modules or "keras" in sys.modules:
|
543
|
-
_monkey_tfkeras()
|
544
|
-
|
545
|
-
# Always setup import hooks looking for keras or tf.keras
|
546
|
-
add_import_hook(fullname="keras", on_import=_monkey_tfkeras)
|
547
|
-
add_import_hook(fullname="tensorflow.python.keras", on_import=_monkey_tfkeras)
|
548
|
-
|
549
|
-
if "absl.app" in sys.modules:
|
550
|
-
_monkey_absl()
|
551
|
-
else:
|
552
|
-
add_import_hook(fullname="absl.app", on_import=_monkey_absl)
|
553
|
-
|
554
|
-
# update wandb.config on fit or program finish
|
555
|
-
trigger.register("on_fit", _magic_update_config)
|
556
|
-
trigger.register("on_finished", _magic_update_config)
|
wandb/magic.py
DELETED