wandb 0.17.5__py3-none-any.whl → 0.17.7__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.
Files changed (72) hide show
  1. wandb/__init__.py +5 -16
  2. wandb/agents/pyagent.py +1 -2
  3. wandb/apis/public/api.py +1 -1
  4. wandb/apis/public/jobs.py +5 -0
  5. wandb/bin/nvidia_gpu_stats +0 -0
  6. wandb/cli/cli.py +21 -0
  7. wandb/data_types.py +5 -4
  8. wandb/env.py +6 -0
  9. wandb/integration/kfp/wandb_logging.py +1 -1
  10. wandb/integration/lightning/fabric/logger.py +5 -5
  11. wandb/integration/openai/fine_tuning.py +13 -5
  12. wandb/integration/ultralytics/pose_utils.py +0 -1
  13. wandb/proto/v3/wandb_internal_pb2.py +226 -226
  14. wandb/proto/v3/wandb_settings_pb2.py +1 -1
  15. wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
  16. wandb/proto/v4/wandb_internal_pb2.py +226 -226
  17. wandb/proto/v4/wandb_settings_pb2.py +1 -1
  18. wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
  19. wandb/proto/v5/wandb_internal_pb2.py +226 -226
  20. wandb/proto/v5/wandb_settings_pb2.py +1 -1
  21. wandb/proto/v5/wandb_telemetry_pb2.py +10 -10
  22. wandb/proto/wandb_deprecated.py +4 -0
  23. wandb/proto/wandb_internal_pb2.py +6 -0
  24. wandb/sdk/artifacts/artifact.py +6 -1
  25. wandb/sdk/artifacts/artifact_manifest_entry.py +31 -0
  26. wandb/sdk/artifacts/storage_handlers/azure_handler.py +35 -23
  27. wandb/sdk/data_types/_dtypes.py +5 -5
  28. wandb/sdk/data_types/base_types/media.py +3 -1
  29. wandb/sdk/data_types/helper_types/bounding_boxes_2d.py +3 -1
  30. wandb/sdk/data_types/helper_types/image_mask.py +3 -1
  31. wandb/sdk/data_types/image.py +3 -1
  32. wandb/sdk/data_types/object_3d.py +113 -2
  33. wandb/sdk/data_types/saved_model.py +3 -1
  34. wandb/sdk/interface/interface.py +40 -16
  35. wandb/sdk/interface/interface_shared.py +6 -9
  36. wandb/sdk/internal/datastore.py +1 -1
  37. wandb/sdk/internal/handler.py +0 -2
  38. wandb/sdk/internal/internal.py +1 -1
  39. wandb/sdk/internal/job_builder.py +5 -2
  40. wandb/sdk/internal/sender.py +31 -15
  41. wandb/sdk/internal/tb_watcher.py +2 -2
  42. wandb/sdk/internal/update.py +2 -2
  43. wandb/sdk/launch/_launch.py +4 -2
  44. wandb/sdk/launch/_project_spec.py +34 -8
  45. wandb/sdk/launch/agent/agent.py +6 -2
  46. wandb/sdk/launch/agent/run_queue_item_file_saver.py +2 -4
  47. wandb/sdk/launch/builder/build.py +4 -2
  48. wandb/sdk/launch/builder/kaniko_builder.py +13 -5
  49. wandb/sdk/launch/builder/templates/_wandb_bootstrap.py +2 -1
  50. wandb/sdk/launch/create_job.py +2 -0
  51. wandb/sdk/launch/inputs/internal.py +42 -28
  52. wandb/sdk/launch/inputs/schema.py +39 -0
  53. wandb/sdk/launch/runner/kubernetes_runner.py +72 -0
  54. wandb/sdk/launch/runner/local_container.py +13 -10
  55. wandb/sdk/launch/runner/sagemaker_runner.py +3 -5
  56. wandb/sdk/launch/utils.py +2 -0
  57. wandb/sdk/lib/apikey.py +1 -1
  58. wandb/sdk/lib/disabled.py +13 -174
  59. wandb/sdk/service/streams.py +2 -4
  60. wandb/sdk/wandb_config.py +1 -1
  61. wandb/sdk/wandb_init.py +77 -33
  62. wandb/sdk/wandb_login.py +6 -6
  63. wandb/sdk/wandb_run.py +150 -90
  64. wandb/sdk/wandb_settings.py +4 -3
  65. wandb/sdk/wandb_setup.py +66 -3
  66. wandb/sdk/wandb_sweep.py +5 -2
  67. wandb/wandb_agent.py +2 -0
  68. {wandb-0.17.5.dist-info → wandb-0.17.7.dist-info}/METADATA +3 -2
  69. {wandb-0.17.5.dist-info → wandb-0.17.7.dist-info}/RECORD +72 -70
  70. {wandb-0.17.5.dist-info → wandb-0.17.7.dist-info}/WHEEL +0 -0
  71. {wandb-0.17.5.dist-info → wandb-0.17.7.dist-info}/entry_points.txt +0 -0
  72. {wandb-0.17.5.dist-info → wandb-0.17.7.dist-info}/licenses/LICENSE +0 -0
