snowflake-ml-python 1.7.0__py3-none-any.whl → 1.7.2__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/__init__.py +4 -0
- snowflake/cortex/_complete.py +107 -64
- snowflake/cortex/_finetune.py +273 -0
- snowflake/cortex/_sse_client.py +91 -28
- snowflake/cortex/_util.py +30 -1
- snowflake/ml/_internal/type_utils.py +3 -3
- snowflake/ml/_internal/utils/jwt_generator.py +141 -0
- snowflake/ml/data/__init__.py +5 -0
- snowflake/ml/model/_client/model/model_version_impl.py +26 -12
- snowflake/ml/model/_client/ops/model_ops.py +51 -30
- snowflake/ml/model/_client/ops/service_ops.py +25 -9
- snowflake/ml/model/_client/sql/model.py +0 -14
- snowflake/ml/model/_client/sql/service.py +25 -1
- snowflake/ml/model/_client/sql/stage.py +1 -1
- snowflake/ml/model/_model_composer/model_method/infer_function.py_template +2 -1
- snowflake/ml/model/_packager/model_env/model_env.py +12 -0
- snowflake/ml/model/_packager/model_handlers/_utils.py +1 -1
- snowflake/ml/model/_packager/model_handlers/catboost.py +1 -1
- snowflake/ml/model/_packager/model_handlers/custom.py +3 -1
- snowflake/ml/model/_packager/model_handlers/lightgbm.py +2 -1
- snowflake/ml/model/_packager/model_handlers/sklearn.py +50 -1
- snowflake/ml/model/_packager/model_handlers/snowmlmodel.py +1 -1
- snowflake/ml/model/_packager/model_handlers/tensorflow.py +23 -6
- snowflake/ml/model/_packager/model_handlers/torchscript.py +14 -14
- snowflake/ml/model/_packager/model_meta/_packaging_requirements.py +2 -3
- snowflake/ml/model/_packager/model_meta/model_meta_schema.py +5 -0
- snowflake/ml/model/_packager/model_runtime/_snowml_inference_alternative_requirements.py +2 -10
- snowflake/ml/model/_packager/model_runtime/model_runtime.py +4 -9
- snowflake/ml/model/_packager/model_task/model_task_utils.py +1 -1
- snowflake/ml/model/_signatures/core.py +63 -16
- snowflake/ml/model/_signatures/pandas_handler.py +71 -27
- snowflake/ml/model/_signatures/pytorch_handler.py +2 -2
- snowflake/ml/model/_signatures/snowpark_handler.py +2 -1
- snowflake/ml/model/_signatures/tensorflow_handler.py +2 -2
- snowflake/ml/model/_signatures/utils.py +4 -1
- snowflake/ml/model/model_signature.py +38 -9
- snowflake/ml/model/type_hints.py +1 -1
- snowflake/ml/modeling/lightgbm/lgbm_classifier.py +2 -4
- snowflake/ml/modeling/lightgbm/lgbm_regressor.py +2 -4
- snowflake/ml/monitoring/_client/model_monitor_sql_client.py +148 -1200
- snowflake/ml/monitoring/_manager/model_monitor_manager.py +114 -238
- snowflake/ml/monitoring/entities/model_monitor_config.py +38 -12
- snowflake/ml/monitoring/model_monitor.py +12 -86
- snowflake/ml/registry/registry.py +28 -40
- snowflake/ml/utils/authentication.py +75 -0
- snowflake/ml/version.py +1 -1
- {snowflake_ml_python-1.7.0.dist-info → snowflake_ml_python-1.7.2.dist-info}/METADATA +116 -52
- {snowflake_ml_python-1.7.0.dist-info → snowflake_ml_python-1.7.2.dist-info}/RECORD +51 -49
- {snowflake_ml_python-1.7.0.dist-info → snowflake_ml_python-1.7.2.dist-info}/WHEEL +1 -1
- snowflake/ml/monitoring/entities/model_monitor_interval.py +0 -46
- snowflake/ml/monitoring/entities/output_score_type.py +0 -90
- {snowflake_ml_python-1.7.0.dist-info → snowflake_ml_python-1.7.2.dist-info}/LICENSE.txt +0 -0
- {snowflake_ml_python-1.7.0.dist-info → snowflake_ml_python-1.7.2.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,7 @@
|
|
1
|
-
from typing import List, Union
|
2
|
-
|
3
|
-
import pandas as pd
|
4
|
-
|
5
1
|
from snowflake import snowpark
|
6
2
|
from snowflake.ml._internal import telemetry
|
7
3
|
from snowflake.ml._internal.utils import sql_identifier
|
4
|
+
from snowflake.ml.monitoring import model_monitor_version
|
8
5
|
from snowflake.ml.monitoring._client import model_monitor_sql_client
|
9
6
|
|
10
7
|
|
@@ -13,114 +10,43 @@ class ModelMonitor:
|
|
13
10
|
|
14
11
|
name: sql_identifier.SqlIdentifier
|
15
12
|
_model_monitor_client: model_monitor_sql_client.ModelMonitorSQLClient
|
16
|
-
_fully_qualified_model_name: str
|
17
|
-
_version_name: sql_identifier.SqlIdentifier
|
18
|
-
_function_name: sql_identifier.SqlIdentifier
|
19
|
-
_prediction_columns: List[sql_identifier.SqlIdentifier]
|
20
|
-
_label_columns: List[sql_identifier.SqlIdentifier]
|
21
13
|
|
22
14
|
def __init__(self) -> None:
|
23
|
-
raise RuntimeError("
|
15
|
+
raise RuntimeError("Model Monitor's initializer is not meant to be used.")
|
24
16
|
|
25
17
|
@classmethod
|
26
18
|
def _ref(
|
27
19
|
cls,
|
28
20
|
model_monitor_client: model_monitor_sql_client.ModelMonitorSQLClient,
|
29
21
|
name: sql_identifier.SqlIdentifier,
|
30
|
-
*,
|
31
|
-
fully_qualified_model_name: str,
|
32
|
-
version_name: sql_identifier.SqlIdentifier,
|
33
|
-
function_name: sql_identifier.SqlIdentifier,
|
34
|
-
prediction_columns: List[sql_identifier.SqlIdentifier],
|
35
|
-
label_columns: List[sql_identifier.SqlIdentifier],
|
36
22
|
) -> "ModelMonitor":
|
37
23
|
self: "ModelMonitor" = object.__new__(cls)
|
38
24
|
self.name = name
|
39
25
|
self._model_monitor_client = model_monitor_client
|
40
|
-
self._fully_qualified_model_name = fully_qualified_model_name
|
41
|
-
self._version_name = version_name
|
42
|
-
self._function_name = function_name
|
43
|
-
self._prediction_columns = prediction_columns
|
44
|
-
self._label_columns = label_columns
|
45
26
|
return self
|
46
27
|
|
47
28
|
@telemetry.send_api_usage_telemetry(
|
48
29
|
project=telemetry.TelemetryProject.MLOPS.value,
|
49
30
|
subproject=telemetry.TelemetrySubProject.MONITORING.value,
|
50
31
|
)
|
51
|
-
|
52
|
-
"""
|
53
|
-
The baseline dataframe is compared with the monitored data once monitoring is enabled.
|
54
|
-
The columns of the dataframe should match the columns of the source table that the
|
55
|
-
ModelMonitor was configured with. Calling this method overwrites any existing baseline split data.
|
56
|
-
|
57
|
-
Args:
|
58
|
-
baseline_df: Snowpark dataframe containing baseline data.
|
59
|
-
|
60
|
-
Raises:
|
61
|
-
ValueError: baseline_df does not contain prediction or label columns
|
62
|
-
"""
|
63
|
-
statement_params = telemetry.get_statement_params(
|
64
|
-
project=telemetry.TelemetryProject.MLOPS.value,
|
65
|
-
subproject=telemetry.TelemetrySubProject.MONITORING.value,
|
66
|
-
)
|
67
|
-
|
68
|
-
if isinstance(baseline_df, pd.DataFrame):
|
69
|
-
baseline_df = self._model_monitor_client._sql_client._session.create_dataframe(baseline_df)
|
70
|
-
|
71
|
-
column_names_identifiers: List[sql_identifier.SqlIdentifier] = [
|
72
|
-
sql_identifier.SqlIdentifier(column_name) for column_name in baseline_df.columns
|
73
|
-
]
|
74
|
-
prediction_cols_not_found = any(
|
75
|
-
[prediction_col not in column_names_identifiers for prediction_col in self._prediction_columns]
|
76
|
-
)
|
77
|
-
label_cols_not_found = any(
|
78
|
-
[label_col.identifier() not in column_names_identifiers for label_col in self._label_columns]
|
79
|
-
)
|
80
|
-
|
81
|
-
if prediction_cols_not_found:
|
82
|
-
raise ValueError(
|
83
|
-
"Specified prediction columns were not found in the baseline dataframe. "
|
84
|
-
f"Columns provided were: {column_names_identifiers}. "
|
85
|
-
f"Configured prediction columns were: {self._prediction_columns}."
|
86
|
-
)
|
87
|
-
if label_cols_not_found:
|
88
|
-
raise ValueError(
|
89
|
-
"Specified label columns were not found in the baseline dataframe."
|
90
|
-
f"Columns provided in the baseline dataframe were: {column_names_identifiers}."
|
91
|
-
f"Configured label columns were: {self._label_columns}."
|
92
|
-
)
|
93
|
-
|
94
|
-
# Create the table by materializing the df
|
95
|
-
self._model_monitor_client.materialize_baseline_dataframe(
|
96
|
-
baseline_df,
|
97
|
-
self._fully_qualified_model_name,
|
98
|
-
self._version_name,
|
99
|
-
statement_params=statement_params,
|
100
|
-
)
|
101
|
-
|
32
|
+
@snowpark._internal.utils.private_preview(version=model_monitor_version.SNOWFLAKE_ML_MONITORING_MIN_VERSION)
|
102
33
|
def suspend(self) -> None:
|
103
|
-
"""Suspend
|
34
|
+
"""Suspend the Model Monitor"""
|
104
35
|
statement_params = telemetry.get_statement_params(
|
105
36
|
telemetry.TelemetryProject.MLOPS.value,
|
106
37
|
telemetry.TelemetrySubProject.MONITORING.value,
|
107
38
|
)
|
108
|
-
|
109
|
-
self._model_monitor_client.suspend_monitor_dynamic_tables(
|
110
|
-
model_name=model_name,
|
111
|
-
version_name=self._version_name,
|
112
|
-
statement_params=statement_params,
|
113
|
-
)
|
39
|
+
self._model_monitor_client.suspend_monitor(self.name, statement_params=statement_params)
|
114
40
|
|
41
|
+
@telemetry.send_api_usage_telemetry(
|
42
|
+
project=telemetry.TelemetryProject.MLOPS.value,
|
43
|
+
subproject=telemetry.TelemetrySubProject.MONITORING.value,
|
44
|
+
)
|
45
|
+
@snowpark._internal.utils.private_preview(version=model_monitor_version.SNOWFLAKE_ML_MONITORING_MIN_VERSION)
|
115
46
|
def resume(self) -> None:
|
116
|
-
"""Resume
|
47
|
+
"""Resume the Model Monitor"""
|
117
48
|
statement_params = telemetry.get_statement_params(
|
118
49
|
telemetry.TelemetryProject.MLOPS.value,
|
119
50
|
telemetry.TelemetrySubProject.MONITORING.value,
|
120
51
|
)
|
121
|
-
|
122
|
-
self._model_monitor_client.resume_monitor_dynamic_tables(
|
123
|
-
model_name=model_name,
|
124
|
-
version_name=self._version_name,
|
125
|
-
statement_params=statement_params,
|
126
|
-
)
|
52
|
+
self._model_monitor_client.resume_monitor(self.name, statement_params=statement_params)
|
@@ -23,6 +23,11 @@ from snowflake.snowpark import session
|
|
23
23
|
_TELEMETRY_PROJECT = "MLOps"
|
24
24
|
_MODEL_TELEMETRY_SUBPROJECT = "ModelManagement"
|
25
25
|
|
26
|
+
_MODEL_MONITORING_UNIMPLEMENTED_ERROR = "Model Monitoring is not implemented in python yet."
|
27
|
+
_MODEL_MONITORING_DISABLED_ERROR = (
|
28
|
+
"""Must enable monitoring to use this method. Please set `options={"enable_monitoring": True}` in the Registry"""
|
29
|
+
)
|
30
|
+
|
26
31
|
|
27
32
|
class Registry:
|
28
33
|
def __init__(
|
@@ -84,7 +89,6 @@ class Registry:
|
|
84
89
|
session=session,
|
85
90
|
database_name=self._database_name,
|
86
91
|
schema_name=self._schema_name,
|
87
|
-
create_if_not_exists=True, # TODO: Support static setup method to configure schema for monitoring.
|
88
92
|
statement_params=monitor_statement_params,
|
89
93
|
)
|
90
94
|
|
@@ -381,47 +385,38 @@ class Registry:
|
|
381
385
|
def add_monitor(
|
382
386
|
self,
|
383
387
|
name: str,
|
384
|
-
|
388
|
+
source_config: model_monitor_config.ModelMonitorSourceConfig,
|
385
389
|
model_monitor_config: model_monitor_config.ModelMonitorConfig,
|
386
|
-
*,
|
387
|
-
add_dashboard_udtfs: bool = False,
|
388
390
|
) -> model_monitor.ModelMonitor:
|
389
|
-
"""Add a Model Monitor to the Registry
|
391
|
+
"""Add a Model Monitor to the Registry.
|
390
392
|
|
391
393
|
Args:
|
392
|
-
name: Name of Model Monitor to create
|
393
|
-
|
394
|
-
model_monitor_config: Configuration options of
|
395
|
-
add_dashboard_udtfs: Add UDTFs useful for creating a dashboard.
|
394
|
+
name: Name of Model Monitor to create.
|
395
|
+
source_config: Configuration options of table for Model Monitor.
|
396
|
+
model_monitor_config: Configuration options of Model Monitor.
|
396
397
|
|
397
398
|
Returns:
|
398
|
-
The newly added
|
399
|
+
The newly added Model Monitor object.
|
399
400
|
|
400
401
|
Raises:
|
401
|
-
ValueError: If monitoring
|
402
|
+
ValueError: If monitoring is not enabled in the Registry.
|
402
403
|
"""
|
403
404
|
if not self.enable_monitoring:
|
404
|
-
raise ValueError(
|
405
|
-
|
406
|
-
)
|
407
|
-
|
408
|
-
# TODO: Change to fully qualified source table reference to allow table to live in different DB.
|
409
|
-
return self._model_monitor_manager.add_monitor(
|
410
|
-
name, table_config, model_monitor_config, add_dashboard_udtfs=add_dashboard_udtfs
|
411
|
-
)
|
405
|
+
raise ValueError(_MODEL_MONITORING_DISABLED_ERROR)
|
406
|
+
return self._model_monitor_manager.add_monitor(name, source_config, model_monitor_config)
|
412
407
|
|
413
408
|
@overload
|
414
409
|
def get_monitor(self, model_version: model_version_impl.ModelVersion) -> model_monitor.ModelMonitor:
|
415
|
-
"""Get a Model Monitor on a
|
410
|
+
"""Get a Model Monitor on a Model Version from the Registry.
|
416
411
|
|
417
412
|
Args:
|
418
|
-
model_version:
|
413
|
+
model_version: Model Version for which to retrieve the Model Monitor.
|
419
414
|
"""
|
420
415
|
...
|
421
416
|
|
422
417
|
@overload
|
423
418
|
def get_monitor(self, name: str) -> model_monitor.ModelMonitor:
|
424
|
-
"""Get a Model Monitor from the Registry
|
419
|
+
"""Get a Model Monitor by name from the Registry.
|
425
420
|
|
426
421
|
Args:
|
427
422
|
name: Name of Model Monitor to retrieve.
|
@@ -436,27 +431,24 @@ class Registry:
|
|
436
431
|
def get_monitor(
|
437
432
|
self, *, name: Optional[str] = None, model_version: Optional[model_version_impl.ModelVersion] = None
|
438
433
|
) -> model_monitor.ModelMonitor:
|
439
|
-
"""Get a Model Monitor from the Registry
|
434
|
+
"""Get a Model Monitor from the Registry.
|
440
435
|
|
441
436
|
Args:
|
442
437
|
name: Name of Model Monitor to retrieve.
|
443
|
-
model_version:
|
438
|
+
model_version: Model Version for which to retrieve the Model Monitor.
|
444
439
|
|
445
440
|
Returns:
|
446
|
-
The fetched
|
441
|
+
The fetched Model Monitor.
|
447
442
|
|
448
443
|
Raises:
|
449
|
-
ValueError: If monitoring
|
450
|
-
ValueError: If neither name nor model_version specified.
|
444
|
+
ValueError: If monitoring is not enabled in the Registry.
|
451
445
|
"""
|
452
446
|
if not self.enable_monitoring:
|
453
|
-
raise ValueError(
|
454
|
-
"Must enable monitoring in Registry to use this method. Please set the `enable_monitoring=True` option"
|
455
|
-
)
|
447
|
+
raise ValueError(_MODEL_MONITORING_DISABLED_ERROR)
|
456
448
|
if name is not None:
|
457
449
|
return self._model_monitor_manager.get_monitor(name=name)
|
458
450
|
elif model_version is not None:
|
459
|
-
return self._model_monitor_manager.get_monitor_by_model_version(model_version
|
451
|
+
return self._model_monitor_manager.get_monitor_by_model_version(model_version)
|
460
452
|
else:
|
461
453
|
raise ValueError("Must provide either `name` or `model_version` to get ModelMonitor")
|
462
454
|
|
@@ -472,12 +464,10 @@ class Registry:
|
|
472
464
|
List of snowpark.Row containing metadata for each model monitor.
|
473
465
|
|
474
466
|
Raises:
|
475
|
-
ValueError: If monitoring
|
467
|
+
ValueError: If monitoring is not enabled in the Registry.
|
476
468
|
"""
|
477
469
|
if not self.enable_monitoring:
|
478
|
-
raise ValueError(
|
479
|
-
"Must enable monitoring in Registry to use this method. Please set the `enable_monitoring=True` option"
|
480
|
-
)
|
470
|
+
raise ValueError(_MODEL_MONITORING_DISABLED_ERROR)
|
481
471
|
return self._model_monitor_manager.show_model_monitors()
|
482
472
|
|
483
473
|
@telemetry.send_api_usage_telemetry(
|
@@ -486,16 +476,14 @@ class Registry:
|
|
486
476
|
)
|
487
477
|
@snowpark._internal.utils.private_preview(version=model_monitor_version.SNOWFLAKE_ML_MONITORING_MIN_VERSION)
|
488
478
|
def delete_monitor(self, name: str) -> None:
|
489
|
-
"""Delete a Model Monitor from the Registry
|
479
|
+
"""Delete a Model Monitor by name from the Registry.
|
490
480
|
|
491
481
|
Args:
|
492
482
|
name: Name of the Model Monitor to delete.
|
493
483
|
|
494
484
|
Raises:
|
495
|
-
ValueError: If monitoring
|
485
|
+
ValueError: If monitoring is not enabled in the registry.
|
496
486
|
"""
|
497
487
|
if not self.enable_monitoring:
|
498
|
-
raise ValueError(
|
499
|
-
"Must enable monitoring in Registry to use this method. Please set the `enable_monitoring=True` option"
|
500
|
-
)
|
488
|
+
raise ValueError(_MODEL_MONITORING_DISABLED_ERROR)
|
501
489
|
self._model_monitor_manager.delete_monitor(name)
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import http
|
2
|
+
import logging
|
3
|
+
from datetime import timedelta
|
4
|
+
from typing import Dict, Optional
|
5
|
+
|
6
|
+
import requests
|
7
|
+
from cryptography.hazmat.primitives.asymmetric import types
|
8
|
+
from requests import auth
|
9
|
+
|
10
|
+
from snowflake.ml._internal.utils import jwt_generator
|
11
|
+
|
12
|
+
logger = logging.getLogger(__name__)
|
13
|
+
_JWT_TOKEN_CACHE: Dict[str, Dict[int, str]] = {}
|
14
|
+
|
15
|
+
|
16
|
+
def get_jwt_token_generator(
|
17
|
+
account: str,
|
18
|
+
user: str,
|
19
|
+
private_key: types.PRIVATE_KEY_TYPES,
|
20
|
+
lifetime: Optional[timedelta] = None,
|
21
|
+
renewal_delay: Optional[timedelta] = None,
|
22
|
+
) -> jwt_generator.JWTGenerator:
|
23
|
+
return jwt_generator.JWTGenerator(account, user, private_key, lifetime=lifetime, renewal_delay=renewal_delay)
|
24
|
+
|
25
|
+
|
26
|
+
def _get_snowflake_token_by_jwt(
|
27
|
+
jwt_token_generator: jwt_generator.JWTGenerator,
|
28
|
+
account: Optional[str] = None,
|
29
|
+
role: Optional[str] = None,
|
30
|
+
endpoint: Optional[str] = None,
|
31
|
+
snowflake_account_url: Optional[str] = None,
|
32
|
+
) -> str:
|
33
|
+
scope_role = f"session:role:{role}" if role is not None else None
|
34
|
+
scope = " ".join(filter(None, [scope_role, endpoint]))
|
35
|
+
data = {
|
36
|
+
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
37
|
+
"scope": scope or None,
|
38
|
+
"assertion": jwt_token_generator.get_token(),
|
39
|
+
}
|
40
|
+
account = account or jwt_token_generator.account
|
41
|
+
url = f"https://{account}.snowflakecomputing.com/oauth/token"
|
42
|
+
if snowflake_account_url:
|
43
|
+
url = f"{snowflake_account_url}/oauth/token"
|
44
|
+
|
45
|
+
cache_key = hash(frozenset(data.items()))
|
46
|
+
if url in _JWT_TOKEN_CACHE:
|
47
|
+
if cache_key in _JWT_TOKEN_CACHE[url]:
|
48
|
+
return _JWT_TOKEN_CACHE[url][cache_key]
|
49
|
+
else:
|
50
|
+
_JWT_TOKEN_CACHE[url] = {}
|
51
|
+
|
52
|
+
response = requests.post(url, data=data)
|
53
|
+
if response.status_code != http.HTTPStatus.OK:
|
54
|
+
raise RuntimeError(f"Failed to get snowflake token: {response.status_code} {response.content!r}")
|
55
|
+
auth_token = response.text
|
56
|
+
_JWT_TOKEN_CACHE[url][cache_key] = auth_token
|
57
|
+
return auth_token
|
58
|
+
|
59
|
+
|
60
|
+
class SnowflakeJWTTokenAuth(auth.AuthBase):
|
61
|
+
def __init__(
|
62
|
+
self,
|
63
|
+
jwt_token_generator: jwt_generator.JWTGenerator,
|
64
|
+
account: Optional[str] = None,
|
65
|
+
role: Optional[str] = None,
|
66
|
+
endpoint: Optional[str] = None,
|
67
|
+
snowflake_account_url: Optional[str] = None,
|
68
|
+
) -> None:
|
69
|
+
self.snowflake_token = _get_snowflake_token_by_jwt(
|
70
|
+
jwt_token_generator, account, role, endpoint, snowflake_account_url
|
71
|
+
)
|
72
|
+
|
73
|
+
def __call__(self, r: requests.PreparedRequest) -> requests.PreparedRequest:
|
74
|
+
r.headers["Authorization"] = f'Snowflake Token="{self.snowflake_token}"'
|
75
|
+
return r
|
snowflake/ml/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
VERSION="1.7.
|
1
|
+
VERSION="1.7.2"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: snowflake-ml-python
|
3
|
-
Version: 1.7.
|
3
|
+
Version: 1.7.2
|
4
4
|
Summary: The machine learning client library that is used for interacting with Snowflake to build machine learning solutions.
|
5
5
|
Author-email: "Snowflake, Inc" <support@snowflake.com>
|
6
6
|
License:
|
@@ -232,60 +232,62 @@ Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
232
232
|
Requires-Python: <3.12,>=3.9
|
233
233
|
Description-Content-Type: text/markdown
|
234
234
|
License-File: LICENSE.txt
|
235
|
-
Requires-Dist: absl-py
|
236
|
-
Requires-Dist: anyio
|
237
|
-
Requires-Dist: cachetools
|
238
|
-
Requires-Dist: cloudpickle
|
239
|
-
Requires-Dist:
|
240
|
-
Requires-Dist:
|
241
|
-
Requires-Dist:
|
242
|
-
Requires-Dist:
|
243
|
-
Requires-Dist:
|
235
|
+
Requires-Dist: absl-py<2,>=0.15
|
236
|
+
Requires-Dist: anyio<4,>=3.5.0
|
237
|
+
Requires-Dist: cachetools<6,>=3.1.1
|
238
|
+
Requires-Dist: cloudpickle>=2.0.0
|
239
|
+
Requires-Dist: cryptography
|
240
|
+
Requires-Dist: fsspec[http]<2024,>=2022.11
|
241
|
+
Requires-Dist: importlib_resources<7,>=6.1.1
|
242
|
+
Requires-Dist: numpy<2,>=1.23
|
243
|
+
Requires-Dist: packaging<25,>=20.9
|
244
|
+
Requires-Dist: pandas<3,>=1.0.0
|
244
245
|
Requires-Dist: pyarrow
|
245
|
-
Requires-Dist:
|
246
|
-
Requires-Dist:
|
247
|
-
Requires-Dist:
|
248
|
-
Requires-Dist:
|
249
|
-
Requires-Dist:
|
250
|
-
Requires-Dist:
|
251
|
-
Requires-Dist:
|
252
|
-
Requires-Dist: snowflake-
|
253
|
-
Requires-Dist:
|
254
|
-
Requires-Dist:
|
255
|
-
Requires-Dist:
|
246
|
+
Requires-Dist: pyjwt<3,>=2.0.0
|
247
|
+
Requires-Dist: pytimeparse<2,>=1.1.8
|
248
|
+
Requires-Dist: pyyaml<7,>=6.0
|
249
|
+
Requires-Dist: retrying<2,>=1.3.3
|
250
|
+
Requires-Dist: s3fs<2024,>=2022.11
|
251
|
+
Requires-Dist: scikit-learn<1.6,>=1.4
|
252
|
+
Requires-Dist: scipy<2,>=1.9
|
253
|
+
Requires-Dist: snowflake-connector-python[pandas]<4,>=3.5.0
|
254
|
+
Requires-Dist: snowflake-snowpark-python<2,>=1.17.0
|
255
|
+
Requires-Dist: sqlparse<1,>=0.4
|
256
|
+
Requires-Dist: typing-extensions<5,>=4.1.0
|
257
|
+
Requires-Dist: xgboost<3,>=1.7.3
|
256
258
|
Provides-Extra: all
|
257
|
-
Requires-Dist: catboost
|
258
|
-
Requires-Dist: lightgbm
|
259
|
-
Requires-Dist: mlflow
|
260
|
-
Requires-Dist: peft
|
261
|
-
Requires-Dist: sentence-transformers
|
262
|
-
Requires-Dist: sentencepiece
|
263
|
-
Requires-Dist: shap
|
264
|
-
Requires-Dist: tensorflow
|
265
|
-
Requires-Dist: tokenizers
|
266
|
-
Requires-Dist: torch
|
267
|
-
Requires-Dist: torchdata
|
268
|
-
Requires-Dist: transformers
|
259
|
+
Requires-Dist: catboost<2,>=1.2.0; extra == "all"
|
260
|
+
Requires-Dist: lightgbm<5,>=4.1.0; extra == "all"
|
261
|
+
Requires-Dist: mlflow<2.4,>=2.1.0; extra == "all"
|
262
|
+
Requires-Dist: peft<1,>=0.5.0; extra == "all"
|
263
|
+
Requires-Dist: sentence-transformers<3,>=2.2.2; extra == "all"
|
264
|
+
Requires-Dist: sentencepiece<1,>=0.1.95; extra == "all"
|
265
|
+
Requires-Dist: shap<1,>=0.46.0; extra == "all"
|
266
|
+
Requires-Dist: tensorflow<3,>=2.10; extra == "all"
|
267
|
+
Requires-Dist: tokenizers<1,>=0.10; extra == "all"
|
268
|
+
Requires-Dist: torch<2.3.0,>=2.0.1; extra == "all"
|
269
|
+
Requires-Dist: torchdata<1,>=0.4; extra == "all"
|
270
|
+
Requires-Dist: transformers<5,>=4.32.1; extra == "all"
|
269
271
|
Provides-Extra: catboost
|
270
|
-
Requires-Dist: catboost
|
272
|
+
Requires-Dist: catboost<2,>=1.2.0; extra == "catboost"
|
271
273
|
Provides-Extra: lightgbm
|
272
|
-
Requires-Dist: lightgbm
|
274
|
+
Requires-Dist: lightgbm<5,>=4.1.0; extra == "lightgbm"
|
273
275
|
Provides-Extra: llm
|
274
|
-
Requires-Dist: peft
|
276
|
+
Requires-Dist: peft<1,>=0.5.0; extra == "llm"
|
275
277
|
Provides-Extra: mlflow
|
276
|
-
Requires-Dist: mlflow
|
278
|
+
Requires-Dist: mlflow<2.4,>=2.1.0; extra == "mlflow"
|
277
279
|
Provides-Extra: shap
|
278
|
-
Requires-Dist: shap
|
280
|
+
Requires-Dist: shap<1,>=0.46.0; extra == "shap"
|
279
281
|
Provides-Extra: tensorflow
|
280
|
-
Requires-Dist: tensorflow
|
282
|
+
Requires-Dist: tensorflow<3,>=2.10; extra == "tensorflow"
|
281
283
|
Provides-Extra: torch
|
282
|
-
Requires-Dist: torch
|
283
|
-
Requires-Dist: torchdata
|
284
|
+
Requires-Dist: torch<2.3.0,>=2.0.1; extra == "torch"
|
285
|
+
Requires-Dist: torchdata<1,>=0.4; extra == "torch"
|
284
286
|
Provides-Extra: transformers
|
285
|
-
Requires-Dist: sentence-transformers
|
286
|
-
Requires-Dist: sentencepiece
|
287
|
-
Requires-Dist: tokenizers
|
288
|
-
Requires-Dist: transformers
|
287
|
+
Requires-Dist: sentence-transformers<3,>=2.2.2; extra == "transformers"
|
288
|
+
Requires-Dist: sentencepiece<1,>=0.1.95; extra == "transformers"
|
289
|
+
Requires-Dist: tokenizers<1,>=0.10; extra == "transformers"
|
290
|
+
Requires-Dist: transformers<5,>=4.32.1; extra == "transformers"
|
289
291
|
|
290
292
|
# Snowpark ML
|
291
293
|
|
@@ -301,7 +303,7 @@ and deployment process, and includes two key components.
|
|
301
303
|
|
302
304
|
### Snowpark ML Development
|
303
305
|
|
304
|
-
[Snowpark ML Development](https://docs.snowflake.com/en/developer-guide/snowpark-ml/index#
|
306
|
+
[Snowpark ML Development](https://docs.snowflake.com/en/developer-guide/snowpark-ml/index#ml-modeling)
|
305
307
|
provides a collection of python APIs enabling efficient ML model development directly in Snowflake:
|
306
308
|
|
307
309
|
1. Modeling API (`snowflake.ml.modeling`) for data preprocessing, feature engineering and model training in Snowflake.
|
@@ -315,14 +317,21 @@ their native data loader formats.
|
|
315
317
|
1. FileSet API: FileSet provides a Python fsspec-compliant API for materializing data into a Snowflake internal stage
|
316
318
|
from a query or Snowpark Dataframe along with a number of convenience APIs.
|
317
319
|
|
318
|
-
###
|
320
|
+
### Snowflake MLOps
|
319
321
|
|
320
|
-
|
321
|
-
the Snowpark ML Development API, and provides
|
322
|
+
Snowflake MLOps contains suit of tools and objects to make ML development cycle. It complements
|
323
|
+
the Snowpark ML Development API, and provides end to end development to deployment within Snowflake.
|
322
324
|
Currently, the API consists of:
|
323
325
|
|
324
|
-
1. Registry: A python API
|
325
|
-
|
326
|
+
1. [Registry](https://docs.snowflake.com/en/developer-guide/snowpark-ml/index#snowflake-model-registry): A python API
|
327
|
+
allows secure deployment and management of models in Snowflake, supporting models trained both inside and outside of
|
328
|
+
Snowflake.
|
329
|
+
2. [Feature Store](https://docs.snowflake.com/en/developer-guide/snowpark-ml/index#snowflake-feature-store): A fully
|
330
|
+
integrated solution for defining, managing, storing and discovering ML features derived from your data. The
|
331
|
+
Snowflake Feature Store supports automated, incremental refresh from batch and streaming data sources, so that
|
332
|
+
feature pipelines need be defined only once to be continuously updated with new data.
|
333
|
+
3. [Datasets](https://docs.snowflake.com/developer-guide/snowflake-ml/overview#snowflake-datasets): Dataset provide an
|
334
|
+
immutable, versioned snapshot of your data suitable for ingestion by your machine learning models.
|
326
335
|
|
327
336
|
## Getting started
|
328
337
|
|
@@ -370,9 +379,64 @@ conda install \
|
|
370
379
|
Note that until a `snowflake-ml-python` package version is available in the official Snowflake conda channel, there may
|
371
380
|
be compatibility issues. Server-side functionality that `snowflake-ml-python` depends on may not yet be released.
|
372
381
|
|
382
|
+
### Verifying the package
|
383
|
+
|
384
|
+
1. Install cosign.
|
385
|
+
This example is using golang installation: [installing-cosign-with-go](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-go).
|
386
|
+
1. Download the file from the repository like [pypi](https://pypi.org/project/snowflake-ml-python/#files).
|
387
|
+
1. Download the signature files from the [release tag](https://github.com/snowflakedb/snowflake-ml-python/releases/tag/1.7.0).
|
388
|
+
1. Verify signature on projects signed using Jenkins job:
|
389
|
+
|
390
|
+
```sh
|
391
|
+
cosign verify-blob snowflake_ml_python-1.7.0.tar.gz --key snowflake-ml-python-1.7.0.pub --signature resources.linux.snowflake_ml_python-1.7.0.tar.gz.sig
|
392
|
+
|
393
|
+
cosign verify-blob snowflake_ml_python-1.7.0.tar.gz --key snowflake-ml-python-1.7.0.pub --signature resources.linux.snowflake_ml_python-1.7.0
|
394
|
+
```
|
395
|
+
|
396
|
+
NOTE: Version 1.7.0 is used as example here. Please choose the the latest version.
|
397
|
+
|
373
398
|
# Release History
|
374
399
|
|
375
|
-
## 1.7.
|
400
|
+
## 1.7.2
|
401
|
+
|
402
|
+
### Bug Fixes
|
403
|
+
|
404
|
+
- Model Explainability: Fix issue that explain is enabled for scikit-learn pipeline
|
405
|
+
whose task is UNKNOWN and fails later when invoked.
|
406
|
+
|
407
|
+
### Behavior Changes
|
408
|
+
|
409
|
+
### New Features
|
410
|
+
|
411
|
+
- Registry: Support asynchronous model inference service creation with the `block` option
|
412
|
+
in `ModelVersion.create_service()` set to True by default.
|
413
|
+
|
414
|
+
## 1.7.1 (2024-11-05)
|
415
|
+
|
416
|
+
### Bug Fixes
|
417
|
+
|
418
|
+
- Registry: Null value is now allowed in the dataframe used in model signature inference. Null values will be ignored
|
419
|
+
and others will be used to infer the signature.
|
420
|
+
- Registry: Pandas Extension DTypes (`pandas.StringDType()`, `pandas.BooleanDType()`, etc.) are now supported in model
|
421
|
+
signature inference.
|
422
|
+
- Registry: Null value is now allowed in the dataframe used to predict.
|
423
|
+
- Data: Fix missing `snowflake.ml.data.*` module exports in wheel
|
424
|
+
- Dataset: Fix missing `snowflake.ml.dataset.*` module exports in wheel.
|
425
|
+
- Registry: Fix the issue that `tf_keras.Model` is not recognized as keras model when logging.
|
426
|
+
|
427
|
+
### Behavior Changes
|
428
|
+
|
429
|
+
### New Features
|
430
|
+
|
431
|
+
- Registry: Option to `enable_monitoring` set to False by default. This will gate access to preview features of Model Monitoring.
|
432
|
+
- Model Monitoring: `show_model_monitors` Registry method. This feature is still in Private Preview.
|
433
|
+
- Registry: Support `pd.Series` in input and output data.
|
434
|
+
- Model Monitoring: `add_monitor` Registry method. This feature is still in Private Preview.
|
435
|
+
- Model Monitoring: `resume` and `suspend` ModelMonitor. This feature is still in Private Preview.
|
436
|
+
- Model Monitoring: `get_monitor` Registry method. This feature is still in Private Preview.
|
437
|
+
- Model Monitoring: `delete_monitor` Registry method. This feature is still in Private Preview.
|
438
|
+
|
439
|
+
## 1.7.0 (10-22-2024)
|
376
440
|
|
377
441
|
### Behavior Change
|
378
442
|
|