expops 0.1.3__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.
- expops-0.1.3.dist-info/METADATA +826 -0
- expops-0.1.3.dist-info/RECORD +86 -0
- expops-0.1.3.dist-info/WHEEL +5 -0
- expops-0.1.3.dist-info/entry_points.txt +3 -0
- expops-0.1.3.dist-info/licenses/LICENSE +674 -0
- expops-0.1.3.dist-info/top_level.txt +1 -0
- mlops/__init__.py +0 -0
- mlops/__main__.py +11 -0
- mlops/_version.py +34 -0
- mlops/adapters/__init__.py +12 -0
- mlops/adapters/base.py +86 -0
- mlops/adapters/config_schema.py +89 -0
- mlops/adapters/custom/__init__.py +3 -0
- mlops/adapters/custom/custom_adapter.py +447 -0
- mlops/adapters/plugin_manager.py +113 -0
- mlops/adapters/sklearn/__init__.py +3 -0
- mlops/adapters/sklearn/adapter.py +94 -0
- mlops/cluster/__init__.py +3 -0
- mlops/cluster/controller.py +496 -0
- mlops/cluster/process_runner.py +91 -0
- mlops/cluster/providers.py +258 -0
- mlops/core/__init__.py +95 -0
- mlops/core/custom_model_base.py +38 -0
- mlops/core/dask_networkx_executor.py +1265 -0
- mlops/core/executor_worker.py +1239 -0
- mlops/core/experiment_tracker.py +81 -0
- mlops/core/graph_types.py +64 -0
- mlops/core/networkx_parser.py +135 -0
- mlops/core/payload_spill.py +278 -0
- mlops/core/pipeline_utils.py +162 -0
- mlops/core/process_hashing.py +216 -0
- mlops/core/step_state_manager.py +1298 -0
- mlops/core/step_system.py +956 -0
- mlops/core/workspace.py +99 -0
- mlops/environment/__init__.py +10 -0
- mlops/environment/base.py +43 -0
- mlops/environment/conda_manager.py +307 -0
- mlops/environment/factory.py +70 -0
- mlops/environment/pyenv_manager.py +146 -0
- mlops/environment/setup_env.py +31 -0
- mlops/environment/system_manager.py +66 -0
- mlops/environment/utils.py +105 -0
- mlops/environment/venv_manager.py +134 -0
- mlops/main.py +527 -0
- mlops/managers/project_manager.py +400 -0
- mlops/managers/reproducibility_manager.py +575 -0
- mlops/platform.py +996 -0
- mlops/reporting/__init__.py +16 -0
- mlops/reporting/context.py +187 -0
- mlops/reporting/entrypoint.py +292 -0
- mlops/reporting/kv_utils.py +77 -0
- mlops/reporting/registry.py +50 -0
- mlops/runtime/__init__.py +9 -0
- mlops/runtime/context.py +34 -0
- mlops/runtime/env_export.py +113 -0
- mlops/storage/__init__.py +12 -0
- mlops/storage/adapters/__init__.py +9 -0
- mlops/storage/adapters/gcp_kv_store.py +778 -0
- mlops/storage/adapters/gcs_object_store.py +96 -0
- mlops/storage/adapters/memory_store.py +240 -0
- mlops/storage/adapters/redis_store.py +438 -0
- mlops/storage/factory.py +199 -0
- mlops/storage/interfaces/__init__.py +6 -0
- mlops/storage/interfaces/kv_store.py +118 -0
- mlops/storage/path_utils.py +38 -0
- mlops/templates/premier-league/charts/plot_metrics.js +70 -0
- mlops/templates/premier-league/charts/plot_metrics.py +145 -0
- mlops/templates/premier-league/charts/requirements.txt +6 -0
- mlops/templates/premier-league/configs/cluster_config.yaml +13 -0
- mlops/templates/premier-league/configs/project_config.yaml +207 -0
- mlops/templates/premier-league/data/England CSV.csv +12154 -0
- mlops/templates/premier-league/models/premier_league_model.py +638 -0
- mlops/templates/premier-league/requirements.txt +8 -0
- mlops/templates/sklearn-basic/README.md +22 -0
- mlops/templates/sklearn-basic/charts/plot_metrics.py +85 -0
- mlops/templates/sklearn-basic/charts/requirements.txt +3 -0
- mlops/templates/sklearn-basic/configs/project_config.yaml +64 -0
- mlops/templates/sklearn-basic/data/train.csv +14 -0
- mlops/templates/sklearn-basic/models/model.py +62 -0
- mlops/templates/sklearn-basic/requirements.txt +10 -0
- mlops/web/__init__.py +3 -0
- mlops/web/server.py +585 -0
- mlops/web/ui/index.html +52 -0
- mlops/web/ui/mlops-charts.js +357 -0
- mlops/web/ui/script.js +1244 -0
- mlops/web/ui/styles.css +248 -0
mlops/__main__.py
ADDED
mlops/_version.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '0.1.3'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 3)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
mlops/adapters/base.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
@dataclass
|
|
7
|
+
class ModelConfig:
|
|
8
|
+
"""Configuration for a model adapter."""
|
|
9
|
+
name: str
|
|
10
|
+
framework: str
|
|
11
|
+
language: str
|
|
12
|
+
version: str
|
|
13
|
+
parameters: Dict[str, Any]
|
|
14
|
+
requirements: Dict[str, str]
|
|
15
|
+
hardware_requirements: Optional[Dict[str, Any]] = None
|
|
16
|
+
|
|
17
|
+
class ModelAdapter(ABC):
|
|
18
|
+
"""Base class for all model adapters.
|
|
19
|
+
|
|
20
|
+
This interface defines the contract that all model adapters must implement.
|
|
21
|
+
It provides methods for training, evaluation, and model management.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, config: ModelConfig, python_interpreter: Optional[str] = None, environment_name: Optional[str] = None, conda_env_name: Optional[str] = None):
|
|
25
|
+
self.config = config
|
|
26
|
+
self.model = None
|
|
27
|
+
self.python_interpreter = python_interpreter
|
|
28
|
+
|
|
29
|
+
# Support both new and legacy parameter names
|
|
30
|
+
self.environment_name = environment_name or conda_env_name
|
|
31
|
+
# Keep legacy property for backward compatibility
|
|
32
|
+
self.conda_env_name = self.environment_name
|
|
33
|
+
|
|
34
|
+
if self.python_interpreter:
|
|
35
|
+
print(f"[{self.__class__.__name__}] Initialized with Python interpreter: {self.python_interpreter}")
|
|
36
|
+
|
|
37
|
+
if self.environment_name:
|
|
38
|
+
print(f"[{self.__class__.__name__}] Initialized with environment: {self.environment_name}")
|
|
39
|
+
else:
|
|
40
|
+
print(f"[{self.__class__.__name__}] Initialized without specific environment")
|
|
41
|
+
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def initialize(self) -> None:
|
|
44
|
+
"""Initialize the model with the given configuration."""
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
@abstractmethod
|
|
48
|
+
def run(self, data_paths: Dict[str, Path] | None = None, **kwargs) -> Dict[str, Any]:
|
|
49
|
+
"""Run the pipeline according to the configured processes/steps.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
data_paths: Optional mapping of named data roles to paths (e.g., {"training": Path(...), "validation": Path(...)}).
|
|
53
|
+
**kwargs: Additional parameters forwarded to the adapter/pipeline.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Dictionary containing pipeline results and/or metrics.
|
|
57
|
+
"""
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
@abstractmethod
|
|
61
|
+
def save(self, path: Path) -> None:
|
|
62
|
+
"""Save the model to the specified path."""
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
@abstractmethod
|
|
66
|
+
def load(self, path: Path) -> None:
|
|
67
|
+
"""Load the model from the specified path."""
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
# Optional prediction interface for adapters that expose direct predict APIs
|
|
71
|
+
def predict(self, data: Any) -> Any:
|
|
72
|
+
"""Optional: Make predictions using the model if supported by the adapter."""
|
|
73
|
+
raise NotImplementedError("This adapter does not implement a direct predict() API.")
|
|
74
|
+
|
|
75
|
+
@classmethod
|
|
76
|
+
@abstractmethod
|
|
77
|
+
def validate_config(cls, config: ModelConfig) -> bool:
|
|
78
|
+
"""Validate the configuration for this adapter.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
config: Configuration to validate
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
True if configuration is valid, False otherwise
|
|
85
|
+
"""
|
|
86
|
+
pass
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from typing import Dict, Any, Optional, List, Union
|
|
2
|
+
from pydantic import BaseModel, Field, ConfigDict
|
|
3
|
+
|
|
4
|
+
class HardwareRequirements(BaseModel):
|
|
5
|
+
"""Hardware requirements for model training."""
|
|
6
|
+
gpu: bool = False
|
|
7
|
+
min_memory_gb: Optional[float] = None
|
|
8
|
+
min_cpu_cores: Optional[int] = None
|
|
9
|
+
|
|
10
|
+
class ModelParameters(BaseModel):
|
|
11
|
+
"""Model-specific parameters."""
|
|
12
|
+
class_name: Optional[str] = Field(None, description="Fully qualified class name of the model (for pre-built frameworks)")
|
|
13
|
+
custom_script_path: Optional[str] = Field(None, description="Path to the custom Python script (relative to project root or absolute)")
|
|
14
|
+
custom_target: Optional[str] = Field(None, description="(Optional) Name of the class or function within the custom script. If not provided, the adapter will look for a MLOpsCustomModelBase subclass.")
|
|
15
|
+
hyperparameters: Dict[str, Any] = Field(default_factory=dict, description="Model initialization parameters")
|
|
16
|
+
training_params: Dict[str, Any] = Field(default_factory=dict, description="Training-specific parameters")
|
|
17
|
+
# Caching and execution
|
|
18
|
+
cache: Dict[str, Any] = Field(default_factory=dict, description="Caching configuration (ttl_hours, backend, object_store)")
|
|
19
|
+
executor: Dict[str, Any] = Field(default_factory=dict, description="Executor configuration (n_workers, scheduler_address)")
|
|
20
|
+
|
|
21
|
+
# NetworkX pipeline configuration - supports process-level DAGs with step-level loops
|
|
22
|
+
pipeline: Optional[Dict[str, Any]] = Field(None, description="NetworkX pipeline configuration with processes and steps")
|
|
23
|
+
|
|
24
|
+
class AdapterConfig(BaseModel):
|
|
25
|
+
"""Configuration for a model adapter."""
|
|
26
|
+
name: str = Field(..., description="Name of the model")
|
|
27
|
+
framework: str = Field(..., description="ML framework (e.g., sklearn, pytorch, tensorflow, custom)")
|
|
28
|
+
language: str = Field(..., description="Programming language (e.g., python, cpp)")
|
|
29
|
+
version: str = Field(..., description="Version of the framework or custom model")
|
|
30
|
+
parameters: ModelParameters = Field(..., description="Model-specific parameters")
|
|
31
|
+
requirements: Dict[str, str] = Field(
|
|
32
|
+
default_factory=dict,
|
|
33
|
+
description="Package requirements (package_name: version)"
|
|
34
|
+
)
|
|
35
|
+
hardware_requirements: Optional[HardwareRequirements] = Field(
|
|
36
|
+
None,
|
|
37
|
+
description="Hardware requirements for training"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
model_config = ConfigDict(
|
|
41
|
+
json_schema_extra={
|
|
42
|
+
"example": {
|
|
43
|
+
"name": "custom_model_with_loops",
|
|
44
|
+
"framework": "custom",
|
|
45
|
+
"language": "python",
|
|
46
|
+
"version": "1.0.0",
|
|
47
|
+
"parameters": {
|
|
48
|
+
"custom_script_path": "examples/custom_models/networkx_examples/models/kmeans_model.py",
|
|
49
|
+
"custom_target": "KMeansCustomModel",
|
|
50
|
+
"hyperparameters": {
|
|
51
|
+
"n_clusters": 3,
|
|
52
|
+
"max_iterations": 100,
|
|
53
|
+
"convergence_threshold": 0.001
|
|
54
|
+
},
|
|
55
|
+
# NetworkX pipeline configuration with process-level DAGs and step-level loops
|
|
56
|
+
"pipeline": {
|
|
57
|
+
"process_adjlist": "data_prep clustering\nclustering evaluation",
|
|
58
|
+
"processes": [
|
|
59
|
+
{"name": "data_prep", "max_iterations": 1},
|
|
60
|
+
{"name": "clustering", "max_iterations": 100, "convergence_threshold": 0.001},
|
|
61
|
+
{"name": "evaluation", "max_iterations": 1}
|
|
62
|
+
],
|
|
63
|
+
"steps": [
|
|
64
|
+
{"name": "preprocess_data", "process": "data_prep"},
|
|
65
|
+
{"name": "initialize_centroids", "process": "clustering"},
|
|
66
|
+
{"name": "update_centroids", "process": "clustering", "loop_back_to": "assign_clusters"},
|
|
67
|
+
{"name": "assign_clusters", "process": "clustering", "depends_on": ["update_centroids"], "loop_back_to": "update_centroids"},
|
|
68
|
+
{"name": "evaluate_clustering", "process": "evaluation", "depends_on": ["assign_clusters"]}
|
|
69
|
+
],
|
|
70
|
+
"execution": {
|
|
71
|
+
"parallel": True,
|
|
72
|
+
"failure_mode": "stop",
|
|
73
|
+
"max_workers": 4
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"requirements": {
|
|
78
|
+
"networkx": "3.0",
|
|
79
|
+
"numpy": "1.24.0",
|
|
80
|
+
"scikit-learn": "1.3.0"
|
|
81
|
+
},
|
|
82
|
+
"hardware_requirements": {
|
|
83
|
+
"gpu": False,
|
|
84
|
+
"min_memory_gb": 4.0,
|
|
85
|
+
"min_cpu_cores": 2
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
)
|