wandb/sdk/wandb_run.py CHANGED
@@ -42,6 +42,7 @@ from wandb._globals import _datatypes_set_callback
42
42
  from wandb.apis import internal, public
43
43
  from wandb.apis.internal import Api
44
44
  from wandb.apis.public import Api as PublicApi
45
+ from wandb.errors import CommError
45
46
  from wandb.proto.wandb_internal_pb2 import (
46
47
  MetricRecord,
47
48
  PollExitResponse,
@@ -69,7 +70,7 @@ from wandb.viz import CustomChart, Visualize, custom_chart
69
70
 
70
71
  from . import wandb_config, wandb_metric, wandb_summary
71
72
  from .data_types._dtypes import TypeRegistry
72
- from .interface.interface import GlobStr, InterfaceBase
73
+ from .interface.interface import FilesDict, GlobStr, InterfaceBase, PolicyName
73
74
  from .interface.summary_record import SummaryRecord
74
75
  from .lib import (
75
76
  config_util,
@@ -89,6 +90,7 @@ from .lib.printer import get_printer
89
90
  from .lib.proto_util import message_to_dict
90
91
  from .lib.reporting import Reporter
91
92
  from .lib.wburls import wburls
93
+ from .wandb_alerts import AlertLevel
92
94
  from .wandb_settings import Settings
93
95
  from .wandb_setup import _WandbSetup
94
96
 
@@ -108,9 +110,7 @@ if TYPE_CHECKING:
108
110
  SampledHistoryResponse,
109
111
  )
110
112
 
111
- from .interface.interface import FilesDict, PolicyName
112
113
  from .lib.printer import PrinterJupyter, PrinterTerm
113
- from .wandb_alerts import AlertLevel
114
114
 
115
115
  class GitSourceDict(TypedDict):
116
116
  remote: str
@@ -235,10 +235,10 @@ class RunStatusChecker:
235
235
 
236
236
  with lock:
237
237
  if self._join_event.is_set():
238
- return
238
+ break
239
239
  set_handle(local_handle)
240
240
  try:
241
- result = local_handle.wait(timeout=timeout)
241
+ result = local_handle.wait(timeout=timeout, release=False)
242
242
  except MailboxError:
243
243
  # background threads are oportunistically getting results
244
244
  # from the internal process but the internal process could
@@ -253,6 +253,7 @@ class RunStatusChecker:
253
253
  if result:
254
254
  process(result)
255
255
  # if request finished, clear the handle to send on the next interval
256
+ local_handle.abandon()
256
257
  local_handle = None
257
258
 
258
259
  time_elapsed = time.monotonic() - time_probe
@@ -294,7 +295,7 @@ class RunStatusChecker:
294
295
  if stop_status.run_should_stop:
295
296
  # TODO(frz): This check is required
296
297
  # until WB-3606 is resolved on server side.
297
- if not wandb.agents.pyagent.is_running():
298
+ if not wandb.agents.pyagent.is_running(): # type: ignore
298
299
  thread.interrupt_main()
299
300
  return
300
301
 
@@ -591,8 +592,12 @@ class Run:
591
592
  ) -> None:
592
593
  # pid is set, so we know if this run object was initialized by this process
593
594
  self._init_pid = os.getpid()
595
+ self._settings = settings
596
+
597
+ if settings._noop:
598
+ return
599
+
594
600
  self._init(
595
- settings=settings,
596
601
  config=config,
597
602
  sweep_config=sweep_config,
598
603
  launch_config=launch_config,
@@ -600,12 +605,10 @@ class Run:
600
605
 
601
606
  def _init(
602
607
  self,
603
- settings: Settings,
604
608
  config: Optional[Dict[str, Any]] = None,
605
609
  sweep_config: Optional[Dict[str, Any]] = None,
606
610
  launch_config: Optional[Dict[str, Any]] = None,
607
611
  ) -> None:
608
- self._settings = settings
609
612
  self._config = wandb_config.Config()
610
613
  self._config._set_callback(self._config_callback)
611
614
  self._config._set_artifact_callback(self._config_artifact_callback)
@@ -618,7 +621,7 @@ class Run:
618
621
  )
