snowflake-ml-python 2.4.0__py3-none-any.whl → 2.6.0__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.
- snowflake/cortex/_classify_text.py +38 -32
- snowflake/ml/_internal/env_utils.py +6 -2
- snowflake/ml/_internal/file_utils.py +18 -1
- snowflake/ml/_internal/platform_capabilities.py +1 -1
- snowflake/ml/dataset/dataset.py +1 -1
- snowflake/ml/experiment/_entities/run.py +61 -8
- snowflake/ml/experiment/experiment_tracking.py +8 -10
- snowflake/ml/feature_store/decl/__init__.py +168 -0
- snowflake/ml/feature_store/decl/api.py +1796 -0
- snowflake/ml/feature_store/decl/compiler.py +770 -0
- snowflake/ml/feature_store/decl/dependencies.py +163 -0
- snowflake/ml/feature_store/decl/enums.py +55 -0
- snowflake/ml/feature_store/decl/errors.py +87 -0
- snowflake/ml/feature_store/decl/exporter.py +2376 -0
- snowflake/ml/feature_store/decl/imperative_executor.py +3487 -0
- snowflake/ml/feature_store/decl/invariants.py +3869 -0
- snowflake/ml/feature_store/decl/loader.py +871 -0
- snowflake/ml/feature_store/decl/manifest.py +348 -0
- snowflake/ml/feature_store/decl/planner.py +1319 -0
- snowflake/ml/feature_store/decl/project_paths.py +152 -0
- snowflake/ml/feature_store/decl/python_codegen.py +413 -0
- snowflake/ml/feature_store/decl/queries.py +172 -0
- snowflake/ml/feature_store/decl/serializer.py +313 -0
- snowflake/ml/feature_store/decl/service.py +736 -0
- snowflake/ml/feature_store/decl/spec_compiler.py +612 -0
- snowflake/ml/feature_store/decl/spec_models.py +1040 -0
- snowflake/ml/feature_store/decl/state.py +1995 -0
- snowflake/ml/feature_store/decl/templating.py +158 -0
- snowflake/ml/feature_store/decl/types.py +219 -0
- snowflake/ml/feature_store/decl/udf_loader.py +99 -0
- snowflake/ml/feature_store/feature_store.py +45 -21
- snowflake/ml/feature_store/feature_view.py +59 -17
- snowflake/ml/feature_store/spec/table_schema_evolution.py +10 -4
- snowflake/ml/jobs/__init__.py +10 -0
- snowflake/ml/jobs/_interop/data_utils.py +34 -2
- snowflake/ml/jobs/_interop/legacy.py +3 -3
- snowflake/ml/jobs/_utils/constants.py +9 -0
- snowflake/ml/jobs/_utils/object_naming.py +45 -0
- snowflake/ml/jobs/_utils/option_parsing.py +102 -0
- snowflake/ml/jobs/_utils/runtime_env_utils.py +25 -1
- snowflake/ml/jobs/_utils/stage_utils.py +25 -1
- snowflake/ml/jobs/code_bundle.py +532 -0
- snowflake/ml/jobs/job.py +59 -12
- snowflake/ml/jobs/job_definition.py +20 -51
- snowflake/ml/jobs/manager.py +3 -1
- snowflake/ml/lineage/lineage_node.py +9 -1
- snowflake/ml/model/__init__.py +0 -2
- snowflake/ml/model/_client/model/batch_inference_task.py +5 -9
- snowflake/ml/model/_client/model/model_version_impl.py +24 -51
- snowflake/ml/model/_client/ops/model_ops.py +12 -19
- snowflake/ml/model/_client/ops/service_ops.py +3 -2
- snowflake/ml/model/_client/service/model_deployment_spec.py +53 -33
- snowflake/ml/model/_client/sql/model.py +17 -51
- snowflake/ml/model/_packager/model_handlers/huggingface/_handler.py +19 -50
- snowflake/ml/model/_packager/model_handlers/mlflow.py +66 -101
- snowflake/ml/model/_packager/model_meta/model_meta.py +3 -1
- snowflake/ml/model/_packager/model_runtime/_snowml_inference_alternative_requirements.py +2 -2
- snowflake/ml/model/_packager/model_runtime/model_runtime.py +5 -1
- snowflake/ml/model/models/huggingface.py +135 -37
- snowflake/ml/model/type_hints.py +3 -4
- snowflake/ml/modeling/_internal/optional_dependency.py +6 -30
- snowflake/ml/modeling/calibration/__init__.py +1 -2
- snowflake/ml/modeling/cluster/__init__.py +1 -2
- snowflake/ml/modeling/compose/__init__.py +1 -2
- snowflake/ml/modeling/covariance/__init__.py +1 -2
- snowflake/ml/modeling/decomposition/__init__.py +1 -2
- snowflake/ml/modeling/discriminant_analysis/__init__.py +1 -2
- snowflake/ml/modeling/ensemble/__init__.py +1 -2
- snowflake/ml/modeling/feature_selection/__init__.py +1 -2
- snowflake/ml/modeling/gaussian_process/__init__.py +1 -2
- snowflake/ml/modeling/impute/__init__.py +1 -2
- snowflake/ml/modeling/kernel_approximation/__init__.py +1 -2
- snowflake/ml/modeling/kernel_ridge/__init__.py +1 -2
- snowflake/ml/modeling/lightgbm/__init__.py +1 -2
- snowflake/ml/modeling/linear_model/__init__.py +1 -2
- snowflake/ml/modeling/manifold/__init__.py +1 -2
- snowflake/ml/modeling/metrics/__init__.py +2 -3
- snowflake/ml/modeling/mixture/__init__.py +1 -2
- snowflake/ml/modeling/model_selection/__init__.py +1 -2
- snowflake/ml/modeling/multiclass/__init__.py +1 -2
- snowflake/ml/modeling/naive_bayes/__init__.py +1 -2
- snowflake/ml/modeling/neighbors/__init__.py +1 -2
- snowflake/ml/modeling/neural_network/__init__.py +1 -2
- snowflake/ml/modeling/pipeline/__init__.py +1 -2
- snowflake/ml/modeling/preprocessing/__init__.py +1 -2
- snowflake/ml/modeling/semi_supervised/__init__.py +1 -2
- snowflake/ml/modeling/svm/__init__.py +1 -2
- snowflake/ml/modeling/tree/__init__.py +1 -2
- snowflake/ml/modeling/xgboost/__init__.py +1 -2
- snowflake/ml/registry/_manager/model_manager.py +0 -1
- snowflake/ml/registry/_manager/model_parameter_reconciler.py +31 -1
- snowflake/ml/version.py +1 -1
- {snowflake_ml_python-2.4.0.dist-info → snowflake_ml_python-2.6.0.dist-info}/METADATA +65 -4
- {snowflake_ml_python-2.4.0.dist-info → snowflake_ml_python-2.6.0.dist-info}/RECORD +97 -72
- snowflake/ml/model/models/huggingface_pipeline.py +0 -268
- {snowflake_ml_python-2.4.0.dist-info → snowflake_ml_python-2.6.0.dist-info}/WHEEL +0 -0
- {snowflake_ml_python-2.4.0.dist-info → snowflake_ml_python-2.6.0.dist-info}/licenses/LICENSE.txt +0 -0
- {snowflake_ml_python-2.4.0.dist-info → snowflake_ml_python-2.6.0.dist-info}/top_level.txt +0 -0
|
@@ -6,24 +6,23 @@ from typing_extensions import deprecated
|
|
|
6
6
|
from snowflake import snowpark
|
|
7
7
|
from snowflake.cortex._util import (
|
|
8
8
|
CORTEX_FUNCTIONS_TELEMETRY_PROJECT,
|
|
9
|
-
|
|
9
|
+
SnowflakeAuthenticationException,
|
|
10
10
|
warn_cortex_deprecated,
|
|
11
11
|
)
|
|
12
12
|
from snowflake.ml._internal import telemetry
|
|
13
|
-
from snowflake.snowpark import functions
|
|
13
|
+
from snowflake.snowpark import context, functions
|
|
14
14
|
|
|
15
15
|
_AI_CLASSIFY_FUNCTION_NAME = "AI_CLASSIFY"
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
|
|
16
|
+
# AI_CLASSIFY requires its config argument to be a constant object literal. A Python dict is rendered by
|
|
17
|
+
# Snowpark as PARSE_JSON('...')::OBJECT, which the server rejects ("... is not a constant"), so emit the
|
|
18
|
+
# config as a SQL object constant via sql_expr -- this mirrors snowflake.snowpark.functions.ai_classify.
|
|
19
|
+
# Legacy CLASSIFY_TEXT was always single-label, so set output_mode explicitly to keep that contract.
|
|
20
|
+
_AI_CLASSIFY_SINGLE_LABEL_CONFIG_SQL = "{'output_mode': 'single'}"
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
def _adapt_ai_classify_result(result: Any) -> str:
|
|
23
24
|
"""Map an AI_CLASSIFY result to the legacy CLASSIFY_TEXT {"label": ...} JSON string."""
|
|
24
|
-
#
|
|
25
|
-
# collects as a JSON string such as '{"label": "positive"}'. We reproduce that exact shape so
|
|
26
|
-
# existing callers that json.loads the result and read ["label"] keep working.
|
|
25
|
+
# Used for non-Column results (e.g. a dict/JSON string): reproduce the legacy single-label object shape.
|
|
27
26
|
parsed: Any = result
|
|
28
27
|
if isinstance(result, str):
|
|
29
28
|
try:
|
|
@@ -40,6 +39,20 @@ def _adapt_ai_classify_result(result: Any) -> str:
|
|
|
40
39
|
return json.dumps({"label": label})
|
|
41
40
|
|
|
42
41
|
|
|
42
|
+
def _ai_classify_label_column(
|
|
43
|
+
str_input: str | snowpark.Column,
|
|
44
|
+
categories: list[str] | snowpark.Column,
|
|
45
|
+
) -> snowpark.Column:
|
|
46
|
+
"""Call AI_CLASSIFY in single-label mode and re-wrap to the legacy CLASSIFY_TEXT {"label": ...} OBJECT."""
|
|
47
|
+
result = functions.builtin(_AI_CLASSIFY_FUNCTION_NAME)(
|
|
48
|
+
str_input, categories, functions.sql_expr(_AI_CLASSIFY_SINGLE_LABEL_CONFIG_SQL)
|
|
49
|
+
)
|
|
50
|
+
# AI_CLASSIFY returns {"labels": [...]}; collapse to the legacy single {"label": ...}. Subscript access
|
|
51
|
+
# (not functions.get with a bare string, which Snowpark treats as a column identifier) uses literal keys.
|
|
52
|
+
label = functions.coalesce(result["labels"][0], result["label"])
|
|
53
|
+
return functions.object_construct(functions.lit("label"), label)
|
|
54
|
+
|
|
55
|
+
|
|
43
56
|
@telemetry.send_api_usage_telemetry(
|
|
44
57
|
project=CORTEX_FUNCTIONS_TELEMETRY_PROJECT,
|
|
45
58
|
)
|
|
@@ -56,32 +69,25 @@ def classify_text(
|
|
|
56
69
|
session: The snowpark session to use. Will be inferred by context if not specified.
|
|
57
70
|
|
|
58
71
|
Returns:
|
|
59
|
-
A column of classification responses.
|
|
72
|
+
A column of classification responses (legacy CLASSIFY_TEXT {"label": ...} shape).
|
|
73
|
+
|
|
74
|
+
Raises:
|
|
75
|
+
SnowflakeAuthenticationException: if no session is provided and none is active.
|
|
60
76
|
"""
|
|
61
77
|
warn_cortex_deprecated("classify_text", "ai_classify")
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if isinstance(result, snowpark.Column):
|
|
66
|
-
# AI_CLASSIFY returns {"labels": [...]}; re-wrap as the legacy CLASSIFY_TEXT {"label": ...} OBJECT
|
|
67
|
-
# so downstream SQL that reads col["label"] is unchanged. Subscript access (not functions.get with
|
|
68
|
-
# a bare string, which Snowpark treats as a column identifier) extracts the field by literal key.
|
|
69
|
-
label = functions.coalesce(result["labels"][0], result["label"])
|
|
70
|
-
return functions.object_construct(functions.lit("label"), label)
|
|
71
|
-
return _adapt_ai_classify_result(result)
|
|
72
|
-
|
|
78
|
+
column = _ai_classify_label_column(str_input, categories)
|
|
79
|
+
if isinstance(str_input, snowpark.Column) or isinstance(categories, snowpark.Column):
|
|
80
|
+
return column
|
|
73
81
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
args.append(config)
|
|
84
|
-
return cast(str | snowpark.Column, call_sql_function(function, session, *args))
|
|
82
|
+
# Immediate (literal) path: evaluate and return the collected OBJECT as a JSON string, exactly as the
|
|
83
|
+
# legacy CLASSIFY_TEXT immediate path did.
|
|
84
|
+
session = session or context.get_active_session()
|
|
85
|
+
if session is None:
|
|
86
|
+
raise SnowflakeAuthenticationException(
|
|
87
|
+
"""Session required. Provide the session through a session=... argument or ensure an active session is
|
|
88
|
+
available in your environment."""
|
|
89
|
+
)
|
|
90
|
+
return cast(str, session.create_dataframe([snowpark.Row()]).select(column).collect()[0][0])
|
|
85
91
|
|
|
86
92
|
|
|
87
93
|
ClassifyText = deprecated(
|
|
@@ -90,6 +90,9 @@ def _validate_pip_requirement_string(req_str: str) -> requirements.Requirement:
|
|
|
90
90
|
Returns:
|
|
91
91
|
A requirements.Requirement object containing the requirement information.
|
|
92
92
|
"""
|
|
93
|
+
# A requirement string must not carry surrounding whitespace: packaging>=26 accepts only a
|
|
94
|
+
# requirement that ends at the end of the string, so a trailing newline is a parse error.
|
|
95
|
+
req_str = req_str.strip()
|
|
93
96
|
try:
|
|
94
97
|
r = requirements.Requirement(req_str)
|
|
95
98
|
|
|
@@ -780,8 +783,9 @@ def load_requirements_file(path: pathlib.Path) -> list[requirements.Requirement]
|
|
|
780
783
|
with open(path, encoding="utf-8") as f:
|
|
781
784
|
reqs = f.readlines()
|
|
782
785
|
|
|
783
|
-
#
|
|
784
|
-
|
|
786
|
+
# "-" lines are pip options (e.g. --extra-index-url) and "#" lines are comments; neither is a
|
|
787
|
+
# requirement. Strip as well, since a requirement string must not keep readlines()' newline.
|
|
788
|
+
reqs = [stripped for line in reqs if (stripped := line.strip()) and not stripped.startswith(("-", "#"))]
|
|
785
789
|
|
|
786
790
|
return validate_pip_requirement_string_list(reqs)
|
|
787
791
|
|
|
@@ -120,7 +120,21 @@ def make_archive(
|
|
|
120
120
|
)
|
|
121
121
|
|
|
122
122
|
|
|
123
|
-
def zip_python_package(
|
|
123
|
+
def zip_python_package(
|
|
124
|
+
zipfile_path: str,
|
|
125
|
+
package_name: str,
|
|
126
|
+
ignore_generated_py_file: bool = True,
|
|
127
|
+
*,
|
|
128
|
+
exclude_dir_names: tuple[str, ...] = (),
|
|
129
|
+
) -> None:
|
|
130
|
+
"""Zip an imported Python package.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
zipfile_path: Destination zip path.
|
|
134
|
+
package_name: Dotted package name to zip.
|
|
135
|
+
ignore_generated_py_file: When True, omit generated bytecode and stub files.
|
|
136
|
+
exclude_dir_names: Directory names to omit anywhere in the package. The directory entry itself is not written.
|
|
137
|
+
"""
|
|
124
138
|
import importlib_resources
|
|
125
139
|
from importlib_resources import abc as importlib_resources_abc
|
|
126
140
|
|
|
@@ -131,6 +145,7 @@ def zip_python_package(zipfile_path: str, package_name: str, ignore_generated_py
|
|
|
131
145
|
|
|
132
146
|
base_dirs = package_name.split(".")
|
|
133
147
|
assert len(base_dirs) >= 1, "Invalid package name."
|
|
148
|
+
excluded_dirs = set(exclude_dir_names)
|
|
134
149
|
|
|
135
150
|
with zipfile.ZipFile(zipfile_path, mode="w", compression=zipfile.ZIP_DEFLATED) as zf:
|
|
136
151
|
for i in range(len(base_dirs)):
|
|
@@ -141,6 +156,8 @@ def zip_python_package(zipfile_path: str, package_name: str, ignore_generated_py
|
|
|
141
156
|
def _add_to_zip(
|
|
142
157
|
zf: zipfile.ZipFile, path_info: importlib_resources_abc.Traversable, base_arcname: pathlib.PurePosixPath
|
|
143
158
|
) -> None:
|
|
159
|
+
if path_info.name in excluded_dirs:
|
|
160
|
+
return
|
|
144
161
|
if path_info.is_file():
|
|
145
162
|
if ignore_generated_py_file and path_info.name.endswith(GENERATED_PY_FILE_EXT):
|
|
146
163
|
return
|
|
@@ -93,7 +93,7 @@ class PlatformCapabilities:
|
|
|
93
93
|
return self._get_bool_feature(ENABLE_MODEL_METHOD_SIGNATURE_PARAMETERS, False)
|
|
94
94
|
|
|
95
95
|
def is_lora_adapters_enabled(self) -> bool:
|
|
96
|
-
return False
|
|
96
|
+
return self._get_bool_feature(ENABLE_LORA_ADAPTERS, False)
|
|
97
97
|
|
|
98
98
|
def is_single_output_native_type_enabled(self) -> bool:
|
|
99
99
|
"""Whether a single, non-OBJECT model FUNCTION output is registered with its native SQL type.
|
snowflake/ml/dataset/dataset.py
CHANGED
|
@@ -341,7 +341,7 @@ class Dataset(lineage_node.LineageNode):
|
|
|
341
341
|
metadata = dataset_metadata.DatasetMetadata(
|
|
342
342
|
source_query=source_query,
|
|
343
343
|
owner=self._session.sql("SELECT CURRENT_USER()").collect(statement_params=_TELEMETRY_STATEMENT_PARAMS)[0][
|
|
344
|
-
|
|
344
|
+
0
|
|
345
345
|
],
|
|
346
346
|
exclude_cols=exclude_cols,
|
|
347
347
|
label_cols=label_cols,
|
|
@@ -2,9 +2,11 @@ import types
|
|
|
2
2
|
import warnings
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
-
from snowflake
|
|
5
|
+
from snowflake import snowpark
|
|
6
|
+
from snowflake.ml._internal.utils import identifier, sql_identifier
|
|
6
7
|
from snowflake.ml.experiment import _experiment_info as experiment_info
|
|
7
8
|
from snowflake.ml.experiment._entities import run_metadata
|
|
9
|
+
from snowflake.ml.lineage import lineage_node
|
|
8
10
|
|
|
9
11
|
if TYPE_CHECKING:
|
|
10
12
|
from snowflake.ml.experiment import experiment_tracking
|
|
@@ -12,13 +14,24 @@ if TYPE_CHECKING:
|
|
|
12
14
|
METADATA_SIZE_WARNING_MESSAGE = "It is likely that no further metrics or parameters will be logged for this run."
|
|
13
15
|
|
|
14
16
|
|
|
15
|
-
class Run:
|
|
17
|
+
class Run(lineage_node.LineageNode):
|
|
18
|
+
"""An experiment run.
|
|
19
|
+
|
|
20
|
+
When created by ``ExperimentTracking.start_run``, the run is an active context manager that
|
|
21
|
+
patches model logging and ends the run on exit. When returned by the lineage system
|
|
22
|
+
(``model_version.lineage(direction="upstream", domain_filter={"experiment"})``), it is a
|
|
23
|
+
read-only handle exposing the identifiers needed to look up metrics and parameters.
|
|
24
|
+
"""
|
|
25
|
+
|
|
16
26
|
def __init__(
|
|
17
27
|
self,
|
|
18
|
-
experiment_tracking: "experiment_tracking.ExperimentTracking",
|
|
28
|
+
experiment_tracking: "experiment_tracking.ExperimentTracking | None" = None,
|
|
19
29
|
*,
|
|
20
30
|
experiment_name: sql_identifier.SqlIdentifier,
|
|
21
31
|
run_name: sql_identifier.SqlIdentifier,
|
|
32
|
+
session: snowpark.Session | None = None,
|
|
33
|
+
database_name: str | None = None,
|
|
34
|
+
schema_name: str | None = None,
|
|
22
35
|
) -> None:
|
|
23
36
|
self._experiment_tracking = experiment_tracking
|
|
24
37
|
self.experiment_name = experiment_name
|
|
@@ -27,10 +40,31 @@ class Run:
|
|
|
27
40
|
# Whether we've already shown the user a warning about exceeding the run metadata size limit.
|
|
28
41
|
self._warned_about_metadata_size = False
|
|
29
42
|
|
|
43
|
+
if experiment_tracking is not None:
|
|
44
|
+
_session = experiment_tracking._session
|
|
45
|
+
self.database_name = str(experiment_tracking._database_name)
|
|
46
|
+
self.schema_name = str(experiment_tracking._schema_name)
|
|
47
|
+
else:
|
|
48
|
+
if session is None or database_name is None or schema_name is None:
|
|
49
|
+
raise ValueError(
|
|
50
|
+
"session, database_name, and schema_name are required when experiment_tracking is None"
|
|
51
|
+
)
|
|
52
|
+
_session = session
|
|
53
|
+
self.database_name = database_name
|
|
54
|
+
self.schema_name = schema_name
|
|
55
|
+
|
|
30
56
|
self._patcher = experiment_info.ExperimentInfoPatcher(
|
|
31
57
|
experiment_info=self._get_experiment_info(),
|
|
32
58
|
)
|
|
33
59
|
|
|
60
|
+
# A run is modelled in lineage as a version of its experiment, so the node name is the experiment's.
|
|
61
|
+
super().__init__(
|
|
62
|
+
session=_session,
|
|
63
|
+
name=self._fully_qualified_experiment_name(),
|
|
64
|
+
domain="experiment",
|
|
65
|
+
version=str(run_name),
|
|
66
|
+
)
|
|
67
|
+
|
|
34
68
|
def __enter__(self) -> "Run":
|
|
35
69
|
self._patcher.__enter__()
|
|
36
70
|
return self
|
|
@@ -42,18 +76,19 @@ class Run:
|
|
|
42
76
|
tb: types.TracebackType | None,
|
|
43
77
|
) -> None:
|
|
44
78
|
self._patcher.__exit__(exc_type, exc_value, tb)
|
|
45
|
-
if self._experiment_tracking._run is self:
|
|
79
|
+
if self._experiment_tracking is not None and self._experiment_tracking._run is self:
|
|
46
80
|
if exc_type is not None:
|
|
47
81
|
self._experiment_tracking._try_log_exception(exc_type, exc_value, tb)
|
|
48
82
|
self._experiment_tracking.end_run(status=run_metadata.RunStatus.FAILED.value)
|
|
49
83
|
else:
|
|
50
84
|
self._experiment_tracking.end_run()
|
|
51
85
|
|
|
86
|
+
def _fully_qualified_experiment_name(self) -> str:
|
|
87
|
+
return sql_identifier.get_fully_qualified_name(self.database_name, self.schema_name, self.experiment_name)
|
|
88
|
+
|
|
52
89
|
def _get_experiment_info(self) -> experiment_info.ExperimentInfo:
|
|
53
90
|
return experiment_info.ExperimentInfo(
|
|
54
|
-
fully_qualified_name=self.
|
|
55
|
-
self._experiment_tracking._database_name, self._experiment_tracking._schema_name, self.experiment_name
|
|
56
|
-
),
|
|
91
|
+
fully_qualified_name=self._fully_qualified_experiment_name(),
|
|
57
92
|
run_name=self.name.identifier(),
|
|
58
93
|
)
|
|
59
94
|
|
|
@@ -67,9 +102,27 @@ class Run:
|
|
|
67
102
|
RuntimeWarning: If the experiment tracking instance was created with warnings_as_errors=True.
|
|
68
103
|
"""
|
|
69
104
|
message = f"{sql_error_msg}. {METADATA_SIZE_WARNING_MESSAGE}"
|
|
70
|
-
if self._experiment_tracking._warnings_as_errors:
|
|
105
|
+
if self._experiment_tracking is not None and self._experiment_tracking._warnings_as_errors:
|
|
71
106
|
raise RuntimeWarning(message)
|
|
72
107
|
# Once the limit is hit every subsequent log attempt fails the same way, so warn only once.
|
|
73
108
|
if not self._warned_about_metadata_size:
|
|
74
109
|
warnings.warn(message, RuntimeWarning, stacklevel=2)
|
|
75
110
|
self._warned_about_metadata_size = True
|
|
111
|
+
|
|
112
|
+
@staticmethod
|
|
113
|
+
def _load_from_lineage_node(
|
|
114
|
+
session: snowpark.Session,
|
|
115
|
+
name: str,
|
|
116
|
+
version: str,
|
|
117
|
+
) -> "Run":
|
|
118
|
+
database_name, schema_name, experiment_name = identifier.parse_schema_level_object_identifier(name)
|
|
119
|
+
return Run(
|
|
120
|
+
experiment_name=sql_identifier.SqlIdentifier(experiment_name),
|
|
121
|
+
run_name=sql_identifier.SqlIdentifier(version),
|
|
122
|
+
session=session,
|
|
123
|
+
database_name=database_name,
|
|
124
|
+
schema_name=schema_name,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
lineage_node.DOMAIN_LINEAGE_REGISTRY["experiment"] = Run
|
|
@@ -25,7 +25,6 @@ from snowflake.ml.experiment._client import (
|
|
|
25
25
|
experiment_tracking_sql_client as sql_client,
|
|
26
26
|
)
|
|
27
27
|
from snowflake.ml.experiment._entities import run_metadata
|
|
28
|
-
from snowflake.ml.lineage import lineage_node
|
|
29
28
|
from snowflake.ml.model import type_hints
|
|
30
29
|
from snowflake.ml.utils import sql_client as sql_client_utils
|
|
31
30
|
from snowflake.snowpark import functions
|
|
@@ -328,15 +327,14 @@ class ExperimentTracking:
|
|
|
328
327
|
else:
|
|
329
328
|
raise RuntimeError("No run is active. Please provide a run_name or start a run.")
|
|
330
329
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
)
|
|
330
|
+
if self._run and self._run.name == resolved_run_name:
|
|
331
|
+
run_node = self._run
|
|
332
|
+
else:
|
|
333
|
+
run_node = entities.Run(
|
|
334
|
+
experiment_tracking=self,
|
|
335
|
+
experiment_name=self._experiment.name,
|
|
336
|
+
run_name=resolved_run_name,
|
|
337
|
+
)
|
|
340
338
|
logged_models = run_node.lineage(direction="downstream", domain_filter={"model"})
|
|
341
339
|
return [model for model in logged_models if isinstance(model, ml_model.ModelVersion)]
|
|
342
340
|
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""Public API for the declarative feature store library.
|
|
2
|
+
|
|
3
|
+
Import the key functions and types from this package:
|
|
4
|
+
|
|
5
|
+
from snowflake.ml.feature_store.decl import (
|
|
6
|
+
load_specs,
|
|
7
|
+
validate_specs,
|
|
8
|
+
generate_plan,
|
|
9
|
+
fetch_applied_state,
|
|
10
|
+
SpecBatch,
|
|
11
|
+
AppliedState,
|
|
12
|
+
Plan,
|
|
13
|
+
PlanOptions,
|
|
14
|
+
ValidationResult,
|
|
15
|
+
PlanOp,
|
|
16
|
+
AppliedObject,
|
|
17
|
+
SpecLoadError,
|
|
18
|
+
ValidationError,
|
|
19
|
+
DependencyError,
|
|
20
|
+
StateDriftError,
|
|
21
|
+
FSBaseType,
|
|
22
|
+
FeatureViewKind,
|
|
23
|
+
SourceType,
|
|
24
|
+
FeatureAggregationMethod,
|
|
25
|
+
OpKind,
|
|
26
|
+
TYPE_ALIASES,
|
|
27
|
+
normalize_type,
|
|
28
|
+
FSColumn,
|
|
29
|
+
SpecBase,
|
|
30
|
+
Entity,
|
|
31
|
+
StreamingSource,
|
|
32
|
+
BatchSource,
|
|
33
|
+
SourceRef,
|
|
34
|
+
UDF,
|
|
35
|
+
Feature,
|
|
36
|
+
FeatureView,
|
|
37
|
+
FeatureViewRef,
|
|
38
|
+
FeatureGroup,
|
|
39
|
+
)
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
from snowflake.ml.feature_store.decl.api import (
|
|
44
|
+
discover_project,
|
|
45
|
+
fetch_applied_state,
|
|
46
|
+
generate_plan,
|
|
47
|
+
load_manifest,
|
|
48
|
+
load_project,
|
|
49
|
+
load_specs,
|
|
50
|
+
resolve_datasource_columns,
|
|
51
|
+
resolve_target,
|
|
52
|
+
validate_specs,
|
|
53
|
+
)
|
|
54
|
+
except ModuleNotFoundError: # lower-layer BUILD targets omit api.py
|
|
55
|
+
pass
|
|
56
|
+
from snowflake.ml.feature_store.decl.enums import (
|
|
57
|
+
TYPE_ALIASES,
|
|
58
|
+
FeatureAggregationMethod,
|
|
59
|
+
FeatureViewKind,
|
|
60
|
+
FSBaseType,
|
|
61
|
+
OpKind,
|
|
62
|
+
SourceType,
|
|
63
|
+
normalize_type,
|
|
64
|
+
)
|
|
65
|
+
from snowflake.ml.feature_store.decl.errors import (
|
|
66
|
+
DependencyError,
|
|
67
|
+
SpecLoadError,
|
|
68
|
+
StateDriftError,
|
|
69
|
+
ValidationError,
|
|
70
|
+
)
|
|
71
|
+
from snowflake.ml.feature_store.decl.manifest import (
|
|
72
|
+
FSManifest,
|
|
73
|
+
FSTarget,
|
|
74
|
+
FSTemplating,
|
|
75
|
+
InvalidManifestError,
|
|
76
|
+
ManifestConfigurationError,
|
|
77
|
+
ManifestNotFoundError,
|
|
78
|
+
TargetContext,
|
|
79
|
+
)
|
|
80
|
+
from snowflake.ml.feature_store.decl.project_paths import FSProjectPaths
|
|
81
|
+
from snowflake.ml.feature_store.decl.spec_models import (
|
|
82
|
+
UDF,
|
|
83
|
+
Backfill,
|
|
84
|
+
BatchFeatureView,
|
|
85
|
+
BatchSource,
|
|
86
|
+
Entity,
|
|
87
|
+
Feature,
|
|
88
|
+
FeatureGroup,
|
|
89
|
+
FeatureView,
|
|
90
|
+
FeatureViewRef,
|
|
91
|
+
FSColumn,
|
|
92
|
+
RealtimeFeatureView,
|
|
93
|
+
SourceRef,
|
|
94
|
+
SpecBase,
|
|
95
|
+
StorageConfig,
|
|
96
|
+
StreamingFeatureView,
|
|
97
|
+
StreamingSource,
|
|
98
|
+
)
|
|
99
|
+
from snowflake.ml.feature_store.decl.types import (
|
|
100
|
+
AppliedObject,
|
|
101
|
+
AppliedState,
|
|
102
|
+
Plan,
|
|
103
|
+
PlanOp,
|
|
104
|
+
PlanOptions,
|
|
105
|
+
SpecBatch,
|
|
106
|
+
ValidationResult,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
__all__ = [
|
|
110
|
+
# api.py
|
|
111
|
+
"load_specs",
|
|
112
|
+
"validate_specs",
|
|
113
|
+
"generate_plan",
|
|
114
|
+
"fetch_applied_state",
|
|
115
|
+
"resolve_datasource_columns",
|
|
116
|
+
"load_manifest",
|
|
117
|
+
"discover_project",
|
|
118
|
+
"resolve_target",
|
|
119
|
+
"load_project",
|
|
120
|
+
# enums.py
|
|
121
|
+
"FSBaseType",
|
|
122
|
+
"FeatureViewKind",
|
|
123
|
+
"SourceType",
|
|
124
|
+
"FeatureAggregationMethod",
|
|
125
|
+
"OpKind",
|
|
126
|
+
"TYPE_ALIASES",
|
|
127
|
+
"normalize_type",
|
|
128
|
+
# errors.py
|
|
129
|
+
"SpecLoadError",
|
|
130
|
+
"ValidationError",
|
|
131
|
+
"DependencyError",
|
|
132
|
+
"StateDriftError",
|
|
133
|
+
# manifest.py
|
|
134
|
+
"FSManifest",
|
|
135
|
+
"FSTarget",
|
|
136
|
+
"FSTemplating",
|
|
137
|
+
"TargetContext",
|
|
138
|
+
"ManifestNotFoundError",
|
|
139
|
+
"InvalidManifestError",
|
|
140
|
+
"ManifestConfigurationError",
|
|
141
|
+
# project_paths.py
|
|
142
|
+
"FSProjectPaths",
|
|
143
|
+
# spec_models.py
|
|
144
|
+
"FSColumn",
|
|
145
|
+
"SpecBase",
|
|
146
|
+
"Entity",
|
|
147
|
+
"StreamingSource",
|
|
148
|
+
"BatchSource",
|
|
149
|
+
"SourceRef",
|
|
150
|
+
"UDF",
|
|
151
|
+
"Feature",
|
|
152
|
+
"FeatureView",
|
|
153
|
+
"StreamingFeatureView",
|
|
154
|
+
"BatchFeatureView",
|
|
155
|
+
"RealtimeFeatureView",
|
|
156
|
+
"FeatureViewRef",
|
|
157
|
+
"FeatureGroup",
|
|
158
|
+
"Backfill",
|
|
159
|
+
"StorageConfig",
|
|
160
|
+
# types.py
|
|
161
|
+
"AppliedObject",
|
|
162
|
+
"AppliedState",
|
|
163
|
+
"PlanOp",
|
|
164
|
+
"Plan",
|
|
165
|
+
"ValidationResult",
|
|
166
|
+
"PlanOptions",
|
|
167
|
+
"SpecBatch",
|
|
168
|
+
]
|