wandb 0.15.9__py3-none-any.whl → 0.15.11__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. wandb/__init__.py +5 -1
  2. wandb/apis/public.py +137 -17
  3. wandb/apis/reports/_panels.py +1 -1
  4. wandb/apis/reports/blocks.py +1 -0
  5. wandb/apis/reports/report.py +27 -5
  6. wandb/cli/cli.py +52 -41
  7. wandb/docker/__init__.py +17 -0
  8. wandb/docker/auth.py +1 -1
  9. wandb/env.py +24 -4
  10. wandb/filesync/step_checksum.py +3 -3
  11. wandb/integration/openai/openai.py +3 -0
  12. wandb/integration/ultralytics/__init__.py +9 -0
  13. wandb/integration/ultralytics/bbox_utils.py +196 -0
  14. wandb/integration/ultralytics/callback.py +458 -0
  15. wandb/integration/ultralytics/classification_utils.py +66 -0
  16. wandb/integration/ultralytics/mask_utils.py +141 -0
  17. wandb/integration/ultralytics/pose_utils.py +92 -0
  18. wandb/integration/xgboost/xgboost.py +3 -3
  19. wandb/integration/yolov8/__init__.py +0 -7
  20. wandb/integration/yolov8/yolov8.py +22 -3
  21. wandb/old/settings.py +7 -0
  22. wandb/plot/line_series.py +0 -1
  23. wandb/proto/v3/wandb_internal_pb2.py +353 -300
  24. wandb/proto/v3/wandb_server_pb2.py +37 -41
  25. wandb/proto/v3/wandb_settings_pb2.py +2 -2
  26. wandb/proto/v3/wandb_telemetry_pb2.py +16 -16
  27. wandb/proto/v4/wandb_internal_pb2.py +272 -260
  28. wandb/proto/v4/wandb_server_pb2.py +37 -40
  29. wandb/proto/v4/wandb_settings_pb2.py +2 -2
  30. wandb/proto/v4/wandb_telemetry_pb2.py +16 -16
  31. wandb/proto/wandb_internal_codegen.py +7 -31
  32. wandb/sdk/artifacts/artifact.py +321 -189
  33. wandb/sdk/artifacts/artifact_cache.py +14 -0
  34. wandb/sdk/artifacts/artifact_manifest.py +5 -4
  35. wandb/sdk/artifacts/artifact_manifest_entry.py +37 -9
  36. wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +1 -9
  37. wandb/sdk/artifacts/artifact_saver.py +13 -50
  38. wandb/sdk/artifacts/artifact_ttl.py +6 -0
  39. wandb/sdk/artifacts/artifacts_cache.py +119 -93
  40. wandb/sdk/artifacts/staging.py +25 -0
  41. wandb/sdk/artifacts/storage_handlers/s3_handler.py +12 -7
  42. wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +2 -3
  43. wandb/sdk/artifacts/storage_policies/__init__.py +4 -0
  44. wandb/sdk/artifacts/storage_policies/register.py +1 -0
  45. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +4 -3
  46. wandb/sdk/artifacts/storage_policy.py +4 -2
  47. wandb/sdk/backend/backend.py +0 -16
  48. wandb/sdk/data_types/image.py +3 -1
  49. wandb/sdk/integration_utils/auto_logging.py +38 -13
  50. wandb/sdk/interface/interface.py +16 -135
  51. wandb/sdk/interface/interface_shared.py +9 -147
  52. wandb/sdk/interface/interface_sock.py +0 -26
  53. wandb/sdk/internal/file_pusher.py +20 -3
  54. wandb/sdk/internal/file_stream.py +3 -1
  55. wandb/sdk/internal/handler.py +53 -70
  56. wandb/sdk/internal/internal_api.py +220 -130
  57. wandb/sdk/internal/job_builder.py +41 -37
  58. wandb/sdk/internal/sender.py +7 -25
  59. wandb/sdk/internal/system/assets/disk.py +144 -11
  60. wandb/sdk/internal/system/system_info.py +6 -2
  61. wandb/sdk/launch/__init__.py +5 -0
  62. wandb/sdk/launch/{launch.py → _launch.py} +53 -54
  63. wandb/sdk/launch/{launch_add.py → _launch_add.py} +34 -31
  64. wandb/sdk/launch/_project_spec.py +13 -2
  65. wandb/sdk/launch/agent/agent.py +103 -59
  66. wandb/sdk/launch/agent/run_queue_item_file_saver.py +6 -4
  67. wandb/sdk/launch/builder/build.py +19 -1
  68. wandb/sdk/launch/builder/docker_builder.py +5 -1
  69. wandb/sdk/launch/builder/kaniko_builder.py +5 -1
  70. wandb/sdk/launch/create_job.py +20 -5
  71. wandb/sdk/launch/loader.py +14 -5
  72. wandb/sdk/launch/runner/abstract.py +0 -2
  73. wandb/sdk/launch/runner/kubernetes_monitor.py +329 -0
  74. wandb/sdk/launch/runner/kubernetes_runner.py +66 -209
  75. wandb/sdk/launch/runner/local_container.py +5 -2
  76. wandb/sdk/launch/runner/local_process.py +4 -1
  77. wandb/sdk/launch/sweeps/scheduler.py +43 -25
  78. wandb/sdk/launch/sweeps/utils.py +5 -3
  79. wandb/sdk/launch/utils.py +3 -1
  80. wandb/sdk/lib/_settings_toposort_generate.py +3 -9
  81. wandb/sdk/lib/_settings_toposort_generated.py +27 -3
  82. wandb/sdk/lib/_wburls_generated.py +1 -0
  83. wandb/sdk/lib/filenames.py +27 -6
  84. wandb/sdk/lib/filesystem.py +181 -7
  85. wandb/sdk/lib/fsm.py +5 -3
  86. wandb/sdk/lib/gql_request.py +3 -0
  87. wandb/sdk/lib/ipython.py +7 -0
  88. wandb/sdk/lib/wburls.py +1 -0
  89. wandb/sdk/service/port_file.py +2 -15
  90. wandb/sdk/service/server.py +7 -55
  91. wandb/sdk/service/service.py +56 -26
  92. wandb/sdk/service/service_base.py +1 -1
  93. wandb/sdk/service/streams.py +11 -5
  94. wandb/sdk/verify/verify.py +2 -2
  95. wandb/sdk/wandb_init.py +8 -2
  96. wandb/sdk/wandb_manager.py +4 -14
  97. wandb/sdk/wandb_run.py +143 -53
  98. wandb/sdk/wandb_settings.py +148 -35
  99. wandb/testing/relay.py +85 -38
  100. wandb/util.py +87 -4
  101. wandb/wandb_torch.py +24 -38
  102. {wandb-0.15.9.dist-info → wandb-0.15.11.dist-info}/METADATA +48 -23
  103. {wandb-0.15.9.dist-info → wandb-0.15.11.dist-info}/RECORD +107 -103
  104. {wandb-0.15.9.dist-info → wandb-0.15.11.dist-info}/WHEEL +1 -1
  105. wandb/proto/v3/wandb_server_pb2_grpc.py +0 -1422
  106. wandb/proto/v4/wandb_server_pb2_grpc.py +0 -1422
  107. wandb/proto/wandb_server_pb2_grpc.py +0 -8
  108. wandb/sdk/artifacts/storage_policies/s3_bucket_policy.py +0 -61
  109. wandb/sdk/interface/interface_grpc.py +0 -460
  110. wandb/sdk/service/server_grpc.py +0 -444
  111. wandb/sdk/service/service_grpc.py +0 -73
  112. {wandb-0.15.9.dist-info → wandb-0.15.11.dist-info}/LICENSE +0 -0
  113. {wandb-0.15.9.dist-info → wandb-0.15.11.dist-info}/entry_points.txt +0 -0
  114. {wandb-0.15.9.dist-info → wandb-0.15.11.dist-info}/top_level.txt +0 -0
