wandb 0.17.4__py3-none-win32.whl → 0.17.6__py3-none-win32.whl
Sign up to get free protection for your applications and to get access to all the features.
- wandb/__init__.py +3 -1
- wandb/apis/public/api.py +1 -1
- wandb/apis/public/jobs.py +5 -0
- wandb/bin/wandb-core +0 -0
- wandb/data_types.py +2 -1
- wandb/env.py +6 -0
- wandb/filesync/upload_job.py +1 -1
- wandb/integration/lightning/fabric/logger.py +4 -4
- wandb/proto/v3/wandb_internal_pb2.py +339 -328
- wandb/proto/v3/wandb_settings_pb2.py +1 -1
- wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v4/wandb_internal_pb2.py +326 -323
- wandb/proto/v4/wandb_settings_pb2.py +1 -1
- wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v5/wandb_internal_pb2.py +326 -323
- wandb/proto/v5/wandb_settings_pb2.py +1 -1
- wandb/proto/v5/wandb_telemetry_pb2.py +10 -10
- wandb/proto/wandb_deprecated.py +4 -0
- wandb/proto/wandb_internal_pb2.py +6 -0
- wandb/sdk/artifacts/artifact.py +16 -24
- wandb/sdk/artifacts/artifact_manifest_entry.py +31 -0
- wandb/sdk/artifacts/storage_handlers/azure_handler.py +35 -23
- wandb/sdk/data_types/object_3d.py +113 -2
- wandb/sdk/interface/interface.py +35 -5
- wandb/sdk/interface/interface_shared.py +9 -7
- wandb/sdk/internal/handler.py +1 -1
- wandb/sdk/internal/internal_api.py +4 -4
- wandb/sdk/internal/sender.py +40 -17
- wandb/sdk/launch/_launch.py +4 -2
- wandb/sdk/launch/_project_spec.py +34 -8
- wandb/sdk/launch/agent/agent.py +6 -2
- wandb/sdk/launch/agent/run_queue_item_file_saver.py +2 -4
- wandb/sdk/launch/builder/build.py +4 -2
- wandb/sdk/launch/builder/kaniko_builder.py +30 -9
- wandb/sdk/launch/builder/templates/_wandb_bootstrap.py +2 -1
- wandb/sdk/launch/inputs/internal.py +93 -2
- wandb/sdk/launch/inputs/manage.py +21 -3
- wandb/sdk/launch/inputs/schema.py +39 -0
- wandb/sdk/launch/runner/kubernetes_runner.py +72 -0
- wandb/sdk/launch/runner/local_container.py +13 -10
- wandb/sdk/launch/runner/sagemaker_runner.py +3 -5
- wandb/sdk/launch/utils.py +2 -0
- wandb/sdk/lib/disabled.py +13 -174
- wandb/sdk/lib/tracelog.py +2 -2
- wandb/sdk/wandb_init.py +23 -27
- wandb/sdk/wandb_login.py +6 -6
- wandb/sdk/wandb_manager.py +9 -5
- wandb/sdk/wandb_run.py +141 -97
- wandb/sdk/wandb_settings.py +3 -2
- wandb/util.py +29 -11
- wandb/wandb_agent.py +2 -0
- {wandb-0.17.4.dist-info → wandb-0.17.6.dist-info}/METADATA +3 -2
- {wandb-0.17.4.dist-info → wandb-0.17.6.dist-info}/RECORD +56 -55
- {wandb-0.17.4.dist-info → wandb-0.17.6.dist-info}/WHEEL +0 -0
- {wandb-0.17.4.dist-info → wandb-0.17.6.dist-info}/entry_points.txt +0 -0
- {wandb-0.17.4.dist-info → wandb-0.17.6.dist-info}/licenses/LICENSE +0 -0
@@ -1,12 +1,13 @@
|
|
1
1
|
"""Functions for declaring overridable configuration for launch jobs."""
|
2
2
|
|
3
|
-
from typing import List, Optional
|
3
|
+
from typing import Any, List, Optional
|
4
4
|
|
5
5
|
|
6
6
|
def manage_config_file(
|
7
7
|
path: str,
|
8
8
|
include: Optional[List[str]] = None,
|
9
9
|
exclude: Optional[List[str]] = None,
|
10
|
+
schema: Optional[Any] = None,
|
10
11
|
):
|
11
12
|
r"""Declare an overridable configuration file for a launch job.
|
12
13
|
|
@@ -43,18 +44,27 @@ def manage_config_file(
|
|
43
44
|
relative and must not contain backwards traversal, i.e. `..`.
|
44
45
|
include (List[str]): A list of keys to include in the configuration file.
|
45
46
|
exclude (List[str]): A list of keys to exclude from the configuration file.
|
47
|
+
schema (dict | Pydantic model): A JSON Schema or Pydantic model describing
|
48
|
+
describing which attributes will be editable from the Launch drawer.
|
49
|
+
Accepts both an instance of a Pydantic BaseModel class or the BaseModel
|
50
|
+
class itself.
|
46
51
|
|
47
52
|
Raises:
|
48
53
|
LaunchError: If the path is not valid, or if there is no active run.
|
49
54
|
"""
|
55
|
+
# note: schema's Any type is because in the case where a BaseModel class is
|
56
|
+
# provided, its type is a pydantic internal type that we don't want our typing
|
57
|
+
# to depend on. schema's type should be considered
|
58
|
+
# "Optional[dict | <something with a .model_json_schema() method>]"
|
50
59
|
from .internal import handle_config_file_input
|
51
60
|
|
52
|
-
return handle_config_file_input(path, include, exclude)
|
61
|
+
return handle_config_file_input(path, include, exclude, schema)
|
53
62
|
|
54
63
|
|
55
64
|
def manage_wandb_config(
|
56
65
|
include: Optional[List[str]] = None,
|
57
66
|
exclude: Optional[List[str]] = None,
|
67
|
+
schema: Optional[Any] = None,
|
58
68
|
):
|
59
69
|
r"""Declare wandb.config as an overridable configuration for a launch job.
|
60
70
|
|
@@ -86,10 +96,18 @@ def manage_wandb_config(
|
|
86
96
|
Args:
|
87
97
|
include (List[str]): A list of subtrees to include in the configuration.
|
88
98
|
exclude (List[str]): A list of subtrees to exclude from the configuration.
|
99
|
+
schema (dict | Pydantic model): A JSON Schema or Pydantic model describing
|
100
|
+
describing which attributes will be editable from the Launch drawer.
|
101
|
+
Accepts both an instance of a Pydantic BaseModel class or the BaseModel
|
102
|
+
class itself.
|
89
103
|
|
90
104
|
Raises:
|
91
105
|
LaunchError: If there is no active run.
|
92
106
|
"""
|
107
|
+
# note: schema's Any type is because in the case where a BaseModel class is
|
108
|
+
# provided, its type is a pydantic internal type that we don't want our typing
|
109
|
+
# to depend on. schema's type should be considered
|
110
|
+
# "Optional[dict | <something with a .model_json_schema() method>]"
|
93
111
|
from .internal import handle_run_config_input
|
94
112
|
|
95
|
-
handle_run_config_input(include, exclude)
|
113
|
+
handle_run_config_input(include, exclude, schema)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
META_SCHEMA = {
|
2
|
+
"type": "object",
|
3
|
+
"properties": {
|
4
|
+
"type": {
|
5
|
+
"type": "string",
|
6
|
+
"enum": ["boolean", "integer", "number", "string", "object"],
|
7
|
+
},
|
8
|
+
"title": {"type": "string"},
|
9
|
+
"description": {"type": "string"},
|
10
|
+
"enum": {"type": "array", "items": {"type": ["integer", "number", "string"]}},
|
11
|
+
"properties": {"type": "object", "patternProperties": {".*": {"$ref": "#"}}},
|
12
|
+
"allOf": {"type": "array", "items": {"$ref": "#"}},
|
13
|
+
},
|
14
|
+
"allOf": [
|
15
|
+
{
|
16
|
+
"if": {"properties": {"type": {"const": "number"}}},
|
17
|
+
"then": {
|
18
|
+
"properties": {
|
19
|
+
"minimum": {"type": ["integer", "number"]},
|
20
|
+
"maximum": {"type": ["integer", "number"]},
|
21
|
+
"exclusiveMinimum": {"type": ["integer", "number"]},
|
22
|
+
"exclusiveMaximum": {"type": ["integer", "number"]},
|
23
|
+
}
|
24
|
+
},
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"if": {"properties": {"type": {"const": "integer"}}},
|
28
|
+
"then": {
|
29
|
+
"properties": {
|
30
|
+
"minimum": {"type": "integer"},
|
31
|
+
"maximum": {"type": "integer"},
|
32
|
+
"exclusiveMinimum": {"type": "integer"},
|
33
|
+
"exclusiveMaximum": {"type": "integer"},
|
34
|
+
}
|
35
|
+
},
|
36
|
+
},
|
37
|
+
],
|
38
|
+
"unevaluatedProperties": False,
|
39
|
+
}
|
@@ -31,6 +31,7 @@ from wandb.util import get_module
|
|
31
31
|
from .._project_spec import EntryPoint, LaunchProject
|
32
32
|
from ..errors import LaunchError
|
33
33
|
from ..utils import (
|
34
|
+
CODE_MOUNT_DIR,
|
34
35
|
LOG_PREFIX,
|
35
36
|
MAX_ENV_LENGTHS,
|
36
37
|
PROJECT_SYNCHRONOUS,
|
@@ -66,6 +67,10 @@ API_KEY_SECRET_MAX_RETRIES = 5
|
|
66
67
|
_logger = logging.getLogger(__name__)
|
67
68
|
|
68
69
|
|
70
|
+
SOURCE_CODE_PVC_MOUNT_PATH = os.environ.get("WANDB_LAUNCH_CODE_PVC_MOUNT_PATH")
|
71
|
+
SOURCE_CODE_PVC_NAME = os.environ.get("WANDB_LAUNCH_CODE_PVC_NAME")
|
72
|
+
|
73
|
+
|
69
74
|
class KubernetesSubmittedRun(AbstractRun):
|
70
75
|
"""Wrapper for a launched run on Kubernetes."""
|
71
76
|
|
@@ -468,6 +473,12 @@ class KubernetesRunner(AbstractRunner):
|
|
468
473
|
"true",
|
469
474
|
)
|
470
475
|
|
476
|
+
if launch_project.job_base_image:
|
477
|
+
apply_code_mount_configuration(
|
478
|
+
job,
|
479
|
+
launch_project,
|
480
|
+
)
|
481
|
+
|
471
482
|
# Add wandb.ai/agent: current agent label on all pods
|
472
483
|
if LaunchAgent.initialized():
|
473
484
|
add_label_to_pods(
|
@@ -504,6 +515,22 @@ class KubernetesRunner(AbstractRunner):
|
|
504
515
|
kubernetes_asyncio, resource_args
|
505
516
|
)
|
506
517
|
|
518
|
+
# If using pvc for code mount, move code there.
|
519
|
+
if launch_project.job_base_image is not None:
|
520
|
+
if SOURCE_CODE_PVC_NAME is None or SOURCE_CODE_PVC_MOUNT_PATH is None:
|
521
|
+
raise LaunchError(
|
522
|
+
"WANDB_LAUNCH_SOURCE_CODE_PVC_ environment variables not set. "
|
523
|
+
"Unable to mount source code PVC into base image. "
|
524
|
+
"Use the `codeMountPvcName` variable in the agent helm chart "
|
525
|
+
"to enable base image jobs for this agent. See "
|
526
|
+
"https://github.com/wandb/helm-charts/tree/main/charts/launch-agent "
|
527
|
+
"for more information."
|
528
|
+
)
|
529
|
+
code_subdir = launch_project.get_image_source_string()
|
530
|
+
launch_project.change_project_dir(
|
531
|
+
os.path.join(SOURCE_CODE_PVC_MOUNT_PATH, code_subdir)
|
532
|
+
)
|
533
|
+
|
507
534
|
# If the user specified an alternate api, we need will execute this
|
508
535
|
# run by creating a custom object.
|
509
536
|
api_version = resource_args.get("apiVersion", "batch/v1")
|
@@ -542,6 +569,9 @@ class KubernetesRunner(AbstractRunner):
|
|
542
569
|
LaunchAgent.name()
|
543
570
|
)
|
544
571
|
|
572
|
+
if launch_project.job_base_image:
|
573
|
+
apply_code_mount_configuration(resource_args, launch_project)
|
574
|
+
|
545
575
|
overrides = {}
|
546
576
|
if launch_project.override_args:
|
547
577
|
overrides["args"] = launch_project.override_args
|
@@ -889,3 +919,45 @@ def add_entrypoint_args_overrides(manifest: Union[dict, list], overrides: dict)
|
|
889
919
|
container["args"] = overrides["args"]
|
890
920
|
for value in manifest.values():
|
891
921
|
add_entrypoint_args_overrides(value, overrides)
|
922
|
+
|
923
|
+
|
924
|
+
def apply_code_mount_configuration(
|
925
|
+
manifest: Union[Dict, list], project: LaunchProject
|
926
|
+
) -> None:
|
927
|
+
"""Apply code mount configuration to all containers in a manifest.
|
928
|
+
|
929
|
+
Recursively traverses the manifest and adds the code mount configuration to
|
930
|
+
all containers. Containers are identified by the presence of a "spec" key
|
931
|
+
with a "containers" key in the value.
|
932
|
+
|
933
|
+
Arguments:
|
934
|
+
manifest: The manifest to modify.
|
935
|
+
project: The launch project.
|
936
|
+
|
937
|
+
Returns: None.
|
938
|
+
"""
|
939
|
+
assert SOURCE_CODE_PVC_NAME is not None
|
940
|
+
source_dir = project.get_image_source_string()
|
941
|
+
for pod in yield_pods(manifest):
|
942
|
+
for container in yield_containers(pod):
|
943
|
+
if "volumeMounts" not in container:
|
944
|
+
container["volumeMounts"] = []
|
945
|
+
container["volumeMounts"].append(
|
946
|
+
{
|
947
|
+
"name": "wandb-source-code-volume",
|
948
|
+
"mountPath": CODE_MOUNT_DIR,
|
949
|
+
"subPath": source_dir,
|
950
|
+
}
|
951
|
+
)
|
952
|
+
container["workingDir"] = CODE_MOUNT_DIR
|
953
|
+
spec = pod["spec"]
|
954
|
+
if "volumes" not in spec:
|
955
|
+
spec["volumes"] = []
|
956
|
+
spec["volumes"].append(
|
957
|
+
{
|
958
|
+
"name": "wandb-source-code-volume",
|
959
|
+
"persistentVolumeClaim": {
|
960
|
+
"claimName": SOURCE_CODE_PVC_NAME,
|
961
|
+
},
|
962
|
+
}
|
963
|
+
)
|
@@ -14,6 +14,7 @@ from wandb.sdk.launch.registry.abstract import AbstractRegistry
|
|
14
14
|
from .._project_spec import LaunchProject
|
15
15
|
from ..errors import LaunchError
|
16
16
|
from ..utils import (
|
17
|
+
CODE_MOUNT_DIR,
|
17
18
|
LOG_PREFIX,
|
18
19
|
MAX_ENV_LENGTHS,
|
19
20
|
PROJECT_SYNCHRONOUS,
|
@@ -121,7 +122,15 @@ class LocalContainerRunner(AbstractRunner):
|
|
121
122
|
docker_args["network"] = "host"
|
122
123
|
if sys.platform == "linux" or sys.platform == "linux2":
|
123
124
|
docker_args["add-host"] = "host.docker.internal:host-gateway"
|
124
|
-
|
125
|
+
base_image = launch_project.job_base_image
|
126
|
+
if base_image is not None:
|
127
|
+
# Mount code into the container and set the working directory.
|
128
|
+
if "volume" not in docker_args:
|
129
|
+
docker_args["volume"] = []
|
130
|
+
docker_args["volume"].append(
|
131
|
+
f"{launch_project.project_dir}:{CODE_MOUNT_DIR}"
|
132
|
+
)
|
133
|
+
docker_args["workdir"] = CODE_MOUNT_DIR
|
125
134
|
return docker_args
|
126
135
|
|
127
136
|
async def run(
|
@@ -146,7 +155,7 @@ class LocalContainerRunner(AbstractRunner):
|
|
146
155
|
elif _is_wandb_dev_uri(self._api.settings("base_url")):
|
147
156
|
env_vars["WANDB_BASE_URL"] = "http://host.docker.internal:9001"
|
148
157
|
|
149
|
-
if launch_project.docker_image:
|
158
|
+
if launch_project.docker_image or launch_project.job_base_image:
|
150
159
|
try:
|
151
160
|
pull_docker_image(image_uri)
|
152
161
|
except Exception as e:
|
@@ -156,14 +165,8 @@ class LocalContainerRunner(AbstractRunner):
|
|
156
165
|
f"Failed to pull docker image {image_uri} with error: {e}"
|
157
166
|
)
|
158
167
|
|
159
|
-
|
160
|
-
|
161
|
-
entry_cmd = (
|
162
|
-
launch_project.override_entrypoint.command
|
163
|
-
if launch_project.override_entrypoint is not None
|
164
|
-
else None
|
165
|
-
)
|
166
|
-
|
168
|
+
entrypoint = launch_project.get_job_entry_point()
|
169
|
+
entry_cmd = None if entrypoint is None else entrypoint.command
|
167
170
|
command_str = " ".join(
|
168
171
|
get_docker_command(
|
169
172
|
image_uri,
|
@@ -221,7 +221,6 @@ class SageMakerRunner(AbstractRunner):
|
|
221
221
|
await run.wait()
|
222
222
|
return run
|
223
223
|
|
224
|
-
launch_project.fill_macros(image_uri)
|
225
224
|
_logger.info("Connecting to sagemaker client")
|
226
225
|
entry_point = (
|
227
226
|
launch_project.override_entrypoint or launch_project.get_job_entry_point()
|
@@ -296,13 +295,12 @@ def build_sagemaker_args(
|
|
296
295
|
entry_point: Optional[EntryPoint],
|
297
296
|
args: Optional[List[str]],
|
298
297
|
max_env_length: int,
|
299
|
-
image_uri:
|
298
|
+
image_uri: str,
|
300
299
|
default_output_path: Optional[str] = None,
|
301
300
|
) -> Dict[str, Any]:
|
302
301
|
sagemaker_args: Dict[str, Any] = {}
|
303
|
-
|
304
|
-
|
305
|
-
)
|
302
|
+
resource_args = launch_project.fill_macros(image_uri)
|
303
|
+
given_sagemaker_args: Optional[Dict[str, Any]] = resource_args.get("sagemaker")
|
306
304
|
|
307
305
|
if given_sagemaker_args is None:
|
308
306
|
raise LaunchError(
|
wandb/sdk/launch/utils.py
CHANGED
@@ -87,6 +87,8 @@ LOG_PREFIX = f"{click.style('launch:', fg='magenta')} "
|
|
87
87
|
MAX_ENV_LENGTHS: Dict[str, int] = defaultdict(lambda: 32670)
|
88
88
|
MAX_ENV_LENGTHS["SageMakerRunner"] = 512
|
89
89
|
|
90
|
+
CODE_MOUNT_DIR = "/mnt/wandb"
|
91
|
+
|
90
92
|
|
91
93
|
def load_wandb_config() -> Config:
|
92
94
|
"""Load wandb config from WANDB_CONFIG environment variable(s).
|
wandb/sdk/lib/disabled.py
CHANGED
@@ -1,178 +1,6 @@
|
|
1
|
-
|
1
|
+
from typing import Any
|
2
2
|
|
3
|
-
|
4
|
-
class RunDisabled(str):
|
5
|
-
def __init__(self, *args, **kwargs):
|
6
|
-
object.__setattr__(self, "___dict", {})
|
7
|
-
|
8
|
-
def __add__(self, other):
|
9
|
-
return self
|
10
|
-
|
11
|
-
def __sub__(self, other):
|
12
|
-
return self
|
13
|
-
|
14
|
-
def __mul__(self, other):
|
15
|
-
return self
|
16
|
-
|
17
|
-
def __truediv__(self, other):
|
18
|
-
return self
|
19
|
-
|
20
|
-
def __floordiv__(self, other):
|
21
|
-
return self
|
22
|
-
|
23
|
-
def __mod__(self, other):
|
24
|
-
return self
|
25
|
-
|
26
|
-
def __pow__(self, other, modulo=None):
|
27
|
-
return self
|
28
|
-
|
29
|
-
def __lshift__(self, other):
|
30
|
-
return self
|
31
|
-
|
32
|
-
def __rshift__(self, other):
|
33
|
-
return self
|
34
|
-
|
35
|
-
def __and__(self, other):
|
36
|
-
return self
|
37
|
-
|
38
|
-
def __xor__(self, other):
|
39
|
-
return self
|
40
|
-
|
41
|
-
def __or__(self, other):
|
42
|
-
return self
|
43
|
-
|
44
|
-
def __iadd__(self, other):
|
45
|
-
return self
|
46
|
-
|
47
|
-
def __isub__(self, other):
|
48
|
-
return self
|
49
|
-
|
50
|
-
def __imul__(self, other):
|
51
|
-
return self
|
52
|
-
|
53
|
-
def __idiv__(self, other):
|
54
|
-
return self
|
55
|
-
|
56
|
-
def __ifloordiv__(self, other):
|
57
|
-
return self
|
58
|
-
|
59
|
-
def __imod__(self, other):
|
60
|
-
return self
|
61
|
-
|
62
|
-
def __ipow__(self, other, modulo=None):
|
63
|
-
return self
|
64
|
-
|
65
|
-
def __ilshift__(self, other):
|
66
|
-
return self
|
67
|
-
|
68
|
-
def __irshift__(self, other):
|
69
|
-
return self
|
70
|
-
|
71
|
-
def __iand__(self, other):
|
72
|
-
return self
|
73
|
-
|
74
|
-
def __ixor__(self, other):
|
75
|
-
return self
|
76
|
-
|
77
|
-
def __ior__(self, other):
|
78
|
-
return self
|
79
|
-
|
80
|
-
def __neg__(self):
|
81
|
-
return self
|
82
|
-
|
83
|
-
def __pos__(self):
|
84
|
-
return self
|
85
|
-
|
86
|
-
def __abs__(self):
|
87
|
-
return self
|
88
|
-
|
89
|
-
def __invert__(self):
|
90
|
-
return self
|
91
|
-
|
92
|
-
def __complex__(self):
|
93
|
-
return 1 + 0j
|
94
|
-
|
95
|
-
def __int__(self):
|
96
|
-
return 1
|
97
|
-
|
98
|
-
def __long__(self):
|
99
|
-
return 1
|
100
|
-
|
101
|
-
def __float__(self):
|
102
|
-
return 1.0
|
103
|
-
|
104
|
-
def __oct__(self):
|
105
|
-
return oct(1)
|
106
|
-
|
107
|
-
def __hex__(self):
|
108
|
-
return hex(1)
|
109
|
-
|
110
|
-
def __lt__(self, other):
|
111
|
-
return True
|
112
|
-
|
113
|
-
def __le__(self, other):
|
114
|
-
return True
|
115
|
-
|
116
|
-
def __eq__(self, other):
|
117
|
-
return True
|
118
|
-
|
119
|
-
def __ne__(self, other):
|
120
|
-
return True
|
121
|
-
|
122
|
-
def __gt__(self, other):
|
123
|
-
return True
|
124
|
-
|
125
|
-
def __ge__(self, other):
|
126
|
-
return True
|
127
|
-
|
128
|
-
def __getattr__(self, attr):
|
129
|
-
return self[attr]
|
130
|
-
|
131
|
-
def __getitem__(self, key):
|
132
|
-
d = object.__getattribute__(self, "___dict")
|
133
|
-
try:
|
134
|
-
if key in d:
|
135
|
-
return d[key]
|
136
|
-
except TypeError:
|
137
|
-
key = str(key)
|
138
|
-
if key in d:
|
139
|
-
return d[key]
|
140
|
-
dummy = RunDisabled()
|
141
|
-
d[key] = dummy
|
142
|
-
return dummy
|
143
|
-
|
144
|
-
def __setitem__(self, key, value):
|
145
|
-
object.__getattribute__(self, "___dict")[key] = value
|
146
|
-
|
147
|
-
def __setattr__(self, key, value):
|
148
|
-
self[key] = value
|
149
|
-
|
150
|
-
def __call__(self, *args, **kwargs):
|
151
|
-
return RunDisabled()
|
152
|
-
|
153
|
-
def __len__(self):
|
154
|
-
return 1
|
155
|
-
|
156
|
-
def __str__(self):
|
157
|
-
return ""
|
158
|
-
|
159
|
-
def __enter__(self):
|
160
|
-
return self
|
161
|
-
|
162
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
163
|
-
return exc_type is None
|
164
|
-
|
165
|
-
def __repr__(self):
|
166
|
-
return ""
|
167
|
-
|
168
|
-
def __nonzero__(self):
|
169
|
-
return True
|
170
|
-
|
171
|
-
def __bool__(self):
|
172
|
-
return True
|
173
|
-
|
174
|
-
def __getstate__(self):
|
175
|
-
return 1
|
3
|
+
from wandb.sdk.lib import deprecate
|
176
4
|
|
177
5
|
|
178
6
|
class SummaryDisabled(dict):
|
@@ -188,3 +16,14 @@ class SummaryDisabled(dict):
|
|
188
16
|
val = SummaryDisabled(val)
|
189
17
|
self[key] = val
|
190
18
|
return val
|
19
|
+
|
20
|
+
|
21
|
+
class RunDisabled:
|
22
|
+
"""Compatibility class for integrations that explicitly check for wandb.RunDisabled."""
|
23
|
+
|
24
|
+
def __getattr__(self, name: str) -> Any:
|
25
|
+
deprecate.deprecate(
|
26
|
+
field_name=deprecate.Deprecated.run_disabled,
|
27
|
+
warning_message="RunDisabled is deprecated and is a no-op. "
|
28
|
+
'`wandb.init(mode="disabled")` now returns and instance of `wandb.sdk.wandb_run.Run`.',
|
29
|
+
)
|
wandb/sdk/lib/tracelog.py
CHANGED
@@ -45,8 +45,8 @@ logger = logging.getLogger(__name__)
|
|
45
45
|
ANNOTATE_QUEUE_NAME = "_DEBUGLOG_QUEUE_NAME"
|
46
46
|
|
47
47
|
# capture stdout and stderr before anyone messes with them
|
48
|
-
stdout_write = sys.__stdout__.write
|
49
|
-
stderr_write = sys.__stderr__.write
|
48
|
+
stdout_write = sys.__stdout__.write # type: ignore
|
49
|
+
stderr_write = sys.__stderr__.write # type: ignore
|
50
50
|
|
51
51
|
|
52
52
|
def _log(
|
wandb/sdk/wandb_init.py
CHANGED
@@ -30,15 +30,7 @@ from wandb.util import _is_artifact_representation
|
|
30
30
|
|
31
31
|
from . import wandb_login, wandb_setup
|
32
32
|
from .backend.backend import Backend
|
33
|
-
from .lib import
|
34
|
-
RunDisabled,
|
35
|
-
SummaryDisabled,
|
36
|
-
filesystem,
|
37
|
-
ipython,
|
38
|
-
module,
|
39
|
-
reporting,
|
40
|
-
telemetry,
|
41
|
-
)
|
33
|
+
from .lib import SummaryDisabled, filesystem, ipython, module, reporting, telemetry
|
42
34
|
from .lib.deprecate import Deprecated, deprecate
|
43
35
|
from .lib.mailbox import Mailbox, MailboxProgress
|
44
36
|
from .lib.printer import Printer, get_printer
|
@@ -529,20 +521,18 @@ class _WandbInit:
|
|
529
521
|
logger.info(f"Logging user logs to {settings.log_user}")
|
530
522
|
logger.info(f"Logging internal logs to {settings.log_internal}")
|
531
523
|
|
532
|
-
def _make_run_disabled(self) ->
|
533
|
-
drun =
|
534
|
-
drun.
|
535
|
-
drun.
|
536
|
-
drun.
|
537
|
-
drun.summary = SummaryDisabled()
|
538
|
-
drun.log = lambda data, *_, **__: drun.summary.update(data)
|
539
|
-
drun.finish = lambda *_, **__: module.unset_globals()
|
540
|
-
drun.
|
541
|
-
drun.
|
542
|
-
drun.
|
543
|
-
drun.
|
544
|
-
drun.name = "dummy-" + drun.id
|
545
|
-
drun.dir = tempfile.gettempdir()
|
524
|
+
def _make_run_disabled(self) -> Run:
|
525
|
+
drun = Run(settings=Settings(mode="disabled", files_dir=tempfile.gettempdir()))
|
526
|
+
drun._config = wandb.wandb_sdk.wandb_config.Config()
|
527
|
+
drun._config.update(self.sweep_config)
|
528
|
+
drun._config.update(self.config)
|
529
|
+
drun.summary = SummaryDisabled() # type: ignore
|
530
|
+
drun.log = lambda data, *_, **__: drun.summary.update(data) # type: ignore
|
531
|
+
drun.finish = lambda *_, **__: module.unset_globals() # type: ignore
|
532
|
+
drun._step = 0
|
533
|
+
drun._run_obj = None
|
534
|
+
drun._run_id = runid.generate_id()
|
535
|
+
drun._name = "dummy-" + drun.id
|
546
536
|
module.set_global(
|
547
537
|
run=drun,
|
548
538
|
config=drun.config,
|
@@ -563,7 +553,7 @@ class _WandbInit:
|
|
563
553
|
percent_done = handle.percent_done
|
564
554
|
self.printer.progress_update(line, percent_done=percent_done)
|
565
555
|
|
566
|
-
def init(self) ->
|
556
|
+
def init(self) -> Run: # noqa: C901
|
567
557
|
if logger is None:
|
568
558
|
raise RuntimeError("Logger not initialized")
|
569
559
|
logger.info("calling init triggers")
|
@@ -700,6 +690,12 @@ class _WandbInit:
|
|
700
690
|
tel.feature.flow_control_custom = True
|
701
691
|
if self.settings._require_core:
|
702
692
|
tel.feature.core = True
|
693
|
+
if self.settings._shared:
|
694
|
+
wandb.termwarn(
|
695
|
+
"The `_shared` feature is experimental and may change. "
|
696
|
+
"Please contact support@wandb.com for guidance and to report any issues."
|
697
|
+
)
|
698
|
+
tel.feature.shared_mode = True
|
703
699
|
|
704
700
|
tel.env.maybe_mp = _maybe_mp_process(backend)
|
705
701
|
|
@@ -853,7 +849,7 @@ def _attach(
|
|
853
849
|
run_id: Optional[str] = None,
|
854
850
|
*,
|
855
851
|
run: Optional["Run"] = None,
|
856
|
-
) ->
|
852
|
+
) -> Optional[Run]:
|
857
853
|
"""Attach to a run currently executing in another process/thread.
|
858
854
|
|
859
855
|
Arguments:
|
@@ -907,7 +903,7 @@ def _attach(
|
|
907
903
|
if run is None:
|
908
904
|
run = Run(settings=settings)
|
909
905
|
else:
|
910
|
-
run._init(
|
906
|
+
run._init()
|
911
907
|
run._set_library(_wl)
|
912
908
|
run._set_backend(backend)
|
913
909
|
backend._hack_set_run(run)
|
@@ -957,7 +953,7 @@ def init(
|
|
957
953
|
fork_from: Optional[str] = None,
|
958
954
|
resume_from: Optional[str] = None,
|
959
955
|
settings: Union[Settings, Dict[str, Any], None] = None,
|
960
|
-
) ->
|
956
|
+
) -> Run:
|
961
957
|
r"""Start a new run to track and log to W&B.
|
962
958
|
|
963
959
|
In an ML training pipeline, you could add `wandb.init()`
|
wandb/sdk/wandb_login.py
CHANGED
@@ -54,16 +54,16 @@ def login(
|
|
54
54
|
) -> bool:
|
55
55
|
"""Set up W&B login credentials.
|
56
56
|
|
57
|
-
By default, this will only store
|
57
|
+
By default, this will only store credentials locally without
|
58
58
|
verifying them with the W&B server. To verify credentials, pass
|
59
|
-
verify=True
|
59
|
+
`verify=True`.
|
60
60
|
|
61
61
|
Arguments:
|
62
62
|
anonymous: (string, optional) Can be "must", "allow", or "never".
|
63
|
-
If set to "must"
|
64
|
-
"allow"
|
65
|
-
isn't already logged in.
|
66
|
-
|
63
|
+
If set to "must", always log a user in anonymously. If set to
|
64
|
+
"allow", only create an anonymous user if the user
|
65
|
+
isn't already logged in. If set to "never", never log a
|
66
|
+
user anonymously. Default set to "never".
|
67
67
|
relogin: (bool, optional) If true, will re-prompt for API key.
|
68
68
|
host: (string, optional) The host to connect to.
|
69
69
|
force: (bool, optional) If true, will force a relogin.
|
wandb/sdk/wandb_manager.py
CHANGED
@@ -114,17 +114,21 @@ class _Manager:
|
|
114
114
|
|
115
115
|
try:
|
116
116
|
svc_iface._svc_connect(port=port)
|
117
|
+
|
117
118
|
except ConnectionRefusedError as e:
|
118
119
|
if not psutil.pid_exists(self._token.pid):
|
119
120
|
message = (
|
120
|
-
"Connection to wandb service failed
|
121
|
-
"
|
121
|
+
"Connection to wandb service failed"
|
122
|
+
" because the process is not available."
|
122
123
|
)
|
123
124
|
else:
|
124
|
-
message =
|
125
|
-
raise ManagerConnectionRefusedError(message)
|
125
|
+
message = "Connection to wandb service failed."
|
126
|
+
raise ManagerConnectionRefusedError(message) from e
|
127
|
+
|
126
128
|
except Exception as e:
|
127
|
-
raise ManagerConnectionError(
|
129
|
+
raise ManagerConnectionError(
|
130
|
+
"Connection to wandb service failed.",
|
131
|
+
) from e
|
128
132
|
|
129
133
|
def __init__(self, settings: "Settings") -> None:
|
130
134
|
"""Connects to the internal service, starting it if necessary."""
|