619
622
  self.summary._set_update_callback(self._summary_update_callback)
620
623
  self._step = 0
621
- self._torch_history: Optional[wandb.wandb_torch.TorchHistory] = None
624
+ self._torch_history: Optional[wandb.wandb_torch.TorchHistory] = None # type: ignore
622
625
 
623
626
  # todo: eventually would be nice to make this configurable using self._settings._start_time
624
627
  # need to test (jhr): if you set start time to 2 days ago and run a test for 15 minutes,
@@ -917,9 +920,9 @@ class Run:
917
920
  self.__dict__.update(state)
918
921
 
919
922
  @property
920
- def _torch(self) -> "wandb.wandb_torch.TorchHistory":
923
+ def _torch(self) -> "wandb.wandb_torch.TorchHistory": # type: ignore
921
924
  if self._torch_history is None:
922
- self._torch_history = wandb.wandb_torch.TorchHistory()
925
+ self._torch_history = wandb.wandb_torch.TorchHistory() # type: ignore
923
926
  return self._torch_history
924
927
 
925
928
  @property
@@ -1086,13 +1089,14 @@ class Run:
1086
1089
  @_run_decorator._attach
1087
1090
  def mode(self) -> str:
1088
1091
  """For compatibility with `0.9.x` and earlier, deprecate eventually."""
1089
- deprecate.deprecate(
1090
- field_name=deprecate.Deprecated.run__mode,
1091
- warning_message=(
1092
- "The mode property of wandb.run is deprecated "
1093
- "and will be removed in a future release."
1094
- ),
1095
- )
1092
+ if hasattr(self, "_telemetry_obj"):
1093
+ deprecate.deprecate(
1094
+ field_name=deprecate.Deprecated.run__mode,
1095
+ warning_message=(
1096
+ "The mode property of wandb.run is deprecated "
1097
+ "and will be removed in a future release."
1098
+ ),
1099
+ )
1096
1100
  return "dryrun" if self._settings._offline else "run"
1097
1101
 
1098
1102
  @property
@@ -1672,15 +1676,15 @@ class Run:
1672
1676
  commit: Optional[bool] = None,
1673
1677
  sync: Optional[bool] = None,
1674
1678
  ) -> None:
1675
- """Log a dictionary of data to the current run's history.
1679
+ """Upload run data.
1676
1680
 
1677
- Use `wandb.log` to log data from runs, such as scalars, images, video,
1681
+ Use `log` to log data from runs, such as scalars, images, video,
1678
1682
  histograms, plots, and tables.
1679
1683
 
