lightly-train 0.2.2__tar.gz → 0.2.4__tar.gz

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 (143) hide show
  1. lightly_train-0.2.4/.github/pull_request_template.md +7 -0
  2. {lightly_train-0.2.2 → lightly_train-0.2.4}/.github/workflows/build_docker_image.yml +2 -2
  3. {lightly_train-0.2.2 → lightly_train-0.2.4}/.gitignore +1 -0
  4. {lightly_train-0.2.2 → lightly_train-0.2.4}/DOCS.md +26 -5
  5. {lightly_train-0.2.2 → lightly_train-0.2.4}/Makefile +3 -3
  6. {lightly_train-0.2.2 → lightly_train-0.2.4}/PKG-INFO +3 -1
  7. {lightly_train-0.2.2 → lightly_train-0.2.4}/docker/Dockerfile-amd64-cuda +7 -8
  8. {lightly_train-0.2.2 → lightly_train-0.2.4}/docker/Makefile +19 -6
  9. {lightly_train-0.2.2 → lightly_train-0.2.4}/docker/README.md +14 -1
  10. {lightly_train-0.2.2 → lightly_train-0.2.4}/pyproject.toml +7 -0
  11. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/__init__.py +9 -1
  12. lightly_train-0.2.4/src/lightly_train/_callbacks/callback_args.py +45 -0
  13. lightly_train-0.2.4/src/lightly_train/_callbacks/callback_helpers.py +75 -0
  14. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_callbacks/checkpoint.py +15 -4
  15. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_checkpoint.py +28 -2
  16. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_cli.py +60 -8
  17. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_commands/_warnings.py +23 -0
  18. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_commands/common_helpers.py +30 -15
  19. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_commands/embed.py +24 -4
  20. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_commands/export.py +19 -5
  21. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_commands/extract_video_frames.py +23 -4
  22. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_commands/train.py +57 -5
  23. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_commands/train_helpers.py +57 -46
  24. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_loggers/jsonl.py +12 -3
  25. lightly_train-0.2.4/src/lightly_train/_loggers/logger_args.py +23 -0
  26. lightly_train-0.2.4/src/lightly_train/_loggers/logger_helpers.py +89 -0
  27. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_loggers/tensorboard.py +14 -0
  28. lightly_train-0.2.4/src/lightly_train/_loggers/wandb.py +32 -0
  29. lightly_train-0.2.4/src/lightly_train/_logging.py +171 -0
  30. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_methods/densecl.py +6 -6
  31. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_methods/densecldino.py +5 -6
  32. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_methods/dino.py +6 -6
  33. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_methods/method.py +48 -1
  34. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_methods/simclr.py +7 -8
  35. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/timm/timm.py +4 -2
  36. lightly_train-0.2.4/src/lightly_train/_plot.py +95 -0
  37. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_transforms.py +7 -0
  38. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train.egg-info/PKG-INFO +3 -1
  39. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train.egg-info/SOURCES.txt +13 -0
  40. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train.egg-info/requires.txt +3 -0
  41. lightly_train-0.2.4/tests/_callbacks/test_callback_helpers.py +154 -0
  42. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_commands/test_common_helpers.py +83 -20
  43. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_commands/test_embed.py +28 -5
  44. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_commands/test_train.py +52 -3
  45. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_commands/test_train_helpers.py +46 -4
  46. lightly_train-0.2.4/tests/_loggers/test_logger_helpers.py +158 -0
  47. lightly_train-0.2.4/tests/_optim/__init__.py +7 -0
  48. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/test__cli.py +13 -10
  49. lightly_train-0.2.4/tests/test__logging.py +88 -0
  50. lightly_train-0.2.4/tests/test__plot.py +31 -0
  51. {lightly_train-0.2.2 → lightly_train-0.2.4}/.github/workflows/release_dockerhub.yml +0 -0
  52. {lightly_train-0.2.2 → lightly_train-0.2.4}/.github/workflows/release_pypi.yml +0 -0
  53. {lightly_train-0.2.2 → lightly_train-0.2.4}/.github/workflows/test.yml +0 -0
  54. {lightly_train-0.2.2 → lightly_train-0.2.4}/.github/workflows/test_code_format.yml +0 -0
  55. {lightly_train-0.2.2 → lightly_train-0.2.4}/.github/workflows/test_docker.yml +0 -0
  56. {lightly_train-0.2.2 → lightly_train-0.2.4}/.github/workflows/test_minimal_deps.yml +0 -0
  57. {lightly_train-0.2.2 → lightly_train-0.2.4}/.github/workflows/weekly_dependency_tests.yml +0 -0
  58. {lightly_train-0.2.2 → lightly_train-0.2.4}/CONTRIBUTE.md +0 -0
  59. {lightly_train-0.2.2 → lightly_train-0.2.4}/LICENSE +0 -0
  60. {lightly_train-0.2.2 → lightly_train-0.2.4}/README.md +0 -0
  61. {lightly_train-0.2.2 → lightly_train-0.2.4}/dev_tools/licenseheader.tmpl +0 -0
  62. {lightly_train-0.2.2 → lightly_train-0.2.4}/setup.cfg +0 -0
  63. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_callbacks/__init__.py +0 -0
  64. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_commands/__init__.py +0 -0
  65. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_configs/__init__.py +0 -0
  66. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_configs/config.py +0 -0
  67. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_configs/omegaconf_utils.py +0 -0
  68. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_configs/validate.py +0 -0
  69. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_constants.py +0 -0
  70. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_embedding/__init__.py +0 -0
  71. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_embedding/embedding_format.py +0 -0
  72. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_embedding/embedding_predictor.py +0 -0
  73. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_embedding/embedding_transform.py +0 -0
  74. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_embedding/writers/__init__.py +0 -0
  75. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_embedding/writers/csv_writer.py +0 -0
  76. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_embedding/writers/embedding_writer.py +0 -0
  77. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_embedding/writers/torch_writer.py +0 -0
  78. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_embedding/writers/writer_helpers.py +0 -0
  79. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_loggers/__init__.py +0 -0
  80. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_methods/__init__.py +0 -0
  81. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_methods/method_args.py +0 -0
  82. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_methods/method_helpers.py +0 -0
  83. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/__init__.py +0 -0
  84. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/custom/__init__.py +0 -0
  85. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/custom/custom.py +0 -0
  86. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/custom/custom_package.py +0 -0
  87. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/embedding/__init__.py +0 -0
  88. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/embedding/base.py +0 -0
  89. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/embedding_model.py +0 -0
  90. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/feature_extractor.py +0 -0
  91. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/package.py +0 -0
  92. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/package_helpers.py +0 -0
  93. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/super_gradients/__init__.py +0 -0
  94. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/super_gradients/customizable_detector.py +0 -0
  95. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/super_gradients/super_gradients.py +0 -0
  96. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/super_gradients/super_gradients_package.py +0 -0
  97. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/timm/__init__.py +0 -0
  98. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/timm/timm_package.py +0 -0
  99. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/torchvision/__init__.py +0 -0
  100. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/torchvision/convnext.py +0 -0
  101. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/torchvision/resnet.py +0 -0
  102. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/torchvision/torchvision.py +0 -0
  103. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_models/torchvision/torchvision_package.py +0 -0
  104. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_optim/__init__.py +0 -0
  105. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_optim/adamw_args.py +0 -0
  106. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_optim/optimizer.py +0 -0
  107. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_optim/optimizer_args.py +0 -0
  108. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_optim/optimizer_type.py +0 -0
  109. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_optim/trainable_modules.py +0 -0
  110. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/_scaling.py +0 -0
  111. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/errors.py +0 -0
  112. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train/types.py +0 -0
  113. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train.egg-info/dependency_links.txt +0 -0
  114. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train.egg-info/entry_points.txt +0 -0
  115. {lightly_train-0.2.2 → lightly_train-0.2.4}/src/lightly_train.egg-info/top_level.txt +0 -0
  116. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/__init__.py +0 -0
  117. {lightly_train-0.2.2/tests/_commands → lightly_train-0.2.4/tests/_callbacks}/__init__.py +0 -0
  118. {lightly_train-0.2.2/tests/_configs → lightly_train-0.2.4/tests/_commands}/__init__.py +0 -0
  119. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_commands/test_export.py +0 -0
  120. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_commands/test_extract_video_frames.py +0 -0
  121. {lightly_train-0.2.2/tests/_embedding → lightly_train-0.2.4/tests/_configs}/__init__.py +0 -0
  122. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_configs/test_validate.py +0 -0
  123. {lightly_train-0.2.2/tests/_embedding/writers → lightly_train-0.2.4/tests/_embedding}/__init__.py +0 -0
  124. {lightly_train-0.2.2/tests/_methods → lightly_train-0.2.4/tests/_embedding/writers}/__init__.py +0 -0
  125. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_embedding/writers/test_csv_writer.py +0 -0
  126. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_embedding/writers/test_torch_writer.py +0 -0
  127. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_embedding/writers/test_writer_helpers.py +0 -0
  128. {lightly_train-0.2.2/tests/_models → lightly_train-0.2.4/tests/_methods}/__init__.py +0 -0
  129. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_methods/test_method_helpers.py +0 -0
  130. {lightly_train-0.2.2/tests/_models/custom → lightly_train-0.2.4/tests/_models}/__init__.py +0 -0
  131. {lightly_train-0.2.2/tests/_models/timm → lightly_train-0.2.4/tests/_models/custom}/__init__.py +0 -0
  132. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_models/custom/test_custom.py +0 -0
  133. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_models/custom/test_custom_package.py +0 -0
  134. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_models/super_gradients/test_super_gradients_package.py +0 -0
  135. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_models/test_package_helpers.py +0 -0
  136. {lightly_train-0.2.2/tests/_optim → lightly_train-0.2.4/tests/_models/timm}/__init__.py +0 -0
  137. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_models/timm/test_timm.py +0 -0
  138. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_models/timm/test_timm_package.py +0 -0
  139. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_models/torchvision/test_torchvision_package.py +0 -0
  140. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/_optim/test_optimizer.py +0 -0
  141. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/helpers.py +0 -0
  142. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/test__checkpoint.py +0 -0
  143. {lightly_train-0.2.2 → lightly_train-0.2.4}/tests/test__scaling.py +0 -0
