wandb 0.19.12rc1__py3-none-win32.whl → 0.20.1__py3-none-win32.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 -2
- wandb/__init__.pyi +3 -6
- wandb/_iterutils.py +26 -7
- wandb/_pydantic/__init__.py +2 -1
- wandb/_pydantic/utils.py +7 -0
- wandb/agents/pyagent.py +9 -15
- wandb/analytics/sentry.py +1 -2
- wandb/apis/attrs.py +3 -4
- wandb/apis/importers/internals/util.py +1 -1
- wandb/apis/importers/validation.py +2 -2
- wandb/apis/importers/wandb.py +30 -25
- wandb/apis/normalize.py +2 -2
- wandb/apis/public/__init__.py +1 -0
- wandb/apis/public/api.py +37 -33
- wandb/apis/public/artifacts.py +103 -72
- wandb/apis/public/jobs.py +3 -2
- wandb/apis/public/registries/registries_search.py +4 -2
- wandb/apis/public/registries/registry.py +1 -1
- wandb/apis/public/registries/utils.py +9 -9
- wandb/apis/public/runs.py +18 -6
- wandb/automations/_filters/expressions.py +1 -1
- wandb/automations/_filters/operators.py +1 -1
- wandb/automations/_filters/run_metrics.py +1 -1
- wandb/beta/workflows.py +6 -5
- wandb/bin/gpu_stats.exe +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +54 -73
- wandb/docker/__init__.py +21 -74
- wandb/docker/names.py +40 -0
- wandb/env.py +0 -1
- wandb/errors/util.py +1 -1
- wandb/filesync/step_checksum.py +1 -1
- wandb/filesync/step_upload.py +1 -1
- wandb/integration/diffusers/resolvers/multimodal.py +1 -2
- wandb/integration/gym/__init__.py +5 -6
- wandb/integration/keras/callbacks/model_checkpoint.py +2 -2
- wandb/integration/keras/keras.py +13 -19
- wandb/integration/kfp/kfp_patch.py +2 -3
- wandb/integration/langchain/wandb_tracer.py +1 -1
- wandb/integration/metaflow/metaflow.py +13 -13
- wandb/integration/openai/fine_tuning.py +3 -2
- wandb/integration/sagemaker/auth.py +2 -1
- wandb/integration/sklearn/utils.py +2 -1
- wandb/integration/tensorboard/__init__.py +1 -1
- wandb/integration/tensorboard/log.py +2 -5
- wandb/integration/tensorflow/__init__.py +2 -2
- wandb/jupyter.py +20 -17
- wandb/plot/confusion_matrix.py +1 -1
- wandb/plot/utils.py +8 -7
- wandb/proto/v3/wandb_internal_pb2.py +355 -335
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v3/wandb_telemetry_pb2.py +12 -12
- wandb/proto/v4/wandb_internal_pb2.py +339 -335
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_telemetry_pb2.py +12 -12
- wandb/proto/v5/wandb_internal_pb2.py +339 -335
- wandb/proto/v5/wandb_settings_pb2.py +2 -2
- wandb/proto/v5/wandb_telemetry_pb2.py +12 -12
- wandb/proto/v6/wandb_internal_pb2.py +339 -335
- wandb/proto/v6/wandb_settings_pb2.py +2 -2
- wandb/proto/v6/wandb_telemetry_pb2.py +12 -12
- wandb/proto/wandb_deprecated.py +6 -8
- wandb/sdk/artifacts/_internal_artifact.py +43 -0
- wandb/sdk/artifacts/_validators.py +55 -35
- wandb/sdk/artifacts/artifact.py +117 -115
- wandb/sdk/artifacts/artifact_download_logger.py +2 -0
- wandb/sdk/artifacts/artifact_saver.py +1 -3
- wandb/sdk/artifacts/artifact_state.py +2 -0
- wandb/sdk/artifacts/artifact_ttl.py +2 -0
- wandb/sdk/artifacts/exceptions.py +14 -0
- wandb/sdk/artifacts/staging.py +2 -0
- wandb/sdk/artifacts/storage_handlers/local_file_handler.py +2 -6
- wandb/sdk/artifacts/storage_handlers/multi_handler.py +1 -1
- wandb/sdk/artifacts/storage_handlers/tracking_handler.py +2 -6
- wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +1 -5
- wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +1 -1
- wandb/sdk/artifacts/storage_layout.py +2 -0
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +3 -3
- wandb/sdk/backend/backend.py +11 -182
- wandb/sdk/data_types/_dtypes.py +2 -6
- wandb/sdk/data_types/audio.py +20 -3
- wandb/sdk/data_types/base_types/media.py +12 -7
- wandb/sdk/data_types/base_types/wb_value.py +8 -18
- wandb/sdk/data_types/bokeh.py +19 -2
- wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +17 -1
- wandb/sdk/data_types/helper_types/image_mask.py +7 -1
- wandb/sdk/data_types/html.py +4 -4
- wandb/sdk/data_types/image.py +178 -103
- wandb/sdk/data_types/molecule.py +6 -6
- wandb/sdk/data_types/object_3d.py +10 -5
- wandb/sdk/data_types/saved_model.py +11 -6
- wandb/sdk/data_types/table.py +313 -83
- wandb/sdk/data_types/table_decorators.py +108 -0
- wandb/sdk/data_types/utils.py +43 -7
- wandb/sdk/data_types/video.py +21 -3
- wandb/sdk/interface/interface.py +10 -0
- wandb/sdk/internal/datastore.py +2 -6
- wandb/sdk/internal/file_pusher.py +1 -5
- wandb/sdk/internal/file_stream.py +8 -17
- wandb/sdk/internal/handler.py +2 -2
- wandb/sdk/internal/incremental_table_util.py +53 -0
- wandb/sdk/internal/internal.py +3 -5
- wandb/sdk/internal/internal_api.py +66 -89
- wandb/sdk/internal/job_builder.py +2 -7
- wandb/sdk/internal/profiler.py +2 -2
- wandb/sdk/internal/progress.py +1 -3
- wandb/sdk/internal/run.py +1 -6
- wandb/sdk/internal/sender.py +24 -36
- wandb/sdk/internal/system/assets/aggregators.py +1 -7
- wandb/sdk/internal/system/assets/disk.py +3 -3
- wandb/sdk/internal/system/assets/gpu.py +4 -4
- wandb/sdk/internal/system/assets/gpu_amd.py +4 -4
- wandb/sdk/internal/system/assets/interfaces.py +6 -6
- wandb/sdk/internal/system/assets/tpu.py +1 -1
- wandb/sdk/internal/system/assets/trainium.py +6 -6
- wandb/sdk/internal/system/system_info.py +5 -7
- wandb/sdk/internal/system/system_monitor.py +4 -4
- wandb/sdk/internal/tb_watcher.py +5 -7
- wandb/sdk/launch/_launch.py +1 -1
- wandb/sdk/launch/_project_spec.py +19 -20
- wandb/sdk/launch/agent/agent.py +3 -3
- wandb/sdk/launch/agent/config.py +1 -1
- wandb/sdk/launch/agent/job_status_tracker.py +2 -2
- wandb/sdk/launch/builder/build.py +2 -3
- wandb/sdk/launch/builder/kaniko_builder.py +5 -4
- wandb/sdk/launch/environment/gcp_environment.py +1 -2
- wandb/sdk/launch/registry/azure_container_registry.py +2 -2
- wandb/sdk/launch/registry/elastic_container_registry.py +2 -2
- wandb/sdk/launch/registry/google_artifact_registry.py +3 -3
- wandb/sdk/launch/runner/abstract.py +5 -5
- wandb/sdk/launch/runner/kubernetes_monitor.py +2 -2
- wandb/sdk/launch/runner/kubernetes_runner.py +1 -1
- wandb/sdk/launch/runner/sagemaker_runner.py +2 -4
- wandb/sdk/launch/runner/vertex_runner.py +2 -7
- wandb/sdk/launch/sweeps/__init__.py +1 -1
- wandb/sdk/launch/sweeps/scheduler.py +2 -2
- wandb/sdk/launch/sweeps/utils.py +3 -3
- wandb/sdk/launch/utils.py +3 -4
- wandb/sdk/lib/apikey.py +5 -8
- wandb/sdk/lib/config_util.py +3 -3
- wandb/sdk/lib/fsm.py +3 -18
- wandb/sdk/lib/gitlib.py +6 -5
- wandb/sdk/lib/ipython.py +2 -2
- wandb/sdk/lib/json_util.py +9 -14
- wandb/sdk/lib/printer.py +3 -8
- wandb/sdk/lib/redirect.py +1 -1
- wandb/sdk/lib/retry.py +3 -7
- wandb/sdk/lib/run_moment.py +2 -2
- wandb/sdk/lib/service_connection.py +3 -1
- wandb/sdk/lib/service_token.py +1 -2
- wandb/sdk/mailbox/mailbox_handle.py +3 -7
- wandb/sdk/mailbox/response_handle.py +2 -6
- wandb/sdk/service/streams.py +3 -7
- wandb/sdk/verify/verify.py +5 -6
- wandb/sdk/wandb_config.py +1 -1
- wandb/sdk/wandb_init.py +38 -106
- wandb/sdk/wandb_login.py +7 -6
- wandb/sdk/wandb_run.py +52 -240
- wandb/sdk/wandb_settings.py +71 -60
- wandb/sdk/wandb_setup.py +40 -14
- wandb/sdk/wandb_watch.py +5 -7
- wandb/sync/__init__.py +1 -1
- wandb/sync/sync.py +13 -13
- wandb/util.py +17 -35
- wandb/wandb_agent.py +8 -11
- {wandb-0.19.12rc1.dist-info → wandb-0.20.1.dist-info}/METADATA +5 -5
- {wandb-0.19.12rc1.dist-info → wandb-0.20.1.dist-info}/RECORD +170 -168
- wandb/docker/auth.py +0 -435
- wandb/docker/www_authenticate.py +0 -94
- {wandb-0.19.12rc1.dist-info → wandb-0.20.1.dist-info}/WHEEL +0 -0
- {wandb-0.19.12rc1.dist-info → wandb-0.20.1.dist-info}/entry_points.txt +0 -0
- {wandb-0.19.12rc1.dist-info → wandb-0.20.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,108 @@
|
|
1
|
+
"""Decorators for W&B Table operations."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from functools import wraps
|
6
|
+
from typing import Any, Callable, TypeVar
|
7
|
+
|
8
|
+
from typing_extensions import Concatenate, ParamSpec
|
9
|
+
|
10
|
+
import wandb
|
11
|
+
|
12
|
+
_P = ParamSpec("_P")
|
13
|
+
_T = TypeVar("_T")
|
14
|
+
|
15
|
+
|
16
|
+
def allow_relogging_after_mutation(
|
17
|
+
method: Callable[Concatenate[wandb.Table, _P], _T],
|
18
|
+
) -> Callable[Concatenate[wandb.Table, _P], _T]:
|
19
|
+
"""Decorator that handles table state after mutations based on log_mode.
|
20
|
+
|
21
|
+
For MUTABLE tables, resets the run and artifact target to allow re-logging.
|
22
|
+
For IMMUTABLE tables, warns if attempting to mutate after logging.
|
23
|
+
"""
|
24
|
+
|
25
|
+
@wraps(method)
|
26
|
+
def wrapper(self: wandb.Table, *args: Any, **kwargs: Any) -> _T:
|
27
|
+
has_been_logged = self._run is not None or self._artifact_target is not None
|
28
|
+
|
29
|
+
if self.log_mode == "MUTABLE":
|
30
|
+
self._run = None
|
31
|
+
self._artifact_target = None
|
32
|
+
self._path = None
|
33
|
+
self._sha256 = None
|
34
|
+
elif self.log_mode == "IMMUTABLE" and has_been_logged:
|
35
|
+
wandb.termwarn(
|
36
|
+
"You are mutating a Table with log_mode='IMMUTABLE' that has been "
|
37
|
+
"logged already. Subsequent log() calls will have no effect. "
|
38
|
+
"Set log_mode='MUTABLE' to enable re-logging after mutations",
|
39
|
+
repeat=False,
|
40
|
+
)
|
41
|
+
|
42
|
+
return method(self, *args, **kwargs)
|
43
|
+
|
44
|
+
return wrapper
|
45
|
+
|
46
|
+
|
47
|
+
def allow_incremental_logging_after_append(
|
48
|
+
method: Callable[Concatenate[wandb.Table, _P], _T],
|
49
|
+
) -> Callable[Concatenate[wandb.Table, _P], _T]:
|
50
|
+
"""Decorator that handles incremental logging state after append operations.
|
51
|
+
|
52
|
+
For INCREMENTAL tables, manages artifact references and increments counters
|
53
|
+
to support partial data logging.
|
54
|
+
"""
|
55
|
+
|
56
|
+
@wraps(method)
|
57
|
+
def wrapper(self: wandb.Table, *args: Any, **kwargs: Any) -> _T:
|
58
|
+
res = method(self, *args, **kwargs)
|
59
|
+
|
60
|
+
if self.log_mode != "INCREMENTAL" or self._artifact_target is None:
|
61
|
+
return res
|
62
|
+
|
63
|
+
art_entry_url = self._get_artifact_entry_ref_url()
|
64
|
+
if art_entry_url is not None:
|
65
|
+
if self._previous_increments_paths is None:
|
66
|
+
raise ValueError(
|
67
|
+
"_previous_increments_paths must be set if incremental"
|
68
|
+
" table has been logged already"
|
69
|
+
)
|
70
|
+
self._previous_increments_paths.append(art_entry_url)
|
71
|
+
self._run = None
|
72
|
+
self._artifact_target = None
|
73
|
+
self._path = None
|
74
|
+
self._sha256 = None
|
75
|
+
|
76
|
+
if self._increment_num is None:
|
77
|
+
raise ValueError(
|
78
|
+
"_increment_num must be set if incremental table has been"
|
79
|
+
" logged already"
|
80
|
+
)
|
81
|
+
|
82
|
+
self._increment_num += 1
|
83
|
+
if self._increment_num > 99:
|
84
|
+
wandb.termwarn(
|
85
|
+
"You have exceeded 100 increments for this table. "
|
86
|
+
"Only the latest 100 increments will be visualized in the run workspace.",
|
87
|
+
repeat=False,
|
88
|
+
)
|
89
|
+
return res
|
90
|
+
|
91
|
+
return wrapper
|
92
|
+
|
93
|
+
|
94
|
+
def ensure_not_incremental(
|
95
|
+
method: Callable[Concatenate[wandb.Table, _P], _T],
|
96
|
+
) -> Callable[Concatenate[wandb.Table, _P], _T]:
|
97
|
+
"""Decorator that checks if log mode is incremental to disallow methods from being called."""
|
98
|
+
|
99
|
+
@wraps(method)
|
100
|
+
def wrapper(self: wandb.Table, *args: Any, **kwargs: Any) -> _T:
|
101
|
+
if self.log_mode == "INCREMENTAL":
|
102
|
+
raise wandb.Error(
|
103
|
+
f"Operation '{method.__name__}' is not supported for tables with "
|
104
|
+
"log_mode='INCREMENTAL'. Use a different log mode like 'MUTABLE' or 'IMMUTABLE'."
|
105
|
+
)
|
106
|
+
return method(self, *args, **kwargs)
|
107
|
+
|
108
|
+
return wrapper
|
wandb/sdk/data_types/utils.py
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
import datetime
|
2
2
|
import logging
|
3
3
|
import os
|
4
|
-
import re
|
5
4
|
from decimal import Decimal
|
6
5
|
from typing import TYPE_CHECKING, Optional, Sequence, Union, cast
|
7
6
|
|
8
7
|
import wandb
|
9
8
|
from wandb import util
|
10
9
|
|
10
|
+
from ..internal import incremental_table_util
|
11
11
|
from .base_types.media import BatchableMedia, Media
|
12
12
|
from .base_types.wb_value import WBValue
|
13
13
|
from .image import _server_accepts_image_filenames
|
@@ -148,11 +148,7 @@ def val_to_json(
|
|
148
148
|
"partitioned-table",
|
149
149
|
"joined-table",
|
150
150
|
]:
|
151
|
-
|
152
|
-
sanitized_key = re.sub(r"[^a-zA-Z0-9_\-.]+", "", key)
|
153
|
-
art = wandb.Artifact(f"run-{run.id}-{sanitized_key}", "run_table")
|
154
|
-
art.add(val, key)
|
155
|
-
run.log_artifact(art)
|
151
|
+
_log_table_artifact(val, key, run)
|
156
152
|
|
157
153
|
# Partitioned tables and joined tables do not support being bound to runs.
|
158
154
|
if not (
|
@@ -161,11 +157,51 @@ def val_to_json(
|
|
161
157
|
):
|
162
158
|
val.bind_to_run(run, key, namespace)
|
163
159
|
|
164
|
-
|
160
|
+
res = val.to_json(run)
|
161
|
+
|
162
|
+
if isinstance(val, wandb.Table) and val.log_mode == "INCREMENTAL":
|
163
|
+
# Set the _last_logged_idx AFTER the Table has been logged and
|
164
|
+
# bound to the run.
|
165
|
+
val._last_logged_idx = len(val.data) - 1
|
166
|
+
return res
|
165
167
|
|
166
168
|
return converted # type: ignore
|
167
169
|
|
168
170
|
|
171
|
+
def _log_table_artifact(val: "Media", key: str, run: "LocalRun") -> None:
|
172
|
+
"""Log a table to the run based on the table type and logging mode.
|
173
|
+
|
174
|
+
Creates and logs a `run_table` type for Table, PartitionedTable, and
|
175
|
+
JoinedTable values. For tables with log_mode="INCREMENTAL", creates and
|
176
|
+
logs an incremental artifact of type `wandb-run-incremental-table.`
|
177
|
+
|
178
|
+
Args:
|
179
|
+
val: A wbvalue with log_type "table", "partitioned-table",
|
180
|
+
or "joined-table."
|
181
|
+
key: The key used to log val.
|
182
|
+
run: The LocalRun used to log val.
|
183
|
+
"""
|
184
|
+
from wandb.sdk.artifacts._internal_artifact import InternalArtifact
|
185
|
+
|
186
|
+
if isinstance(val, wandb.Table) and val.log_mode == "INCREMENTAL":
|
187
|
+
if (
|
188
|
+
run.resumed
|
189
|
+
and val._previous_increments_paths is None
|
190
|
+
and val._increment_num is None
|
191
|
+
):
|
192
|
+
val._load_incremental_table_state_from_resumed_run(run, key)
|
193
|
+
else:
|
194
|
+
val._set_incremental_table_run_target(run)
|
195
|
+
art = incremental_table_util.init_artifact(run, key)
|
196
|
+
entry_name = incremental_table_util.get_entry_name(val, key)
|
197
|
+
else:
|
198
|
+
art = InternalArtifact(f"run-{run.id}-{key}", "run_table")
|
199
|
+
entry_name = key
|
200
|
+
|
201
|
+
art.add(val, entry_name)
|
202
|
+
run.log_artifact(art)
|
203
|
+
|
204
|
+
|
169
205
|
def _prune_max_seq(seq: Sequence["BatchableMedia"]) -> Sequence["BatchableMedia"]:
|
170
206
|
# If media type has a max respect it
|
171
207
|
items = seq
|
wandb/sdk/data_types/video.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import functools
|
2
2
|
import logging
|
3
3
|
import os
|
4
|
+
import pathlib
|
4
5
|
from io import BytesIO
|
5
6
|
from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, Type, Union
|
6
7
|
|
@@ -34,12 +35,26 @@ if TYPE_CHECKING: # pragma: no cover
|
|
34
35
|
def write_gif_with_image_io(
|
35
36
|
clip: Any, filename: str, fps: Optional[int] = None
|
36
37
|
) -> None:
|
38
|
+
from packaging.version import parse
|
39
|
+
|
37
40
|
imageio = util.get_module(
|
38
41
|
"imageio",
|
39
42
|
required='wandb.Video requires imageio when passing raw data. Install with "pip install wandb[media]"',
|
40
43
|
)
|
41
44
|
|
42
|
-
|
45
|
+
if parse(imageio.__version__) < parse("2.28.1"):
|
46
|
+
raise ValueError(
|
47
|
+
"imageio version 2.28.1 or higher is required to encode gifs. "
|
48
|
+
"Please upgrade imageio with `pip install imageio>=2.28.1`"
|
49
|
+
)
|
50
|
+
|
51
|
+
writer = imageio.save(
|
52
|
+
filename,
|
53
|
+
quantizer=0,
|
54
|
+
palettesize=256,
|
55
|
+
loop=0,
|
56
|
+
duration=1000 / clip.fps,
|
57
|
+
)
|
43
58
|
|
44
59
|
for frame in clip.iter_frames(fps=fps, dtype="uint8"):
|
45
60
|
writer.append_data(frame)
|
@@ -57,7 +72,7 @@ class Video(BatchableMedia):
|
|
57
72
|
|
58
73
|
def __init__(
|
59
74
|
self,
|
60
|
-
data_or_path: Union["np.ndarray",
|
75
|
+
data_or_path: Union[str, pathlib.Path, "np.ndarray", "TextIO", "BytesIO"],
|
61
76
|
caption: Optional[str] = None,
|
62
77
|
fps: Optional[int] = None,
|
63
78
|
format: Optional[Literal["gif", "mp4", "webm", "ogg"]] = None,
|
@@ -84,6 +99,7 @@ class Video(BatchableMedia):
|
|
84
99
|
or io object. This parameter will be used to determine the format
|
85
100
|
to use when encoding the video data. Accepted values are "gif",
|
86
101
|
"mp4", "webm", or "ogg".
|
102
|
+
If no value is provided, the default format will be "gif".
|
87
103
|
|
88
104
|
Examples:
|
89
105
|
### Log a numpy array as a video
|
@@ -130,7 +146,9 @@ class Video(BatchableMedia):
|
|
130
146
|
with open(filename, "wb") as f:
|
131
147
|
f.write(data_or_path.read())
|
132
148
|
self._set_file(filename, is_tmp=True)
|
133
|
-
elif isinstance(data_or_path, str):
|
149
|
+
elif isinstance(data_or_path, (str, pathlib.Path)):
|
150
|
+
data_or_path = str(data_or_path)
|
151
|
+
|
134
152
|
_, ext = os.path.splitext(data_or_path)
|
135
153
|
ext = ext[1:].lower()
|
136
154
|
if ext not in Video.EXTS:
|
wandb/sdk/interface/interface.py
CHANGED
@@ -166,6 +166,16 @@ class InterfaceBase:
|
|
166
166
|
proto_run.host = run._settings.host
|
167
167
|
if run._settings.resumed:
|
168
168
|
proto_run.resumed = run._settings.resumed
|
169
|
+
if run._settings.fork_from:
|
170
|
+
run_moment = run._settings.fork_from
|
171
|
+
proto_run.branch_point.run = run_moment.run
|
172
|
+
proto_run.branch_point.metric = run_moment.metric
|
173
|
+
proto_run.branch_point.value = run_moment.value
|
174
|
+
if run._settings.resume_from:
|
175
|
+
run_moment = run._settings.resume_from
|
176
|
+
proto_run.branch_point.run = run_moment.run
|
177
|
+
proto_run.branch_point.metric = run_moment.metric
|
178
|
+
proto_run.branch_point.value = run_moment.value
|
169
179
|
if run._forked:
|
170
180
|
proto_run.forked = run._forked
|
171
181
|
if run._config is not None:
|
wandb/sdk/internal/datastore.py
CHANGED
@@ -126,9 +126,7 @@ class DataStore:
|
|
126
126
|
return None
|
127
127
|
assert (
|
128
128
|
len(header) == LEVELDBLOG_HEADER_LEN
|
129
|
-
), "record header is {} bytes instead of the expected {}"
|
130
|
-
len(header), LEVELDBLOG_HEADER_LEN
|
131
|
-
)
|
129
|
+
), f"record header is {len(header)} bytes instead of the expected {LEVELDBLOG_HEADER_LEN}"
|
132
130
|
fields = struct.unpack("<IHB", header)
|
133
131
|
checksum, dlength, dtype = fields
|
134
132
|
# check len, better fit in the block
|
@@ -195,9 +193,7 @@ class DataStore:
|
|
195
193
|
header = self._fp.read(LEVELDBLOG_HEADER_LEN)
|
196
194
|
assert (
|
197
195
|
len(header) == LEVELDBLOG_HEADER_LEN
|
198
|
-
), "header is {} bytes instead of the expected {}"
|
199
|
-
len(header), LEVELDBLOG_HEADER_LEN
|
200
|
-
)
|
196
|
+
), f"header is {len(header)} bytes instead of the expected {LEVELDBLOG_HEADER_LEN}"
|
201
197
|
ident, magic, version = struct.unpack("<4sHB", header)
|
202
198
|
if ident != strtobytes(LEVELDBLOG_HEADER_IDENT):
|
203
199
|
raise Exception("Invalid header")
|
@@ -98,11 +98,7 @@ class FilePusher:
|
|
98
98
|
if not self.is_alive():
|
99
99
|
stop = True
|
100
100
|
summary = self._stats.summary()
|
101
|
-
line = " {:.2f}MB of {:.2f}MB uploaded ({:.2f}MB deduped)\r"
|
102
|
-
summary.uploaded_bytes / 1048576.0,
|
103
|
-
summary.total_bytes / 1048576.0,
|
104
|
-
summary.deduped_bytes / 1048576.0,
|
105
|
-
)
|
101
|
+
line = f" {summary.uploaded_bytes / 1048576.0:.2f}MB of {summary.total_bytes / 1048576.0:.2f}MB uploaded ({summary.deduped_bytes / 1048576.0:.2f}MB deduped)\r"
|
106
102
|
line = spinner_states[step % 4] + line
|
107
103
|
step += 1
|
108
104
|
wandb.termlog(line, newline=False, prefix=prefix)
|
@@ -75,7 +75,7 @@ class DefaultFilePolicy:
|
|
75
75
|
|
76
76
|
# get key size and convert to MB
|
77
77
|
key_sizes = [(k, len(json.dumps(v))) for k, v in loaded.items()]
|
78
|
-
key_msg = [f"{k}: {v/1048576:.5f} MB" for k, v in key_sizes]
|
78
|
+
key_msg = [f"{k}: {v / 1048576:.5f} MB" for k, v in key_sizes]
|
79
79
|
wandb.termerror(f"Step: {loaded['_step']} | {key_msg}", repeat=False)
|
80
80
|
self.has_debug_log = True
|
81
81
|
|
@@ -88,10 +88,7 @@ class JsonlFilePolicy(DefaultFilePolicy):
|
|
88
88
|
chunk_data = []
|
89
89
|
for chunk in chunks:
|
90
90
|
if len(chunk.data) > util.MAX_LINE_BYTES:
|
91
|
-
msg = "Metric data exceeds maximum size of {} ({})"
|
92
|
-
util.to_human_size(util.MAX_LINE_BYTES),
|
93
|
-
util.to_human_size(len(chunk.data)),
|
94
|
-
)
|
91
|
+
msg = f"Metric data exceeds maximum size of {util.to_human_size(util.MAX_LINE_BYTES)} ({util.to_human_size(len(chunk.data))})"
|
95
92
|
wandb.termerror(msg, repeat=False)
|
96
93
|
wandb._sentry.message(msg, repeat=False)
|
97
94
|
self._debug_log(chunk.data)
|
@@ -108,9 +105,7 @@ class SummaryFilePolicy(DefaultFilePolicy):
|
|
108
105
|
def process_chunks(self, chunks: List[Chunk]) -> Union[bool, "ProcessedChunk"]:
|
109
106
|
data = chunks[-1].data
|
110
107
|
if len(data) > util.MAX_LINE_BYTES:
|
111
|
-
msg = "Summary data exceeds maximum size of {}. Dropping it."
|
112
|
-
util.to_human_size(util.MAX_LINE_BYTES)
|
113
|
-
)
|
108
|
+
msg = f"Summary data exceeds maximum size of {util.to_human_size(util.MAX_LINE_BYTES)}. Dropping it."
|
114
109
|
wandb.termerror(msg, repeat=False)
|
115
110
|
wandb._sentry.message(msg, repeat=False)
|
116
111
|
self._debug_log(data)
|
@@ -494,12 +489,12 @@ class FileStreamApi:
|
|
494
489
|
# TODO: Consolidate with internal_util.ExceptionThread
|
495
490
|
try:
|
496
491
|
self._thread_body()
|
497
|
-
except Exception
|
492
|
+
except Exception:
|
498
493
|
exc_info = sys.exc_info()
|
499
494
|
self._exc_info = exc_info
|
500
495
|
logger.exception("generic exception in filestream thread")
|
501
496
|
wandb._sentry.exception(exc_info)
|
502
|
-
raise
|
497
|
+
raise
|
503
498
|
|
504
499
|
def _handle_response(self, response: Union[Exception, "requests.Response"]) -> None:
|
505
500
|
"""Log dropped chunks and updates dynamic settings."""
|
@@ -507,7 +502,7 @@ class FileStreamApi:
|
|
507
502
|
wandb.termerror(
|
508
503
|
"Dropped streaming file chunk (see wandb/debug-internal.log)"
|
509
504
|
)
|
510
|
-
logger.exception("dropped chunk {}"
|
505
|
+
logger.exception(f"dropped chunk {response}")
|
511
506
|
self._dropped_chunks += 1
|
512
507
|
else:
|
513
508
|
parsed: Optional[dict] = None
|
@@ -664,8 +659,7 @@ def request_with_retry(
|
|
664
659
|
e.response is not None and e.response.status_code == 429
|
665
660
|
):
|
666
661
|
err_str = (
|
667
|
-
"Filestream rate limit exceeded, "
|
668
|
-
f"retrying in {delay:.1f} seconds. "
|
662
|
+
f"Filestream rate limit exceeded, retrying in {delay:.1f} seconds. "
|
669
663
|
)
|
670
664
|
if retry_callback:
|
671
665
|
retry_callback(e.response.status_code, err_str)
|
@@ -688,8 +682,5 @@ def request_with_retry(
|
|
688
682
|
error_message = response.json()["error"] # todo: clean this up
|
689
683
|
except Exception:
|
690
684
|
pass
|
691
|
-
logger.
|
692
|
-
logger.exception(
|
693
|
-
"requests_with_retry encountered unretryable exception: %s", e
|
694
|
-
)
|
685
|
+
logger.exception(f"requests_with_retry error: {error_message}")
|
695
686
|
return e
|
wandb/sdk/internal/handler.py
CHANGED
@@ -704,8 +704,8 @@ class HandleManager:
|
|
704
704
|
):
|
705
705
|
try:
|
706
706
|
self._metadata = Metadata(**self._system_monitor.probe(publish=True))
|
707
|
-
except Exception
|
708
|
-
logger.
|
707
|
+
except Exception:
|
708
|
+
logger.exception("Error probing system metadata.")
|
709
709
|
|
710
710
|
self._tb_watcher = tb_watcher.TBWatcher(
|
711
711
|
self._settings, interface=self._interface, run_proto=run_start.run
|
@@ -0,0 +1,53 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import time
|
4
|
+
from typing import TYPE_CHECKING
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from wandb import Table
|
8
|
+
from wandb.sdk.artifacts.artifact import Artifact
|
9
|
+
|
10
|
+
from ..wandb_run import Run as LocalRun
|
11
|
+
|
12
|
+
ART_TYPE = "wandb-run-incremental-table"
|
13
|
+
|
14
|
+
|
15
|
+
def _get_artifact_name(run: LocalRun, key: str) -> str:
|
16
|
+
from wandb.sdk.artifacts._internal_artifact import sanitize_artifact_name
|
17
|
+
|
18
|
+
return sanitize_artifact_name(f"run-{run.id}-incr-{key}")
|
19
|
+
|
20
|
+
|
21
|
+
def init_artifact(run: LocalRun, sanitized_key: str) -> Artifact:
|
22
|
+
"""Initialize a new artifact for an incremental table.
|
23
|
+
|
24
|
+
Args:
|
25
|
+
run: The wandb run associated with this artifact
|
26
|
+
sanitized_key: Sanitized string key to identify the table
|
27
|
+
|
28
|
+
Returns:
|
29
|
+
A wandb Artifact configured for incremental table storage
|
30
|
+
"""
|
31
|
+
from wandb.sdk.artifacts._internal_artifact import InternalArtifact
|
32
|
+
|
33
|
+
artifact = InternalArtifact(
|
34
|
+
_get_artifact_name(run, sanitized_key),
|
35
|
+
ART_TYPE,
|
36
|
+
incremental=True,
|
37
|
+
)
|
38
|
+
return artifact
|
39
|
+
|
40
|
+
|
41
|
+
def get_entry_name(incr_table: Table, key: str) -> str:
|
42
|
+
"""Generate a unique entry name for a table increment.
|
43
|
+
|
44
|
+
Args:
|
45
|
+
run: The wandb run associated with this table
|
46
|
+
incr_table: The incremental table being updated
|
47
|
+
key: String key for the table entry
|
48
|
+
|
49
|
+
Returns:
|
50
|
+
A unique string name for the table entry
|
51
|
+
"""
|
52
|
+
epoch = time.time_ns() // 1_000_000
|
53
|
+
return f"{incr_table._increment_num}-{epoch}.{key}"
|
wandb/sdk/internal/internal.py
CHANGED
@@ -169,11 +169,9 @@ def wandb_internal(
|
|
169
169
|
traceback.print_exception(*exc_info)
|
170
170
|
wandb._sentry.exception(exc_info)
|
171
171
|
wandb.termerror("Internal wandb error: file data was not synced")
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
os._exit(-1)
|
176
|
-
sys.exit(-1)
|
172
|
+
# TODO: We can make this more graceful by returning an error to streams.py
|
173
|
+
# and potentially just fail the one stream.
|
174
|
+
os._exit(-1)
|
177
175
|
|
178
176
|
close_internal_log()
|
179
177
|
|