snowflake-ml-python 1.6.1__py3-none-any.whl → 1.6.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.
- snowflake/cortex/__init__.py +4 -0
- snowflake/cortex/_classify_text.py +2 -2
- snowflake/cortex/_embed_text_1024.py +37 -0
- snowflake/cortex/_embed_text_768.py +37 -0
- snowflake/cortex/_extract_answer.py +2 -2
- snowflake/cortex/_sentiment.py +2 -2
- snowflake/cortex/_summarize.py +2 -2
- snowflake/cortex/_translate.py +2 -2
- snowflake/cortex/_util.py +4 -4
- snowflake/ml/_internal/env_utils.py +5 -5
- snowflake/ml/_internal/exceptions/error_codes.py +2 -0
- snowflake/ml/_internal/telemetry.py +142 -20
- snowflake/ml/_internal/utils/db_utils.py +50 -0
- snowflake/ml/_internal/utils/identifier.py +48 -11
- snowflake/ml/_internal/utils/service_logger.py +63 -0
- snowflake/ml/_internal/utils/snowflake_env.py +23 -13
- snowflake/ml/_internal/utils/sql_identifier.py +26 -2
- snowflake/ml/_internal/utils/table_manager.py +19 -1
- snowflake/ml/data/_internal/arrow_ingestor.py +1 -11
- snowflake/ml/data/data_connector.py +33 -7
- snowflake/ml/data/ingestor_utils.py +20 -10
- snowflake/ml/data/torch_utils.py +68 -0
- snowflake/ml/dataset/dataset.py +1 -3
- snowflake/ml/feature_store/access_manager.py +3 -3
- snowflake/ml/feature_store/feature_store.py +60 -19
- snowflake/ml/feature_store/feature_view.py +84 -30
- snowflake/ml/fileset/embedded_stage_fs.py +1 -1
- snowflake/ml/fileset/fileset.py +1 -1
- snowflake/ml/fileset/sfcfs.py +9 -3
- snowflake/ml/fileset/stage_fs.py +2 -1
- snowflake/ml/lineage/lineage_node.py +7 -2
- snowflake/ml/model/__init__.py +1 -2
- snowflake/ml/model/_client/model/model_version_impl.py +96 -12
- snowflake/ml/model/_client/ops/model_ops.py +124 -6
- snowflake/ml/model/_client/ops/service_ops.py +309 -9
- snowflake/ml/model/_client/service/model_deployment_spec.py +8 -5
- snowflake/ml/model/_client/service/model_deployment_spec_schema.py +2 -2
- snowflake/ml/model/_client/sql/_base.py +5 -0
- snowflake/ml/model/_client/sql/model.py +1 -0
- snowflake/ml/model/_client/sql/model_version.py +9 -5
- snowflake/ml/model/_client/sql/service.py +121 -20
- snowflake/ml/model/_model_composer/model_composer.py +11 -39
- snowflake/ml/model/_model_composer/model_manifest/model_manifest.py +31 -11
- snowflake/ml/model/_packager/model_env/model_env.py +4 -38
- snowflake/ml/model/_packager/model_handlers/_utils.py +134 -28
- snowflake/ml/model/_packager/model_handlers/catboost.py +31 -30
- snowflake/ml/model/_packager/model_handlers/huggingface_pipeline.py +26 -18
- snowflake/ml/model/_packager/model_handlers/lightgbm.py +31 -58
- snowflake/ml/model/_packager/model_handlers/mlflow.py +3 -5
- snowflake/ml/model/_packager/model_handlers/model_objective_utils.py +169 -0
- snowflake/ml/model/_packager/model_handlers/sentence_transformers.py +15 -8
- snowflake/ml/model/_packager/model_handlers/sklearn.py +56 -60
- snowflake/ml/model/_packager/model_handlers/snowmlmodel.py +141 -9
- snowflake/ml/model/_packager/model_handlers/torchscript.py +2 -2
- snowflake/ml/model/_packager/model_handlers/xgboost.py +63 -48
- snowflake/ml/model/_packager/model_meta/model_meta.py +16 -42
- snowflake/ml/model/_packager/model_meta/model_meta_schema.py +1 -14
- snowflake/ml/model/_packager/model_packager.py +14 -8
- snowflake/ml/model/_packager/model_runtime/model_runtime.py +11 -0
- snowflake/ml/model/_signatures/pytorch_handler.py +1 -1
- snowflake/ml/model/_signatures/snowpark_handler.py +3 -2
- snowflake/ml/model/_signatures/utils.py +9 -0
- snowflake/ml/model/type_hints.py +12 -145
- snowflake/ml/modeling/_internal/constants.py +1 -0
- snowflake/ml/modeling/_internal/local_implementations/pandas_handlers.py +5 -5
- snowflake/ml/modeling/_internal/local_implementations/pandas_trainer.py +9 -6
- snowflake/ml/modeling/_internal/model_specifications.py +2 -0
- snowflake/ml/modeling/_internal/model_trainer.py +1 -0
- snowflake/ml/modeling/_internal/snowpark_implementations/distributed_hpo_trainer.py +2 -4
- snowflake/ml/modeling/_internal/snowpark_implementations/snowpark_handlers.py +5 -5
- snowflake/ml/modeling/_internal/snowpark_implementations/snowpark_trainer.py +130 -166
- snowflake/ml/modeling/_internal/snowpark_implementations/xgboost_external_memory_trainer.py +0 -1
- snowflake/ml/modeling/calibration/calibrated_classifier_cv.py +61 -21
- snowflake/ml/modeling/cluster/affinity_propagation.py +61 -21
- snowflake/ml/modeling/cluster/agglomerative_clustering.py +61 -21
- snowflake/ml/modeling/cluster/birch.py +61 -21
- snowflake/ml/modeling/cluster/bisecting_k_means.py +61 -21
- snowflake/ml/modeling/cluster/dbscan.py +61 -21
- snowflake/ml/modeling/cluster/feature_agglomeration.py +61 -21
- snowflake/ml/modeling/cluster/k_means.py +61 -21
- snowflake/ml/modeling/cluster/mean_shift.py +61 -21
- snowflake/ml/modeling/cluster/mini_batch_k_means.py +61 -21
- snowflake/ml/modeling/cluster/optics.py +61 -21
- snowflake/ml/modeling/cluster/spectral_biclustering.py +61 -21
- snowflake/ml/modeling/cluster/spectral_clustering.py +61 -21
- snowflake/ml/modeling/cluster/spectral_coclustering.py +61 -21
- snowflake/ml/modeling/compose/column_transformer.py +61 -21
- snowflake/ml/modeling/compose/transformed_target_regressor.py +61 -21
- snowflake/ml/modeling/covariance/elliptic_envelope.py +61 -21
- snowflake/ml/modeling/covariance/empirical_covariance.py +61 -21
- snowflake/ml/modeling/covariance/graphical_lasso.py +61 -21
- snowflake/ml/modeling/covariance/graphical_lasso_cv.py +61 -21
- snowflake/ml/modeling/covariance/ledoit_wolf.py +61 -21
- snowflake/ml/modeling/covariance/min_cov_det.py +61 -21
- snowflake/ml/modeling/covariance/oas.py +61 -21
- snowflake/ml/modeling/covariance/shrunk_covariance.py +61 -21
- snowflake/ml/modeling/decomposition/dictionary_learning.py +61 -21
- snowflake/ml/modeling/decomposition/factor_analysis.py +61 -21
- snowflake/ml/modeling/decomposition/fast_ica.py +61 -21
- snowflake/ml/modeling/decomposition/incremental_pca.py +61 -21
- snowflake/ml/modeling/decomposition/kernel_pca.py +61 -21
- snowflake/ml/modeling/decomposition/mini_batch_dictionary_learning.py +61 -21
- snowflake/ml/modeling/decomposition/mini_batch_sparse_pca.py +61 -21
- snowflake/ml/modeling/decomposition/pca.py +61 -21
- snowflake/ml/modeling/decomposition/sparse_pca.py +61 -21
- snowflake/ml/modeling/decomposition/truncated_svd.py +61 -21
- snowflake/ml/modeling/discriminant_analysis/linear_discriminant_analysis.py +61 -21
- snowflake/ml/modeling/discriminant_analysis/quadratic_discriminant_analysis.py +61 -21
- snowflake/ml/modeling/ensemble/ada_boost_classifier.py +61 -21
- snowflake/ml/modeling/ensemble/ada_boost_regressor.py +61 -21
- snowflake/ml/modeling/ensemble/bagging_classifier.py +61 -21
- snowflake/ml/modeling/ensemble/bagging_regressor.py +61 -21
- snowflake/ml/modeling/ensemble/extra_trees_classifier.py +61 -21
- snowflake/ml/modeling/ensemble/extra_trees_regressor.py +61 -21
- snowflake/ml/modeling/ensemble/gradient_boosting_classifier.py +61 -21
- snowflake/ml/modeling/ensemble/gradient_boosting_regressor.py +61 -21
- snowflake/ml/modeling/ensemble/hist_gradient_boosting_classifier.py +61 -21
- snowflake/ml/modeling/ensemble/hist_gradient_boosting_regressor.py +61 -21
- snowflake/ml/modeling/ensemble/isolation_forest.py +61 -21
- snowflake/ml/modeling/ensemble/random_forest_classifier.py +61 -21
- snowflake/ml/modeling/ensemble/random_forest_regressor.py +61 -21
- snowflake/ml/modeling/ensemble/stacking_regressor.py +61 -21
- snowflake/ml/modeling/ensemble/voting_classifier.py +61 -21
- snowflake/ml/modeling/ensemble/voting_regressor.py +61 -21
- snowflake/ml/modeling/feature_selection/generic_univariate_select.py +61 -21
- snowflake/ml/modeling/feature_selection/select_fdr.py +61 -21
- snowflake/ml/modeling/feature_selection/select_fpr.py +61 -21
- snowflake/ml/modeling/feature_selection/select_fwe.py +61 -21
- snowflake/ml/modeling/feature_selection/select_k_best.py +61 -21
- snowflake/ml/modeling/feature_selection/select_percentile.py +61 -21
- snowflake/ml/modeling/feature_selection/sequential_feature_selector.py +61 -21
- snowflake/ml/modeling/feature_selection/variance_threshold.py +61 -21
- snowflake/ml/modeling/gaussian_process/gaussian_process_classifier.py +61 -21
- snowflake/ml/modeling/gaussian_process/gaussian_process_regressor.py +61 -21
- snowflake/ml/modeling/impute/iterative_imputer.py +61 -21
- snowflake/ml/modeling/impute/knn_imputer.py +61 -21
- snowflake/ml/modeling/impute/missing_indicator.py +61 -21
- snowflake/ml/modeling/kernel_approximation/additive_chi2_sampler.py +61 -21
- snowflake/ml/modeling/kernel_approximation/nystroem.py +61 -21
- snowflake/ml/modeling/kernel_approximation/polynomial_count_sketch.py +61 -21
- snowflake/ml/modeling/kernel_approximation/rbf_sampler.py +61 -21
- snowflake/ml/modeling/kernel_approximation/skewed_chi2_sampler.py +61 -21
- snowflake/ml/modeling/kernel_ridge/kernel_ridge.py +61 -21
- snowflake/ml/modeling/lightgbm/lgbm_classifier.py +61 -21
- snowflake/ml/modeling/lightgbm/lgbm_regressor.py +61 -21
- snowflake/ml/modeling/linear_model/ard_regression.py +61 -21
- snowflake/ml/modeling/linear_model/bayesian_ridge.py +61 -21
- snowflake/ml/modeling/linear_model/elastic_net.py +61 -21
- snowflake/ml/modeling/linear_model/elastic_net_cv.py +61 -21
- snowflake/ml/modeling/linear_model/gamma_regressor.py +61 -21
- snowflake/ml/modeling/linear_model/huber_regressor.py +61 -21
- snowflake/ml/modeling/linear_model/lars.py +61 -21
- snowflake/ml/modeling/linear_model/lars_cv.py +61 -21
- snowflake/ml/modeling/linear_model/lasso.py +61 -21
- snowflake/ml/modeling/linear_model/lasso_cv.py +61 -21
- snowflake/ml/modeling/linear_model/lasso_lars.py +61 -21
- snowflake/ml/modeling/linear_model/lasso_lars_cv.py +61 -21
- snowflake/ml/modeling/linear_model/lasso_lars_ic.py +61 -21
- snowflake/ml/modeling/linear_model/linear_regression.py +61 -21
- snowflake/ml/modeling/linear_model/logistic_regression.py +61 -21
- snowflake/ml/modeling/linear_model/logistic_regression_cv.py +61 -21
- snowflake/ml/modeling/linear_model/multi_task_elastic_net.py +61 -21
- snowflake/ml/modeling/linear_model/multi_task_elastic_net_cv.py +61 -21
- snowflake/ml/modeling/linear_model/multi_task_lasso.py +61 -21
- snowflake/ml/modeling/linear_model/multi_task_lasso_cv.py +61 -21
- snowflake/ml/modeling/linear_model/orthogonal_matching_pursuit.py +61 -21
- snowflake/ml/modeling/linear_model/passive_aggressive_classifier.py +61 -21
- snowflake/ml/modeling/linear_model/passive_aggressive_regressor.py +61 -21
- snowflake/ml/modeling/linear_model/perceptron.py +61 -21
- snowflake/ml/modeling/linear_model/poisson_regressor.py +61 -21
- snowflake/ml/modeling/linear_model/ransac_regressor.py +61 -21
- snowflake/ml/modeling/linear_model/ridge.py +61 -21
- snowflake/ml/modeling/linear_model/ridge_classifier.py +61 -21
- snowflake/ml/modeling/linear_model/ridge_classifier_cv.py +61 -21
- snowflake/ml/modeling/linear_model/ridge_cv.py +61 -21
- snowflake/ml/modeling/linear_model/sgd_classifier.py +61 -21
- snowflake/ml/modeling/linear_model/sgd_one_class_svm.py +61 -21
- snowflake/ml/modeling/linear_model/sgd_regressor.py +61 -21
- snowflake/ml/modeling/linear_model/theil_sen_regressor.py +61 -21
- snowflake/ml/modeling/linear_model/tweedie_regressor.py +61 -21
- snowflake/ml/modeling/manifold/isomap.py +61 -21
- snowflake/ml/modeling/manifold/mds.py +61 -21
- snowflake/ml/modeling/manifold/spectral_embedding.py +61 -21
- snowflake/ml/modeling/manifold/tsne.py +61 -21
- snowflake/ml/modeling/metrics/metrics_utils.py +2 -2
- snowflake/ml/modeling/metrics/ranking.py +0 -3
- snowflake/ml/modeling/metrics/regression.py +0 -3
- snowflake/ml/modeling/mixture/bayesian_gaussian_mixture.py +61 -21
- snowflake/ml/modeling/mixture/gaussian_mixture.py +61 -21
- snowflake/ml/modeling/multiclass/one_vs_one_classifier.py +61 -21
- snowflake/ml/modeling/multiclass/one_vs_rest_classifier.py +61 -21
- snowflake/ml/modeling/multiclass/output_code_classifier.py +61 -21
- snowflake/ml/modeling/naive_bayes/bernoulli_nb.py +61 -21
- snowflake/ml/modeling/naive_bayes/categorical_nb.py +61 -21
- snowflake/ml/modeling/naive_bayes/complement_nb.py +61 -21
- snowflake/ml/modeling/naive_bayes/gaussian_nb.py +61 -21
- snowflake/ml/modeling/naive_bayes/multinomial_nb.py +61 -21
- snowflake/ml/modeling/neighbors/k_neighbors_classifier.py +61 -21
- snowflake/ml/modeling/neighbors/k_neighbors_regressor.py +61 -21
- snowflake/ml/modeling/neighbors/kernel_density.py +61 -21
- snowflake/ml/modeling/neighbors/local_outlier_factor.py +61 -21
- snowflake/ml/modeling/neighbors/nearest_centroid.py +61 -21
- snowflake/ml/modeling/neighbors/nearest_neighbors.py +61 -21
- snowflake/ml/modeling/neighbors/neighborhood_components_analysis.py +61 -21
- snowflake/ml/modeling/neighbors/radius_neighbors_classifier.py +61 -21
- snowflake/ml/modeling/neighbors/radius_neighbors_regressor.py +61 -21
- snowflake/ml/modeling/neural_network/bernoulli_rbm.py +61 -21
- snowflake/ml/modeling/neural_network/mlp_classifier.py +61 -21
- snowflake/ml/modeling/neural_network/mlp_regressor.py +61 -21
- snowflake/ml/modeling/parameters/disable_model_tracer.py +5 -0
- snowflake/ml/modeling/pipeline/pipeline.py +1 -13
- snowflake/ml/modeling/preprocessing/polynomial_features.py +61 -21
- snowflake/ml/modeling/semi_supervised/label_propagation.py +61 -21
- snowflake/ml/modeling/semi_supervised/label_spreading.py +61 -21
- snowflake/ml/modeling/svm/linear_svc.py +61 -21
- snowflake/ml/modeling/svm/linear_svr.py +61 -21
- snowflake/ml/modeling/svm/nu_svc.py +61 -21
- snowflake/ml/modeling/svm/nu_svr.py +61 -21
- snowflake/ml/modeling/svm/svc.py +61 -21
- snowflake/ml/modeling/svm/svr.py +61 -21
- snowflake/ml/modeling/tree/decision_tree_classifier.py +61 -21
- snowflake/ml/modeling/tree/decision_tree_regressor.py +61 -21
- snowflake/ml/modeling/tree/extra_tree_classifier.py +61 -21
- snowflake/ml/modeling/tree/extra_tree_regressor.py +61 -21
- snowflake/ml/modeling/xgboost/xgb_classifier.py +64 -23
- snowflake/ml/modeling/xgboost/xgb_regressor.py +64 -23
- snowflake/ml/modeling/xgboost/xgbrf_classifier.py +64 -23
- snowflake/ml/modeling/xgboost/xgbrf_regressor.py +64 -23
- snowflake/ml/monitoring/_client/model_monitor.py +126 -0
- snowflake/ml/monitoring/_client/model_monitor_manager.py +361 -0
- snowflake/ml/monitoring/_client/model_monitor_version.py +1 -0
- snowflake/ml/monitoring/_client/monitor_sql_client.py +1335 -0
- snowflake/ml/monitoring/_client/queries/record_count.ssql +14 -0
- snowflake/ml/monitoring/_client/queries/rmse.ssql +28 -0
- snowflake/ml/monitoring/entities/model_monitor_config.py +28 -0
- snowflake/ml/monitoring/entities/model_monitor_interval.py +46 -0
- snowflake/ml/monitoring/entities/output_score_type.py +90 -0
- snowflake/ml/registry/_manager/model_manager.py +4 -0
- snowflake/ml/registry/registry.py +166 -8
- snowflake/ml/version.py +1 -1
- {snowflake_ml_python-1.6.1.dist-info → snowflake_ml_python-1.6.3.dist-info}/METADATA +43 -9
- snowflake_ml_python-1.6.3.dist-info/RECORD +400 -0
- {snowflake_ml_python-1.6.1.dist-info → snowflake_ml_python-1.6.3.dist-info}/WHEEL +1 -1
- snowflake/ml/_internal/container_services/image_registry/credential.py +0 -84
- snowflake/ml/_internal/container_services/image_registry/http_client.py +0 -127
- snowflake/ml/_internal/container_services/image_registry/imagelib.py +0 -400
- snowflake/ml/_internal/container_services/image_registry/registry_client.py +0 -212
- snowflake/ml/_internal/utils/log_stream_processor.py +0 -30
- snowflake/ml/_internal/utils/session_token_manager.py +0 -46
- snowflake/ml/_internal/utils/spcs_attribution_utils.py +0 -122
- snowflake/ml/_internal/utils/uri.py +0 -77
- snowflake/ml/data/torch_dataset.py +0 -33
- snowflake/ml/model/_api.py +0 -568
- snowflake/ml/model/_deploy_client/image_builds/base_image_builder.py +0 -12
- snowflake/ml/model/_deploy_client/image_builds/client_image_builder.py +0 -249
- snowflake/ml/model/_deploy_client/image_builds/docker_context.py +0 -130
- snowflake/ml/model/_deploy_client/image_builds/gunicorn_run.sh +0 -36
- snowflake/ml/model/_deploy_client/image_builds/inference_server/main.py +0 -268
- snowflake/ml/model/_deploy_client/image_builds/server_image_builder.py +0 -215
- snowflake/ml/model/_deploy_client/image_builds/templates/dockerfile_template +0 -53
- snowflake/ml/model/_deploy_client/image_builds/templates/image_build_job_spec_template +0 -38
- snowflake/ml/model/_deploy_client/image_builds/templates/kaniko_shell_script_template +0 -105
- snowflake/ml/model/_deploy_client/snowservice/deploy.py +0 -611
- snowflake/ml/model/_deploy_client/snowservice/deploy_options.py +0 -116
- snowflake/ml/model/_deploy_client/snowservice/instance_types.py +0 -10
- snowflake/ml/model/_deploy_client/snowservice/templates/service_spec_template +0 -28
- snowflake/ml/model/_deploy_client/snowservice/templates/service_spec_template_with_model +0 -21
- snowflake/ml/model/_deploy_client/utils/constants.py +0 -48
- snowflake/ml/model/_deploy_client/utils/snowservice_client.py +0 -280
- snowflake/ml/model/_deploy_client/warehouse/deploy.py +0 -202
- snowflake/ml/model/_deploy_client/warehouse/infer_template.py +0 -99
- snowflake/ml/model/_packager/model_handlers/llm.py +0 -267
- snowflake/ml/model/_packager/model_meta/_core_requirements.py +0 -11
- snowflake/ml/model/deploy_platforms.py +0 -6
- snowflake/ml/model/models/llm.py +0 -104
- snowflake/ml/monitoring/monitor.py +0 -203
- snowflake/ml/registry/_initial_schema.py +0 -142
- snowflake/ml/registry/_schema.py +0 -82
- snowflake/ml/registry/_schema_upgrade_plans.py +0 -116
- snowflake/ml/registry/_schema_version_manager.py +0 -163
- snowflake/ml/registry/model_registry.py +0 -2048
- snowflake_ml_python-1.6.1.dist-info/RECORD +0 -422
- {snowflake_ml_python-1.6.1.dist-info → snowflake_ml_python-1.6.3.dist-info}/LICENSE.txt +0 -0
- {snowflake_ml_python-1.6.1.dist-info → snowflake_ml_python-1.6.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,361 @@
|
|
1
|
+
from typing import Any, Dict, List, Optional
|
2
|
+
|
3
|
+
from snowflake import snowpark
|
4
|
+
from snowflake.ml._internal import telemetry
|
5
|
+
from snowflake.ml._internal.utils import db_utils, sql_identifier
|
6
|
+
from snowflake.ml.model import type_hints
|
7
|
+
from snowflake.ml.model._client.model import model_version_impl
|
8
|
+
from snowflake.ml.model._model_composer.model_manifest import model_manifest_schema
|
9
|
+
from snowflake.ml.monitoring._client import model_monitor, monitor_sql_client
|
10
|
+
from snowflake.ml.monitoring.entities import (
|
11
|
+
model_monitor_config,
|
12
|
+
model_monitor_interval,
|
13
|
+
)
|
14
|
+
from snowflake.snowpark import session
|
15
|
+
|
16
|
+
|
17
|
+
def _validate_name_constraints(model_version: model_version_impl.ModelVersion) -> None:
|
18
|
+
system_table_prefixes = [
|
19
|
+
monitor_sql_client._SNOWML_MONITORING_TABLE_NAME_PREFIX,
|
20
|
+
monitor_sql_client._SNOWML_MONITORING_ACCURACY_TABLE_NAME_PREFIX,
|
21
|
+
]
|
22
|
+
|
23
|
+
max_allowed_model_name_and_version_length = (
|
24
|
+
db_utils.MAX_IDENTIFIER_LENGTH - max(len(prefix) for prefix in system_table_prefixes) - 1
|
25
|
+
) # -1 includes '_' between model_name + model_version
|
26
|
+
if len(model_version.model_name) + len(model_version.version_name) > max_allowed_model_name_and_version_length:
|
27
|
+
error_msg = f"Model name and version name exceeds maximum length of {max_allowed_model_name_and_version_length}"
|
28
|
+
raise ValueError(error_msg)
|
29
|
+
|
30
|
+
|
31
|
+
class ModelMonitorManager:
|
32
|
+
"""Class to manage internal operations for Model Monitor workflows.""" # TODO: Move to Registry.
|
33
|
+
|
34
|
+
@staticmethod
|
35
|
+
def setup(session: session.Session, database_name: str, schema_name: str) -> None:
|
36
|
+
"""Static method to set up schema for Model Monitoring resources.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
session: The Snowpark Session to connect with Snowflake.
|
40
|
+
database_name: The name of the database. If None, the current database of the session
|
41
|
+
will be used. Defaults to None.
|
42
|
+
schema_name: The name of the schema. If None, the current schema of the session
|
43
|
+
will be used. If there is no active schema, the PUBLIC schema will be used. Defaults to None.
|
44
|
+
"""
|
45
|
+
statement_params = telemetry.get_statement_params(
|
46
|
+
project=telemetry.TelemetryProject.MLOPS.value,
|
47
|
+
subproject=telemetry.TelemetrySubProject.MONITORING.value,
|
48
|
+
)
|
49
|
+
database_name_id = sql_identifier.SqlIdentifier(database_name)
|
50
|
+
schema_name_id = sql_identifier.SqlIdentifier(schema_name)
|
51
|
+
monitor_sql_client._ModelMonitorSQLClient.initialize_monitoring_schema(
|
52
|
+
session, database_name_id, schema_name_id, statement_params=statement_params
|
53
|
+
)
|
54
|
+
|
55
|
+
def _fetch_task_from_model_version(
|
56
|
+
self,
|
57
|
+
model_version: model_version_impl.ModelVersion,
|
58
|
+
) -> type_hints.Task:
|
59
|
+
task = model_version.get_model_task()
|
60
|
+
if task == type_hints.Task.UNKNOWN:
|
61
|
+
raise ValueError("Registry model must be logged with task in order to be monitored.")
|
62
|
+
return task
|
63
|
+
|
64
|
+
def __init__(
|
65
|
+
self,
|
66
|
+
session: session.Session,
|
67
|
+
database_name: sql_identifier.SqlIdentifier,
|
68
|
+
schema_name: sql_identifier.SqlIdentifier,
|
69
|
+
*,
|
70
|
+
create_if_not_exists: bool = False,
|
71
|
+
statement_params: Optional[Dict[str, Any]] = None,
|
72
|
+
) -> None:
|
73
|
+
"""
|
74
|
+
Opens a ModelMonitorManager for a given database and schema.
|
75
|
+
Optionally sets up the schema for Model Monitoring.
|
76
|
+
|
77
|
+
Args:
|
78
|
+
session: The Snowpark Session to connect with Snowflake.
|
79
|
+
database_name: The name of the database.
|
80
|
+
schema_name: The name of the schema.
|
81
|
+
create_if_not_exists: Flag whether to initialize resources in the schema needed for Model Monitoring.
|
82
|
+
statement_params: Optional set of statement params.
|
83
|
+
|
84
|
+
Raises:
|
85
|
+
ValueError: When there is no specified or active database in the session.
|
86
|
+
"""
|
87
|
+
self._database_name = database_name
|
88
|
+
self._schema_name = schema_name
|
89
|
+
self.statement_params = statement_params
|
90
|
+
self._model_monitor_client = monitor_sql_client._ModelMonitorSQLClient(
|
91
|
+
session,
|
92
|
+
database_name=self._database_name,
|
93
|
+
schema_name=self._schema_name,
|
94
|
+
)
|
95
|
+
if create_if_not_exists:
|
96
|
+
monitor_sql_client._ModelMonitorSQLClient.initialize_monitoring_schema(
|
97
|
+
session, self._database_name, self._schema_name, self.statement_params
|
98
|
+
)
|
99
|
+
elif not self._model_monitor_client._validate_is_initialized():
|
100
|
+
raise ValueError(
|
101
|
+
"Monitoring has not been setup. Set create_if_not_exists or call ModelMonitorManager.setup"
|
102
|
+
)
|
103
|
+
|
104
|
+
def _get_and_validate_model_function_from_model_version(
|
105
|
+
self, function: str, model_version: model_version_impl.ModelVersion
|
106
|
+
) -> model_manifest_schema.ModelFunctionInfo:
|
107
|
+
functions = model_version.show_functions()
|
108
|
+
for f in functions:
|
109
|
+
if f["target_method"] == function:
|
110
|
+
return f
|
111
|
+
existing_target_methods = {f["target_method"] for f in functions}
|
112
|
+
raise ValueError(
|
113
|
+
f"Function with name {function} does not exist in the given model version. "
|
114
|
+
f"Found: {existing_target_methods}."
|
115
|
+
)
|
116
|
+
|
117
|
+
def _validate_monitor_config_or_raise(
|
118
|
+
self,
|
119
|
+
table_config: model_monitor_config.ModelMonitorTableConfig,
|
120
|
+
model_monitor_config: model_monitor_config.ModelMonitorConfig,
|
121
|
+
) -> None:
|
122
|
+
"""Validate provided config for model monitor.
|
123
|
+
|
124
|
+
Args:
|
125
|
+
table_config: Config for model monitor tables.
|
126
|
+
model_monitor_config: Config for ModelMonitor.
|
127
|
+
|
128
|
+
Raises:
|
129
|
+
ValueError: If warehouse provided does not exist.
|
130
|
+
"""
|
131
|
+
|
132
|
+
# Validate naming will not exceed 255 chars
|
133
|
+
_validate_name_constraints(model_monitor_config.model_version)
|
134
|
+
|
135
|
+
if len(table_config.prediction_columns) != len(table_config.label_columns):
|
136
|
+
raise ValueError("Prediction and Label column names must be of the same length.")
|
137
|
+
# output and ground cols are list to keep interface extensible.
|
138
|
+
# for prpr only one label and one output col will be supported
|
139
|
+
if len(table_config.prediction_columns) != 1 or len(table_config.label_columns) != 1:
|
140
|
+
raise ValueError("Multiple Output columns are not supported in monitoring")
|
141
|
+
|
142
|
+
# Validate warehouse exists.
|
143
|
+
warehouse_name_id = sql_identifier.SqlIdentifier(model_monitor_config.background_compute_warehouse_name)
|
144
|
+
self._model_monitor_client.validate_monitor_warehouse(warehouse_name_id, statement_params=self.statement_params)
|
145
|
+
|
146
|
+
# Validate refresh interval.
|
147
|
+
try:
|
148
|
+
num_units, time_units = model_monitor_config.refresh_interval.strip().split(" ")
|
149
|
+
int(num_units) # try to cast
|
150
|
+
if time_units.lower() not in {"seconds", "minutes", "hours", "days"}:
|
151
|
+
raise ValueError(
|
152
|
+
"""Invalid time unit in refresh interval. Provide '<num> <seconds | minutes | hours | days>'.
|
153
|
+
See https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table#required-parameters for more info."""
|
154
|
+
)
|
155
|
+
except Exception as e: # TODO: Link to DT page.
|
156
|
+
raise ValueError(
|
157
|
+
f"""Failed to parse refresh interval with exception {e}.
|
158
|
+
Provide '<num> <seconds | minutes | hours | days>'.
|
159
|
+
See https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table#required-parameters for more info."""
|
160
|
+
)
|
161
|
+
|
162
|
+
def add_monitor(
|
163
|
+
self,
|
164
|
+
name: str,
|
165
|
+
table_config: model_monitor_config.ModelMonitorTableConfig,
|
166
|
+
model_monitor_config: model_monitor_config.ModelMonitorConfig,
|
167
|
+
*,
|
168
|
+
add_dashboard_udtfs: bool = False,
|
169
|
+
) -> model_monitor.ModelMonitor:
|
170
|
+
"""Add a new Model Monitor.
|
171
|
+
|
172
|
+
Args:
|
173
|
+
name: Name of Model Monitor to create.
|
174
|
+
table_config: Configuration options for the source table used in ModelMonitor.
|
175
|
+
model_monitor_config: Configuration options of ModelMonitor.
|
176
|
+
add_dashboard_udtfs: Add UDTFs useful for creating a dashboard.
|
177
|
+
|
178
|
+
Returns:
|
179
|
+
The newly added ModelMonitor object.
|
180
|
+
"""
|
181
|
+
# Validates configuration or raise.
|
182
|
+
self._validate_monitor_config_or_raise(table_config, model_monitor_config)
|
183
|
+
model_function = self._get_and_validate_model_function_from_model_version(
|
184
|
+
model_monitor_config.model_function_name, model_monitor_config.model_version
|
185
|
+
)
|
186
|
+
monitor_refresh_interval = model_monitor_interval.ModelMonitorRefreshInterval(
|
187
|
+
model_monitor_config.refresh_interval
|
188
|
+
)
|
189
|
+
name_id = sql_identifier.SqlIdentifier(name)
|
190
|
+
source_table_name_id = sql_identifier.SqlIdentifier(table_config.source_table)
|
191
|
+
prediction_columns = [
|
192
|
+
sql_identifier.SqlIdentifier(column_name) for column_name in table_config.prediction_columns
|
193
|
+
]
|
194
|
+
label_columns = [sql_identifier.SqlIdentifier(column_name) for column_name in table_config.label_columns]
|
195
|
+
id_columns = [sql_identifier.SqlIdentifier(column_name) for column_name in table_config.id_columns]
|
196
|
+
ts_column = sql_identifier.SqlIdentifier(table_config.timestamp_column)
|
197
|
+
|
198
|
+
# Validate source table
|
199
|
+
self._model_monitor_client.validate_source_table(
|
200
|
+
source_table_name=source_table_name_id,
|
201
|
+
timestamp_column=ts_column,
|
202
|
+
prediction_columns=prediction_columns,
|
203
|
+
label_columns=label_columns,
|
204
|
+
id_columns=id_columns,
|
205
|
+
model_function=model_function,
|
206
|
+
)
|
207
|
+
|
208
|
+
task = self._fetch_task_from_model_version(model_version=model_monitor_config.model_version)
|
209
|
+
score_type = self._model_monitor_client.get_score_type(task, source_table_name_id, prediction_columns)
|
210
|
+
|
211
|
+
# Insert monitoring metadata for new model version.
|
212
|
+
self._model_monitor_client.create_monitor_on_model_version(
|
213
|
+
monitor_name=name_id,
|
214
|
+
source_table_name=source_table_name_id,
|
215
|
+
fully_qualified_model_name=model_monitor_config.model_version.fully_qualified_model_name,
|
216
|
+
version_name=sql_identifier.SqlIdentifier(model_monitor_config.model_version.version_name),
|
217
|
+
function_name=model_monitor_config.model_function_name,
|
218
|
+
timestamp_column=ts_column,
|
219
|
+
prediction_columns=prediction_columns,
|
220
|
+
label_columns=label_columns,
|
221
|
+
id_columns=id_columns,
|
222
|
+
task=task,
|
223
|
+
statement_params=self.statement_params,
|
224
|
+
)
|
225
|
+
|
226
|
+
# Create Dynamic tables for model monitor.
|
227
|
+
self._model_monitor_client.create_dynamic_tables_for_monitor(
|
228
|
+
model_name=sql_identifier.SqlIdentifier(model_monitor_config.model_version.model_name),
|
229
|
+
model_version_name=sql_identifier.SqlIdentifier(model_monitor_config.model_version.version_name),
|
230
|
+
task=task,
|
231
|
+
source_table_name=source_table_name_id,
|
232
|
+
refresh_interval=monitor_refresh_interval,
|
233
|
+
aggregation_window=model_monitor_config.aggregation_window,
|
234
|
+
warehouse_name=sql_identifier.SqlIdentifier(model_monitor_config.background_compute_warehouse_name),
|
235
|
+
timestamp_column=sql_identifier.SqlIdentifier(table_config.timestamp_column),
|
236
|
+
id_columns=id_columns,
|
237
|
+
prediction_columns=prediction_columns,
|
238
|
+
label_columns=label_columns,
|
239
|
+
score_type=score_type,
|
240
|
+
)
|
241
|
+
|
242
|
+
# Initialize baseline table.
|
243
|
+
self._model_monitor_client.initialize_baseline_table(
|
244
|
+
model_name=sql_identifier.SqlIdentifier(model_monitor_config.model_version.model_name),
|
245
|
+
version_name=sql_identifier.SqlIdentifier(model_monitor_config.model_version.version_name),
|
246
|
+
source_table_name=table_config.source_table,
|
247
|
+
columns_to_drop=[ts_column, *id_columns],
|
248
|
+
statement_params=self.statement_params,
|
249
|
+
)
|
250
|
+
|
251
|
+
# Add udtfs helpful for dashboard queries.
|
252
|
+
# TODO(apgupta) Make this true by default.
|
253
|
+
if add_dashboard_udtfs:
|
254
|
+
self._model_monitor_client.add_dashboard_udtfs(
|
255
|
+
name_id,
|
256
|
+
model_name=sql_identifier.SqlIdentifier(model_monitor_config.model_version.model_name),
|
257
|
+
model_version_name=sql_identifier.SqlIdentifier(model_monitor_config.model_version.version_name),
|
258
|
+
task=task,
|
259
|
+
score_type=score_type,
|
260
|
+
output_columns=prediction_columns,
|
261
|
+
ground_truth_columns=label_columns,
|
262
|
+
)
|
263
|
+
|
264
|
+
return model_monitor.ModelMonitor._ref(
|
265
|
+
model_monitor_client=self._model_monitor_client,
|
266
|
+
name=name_id,
|
267
|
+
fully_qualified_model_name=model_monitor_config.model_version.fully_qualified_model_name,
|
268
|
+
version_name=sql_identifier.SqlIdentifier(model_monitor_config.model_version.version_name),
|
269
|
+
function_name=sql_identifier.SqlIdentifier(model_monitor_config.model_function_name),
|
270
|
+
prediction_columns=prediction_columns,
|
271
|
+
label_columns=label_columns,
|
272
|
+
)
|
273
|
+
|
274
|
+
def get_monitor_by_model_version(
|
275
|
+
self, model_version: model_version_impl.ModelVersion
|
276
|
+
) -> model_monitor.ModelMonitor:
|
277
|
+
fq_model_name = model_version.fully_qualified_model_name
|
278
|
+
version_name = sql_identifier.SqlIdentifier(model_version.version_name)
|
279
|
+
if self._model_monitor_client.validate_existence(fq_model_name, version_name, self.statement_params):
|
280
|
+
model_db, model_schema, model_name = sql_identifier.parse_fully_qualified_name(fq_model_name)
|
281
|
+
if model_db is None or model_schema is None:
|
282
|
+
raise ValueError("Failed to parse model name")
|
283
|
+
|
284
|
+
model_monitor_params: monitor_sql_client._ModelMonitorParams = (
|
285
|
+
self._model_monitor_client.get_model_monitor_by_model_version(
|
286
|
+
model_db=model_db,
|
287
|
+
model_schema=model_schema,
|
288
|
+
model_name=model_name,
|
289
|
+
version_name=version_name,
|
290
|
+
statement_params=self.statement_params,
|
291
|
+
)
|
292
|
+
)
|
293
|
+
return model_monitor.ModelMonitor._ref(
|
294
|
+
model_monitor_client=self._model_monitor_client,
|
295
|
+
name=sql_identifier.SqlIdentifier(model_monitor_params["monitor_name"]),
|
296
|
+
fully_qualified_model_name=fq_model_name,
|
297
|
+
version_name=version_name,
|
298
|
+
function_name=sql_identifier.SqlIdentifier(model_monitor_params["function_name"]),
|
299
|
+
prediction_columns=model_monitor_params["prediction_columns"],
|
300
|
+
label_columns=model_monitor_params["label_columns"],
|
301
|
+
)
|
302
|
+
|
303
|
+
else:
|
304
|
+
raise ValueError(
|
305
|
+
f"ModelMonitor not found for model version {model_version.model_name} - {model_version.version_name}"
|
306
|
+
)
|
307
|
+
|
308
|
+
def get_monitor(self, name: str) -> model_monitor.ModelMonitor:
|
309
|
+
"""Get a Model Monitor from the Registry
|
310
|
+
|
311
|
+
Args:
|
312
|
+
name: Name of Model Monitor to retrieve.
|
313
|
+
|
314
|
+
Raises:
|
315
|
+
ValueError: If model monitor is not found.
|
316
|
+
|
317
|
+
Returns:
|
318
|
+
The fetched ModelMonitor.
|
319
|
+
"""
|
320
|
+
name_id = sql_identifier.SqlIdentifier(name)
|
321
|
+
|
322
|
+
if not self._model_monitor_client.validate_existence_by_name(
|
323
|
+
monitor_name=name_id,
|
324
|
+
statement_params=self.statement_params,
|
325
|
+
):
|
326
|
+
raise ValueError(f"Unable to find model monitor '{name}'")
|
327
|
+
model_monitor_params: monitor_sql_client._ModelMonitorParams = (
|
328
|
+
self._model_monitor_client.get_model_monitor_by_name(name_id, statement_params=self.statement_params)
|
329
|
+
)
|
330
|
+
|
331
|
+
return model_monitor.ModelMonitor._ref(
|
332
|
+
model_monitor_client=self._model_monitor_client,
|
333
|
+
name=name_id,
|
334
|
+
fully_qualified_model_name=model_monitor_params["fully_qualified_model_name"],
|
335
|
+
version_name=sql_identifier.SqlIdentifier(model_monitor_params["version_name"]),
|
336
|
+
function_name=sql_identifier.SqlIdentifier(model_monitor_params["function_name"]),
|
337
|
+
prediction_columns=model_monitor_params["prediction_columns"],
|
338
|
+
label_columns=model_monitor_params["label_columns"],
|
339
|
+
)
|
340
|
+
|
341
|
+
def show_model_monitors(self) -> List[snowpark.Row]:
|
342
|
+
"""Show all model monitors in the registry.
|
343
|
+
|
344
|
+
Returns:
|
345
|
+
List of snowpark.Row containing metadata for each model monitor.
|
346
|
+
"""
|
347
|
+
return self._model_monitor_client.get_all_model_monitor_metadata()
|
348
|
+
|
349
|
+
def delete_monitor(self, name: str) -> None:
|
350
|
+
"""Delete a Model Monitor from the Registry
|
351
|
+
|
352
|
+
Args:
|
353
|
+
name: Name of the Model Monitor to delete.
|
354
|
+
"""
|
355
|
+
name_id = sql_identifier.SqlIdentifier(name)
|
356
|
+
monitor_params = self._model_monitor_client.get_model_monitor_by_name(name_id)
|
357
|
+
_, _, model = sql_identifier.parse_fully_qualified_name(monitor_params["fully_qualified_model_name"])
|
358
|
+
version = sql_identifier.SqlIdentifier(monitor_params["version_name"])
|
359
|
+
self._model_monitor_client.delete_monitor_metadata(name_id)
|
360
|
+
self._model_monitor_client.delete_baseline_table(model, version)
|
361
|
+
self._model_monitor_client.delete_dynamic_tables(model, version)
|
@@ -0,0 +1 @@
|
|
1
|
+
SNOWFLAKE_ML_MONITORING_MIN_VERSION = "1.7.0"
|