@@ -0,0 +1,7 @@
1
+ ## What has changed and why?
2
+
3
+ (Delete this: Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.)
4
+
5
+ ## How has it been tested?
6
+
7
+ (Delete this: Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration.)
@@ -52,7 +52,7 @@ jobs:
52
52
  if: ${{ needs.build-docker-image.result == 'success' }}
53
53
  uses: rtCamp/action-slack-notify@v2
54
54
  env:
55
- SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_RELEASES }}
55
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_RELEASES_DEV }}
56
56
  SLACK_ICON_EMOJI: ":train:"
57
57
  SLACK_USERNAME: "Build of LightlyTrain Docker Image"
58
58
  SLACK_COLOR: "good"
@@ -71,7 +71,7 @@ jobs:
71
71
  if: ${{ needs.build-docker-image.result != 'success' }}
72
72
  uses: rtCamp/action-slack-notify@v2
73
73
  env:
74
- SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_RELEASES }}
74
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_RELEASES_DEV }}
75
75
  SLACK_ICON_EMOJI: ":x:"
76
76
  SLACK_USERNAME: "Build of LightlyTrain Docker Image"
77
77
  SLACK_COLOR: "danger"
@@ -1,5 +1,6 @@
1
1
  *.code-workspace
2
2
  lightly_train_docker_test_data