wandb/env.py CHANGED
@@ -14,6 +14,7 @@ import json
14
14
  import os
15
15
  import sys
16
16
  from distutils.util import strtobool
17
+ from pathlib import Path
17
18
  from typing import List, MutableMapping, Optional, Union
18
19
 
19
20
  import appdirs
@@ -50,6 +51,7 @@ RUN_GROUP = "WANDB_RUN_GROUP"
50
51
  RUN_DIR = "WANDB_RUN_DIR"
51
52
  SWEEP_ID = "WANDB_SWEEP_ID"
52
53
  HTTP_TIMEOUT = "WANDB_HTTP_TIMEOUT"
54
+ FILE_PUSHER_TIMEOUT = "WANDB_FILE_PUSHER_TIMEOUT"
53
55
  API_KEY = "WANDB_API_KEY"
54
56
  JOB_TYPE = "WANDB_JOB_TYPE"
55
57
  DISABLE_CODE = "WANDB_DISABLE_CODE"
@@ -72,6 +74,7 @@ JUPYTER = "WANDB_JUPYTER"
72
74
  CONFIG_DIR = "WANDB_CONFIG_DIR"
73
75
  DATA_DIR = "WANDB_DATA_DIR"
74
76
  ARTIFACT_DIR = "WANDB_ARTIFACT_DIR"
