wandb 0.17.0rc2__py3-none-win_amd64.whl → 0.17.1__py3-none-win_amd64.whl
Sign up to get free protection for your applications and to get access to all the features.
- wandb/__init__.py +1 -2
- wandb/apis/importers/internals/internal.py +0 -1
- wandb/apis/importers/wandb.py +12 -7
- wandb/apis/internal.py +0 -3
- wandb/apis/public/api.py +213 -79
- wandb/apis/public/artifacts.py +335 -100
- wandb/apis/public/files.py +9 -9
- wandb/apis/public/jobs.py +16 -4
- wandb/apis/public/projects.py +26 -28
- wandb/apis/public/query_generator.py +1 -1
- wandb/apis/public/runs.py +163 -65
- wandb/apis/public/sweeps.py +2 -2
- wandb/apis/reports/__init__.py +1 -7
- wandb/apis/reports/v1/__init__.py +5 -27
- wandb/apis/reports/v2/__init__.py +7 -19
- wandb/apis/workspaces/__init__.py +8 -0
- wandb/beta/workflows.py +8 -3
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +131 -59
- wandb/docker/__init__.py +1 -1
- 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 +5 -107
- wandb/filesync/upload_job.py +0 -76
- wandb/integration/gym/__init__.py +35 -15
- wandb/integration/openai/fine_tuning.py +21 -3
- wandb/integration/prodigy/prodigy.py +1 -1
- wandb/jupyter.py +16 -17
- 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 +54 -54
- 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 +54 -54
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v5/wandb_base_pb2.py +30 -0
- wandb/proto/v5/wandb_internal_pb2.py +355 -0
- wandb/proto/v5/wandb_server_pb2.py +63 -0
- wandb/proto/v5/wandb_settings_pb2.py +45 -0
- wandb/proto/v5/wandb_telemetry_pb2.py +41 -0
- wandb/proto/wandb_base_pb2.py +2 -0
- wandb/proto/wandb_deprecated.py +9 -1
- wandb/proto/wandb_generate_deprecated.py +34 -0
- wandb/proto/{wandb_internal_codegen.py → wandb_generate_proto.py} +1 -35
- wandb/proto/wandb_internal_pb2.py +2 -0
- wandb/proto/wandb_server_pb2.py +2 -0
- wandb/proto/wandb_settings_pb2.py +2 -0
- wandb/proto/wandb_telemetry_pb2.py +2 -0
- wandb/sdk/artifacts/artifact.py +68 -22
- wandb/sdk/artifacts/artifact_manifest.py +1 -1
- wandb/sdk/artifacts/artifact_manifest_entry.py +6 -3
- wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +1 -1
- wandb/sdk/artifacts/artifact_saver.py +1 -10
- wandb/sdk/artifacts/storage_handlers/local_file_handler.py +6 -2
- wandb/sdk/artifacts/storage_handlers/multi_handler.py +1 -1
- wandb/sdk/artifacts/storage_handlers/tracking_handler.py +6 -4
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +2 -42
- wandb/sdk/artifacts/storage_policy.py +1 -12
- wandb/sdk/data_types/image.py +1 -1
- wandb/sdk/data_types/video.py +4 -2
- wandb/sdk/interface/interface.py +13 -0
- wandb/sdk/interface/interface_shared.py +1 -1
- wandb/sdk/internal/file_pusher.py +2 -5
- wandb/sdk/internal/file_stream.py +6 -19
- wandb/sdk/internal/internal_api.py +148 -136
- wandb/sdk/internal/job_builder.py +207 -135
- wandb/sdk/internal/progress.py +0 -28
- wandb/sdk/internal/sender.py +102 -39
- wandb/sdk/internal/settings_static.py +8 -1
- wandb/sdk/internal/system/assets/trainium.py +3 -3
- wandb/sdk/internal/system/system_info.py +4 -2
- wandb/sdk/internal/update.py +1 -1
- 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 +184 -224
- wandb/sdk/launch/agent/agent.py +58 -18
- wandb/sdk/launch/agent/config.py +0 -3
- wandb/sdk/launch/builder/abstract.py +67 -0
- wandb/sdk/launch/builder/build.py +165 -576
- wandb/sdk/launch/builder/context_manager.py +235 -0
- wandb/sdk/launch/builder/docker_builder.py +7 -23
- wandb/sdk/launch/builder/kaniko_builder.py +10 -23
- wandb/sdk/launch/builder/templates/dockerfile.py +92 -0
- wandb/sdk/launch/create_job.py +51 -45
- wandb/sdk/launch/environment/aws_environment.py +26 -1
- wandb/sdk/launch/inputs/files.py +148 -0
- wandb/sdk/launch/inputs/internal.py +224 -0
- wandb/sdk/launch/inputs/manage.py +95 -0
- wandb/sdk/launch/runner/abstract.py +2 -2
- wandb/sdk/launch/runner/kubernetes_monitor.py +45 -12
- wandb/sdk/launch/runner/kubernetes_runner.py +6 -8
- 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 +20 -14
- wandb/sdk/launch/runner/vertex_runner.py +8 -7
- wandb/sdk/launch/sweeps/scheduler.py +2 -0
- wandb/sdk/launch/sweeps/utils.py +2 -2
- wandb/sdk/launch/utils.py +16 -138
- wandb/sdk/lib/_settings_toposort_generated.py +2 -5
- wandb/sdk/lib/apikey.py +4 -2
- wandb/sdk/lib/config_util.py +3 -3
- wandb/sdk/lib/proto_util.py +22 -1
- wandb/sdk/lib/redirect.py +1 -1
- wandb/sdk/service/service.py +2 -1
- wandb/sdk/service/streams.py +5 -5
- wandb/sdk/wandb_init.py +25 -59
- wandb/sdk/wandb_login.py +28 -25
- wandb/sdk/wandb_run.py +112 -45
- wandb/sdk/wandb_settings.py +33 -64
- wandb/sdk/wandb_watch.py +1 -1
- wandb/sklearn/plot/classifier.py +4 -6
- wandb/sync/sync.py +2 -2
- wandb/testing/relay.py +32 -17
- wandb/util.py +36 -37
- wandb/wandb_agent.py +3 -3
- wandb/wandb_controller.py +3 -2
- {wandb-0.17.0rc2.dist-info → wandb-0.17.1.dist-info}/METADATA +7 -9
- {wandb-0.17.0rc2.dist-info → wandb-0.17.1.dist-info}/RECORD +125 -147
- wandb/apis/reports/v1/_blocks.py +0 -1406
- wandb/apis/reports/v1/_helpers.py +0 -70
- wandb/apis/reports/v1/_panels.py +0 -1282
- wandb/apis/reports/v1/_templates.py +0 -478
- wandb/apis/reports/v1/blocks.py +0 -27
- wandb/apis/reports/v1/helpers.py +0 -2
- wandb/apis/reports/v1/mutations.py +0 -66
- wandb/apis/reports/v1/panels.py +0 -17
- wandb/apis/reports/v1/report.py +0 -268
- wandb/apis/reports/v1/runset.py +0 -144
- wandb/apis/reports/v1/templates.py +0 -7
- wandb/apis/reports/v1/util.py +0 -406
- wandb/apis/reports/v1/validators.py +0 -131
- wandb/apis/reports/v2/blocks.py +0 -25
- wandb/apis/reports/v2/expr_parsing.py +0 -257
- wandb/apis/reports/v2/gql.py +0 -68
- wandb/apis/reports/v2/interface.py +0 -1911
- wandb/apis/reports/v2/internal.py +0 -867
- wandb/apis/reports/v2/metrics.py +0 -6
- wandb/apis/reports/v2/panels.py +0 -15
- wandb/catboost/__init__.py +0 -9
- wandb/fastai/__init__.py +0 -9
- wandb/keras/__init__.py +0 -19
- 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.17.0rc2.dist-info → wandb-0.17.1.dist-info}/WHEEL +0 -0
- {wandb-0.17.0rc2.dist-info → wandb-0.17.1.dist-info}/entry_points.txt +0 -0
- {wandb-0.17.0rc2.dist-info → wandb-0.17.1.dist-info}/licenses/LICENSE +0 -0
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,
|
@@ -957,8 +946,9 @@ def init(
|
|
957
946
|
save_code: Optional[bool] = None,
|
958
947
|
id: Optional[str] = None,
|
959
948
|
fork_from: Optional[str] = None,
|
949
|
+
resume_from: Optional[str] = None,
|
960
950
|
settings: Union[Settings, Dict[str, Any], None] = None,
|
961
|
-
) -> Union[Run, RunDisabled
|
951
|
+
) -> Union[Run, RunDisabled]:
|
962
952
|
r"""Start a new run to track and log to W&B.
|
963
953
|
|
964
954
|
In an ML training pipeline, you could add `wandb.init()`
|
@@ -1006,7 +996,7 @@ def init(
|
|
1006
996
|
there, so make sure to create your account or team in the UI before
|
1007
997
|
starting to log runs.
|
1008
998
|
If you don't specify an entity, the run will be sent to your default
|
1009
|
-
entity
|
999
|
+
entity. Change your default entity
|
1010
1000
|
in [your settings](https://wandb.ai/settings) under "default location
|
1011
1001
|
to create new projects".
|
1012
1002
|
config: (dict, argparse, absl.flags, str, optional)
|
@@ -1164,57 +1154,33 @@ def init(
|
|
1164
1154
|
wandb._assert_is_user_process()
|
1165
1155
|
|
1166
1156
|
kwargs = dict(locals())
|
1167
|
-
error_seen = None
|
1168
|
-
except_exit = None
|
1169
|
-
run: Optional[Union[Run, RunDisabled]] = None
|
1170
1157
|
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1158
|
+
num_resume_options_set = (
|
1159
|
+
(fork_from is not None) # wrap
|
1160
|
+
+ (resume is not None)
|
1161
|
+
+ (resume_from is not None)
|
1162
|
+
)
|
1163
|
+
if num_resume_options_set > 1:
|
1164
|
+
raise ValueError(
|
1165
|
+
"You cannot specify more than one of `fork_from`, `resume`, or `resume_from`"
|
1166
|
+
)
|
1174
1167
|
|
1175
1168
|
try:
|
1176
1169
|
wi = _WandbInit()
|
1177
1170
|
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
|
1171
|
+
return wi.init()
|
1172
|
+
|
1201
1173
|
except KeyboardInterrupt as e:
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1174
|
+
if logger is not None:
|
1175
|
+
logger.warning("interrupted", exc_info=e)
|
1176
|
+
|
1177
|
+
raise
|
1178
|
+
|
1205
1179
|
except Exception as e:
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
logger.error("error", exc_info=e)
|
1180
|
+
if logger is not None:
|
1181
|
+
logger.exception("error in wandb.init()", exc_info=e)
|
1182
|
+
|
1210
1183
|
# Need to build delay into this sentry capture because our exit hooks
|
1211
1184
|
# 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
|
1185
|
+
wandb._sentry.reraise(e)
|
1186
|
+
raise AssertionError() # unreachable
|
wandb/sdk/wandb_login.py
CHANGED
@@ -6,7 +6,7 @@ This authenticates your machine to log data to your account.
|
|
6
6
|
import enum
|
7
7
|
import os
|
8
8
|
import sys
|
9
|
-
from typing import
|
9
|
+
from typing import Optional, Tuple
|
10
10
|
|
11
11
|
if sys.version_info >= (3, 8):
|
12
12
|
from typing import Literal
|
@@ -112,11 +112,10 @@ class ApiKeyStatus(enum.Enum):
|
|
112
112
|
|
113
113
|
class _WandbLogin:
|
114
114
|
def __init__(self):
|
115
|
-
self.kwargs: Optional[Dict] = None
|
116
115
|
self._settings: Optional[Settings] = None
|
117
116
|
self._backend = None
|
118
|
-
self._silent = None
|
119
|
-
self._entity = None
|
117
|
+
self._silent: Optional[bool] = None
|
118
|
+
self._entity: Optional[str] = None
|
120
119
|
self._wl = None
|
121
120
|
self._key = None
|
122
121
|
self._relogin = None
|
@@ -130,7 +129,8 @@ class _WandbLogin:
|
|
130
129
|
host: Optional[str] = None,
|
131
130
|
force: Optional[bool] = None,
|
132
131
|
timeout: Optional[int] = None,
|
133
|
-
):
|
132
|
+
) -> None:
|
133
|
+
"""Updates login-related settings on the global setup object."""
|
134
134
|
self._relogin = relogin
|
135
135
|
|
136
136
|
# built up login settings
|
@@ -152,19 +152,24 @@ class _WandbLogin:
|
|
152
152
|
self._wl = wandb.setup(settings=login_settings)
|
153
153
|
self._settings = self._wl.settings
|
154
154
|
|
155
|
-
def is_apikey_configured(self):
|
155
|
+
def is_apikey_configured(self) -> bool:
|
156
|
+
"""Returns whether an API key is set or can be inferred."""
|
156
157
|
return apikey.api_key(settings=self._settings) is not None
|
157
158
|
|
158
159
|
def set_backend(self, backend):
|
159
160
|
self._backend = backend
|
160
161
|
|
161
|
-
def set_silent(self, silent: bool):
|
162
|
+
def set_silent(self, silent: bool) -> None:
|
162
163
|
self._silent = silent
|
163
164
|
|
164
|
-
def set_entity(self, entity: str):
|
165
|
+
def set_entity(self, entity: str) -> None:
|
165
166
|
self._entity = entity
|
166
167
|
|
167
|
-
def login(self):
|
168
|
+
def login(self) -> bool:
|
169
|
+
"""Returns whether the user is logged in (i.e. an API key exists).
|
170
|
+
|
171
|
+
If the user is logged in, this also prints an informational message.
|
172
|
+
"""
|
168
173
|
apikey_configured = self.is_apikey_configured()
|
169
174
|
if self._settings.relogin or self._relogin:
|
170
175
|
apikey_configured = False
|
@@ -172,11 +177,12 @@ class _WandbLogin:
|
|
172
177
|
return False
|
173
178
|
|
174
179
|
if not self._silent:
|
175
|
-
self.
|
180
|
+
self._print_logged_in_message()
|
176
181
|
|
177
182
|
return apikey_configured
|
178
183
|
|
179
|
-
def
|
184
|
+
def _print_logged_in_message(self) -> None:
|
185
|
+
"""Prints a message telling the user they are logged in."""
|
180
186
|
username = self._wl._get_username()
|
181
187
|
|
182
188
|
if username:
|
@@ -200,7 +206,8 @@ class _WandbLogin:
|
|
200
206
|
repeat=False,
|
201
207
|
)
|
202
208
|
|
203
|
-
def configure_api_key(self, key):
|
209
|
+
def configure_api_key(self, key: str) -> None:
|
210
|
+
"""Saves the API key and updates the the global setup object."""
|
204
211
|
if self._settings._notebook and not self._settings.silent:
|
205
212
|
wandb.termwarn(
|
206
213
|
"If you're specifying your api key in code, ensure this "
|
@@ -213,8 +220,14 @@ class _WandbLogin:
|
|
213
220
|
self._key = key
|
214
221
|
|
215
222
|
def update_session(
|
216
|
-
self,
|
223
|
+
self,
|
224
|
+
key: Optional[str],
|
225
|
+
status: ApiKeyStatus = ApiKeyStatus.VALID,
|
217
226
|
) -> None:
|
227
|
+
"""Updates mode and API key settings on the global setup object.
|
228
|
+
|
229
|
+
If we're online, this also pulls in user settings from the server.
|
230
|
+
"""
|
218
231
|
_logger = wandb.setup()._get_logger()
|
219
232
|
login_settings = dict()
|
220
233
|
if status == ApiKeyStatus.OFFLINE:
|
@@ -252,7 +265,8 @@ class _WandbLogin:
|
|
252
265
|
return None, ApiKeyStatus.OFFLINE
|
253
266
|
return key, ApiKeyStatus.VALID
|
254
267
|
|
255
|
-
def prompt_api_key(self):
|
268
|
+
def prompt_api_key(self) -> None:
|
269
|
+
"""Updates the global API key by prompting the user."""
|
256
270
|
key, status = self._prompt_api_key()
|
257
271
|
if status == ApiKeyStatus.NOTTY:
|
258
272
|
directive = (
|
@@ -265,14 +279,6 @@ class _WandbLogin:
|
|
265
279
|
self.update_session(key, status=status)
|
266
280
|
self._key = key
|
267
281
|
|
268
|
-
def propogate_login(self):
|
269
|
-
# TODO(jhr): figure out if this is really necessary
|
270
|
-
if self._backend:
|
271
|
-
# TODO: calling this twice is gross, this deserves a refactor
|
272
|
-
# Make sure our backend picks up the new creds
|
273
|
-
# _ = self._backend.interface.communicate_login(key, anonymous)
|
274
|
-
pass
|
275
|
-
|
276
282
|
|
277
283
|
def _login(
|
278
284
|
*,
|
@@ -333,7 +339,4 @@ def _login(
|
|
333
339
|
if not key:
|
334
340
|
wlogin.prompt_api_key()
|
335
341
|
|
336
|
-
# make sure login credentials get to the backend
|
337
|
-
wlogin.propogate_login()
|
338
|
-
|
339
342
|
return wlogin._key or False
|
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
|
*,
|
@@ -247,7 +256,7 @@ class RunStatusChecker:
|
|
247
256
|
local_handle = None
|
248
257
|
|
249
258
|
time_elapsed = time.monotonic() - time_probe
|
250
|
-
wait_time = max(
|
259
|
+
wait_time = max(timeout - time_elapsed, 0)
|
251
260
|
join_requested = self._join_event.wait(timeout=wait_time)
|
252
261
|
|
253
262
|
def check_network_status(self) -> None:
|
@@ -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()
|
@@ -676,6 +706,12 @@ class Run:
|
|
676
706
|
"step": self._settings.fork_from.value,
|
677
707
|
}
|
678
708
|
|
709
|
+
if self._settings.resume_from is not None:
|
710
|
+
config[wandb_key]["branch_point"] = {
|
711
|
+
"run_id": self._settings.resume_from.run,
|
712
|
+
"step": self._settings.resume_from.value,
|
713
|
+
}
|
714
|
+
|
679
715
|
self._config._update(config, ignore_locked=True)
|
680
716
|
|
681
717
|
if sweep_config:
|
@@ -1400,6 +1436,10 @@ class Run:
|
|
1400
1436
|
# self._printer.display(line)
|
1401
1437
|
|
1402
1438
|
def _summary_get_current_summary_callback(self) -> Dict[str, Any]:
|
1439
|
+
if self._is_finished:
|
1440
|
+
# TODO: WB-18420: fetch summary from backend and stage it before run is finished
|
1441
|
+
wandb.termwarn("Summary data not available in finished run")
|
1442
|
+
return {}
|
1403
1443
|
if not self._backend or not self._backend.interface:
|
1404
1444
|
return {}
|
1405
1445
|
handle = self._backend.interface.deliver_get_summary()
|
@@ -1792,7 +1832,7 @@ class Run:
|
|
1792
1832
|
import wandb
|
1793
1833
|
|
1794
1834
|
run = wandb.init()
|
1795
|
-
run.log({"pr": wandb.
|
1835
|
+
run.log({"pr": wandb.plot.pr_curve(y_test, y_probas, labels)})
|
1796
1836
|
```
|
1797
1837
|
|
1798
1838
|
### 3D Object
|
@@ -2443,6 +2483,8 @@ class Run:
|
|
2443
2483
|
self._telemetry_obj_active = True
|
2444
2484
|
self._telemetry_flush()
|
2445
2485
|
|
2486
|
+
self._detect_and_apply_job_inputs()
|
2487
|
+
|
2446
2488
|
# object is about to be returned to the user, don't let them modify it
|
2447
2489
|
self._freeze()
|
2448
2490
|
|
@@ -2450,6 +2492,12 @@ class Run:
|
|
2450
2492
|
if os.path.exists(self._settings.resume_fname):
|
2451
2493
|
os.remove(self._settings.resume_fname)
|
2452
2494
|
|
2495
|
+
def _detect_and_apply_job_inputs(self) -> None:
|
2496
|
+
"""If the user has staged launch inputs, apply them to the run."""
|
2497
|
+
from wandb.sdk.launch.inputs.internal import StagedLaunchInputs
|
2498
|
+
|
2499
|
+
StagedLaunchInputs().apply(self)
|
2500
|
+
|
2453
2501
|
def _make_job_source_reqs(self) -> Tuple[List[str], Dict[str, Any], Dict[str, Any]]:
|
2454
2502
|
from wandb.util import working_set
|
2455
2503
|
|
@@ -2555,6 +2603,14 @@ class Run:
|
|
2555
2603
|
self._console_stop() # TODO: there's a race here with jupyter console logging
|
2556
2604
|
|
2557
2605
|
assert self._backend and self._backend.interface
|
2606
|
+
|
2607
|
+
# get the server info before starting the defer state machine as
|
2608
|
+
# it will stop communication with the server
|
2609
|
+
server_info_handle = self._backend.interface.deliver_request_server_info()
|
2610
|
+
result = server_info_handle.wait(timeout=-1)
|
2611
|
+
assert result
|
2612
|
+
self._server_info_response = result.response.server_info_response
|
2613
|
+
|
2558
2614
|
exit_handle = self._backend.interface.deliver_exit(self._exit_code)
|
2559
2615
|
exit_handle.add_probe(on_probe=self._on_probe_exit)
|
2560
2616
|
|
@@ -2563,6 +2619,7 @@ class Run:
|
|
2563
2619
|
# self._exit_code, settings=self._settings, printer=self._printer
|
2564
2620
|
# )
|
2565
2621
|
|
2622
|
+
# wait for the exit to complete
|
2566
2623
|
_ = exit_handle.wait(timeout=-1, on_progress=self._on_progress_exit)
|
2567
2624
|
|
2568
2625
|
poll_exit_handle = self._backend.interface.deliver_poll_exit()
|
@@ -2580,16 +2637,11 @@ class Run:
|
|
2580
2637
|
|
2581
2638
|
# dispatch all our final requests
|
2582
2639
|
|
2583
|
-
server_info_handle = self._backend.interface.deliver_request_server_info()
|
2584
2640
|
final_summary_handle = self._backend.interface.deliver_get_summary()
|
2585
2641
|
sampled_history_handle = (
|
2586
2642
|
self._backend.interface.deliver_request_sampled_history()
|
2587
2643
|
)
|
2588
2644
|
|
2589
|
-
result = server_info_handle.wait(timeout=-1)
|
2590
|
-
assert result
|
2591
|
-
self._server_info_response = result.response.server_info_response
|
2592
|
-
|
2593
2645
|
result = sampled_history_handle.wait(timeout=-1)
|
2594
2646
|
assert result
|
2595
2647
|
self._sampled_history = result.response.sampled_history_response
|
@@ -2708,12 +2760,23 @@ class Run:
|
|
2708
2760
|
if i not in valid:
|
2709
2761
|
raise wandb.Error(f"Unhandled define_metric() arg: summary op: {i}")
|
2710
2762
|
summary_ops.append(i)
|
2763
|
+
with telemetry.context(run=self) as tel:
|
2764
|
+
tel.feature.metric_summary = True
|
2711
2765
|
goal_cleaned: Optional[str] = None
|
2712
2766
|
if goal is not None:
|
2713
2767
|
goal_cleaned = goal[:3].lower()
|
2714
2768
|
valid_goal = {"min", "max"}
|
2715
2769
|
if goal_cleaned not in valid_goal:
|
2716
2770
|
raise wandb.Error(f"Unhandled define_metric() arg: goal: {goal}")
|
2771
|
+
with telemetry.context(run=self) as tel:
|
2772
|
+
tel.feature.metric_goal = True
|
2773
|
+
if hidden:
|
2774
|
+
with telemetry.context(run=self) as tel:
|
2775
|
+
tel.feature.metric_hidden = True
|
2776
|
+
if step_sync:
|
2777
|
+
with telemetry.context(run=self) as tel:
|
2778
|
+
tel.feature.metric_step_sync = True
|
2779
|
+
|
2717
2780
|
m = wandb_metric.Metric(
|
2718
2781
|
name=name,
|
2719
2782
|
step_metric=step_metric,
|
@@ -2898,6 +2961,7 @@ class Run:
|
|
2898
2961
|
api.use_artifact(
|
2899
2962
|
artifact.id,
|
2900
2963
|
entity_name=r.entity,
|
2964
|
+
project_name=r.project,
|
2901
2965
|
use_as=use_as or artifact_or_name,
|
2902
2966
|
)
|
2903
2967
|
else:
|
@@ -2960,8 +3024,7 @@ class Run:
|
|
2960
3024
|
- `s3://bucket/path`
|
2961
3025
|
You can also pass an Artifact object created by calling
|
2962
3026
|
`wandb.Artifact`.
|
2963
|
-
name: (str, optional) An artifact name.
|
2964
|
-
Valid names can be in the following forms:
|
3027
|
+
name: (str, optional) An artifact name. Valid names can be in the following forms:
|
2965
3028
|
- name:version
|
2966
3029
|
- name:alias
|
2967
3030
|
- digest
|
@@ -3607,7 +3670,11 @@ class Run:
|
|
3607
3670
|
project_url = settings.project_url
|
3608
3671
|
sweep_url = settings.sweep_url
|
3609
3672
|
|
3610
|
-
run_state_str =
|
3673
|
+
run_state_str = (
|
3674
|
+
"Resuming run"
|
3675
|
+
if settings.resumed or settings.resume_from
|
3676
|
+
else "Syncing run"
|
3677
|
+
)
|
3611
3678
|
run_name = settings.run_name
|
3612
3679
|
if not run_name:
|
3613
3680
|
return
|
@@ -3964,11 +4031,11 @@ class Run:
|
|
3964
4031
|
|
3965
4032
|
# Render summary if available
|
3966
4033
|
if summary:
|
3967
|
-
final_summary = {
|
3968
|
-
|
3969
|
-
|
3970
|
-
|
3971
|
-
|
4034
|
+
final_summary = {}
|
4035
|
+
for item in summary.item:
|
4036
|
+
if item.key.startswith("_") or len(item.nested_key) > 0:
|
4037
|
+
continue
|
4038
|
+
final_summary[item.key] = json.loads(item.value_json)
|
3972
4039
|
|
3973
4040
|
logger.info("rendering summary")
|
3974
4041
|
summary_rows = []
|