We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
_lightly_cli is missing it's return statement
as a side effect `train_model_and_embed_images` is not working as expected.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lightly/cli/embed_cli.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """**Lightly Embed:** Embed images with one command.
3 
4 This module contains the entrypoint for the **lightly-embed**
5 command-line interface.
6 """
7 
8 # Copyright (c) 2020. Lightly AG and its affiliates.
9 # All Rights Reserved
10 
11 import os
12 
13 import hydra
14 import torch
15 import torchvision
16 from torch.utils.hipify.hipify_python import bcolors
17 
18 from lightly.data import LightlyDataset
19 
20 from lightly.utils import save_embeddings
21 
22 from lightly.cli._helpers import get_model_from_config
23 from lightly.cli._helpers import fix_input_path
24 from lightly.cli._helpers import cpu_count
25 
26 
27 def _embed_cli(cfg, is_cli_call=True):
28     input_dir = cfg['input_dir']
29     if input_dir and is_cli_call:
30         input_dir = fix_input_path(input_dir)
31 
32     torch.backends.cudnn.deterministic = True
33     torch.backends.cudnn.benchmark = False
34 
35     if torch.cuda.is_available():
36         device = torch.device('cuda')
37     else:
38         device = torch.device('cpu')
39 
40     transform = torchvision.transforms.Compose(
41         [
42             torchvision.transforms.Resize(
43                 (cfg['collate']['input_size'], cfg['collate']['input_size'])
44             ),
45             torchvision.transforms.ToTensor(),
46             torchvision.transforms.Normalize(
47                 mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
48             ),
49         ]
50     )
51 
52     dataset = LightlyDataset(input_dir, transform=transform)
53 
54     # disable drop_last and shuffle
55     cfg['loader']['drop_last'] = False
56     cfg['loader']['shuffle'] = False
57     cfg['loader']['batch_size'] = min(cfg['loader']['batch_size'], len(dataset))
58 
59     # determine the number of available cores
60     if cfg['loader']['num_workers'] < 0:
61         cfg['loader']['num_workers'] = cpu_count()
62 
63     dataloader = torch.utils.data.DataLoader(dataset, **cfg['loader'])
64 
65     encoder = get_model_from_config(cfg, is_cli_call)
66 
67     embeddings, labels, filenames = encoder.embed(dataloader, device=device)
68 
69     if is_cli_call:
70         path = os.path.join(os.getcwd(), 'embeddings.csv')
71         save_embeddings(path, embeddings, labels, filenames)
72         print(f'Embeddings are stored at {bcolors.OKBLUE}{path}{bcolors.ENDC}')
73         os.environ[
74             cfg['environment_variable_names']['lightly_last_embedding_path']
75         ] = path
76         return path
77 
78     return embeddings, labels, filenames
79 
80 
81 @hydra.main(config_path='config', config_name='config')
82 def embed_cli(cfg):
83     """Embed images from the command-line.
84 
85     Args:
86         cfg:
87             The default configs are loaded from the config file.
88             To overwrite them please see the section on the config file
89             (.config.config.yaml).
90 
91     Command-Line Args:
92         input_dir:
93             Path to the input directory where images are stored.
94         checkpoint:
95             Path to the checkpoint of a pretrained model. If left
96             empty, a pretrained model by lightly is used.
97 
98     Examples:
99         >>> # embed images with default settings and a lightly model
100         >>> lightly-embed input_dir=data/
101         >>>
102         >>> # embed images with default settings and a custom checkpoint
103         >>> lightly-embed input_dir=data/ checkpoint=my_checkpoint.ckpt
104         >>>
105         >>> # embed images with custom settings
106         >>> lightly-embed input_dir=data/ model.num_ftrs=32
107 
108     """
109     return _embed_cli(cfg)
110 
111 
112 def entry():
113     embed_cli()
114
```

Path: `lightly/core.py`
Content:
```
1 """ Contains the core functionality of the lightly Python package. """
2 
3 # Copyright (c) 2020. Lightly AG and its affiliates.
4 # All Rights Reserved
5 
6 from lightly.cli.train_cli import _train_cli
7 from lightly.cli.embed_cli import _embed_cli
8 from lightly.cli.lightly_cli import _lightly_cli
9 import lightly.cli as cli
10 
11 import yaml
12 import os
13 
14 
15 def _get_config_path(config_path):
16     """Find path to yaml config file
17 
18     Args:
19         config_path: (str) Path to config.yaml file
20 
21     Returns:
22         Path to config.yaml if specified else default config.yaml
23 
24     Raises:
25         ValueError: If the config_path is not None but doesn't exist
26 
27     """
28     if config_path is None:
29         dirname = os.path.dirname(cli.__file__)
30         config_path = os.path.join(dirname, 'config/config.yaml')
31     if not os.path.exists(config_path):
32         raise ValueError("Config path {} does not exist!".format(config_path))
33 
34     return config_path
35 
36 
37 def _load_config_file(config_path):
38     """Load a yaml config file
39 
40     Args:
41         config_path: (str) Path to config.yaml file
42 
43     Returns:
44         Dictionary with configs from config.yaml
45 
46     """
47     Loader = yaml.FullLoader
48     with open(config_path, 'r') as config_file:
49         cfg = yaml.load(config_file, Loader=Loader)
50 
51     return cfg
52 
53 
54 def _add_kwargs(cfg, kwargs):
55     """Add keyword arguments to config
56 
57     Args:
58         cfg: (dict) Dictionary of configs from config.yaml
59         kwargs: (dict) Dictionary of keyword arguments
60 
61     Returns:
62         Union of cfg and kwargs
63 
64     """
65     for key, item in kwargs.items():
66         if isinstance(item, dict):
67             if key in cfg:
68                 cfg[key] = _add_kwargs(cfg[key], item)
69             else:
70                 cfg[key] = item
71         else:
72             cfg[key] = item
73     return cfg
74 
75 
76 def train_model_and_embed_images(config_path: str = None, **kwargs):
77     """Train a self-supervised model and use it to embed images.
78 
79     Calls the same function as lightly-magic. All arguments passed to
80     lightly-magic can also be passed to this function (see below for an
81     example).
82 
83     Args:
84         config_path:
85             Path to config.yaml. If None, the default configs will be used.
86         **kwargs:
87             Overwrite default configs py passing keyword arguments.
88 
89     Returns:
90         Embeddings, labels, and filenames of the images.
91 
92     Examples:
93         >>> import lightly
94         >>>
95         >>> # train a model and embed images with default configs
96         >>> embeddings, _, _ = lightly.train_model_and_embed_images(
97         >>>     input_dir='path/to/data')
98         >>>
99         >>> # train a model and embed images with separate config file
100         >>> my_config_path = 'my/config/file.yaml'
101         >>> embeddings, _, _ = lightly.train_model_and_embed_images(
102         >>>     input_dir='path/to/data', config_path=my_config_path)
103         >>>
104         >>> # train a model and embed images with default settings + overwrites
105         >>> my_trainer = {max_epochs: 10}
106         >>> embeddings, _, _ = lightly.train_model_and_embed_images(
107         >>>     input_dir='path/to/data', trainer=my_trainer)
108         >>> # the command above is equivalent to:
109         >>> # lightly-magic input_dir='path/to/data' trainer.max_epochs=10
110 
111     """
112     config_path = _get_config_path(config_path)
113     config_args = _load_config_file(config_path)
114     config_args = _add_kwargs(config_args, kwargs)
115     return _lightly_cli(config_args, is_cli_call=False)
116 
117 
118 def train_embedding_model(config_path: str = None, **kwargs):
119     """Train a self-supervised model.
120 
121     Calls the same function as lightly-train. All arguments passed to
122     lightly-train can also be passed to this function (see below for an
123     example).
124 
125     Args:
126         config_path:
127             Path to config.yaml. If None, the default configs will be used.
128         **kwargs:
129             Overwrite default configs py passing keyword arguments.
130 
131     Returns:
132         Path to checkpoint of the trained embedding model.
133 
134     Examples:
135         >>> import lightly
136         >>>
137         >>> # train a model with default configs
138         >>> checkpoint_path = lightly.train_embedding_model(
139         >>>     input_dir='path/to/data')
140         >>>
141         >>> # train a model with separate config file
142         >>> my_config_path = 'my/config/file.yaml'
143         >>> checkpoint_path = lightly.train_embedding_model(
144         >>>     input_dir='path/to/data', config_path=my_config_path)
145         >>>
146         >>> # train a model with default settings and overwrites: large batch
147         >>> # sizes are benefitial for self-supervised training and more 
148         >>> # workers speed up the dataloading process.
149         >>> my_loader = {
150         >>>     batch_size: 100,
151         >>>     num_workers: 8,
152         >>> }
153         >>> checkpoint_path = lightly.train_embedding_model(
154         >>>     input_dir='path/to/data', loader=my_loader)
155         >>> # the command above is equivalent to:
156         >>> # lightly-train input_dir='path/to/data' loader.batch_size=100 loader.num_workers=8
157     """
158     config_path = _get_config_path(config_path)
159     config_args = _load_config_file(config_path)
160     config_args = _add_kwargs(config_args, kwargs)
161 
162     return _train_cli(config_args, is_cli_call=False)
163 
164 
165 def embed_images(checkpoint: str, config_path: str = None, **kwargs):
166     """Embed images with a self-supervised model.
167 
168     Calls the same function as lightly-embed. All arguments passed to
169     lightly-embed can also be passed to this function (see below for an
170     example).
171 
172     Args:
173         checkpoint:
174             Path to the checkpoint file for the embedding model.
175         config_path:
176             Path to config.yaml. If None, the default configs will be used.
177         **kwargs:
178             Overwrite default configs py passing keyword arguments.
179 
180     Returns:
181         Embeddings, labels, and filenames of the images.
182 
183     Examples:
184         >>> import lightly
185         >>> my_checkpoint_path = 'path/to/checkpoint.ckpt'
186         >>>
187         >>> # embed images with default configs
188         >>> embeddings, _, _ = lightly.embed_images(
189         >>>     my_checkpoint_path, input_dir='path/to/data')
190         >>>
191         >>> # embed images with separate config file
192         >>> my_config_path = 'my/config/file.yaml'
193         >>> embeddings, _, _ = lightly.embed_images(
194         >>>     my_checkpoint_path, input_dir='path/to/data', config_path=my_config_path)
195         >>>
196         >>> # embed images with default settings and overwrites: at inference,
197         >>> # we can use larger input_sizes because it requires less memory.
198         >>> my_collate = {input_size: 256}
199         >>> embeddings, _, _ = lightly.embed_images(
200         >>>     my_checkpoint_path, input_dir='path/to/data', collate=my_collate)
201         >>> # the command above is equivalent to:
202         >>> # lightly-embed input_dir='path/to/data' collate.input_size=256
203 
204     """
205     config_path = _get_config_path(config_path)
206     config_args = _load_config_file(config_path)
207     config_args = _add_kwargs(config_args, kwargs)
208 
209     config_args['checkpoint'] = checkpoint
210 
211     return _embed_cli(config_args, is_cli_call=False)
212
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lightly/cli/embed_cli.py b/lightly/cli/embed_cli.py
--- a/lightly/cli/embed_cli.py
+++ b/lightly/cli/embed_cli.py
@@ -9,8 +9,10 @@
 # All Rights Reserved
 
 import os
