hafnia 0.1.24__py3-none-any.whl → 0.1.26__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.
@@ -1,111 +0,0 @@
1
- import os
2
- import subprocess
3
- import sys
4
- from dataclasses import dataclass
5
- from pathlib import Path
6
- from typing import Dict
7
-
8
- from hafnia.log import logger
9
-
10
-
11
- @dataclass
12
- class PythonModule:
13
- """Dataclass to store Python module details."""
14
-
15
- module_name: str
16
- runner_path: str
17
-
18
-
19
- def handle_mount(source: str) -> None:
20
- """
21
- Mounts the Hafnia environment by adding source directories to PYTHONPATH.
22
-
23
- Args:
24
- source (str): Path to the root directory containing 'lib' and 'scripts' subdirectories
25
-
26
- Raises:
27
- FileNotFoundError: If the required directory structure is not found
28
- """
29
- source_path = Path(source)
30
- lib_dir = source_path / "lib"
31
- scripts_dir = source_path / "scripts"
32
-
33
- if not lib_dir.exists() and not scripts_dir.exists():
34
- logger.error(f"Filestructure is not supported. Expected 'lib' and 'scripts' directories in {source_path}.")
35
- exit(1)
36
-
37
- sys.path.extend([lib_dir.as_posix(), scripts_dir.as_posix()])
38
- python_path = os.getenv("PYTHONPATH", "")
39
- os.environ["PYTHONPATH"] = f"{python_path}:{lib_dir.as_posix()}:{scripts_dir.as_posix()}"
40
- logger.info(f"Mounted codebase from {source_path}")
41
-
42
-
43
- def collect_python_modules(directory: Path) -> Dict[str, PythonModule]:
44
- """
45
- Collects Python modules from a directory and its subdirectories.
46
-
47
- This function dynamically imports Python modules found in the specified directory,
48
- excluding files that start with '_' or '.'. It's used to discover available tasks
49
- in the Hafnia environment.
50
-
51
- Args:
52
- directory (Path): The directory to search for Python modules
53
-
54
- Returns:
55
- Dict[str, Dict[str, str]]: A dictionary mapping task names to module details, where each detail contains:
56
- - module_name (str): The full module name
57
- - runner_path (str): The absolute path to the module file
58
- """
59
- from importlib.util import module_from_spec, spec_from_file_location
60
-
61
- modules = {}
62
- for fname in directory.rglob("*.py"):
63
- if fname.name.startswith("-"):
64
- continue
65
-
66
- task_name = fname.stem
67
- module_name = f"{directory.name}.{task_name}"
68
-
69
- spec = spec_from_file_location(module_name, fname)
70
- if spec is None:
71
- logger.warning(f"Was not able to load {module_name} from {fname}")
72
- continue
73
- if spec.loader is None:
74
- logger.warning(f"Loader is None for {module_name} from {fname}")
75
- continue
76
- module = module_from_spec(spec)
77
- spec.loader.exec_module(module)
78
-
79
- modules[task_name] = PythonModule(module_name, str(fname.resolve()))
80
-
81
- return modules
82
-
83
-
84
- def handle_launch(task: str) -> None:
85
- """
86
- Launch and execute a specified Hafnia task.
87
-
88
- This function verifies the Hafnia environment status, locates the task script,
89
- and executes it in a subprocess with output streaming.
90
-
91
- Args:
92
- task (str): Name of the task to execute
93
-
94
- Raises:
95
- ValueError: If the task is not found or scripts directory is not in PYTHONPATH
96
- """
97
- recipe_dir = os.getenv("RECIPE_DIR", None)
98
- if recipe_dir is None:
99
- raise ValueError("RECIPE_DIR environment variable not set.")
100
- handle_mount(recipe_dir)
101
- scripts_dir = [p for p in sys.path if "scripts" in p][0]
102
- scripts = collect_python_modules(Path(scripts_dir))
103
- if task not in scripts:
104
- available_tasks = ", ".join(sorted(scripts.keys()))
105
- logger.error(f"Task '{task}' not found. Available tasks: {available_tasks}")
106
- exit(1)
107
- try:
108
- subprocess.check_call(["python", scripts[task].runner_path], stdout=sys.stdout, stderr=sys.stdout)
109
- except subprocess.CalledProcessError as e:
110
- logger.error(f"Error executing task: {str(e)}")
111
- exit(1)
@@ -1,197 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: hafnia
3
- Version: 0.1.24
4
- Summary: Python tools for communication with Hafnia platform.
5
- Author-email: Ivan Sahumbaiev <ivsa@milestone.dk>
6
- License-File: LICENSE
7
- Requires-Python: >=3.10
8
- Requires-Dist: boto3>=1.35.91
9
- Requires-Dist: click>=8.1.8
10
- Requires-Dist: datasets>=3.2.0
11
- Requires-Dist: flatten-dict>=0.4.2
12
- Requires-Dist: pillow>=11.1.0
13
- Requires-Dist: pyarrow>=18.1.0
14
- Requires-Dist: pydantic>=2.10.4
15
- Requires-Dist: rich>=13.9.4
16
- Requires-Dist: tqdm>=4.67.1
17
- Provides-Extra: torch
18
- Requires-Dist: flatten-dict>=0.4.2; extra == 'torch'
19
- Requires-Dist: torch>=2.6.0; extra == 'torch'
20
- Requires-Dist: torchvision>=0.21.0; extra == 'torch'
21
- Description-Content-Type: text/markdown
22
-
23
- # Hafnia
24
-
25
- The `hafnia` python package is a collection of tools to create and run model training recipes on
26
- the [Hafnia Platform](https://hafnia.milestonesys.com/).
27
-
28
- The package includes the following interfaces:
29
-
30
- - `cli`: A Command Line Interface (CLI) to 1) configure/connect to Hafnia's [Training-aaS](https://hafnia.readme.io/docs/training-as-a-service) and 2) create and
31
- launch recipe scripts.
32
- - `hafnia`: A python package with helper functions to load and interact with sample datasets and an experiment
33
- tracker (`HafniaLogger`).
34
-
35
-
36
- ## The Concept: Training as a Service (Training-aaS)
37
- `Training-aaS` is the concept of training models on the Hafnia platform on large
38
- and *hidden* datasets. Hidden datasets refers to datasets that can be used for
39
- training, but are not available for download or direct access.
40
-
41
- This is a key feature of the Hafnia platform, as a hidden dataset ensures data
42
- privacy, and allow models to be trained compliantly and ethically by third parties (you).
43
-
44
- The `script2model` approach is a Training-aaS concept, where you package your custom training
45
- script as a *training recipe* and use the recipe to train models on the hidden datasets.
46
-
47
- To support local development of a training recipe, we have introduced a **sample dataset**
48
- for each dataset available in the Hafnia [data library](https://hafnia.milestonesys.com/training-aas/datasets). The sample dataset is a small
49
- and anonymized subset of the full dataset and available for download.
50
-
51
- With the sample dataset, you can seamlessly switch between local development and Training-aaS.
52
- Locally, you can create, validate and debug your training recipe. The recipe is then
53
- launched with Training-aaS, where the recipe runs on the full dataset and can be scaled to run on
54
- multiple GPUs and instances if needed.
55
-
56
- ## Getting started: Configuration
57
- To get started with Hafnia:
58
-
59
- 1. Install `hafnia` with your favorite python package manager. With pip do this:
60
-
61
- `pip install hafnia`
62
- 1. Sign in to the [Hafnia Platform](https://hafnia.milestonesys.com/).
63
- 1. Create an API KEY for Training aaS. For more instructions, follow this
64
- [guide](https://hafnia.readme.io/docs/create-an-api-key).
65
- Copy the key and save it for later use.
66
- 1. From terminal, configure your machine to access Hafnia:
67
-
68
- ```
69
- # Start configuration with
70
- hafnia configure
71
-
72
- # You are then prompted:
73
- Profile Name [default]: # Press [Enter] or select an optional name
74
- Hafnia API Key: # Pass your HAFNIA API key
75
- Hafnia Platform URL [https://api.mdi.milestonesys.com]: # Press [Enter]
76
- ```
77
- 1. Download `mnist` from terminal to verify that your configuration is working.
78
-
79
- ```bash
80
- hafnia data download mnist --force
81
- ```
82
-
83
- ## Getting started: Loading datasets samples
84
- With Hafnia configured on your local machine, it is now possible to download
85
- and explore the dataset sample with a python script:
86
-
87
- ```python
88
- from hafnia.data import load_dataset
89
-
90
- dataset_splits = load_dataset("mnist")
91
- print(dataset_splits)
92
- print(dataset_splits["train"])
93
- ```
94
- The returned sample dataset is a [hugging face dataset](https://huggingface.co/docs/datasets/index)
95
- and contains train, validation and test splits.
96
-
97
- An important feature of `load_dataset` is that it will return the full dataset
98
- when loaded on the Hafnia platform.
99
- This enables seamlessly switching between running/validating a training script
100
- locally (on the sample dataset) and running full model trainings with Training-aaS (on the full dataset).
101
- without changing code or configurations for the training script.
102
-
103
- Available datasets with corresponding sample datasets can be found in [data library](https://hafnia.milestonesys.com/training-aas/datasets) including metadata and description for each dataset.
104
-
105
-
106
- ## Getting started: Experiment Tracking with HafniaLogger
107
- The `HafniaLogger` is an important part of the recipe script and enables you to track, log and
108
- reproduce your experiments.
109
-
110
- When integrated into your training script, the `HafniaLogger` is responsible for collecting:
111
-
112
- - **Trained Model**: The model trained during the experiment
113
- - **Model Checkpoints**: Intermediate model states saved during training
114
- - **Experiment Configurations**: Hyperparameters and other settings used in your experiment
115
- - **Training/Evaluation Metrics**: Performance data such as loss values, accuracy, and custom metrics
116
-
117
- ### Basic Implementation Example
118
-
119
- Here's how to integrate the `HafniaLogger` into your training script:
120
-
121
- ```python
122
- from hafnia.experiment import HafniaLogger
123
-
124
- batch_size = 128
125
- learning_rate = 0.001
126
-
127
- # Initialize Hafnia logger
128
- logger = HafniaLogger()
129
-
130
- # Log experiment parameters
131
- logger.log_configuration({"batch_size": 128, "learning_rate": 0.001})
132
-
133
- # Store checkpoints in this path
134
- ckpt_dir = logger.path_model_checkpoints()
135
-
136
- # Store the trained model in this path
137
- model_dir = logger.path_model()
138
-
139
- # Log scalar and metric values during training and validation
140
- logger.log_scalar("train/loss", value=0.1, step=100)
141
- logger.log_metric("train/accuracy", value=0.98, step=100)
142
-
143
- logger.log_scalar("validation/loss", value=0.1, step=100)
144
- logger.log_metric("validation/accuracy", value=0.95, step=100)
145
- ```
146
-
147
- Similar to `load_dataset`, the tracker behaves differently when running locally or in the cloud.
148
- Locally, experiment data is stored in a local folder `.data/experiments/{DATE_TIME}`.
149
-
150
- In the cloud, the experiment data will be available in the Hafnia platform under
151
- [experiments](https://hafnia.milestonesys.com/training-aas/experiments).
152
-
153
- ## Example: Torch Dataloader
154
- Commonly for `torch`-based training scripts, a dataset is used in combination
155
- with a dataloader that performs data augmentations and batching of the dataset as torch tensors.
156
-
157
- To support this, we have provided a torch dataloader example script
158
- [example_torchvision_dataloader.py](./examples/example_torchvision_dataloader.py).
159
-
160
- The script demonstrates how to make a dataloader with data augmentation (`torchvision.transforms.v2`)
161
- and a helper function for visualizing image and labels.
162
-
163
- The dataloader and visualization function supports computer vision tasks
164
- and datasets available in the data library.
165
-
166
- ## Example: Training-aaS
167
- By combining logging and dataset loading, we can now construct our model training recipe.
168
-
169
- To demonstrate this, we have provided a recipe project that serves as a template for creating and structuring training recipes
170
- [recipe-classification](https://github.com/Data-insight-Platform/recipe-classification)
171
-
172
- The project also contains additional information on how to structure your training recipe, use the `HafniaLogger`, the `load_dataset` function and different approach for launching
173
- the training recipe on the Hafnia platform.
174
-
175
- ## Detailed Documentation
176
- For more information, go to our [documentation page](https://hafnia.readme.io/docs/welcome-to-hafnia)
177
- or in below markdown pages.
178
-
179
- - [CLI](docs/cli.md) - Detailed guide for the Hafnia command-line interface
180
- - [Script2Model Documentation](docs/s2m.md) - Detailed guide for script2model
181
- - [Release lifecycle](docs/release.md) - Details about package release lifecycle.
182
-
183
- ## Development
184
- For development, we are using an uv based virtual python environment.
185
-
186
- Install uv
187
-
188
- curl -LsSf https://astral.sh/uv/install.sh | sh
189
-
190
-
191
- Install python dependencies including developer (`--dev`) and optional dependencies (`--all-extras`).
192
-
193
- uv sync --all-extras --dev
194
-
195
- Run tests:
196
-
197
- uv run pytest tests
@@ -1,28 +0,0 @@
1
- cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- cli/__main__.py,sha256=h1tOAK15us_dkoMd6Yd4SesVPisojTxOXiYxpLZnatw,1736
3
- cli/config.py,sha256=Js_dCn39l7hLhA3ovHorOyVqj-LCLzUg_figSy4jNjs,5279
4
- cli/consts.py,sha256=nd9fPTypqCJYJoOp9QifNgj7-c91J-T0dTv83c33g50,892
5
- cli/data_cmds.py,sha256=FYZPaeTs6WQnTf9b4a56w3SXQ1VAOMF5s8eUDHeNtd4,1538
6
- cli/experiment_cmds.py,sha256=d9M8008Z0Y49KIITy73qd5ViPehgMymDVAgsvZhwye0,3099
7
- cli/profile_cmds.py,sha256=Rg-5wLHSWlZhNPUZBO7LdyJS-Y-SgI6qKLoAac2gSdk,2534
8
- cli/runc_cmds.py,sha256=fNgPNURXmO4nfLyuorcpqWEeNNuTVsRBHxcIA9FCPts,2197
9
- hafnia/__init__.py,sha256=Zphq-cQoX95Z11zm4lkrU-YiAJxddR7IBfwDkxeHoDE,108
10
- hafnia/http.py,sha256=rID6Krn9wRGXwsJYvpffsFlt5cwxFgkcihYppqtdT-8,2974
11
- hafnia/log.py,sha256=ii--Q6IThsWOluRp_Br9WGhwBtKChU80BXk5pK_NU5A,819
12
- hafnia/torch_helpers.py,sha256=P_Jl4IwqUebKVCOXNe6iTorJZA3S-3d92HV274UHIko,7456
13
- hafnia/utils.py,sha256=WWWXZPolzncQmSb4onArT1lJyISV0D22eEejrHWePoc,2425
14
- hafnia/data/__init__.py,sha256=Pntmo_1fst8OhyrHB60jQ8mhJJ4hL38tdjLvt0YXEJo,73
15
- hafnia/data/factory.py,sha256=61oGQsm1naG_6Nd_UY2teOki8Oiu2F-gT-nGocmqAcg,2992
16
- hafnia/experiment/__init__.py,sha256=OEFE6HqhO5zcTCLZcPcPVjIg7wMFFnvZ1uOtAVhRz7M,85
17
- hafnia/experiment/hafnia_logger.py,sha256=bkSfioEaBXthUEGBjMbQaSefU30b_Gu809VcmWy_wyg,6566
18
- hafnia/platform/__init__.py,sha256=Oz1abs40hEKspLg6mVIokdtsp1tZJF9Pndv8uSMOgtQ,522
19
- hafnia/platform/api.py,sha256=aJvlQGjzqm-D3WYb2xTEYX60YoJoWN_kyYdlkvqt_MI,382
20
- hafnia/platform/builder.py,sha256=VqcbOPxC7HqGAqFMb6ewThBZYLEV5RBgQrVuMd2dbLY,6622
21
- hafnia/platform/download.py,sha256=AWnlSYj9FD7GvZ_-9Sw5jrcxi3RyBSSUVph8U9T9ZbQ,4711
22
- hafnia/platform/executor.py,sha256=HA8IF2ZTZ6ZiRWNjVdIdWKiUa5i8Yoz06mIUBDwzVDk,3759
23
- hafnia/platform/experiment.py,sha256=951ppXdrp075pW2xGFOM0oiGYGE1I53tP9azQjjIUe8,2305
24
- hafnia-0.1.24.dist-info/METADATA,sha256=85f5fVCG57auPMtzbF6T0o05smjq20XvZP-6jqNqEYg,8124
25
- hafnia-0.1.24.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
26
- hafnia-0.1.24.dist-info/entry_points.txt,sha256=FCJVIQ8GP2VE9I3eeGVF5eLxVDNW_01pOJCpG_CGnMM,45
27
- hafnia-0.1.24.dist-info/licenses/LICENSE,sha256=DqQ3NOAy7Efwppv0IAVXEm3Za2SI_1OuDfG20ab8eQw,1078
28
- hafnia-0.1.24.dist-info/RECORD,,