77
+ ARTIFACT_FETCH_FILE_URL_BATCH_SIZE = "WANDB_ARTIFACT_FETCH_FILE_URL_BATCH_SIZE"
75
78
  CACHE_DIR = "WANDB_CACHE_DIR"
76
79
  DISABLE_SSL = "WANDB_INSECURE_DISABLE_SSL"
77
80
  SERVICE = "WANDB_SERVICE"
@@ -120,6 +123,7 @@ def immutable_keys() -> List[str]:
120
123
  HOST,
121
124
  DATA_DIR,
122
125
  ARTIFACT_DIR,
126
+ ARTIFACT_FETCH_FILE_URL_BATCH_SIZE,
123
127
  CACHE_DIR,
124
128
  USE_V1_ARTIFACTS,
125
129
  DISABLE_SSL,
@@ -191,13 +195,24 @@ def get_docker(
191
195
  return env.get(DOCKER, default)
192
196
 
193
197
 
194
- def get_http_timeout(default: int = 10, env: Optional[Env] = None) -> int:
198
+ def get_http_timeout(default: int = 20, env: Optional[Env] = None) -> int:
195
199
  if env is None:
196
200
  env = os.environ
197
201
 
198
202
  return int(env.get(HTTP_TIMEOUT, default))
199
203
 
200
204
 
205
+ def get_file_pusher_timeout(
206
+ default: Optional[int] = None,
207
+ env: Optional[Env] = None,
208
+ ) -> Optional[int]:
209
+ if env is None:
210
+ env = os.environ
211
+
212
+ timeout = env.get(FILE_PUSHER_TIMEOUT, default)
213
+ return int(timeout) if timeout else None
214
+
215
+
201
216
  def get_ignore(
202
217
  default: Optional[List[str]] = None, env: Optional[Env] = None
203
218
  ) -> Optional[List[str]]:
@@ -367,14 +382,19 @@ def get_artifact_dir(env: Optional[Env] = None) -> str:
367
382
  return val
368
383
 
369
384
 
370
- def get_cache_dir(env: Optional[Env] = None) -> str:
371
- default_dir = appdirs.user_cache_dir("wandb")
385
+ def get_artifact_fetch_file_url_batch_size(env: Optional[Env] = None) -> int:
386
+ default_batch_size = 5000
372
387
  if env is None:
373
388
  env = os.environ
374
- val = env.get(CACHE_DIR, default_dir)
389
+ val = int(env.get(ARTIFACT_FETCH_FILE_URL_BATCH_SIZE, default_batch_size))
375
390
  return val
376
391
 
377
392
 
393
+ def get_cache_dir(env: Optional[Env] = None) -> Path:
394
+ env = env or os.environ
395
+ return Path(env.get(CACHE_DIR, appdirs.user_cache_dir("wandb")))
396
+
397
+
378
398
  def get_use_v1_artifacts(env: Optional[Env] = None) -> bool:
379
399
  if env is None:
380
400
  env = os.environ
@@ -16,8 +16,8 @@ if TYPE_CHECKING:
16
16
  import tempfile
17
17
 
18
18
  from wandb.filesync import stats
19
- from wandb.sdk.artifacts import artifact_saver
20
19
  from wandb.sdk.artifacts.artifact_manifest import ArtifactManifest
20
+ from wandb.sdk.artifacts.artifact_saver import SaveFn, SaveFnAsync
21
21
  from wandb.sdk.internal import internal_api
22
22
 
23
23
 
@@ -30,8 +30,8 @@ class RequestUpload(NamedTuple):
30
30
  class RequestStoreManifestFiles(NamedTuple):
31
31
  manifest: "ArtifactManifest"
32
32
  artifact_id: str
33
- save_fn: "artifact_saver.SaveFn"
34
- save_fn_async: "artifact_saver.SaveFnAsync"
33
+ save_fn: "SaveFn"
34
+ save_fn_async: "SaveFnAsync"
35
35
 
36
36
 
37
37
  class RequestCommitArtifact(NamedTuple):
@@ -13,6 +13,9 @@ autolog = AutologAPI(
13
13
  "Edit.create",
14
14
  "Completion.create",
15
15
  "ChatCompletion.create",
16
+ "Edit.acreate",
17
+ "Completion.acreate",
18
+ "ChatCompletion.acreate",
16
19
  ),
17
20
  resolver=OpenAIRequestResponseResolver(),
18
21
  telemetry_feature="openai_autolog",
@@ -0,0 +1,9 @@
1
+ """Tools for integrating with [`ultralytics`](https://docs.ultralytics.com/).
2
+
3
+ Ultralytics is a computer vision framework for training and deploying YOLOv8
4
+ models.
5
+ """
6
+
7
+ from wandb.integration.ultralytics.callback import add_wandb_callback
8
+
9
+ __all__ = ("add_wandb_callback",)
@@ -0,0 +1,196 @@
1
+ from typing import Any, Dict, List, Optional, Tuple, Union
2
+
3
+ import torch
4
+ from ultralytics.engine.results import Results
5
+ from ultralytics.models.yolo.detect import DetectionPredictor
6
+ from ultralytics.yolo.utils import ops
7
+
8
+ import wandb
9
+
10
+
11
+ def scale_bounding_box_to_original_image_shape(
12
+ box: torch.Tensor,
13
+ resized_image_shape: Tuple,
14
+ original_image_shape: Tuple,
15
+ ratio_pad: bool,
16
+ ) -> List[int]:
17
+ """YOLOv8 resizes images during training and the label values are normalized based on this resized shape.
18
+
19
+ This function rescales the bounding box labels to the original
20
+ image shape.
21
+
22
+ Reference: https://github.com/ultralytics/ultralytics/blob/main/ultralytics/yolo/utils/callbacks/comet.py#L105
23
+ """
24
+ resized_image_height, resized_image_width = resized_image_shape
25
+ # Convert normalized xywh format predictions to xyxy in resized scale format
26
+ box = ops.xywhn2xyxy(box, h=resized_image_height, w=resized_image_width)
27
+ # Scale box predictions from resized image scale back to original image scale
28
+ box = ops.scale_boxes(resized_image_shape, box, original_image_shape, ratio_pad)
29
+ # # Convert bounding box format from xyxy to xywh for Comet logging
30
+ box = ops.xyxy2xywh(box)
31
+ return box.tolist()
32
+
33
+
34
+ def get_ground_truth_bbox_annotations(
35
+ img_idx: int, image_path: str, batch: Dict, class_name_map: Dict = None
36
+ ) -> List[Dict[str, Any]]:
37
+ """Get ground truth bounding box annotation data in the form required for `wandb.Image` overlay system."""
38
+ indices = batch["batch_idx"] == img_idx
39
+ bboxes = batch["bboxes"][indices]
40
+ cls_labels = batch["cls"][indices].squeeze(1).tolist()
41
+
42
+ class_name_map_reverse = {v: k for k, v in class_name_map.items()}
43
+
44
+ if len(bboxes) == 0:
45
+ wandb.termwarn(
46
+ f"Image: {image_path} has no bounding boxes labels", repeat=False
47
+ )
48
+ return None
49
+
50
+ cls_labels = batch["cls"][indices].squeeze(1).tolist()
51
+ if class_name_map:
52
+ cls_labels = [str(class_name_map[label]) for label in cls_labels]
53
+
54
+ original_image_shape = batch["ori_shape"][img_idx]
55
+ resized_image_shape = batch["resized_shape"][img_idx]
56
+ ratio_pad = batch["ratio_pad"][img_idx]
57
+
58
+ data = []
59
+ for box, label in zip(bboxes, cls_labels):
60
+ box = scale_bounding_box_to_original_image_shape(
61
+ box, resized_image_shape, original_image_shape, ratio_pad
62
+ )
63
+ data.append(
64
+ {
65
+ "position": {
66
+ "middle": [int(box[0]), int(box[1])],
67
+ "width": int(box[2]),
68
+ "height": int(box[3]),
69
+ },
70
+ "domain": "pixel",
71
+ "class_id": class_name_map_reverse[label],
72
+ "box_caption": label,
73
+ }
74
+ )
75
+
76
+ return data
77
+
78
+
79
+ def get_mean_confidence_map(
80
+ classes: List, confidence: List, class_id_to_label: Dict
81
+ ) -> Dict[str, float]:
82
+ """Get Mean-confidence map from the predictions to be logged into a `wandb.Table`."""
83
+ confidence_map = {v: [] for _, v in class_id_to_label.items()}
84
+ for class_idx, confidence_value in zip(classes, confidence):
85
+ confidence_map[class_id_to_label[class_idx]].append(confidence_value)
86
+ updated_confidence_map = {}
87
+ for label, confidence_list in confidence_map.items():
88
+ if len(confidence_list) > 0:
89
+ updated_confidence_map[label] = sum(confidence_list) / len(confidence_list)
90
+ else:
91
+ updated_confidence_map[label] = 0
92
+ return updated_confidence_map
93
+
94
+
95
+ def get_boxes(result: Results) -> Tuple[Dict, Dict]:
96
+ """Convert an ultralytics prediction result into metadata for the `wandb.Image` overlay system."""
97
+ boxes = result.boxes.xywh.long().numpy()
98
+ classes = result.boxes.cls.long().numpy()
99
+ confidence = result.boxes.conf.numpy()
100
+ class_id_to_label = {int(k): str(v) for k, v in result.names.items()}
101
+ mean_confidence_map = get_mean_confidence_map(
102
+ classes, confidence, class_id_to_label
103
+ )
104
+ box_data = []
105
+ for idx in range(len(boxes)):
106
+ box_data.append(
107
+ {
108
+ "position": {
109
+ "middle": [int(boxes[idx][0]), int(boxes[idx][1])],
110
+ "width": int(boxes[idx][2]),
111
+ "height": int(boxes[idx][3]),
112
+ },
113
+ "domain": "pixel",
114
+ "class_id": int(classes[idx]),
115
+ "box_caption": class_id_to_label[int(classes[idx])],
116
+ "scores": {"confidence": float(confidence[idx])},
117
+ }
118
+ )
119
+ boxes = {
120
+ "predictions": {
121
+ "box_data": box_data,
122
+ "class_labels": class_id_to_label,
123
+ },
124
+ }
125
+ return boxes, mean_confidence_map
126
+
127
+
128
+ def plot_predictions(
129
+ result: Results, model_name: str, table: Optional[wandb.Table] = None
130
+ ) -> Union[wandb.Table, Tuple[wandb.Image, Dict, Dict]]:
131
+ """Plot the images with the W&B overlay system. The `wandb.Image` is either added to a `wandb.Table` or returned."""
132
+ result = result.to("cpu")
133
+ boxes, mean_confidence_map = get_boxes(result)
134
+ image = wandb.Image(result.orig_img[:, :, ::-1], boxes=boxes)
135
+ if table is not None:
136
+ table.add_data(
137
+ model_name,
138
+ image,
139
+ len(boxes["predictions"]["box_data"]),
140
+ mean_confidence_map,
141
+ result.speed,
142
+ )
143
+ return table
144
+ return image, boxes["predictions"], mean_confidence_map
145
+
146
+
147
+ def plot_validation_results(
148
+ dataloader: Any,
149
+ class_label_map: Dict,
150
+ model_name: str,
151
+ predictor: DetectionPredictor,
152
+ table: wandb.Table,
153
+ max_validation_batches: int,
154
+ epoch: Optional[int] = None,
155
+ ) -> wandb.Table:
156
+ """Plot validation results in a table."""
157
+ data_idx = 0
158
+ for batch_idx, batch in enumerate(dataloader):
159
+ for img_idx, image_path in enumerate(batch["im_file"]):
160
+ prediction_result = predictor(image_path)[0]
161
+ _, prediction_box_data, mean_confidence_map = plot_predictions(
162
+ prediction_result, model_name
163
+ )
164
+ try:
165
+ ground_truth_data = get_ground_truth_bbox_annotations(
166
+ img_idx, image_path, batch, class_label_map
167
+ )
168
+ wandb_image = wandb.Image(
169
+ image_path,
170
+ boxes={
171
+ "ground-truth": {
172
+ "box_data": ground_truth_data,
173
+ "class_labels": class_label_map,
174
+ },
175
+ "predictions": {
176
+ "box_data": prediction_box_data["box_data"],
177
+ "class_labels": class_label_map,
178
+ },
179
+ },
180
+ )
181
+ table_rows = [
182
+ data_idx,
183
+ batch_idx,
184
+ wandb_image,
185
+ mean_confidence_map,
186
+ prediction_result.speed,
187
+ ]
188
+ table_rows = [epoch] + table_rows if epoch is not None else table_rows
189
+ table_rows = [model_name] + table_rows
190
+ table.add_data(*table_rows)
191
+ data_idx += 1
192
+ except TypeError:
193
+ pass
194
+ if batch_idx + 1 == max_validation_batches:
195
+ break
196
+ return table