1680
1684
  See our [guides to logging](https://docs.wandb.ai/guides/track/log) for
1681
1685
  live examples, code snippets, best practices, and more.
1682
1686
 
1683
- The most basic usage is `wandb.log({"train-loss": 0.5, "accuracy": 0.9})`.
1687
+ The most basic usage is `run.log({"train-loss": 0.5, "accuracy": 0.9})`.
1684
1688
  This will save the loss and accuracy to the run's history and update
1685
1689
  the summary values for these metrics.
1686
1690
 
@@ -1689,48 +1693,91 @@ class Run:
1689
1693
  of the W&B app, or export data to visualize and explore locally, e.g. in
1690
1694
  Jupyter notebooks, with [our API](https://docs.wandb.ai/guides/track/public-api-guide).
1691
1695
 
1692
- In the UI, summary values show up in the run table to compare single values across runs.
1693
- Summary values can also be set directly with `wandb.run.summary["key"] = value`.
1694
-
1695
1696
  Logged values don't have to be scalars. Logging any wandb object is supported.
1696
- For example `wandb.log({"example": wandb.Image("myimage.jpg")})` will log an
1697
+ For example `run.log({"example": wandb.Image("myimage.jpg")})` will log an
1697
1698
  example image which will be displayed nicely in the W&B UI.
1698
1699
  See the [reference documentation](https://docs.wandb.com/ref/python/data-types)
1699
1700
  for all of the different supported types or check out our
1700
1701
  [guides to logging](https://docs.wandb.ai/guides/track/log) for examples,
1701
1702
  from 3D molecular structures and segmentation masks to PR curves and histograms.
1702
- `wandb.Table`s can be used to logged structured data. See our
1703
+ You can use `wandb.Table` to log structured data. See our
1703
1704
  [guide to logging tables](https://docs.wandb.ai/guides/data-vis/log-tables)
1704
1705
  for details.
1705
1706
 
1706
- Logging nested metrics is encouraged and is supported in the W&B UI.
1707
- If you log with a nested dictionary like `wandb.log({"train":
1708
- {"acc": 0.9}, "val": {"acc": 0.8}})`, the metrics will be organized into
1709
- `train` and `val` sections in the W&B UI.
1707
+ The W&B UI organizes metrics with a forward slash (`/`) in their name
1708
+ into sections named using the text before the final slash. For example,
1709
+ the following results in two sections named "train" and "validate":
1710
+
1711
+ ```
1712
+ run.log({
1713
+ "train/accuracy": 0.9,
1714
+ "train/loss": 30,
1715
+ "validate/accuracy": 0.8,
1716
+ "validate/loss": 20,
1717
+ })
1718
+ ```
1719
+
1720
+ Only one level of nesting is supported; `run.log({"a/b/c": 1})`
1721
+ produces a section named "a/b".
1722
+
1723
+ `run.log` is not intended to be called more than a few times per second.
1724
+ For optimal performance, limit your logging to once every N iterations,
1725
+ or collect data over multiple iterations and log it in a single step.
1726
+
1727
+ ### The W&B step
1710
1728
 
1711
- wandb keeps track of a global step, which by default increments with each
1712
- call to `wandb.log`, so logging related metrics together is encouraged.
1713
- If it's inconvenient to log related metrics together
1714
- calling `wandb.log({"train-loss": 0.5}, commit=False)` and then
1715
- `wandb.log({"accuracy": 0.9})` is equivalent to calling
1716
- `wandb.log({"train-loss": 0.5, "accuracy": 0.9})`.
1729
+ With basic usage, each call to `log` creates a new "step".
1730
+ The step must always increase, and it is not possible to log
1731
+ to a previous step.
1717
1732
 
1718
- `wandb.log` is not intended to be called more than a few times per second.
1719
- If you want to log more frequently than that it's better to aggregate
1720
- the data on the client side or you may get degraded performance.
1733
+ Note that you can use any metric as the X axis in charts.
1734
+ In many cases, it is better to treat the W&B step like
1735
+ you'd treat a timestamp rather than a training step.
1736
+
1737
+ ```
1738
+ # Example: log an "epoch" metric for use as an X axis.
1739
+ run.log({"epoch": 40, "train-loss": 0.5})
1740
+ ```
1741
+
1742
+ See also [define_metric](https://docs.wandb.ai/ref/python/run#define_metric).
1743
+
1744
+ It is possible to use multiple `log` invocations to log to
1745
+ the same step with the `step` and `commit` parameters.
1746
+ The following are all equivalent:
1747
+
1748
+ ```
1749
+ # Normal usage:
1750
+ run.log({"train-loss": 0.5, "accuracy": 0.8})
1751
+ run.log({"train-loss": 0.4, "accuracy": 0.9})
1752
+
1753
+ # Implicit step without auto-incrementing:
1754
+ run.log({"train-loss": 0.5}, commit=False)
1755
+ run.log({"accuracy": 0.8})
1756
+ run.log({"train-loss": 0.4}, commit=False)
1757
+ run.log({"accuracy": 0.9})
1758
+
1759
+ # Explicit step:
1760
+ run.log({"train-loss": 0.5}, step=current_step)
1761
+ run.log({"accuracy": 0.8}, step=current_step)
1762
+ current_step += 1
1763
+ run.log({"train-loss": 0.4}, step=current_step)
1764
+ run.log({"accuracy": 0.9}, step=current_step)
1765
+ ```
1721
1766
 
1722
1767
  Arguments:
1723
- data: (dict, optional) A dict of serializable python objects i.e `str`,
1724
- `ints`, `floats`, `Tensors`, `dicts`, or any of the `wandb.data_types`.
1725
- commit: (boolean, optional) Save the metrics dict to the wandb server
1726
- and increment the step. If false `wandb.log` just updates the current
1727
- metrics dict with the data argument and metrics won't be saved until
1728
- `wandb.log` is called with `commit=True`.
1729
- step: (integer, optional) The global step in processing. This persists
1730
- any non-committed earlier steps but defaults to not committing the
1731
- specified step.
1732
- sync: (boolean, True) This argument is deprecated and currently doesn't
1733
- change the behaviour of `wandb.log`.
1768
+ data: A `dict` with `str` keys and values that are serializable
1769
+ Python objects including: `int`, `float` and `string`;
1770
+ any of the `wandb.data_types`; lists, tuples and NumPy arrays
1771
+ of serializable Python objects; other `dict`s of this
1772
+ structure.
1773
+ step: The step number to log. If `None`, then an implicit
1774
+ auto-incrementing step is used. See the notes in
1775
+ the description.
1776
+ commit: If true, finalize and upload the step. If false, then
1777
+ accumulate data for the step. See the notes in the description.
1778
+ If `step` is `None`, then the default is `commit=True`;
1779
+ otherwise, the default is `commit=False`.
1780
+ sync: This argument is deprecated and does nothing.
1734
1781
 
1735
1782
  Examples:
1736
1783
  For more and more detailed examples, see
@@ -1882,7 +1929,7 @@ class Run:
1882
1929
  self,
1883
1930
  glob_str: Optional[Union[str, os.PathLike]] = None,
1884
1931
  base_path: Optional[Union[str, os.PathLike]] = None,
1885
- policy: "PolicyName" = "live",
1932
+ policy: PolicyName = "live",
1886
1933
  ) -> Union[bool, List[str]]:
1887
1934
  """Sync one or more files to W&B.
1888
1935
 
@@ -2155,12 +2202,13 @@ class Run:
2155
2202
  @_run_decorator._attach
2156
2203
  def join(self, exit_code: Optional[int] = None) -> None:
2157
2204
  """Deprecated alias for `finish()` - use finish instead."""
2158
- deprecate.deprecate(
2159
- field_name=deprecate.Deprecated.run__join,
2160
- warning_message=(
2161
- "wandb.run.join() is deprecated, please use wandb.run.finish()."
2162
- ),
2163
- )
2205
+ if hasattr(self, "_telemetry_obj"):
2206
+ deprecate.deprecate(
2207
+ field_name=deprecate.Deprecated.run__join,
2208
+ warning_message=(
2209
+ "wandb.run.join() is deprecated, please use wandb.run.finish()."
2210
+ ),
2211
+ )
2164
2212
  self._finish(exit_code=exit_code)
2165
2213
 
2166
2214
  @_run_decorator._noop_on_finish()
@@ -2365,11 +2413,7 @@ class Run:
2365
2413
  return
2366
2414
  self._atexit_cleanup_called = True
2367
2415
 
2368
- exit_code = (
2369
- exit_code #
2370
- or (self._hooks and self._hooks.exit_code)
2371
- or 0
2372
- )
2416
+ exit_code = exit_code or (self._hooks and self._hooks.exit_code) or 0
2373
2417
  self._exit_code = exit_code
2374
2418
  logger.info(f"got exitcode: {exit_code}")
2375
2419
 
@@ -2386,7 +2430,7 @@ class Run:
2386
2430
  self._on_finish()
2387
2431
 
2388
2432
  except KeyboardInterrupt:
2389
- if not wandb.wandb_agent._is_running():
2433
+ if not wandb.wandb_agent._is_running(): # type: ignore
2390
2434
  wandb.termerror("Control-C detected -- Run data was not synced")
2391
2435
  raise
2392
2436
 
@@ -2703,29 +2747,48 @@ class Run:
2703
2747
  summary: Optional[str] = None,
2704
2748
  goal: Optional[str] = None,
2705
2749
  overwrite: Optional[bool] = None,
2706
- **kwargs: Any,
2707
2750
  ) -> wandb_metric.Metric:
2708
- """Define metric properties which will later be logged with `wandb.log()`.
2751
+ """Customize metrics logged with `wandb.log()`.
2709
2752
 
2710
2753
  Arguments:
2711
- name: Name of the metric.
2712
- step_metric: Independent variable associated with the metric.
2713
- step_sync: Automatically add `step_metric` to history if needed.
2714
- Defaults to True if step_metric is specified.
2754
+ name: The name of the metric to customize.
2755
+ step_metric: The name of another metric to serve as the X-axis
2756
+ for this metric in automatically generated charts.
2757
+ step_sync: Automatically insert the last value of step_metric into
2758
+ `run.log()` if it is not provided explicitly. Defaults to True
2759
+ if step_metric is specified.
2715
2760
  hidden: Hide this metric from automatic plots.
2716
2761
  summary: Specify aggregate metrics added to summary.
2717
- Supported aggregations: "min,max,mean,best,last,none"
2718
- Default aggregation is `copy`
2719
- Aggregation `best` defaults to `goal`==`minimize`
2720
- goal: Specify direction for optimizing the metric.
2721
- Supported directions: "minimize,maximize"
2762
+ Supported aggregations include "min", "max", "mean", "last",
2763
+ "best", "copy" and "none". "best" is used together with the
2764
+ goal parameter. "none" prevents a summary from being generated.
2765
+ "copy" is deprecated and should not be used.
2766
+ goal: Specify how to interpret the "best" summary type.
2767
+ Supported options are "minimize" and "maximize".
2768
+ overwrite: If false, then this call is merged with previous
2769
+ `define_metric` calls for the same metric by using their
2770
+ values for any unspecified parameters. If true, then
2771
+ unspecified parameters overwrite values specified by
2772
+ previous calls.
2722
2773
 
2723
2774
  Returns:
2724
- A metric object is returned that can be further specified.
2725
-
2775
+ An object that represents this call but can otherwise be discarded.
2726
2776
  """
2777
+ if summary and "copy" in summary:
2778
+ deprecate.deprecate(
2779
+ deprecate.Deprecated.run__define_metric_copy,
2780
+ "define_metric(summary='copy') is deprecated and will be removed.",
2781
+ self,
2782
+ )
2783
+
2727
2784
  return self._define_metric(
2728
- name, step_metric, step_sync, hidden, summary, goal, overwrite, **kwargs
2785
+ name,
2786
+ step_metric,
2787
+ step_sync,
2788
+ hidden,
2789
+ summary,
2790
+ goal,
2791
+ overwrite,
2729
2792
  )
2730
2793
 
2731
2794
  def _define_metric(
@@ -2737,12 +2800,9 @@ class Run:
2737
2800
  summary: Optional[str] = None,
2738
2801
  goal: Optional[str] = None,
2739
2802
  overwrite: Optional[bool] = None,
2740
- **kwargs: Any,
2741
2803
  ) -> wandb_metric.Metric:
2742
2804
  if not name:
2743
2805
  raise wandb.Error("define_metric() requires non-empty name argument")
2744
- for k in kwargs:
2745
- wandb.termwarn(f"Unhandled define_metric() arg: {k}")
2746
2806
  if isinstance(step_metric, wandb_metric.Metric):
2747
2807
  step_metric = step_metric.name
2748
2808
  for arg_name, arg_val, exp_type in (
@@ -2820,12 +2880,12 @@ class Run:
2820
2880
  idx=None,
2821
2881
  log_graph=False,
2822
2882
  ) -> None:
2823
- wandb.watch(models, criterion, log, log_freq, idx, log_graph)
2883
+ wandb.watch(models, criterion, log, log_freq, idx, log_graph) # type: ignore
2824
2884
 
2825
2885
  # TODO(jhr): annotate this
2826
2886
  @_run_decorator._attach
2827
2887
  def unwatch(self, models=None) -> None: # type: ignore
2828
- wandb.unwatch(models=models)
2888
+ wandb.unwatch(models=models) # type: ignore
2829
2889
 
2830
2890
  # TODO(kdg): remove all artifact swapping logic
2831
2891
  def _swap_artifact_name(self, artifact_name: str, use_as: Optional[str]) -> str:
@@ -3495,7 +3555,7 @@ class Run:
3495
3555
  artifact = self._log_artifact(
3496
3556
  artifact_or_path=path, name=name, type=artifact.type
3497
3557
  )
3498
- except (ValueError, wandb.CommError):
3558
+ except (ValueError, CommError):
3499
3559
  artifact = self._log_artifact(
3500
3560
  artifact_or_path=path, name=name, type="model"
3501
3561
  )
@@ -3515,13 +3575,13 @@ class Run:
3515
3575
  Arguments:
3516
3576
  title: (str) The title of the alert, must be less than 64 characters long.
3517
3577
  text: (str) The text body of the alert.
3518
- level: (str or wandb.AlertLevel, optional) The alert level to use, either: `INFO`, `WARN`, or `ERROR`.
3578
+ level: (str or AlertLevel, optional) The alert level to use, either: `INFO`, `WARN`, or `ERROR`.
3519
3579
  wait_duration: (int, float, or timedelta, optional) The time to wait (in seconds) before sending another
3520
3580
  alert with this title.
3521
3581
  """
3522
- level = level or wandb.AlertLevel.INFO
3523
- level_str: str = level.value if isinstance(level, wandb.AlertLevel) else level
3524
- if level_str not in {lev.value for lev in wandb.AlertLevel}:
3582
+ level = level or AlertLevel.INFO
3583
+ level_str: str = level.value if isinstance(level, AlertLevel) else level
3584
+ if level_str not in {lev.value for lev in AlertLevel}:
3525
3585
  raise ValueError("level must be one of 'INFO', 'WARN', or 'ERROR'")
3526
3586
 
3527
3587
  wait_duration = wait_duration or timedelta(minutes=1)
@@ -3704,12 +3764,12 @@ class Run:
3704
3764
  return
3705
3765
 
3706
3766
  if printer._html:
3707
- if not wandb.jupyter.maybe_display():
3767
+ if not wandb.jupyter.maybe_display(): # type: ignore
3708
3768
  run_line = f"<strong>{printer.link(run_url, run_name)}</strong>"
3709
3769
  project_line, sweep_line = "", ""
3710
3770
 
3711
3771
  # TODO(settings): make settings the source of truth
3712
- if not wandb.jupyter.quiet():
3772
+ if not wandb.jupyter.quiet(): # type: ignore
3713
3773
  doc_html = printer.link(wburls.get("doc_run"), "docs")
3714
3774
 
3715
3775
  project_html = printer.link(project_url, "Weights & Biases")
@@ -1715,7 +1715,7 @@ class Settings(SettingsData):
1715
1715
 
1716
1716
  # Attempt to get notebook information if not already set by the user
1717
1717
  if self._jupyter and (self.notebook_name is None or self.notebook_name == ""):
1718
- meta = wandb.jupyter.notebook_metadata(self.silent)
1718
+ meta = wandb.jupyter.notebook_metadata(self.silent) # type: ignore
1719
1719
  settings["_jupyter_path"] = meta.get("path")
1720
1720
  settings["_jupyter_name"] = meta.get("name")
1721
1721
  settings["_jupyter_root"] = meta.get("root")
@@ -1882,9 +1882,10 @@ class Settings(SettingsData):
1882
1882
  if self.resume_from is None:
1883
1883
  return
1884
1884
 
1885
- if self.run_id is not None:
1885
+ if self.run_id is not None and (self.resume_from.run != self.run_id):
1886
1886
  wandb.termwarn(
1887
- "You cannot specify both run_id and resume_from. " "Ignoring run_id."
1887
+ "Both `run_id` and `resume_from` have been specified with different ids. "
1888
+ "`run_id` will be ignored."
1888
1889
  )
1889
1890
  self.update({"run_id": self.resume_from.run}, source=Source.INIT)
1890
1891
 
wandb/sdk/wandb_setup.py CHANGED
@@ -319,14 +319,77 @@ def _setup(
319
319
  return wl
320
320
 
321
321
 
322
- def setup(
323
- settings: Optional[Settings] = None,
324
- ) -> Optional["_WandbSetup"]:
322
+ def setup(settings: Optional[Settings] = None) -> Optional["_WandbSetup"]:
323
+ """Prepares W&B for use in the current process and its children.
324
+
325
+ You can usually ignore this as it is implicitly called by `wandb.init()`.
326
+
327
+ When using wandb in multiple processes, calling `wandb.setup()`
328
+ in the parent process before starting child processes may improve
329
+ performance and resource utilization.
330
+
331
+ Note that `wandb.setup()` modifies `os.environ`, and it is important
332
+ that child processes inherit the modified environment variables.
333
+
334
+ See also `wandb.teardown()`.
335
+
336
+ Args:
337
+ settings (Optional[Union[Dict[str, Any], wandb.Settings]]): Configuration settings
338
+ to apply globally. These can be overridden by subsequent `wandb.init()` calls.
339
+
340
+ Example:
341
+ ```python
342
+ import multiprocessing
343
+
344
+ import wandb
345
+
346
+
347
+ def run_experiment(params):
348
+ with wandb.init(config=params):
349
+ # Run experiment
350
+ pass
351
+
352
+
353
+ if __name__ == "__main__":
354
+ # Start backend and set global config
355
+ wandb.setup(settings={"project": "my_project"})
356
+
357
+ # Define experiment parameters
358
+ experiment_params = [
359
+ {"learning_rate": 0.01, "epochs": 10},
360
+ {"learning_rate": 0.001, "epochs": 20},
361
+ ]
362
+
363
+ # Start multiple processes, each running a separate experiment
364
+ processes = []
365
+ for params in experiment_params:
366
+ p = multiprocessing.Process(target=run_experiment, args=(params,))
367
+ p.start()
368
+ processes.append(p)
369
+
370
+ # Wait for all processes to complete
371
+ for p in processes:
372
+ p.join()
373
+
374
+ # Optional: Explicitly shut down the backend
375
+ wandb.teardown()
376
+ ```
377
+ """
325
378
  ret = _setup(settings=settings)
326
379
  return ret
327
380
 
328
381
 
329
382
  def teardown(exit_code: Optional[int] = None) -> None:
383
+ """Waits for wandb to finish and frees resources.
384
+
385
+ Completes any runs that were not explicitly finished
386
+ using `run.finish()` and waits for all data to be uploaded.
387
+
388
+ It is recommended to call this at the end of a session
389
+ that used `wandb.setup()`. It is invoked automatically
390
+ in an `atexit` hook, but this is not reliable in certain setups
391
+ such as when using Python's `multiprocessing` module.
392
+ """
330
393
  setup_instance = _WandbSetup._instance
331
394
  _WandbSetup._instance = None
332
395
 
wandb/sdk/wandb_sweep.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import urllib.parse
2
- from typing import Callable, Dict, List, Optional, Union
2
+ from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Union
3
3
 
4
4
  import wandb
5
5
  from wandb import env
@@ -8,6 +8,9 @@ from wandb.sdk.launch.sweeps.utils import handle_sweep_config_violations
8
8
 
9
9
  from . import wandb_login
10
10
 
11
+ if TYPE_CHECKING:
12
+ from wandb.wandb_controller import _WandbController
13
+
11
14
 
12
15
  def _get_sweep_url(api, sweep_id):
13
16
  """Return sweep url if we can figure it out."""
@@ -93,7 +96,7 @@ def controller(
93
96
  sweep_id_or_config: Optional[Union[str, Dict]] = None,
94
97
  entity: Optional[str] = None,
95
98
  project: Optional[str] = None,
96
- ):
99
+ ) -> "_WandbController":
97
100
  """Public sweep controller constructor.
98
101
 
99
102
  Usage:
wandb/wandb_agent.py CHANGED
@@ -43,6 +43,8 @@ class AgentProcess:
43
43
  kwargs = dict(creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
44
44
  else:
45
45
  kwargs = dict(preexec_fn=os.setpgrp)
46
+ if env.get(wandb.env.SERVICE):
47
+ env.pop(wandb.env.SERVICE)
46
48
  self._popen = subprocess.Popen(command, env=env, **kwargs)
47
49
  elif function:
48
50
  self._proc = multiprocessing.Process(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: wandb
3
- Version: 0.17.5
3
+ Version: 0.17.7
4
4
  Summary: A CLI and library for interacting with the Weights & Biases API.
5
5
  Project-URL: Source, https://github.com/wandb/wandb
6
6
  Project-URL: Bug Reports, https://github.com/wandb/wandb/issues
@@ -71,7 +71,7 @@ Requires-Dist: google-cloud-storage; extra == 'gcp'
71
71
  Provides-Extra: importers
72
72
  Requires-Dist: filelock; extra == 'importers'
73
73
  Requires-Dist: mlflow; extra == 'importers'
74
- Requires-Dist: polars; extra == 'importers'
74
+ Requires-Dist: polars<=1.2.1; extra == 'importers'
75
75
  Requires-Dist: rich; extra == 'importers'
76
76
  Requires-Dist: tenacity; extra == 'importers'
77
77
  Provides-Extra: kubeflow
@@ -93,6 +93,7 @@ Requires-Dist: google-cloud-artifact-registry; extra == 'launch'
93
93
  Requires-Dist: google-cloud-compute; extra == 'launch'
94
94
  Requires-Dist: google-cloud-storage; extra == 'launch'
95
95
  Requires-Dist: iso8601; extra == 'launch'
96
+ Requires-Dist: jsonschema; extra == 'launch'
96
97
  Requires-Dist: kubernetes; extra == 'launch'
97
98
  Requires-Dist: kubernetes-asyncio; extra == 'launch'
98
99
  Requires-Dist: nbconvert; extra == 'launch'