wandb 0.19.4rc1__py3-none-any.whl → 0.19.6rc4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wandb/__init__.py +1 -1
- wandb/__init__.pyi +1 -8
- wandb/_iterutils.py +46 -0
- wandb/apis/internal.py +4 -0
- wandb/apis/normalize.py +13 -5
- wandb/bin/gpu_stats +0 -0
- wandb/cli/cli.py +9 -2
- wandb/proto/v3/wandb_internal_pb2.py +36 -36
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_internal_pb2.py +36 -36
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v5/wandb_internal_pb2.py +36 -36
- wandb/proto/v5/wandb_settings_pb2.py +2 -2
- wandb/sdk/artifacts/artifact.py +120 -8
- wandb/sdk/artifacts/storage_handlers/local_file_handler.py +12 -5
- wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +1 -1
- wandb/sdk/backend/backend.py +7 -11
- wandb/sdk/data_types/base_types/wb_value.py +10 -10
- wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +2 -2
- wandb/sdk/data_types/helper_types/image_mask.py +2 -2
- wandb/sdk/data_types/image.py +0 -3
- wandb/sdk/data_types/saved_model.py +1 -1
- wandb/sdk/data_types/utils.py +2 -6
- wandb/sdk/interface/interface.py +26 -12
- wandb/sdk/interface/interface_sock.py +7 -11
- wandb/sdk/internal/internal_api.py +9 -1
- wandb/sdk/internal/sender.py +2 -2
- wandb/sdk/internal/system/assets/cpu.py +1 -1
- wandb/sdk/lib/apikey.py +7 -19
- wandb/sdk/lib/mailbox.py +0 -14
- wandb/sdk/lib/retry.py +6 -3
- wandb/sdk/lib/run_moment.py +19 -7
- wandb/sdk/lib/server.py +20 -0
- wandb/sdk/lib/service_connection.py +2 -2
- wandb/sdk/wandb_init.py +71 -46
- wandb/sdk/wandb_login.py +86 -110
- wandb/sdk/wandb_metadata.py +60 -31
- wandb/sdk/wandb_run.py +32 -45
- wandb/sdk/wandb_settings.py +465 -143
- wandb/sdk/wandb_setup.py +10 -22
- wandb/util.py +44 -12
- {wandb-0.19.4rc1.dist-info → wandb-0.19.6rc4.dist-info}/METADATA +1 -1
- {wandb-0.19.4rc1.dist-info → wandb-0.19.6rc4.dist-info}/RECORD +46 -45
- {wandb-0.19.4rc1.dist-info → wandb-0.19.6rc4.dist-info}/WHEEL +0 -0
- {wandb-0.19.4rc1.dist-info → wandb-0.19.6rc4.dist-info}/entry_points.txt +0 -0
- {wandb-0.19.4rc1.dist-info → wandb-0.19.6rc4.dist-info}/licenses/LICENSE +0 -0
wandb/sdk/wandb_init.py
CHANGED
@@ -20,7 +20,7 @@ import platform
|
|
20
20
|
import sys
|
21
21
|
import tempfile
|
22
22
|
import time
|
23
|
-
from typing import
|
23
|
+
from typing import Any, Literal, Sequence
|
24
24
|
|
25
25
|
if sys.version_info >= (3, 11):
|
26
26
|
from typing import Self
|
@@ -40,16 +40,13 @@ from wandb.util import _is_artifact_representation
|
|
40
40
|
|
41
41
|
from . import wandb_login, wandb_setup
|
42
42
|
from .backend.backend import Backend
|
43
|
-
from .lib import SummaryDisabled, filesystem, module, printer, telemetry
|
43
|
+
from .lib import SummaryDisabled, filesystem, module, paths, printer, telemetry
|
44
44
|
from .lib.deprecate import Deprecated, deprecate
|
45
45
|
from .lib.mailbox import Mailbox, MailboxProgress
|
46
46
|
from .wandb_helper import parse_config
|
47
47
|
from .wandb_run import Run, TeardownHook, TeardownStage
|
48
48
|
from .wandb_settings import Settings
|
49
49
|
|
50
|
-
if TYPE_CHECKING:
|
51
|
-
from wandb.proto import wandb_internal_pb2 as pb
|
52
|
-
|
53
50
|
|
54
51
|
def _huggingface_version() -> str | None:
|
55
52
|
if "transformers" in sys.modules:
|
@@ -180,7 +177,6 @@ class _WandbInit:
|
|
180
177
|
force=run_settings.force,
|
181
178
|
_disable_warning=True,
|
182
179
|
_silent=run_settings.quiet or run_settings.silent,
|
183
|
-
_entity=run_settings.entity,
|
184
180
|
)
|
185
181
|
|
186
182
|
def warn_env_vars_change_after_setup(self) -> None:
|
@@ -454,6 +450,23 @@ class _WandbInit:
|
|
454
450
|
artifacts=result.artifacts,
|
455
451
|
)
|
456
452
|
|
453
|
+
wandb_internal = result.base_no_artifacts.setdefault("_wandb", dict())
|
454
|
+
|
455
|
+
if settings.save_code and settings.program_relpath:
|
456
|
+
wandb_internal["code_path"] = paths.LogicalPath(
|
457
|
+
os.path.join("code", settings.program_relpath)
|
458
|
+
)
|
459
|
+
if settings.fork_from is not None:
|
460
|
+
wandb_internal["branch_point"] = {
|
461
|
+
"run_id": settings.fork_from.run,
|
462
|
+
"step": settings.fork_from.value,
|
463
|
+
}
|
464
|
+
if settings.resume_from is not None:
|
465
|
+
wandb_internal["branch_point"] = {
|
466
|
+
"run_id": settings.resume_from.run,
|
467
|
+
"step": settings.resume_from.value,
|
468
|
+
}
|
469
|
+
|
457
470
|
return result
|
458
471
|
|
459
472
|
def teardown(self) -> None:
|
@@ -864,7 +877,7 @@ class _WandbInit:
|
|
864
877
|
tel.feature.core = True
|
865
878
|
if settings._shared:
|
866
879
|
wandb.termwarn(
|
867
|
-
"The `
|
880
|
+
"The `shared` mode feature is experimental and may change. "
|
868
881
|
"Please contact support@wandb.com for guidance and to report any issues."
|
869
882
|
)
|
870
883
|
tel.feature.shared_mode = True
|
@@ -891,7 +904,6 @@ class _WandbInit:
|
|
891
904
|
run._set_backend(backend)
|
892
905
|
run._set_teardown_hooks(self._teardown_hooks)
|
893
906
|
|
894
|
-
backend._hack_set_run(run)
|
895
907
|
assert backend.interface
|
896
908
|
mailbox.enable_keepalive()
|
897
909
|
backend.interface.publish_header()
|
@@ -902,8 +914,6 @@ class _WandbInit:
|
|
902
914
|
if not (settings.disable_git or settings.x_disable_machine_info):
|
903
915
|
run._populate_git_info()
|
904
916
|
|
905
|
-
run_result: pb.RunUpdateResult | None = None
|
906
|
-
|
907
917
|
if settings._offline and settings.resume:
|
908
918
|
wandb.termwarn(
|
909
919
|
"`resume` will be ignored since W&B syncing is set to `offline`. "
|
@@ -911,6 +921,16 @@ class _WandbInit:
|
|
911
921
|
)
|
912
922
|
error: wandb.Error | None = None
|
913
923
|
|
924
|
+
# In shared mode, generate a unique label if not provided.
|
925
|
+
# The label is used to distinguish between system metrics and console logs
|
926
|
+
# from different writers to the same run.
|
927
|
+
if settings._shared and not settings.x_label:
|
928
|
+
# TODO: If executed in a known distributed environment (e.g. Ray or SLURM),
|
929
|
+
# use the env vars to generate a label (e.g. SLURM_JOB_ID or RANK)
|
930
|
+
prefix = settings.host or ""
|
931
|
+
label = runid.generate_id()
|
932
|
+
settings.x_label = f"{prefix}-{label}" if prefix else label
|
933
|
+
|
914
934
|
timeout = settings.init_timeout
|
915
935
|
|
916
936
|
self._logger.info(
|
@@ -923,47 +943,53 @@ class _WandbInit:
|
|
923
943
|
on_progress=self._on_progress_init,
|
924
944
|
cancel=True,
|
925
945
|
)
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
+
|
947
|
+
# Raise an error if deliver_run failed.
|
948
|
+
#
|
949
|
+
# This is wrapped in a try-except to perform additional cleanup logic
|
950
|
+
# when x_disable_service is True.
|
951
|
+
#
|
952
|
+
# TODO: Remove try-except once x_disable_service is removed.
|
953
|
+
try:
|
954
|
+
if not result or not result.run_result:
|
955
|
+
run_init_handle._cancel()
|
956
|
+
|
957
|
+
# This may either be an issue with the W&B server (a CommError)
|
958
|
+
# or a bug in the SDK (an Error). We cannot distinguish between
|
959
|
+
# the two causes here.
|
960
|
+
raise CommError(
|
961
|
+
f"Run initialization has timed out after {timeout} sec."
|
962
|
+
" Please try increasing the timeout with the `init_timeout`"
|
963
|
+
" setting: `wandb.init(settings=wandb.Settings(init_timeout=120))`."
|
964
|
+
)
|
965
|
+
|
966
|
+
if error := ProtobufErrorHandler.to_exception(result.run_result.error):
|
967
|
+
raise error
|
968
|
+
|
969
|
+
if not result.run_result.HasField("run"):
|
970
|
+
raise Error("Assertion failed: run_result is missing the run field")
|
971
|
+
|
972
|
+
except Exception:
|
946
973
|
if not service:
|
947
|
-
#
|
948
|
-
# we don't need to do console cleanup at this point
|
974
|
+
# Kill the background thread or process.
|
949
975
|
backend.cleanup()
|
950
|
-
self.teardown()
|
951
|
-
raise error
|
952
|
-
|
953
|
-
assert run_result is not None # for mypy
|
954
976
|
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
977
|
+
# Do some Jupyter and logger cleanup.
|
978
|
+
#
|
979
|
+
# NOTE: This shouldn't be necessary. The logger is global,
|
980
|
+
# so on any error outside of this try-catch, we fail to
|
981
|
+
# clean it up, causing the next run to write some of its
|
982
|
+
# initial logs to this run's log file. The Jupyter
|
983
|
+
# monkeypatching should probably happen at the library level
|
984
|
+
# (in wandb.setup()) rather than per-run.
|
985
|
+
self.teardown()
|
986
|
+
raise
|
961
987
|
|
962
|
-
if run_result.run.resumed:
|
988
|
+
if result.run_result.run.resumed:
|
963
989
|
self._logger.info("run resumed")
|
964
990
|
with telemetry.context(run=run) as tel:
|
965
|
-
tel.feature.resumed = run_result.run.resumed
|
966
|
-
run._set_run_obj(run_result.run)
|
991
|
+
tel.feature.resumed = result.run_result.run.resumed
|
992
|
+
run._set_run_obj(result.run_result.run)
|
967
993
|
|
968
994
|
self._logger.info("starting run threads in backend")
|
969
995
|
# initiate run (stats and metadata probing)
|
@@ -1069,7 +1095,6 @@ def _attach(
|
|
1069
1095
|
run._init(settings=settings)
|
1070
1096
|
run._set_library(_wl)
|
1071
1097
|
run._set_backend(backend)
|
1072
|
-
backend._hack_set_run(run)
|
1073
1098
|
assert backend.interface
|
1074
1099
|
|
1075
1100
|
mailbox.enable_keepalive()
|
wandb/sdk/wandb_login.py
CHANGED
@@ -8,6 +8,7 @@ import os
|
|
8
8
|
from typing import Literal, Optional, Tuple
|
9
9
|
|
10
10
|
import click
|
11
|
+
from requests.exceptions import ConnectionError
|
11
12
|
|
12
13
|
import wandb
|
13
14
|
from wandb.errors import AuthenticationError, UsageError
|
@@ -16,7 +17,6 @@ from wandb.old.settings import Settings as OldSettings
|
|
16
17
|
from ..apis import InternalApi
|
17
18
|
from .internal.internal_api import Api
|
18
19
|
from .lib import apikey
|
19
|
-
from .wandb_settings import Settings
|
20
20
|
|
21
21
|
|
22
22
|
def _handle_host_wandb_setting(host: Optional[str], cloud: bool = False) -> None:
|
@@ -73,30 +73,16 @@ def login(
|
|
73
73
|
UsageError - if api_key cannot be configured and no tty
|
74
74
|
"""
|
75
75
|
_handle_host_wandb_setting(host)
|
76
|
-
|
77
|
-
return True
|
78
|
-
|
79
|
-
configured = _login(
|
76
|
+
return _login(
|
80
77
|
anonymous=anonymous,
|
81
78
|
key=key,
|
82
79
|
relogin=relogin,
|
83
80
|
host=host,
|
84
81
|
force=force,
|
85
82
|
timeout=timeout,
|
83
|
+
verify=verify,
|
86
84
|
)
|
87
85
|
|
88
|
-
if verify:
|
89
|
-
from . import wandb_setup
|
90
|
-
|
91
|
-
singleton = wandb_setup.singleton()
|
92
|
-
assert singleton is not None
|
93
|
-
viewer = singleton._server._viewer
|
94
|
-
if not viewer:
|
95
|
-
raise AuthenticationError(
|
96
|
-
"API key verification failed. Make sure your API key is valid."
|
97
|
-
)
|
98
|
-
return True if configured else False
|
99
|
-
|
100
86
|
|
101
87
|
class ApiKeyStatus(enum.Enum):
|
102
88
|
VALID = 1
|
@@ -106,26 +92,15 @@ class ApiKeyStatus(enum.Enum):
|
|
106
92
|
|
107
93
|
|
108
94
|
class _WandbLogin:
|
109
|
-
def __init__(
|
110
|
-
self._settings: Optional[Settings] = None
|
111
|
-
self._backend = None
|
112
|
-
self._silent: Optional[bool] = None
|
113
|
-
self._entity: Optional[str] = None
|
114
|
-
self._wl = None
|
115
|
-
self._key = None
|
116
|
-
self._relogin = None
|
117
|
-
|
118
|
-
def setup(
|
95
|
+
def __init__(
|
119
96
|
self,
|
120
|
-
|
121
|
-
|
97
|
+
anonymous: Optional[Literal["must", "allow", "never"]] = None,
|
98
|
+
force: Optional[bool] = None,
|
99
|
+
host: Optional[str] = None,
|
122
100
|
key: Optional[str] = None,
|
123
101
|
relogin: Optional[bool] = None,
|
124
|
-
host: Optional[str] = None,
|
125
|
-
force: Optional[bool] = None,
|
126
102
|
timeout: Optional[int] = None,
|
127
|
-
)
|
128
|
-
"""Updates login-related settings on the global setup object."""
|
103
|
+
):
|
129
104
|
self._relogin = relogin
|
130
105
|
|
131
106
|
login_settings = {
|
@@ -135,61 +110,47 @@ class _WandbLogin:
|
|
135
110
|
"force": force,
|
136
111
|
"login_timeout": timeout,
|
137
112
|
}
|
113
|
+
self.is_anonymous = anonymous == "must"
|
138
114
|
|
139
|
-
|
140
|
-
self.
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
)
|
145
|
-
|
115
|
+
self._wandb_setup = wandb.setup()
|
116
|
+
self._wandb_setup.settings.update_from_dict(login_settings)
|
117
|
+
self._settings = self._wandb_setup.settings
|
118
|
+
|
119
|
+
def _update_global_anonymous_setting(self) -> None:
|
120
|
+
api = InternalApi()
|
121
|
+
if self.is_anonymous:
|
122
|
+
api.set_setting("anonymous", "must", globally=True, persist=True)
|
123
|
+
else:
|
124
|
+
api.clear_setting("anonymous", globally=True, persist=True)
|
146
125
|
|
147
126
|
def is_apikey_configured(self) -> bool:
|
148
127
|
"""Returns whether an API key is set or can be inferred."""
|
149
128
|
return apikey.api_key(settings=self._settings) is not None
|
150
129
|
|
151
|
-
def should_use_identity_token(self):
|
152
|
-
return self._settings.identity_token_file is not None
|
153
|
-
|
154
|
-
def set_backend(self, backend):
|
155
|
-
self._backend = backend
|
156
|
-
|
157
|
-
def set_silent(self, silent: bool) -> None:
|
158
|
-
self._silent = silent
|
159
|
-
|
160
|
-
def set_entity(self, entity: str) -> None:
|
161
|
-
self._entity = entity
|
162
|
-
|
163
|
-
def login(self) -> bool:
|
164
|
-
"""Returns whether the user is logged in (i.e. an API key exists).
|
165
|
-
|
166
|
-
If the user is logged in, this also prints an informational message.
|
167
|
-
"""
|
168
|
-
apikey_configured = self.is_apikey_configured()
|
169
|
-
if self._settings.relogin or self._relogin:
|
170
|
-
apikey_configured = False
|
171
|
-
if not apikey_configured:
|
172
|
-
return False
|
173
|
-
|
174
|
-
if not self._silent:
|
175
|
-
self._print_logged_in_message()
|
176
|
-
|
177
|
-
return apikey_configured
|
178
|
-
|
179
130
|
def _print_logged_in_message(self) -> None:
|
180
131
|
"""Prints a message telling the user they are logged in."""
|
181
|
-
username = self.
|
132
|
+
username = self._wandb_setup._get_username()
|
182
133
|
|
183
134
|
if username:
|
135
|
+
host_str = (
|
136
|
+
f" to {click.style(self._settings.base_url, fg='green')}"
|
137
|
+
if self._settings.base_url
|
138
|
+
else ""
|
139
|
+
)
|
140
|
+
|
184
141
|
# check to see if we got an entity from the setup call or from the user
|
185
|
-
entity = self.
|
142
|
+
entity = self._settings.entity or self._wandb_setup._get_entity()
|
186
143
|
|
187
144
|
entity_str = ""
|
188
145
|
# check if entity exist, valid (is part of a certain team) and different from the username
|
189
|
-
if
|
146
|
+
if (
|
147
|
+
entity
|
148
|
+
and entity in self._wandb_setup._get_teams()
|
149
|
+
and entity != username
|
150
|
+
):
|
190
151
|
entity_str = f" ({click.style(entity, fg='yellow')})"
|
191
152
|
|
192
|
-
login_state_str = f"Currently logged in as: {click.style(username, fg='yellow')}{entity_str}"
|
153
|
+
login_state_str = f"Currently logged in as: {click.style(username, fg='yellow')}{entity_str}{host_str}"
|
193
154
|
else:
|
194
155
|
login_state_str = "W&B API key is configured"
|
195
156
|
|
@@ -210,9 +171,8 @@ class _WandbLogin:
|
|
210
171
|
"WANDB_API_KEY environment variable, or running "
|
211
172
|
"`wandb login` from the command line."
|
212
173
|
)
|
213
|
-
|
214
|
-
|
215
|
-
self._key = key
|
174
|
+
if key:
|
175
|
+
apikey.write_key(self._settings, key)
|
216
176
|
|
217
177
|
def update_session(
|
218
178
|
self,
|
@@ -230,11 +190,11 @@ class _WandbLogin:
|
|
230
190
|
login_settings = dict(mode="disabled")
|
231
191
|
elif key:
|
232
192
|
login_settings = dict(api_key=key)
|
233
|
-
self.
|
193
|
+
self._wandb_setup.settings.update_from_dict(login_settings)
|
234
194
|
# Whenever the key changes, make sure to pull in user settings
|
235
195
|
# from server.
|
236
|
-
if not self.
|
237
|
-
self.
|
196
|
+
if not self._wandb_setup.settings._offline:
|
197
|
+
self._wandb_setup._update_user_settings()
|
238
198
|
|
239
199
|
def _prompt_api_key(self) -> Tuple[Optional[str], ApiKeyStatus]:
|
240
200
|
api = Api(self._settings)
|
@@ -259,7 +219,7 @@ class _WandbLogin:
|
|
259
219
|
return None, ApiKeyStatus.OFFLINE
|
260
220
|
return key, ApiKeyStatus.VALID
|
261
221
|
|
262
|
-
def prompt_api_key(self) ->
|
222
|
+
def prompt_api_key(self) -> Tuple[Optional[str], ApiKeyStatus]:
|
263
223
|
"""Updates the global API key by prompting the user."""
|
264
224
|
key, status = self._prompt_api_key()
|
265
225
|
if status == ApiKeyStatus.NOTTY:
|
@@ -270,8 +230,24 @@ class _WandbLogin:
|
|
270
230
|
)
|
271
231
|
raise UsageError("api_key not configured (no-tty). call " + directive)
|
272
232
|
|
273
|
-
|
274
|
-
|
233
|
+
return key, status
|
234
|
+
|
235
|
+
def _verify_login(self, key: str) -> None:
|
236
|
+
api = InternalApi(api_key=key)
|
237
|
+
|
238
|
+
try:
|
239
|
+
is_api_key_valid = api.validate_api_key()
|
240
|
+
|
241
|
+
if not is_api_key_valid:
|
242
|
+
raise AuthenticationError(
|
243
|
+
"API key verification failed. Make sure your API key is valid."
|
244
|
+
)
|
245
|
+
except ConnectionError:
|
246
|
+
raise AuthenticationError(
|
247
|
+
"Unable to connect to server to verify API token."
|
248
|
+
)
|
249
|
+
except Exception:
|
250
|
+
raise AuthenticationError("An error occurred while verifying the API key.")
|
275
251
|
|
276
252
|
|
277
253
|
def _login(
|
@@ -282,38 +258,29 @@ def _login(
|
|
282
258
|
host: Optional[str] = None,
|
283
259
|
force: Optional[bool] = None,
|
284
260
|
timeout: Optional[int] = None,
|
285
|
-
|
261
|
+
verify: bool = False,
|
286
262
|
_silent: Optional[bool] = None,
|
287
263
|
_disable_warning: Optional[bool] = None,
|
288
|
-
|
289
|
-
):
|
264
|
+
) -> bool:
|
290
265
|
if wandb.run is not None:
|
291
266
|
if not _disable_warning:
|
292
267
|
wandb.termwarn("Calling wandb.login() after wandb.init() has no effect.")
|
293
268
|
return True
|
294
269
|
|
295
|
-
wlogin = _WandbLogin(
|
296
|
-
|
297
|
-
if _backend:
|
298
|
-
wlogin.set_backend(_backend)
|
299
|
-
|
300
|
-
if _silent:
|
301
|
-
wlogin.set_silent(_silent)
|
302
|
-
|
303
|
-
if _entity:
|
304
|
-
wlogin.set_entity(_entity)
|
305
|
-
|
306
|
-
# configure login object
|
307
|
-
wlogin.setup(
|
270
|
+
wlogin = _WandbLogin(
|
308
271
|
anonymous=anonymous,
|
272
|
+
force=force,
|
273
|
+
host=host,
|
309
274
|
key=key,
|
310
275
|
relogin=relogin,
|
311
|
-
host=host,
|
312
|
-
force=force,
|
313
276
|
timeout=timeout,
|
314
277
|
)
|
315
278
|
|
316
|
-
if wlogin._settings.
|
279
|
+
if wlogin._settings._noop:
|
280
|
+
return True
|
281
|
+
|
282
|
+
if wlogin._settings._offline and not wlogin._settings.x_cli_only_mode:
|
283
|
+
wandb.termwarn("Unable to verify login in offline mode.")
|
317
284
|
return False
|
318
285
|
elif wandb.util._is_kaggle() and not wandb.util._has_internet():
|
319
286
|
wandb.termerror(
|
@@ -321,19 +288,28 @@ def _login(
|
|
321
288
|
)
|
322
289
|
return False
|
323
290
|
|
324
|
-
if wlogin.
|
291
|
+
if wlogin._settings.identity_token_file:
|
325
292
|
return True
|
326
293
|
|
327
|
-
|
328
|
-
|
294
|
+
key_is_pre_configured = False
|
295
|
+
key_status = None
|
296
|
+
if key is None:
|
297
|
+
# Check if key is already set in the settings, or configured in the users .netrc file.
|
298
|
+
key = apikey.api_key(settings=wlogin._settings)
|
299
|
+
if key and not relogin:
|
300
|
+
key_is_pre_configured = True
|
301
|
+
else:
|
302
|
+
key, key_status = wlogin.prompt_api_key()
|
303
|
+
|
304
|
+
if verify:
|
305
|
+
wlogin._verify_login(key)
|
329
306
|
|
330
|
-
if
|
307
|
+
if not key_is_pre_configured:
|
331
308
|
wlogin.configure_api_key(key)
|
309
|
+
wlogin.update_session(key, status=key_status)
|
310
|
+
wlogin._update_global_anonymous_setting()
|
332
311
|
|
333
|
-
if
|
334
|
-
|
335
|
-
|
336
|
-
if not key:
|
337
|
-
wlogin.prompt_api_key()
|
312
|
+
if key and not _silent:
|
313
|
+
wlogin._print_logged_in_message()
|
338
314
|
|
339
|
-
return
|
315
|
+
return key is not None
|
wandb/sdk/wandb_metadata.py
CHANGED
@@ -95,6 +95,7 @@ class GpuNvidiaInfo(BaseModel, validate_assignment=True):
|
|
95
95
|
memory_total: int | None = None
|
96
96
|
cuda_cores: int | None = None
|
97
97
|
architecture: str | None = None
|
98
|
+
uuid: str | None = None
|
98
99
|
|
99
100
|
def to_proto(self) -> wandb_internal_pb2.GpuNvidiaInfo:
|
100
101
|
return wandb_internal_pb2.GpuNvidiaInfo(
|
@@ -102,6 +103,7 @@ class GpuNvidiaInfo(BaseModel, validate_assignment=True):
|
|
102
103
|
memory_total=self.memory_total or 0,
|
103
104
|
cuda_cores=self.cuda_cores or 0,
|
104
105
|
architecture=self.architecture or "",
|
106
|
+
uuid=self.uuid or "",
|
105
107
|
)
|
106
108
|
|
107
109
|
@classmethod
|
@@ -111,6 +113,7 @@ class GpuNvidiaInfo(BaseModel, validate_assignment=True):
|
|
111
113
|
memory_total=proto.memory_total,
|
112
114
|
cuda_cores=proto.cuda_cores,
|
113
115
|
architecture=proto.architecture,
|
116
|
+
uuid=proto.uuid,
|
114
117
|
)
|
115
118
|
|
116
119
|
|
@@ -234,37 +237,63 @@ class Metadata(BaseModel, validate_assignment=True):
|
|
234
237
|
NOTE: Definitions must be kept in sync with wandb_internal.proto::MetadataRequest.
|
235
238
|
|
236
239
|
Attributes:
|
237
|
-
os
|
238
|
-
python
|
239
|
-
heartbeat_at
|
240
|
-
started_at
|
241
|
-
docker
|
242
|
-
cuda
|
243
|
-
args
|
244
|
-
state
|
245
|
-
program
|
246
|
-
code_path
|
247
|
-
git
|
248
|
-
email
|
249
|
-
root
|
250
|
-
host
|
251
|
-
username
|
252
|
-
executable
|
253
|
-
code_path_local
|
254
|
-
colab
|
255
|
-
cpu_count
|
256
|
-
cpu_count_logical
|
257
|
-
gpu_type
|
258
|
-
disk
|
259
|
-
memory
|
260
|
-
cpu
|
261
|
-
apple
|
262
|
-
gpu_nvidia
|
263
|
-
gpu_amd
|
264
|
-
slurm
|
265
|
-
cuda_version
|
266
|
-
trainium
|
267
|
-
tpu
|
240
|
+
os: Operating system.
|
241
|
+
python: Python version.
|
242
|
+
heartbeat_at: Timestamp of last heartbeat.
|
243
|
+
started_at: Timestamp of run start.
|
244
|
+
docker: Docker image.
|
245
|
+
cuda: CUDA version.
|
246
|
+
args: Command-line arguments.
|
247
|
+
state: Run state.
|
248
|
+
program: Program name.
|
249
|
+
code_path: Path to code.
|
250
|
+
git: Git repository information.
|
251
|
+
email: Email address.
|
252
|
+
root: Root directory.
|
253
|
+
host: Host name.
|
254
|
+
username: Username.
|
255
|
+
executable: Python executable path.
|
256
|
+
code_path_local: Local code path.
|
257
|
+
colab: Colab URL.
|
258
|
+
cpu_count: CPU count.
|
259
|
+
cpu_count_logical: Logical CPU count.
|
260
|
+
gpu_type: GPU type.
|
261
|
+
disk: Disk information.
|
262
|
+
memory: Memory information.
|
263
|
+
cpu: CPU information.
|
264
|
+
apple: Apple silicon information.
|
265
|
+
gpu_nvidia: NVIDIA GPU information.
|
266
|
+
gpu_amd: AMD GPU information.
|
267
|
+
slurm: Slurm environment information.
|
268
|
+
cuda_version: CUDA version.
|
269
|
+
trainium: Trainium information.
|
270
|
+
tpu: TPU information.
|
271
|
+
|
272
|
+
Examples:
|
273
|
+
Update Run metadata:
|
274
|
+
|
275
|
+
```python
|
276
|
+
with wandb.init(settings=settings) as run:
|
277
|
+
run._metadata.gpu_nvidia = [
|
278
|
+
{
|
279
|
+
"name": "Tesla T4",
|
280
|
+
"memory_total": "16106127360",
|
281
|
+
"cuda_cores": 2560,
|
282
|
+
"architecture": "Turing",
|
283
|
+
},
|
284
|
+
...,
|
285
|
+
]
|
286
|
+
|
287
|
+
run._metadata.gpu_type = "Tesla T4"
|
288
|
+
run._metadata.gpu_count = 42
|
289
|
+
|
290
|
+
run._metadata.tpu = {
|
291
|
+
"name": "v6e",
|
292
|
+
"hbm_gib": 32,
|
293
|
+
"devices_per_chip": 1,
|
294
|
+
"count": 1337,
|
295
|
+
}
|
296
|
+
```
|
268
297
|
"""
|
269
298
|
|
270
299
|
# TODO: Pydantic configuration.
|