+from typing import Union, Tuple, List
 
 import hydra
+import numpy as np
 import torch
 import torchvision
 from torch.utils.hipify.hipify_python import bcolors
@@ -24,7 +26,21 @@
 from lightly.cli._helpers import cpu_count
 
 
-def _embed_cli(cfg, is_cli_call=True):
+def _embed_cli(cfg, is_cli_call=True) -> \
+    Union[
+        Tuple[np.ndarray, List[int], List[str]],
+        str
+    ]:
+    """ See embed_cli() for usage documentation
+
+        is_cli_call:
+            If True:
+                Saves the embeddings as file and returns the filepath.
+            If False:
+                Returns the embeddings, labels, filenames as tuple.
+                Embeddings are of shape (n_samples, embedding_size)
+                len(labels) = len(filenames) = n_samples
+    """
     input_dir = cfg['input_dir']
     if input_dir and is_cli_call:
         input_dir = fix_input_path(input_dir)
@@ -79,7 +95,7 @@
 
 
 @hydra.main(config_path='config', config_name='config')
-def embed_cli(cfg):
+def embed_cli(cfg) -> str:
     """Embed images from the command-line.
 
     Args:
@@ -95,6 +111,9 @@
             Path to the checkpoint of a pretrained model. If left
             empty, a pretrained model by lightly is used.
 
+    Returns:
+        The path to the created embeddings file.
+
     Examples:
         >>> # embed images with default settings and a lightly model
         >>> lightly-embed input_dir=data/
diff --git a/lightly/core.py b/lightly/core.py
--- a/lightly/core.py
+++ b/lightly/core.py
@@ -2,6 +2,9 @@
 
 # Copyright (c) 2020. Lightly AG and its affiliates.
 # All Rights Reserved
+from typing import Tuple, List
+
+import numpy as np
 
 from lightly.cli.train_cli import _train_cli
 from lightly.cli.embed_cli import _embed_cli
@@ -73,12 +76,15 @@
     return cfg
 
 
-def train_model_and_embed_images(config_path: str = None, **kwargs):
+def train_model_and_embed_images(config_path: str = None, **kwargs) -> Tuple[
+    np.ndarray, List[int], List[str]
+]:
     """Train a self-supervised model and use it to embed images.
 
-    Calls the same function as lightly-magic. All arguments passed to
-    lightly-magic can also be passed to this function (see below for an
-    example).
+    First trains a modle using the _train_cli(),
+    then embeds with the _embed_cli().
+    All arguments passed to the CLI functions
+    can also be passed to this function (see below for an example).
 
     Args:
         config_path:
@@ -88,6 +94,8 @@
 
     Returns:
         Embeddings, labels, and filenames of the images.
+        Embeddings are of shape (n_samples, embedding_size)
+        len(labels) = len(filenames) = n_samples
 
     Examples:
         >>> import lightly
@@ -105,14 +113,16 @@
         >>> my_trainer = {max_epochs: 10}
         >>> embeddings, _, _ = lightly.train_model_and_embed_images(
         >>>     input_dir='path/to/data', trainer=my_trainer)
-        >>> # the command above is equivalent to:
-        >>> # lightly-magic input_dir='path/to/data' trainer.max_epochs=10
 
     """
     config_path = _get_config_path(config_path)
     config_args = _load_config_file(config_path)
     config_args = _add_kwargs(config_args, kwargs)
-    return _lightly_cli(config_args, is_cli_call=False)
+
+    checkpoint = _train_cli(config_args, is_cli_call=False)
+    config_args['checkpoint'] = checkpoint
+    embeddings, labels, filenames = _embed_cli(config_args, is_cli_call=False)
+    return embeddings, labels, filenames
 
 
 def train_embedding_model(config_path: str = None, **kwargs):

{"golden_diff": "diff --git a/lightly/cli/embed_cli.py b/lightly/cli/embed_cli.py\n--- a/lightly/cli/embed_cli.py\n+++ b/lightly/cli/embed_cli.py\n@@ -9,8 +9,10 @@\n # All Rights Reserved\n \n import os\n+from typing import Union, Tuple, List\n \n import hydra\n+import numpy as np\n import torch\n import torchvision\n from torch.utils.hipify.hipify_python import bcolors\n@@ -24,7 +26,21 @@\n from lightly.cli._helpers import cpu_count\n \n \n-def _embed_cli(cfg, is_cli_call=True):\n+def _embed_cli(cfg, is_cli_call=True) -> \\\n+    Union[\n+        Tuple[np.ndarray, List[int], List[str]],\n+        str\n+    ]:\n+    \"\"\" See embed_cli() for usage documentation\n+\n+        is_cli_call:\n+            If True:\n+                Saves the embeddings as file and returns the filepath.\n+            If False:\n+                Returns the embeddings, labels, filenames as tuple.\n+                Embeddings are of shape (n_samples, embedding_size)\n+                len(labels) = len(filenames) = n_samples\n+    \"\"\"\n     input_dir = cfg['input_dir']\n     if input_dir and is_cli_call:\n         input_dir = fix_input_path(input_dir)\n@@ -79,7 +95,7 @@\n \n \n @hydra.main(config_path='config', config_name='config')\n-def embed_cli(cfg):\n+def embed_cli(cfg) -> str:\n     \"\"\"Embed images from the command-line.\n \n     Args:\n@@ -95,6 +111,9 @@\n             Path to the checkpoint of a pretrained model. If left\n             empty, a pretrained model by lightly is used.\n \n+    Returns:\n+        The path to the created embeddings file.\n+\n     Examples:\n         >>> #\u00a0embed images with default settings and a lightly model\n         >>> lightly-embed input_dir=data/\ndiff --git a/lightly/core.py b/lightly/core.py\n--- a/lightly/core.py\n+++ b/lightly/core.py\n@@ -2,6 +2,9 @@\n \n # Copyright (c) 2020. Lightly AG and its affiliates.\n # All Rights Reserved\n+from typing import Tuple, List\n+\n+import numpy as np\n \n from lightly.cli.train_cli import _train_cli\n from lightly.cli.embed_cli import _embed_cli\n@@ -73,12 +76,15 @@\n     return cfg\n \n \n-def train_model_and_embed_images(config_path: str = None, **kwargs):\n+def train_model_and_embed_images(config_path: str = None, **kwargs) -> Tuple[\n+    np.ndarray, List[int], List[str]\n+]:\n     \"\"\"Train a self-supervised model and use it to embed images.\n \n-    Calls the same function as lightly-magic. All arguments passed to\n-    lightly-magic can also be passed to this function (see below for an\n-    example).\n+    First trains a modle using the _train_cli(),\n+    then embeds with the _embed_cli().\n+    All arguments passed to the CLI functions\n+    can also be passed to this function (see below for an example).\n \n     Args:\n         config_path:\n@@ -88,6 +94,8 @@\n \n     Returns:\n         Embeddings, labels, and filenames of the images.\n+        Embeddings are of shape (n_samples, embedding_size)\n+        len(labels) = len(filenames) = n_samples\n \n     Examples:\n         >>> import lightly\n@@ -105,14 +113,16 @@\n         >>> my_trainer = {max_epochs: 10}\n         >>> embeddings, _, _ = lightly.train_model_and_embed_images(\n         >>>     input_dir='path/to/data', trainer=my_trainer)\n-        >>> #\u00a0the command above is equivalent to:\n-        >>> #\u00a0lightly-magic input_dir='path/to/data' trainer.max_epochs=10\n \n     \"\"\"\n     config_path = _get_config_path(config_path)\n     config_args = _load_config_file(config_path)\n     config_args = _add_kwargs(config_args, kwargs)\n-    return _lightly_cli(config_args, is_cli_call=False)\n+\n+    checkpoint = _train_cli(config_args, is_cli_call=False)\n+    config_args['checkpoint'] = checkpoint\n+    embeddings, labels, filenames = _embed_cli(config_args, is_cli_call=False)\n+    return embeddings, labels, filenames\n \n \n def train_embedding_model(config_path: str = None, **kwargs):\n", "issue": "_lightly_cli is missing it's return statement\nas a side effect `train_model_and_embed_images` is not working as expected.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"**Lightly Embed:** Embed images with one command.\n\nThis module contains the entrypoint for the **lightly-embed**\ncommand-line interface.\n\"\"\"\n\n# Copyright (c) 2020. Lightly AG and its affiliates.\n# All Rights Reserved\n\nimport os\n\nimport hydra\nimport torch\nimport torchvision\nfrom torch.utils.hipify.hipify_python import bcolors\n\nfrom lightly.data import LightlyDataset\n\nfrom lightly.utils import save_embeddings\n\nfrom lightly.cli._helpers import get_model_from_config\nfrom lightly.cli._helpers import fix_input_path\nfrom lightly.cli._helpers import cpu_count\n\n\ndef _embed_cli(cfg, is_cli_call=True):\n    input_dir = cfg['input_dir']\n    if input_dir and is_cli_call:\n        input_dir = fix_input_path(input_dir)\n\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n\n    if torch.cuda.is_available():\n        device = torch.device('cuda')\n    else:\n        device = torch.device('cpu')\n\n    transform = torchvision.transforms.Compose(\n        [\n            torchvision.transforms.Resize(\n                (cfg['collate']['input_size'], cfg['collate']['input_size'])\n            ),\n            torchvision.transforms.ToTensor(),\n            torchvision.transforms.Normalize(\n                mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]\n            ),\n        ]\n    )\n\n    dataset = LightlyDataset(input_dir, transform=transform)\n\n    # disable drop_last and shuffle\n    cfg['loader']['drop_last'] = False\n    cfg['loader']['shuffle'] = False\n    cfg['loader']['batch_size'] = min(cfg['loader']['batch_size'], len(dataset))\n\n    # determine the number of available cores\n    if cfg['loader']['num_workers'] < 0:\n        cfg['loader']['num_workers'] = cpu_count()\n\n    dataloader = torch.utils.data.DataLoader(dataset, **cfg['loader'])\n\n    encoder = get_model_from_config(cfg, is_cli_call)\n\n    embeddings, labels, filenames = encoder.embed(dataloader, device=device)\n\n    if is_cli_call:\n        path = os.path.join(os.getcwd(), 'embeddings.csv')\n        save_embeddings(path, embeddings, labels, filenames)\n        print(f'Embeddings are stored at {bcolors.OKBLUE}{path}{bcolors.ENDC}')\n        os.environ[\n            cfg['environment_variable_names']['lightly_last_embedding_path']\n        ] = path\n        return path\n\n    return embeddings, labels, filenames\n\n\n@hydra.main(config_path='config', config_name='config')\ndef embed_cli(cfg):\n    \"\"\"Embed images from the command-line.\n\n    Args:\n        cfg:\n            The default configs are loaded from the config file.\n            To overwrite them please see the section on the config file\n            (.config.config.yaml).\n\n    Command-Line Args:\n        input_dir:\n            Path to the input directory where images are stored.\n        checkpoint:\n            Path to the checkpoint of a pretrained model. If left\n            empty, a pretrained model by lightly is used.\n\n    Examples:\n        >>> #\u00a0embed images with default settings and a lightly model\n        >>> lightly-embed input_dir=data/\n        >>>\n        >>> # embed images with default settings and a custom checkpoint\n        >>> lightly-embed input_dir=data/ checkpoint=my_checkpoint.ckpt\n        >>>\n        >>> # embed images with custom settings\n        >>> lightly-embed input_dir=data/ model.num_ftrs=32\n\n    \"\"\"\n    return _embed_cli(cfg)\n\n\ndef entry():\n    embed_cli()\n", "path": "lightly/cli/embed_cli.py"}, {"content": "\"\"\" Contains the core functionality of the lightly Python package. \"\"\"\n\n# Copyright (c) 2020. Lightly AG and its affiliates.\n# All Rights Reserved\n\nfrom lightly.cli.train_cli import _train_cli\nfrom lightly.cli.embed_cli import _embed_cli\nfrom lightly.cli.lightly_cli import _lightly_cli\nimport lightly.cli as cli\n\nimport yaml\nimport os\n\n\ndef _get_config_path(config_path):\n    \"\"\"Find path to yaml config file\n\n    Args:\n        config_path: (str) Path to config.yaml file\n\n    Returns:\n        Path to config.yaml if specified else default config.yaml\n\n    Raises:\n        ValueError: If the config_path is not None but doesn't exist\n\n    \"\"\"\n    if config_path is None:\n        dirname = os.path.dirname(cli.__file__)\n        config_path = os.path.join(dirname, 'config/config.yaml')\n    if not os.path.exists(config_path):\n        raise ValueError(\"Config path {} does not exist!\".format(config_path))\n\n    return config_path\n\n\ndef _load_config_file(config_path):\n    \"\"\"Load a yaml config file\n\n    Args:\n        config_path: (str) Path to config.yaml file\n\n    Returns:\n        Dictionary with configs from config.yaml\n\n    \"\"\"\n    Loader = yaml.FullLoader\n    with open(config_path, 'r') as config_file:\n        cfg = yaml.load(config_file, Loader=Loader)\n\n    return cfg\n\n\ndef _add_kwargs(cfg, kwargs):\n    \"\"\"Add keyword arguments to config\n\n    Args:\n        cfg: (dict) Dictionary of configs from config.yaml\n        kwargs: (dict) Dictionary of keyword arguments\n\n    Returns:\n        Union of cfg and kwargs\n\n    \"\"\"\n    for key, item in kwargs.items():\n        if isinstance(item, dict):\n            if key in cfg:\n                cfg[key] = _add_kwargs(cfg[key], item)\n            else:\n                cfg[key] = item\n        else:\n            cfg[key] = item\n    return cfg\n\n\ndef train_model_and_embed_images(config_path: str = None, **kwargs):\n    \"\"\"Train a self-supervised model and use it to embed images.\n\n    Calls the same function as lightly-magic. All arguments passed to\n    lightly-magic can also be passed to this function (see below for an\n    example).\n\n    Args:\n        config_path:\n            Path to config.yaml. If None, the default configs will be used.\n        **kwargs:\n            Overwrite default configs py passing keyword arguments.\n\n    Returns:\n        Embeddings, labels, and filenames of the images.\n\n    Examples:\n        >>> import lightly\n        >>>\n        >>> # train a model and embed images with default configs\n        >>> embeddings, _, _ = lightly.train_model_and_embed_images(\n        >>>     input_dir='path/to/data')\n        >>>\n        >>> #\u00a0train a model and embed images with separate config file\n        >>> my_config_path = 'my/config/file.yaml'\n        >>> embeddings, _, _ = lightly.train_model_and_embed_images(\n        >>>     input_dir='path/to/data', config_path=my_config_path)\n        >>>\n        >>> # train a model and embed images with default settings + overwrites\n        >>> my_trainer = {max_epochs: 10}\n        >>> embeddings, _, _ = lightly.train_model_and_embed_images(\n        >>>     input_dir='path/to/data', trainer=my_trainer)\n        >>> #\u00a0the command above is equivalent to:\n        >>> #\u00a0lightly-magic input_dir='path/to/data' trainer.max_epochs=10\n\n    \"\"\"\n    config_path = _get_config_path(config_path)\n    config_args = _load_config_file(config_path)\n    config_args = _add_kwargs(config_args, kwargs)\n    return _lightly_cli(config_args, is_cli_call=False)\n\n\ndef train_embedding_model(config_path: str = None, **kwargs):\n    \"\"\"Train a self-supervised model.\n\n    Calls the same function as lightly-train. All arguments passed to\n    lightly-train can also be passed to this function (see below for an\n    example).\n\n    Args:\n        config_path:\n            Path to config.yaml. If None, the default configs will be used.\n        **kwargs:\n            Overwrite default configs py passing keyword arguments.\n\n    Returns:\n        Path to checkpoint of the trained embedding model.\n\n    Examples:\n        >>> import lightly\n        >>>\n        >>> # train a model with default configs\n        >>> checkpoint_path = lightly.train_embedding_model(\n        >>>     input_dir='path/to/data')\n        >>>\n        >>> #\u00a0train a model with separate config file\n        >>> my_config_path = 'my/config/file.yaml'\n        >>> checkpoint_path = lightly.train_embedding_model(\n        >>>     input_dir='path/to/data', config_path=my_config_path)\n        >>>\n        >>> # train a model with default settings and overwrites: large batch\n        >>> # sizes are benefitial for self-supervised training and more \n        >>> #\u00a0workers speed up the dataloading process.\n        >>> my_loader = {\n        >>>     batch_size: 100,\n        >>>     num_workers: 8,\n        >>> }\n        >>> checkpoint_path = lightly.train_embedding_model(\n        >>>     input_dir='path/to/data', loader=my_loader)\n        >>> #\u00a0the command above is equivalent to:\n        >>> #\u00a0lightly-train input_dir='path/to/data' loader.batch_size=100 loader.num_workers=8\n    \"\"\"\n    config_path = _get_config_path(config_path)\n    config_args = _load_config_file(config_path)\n    config_args = _add_kwargs(config_args, kwargs)\n\n    return _train_cli(config_args, is_cli_call=False)\n\n\ndef embed_images(checkpoint: str, config_path: str = None, **kwargs):\n    \"\"\"Embed images with a self-supervised model.\n\n    Calls the same function as lightly-embed. All arguments passed to\n    lightly-embed can also be passed to this function (see below for an\n    example).\n\n    Args:\n        checkpoint:\n            Path to the checkpoint file for the embedding model.\n        config_path:\n            Path to config.yaml. If None, the default configs will be used.\n        **kwargs:\n            Overwrite default configs py passing keyword arguments.\n\n    Returns:\n        Embeddings, labels, and filenames of the images.\n\n    Examples:\n        >>> import lightly\n        >>> my_checkpoint_path = 'path/to/checkpoint.ckpt'\n        >>>\n        >>> # embed images with default configs\n        >>> embeddings, _, _ = lightly.embed_images(\n        >>>     my_checkpoint_path, input_dir='path/to/data')\n        >>>\n        >>> #\u00a0embed images with separate config file\n        >>> my_config_path = 'my/config/file.yaml'\n        >>> embeddings, _, _ = lightly.embed_images(\n        >>>     my_checkpoint_path, input_dir='path/to/data', config_path=my_config_path)\n        >>>\n        >>> # embed images with default settings and overwrites: at inference,\n        >>> #\u00a0we can use larger input_sizes because it requires less memory.\n        >>> my_collate = {input_size: 256}\n        >>> embeddings, _, _ = lightly.embed_images(\n        >>>     my_checkpoint_path, input_dir='path/to/data', collate=my_collate)\n        >>> #\u00a0the command above is equivalent to:\n        >>> #\u00a0lightly-embed input_dir='path/to/data' collate.input_size=256\n\n    \"\"\"\n    config_path = _get_config_path(config_path)\n    config_args = _load_config_file(config_path)\n    config_args = _add_kwargs(config_args, kwargs)\n\n    config_args['checkpoint'] = checkpoint\n\n    return _embed_cli(config_args, is_cli_call=False)\n", "path": "lightly/core.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"**Lightly Embed:** Embed images with one command.\n\nThis module contains the entrypoint for the **lightly-embed**\ncommand-line interface.\n\"\"\"\n\n# Copyright (c) 2020. Lightly AG and its affiliates.\n# All Rights Reserved\n\nimport os\nfrom typing import Union, Tuple, List\n\nimport hydra\nimport numpy as np\nimport torch\nimport torchvision\nfrom torch.utils.hipify.hipify_python import bcolors\n\nfrom lightly.data import LightlyDataset\n\nfrom lightly.utils import save_embeddings\n\nfrom lightly.cli._helpers import get_model_from_config\nfrom lightly.cli._helpers import fix_input_path\nfrom lightly.cli._helpers import cpu_count\n\n\ndef _embed_cli(cfg, is_cli_call=True) -> \\\n    Union[\n        Tuple[np.ndarray, List[int], List[str]],\n        str\n    ]:\n    \"\"\" See embed_cli() for usage documentation\n\n        is_cli_call:\n            If True:\n                Saves the embeddings as file and returns the filepath.\n            If False:\n                Returns the embeddings, labels, filenames as tuple.\n                Embeddings are of shape (n_samples, embedding_size)\n                len(labels) = len(filenames) = n_samples\n    \"\"\"\n    input_dir = cfg['input_dir']\n    if input_dir and is_cli_call:\n        input_dir = fix_input_path(input_dir)\n\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n\n    if torch.cuda.is_available():\n        device = torch.device('cuda')\n    else:\n        device = torch.device('cpu')\n\n    transform = torchvision.transforms.Compose(\n        [\n            torchvision.transforms.Resize(\n                (cfg['collate']['input_size'], cfg['collate']['input_size'])\n            ),\n            torchvision.transforms.ToTensor(),\n            torchvision.transforms.Normalize(\n                mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]\n            ),\n        ]\n    )\n\n    dataset = LightlyDataset(input_dir, transform=transform)\n\n    # disable drop_last and shuffle\n    cfg['loader']['drop_last'] = False\n    cfg['loader']['shuffle'] = False\n    cfg['loader']['batch_size'] = min(cfg['loader']['batch_size'], len(dataset))\n\n    # determine the number of available cores\n    if cfg['loader']['num_workers'] < 0:\n        cfg['loader']['num_workers'] = cpu_count()\n\n    dataloader = torch.utils.data.DataLoader(dataset, **cfg['loader'])\n\n    encoder = get_model_from_config(cfg, is_cli_call)\n\n    embeddings, labels, filenames = encoder.embed(dataloader, device=device)\n\n    if is_cli_call:\n        path = os.path.join(os.getcwd(), 'embeddings.csv')\n        save_embeddings(path, embeddings, labels, filenames)\n        print(f'Embeddings are stored at {bcolors.OKBLUE}{path}{bcolors.ENDC}')\n        os.environ[\n            cfg['environment_variable_names']['lightly_last_embedding_path']\n        ] = path\n        return path\n\n    return embeddings, labels, filenames\n\n\n@hydra.main(config_path='config', config_name='config')\ndef embed_cli(cfg) -> str:\n    \"\"\"Embed images from the command-line.\n\n    Args:\n        cfg:\n            The default configs are loaded from the config file.\n            To overwrite them please see the section on the config file\n            (.config.config.yaml).\n\n    Command-Line Args:\n        input_dir:\n            Path to the input directory where images are stored.\n        checkpoint:\n            Path to the checkpoint of a pretrained model. If left\n            empty, a pretrained model by lightly is used.\n\n    Returns:\n        The path to the created embeddings file.\n\n    Examples:\n        >>> #\u00a0embed images with default settings and a lightly model\n        >>> lightly-embed input_dir=data/\n        >>>\n        >>> # embed images with default settings and a custom checkpoint\n        >>> lightly-embed input_dir=data/ checkpoint=my_checkpoint.ckpt\n        >>>\n        >>> # embed images with custom settings\n        >>> lightly-embed input_dir=data/ model.num_ftrs=32\n\n    \"\"\"\n    return _embed_cli(cfg)\n\n\ndef entry():\n    embed_cli()\n", "path": "lightly/cli/embed_cli.py"}, {"content": "\"\"\" Contains the core functionality of the lightly Python package. \"\"\"\n\n# Copyright (c) 2020. Lightly AG and its affiliates.\n# All Rights Reserved\nfrom typing import Tuple, List\n\nimport numpy as np\n\nfrom lightly.cli.train_cli import _train_cli\nfrom lightly.cli.embed_cli import _embed_cli\nfrom lightly.cli.lightly_cli import _lightly_cli\nimport lightly.cli as cli\n\nimport yaml\nimport os\n\n\ndef _get_config_path(config_path):\n    \"\"\"Find path to yaml config file\n\n    Args:\n        config_path: (str) Path to config.yaml file\n\n    Returns:\n        Path to config.yaml if specified else default config.yaml\n\n    Raises:\n        ValueError: If the config_path is not None but doesn't exist\n\n    \"\"\"\n    if config_path is None:\n        dirname = os.path.dirname(cli.__file__)\n        config_path = os.path.join(dirname, 'config/config.yaml')\n    if not os.path.exists(config_path):\n        raise ValueError(\"Config path {} does not exist!\".format(config_path))\n\n    return config_path\n\n\ndef _load_config_file(config_path):\n    \"\"\"Load a yaml config file\n\n    Args:\n        config_path: (str) Path to config.yaml file\n\n    Returns:\n        Dictionary with configs from config.yaml\n\n    \"\"\"\n    Loader = yaml.FullLoader\n    with open(config_path, 'r') as config_file:\n        cfg = yaml.load(config_file, Loader=Loader)\n\n    return cfg\n\n\ndef _add_kwargs(cfg, kwargs):\n    \"\"\"Add keyword arguments to config\n\n    Args:\n        cfg: (dict) Dictionary of configs from config.yaml\n        kwargs: (dict) Dictionary of keyword arguments\n\n    Returns:\n        Union of cfg and kwargs\n\n    \"\"\"\n    for key, item in kwargs.items():\n        if isinstance(item, dict):\n            if key in cfg:\n                cfg[key] = _add_kwargs(cfg[key], item)\n            else:\n                cfg[key] = item\n        else:\n            cfg[key] = item\n    return cfg\n\n\ndef train_model_and_embed_images(config_path: str = None, **kwargs) -> Tuple[\n    np.ndarray, List[int], List[str]\n]:\n    \"\"\"Train a self-supervised model and use it to embed images.\n\n    First trains a modle using the _train_cli(),\n    then embeds with the _embed_cli().\n    All arguments passed to the CLI functions\n    can also be passed to this function (see below for an example).\n\n    Args:\n        config_path:\n            Path to config.yaml. If None, the default configs will be used.\n        **kwargs:\n            Overwrite default configs py passing keyword arguments.\n\n    Returns:\n        Embeddings, labels, and filenames of the images.\n        Embeddings are of shape (n_samples, embedding_size)\n        len(labels) = len(filenames) = n_samples\n\n    Examples:\n        >>> import lightly\n        >>>\n        >>> # train a model and embed images with default configs\n        >>> embeddings, _, _ = lightly.train_model_and_embed_images(\n        >>>     input_dir='path/to/data')\n        >>>\n        >>> #\u00a0train a model and embed images with separate config file\n        >>> my_config_path = 'my/config/file.yaml'\n        >>> embeddings, _, _ = lightly.train_model_and_embed_images(\n        >>>     input_dir='path/to/data', config_path=my_config_path)\n        >>>\n        >>> # train a model and embed images with default settings + overwrites\n        >>> my_trainer = {max_epochs: 10}\n        >>> embeddings, _, _ = lightly.train_model_and_embed_images(\n        >>>     input_dir='path/to/data', trainer=my_trainer)\n\n    \"\"\"\n    config_path = _get_config_path(config_path)\n    config_args = _load_config_file(config_path)\n    config_args = _add_kwargs(config_args, kwargs)\n\n    checkpoint = _train_cli(config_args, is_cli_call=False)\n    config_args['checkpoint'] = checkpoint\n    embeddings, labels, filenames = _embed_cli(config_args, is_cli_call=False)\n    return embeddings, labels, filenames\n\n\ndef train_embedding_model(config_path: str = None, **kwargs):\n    \"\"\"Train a self-supervised model.\n\n    Calls the same function as lightly-train. All arguments passed to\n    lightly-train can also be passed to this function (see below for an\n    example).\n\n    Args:\n        config_path:\n            Path to config.yaml. If None, the default configs will be used.\n        **kwargs:\n            Overwrite default configs py passing keyword arguments.\n\n    Returns:\n        Path to checkpoint of the trained embedding model.\n\n    Examples:\n        >>> import lightly\n        >>>\n        >>> # train a model with default configs\n        >>> checkpoint_path = lightly.train_embedding_model(\n        >>>     input_dir='path/to/data')\n        >>>\n        >>> #\u00a0train a model with separate config file\n        >>> my_config_path = 'my/config/file.yaml'\n        >>> checkpoint_path = lightly.train_embedding_model(\n        >>>     input_dir='path/to/data', config_path=my_config_path)\n        >>>\n        >>> # train a model with default settings and overwrites: large batch\n        >>> # sizes are benefitial for self-supervised training and more \n        >>> #\u00a0workers speed up the dataloading process.\n        >>> my_loader = {\n        >>>     batch_size: 100,\n        >>>     num_workers: 8,\n        >>> }\n        >>> checkpoint_path = lightly.train_embedding_model(\n        >>>     input_dir='path/to/data', loader=my_loader)\n        >>> #\u00a0the command above is equivalent to:\n        >>> #\u00a0lightly-train input_dir='path/to/data' loader.batch_size=100 loader.num_workers=8\n    \"\"\"\n    config_path = _get_config_path(config_path)\n    config_args = _load_config_file(config_path)\n    config_args = _add_kwargs(config_args, kwargs)\n\n    return _train_cli(config_args, is_cli_call=False)\n\n\ndef embed_images(checkpoint: str, config_path: str = None, **kwargs):\n    \"\"\"Embed images with a self-supervised model.\n\n    Calls the same function as lightly-embed. All arguments passed to\n    lightly-embed can also be passed to this function (see below for an\n    example).\n\n    Args:\n        checkpoint:\n            Path to the checkpoint file for the embedding model.\n        config_path:\n            Path to config.yaml. If None, the default configs will be used.\n        **kwargs:\n            Overwrite default configs py passing keyword arguments.\n\n    Returns:\n        Embeddings, labels, and filenames of the images.\n\n    Examples:\n        >>> import lightly\n        >>> my_checkpoint_path = 'path/to/checkpoint.ckpt'\n        >>>\n        >>> # embed images with default configs\n        >>> embeddings, _, _ = lightly.embed_images(\n        >>>     my_checkpoint_path, input_dir='path/to/data')\n        >>>\n        >>> #\u00a0embed images with separate config file\n        >>> my_config_path = 'my/config/file.yaml'\n        >>> embeddings, _, _ = lightly.embed_images(\n        >>>     my_checkpoint_path, input_dir='path/to/data', config_path=my_config_path)\n        >>>\n        >>> # embed images with default settings and overwrites: at inference,\n        >>> #\u00a0we can use larger input_sizes because it requires less memory.\n        >>> my_collate = {input_size: 256}\n        >>> embeddings, _, _ = lightly.embed_images(\n        >>>     my_checkpoint_path, input_dir='path/to/data', collate=my_collate)\n        >>> #\u00a0the command above is equivalent to:\n        >>> #\u00a0lightly-embed input_dir='path/to/data' collate.input_size=256\n\n    \"\"\"\n    config_path = _get_config_path(config_path)\n    config_args = _load_config_file(config_path)\n    config_args = _add_kwargs(config_args, kwargs)\n\n    config_args['checkpoint'] = checkpoint\n\n    return _embed_cli(config_args, is_cli_call=False)\n", "path": "lightly/core.py"}]}