3
+ out
3
4
 
4
5
  # Created by https://www.toptal.com/developers/gitignore/api/macos,windows,linux,python
5
6
  # Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,linux,python
@@ -27,12 +27,20 @@ lightly_train.train(
27
27
 
28
28
  In most cases you only have to specify `out`, `data`, and `model`. The rest is optional.
29
29
 
30
- The training process can be monitored with TensorBoard (requires
31
- `pip install lightly-train[tensorboard]`):
30
+ You can monitor your training process with the help of `tensorboard` and `wandb` loggers:
32
31
  ```
33
- tensorboard --logdir my_output_dir
32
+ pip install "lightly-train[tensorboard, wandb]"
34
33
  ```
35
34
 
35
+ Configure the loggers from Python:
36
+ * `loggers={"tensorboard": True}`: Enable `tensorboard` logger with default arguments.
37
+ * `loggers={"wandb": True}`: Enable `wandb` logger with default arguments.
38
+ * `loggers={"wandb": {"project": "my-project"}}`: Configure `wandb` logger with custom arguments.
39
+
40
+ LightlyTrain uses the PyTorchLightning loggers under the hood. Learn more about their configuration:
41
+ * https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.loggers.wandb.html
42
+ * https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.loggers.tensorboard.html
43
+
36
44
  #### Exporting
37
45
  ```python
38
46
  import lightly_train
@@ -94,8 +102,21 @@ lightly-train train \
94
102
 
95
103
  In most cases you only have to specify `out`, `data`, and `model`. The rest is optional.
96
104
 
97
- The training process can be monitored with TensorBoard (requires
98
- `pip install lightly-train[tensorboard]`):
105
+ You can monitor your training process with the help of `tensorboard` and `wandb` loggers:
106
+ ```
107
+ pip install "lightly-train[tensorboard, wandb]"
108
+ ```
109
+
110
+ Configure the loggers from the command-line:
111
+ * `loggers.tensorboard=True`: Enable `tensorboard` logger with default arguments.
112
+ * `loggers.wandb=True`: Enable `wandb` logger with default arguments.
113
+ * `loggers.wandb.project="my-project"`: Configure `wandb` logger with custom arguments.
114
+
115
+ LightlyTrain uses the PyTorchLightning loggers under the hood. Learn more about their configuration:
116
+ * https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.loggers.wandb.html
117
+ * https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.loggers.tensorboard.html
118
+
119
+
99
120
  ```
100
121
  tensorboard --logdir my_output_dir
101
122
  ```
@@ -72,7 +72,7 @@ test:
72
72
 
73
73
  .PHONY: test-ci
74
74
  test-ci:
75
- pytest tests --capture=no -v
75
+ pytest tests -v
76
76
 
77
77
 
78
78
  ### Virtual Environment
@@ -105,8 +105,8 @@ endif
105
105
 
106
106
  # SuperGradients is not compatible with Python>=3.10. It is also not easy to install
107
107
  # on MacOS. Therefore we exclude it from the default extras.
108
- EXTRAS = [dev,tensorboard,timm]
109
- DOCKER_EXTRAS = --extra tensorboard --extra timm
108
+ EXTRAS = [dev,tensorboard,timm,wandb]
109
+ DOCKER_EXTRAS = --extra tensorboard --extra timm --extra wandb
110
110
 
111
111
  # Date until which dependencies installed with --exclude-newer must have been released.
112
112
  # Dependencies released after this date are ignored.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lightly_train
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Train models with self-supervised learning in a single command
5
5
  Author: Lightly Team
6
6
  License: AGPL-3.0
@@ -28,6 +28,8 @@ Provides-Extra: tensorboard
28
28
  Requires-Dist: tensorboard>=2.10.0; extra == "tensorboard"
29
29
  Provides-Extra: timm
30
30
  Requires-Dist: timm>=1.0.3; extra == "timm"
31
+ Provides-Extra: wandb
32
+ Requires-Dist: wandb>=0.12.10; extra == "wandb"
31
33
 
32
34
  # LightlyTrain
33
35
 
@@ -4,10 +4,8 @@
4
4
  # Start FROM PyTorch image https://hub.docker.com/r/pytorch/pytorch
5
5
  FROM pytorch/pytorch:2.3.0-cuda11.8-cudnn8-runtime AS runtime
6
6
 
7
- # Set the environment variable for the volume mounting
8
- ENV LIGHTLY_TRAIN_IS_DOCKER="True" \
9
- # Install packages into the system Python and skip creating a virtual environment.
10
- UV_SYSTEM_PYTHON="true" \
7
+ # Install packages into the system Python and skip creating a virtual environment.
8
+ ENV UV_SYSTEM_PYTHON="true" \
11
9
  # Do not cache dependencies as they would also be saved in the docker image.
12
10
  UV_NO_CACHE="true"
13
11
 
@@ -19,8 +17,8 @@ WORKDIR /home/lightly_train
19
17
 
20
18
  # Install uv
21
19
  COPY Makefile /home/lightly_train
22
-
23
20
  RUN make install-uv
21
+
24
22
  # Add uv to PATH
25
23
  ENV PATH="/root/.cargo/bin:$PATH"
26
24
 
@@ -31,8 +29,9 @@ RUN make install-docker-dependencies
31
29
  # Copy the package itself
32
30
  COPY src /home/lightly_train/src
33
31
 
32
+ # Set and create the directory to save pretrained torch models into
33
+ ENV TORCH_HOME="/home/lightly_train/.cache/torch"
34
+ RUN mkdir -p ${TORCH_HOME} && chmod -R a+w $TORCH_HOME
35
+
34
36
  # Install the package.
35
37
  RUN make install-docker
36
-
37
- # Default command that runs when the container starts.
38
- ENTRYPOINT ["lightly-train"]
@@ -62,15 +62,28 @@ test:
62
62
  @echo "Generate images"
63
63
  mkdir -p $(LIGHTLY_TRAIN_DATA)
64
64
  python -c 'from PIL import Image; [Image.new("RGB", (250, 300)).save(f"$(LIGHTLY_TRAIN_DATA)/{i}.png") for i in range(5)]'
65
+ @echo "Create output directory"
66
+ mkdir -p $(LIGHTLY_TRAIN_OUT)
67
+ chmod -R +rw $(LIGHTLY_TRAIN_OUT)
68
+ docker run --rm --shm-size=1g --user $(shell id -u):$(shell id -g) \
69
+ -v $(LIGHTLY_TRAIN_OUT):/out \
70
+ -v $(LIGHTLY_TRAIN_DATA):/data \
71
+ -v ./Makefile:/home/lightly_train/docker/Makefile \
72
+ --gpus all \
73
+ lightly/$(IMAGE):$(TAG) make test-cli-from-within-docker -C docker
74
+
75
+ # This target is run from within the docker container
76
+ test-cli-from-within-docker:
65
77
  @echo "Test train"
66
- docker run --rm --shm-size=1g --user $(id -u):$(id -g) -v $(LIGHTLY_TRAIN_OUT):/out -v $(LIGHTLY_TRAIN_DATA):/data lightly/$(IMAGE):$(TAG) train model="torchvision/convnext_small" epochs=2 batch_size=2
67
- test -f $(LIGHTLY_TRAIN_OUT)/checkpoints/last.ckpt
78
+ lightly-train train data=/data out=/out model="torchvision/convnext_small" epochs=2 batch_size=2 model_args.weights="IMAGENET1K_V1" devices=2
79
+ test -f /out/checkpoints/last.ckpt
80
+ test `grep -c "GPU available: True (cuda), used: True" /out/train.log` -gt 0
68
81
  @echo "Test embed"
69
- docker run --rm --shm-size=1g --user $(id -u):$(id -g) -v $(LIGHTLY_TRAIN_OUT):/out -v $(LIGHTLY_TRAIN_DATA):/data lightly/train:$(TAG) embed out="/out/embeddings.csv" checkpoint="/out/checkpoints/last.ckpt" batch_size=2 format="csv"
70
- test `wc -l < $(LIGHTLY_TRAIN_OUT)/embeddings.csv` -eq 6
82
+ lightly-train embed data=/data out="/out/embeddings.csv" checkpoint="/out/checkpoints/last.ckpt" batch_size=2 format="csv"
83
+ test `wc -l < /out/embeddings.csv` -eq 6
71
84
  @echo "Test export"
72
- docker run --rm --shm-size=1g --user $(id -u):$(id -g) -v $(LIGHTLY_TRAIN_OUT):/out -v $(LIGHTLY_TRAIN_DATA):/data lightly/train:$(TAG) export out="/out/model.pth" checkpoint="/out/checkpoints/last.ckpt" part="model" format="torch_state_dict"
73
- test -f $(LIGHTLY_TRAIN_OUT)/model.pth
85
+ lightly-train export out="/out/model.pth" checkpoint="/out/checkpoints/last.ckpt" part="model" format="torch_state_dict"
86
+ test -f /out/model.pth
74
87
 
75
88
 
76
89
 
@@ -21,7 +21,20 @@ TODO
21
21
 
22
22
  ## Usage
23
23
 
24
- TODO
24
+ First, start the docker container in interactive mode by using the -it flag. Furthermore,
25
+ you must mount the directories you want to use.
26
+
27
+ ```
28
+ docker run -it --gpus=all --user $(id -u):$(id -g) -v /my_data_dir:/data -v /my_output_dir:/out lightly/train:latest
29
+ ```
30
+
31
+ Then all the usual CLI commands are fully available. E.g. run
32
+
33
+ ```
34
+ lightly-train train data="/data" out="/out" model="torchvision/convnext_small" method=dino
35
+ ```
36
+
37
+
25
38
 
26
39
 
27
40
  ## Development
@@ -52,6 +52,9 @@ tensorboard = [
52
52
  timm = [
53
53
  "timm>=1.0.3",
54
54
  ]
55
+ wandb = [
56
+ "wandb>=0.12.10", # required by pytorch-lightning
57
+ ]
55
58
 
56
59
  [project.scripts]
57
60
  lightly-train = "lightly_train._cli:_cli_entrypoint"
@@ -89,3 +92,7 @@ known-first-party = ["lightly_train"]
89
92
  [tool.ruff.lint.pydocstyle]
90
93
  # Use Google-style docstrings.
91
94
  convention = "google"
95
+
96
+ [tool.ruff.lint.per-file-ignores]
97
+ # Ignore `E402` (import violations) in root `__init__.py`.
98
+ "src/lightly_train/__init__.py" = ["E402"]
@@ -5,6 +5,14 @@
5
5
  # This source code is licensed under the license found in the
6
6
  # LICENSE file in the root directory of this source tree.
7
7
  #
8
+
9
+ # Disable beta transforms warning by torchvision.
10
+ # See https://stackoverflow.com/questions/77279407
11
+ # TODO(Philipp, 09/24): Remove this once the warning is removed.
12
+ import torchvision
13
+
14
+ torchvision.disable_beta_transforms_warning()
15
+
8
16
  from lightly_train._commands.embed import embed
9
17
  from lightly_train._commands.export import ModelFormat, ModelPart, export
10
18
  from lightly_train._commands.train import train
@@ -23,4 +31,4 @@ __all__ = [
23
31
  "train",
24
32
  ]
25
33
 
26
- __version__ = "0.2.2"
34
+ __version__ = "0.2.4"
@@ -0,0 +1,45 @@
1
+ #
2
+ # Copyright (c) Lightly AG and affiliates.
3
+ # All rights reserved.
4
+ #
5
+ # This source code is licensed under the license found in the
6
+ # LICENSE file in the root directory of this source tree.
7
+ #
8
+ from dataclasses import dataclass, field
9
+ from typing import Optional
10
+
11
+ from lightly_train._callbacks.checkpoint import ModelCheckpointArgs
12
+ from lightly_train._configs.config import Config
13
+
14
+
15
+ @dataclass
16
+ class LearningRateMonitorArgs(Config):
17
+ pass
18
+
19
+
20
+ @dataclass
21
+ class DeviceStatsMonitorArgs(Config):
22
+ pass
23
+
24
+
25
+ @dataclass
26
+ class EarlyStoppingArgs(Config):
27
+ monitor: str = "train_loss"
28
+ patience: int = int(1e12)
29
+ check_finite: bool = True
30
+
31
+
32
+ @dataclass
33
+ class CallbackArgs(Config):
34
+ learning_rate_monitor: Optional[LearningRateMonitorArgs] = field(
35
+ default_factory=LearningRateMonitorArgs
36
+ )
37
+ device_stats_monitor: Optional[DeviceStatsMonitorArgs] = field(
38
+ default_factory=DeviceStatsMonitorArgs
39
+ )
40
+ early_stopping: Optional[EarlyStoppingArgs] = field(
41
+ default_factory=EarlyStoppingArgs
42
+ )
43
+ model_checkpoint: Optional[ModelCheckpointArgs] = field(
44
+ default_factory=ModelCheckpointArgs
45
+ )
@@ -0,0 +1,75 @@
1
+ #
2
+ # Copyright (c) Lightly AG and affiliates.
3
+ # All rights reserved.
4
+ #
5
+ # This source code is licensed under the license found in the
6
+ # LICENSE file in the root directory of this source tree.
7
+ #
8
+ from __future__ import annotations
9
+
10
+ import dataclasses
11
+ from pathlib import Path
12
+ from typing import Any
13
+
14
+ from omegaconf import OmegaConf
15
+ from pytorch_lightning import Callback
16
+ from pytorch_lightning.callbacks import (
17
+ DeviceStatsMonitor,
18
+ EarlyStopping,
19
+ LearningRateMonitor,
20
+ )
21
+ from torch.nn import Module
22
+
23
+ from lightly_train._callbacks.callback_args import (
24
+ CallbackArgs,
25
+ )
26
+ from lightly_train._callbacks.checkpoint import ModelCheckpoint
27
+ from lightly_train._checkpoint import CheckpointLightlyTrainModels
28
+ from lightly_train._configs import validate
29
+ from lightly_train._models.embedding_model import EmbeddingModel
30
+
31
+
32
+ def validate_callback_args(callback_dict: dict[str, Any] | None) -> CallbackArgs:
33
+ callback_dictconfig = OmegaConf.create(
34
+ {} if callback_dict is None else callback_dict
35
+ )
36
+ callback_dictconfig = validate.validate_dictconfig(
37
+ callback_dictconfig, CallbackArgs
38
+ )
39
+ callback_args = OmegaConf.to_object(callback_dictconfig)
40
+ assert isinstance(callback_args, CallbackArgs) # make mypy happy
41
+ return callback_args
42
+
43
+
44
+ def get_callbacks(
45
+ callback_args: CallbackArgs,
46
+ out: Path,
47
+ model: Module,
48
+ embedding_model: EmbeddingModel,
49
+ ):
50
+ callbacks: list[Callback] = []
51
+ if callback_args.learning_rate_monitor is not None:
52
+ callbacks.append(
53
+ LearningRateMonitor(
54
+ **dataclasses.asdict(callback_args.learning_rate_monitor)
55
+ )
56
+ )
57
+ if callback_args.device_stats_monitor is not None:
58
+ callbacks.append(
59
+ DeviceStatsMonitor(**dataclasses.asdict(callback_args.device_stats_monitor))
60
+ )
61
+ if callback_args.early_stopping is not None:
62
+ callbacks.append(
63
+ EarlyStopping(**dataclasses.asdict(callback_args.early_stopping))
64
+ )
65
+ if callback_args.model_checkpoint is not None:
66
+ callbacks.append(
67
+ ModelCheckpoint(
68
+ models=CheckpointLightlyTrainModels(
69
+ model=model, embedding_model=embedding_model
70
+ ),
71
+ dirpath=out / "checkpoints",
72
+ **dataclasses.asdict(callback_args.model_checkpoint),
73
+ )
74
+ )
75
+ return callbacks
@@ -7,9 +7,10 @@
7
7
  #
8
8
  from __future__ import annotations
9
9
 
10
- import warnings
10
+ import logging
11
+ from dataclasses import dataclass
11
12
  from datetime import timedelta
12
- from typing import Any
13
+ from typing import Any, Optional
13
14
 
14
15
  from pytorch_lightning import LightningModule, Trainer
15
16
  from pytorch_lightning.callbacks import ModelCheckpoint as _ModelCheckpoint
@@ -19,8 +20,19 @@ from lightly_train._checkpoint import (
19
20
  CheckpointLightlyTrain,
20
21
  CheckpointLightlyTrainModels,
21
22
  )
23
+ from lightly_train._configs.config import Config
22
24
  from lightly_train.types import PathLike
23
25
 
26
+ logger = logging.getLogger(__name__)
27
+
28
+
29
+ @dataclass
30
+ class ModelCheckpointArgs(Config):
31
+ save_last: bool = True
32
+ enable_version_counter: bool = False
33
+ save_top_k: int = 1
34
+ every_n_epochs: Optional[int] = None
35
+
24
36
 
25
37
  class ModelCheckpoint(_ModelCheckpoint):
26
38
  def __init__(
@@ -78,7 +90,6 @@ class ModelCheckpoint(_ModelCheckpoint):
78
90
  checkpoint
79
91
  ).models
80
92
  except KeyError as ex:
81
- warnings.warn(
93
+ logger.warning(
82
94
  f"Could not restore lightly_train models from checkpoint: {ex}"
83
95
  )
84
- pass
@@ -8,6 +8,7 @@
8
8
  from __future__ import annotations
9
9
 
10
10
  import dataclasses
11
+ import logging
11
12
  from dataclasses import dataclass
12
13
  from datetime import datetime, timezone
13
14
  from pathlib import Path
@@ -21,6 +22,8 @@ from torch.serialization import MAP_LOCATION
21
22
  import lightly_train
22
23
  from lightly_train._models.embedding_model import EmbeddingModel
23
24
 
25
+ logger = logging.getLogger(__name__)
26
+
24
27
  CHECKPOINT_LIGHTLY_TRAIN_KEY = "lightly_train"
25
28
 
26
29
 
@@ -104,11 +107,34 @@ class Checkpoint:
104
107
 
105
108
  @staticmethod
106
109
  def from_path(
107
- checkpoint: Path, map_location: MAP_LOCATION | None = "cpu"
110
+ checkpoint: Path,
111
+ map_location: MAP_LOCATION | None = "cpu",
112
+ weights_only: bool = False,
108
113
  ) -> Checkpoint:
109
- checkpoint_dict = torch.load(checkpoint, map_location=map_location)
114
+ """Load a checkpoint from a file path.
115
+
116
+ Args:
117
+ checkpoint:
118
+ Path to the checkpoint file.
119
+ map_location:
120
+ If map_location is a string, it must be a key in torch.device, such as
121
+ 'cpu' or 'cuda:0'. If map_location is a torch.device, it will be used to
122
+ determine where the checkpoint should be loaded to. Default: 'cpu'.
123
+ weights_only:
124
+ If False (default), the whole checkpoint is loaded. If True, only the weights
125
+ of the model are loaded. This requires the user to add safe globals with:
126
+ https://pytorch.org/docs/stable/notes/serialization.html#torch.serialization.add_safe_globals
127
+ TODO(Philipp, 09/24): Expose weights_only argument to the user.
128
+ """
129
+ logger.debug(
130
+ f"Loading checkpoint from '{checkpoint}' with map_location '{map_location}' and weights_only {weights_only}"
131
+ )
132
+ checkpoint_dict = torch.load(
133
+ checkpoint, map_location=map_location, weights_only=weights_only
134
+ )
110
135
  return Checkpoint.from_dict(checkpoint=checkpoint_dict)
111
136
 
112
137
  def save(self, path: Path) -> None:
138
+ logger.debug(f"Saving checkpoint to '{path}'")
113
139
  path.parent.mkdir(parents=True, exist_ok=True)
114
140
  torch.save(self.to_dict(), path)
@@ -6,17 +6,23 @@
6
6
  # LICENSE file in the root directory of this source tree.
7
7
  #
8
8
  import inspect
9
+ import logging
10
+ import os
9
11
  import sys
10
12
  from typing import Callable
11
13
 
12
14
  from omegaconf import DictConfig, OmegaConf
13
15
 
14
16
  import lightly_train
17
+ from lightly_train import _logging
15
18
  from lightly_train._commands import embed, export, extract_video_frames, train
16
19
  from lightly_train._commands.train import TrainConfig
20
+ from lightly_train._logging import LIGHTLY_TRAIN_LOG_LEVEL_ENV_VAR
17
21
  from lightly_train._models import package_helpers
18
22
  from lightly_train.errors import ConfigError
19
23
 
24
+ logger = logging.getLogger(__name__)
25
+
20
26
  _HELP_COMMANDS = {"help", "--help", "-h"}
21
27
  _HELP_MSG = """
22
28
  Commands:
@@ -28,7 +34,10 @@ _HELP_MSG = """
28
34
  lightly-train extract_video_frames Extract frames from videos using ffmpeg.
29
35
  lightly-train help Show help message.
30
36
 
31
- Run `lightly_train <command> help` for more information on a specific command.
37
+ Run `lightly-train <command> help` for more information on a specific command.
38
+
39
+ Optional arguments:
40
+ -v, --verbose Run the command in verbose mode for detailed output.
32
41
  """
33
42
 
34
43
  _train_cfg = TrainConfig()
@@ -96,6 +105,20 @@ _TRAIN_HELP_MSG = f"""
96
105
  For details, see: https://lightning.ai/docs/pytorch/stable/common/trainer.html#precision
97
106
  seed (int):
98
107
  Random seed for reproducibility. Default: {_train_cfg.seed}
108
+ loggers (dict):
109
+ Loggers for training. Either null or a dictionary of logger names to either
110
+ null or a dictionary of logger arguments. Null uses the default loggers.
111
+ To disable a logger, set it to null: `loggers.tensorboard=null`.
112
+ To configure a logger, pass the respective arguments:
113
+ `loggers.wandb.project="my_project"`.
114
+ Default: null
115
+ callbacks (dict):
116
+ Callbacks fo training. Either null or a dictionary of callback names to
117
+ either null or a dictionary of callback arguments. Null uses the default
118
+ callbacks. To disable a callback, set it to null:
119
+ `callbacks.model_checkpoint=null`. To configure a callback, pass the
120
+ respective arguments: `callbacks.model_checkpoint.every_n_epochs=5`.
121
+ Default: null
99
122
  optim_args (dict):
100
123
  Arguments for AdamW optimizer. Available arguments are:
101
124
  - lr (float)
@@ -115,6 +138,9 @@ _TRAIN_HELP_MSG = f"""
115
138
  Additional arguments for the model. The available arguments depend on the
116
139
  the `model` parameter.
117
140
 
141
+ Optional arguments:
142
+ -v, --verbose Run the command in verbose mode for detailed output.
143
+
118
144
  Examples:
119
145
  # Train a ResNet-18 model with SimCLR on ImageNet
120
146
  lightly-train train out=out data=imagenet/train model=torchvision/resnet18 method=simclr
@@ -147,12 +173,15 @@ _EXPORT_HELP_MSG = """
147
173
  Format to save the model in. Valid options are 'torch_model' and
148
174
  'torch_state_dict'. 'torch_model' saves the model as a torch module which
149
175
  can be loaded with `model = torch.load(out)`. This requires that the same
150
- lightly_train version is installed when the model is exported and when it is
176
+ LightlyTrain version is installed when the model is exported and when it is
151
177
  loaded again. 'torch_state_dict' saves the model's state dict which can be
152
178
  loaded with `model.load_state_dict(torch.load(out))`. This is more flexible
153
- and can be used to load the model with different lightly_train versions but
179
+ and can be used to load the model with different LightlyTrain versions but
154
180
  requires the model to already be instantiated.
155
181
 
182
+ Optional arguments:
183
+ -v, --verbose Run the command in verbose mode for detailed output.
184
+
156
185
  Examples:
157
186
  # Export the state dict of the model
158
187
  lightly-train export checkpoint=out/checkpoints/last.ckpt out=out/model.pth \\
@@ -201,6 +230,9 @@ _EMBED_HELP_MSG = """
201
230
  overwrite (bool):
202
231
  Overwrite the output file if it already exists.
203
232
 
233
+ Optional arguments:
234
+ -v, --verbose Run the command in verbose mode for detailed output.
235
+
204
236
  Examples:
205
237
  # Embed images from a model checkpoint
206
238
  lightly-train embed out=embeddings.csv data=images checkpoint=out/checkpoints/last.ckpt \\
@@ -245,6 +277,9 @@ _EXTRACT_VIDEO_FRAMES_HELP_MSG = f"""
245
277
  Number of parallel calls to ffmpeg when processing multiple videos.
246
278
  If None, the number of workers is set to the number of available CPU cores.
247
279
 
280
+ Optional arguments:
281
+ -v, --verbose Run the command in verbose mode for detailed output.
282
+
248
283
  Examples:
249
284
  # Extract frames from videos
250
285
  lightly-train extract_video_frames data=videos out=frames
@@ -257,12 +292,25 @@ _EXTRACT_VIDEO_FRAMES_HELP_MSG = f"""
257
292
  """
258
293
 
259
294
 
295
+ _VERBOSE_FLAGS = ["-v", "--verbose"]
296
+
297
+
260
298
  def cli(config: DictConfig) -> None:
299
+ keys = list(config.keys())
300
+
301
+ # Check if the user wants to run the command in verbose mode.
302
+ # Any of the following will enable verbose mode: -v, --verbose
303
+ if any(flag in keys for flag in _VERBOSE_FLAGS):
304
+ os.environ[LIGHTLY_TRAIN_LOG_LEVEL_ENV_VAR] = str(logging.DEBUG)
305
+ config = OmegaConf.create(
306
+ {k: v for k, v in config.items() if k not in _VERBOSE_FLAGS}
307
+ )
308
+ _logging.set_up_console_logging()
309
+
261
310
  if config.is_empty():
262
311
  _show_help()
263
312
  return
264
313
 
265
- keys = list(config.keys())
266
314
  # First argument after lightly_train is the command. For example `lightly-train train ...`
267
315
  command = str(keys[0]).lower()
268
316
  help_if_config_empty = True
@@ -336,17 +384,21 @@ def _run_command_fn(
336
384
  try:
337
385
  command_fn(config)
338
386
  except ConfigError as ex:
387
+ logger.error(ex)
388
+ raise ex from None # Shorten stacktrace
389
+ except Exception as ex:
390
+ logger.error(ex)
339
391
  raise ex from None # Shorten stacktrace
340
392
 
341
393
 
342
394
  def _list_models(config: DictConfig) -> None:
343
395
  lines = [f" {model}" for model in package_helpers.list_model_names()]
344
- print("\n".join(lines))
396
+ logger.info("\n".join(lines))
345
397
 
346
398
 
347
399
  def _list_methods(config: DictConfig) -> None:
348
400
  lines = [f" {method}" for method in lightly_train.list_methods()]
349
- print("\n".join(lines))
401
+ logger.info("\n".join(lines))
350
402
 
351
403
 
352
404
  def _is_help_command_in_config(config: DictConfig) -> bool:
@@ -361,7 +413,7 @@ def _show_invalid_command_help(command: str) -> None:
361
413
  msg = _format_msg(
362
414
  f"""
363
415
  Unknown command '{command}':
364
- lightly_train {command}
416
+ lightly-train {command}
365
417
  """
366
418
  )
367
419
  msg += "\n"
@@ -370,7 +422,7 @@ def _show_invalid_command_help(command: str) -> None:
370
422
 
371
423
 
372
424
  def _show_msg(msg: str) -> None:
373
- print(_format_msg(msg))
425
+ logger.info(_format_msg(msg))
374
426
 
375
427
 
376
428
  def _format_msg(msg: str) -> str:
@@ -37,6 +37,29 @@ def filter_train_warnings() -> None:
37
37
  "in this directory can be modified when the new ones are saved!"
38
38
  ),
39
39
  )
40
+ # Ignore mixed precision CUDA warnings as the information that CUDA is not available
41
+ # can be found elsewhere. The same warnings don't pop up for full precision training.
42
+ warnings.filterwarnings(
43
+ "ignore",
44
+ message="User provided device_type of 'cuda', but CUDA is not available.",
45
+ module="torch.amp",
46
+ category=UserWarning,
47
+ )
48
+ warnings.filterwarnings(
49
+ "ignore",
50
+ message="torch.cuda.amp.GradScaler is enabled, but CUDA is not available.",
51
+ module="torch.amp",
52
+ category=UserWarning,
53
+ )
54
+ # Ignore `lr_scheduler.step()` before `optimizer.step()` warning as it's a PyTorch Lightning issue.
55
+ # See https://github.com/Lightning-AI/pytorch-lightning/issues/5558
56
+ # TODO(Philipp, 09/24): Remove this once the issue is resolved.
57
+ warnings.filterwarnings(
58
+ "ignore",
59
+ message="Detected call of \`lr_scheduler.step\(\)\` before \`optimizer.step\(\)\`",
60
+ category=UserWarning,
61
+ module="torch.optim.lr_scheduler",
62
+ )
40
63
 
41
64
 
42
65
  def filter_embed_warnings() -> None: