wandb 0.16.6__py3-none-any.whl → 0.17.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- package_readme.md +95 -0
- wandb/__init__.py +2 -3
- wandb/agents/pyagent.py +0 -1
- wandb/analytics/sentry.py +2 -1
- wandb/apis/importers/internals/internal.py +0 -1
- wandb/apis/importers/internals/protocols.py +30 -56
- wandb/apis/importers/mlflow.py +13 -26
- wandb/apis/importers/wandb.py +8 -14
- wandb/apis/internal.py +0 -3
- wandb/apis/public/api.py +55 -3
- wandb/apis/public/artifacts.py +1 -0
- wandb/apis/public/files.py +1 -0
- wandb/apis/public/history.py +1 -0
- wandb/apis/public/jobs.py +17 -4
- wandb/apis/public/projects.py +1 -0
- wandb/apis/public/reports.py +1 -0
- wandb/apis/public/runs.py +15 -17
- wandb/apis/public/sweeps.py +1 -0
- wandb/apis/public/teams.py +1 -0
- wandb/apis/public/users.py +1 -0
- wandb/apis/reports/v1/_blocks.py +3 -7
- wandb/apis/reports/v2/gql.py +1 -0
- wandb/apis/reports/v2/interface.py +3 -4
- wandb/apis/reports/v2/internal.py +5 -8
- wandb/cli/cli.py +92 -22
- wandb/data_types.py +9 -6
- wandb/docker/__init__.py +1 -1
- wandb/env.py +38 -8
- wandb/errors/__init__.py +5 -0
- wandb/errors/term.py +10 -2
- wandb/filesync/step_checksum.py +1 -4
- wandb/filesync/step_prepare.py +4 -24
- wandb/filesync/step_upload.py +4 -106
- wandb/filesync/upload_job.py +0 -76
- wandb/integration/catboost/catboost.py +1 -1
- wandb/integration/fastai/__init__.py +1 -0
- wandb/integration/huggingface/resolver.py +2 -2
- wandb/integration/keras/__init__.py +1 -0
- wandb/integration/keras/callbacks/metrics_logger.py +1 -1
- wandb/integration/keras/keras.py +7 -7
- wandb/integration/langchain/wandb_tracer.py +1 -0
- wandb/integration/lightning/fabric/logger.py +1 -3
- wandb/integration/metaflow/metaflow.py +41 -6
- wandb/integration/openai/fine_tuning.py +3 -3
- wandb/integration/prodigy/prodigy.py +1 -1
- wandb/old/summary.py +1 -1
- wandb/plot/confusion_matrix.py +1 -1
- wandb/plot/pr_curve.py +2 -1
- wandb/plot/roc_curve.py +2 -1
- wandb/{plots → plot}/utils.py +13 -25
- wandb/proto/v3/wandb_internal_pb2.py +364 -332
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v4/wandb_internal_pb2.py +322 -316
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
- wandb/proto/wandb_deprecated.py +7 -1
- wandb/proto/wandb_internal_codegen.py +3 -29
- wandb/sdk/artifacts/artifact.py +26 -11
- wandb/sdk/artifacts/artifact_download_logger.py +1 -0
- wandb/sdk/artifacts/artifact_file_cache.py +18 -4
- wandb/sdk/artifacts/artifact_instance_cache.py +1 -0
- wandb/sdk/artifacts/artifact_manifest.py +1 -0
- wandb/sdk/artifacts/artifact_manifest_entry.py +7 -3
- wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +1 -0
- wandb/sdk/artifacts/artifact_saver.py +2 -8
- wandb/sdk/artifacts/artifact_state.py +1 -0
- wandb/sdk/artifacts/artifact_ttl.py +1 -0
- wandb/sdk/artifacts/exceptions.py +1 -0
- wandb/sdk/artifacts/storage_handlers/azure_handler.py +1 -0
- wandb/sdk/artifacts/storage_handlers/gcs_handler.py +13 -18
- wandb/sdk/artifacts/storage_handlers/http_handler.py +1 -0
- wandb/sdk/artifacts/storage_handlers/local_file_handler.py +1 -0
- wandb/sdk/artifacts/storage_handlers/multi_handler.py +1 -0
- wandb/sdk/artifacts/storage_handlers/s3_handler.py +5 -3
- wandb/sdk/artifacts/storage_handlers/tracking_handler.py +1 -0
- wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +1 -0
- wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +1 -0
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +3 -42
- wandb/sdk/artifacts/storage_policy.py +2 -12
- wandb/sdk/data_types/_dtypes.py +8 -8
- wandb/sdk/data_types/base_types/media.py +3 -6
- wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +3 -1
- wandb/sdk/data_types/image.py +1 -1
- wandb/sdk/data_types/video.py +1 -1
- wandb/sdk/integration_utils/auto_logging.py +5 -6
- wandb/sdk/integration_utils/data_logging.py +10 -6
- wandb/sdk/interface/interface.py +68 -32
- wandb/sdk/interface/interface_shared.py +7 -13
- wandb/sdk/internal/datastore.py +1 -1
- wandb/sdk/internal/file_pusher.py +2 -5
- wandb/sdk/internal/file_stream.py +5 -18
- wandb/sdk/internal/handler.py +18 -2
- wandb/sdk/internal/internal.py +0 -1
- wandb/sdk/internal/internal_api.py +1 -129
- wandb/sdk/internal/internal_util.py +0 -1
- wandb/sdk/internal/job_builder.py +159 -45
- wandb/sdk/internal/profiler.py +1 -0
- wandb/sdk/internal/progress.py +0 -28
- wandb/sdk/internal/run.py +1 -0
- wandb/sdk/internal/sender.py +1 -2
- wandb/sdk/internal/system/assets/gpu_amd.py +44 -44
- wandb/sdk/internal/system/assets/gpu_apple.py +56 -11
- wandb/sdk/internal/system/assets/interfaces.py +6 -8
- wandb/sdk/internal/system/assets/open_metrics.py +2 -2
- wandb/sdk/internal/system/assets/trainium.py +1 -3
- wandb/sdk/launch/__init__.py +9 -1
- wandb/sdk/launch/_launch.py +4 -24
- wandb/sdk/launch/_launch_add.py +1 -3
- wandb/sdk/launch/_project_spec.py +186 -224
- wandb/sdk/launch/agent/agent.py +37 -13
- wandb/sdk/launch/agent/config.py +72 -14
- wandb/sdk/launch/builder/abstract.py +69 -1
- wandb/sdk/launch/builder/build.py +156 -555
- wandb/sdk/launch/builder/context_manager.py +235 -0
- wandb/sdk/launch/builder/docker_builder.py +8 -23
- wandb/sdk/launch/builder/kaniko_builder.py +12 -25
- wandb/sdk/launch/builder/noop.py +1 -0
- wandb/sdk/launch/builder/templates/dockerfile.py +92 -0
- wandb/sdk/launch/create_job.py +47 -37
- wandb/sdk/launch/environment/abstract.py +1 -0
- wandb/sdk/launch/environment/gcp_environment.py +1 -0
- wandb/sdk/launch/environment/local_environment.py +1 -0
- wandb/sdk/launch/inputs/files.py +148 -0
- wandb/sdk/launch/inputs/internal.py +217 -0
- wandb/sdk/launch/inputs/manage.py +95 -0
- wandb/sdk/launch/loader.py +1 -0
- wandb/sdk/launch/registry/abstract.py +1 -0
- wandb/sdk/launch/registry/azure_container_registry.py +1 -0
- wandb/sdk/launch/registry/elastic_container_registry.py +1 -0
- wandb/sdk/launch/registry/google_artifact_registry.py +2 -1
- wandb/sdk/launch/registry/local_registry.py +1 -0
- wandb/sdk/launch/runner/abstract.py +1 -0
- wandb/sdk/launch/runner/kubernetes_monitor.py +1 -0
- wandb/sdk/launch/runner/kubernetes_runner.py +9 -10
- wandb/sdk/launch/runner/local_container.py +2 -3
- wandb/sdk/launch/runner/local_process.py +8 -29
- wandb/sdk/launch/runner/sagemaker_runner.py +21 -20
- wandb/sdk/launch/runner/vertex_runner.py +8 -7
- wandb/sdk/launch/sweeps/scheduler.py +4 -3
- wandb/sdk/launch/sweeps/scheduler_sweep.py +2 -1
- wandb/sdk/launch/sweeps/utils.py +3 -3
- wandb/sdk/launch/utils.py +15 -140
- wandb/sdk/lib/_settings_toposort_generated.py +0 -5
- wandb/sdk/lib/fsm.py +8 -12
- wandb/sdk/lib/gitlib.py +4 -4
- wandb/sdk/lib/import_hooks.py +1 -1
- wandb/sdk/lib/lazyloader.py +0 -1
- wandb/sdk/lib/proto_util.py +23 -2
- wandb/sdk/lib/redirect.py +19 -14
- wandb/sdk/lib/retry.py +3 -2
- wandb/sdk/lib/tracelog.py +1 -1
- wandb/sdk/service/service.py +19 -16
- wandb/sdk/verify/verify.py +2 -1
- wandb/sdk/wandb_init.py +14 -55
- wandb/sdk/wandb_manager.py +2 -2
- wandb/sdk/wandb_require.py +5 -0
- wandb/sdk/wandb_run.py +114 -56
- wandb/sdk/wandb_settings.py +0 -48
- wandb/sdk/wandb_setup.py +1 -1
- wandb/sklearn/__init__.py +1 -0
- wandb/sklearn/plot/__init__.py +1 -0
- wandb/sklearn/plot/classifier.py +11 -12
- wandb/sklearn/plot/clusterer.py +2 -1
- wandb/sklearn/plot/regressor.py +1 -0
- wandb/sklearn/plot/shared.py +1 -0
- wandb/sklearn/utils.py +1 -0
- wandb/testing/relay.py +4 -4
- wandb/trigger.py +1 -0
- wandb/util.py +67 -54
- wandb/wandb_controller.py +2 -3
- wandb/wandb_torch.py +1 -2
- {wandb-0.16.6.dist-info → wandb-0.17.0.dist-info}/METADATA +67 -70
- {wandb-0.16.6.dist-info → wandb-0.17.0.dist-info}/RECORD +177 -187
- {wandb-0.16.6.dist-info → wandb-0.17.0.dist-info}/WHEEL +1 -2
- wandb/bin/apple_gpu_stats +0 -0
- wandb/catboost/__init__.py +0 -9
- wandb/fastai/__init__.py +0 -9
- wandb/keras/__init__.py +0 -18
- wandb/lightgbm/__init__.py +0 -9
- wandb/plots/__init__.py +0 -6
- wandb/plots/explain_text.py +0 -36
- wandb/plots/heatmap.py +0 -81
- wandb/plots/named_entity.py +0 -43
- wandb/plots/part_of_speech.py +0 -50
- wandb/plots/plot_definitions.py +0 -768
- wandb/plots/precision_recall.py +0 -121
- wandb/plots/roc.py +0 -103
- wandb/sacred/__init__.py +0 -3
- wandb/xgboost/__init__.py +0 -9
- wandb-0.16.6.dist-info/top_level.txt +0 -1
- {wandb-0.16.6.dist-info → wandb-0.17.0.dist-info}/entry_points.txt +0 -0
- {wandb-0.16.6.dist-info → wandb-0.17.0.dist-info/licenses}/LICENSE +0 -0
wandb/sdk/lib/redirect.py
CHANGED
@@ -224,7 +224,7 @@ class TerminalEmulator:
|
|
224
224
|
def carriage_return(self):
|
225
225
|
self.cursor.x = 0
|
226
226
|
|
227
|
-
def
|
227
|
+
def cursor_position(self, line, column):
|
228
228
|
self.cursor.x = min(column, 1) - 1
|
229
229
|
self.cursor.y = min(line, 1) - 1
|
230
230
|
|
@@ -393,25 +393,30 @@ class TerminalEmulator:
|
|
393
393
|
p = (int(p[0]), 1)
|
394
394
|
else:
|
395
395
|
p = (1, 1)
|
396
|
-
self.
|
396
|
+
self.cursor_position(*p)
|
397
397
|
except Exception:
|
398
398
|
pass
|
399
399
|
|
400
400
|
def _get_line(self, n):
|
401
401
|
line = self.buffer[n]
|
402
402
|
line_len = self._get_line_len(n)
|
403
|
-
# We have to loop through each character in the line and check if foreground,
|
404
|
-
# other attributes (italics, bold, underline, etc) of the ith
|
405
|
-
# (i-1)th character. If different, the
|
406
|
-
#
|
407
|
-
#
|
408
|
-
#
|
409
|
-
|
410
|
-
#
|
411
|
-
#
|
412
|
-
|
413
|
-
#
|
414
|
-
#
|
403
|
+
# We have to loop through each character in the line and check if foreground,
|
404
|
+
# background and other attributes (italics, bold, underline, etc) of the ith
|
405
|
+
# character are different from those of the (i-1)th character. If different, the
|
406
|
+
# appropriate ascii character for switching the color/attribute should be
|
407
|
+
# appended to the output string before appending the actual character. This loop
|
408
|
+
# and subsequent checks can be expensive, especially because 99% of terminal
|
409
|
+
# output use default colors and formatting. Even in outputs that do contain
|
410
|
+
# colors and styles, its unlikely that they will change on a per character
|
411
|
+
# basis.
|
412
|
+
|
413
|
+
# So instead we create a character list without any ascii codes (`out`), and a
|
414
|
+
# list of all the foregrounds in the line (`fgs`) on which we call np.diff() and
|
415
|
+
# np.where() to find the indices where the foreground change, and insert the
|
416
|
+
# ascii characters in the output list (`out`) on those indices. All of this is
|
417
|
+
# the done only if there are more than 1 foreground color in the line in the
|
418
|
+
# first place (`if len(set(fgs)) > 1 else None`). Same logic is repeated for
|
419
|
+
# background colors and other attributes.
|
415
420
|
|
416
421
|
out = [line[i].data for i in range(line_len)]
|
417
422
|
|
wandb/sdk/lib/retry.py
CHANGED
@@ -248,8 +248,9 @@ class ExponentialBackoff(Backoff):
|
|
248
248
|
if self._timeout_at is not None and NOW_FN() > self._timeout_at:
|
249
249
|
raise exc
|
250
250
|
|
251
|
-
result, self._next_sleep =
|
252
|
-
self.
|
251
|
+
result, self._next_sleep = (
|
252
|
+
self._next_sleep,
|
253
|
+
min(self._max_sleep, self._next_sleep * (1 + random.random())),
|
253
254
|
)
|
254
255
|
|
255
256
|
return result
|
wandb/sdk/lib/tracelog.py
CHANGED
@@ -6,7 +6,7 @@ Functions:
|
|
6
6
|
log_message_send - message sent to socket
|
7
7
|
log_message_recv - message received from socket
|
8
8
|
log_message_process - message processed by thread
|
9
|
-
log_message_link - message linked to another
|
9
|
+
log_message_link - message linked to another message
|
10
10
|
log_message_assert - message encountered problem
|
11
11
|
|
12
12
|
"""
|
wandb/sdk/service/service.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
Backend server process can be connected to using tcp sockets transport.
|
4
4
|
"""
|
5
|
+
|
5
6
|
import datetime
|
6
7
|
import os
|
7
8
|
import pathlib
|
@@ -14,8 +15,8 @@ import time
|
|
14
15
|
from typing import TYPE_CHECKING, Any, Dict, Optional
|
15
16
|
|
16
17
|
from wandb import _sentry, termlog
|
17
|
-
from wandb.env import
|
18
|
-
from wandb.errors import Error
|
18
|
+
from wandb.env import core_debug, core_error_reporting_enabled, is_require_core
|
19
|
+
from wandb.errors import Error, WandbCoreNotAvailableError
|
19
20
|
from wandb.sdk.lib.wburls import wburls
|
20
21
|
from wandb.util import get_core_path, get_module
|
21
22
|
|
@@ -109,7 +110,8 @@ class _Service:
|
|
109
110
|
f"The wandb service process exited with {proc.returncode}. "
|
110
111
|
"Ensure that `sys.executable` is a valid python interpreter. "
|
111
112
|
"You can override it with the `_executable` setting "
|
112
|
-
"or with the `WANDB__EXECUTABLE` environment variable."
|
113
|
+
"or with the `WANDB__EXECUTABLE` environment variable."
|
114
|
+
f"\n{context}",
|
113
115
|
context=context,
|
114
116
|
)
|
115
117
|
if not os.path.isfile(fname):
|
@@ -161,28 +163,29 @@ class _Service:
|
|
161
163
|
exec_cmd_list += ["coverage", "run", "-m"]
|
162
164
|
|
163
165
|
service_args = []
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
166
|
+
|
167
|
+
if is_require_core():
|
168
|
+
try:
|
169
|
+
core_path = get_core_path()
|
170
|
+
except WandbCoreNotAvailableError as e:
|
171
|
+
_sentry.reraise(e)
|
172
|
+
|
171
173
|
service_args.extend([core_path])
|
172
|
-
|
174
|
+
|
175
|
+
if not core_error_reporting_enabled(default="True"):
|
173
176
|
service_args.append("--no-observability")
|
174
|
-
|
177
|
+
|
178
|
+
if core_debug(default="False"):
|
175
179
|
service_args.append("--debug")
|
180
|
+
|
176
181
|
trace_filename = os.environ.get("_WANDB_TRACE")
|
177
182
|
if trace_filename is not None:
|
178
183
|
service_args.extend(["--trace", trace_filename])
|
179
184
|
|
180
185
|
exec_cmd_list = []
|
181
|
-
# TODO: remove this after the wandb-core GA release
|
182
|
-
wandb_core = get_module("wandb_core")
|
183
186
|
termlog(
|
184
|
-
|
185
|
-
f"Please refer to {wburls.get('wandb_core')} for more information.",
|
187
|
+
"Using wandb-core as the SDK backend."
|
188
|
+
f" Please refer to {wburls.get('wandb_core')} for more information.",
|
186
189
|
repeat=False,
|
187
190
|
)
|
188
191
|
else:
|
wandb/sdk/verify/verify.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""Utilities for wandb verify."""
|
2
|
+
|
2
3
|
import getpass
|
3
4
|
import os
|
4
5
|
import time
|
@@ -20,7 +21,7 @@ PROJECT_NAME = "verify"
|
|
20
21
|
GET_RUN_MAX_TIME = 10
|
21
22
|
MIN_RETRYS = 3
|
22
23
|
CHECKMARK = "\u2705"
|
23
|
-
RED_X = "\
|
24
|
+
RED_X = "\u274c"
|
24
25
|
ID_PREFIX = runid.generate_id()
|
25
26
|
|
26
27
|
|
wandb/sdk/wandb_init.py
CHANGED
@@ -15,7 +15,6 @@ import os
|
|
15
15
|
import platform
|
16
16
|
import sys
|
17
17
|
import tempfile
|
18
|
-
import traceback
|
19
18
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union
|
20
19
|
|
21
20
|
import wandb
|
@@ -555,7 +554,7 @@ class _WandbInit:
|
|
555
554
|
percent_done = handle.percent_done
|
556
555
|
self.printer.progress_update(line, percent_done=percent_done)
|
557
556
|
|
558
|
-
def init(self) -> Union[Run, RunDisabled
|
557
|
+
def init(self) -> Union[Run, RunDisabled]: # noqa: C901
|
559
558
|
if logger is None:
|
560
559
|
raise RuntimeError("Logger not initialized")
|
561
560
|
logger.info("calling init triggers")
|
@@ -654,9 +653,6 @@ class _WandbInit:
|
|
654
653
|
if self.settings.launch:
|
655
654
|
tel.feature.launch = True
|
656
655
|
|
657
|
-
if self.settings._async_upload_concurrency_limit:
|
658
|
-
tel.feature.async_uploads = True
|
659
|
-
|
660
656
|
for module_name in telemetry.list_telemetry_imports(only_imported=True):
|
661
657
|
setattr(tel.imports_init, module_name, True)
|
662
658
|
|
@@ -843,13 +839,6 @@ class _WandbInit:
|
|
843
839
|
return run
|
844
840
|
|
845
841
|
|
846
|
-
def getcaller() -> None:
|
847
|
-
if not logger:
|
848
|
-
return None
|
849
|
-
src, line, func, stack = logger.findCaller(stack_info=True)
|
850
|
-
print("Problem at:", src, line, func)
|
851
|
-
|
852
|
-
|
853
842
|
def _attach(
|
854
843
|
attach_id: Optional[str] = None,
|
855
844
|
run_id: Optional[str] = None,
|
@@ -958,7 +947,7 @@ def init(
|
|
958
947
|
id: Optional[str] = None,
|
959
948
|
fork_from: Optional[str] = None,
|
960
949
|
settings: Union[Settings, Dict[str, Any], None] = None,
|
961
|
-
) -> Union[Run, RunDisabled
|
950
|
+
) -> Union[Run, RunDisabled]:
|
962
951
|
r"""Start a new run to track and log to W&B.
|
963
952
|
|
964
953
|
In an ML training pipeline, you could add `wandb.init()`
|
@@ -1164,9 +1153,6 @@ def init(
|
|
1164
1153
|
wandb._assert_is_user_process()
|
1165
1154
|
|
1166
1155
|
kwargs = dict(locals())
|
1167
|
-
error_seen = None
|
1168
|
-
except_exit = None
|
1169
|
-
run: Optional[Union[Run, RunDisabled]] = None
|
1170
1156
|
|
1171
1157
|
# convert fork_from into a version that can be passed to settings
|
1172
1158
|
if fork_from is not None and resume is not None:
|
@@ -1175,46 +1161,19 @@ def init(
|
|
1175
1161
|
try:
|
1176
1162
|
wi = _WandbInit()
|
1177
1163
|
wi.setup(kwargs)
|
1178
|
-
|
1179
|
-
|
1180
|
-
try:
|
1181
|
-
run = wi.init()
|
1182
|
-
except_exit = wi.settings._except_exit
|
1183
|
-
except (KeyboardInterrupt, Exception) as e:
|
1184
|
-
if not isinstance(e, KeyboardInterrupt):
|
1185
|
-
wandb._sentry.exception(e)
|
1186
|
-
if not (
|
1187
|
-
wandb.wandb_agent._is_running() and isinstance(e, KeyboardInterrupt)
|
1188
|
-
):
|
1189
|
-
getcaller()
|
1190
|
-
assert logger
|
1191
|
-
if wi.settings.problem == "fatal":
|
1192
|
-
raise
|
1193
|
-
if wi.settings.problem == "warn":
|
1194
|
-
pass
|
1195
|
-
# TODO(jhr): figure out how to make this RunDummy
|
1196
|
-
run = None
|
1197
|
-
except Error as e:
|
1198
|
-
if logger is not None:
|
1199
|
-
logger.exception(str(e))
|
1200
|
-
raise e
|
1164
|
+
return wi.init()
|
1165
|
+
|
1201
1166
|
except KeyboardInterrupt as e:
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1167
|
+
if logger is not None:
|
1168
|
+
logger.warning("interrupted", exc_info=e)
|
1169
|
+
|
1170
|
+
raise
|
1171
|
+
|
1205
1172
|
except Exception as e:
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
logger.error("error", exc_info=e)
|
1173
|
+
if logger is not None:
|
1174
|
+
logger.exception("error in wandb.init()", exc_info=e)
|
1175
|
+
|
1210
1176
|
# Need to build delay into this sentry capture because our exit hooks
|
1211
1177
|
# mess with sentry's ability to send out errors before the program ends.
|
1212
|
-
wandb._sentry.
|
1213
|
-
|
1214
|
-
finally:
|
1215
|
-
if error_seen:
|
1216
|
-
if except_exit:
|
1217
|
-
wandb.termerror("Abnormal program exit")
|
1218
|
-
os._exit(1)
|
1219
|
-
raise Error("An unexpected error occurred") from error_seen
|
1220
|
-
return run
|
1178
|
+
wandb._sentry.reraise(e)
|
1179
|
+
raise AssertionError() # unreachable
|
wandb/sdk/wandb_manager.py
CHANGED
@@ -5,7 +5,7 @@ Create a manager channel.
|
|
5
5
|
|
6
6
|
import atexit
|
7
7
|
import os
|
8
|
-
from typing import TYPE_CHECKING,
|
8
|
+
from typing import TYPE_CHECKING, Callable, Optional
|
9
9
|
|
10
10
|
import psutil
|
11
11
|
|
@@ -205,7 +205,7 @@ class _Manager:
|
|
205
205
|
svc_iface = self._get_service_interface()
|
206
206
|
svc_iface._svc_inform_start(settings=settings, run_id=run_id)
|
207
207
|
|
208
|
-
def _inform_attach(self, attach_id: str) -> Optional[
|
208
|
+
def _inform_attach(self, attach_id: str) -> Optional["wandb_settings_pb2.Settings"]:
|
209
209
|
svc_iface = self._get_service_interface()
|
210
210
|
try:
|
211
211
|
response = svc_iface._svc_inform_attach(attach_id=attach_id)
|
wandb/sdk/wandb_require.py
CHANGED
@@ -9,9 +9,11 @@ Example:
|
|
9
9
|
wandb.require("incremental-artifacts@beta")
|
10
10
|
"""
|
11
11
|
|
12
|
+
import os
|
12
13
|
from typing import Optional, Sequence, Union
|
13
14
|
|
14
15
|
import wandb
|
16
|
+
from wandb.env import _REQUIRE_CORE
|
15
17
|
from wandb.errors import UnsupportedError
|
16
18
|
from wandb.sdk import wandb_run
|
17
19
|
from wandb.sdk.lib.wburls import wburls
|
@@ -38,6 +40,9 @@ class _Requires:
|
|
38
40
|
def require_service(self) -> None:
|
39
41
|
self._require_service()
|
40
42
|
|
43
|
+
def require_core(self) -> None:
|
44
|
+
os.environ[_REQUIRE_CORE] = "true"
|
45
|
+
|
41
46
|
def apply(self) -> None:
|
42
47
|
"""Call require_* method for supported features."""
|
43
48
|
last_message: str = ""
|
wandb/sdk/wandb_run.py
CHANGED
@@ -207,6 +207,15 @@ class RunStatusChecker:
|
|
207
207
|
self._network_status_thread.start()
|
208
208
|
self._internal_messages_thread.start()
|
209
209
|
|
210
|
+
@staticmethod
|
211
|
+
def _abandon_status_check(
|
212
|
+
lock: threading.Lock,
|
213
|
+
handle: Optional[MailboxHandle],
|
214
|
+
):
|
215
|
+
with lock:
|
216
|
+
if handle:
|
217
|
+
handle.abandon()
|
218
|
+
|
210
219
|
def _loop_check_status(
|
211
220
|
self,
|
212
221
|
*,
|
@@ -265,13 +274,19 @@ class RunStatusChecker:
|
|
265
274
|
)
|
266
275
|
)
|
267
276
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
277
|
+
try:
|
278
|
+
self._loop_check_status(
|
279
|
+
lock=self._network_status_lock,
|
280
|
+
set_handle=lambda x: setattr(self, "_network_status_handle", x),
|
281
|
+
timeout=self._retry_polling_interval,
|
282
|
+
request=self._interface.deliver_network_status,
|
283
|
+
process=_process_network_status,
|
284
|
+
)
|
285
|
+
except BrokenPipeError:
|
286
|
+
self._abandon_status_check(
|
287
|
+
self._network_status_lock,
|
288
|
+
self._network_status_handle,
|
289
|
+
)
|
275
290
|
|
276
291
|
def check_stop_status(self) -> None:
|
277
292
|
def _process_stop_status(result: Result) -> None:
|
@@ -283,13 +298,19 @@ class RunStatusChecker:
|
|
283
298
|
thread.interrupt_main()
|
284
299
|
return
|
285
300
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
301
|
+
try:
|
302
|
+
self._loop_check_status(
|
303
|
+
lock=self._stop_status_lock,
|
304
|
+
set_handle=lambda x: setattr(self, "_stop_status_handle", x),
|
305
|
+
timeout=self._stop_polling_interval,
|
306
|
+
request=self._interface.deliver_stop_status,
|
307
|
+
process=_process_stop_status,
|
308
|
+
)
|
309
|
+
except BrokenPipeError:
|
310
|
+
self._abandon_status_check(
|
311
|
+
self._stop_status_lock,
|
312
|
+
self._stop_status_handle,
|
313
|
+
)
|
293
314
|
|
294
315
|
def check_internal_messages(self) -> None:
|
295
316
|
def _process_internal_messages(result: Result) -> None:
|
@@ -297,25 +318,34 @@ class RunStatusChecker:
|
|
297
318
|
for msg in internal_messages.messages.warning:
|
298
319
|
wandb.termwarn(msg)
|
299
320
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
321
|
+
try:
|
322
|
+
self._loop_check_status(
|
323
|
+
lock=self._internal_messages_lock,
|
324
|
+
set_handle=lambda x: setattr(self, "_internal_messages_handle", x),
|
325
|
+
timeout=1,
|
326
|
+
request=self._interface.deliver_internal_messages,
|
327
|
+
process=_process_internal_messages,
|
328
|
+
)
|
329
|
+
except BrokenPipeError:
|
330
|
+
self._abandon_status_check(
|
331
|
+
self._internal_messages_lock,
|
332
|
+
self._internal_messages_handle,
|
333
|
+
)
|
307
334
|
|
308
335
|
def stop(self) -> None:
|
309
336
|
self._join_event.set()
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
337
|
+
self._abandon_status_check(
|
338
|
+
self._stop_status_lock,
|
339
|
+
self._stop_status_handle,
|
340
|
+
)
|
341
|
+
self._abandon_status_check(
|
342
|
+
self._network_status_lock,
|
343
|
+
self._network_status_handle,
|
344
|
+
)
|
345
|
+
self._abandon_status_check(
|
346
|
+
self._internal_messages_lock,
|
347
|
+
self._internal_messages_handle,
|
348
|
+
)
|
319
349
|
|
320
350
|
def join(self) -> None:
|
321
351
|
self.stop()
|
@@ -327,8 +357,7 @@ class RunStatusChecker:
|
|
327
357
|
class _run_decorator: # noqa: N801
|
328
358
|
_is_attaching: str = ""
|
329
359
|
|
330
|
-
class Dummy:
|
331
|
-
...
|
360
|
+
class Dummy: ...
|
332
361
|
|
333
362
|
@classmethod
|
334
363
|
def _attach(cls, func: Callable) -> Callable:
|
@@ -1401,6 +1430,10 @@ class Run:
|
|
1401
1430
|
# self._printer.display(line)
|
1402
1431
|
|
1403
1432
|
def _summary_get_current_summary_callback(self) -> Dict[str, Any]:
|
1433
|
+
if self._is_finished:
|
1434
|
+
# TODO: WB-18420: fetch summary from backend and stage it before run is finished
|
1435
|
+
wandb.termwarn("Summary data not available in finished run")
|
1436
|
+
return {}
|
1404
1437
|
if not self._backend or not self._backend.interface:
|
1405
1438
|
return {}
|
1406
1439
|
handle = self._backend.interface.deliver_get_summary()
|
@@ -1793,7 +1826,7 @@ class Run:
|
|
1793
1826
|
import wandb
|
1794
1827
|
|
1795
1828
|
run = wandb.init()
|
1796
|
-
run.log({"pr": wandb.
|
1829
|
+
run.log({"pr": wandb.plot.pr_curve(y_test, y_probas, labels)})
|
1797
1830
|
```
|
1798
1831
|
|
1799
1832
|
### 3D Object
|
@@ -1854,7 +1887,7 @@ class Run:
|
|
1854
1887
|
picked up automatically.
|
1855
1888
|
|
1856
1889
|
A `base_path` may be provided to control the directory structure of
|
1857
|
-
uploaded files. It should be a prefix of `glob_str`, and the
|
1890
|
+
uploaded files. It should be a prefix of `glob_str`, and the directory
|
1858
1891
|
structure beneath it is preserved. It's best understood through
|
1859
1892
|
examples:
|
1860
1893
|
|
@@ -1866,16 +1899,19 @@ class Run:
|
|
1866
1899
|
# => Saves files in an "are/myfiles/" folder in the run.
|
1867
1900
|
|
1868
1901
|
wandb.save("/User/username/Documents/run123/*.txt")
|
1869
|
-
# => Saves files in a "run123/" folder in the run.
|
1902
|
+
# => Saves files in a "run123/" folder in the run. See note below.
|
1870
1903
|
|
1871
1904
|
wandb.save("/User/username/Documents/run123/*.txt", base_path="/User")
|
1872
1905
|
# => Saves files in a "username/Documents/run123/" folder in the run.
|
1873
1906
|
|
1874
1907
|
wandb.save("files/*/saveme.txt")
|
1875
1908
|
# => Saves each "saveme.txt" file in an appropriate subdirectory
|
1876
|
-
#
|
1909
|
+
# of "files/".
|
1877
1910
|
```
|
1878
1911
|
|
1912
|
+
Note: when given an absolute path or glob and no `base_path`, one
|
1913
|
+
directory level is preserved as in the example above.
|
1914
|
+
|
1879
1915
|
Arguments:
|
1880
1916
|
glob_str: A relative or absolute path or Unix glob.
|
1881
1917
|
base_path: A path to use to infer a directory structure; see examples.
|
@@ -1909,7 +1945,11 @@ class Run:
|
|
1909
1945
|
# Provide a better error message for a common misuse.
|
1910
1946
|
wandb.termlog(f"{glob_str} is a cloud storage url, can't save file to W&B.")
|
1911
1947
|
return []
|
1912
|
-
|
1948
|
+
# NOTE: We use PurePath instead of Path because WindowsPath doesn't
|
1949
|
+
# like asterisks and errors out in resolve(). It also makes logical
|
1950
|
+
# sense: globs aren't real paths, they're just path-like strings.
|
1951
|
+
glob_path = pathlib.PurePath(glob_str)
|
1952
|
+
resolved_glob_path = pathlib.PurePath(os.path.abspath(glob_path))
|
1913
1953
|
|
1914
1954
|
if base_path is not None:
|
1915
1955
|
base_path = pathlib.Path(base_path)
|
@@ -1923,15 +1963,14 @@ class Run:
|
|
1923
1963
|
'wandb.save("/mnt/folder/file.h5", base_path="/mnt")',
|
1924
1964
|
repeat=False,
|
1925
1965
|
)
|
1926
|
-
base_path =
|
1966
|
+
base_path = resolved_glob_path.parent.parent
|
1927
1967
|
|
1928
1968
|
if policy not in ("live", "end", "now"):
|
1929
1969
|
raise ValueError(
|
1930
1970
|
'Only "live", "end" and "now" policies are currently supported.'
|
1931
1971
|
)
|
1932
1972
|
|
1933
|
-
|
1934
|
-
resolved_base_path = base_path.resolve()
|
1973
|
+
resolved_base_path = pathlib.PurePath(os.path.abspath(base_path))
|
1935
1974
|
|
1936
1975
|
return self._save(
|
1937
1976
|
resolved_glob_path,
|
@@ -1941,8 +1980,8 @@ class Run:
|
|
1941
1980
|
|
1942
1981
|
def _save(
|
1943
1982
|
self,
|
1944
|
-
glob_path: pathlib.
|
1945
|
-
base_path: pathlib.
|
1983
|
+
glob_path: pathlib.PurePath,
|
1984
|
+
base_path: pathlib.PurePath,
|
1946
1985
|
policy: "PolicyName",
|
1947
1986
|
) -> List[str]:
|
1948
1987
|
# Can't use is_relative_to() because that's added in Python 3.9,
|
@@ -2438,6 +2477,8 @@ class Run:
|
|
2438
2477
|
self._telemetry_obj_active = True
|
2439
2478
|
self._telemetry_flush()
|
2440
2479
|
|
2480
|
+
self._detect_and_apply_job_inputs()
|
2481
|
+
|
2441
2482
|
# object is about to be returned to the user, don't let them modify it
|
2442
2483
|
self._freeze()
|
2443
2484
|
|
@@ -2445,6 +2486,12 @@ class Run:
|
|
2445
2486
|
if os.path.exists(self._settings.resume_fname):
|
2446
2487
|
os.remove(self._settings.resume_fname)
|
2447
2488
|
|
2489
|
+
def _detect_and_apply_job_inputs(self) -> None:
|
2490
|
+
"""If the user has staged launch inputs, apply them to the run."""
|
2491
|
+
from wandb.sdk.launch.inputs.internal import StagedLaunchInputs
|
2492
|
+
|
2493
|
+
StagedLaunchInputs().apply(self)
|
2494
|
+
|
2448
2495
|
def _make_job_source_reqs(self) -> Tuple[List[str], Dict[str, Any], Dict[str, Any]]:
|
2449
2496
|
from wandb.util import working_set
|
2450
2497
|
|
@@ -2703,12 +2750,23 @@ class Run:
|
|
2703
2750
|
if i not in valid:
|
2704
2751
|
raise wandb.Error(f"Unhandled define_metric() arg: summary op: {i}")
|
2705
2752
|
summary_ops.append(i)
|
2753
|
+
with telemetry.context(run=self) as tel:
|
2754
|
+
tel.feature.metric_summary = True
|
2706
2755
|
goal_cleaned: Optional[str] = None
|
2707
2756
|
if goal is not None:
|
2708
2757
|
goal_cleaned = goal[:3].lower()
|
2709
2758
|
valid_goal = {"min", "max"}
|
2710
2759
|
if goal_cleaned not in valid_goal:
|
2711
2760
|
raise wandb.Error(f"Unhandled define_metric() arg: goal: {goal}")
|
2761
|
+
with telemetry.context(run=self) as tel:
|
2762
|
+
tel.feature.metric_goal = True
|
2763
|
+
if hidden:
|
2764
|
+
with telemetry.context(run=self) as tel:
|
2765
|
+
tel.feature.metric_hidden = True
|
2766
|
+
if step_sync:
|
2767
|
+
with telemetry.context(run=self) as tel:
|
2768
|
+
tel.feature.metric_step_sync = True
|
2769
|
+
|
2712
2770
|
m = wandb_metric.Metric(
|
2713
2771
|
name=name,
|
2714
2772
|
step_metric=step_metric,
|
@@ -3171,13 +3229,13 @@ class Run:
|
|
3171
3229
|
)
|
3172
3230
|
if entity and artifact._source_entity and entity != artifact._source_entity:
|
3173
3231
|
raise ValueError(
|
3174
|
-
f"Artifact {artifact.name} is owned by entity
|
3175
|
-
f"moved to '{
|
3232
|
+
f"Artifact {artifact.name} is owned by entity "
|
3233
|
+
f"'{artifact._source_entity}'; it can't be moved to '{entity}'"
|
3176
3234
|
)
|
3177
3235
|
if project and artifact._source_project and project != artifact._source_project:
|
3178
3236
|
raise ValueError(
|
3179
|
-
f"Artifact {artifact.name} exists in project
|
3180
|
-
f"moved to '{
|
3237
|
+
f"Artifact {artifact.name} exists in project "
|
3238
|
+
f"'{artifact._source_project}'; it can't be moved to '{project}'"
|
3181
3239
|
)
|
3182
3240
|
|
3183
3241
|
def _prepare_artifact(
|
@@ -3304,8 +3362,8 @@ class Run:
|
|
3304
3362
|
path: (str) path to downloaded model artifact file(s).
|
3305
3363
|
"""
|
3306
3364
|
artifact = self.use_artifact(artifact_or_name=name)
|
3307
|
-
assert
|
3308
|
-
artifact.type.lower()
|
3365
|
+
assert (
|
3366
|
+
"model" in str(artifact.type.lower())
|
3309
3367
|
), "You can only use this method for 'model' artifacts. For an artifact to be a 'model' artifact, its type property must contain the substring 'model'."
|
3310
3368
|
path = artifact.download()
|
3311
3369
|
|
@@ -3397,8 +3455,8 @@ class Run:
|
|
3397
3455
|
public_api = self._public_api()
|
3398
3456
|
try:
|
3399
3457
|
artifact = public_api.artifact(name=f"{name}:latest")
|
3400
|
-
assert
|
3401
|
-
artifact.type.lower()
|
3458
|
+
assert (
|
3459
|
+
"model" in str(artifact.type.lower())
|
3402
3460
|
), "You can only use this method for 'model' artifacts. For an artifact to be a 'model' artifact, its type property must contain the substring 'model'."
|
3403
3461
|
artifact = self._log_artifact(
|
3404
3462
|
artifact_or_path=path, name=name, type=artifact.type
|
@@ -3656,7 +3714,7 @@ class Run:
|
|
3656
3714
|
# FOOTER
|
3657
3715
|
# ------------------------------------------------------------------------------
|
3658
3716
|
# Note: All the footer methods are static methods since we want to share the printing logic
|
3659
|
-
# with the service execution path that doesn't have
|
3717
|
+
# with the service execution path that doesn't have access to the run instance
|
3660
3718
|
@staticmethod
|
3661
3719
|
def _footer(
|
3662
3720
|
sampled_history: Optional["SampledHistoryResponse"] = None,
|
@@ -3959,11 +4017,11 @@ class Run:
|
|
3959
4017
|
|
3960
4018
|
# Render summary if available
|
3961
4019
|
if summary:
|
3962
|
-
final_summary = {
|
3963
|
-
|
3964
|
-
|
3965
|
-
|
3966
|
-
|
4020
|
+
final_summary = {}
|
4021
|
+
for item in summary.item:
|
4022
|
+
if item.key.startswith("_") or len(item.nested_key) > 0:
|
4023
|
+
continue
|
4024
|
+
final_summary[item.key] = json.loads(item.value_json)
|
3967
4025
|
|
3968
4026
|
logger.info("rendering summary")
|
3969
4027
|
summary_rows = []
|