snowflake-ml-python 1.6.2__py3-none-any.whl → 1.6.4__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/utils/db_utils.py +50 -0
- snowflake/ml/_internal/utils/service_logger.py +63 -0
- snowflake/ml/_internal/utils/sql_identifier.py +25 -1
- snowflake/ml/data/_internal/arrow_ingestor.py +1 -11
- snowflake/ml/data/ingestor_utils.py +20 -10
- snowflake/ml/feature_store/access_manager.py +3 -3
- snowflake/ml/feature_store/feature_store.py +19 -2
- snowflake/ml/feature_store/feature_view.py +82 -28
- 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 +78 -9
- snowflake/ml/model/_client/ops/model_ops.py +89 -7
- snowflake/ml/model/_client/ops/service_ops.py +200 -91
- snowflake/ml/model/_client/service/model_deployment_spec.py +4 -0
- snowflake/ml/model/_client/service/model_deployment_spec_schema.py +1 -0
- 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 +35 -13
- snowflake/ml/model/_model_composer/model_composer.py +11 -41
- snowflake/ml/model/_model_composer/model_manifest/model_manifest.py +29 -4
- snowflake/ml/model/_packager/model_env/model_env.py +4 -38
- snowflake/ml/model/_packager/model_handlers/_utils.py +106 -32
- snowflake/ml/model/_packager/model_handlers/catboost.py +26 -27
- snowflake/ml/model/_packager/model_handlers/huggingface_pipeline.py +3 -3
- snowflake/ml/model/_packager/model_handlers/lightgbm.py +21 -6
- snowflake/ml/model/_packager/model_handlers/mlflow.py +3 -5
- snowflake/ml/model/_packager/model_handlers/model_objective_utils.py +111 -58
- snowflake/ml/model/_packager/model_handlers/sentence_transformers.py +15 -8
- snowflake/ml/model/_packager/model_handlers/sklearn.py +50 -66
- snowflake/ml/model/_packager/model_handlers/snowmlmodel.py +36 -17
- snowflake/ml/model/_packager/model_handlers/xgboost.py +22 -7
- snowflake/ml/model/_packager/model_meta/model_meta.py +16 -45
- snowflake/ml/model/_packager/model_meta/model_meta_schema.py +1 -6
- snowflake/ml/model/_packager/model_packager.py +14 -10
- snowflake/ml/model/_packager/model_runtime/model_runtime.py +11 -0
- snowflake/ml/model/_signatures/snowpark_handler.py +3 -2
- snowflake/ml/model/type_hints.py +11 -152
- snowflake/ml/modeling/_internal/snowpark_implementations/distributed_hpo_trainer.py +0 -2
- snowflake/ml/modeling/_internal/snowpark_implementations/snowpark_trainer.py +17 -6
- snowflake/ml/modeling/_internal/snowpark_implementations/xgboost_external_memory_trainer.py +0 -1
- snowflake/ml/modeling/calibration/calibrated_classifier_cv.py +1 -0
- snowflake/ml/modeling/cluster/affinity_propagation.py +1 -0
- snowflake/ml/modeling/cluster/agglomerative_clustering.py +1 -0
- snowflake/ml/modeling/cluster/birch.py +1 -0
- snowflake/ml/modeling/cluster/bisecting_k_means.py +1 -0
- snowflake/ml/modeling/cluster/dbscan.py +1 -0
- snowflake/ml/modeling/cluster/feature_agglomeration.py +1 -0
- snowflake/ml/modeling/cluster/k_means.py +1 -0
- snowflake/ml/modeling/cluster/mean_shift.py +1 -0
- snowflake/ml/modeling/cluster/mini_batch_k_means.py +1 -0
- snowflake/ml/modeling/cluster/optics.py +1 -0
- snowflake/ml/modeling/cluster/spectral_biclustering.py +1 -0
- snowflake/ml/modeling/cluster/spectral_clustering.py +1 -0
- snowflake/ml/modeling/cluster/spectral_coclustering.py +1 -0
- snowflake/ml/modeling/compose/column_transformer.py +1 -0
- snowflake/ml/modeling/compose/transformed_target_regressor.py +1 -0
- snowflake/ml/modeling/covariance/elliptic_envelope.py +1 -0
- snowflake/ml/modeling/covariance/empirical_covariance.py +1 -0
- snowflake/ml/modeling/covariance/graphical_lasso.py +1 -0
- snowflake/ml/modeling/covariance/graphical_lasso_cv.py +1 -0
- snowflake/ml/modeling/covariance/ledoit_wolf.py +1 -0
- snowflake/ml/modeling/covariance/min_cov_det.py +1 -0
- snowflake/ml/modeling/covariance/oas.py +1 -0
- snowflake/ml/modeling/covariance/shrunk_covariance.py +1 -0
- snowflake/ml/modeling/decomposition/dictionary_learning.py +1 -0
- snowflake/ml/modeling/decomposition/factor_analysis.py +1 -0
- snowflake/ml/modeling/decomposition/fast_ica.py +1 -0
- snowflake/ml/modeling/decomposition/incremental_pca.py +1 -0
- snowflake/ml/modeling/decomposition/kernel_pca.py +1 -0
- snowflake/ml/modeling/decomposition/mini_batch_dictionary_learning.py +1 -0
- snowflake/ml/modeling/decomposition/mini_batch_sparse_pca.py +1 -0
- snowflake/ml/modeling/decomposition/pca.py +1 -0
- snowflake/ml/modeling/decomposition/sparse_pca.py +1 -0
- snowflake/ml/modeling/decomposition/truncated_svd.py +1 -0
- snowflake/ml/modeling/discriminant_analysis/linear_discriminant_analysis.py +1 -0
- snowflake/ml/modeling/discriminant_analysis/quadratic_discriminant_analysis.py +1 -0
- snowflake/ml/modeling/ensemble/ada_boost_classifier.py +1 -0
- snowflake/ml/modeling/ensemble/ada_boost_regressor.py +1 -0
- snowflake/ml/modeling/ensemble/bagging_classifier.py +1 -0
- snowflake/ml/modeling/ensemble/bagging_regressor.py +1 -0
- snowflake/ml/modeling/ensemble/extra_trees_classifier.py +1 -0
- snowflake/ml/modeling/ensemble/extra_trees_regressor.py +1 -0
- snowflake/ml/modeling/ensemble/gradient_boosting_classifier.py +1 -0
- snowflake/ml/modeling/ensemble/gradient_boosting_regressor.py +1 -0
- snowflake/ml/modeling/ensemble/hist_gradient_boosting_classifier.py +1 -0
- snowflake/ml/modeling/ensemble/hist_gradient_boosting_regressor.py +1 -0
- snowflake/ml/modeling/ensemble/isolation_forest.py +1 -0
- snowflake/ml/modeling/ensemble/random_forest_classifier.py +1 -0
- snowflake/ml/modeling/ensemble/random_forest_regressor.py +1 -0
- snowflake/ml/modeling/ensemble/stacking_regressor.py +1 -0
- snowflake/ml/modeling/ensemble/voting_classifier.py +1 -0
- snowflake/ml/modeling/ensemble/voting_regressor.py +1 -0
- snowflake/ml/modeling/feature_selection/generic_univariate_select.py +1 -0
- snowflake/ml/modeling/feature_selection/select_fdr.py +1 -0
- snowflake/ml/modeling/feature_selection/select_fpr.py +1 -0
- snowflake/ml/modeling/feature_selection/select_fwe.py +1 -0
- snowflake/ml/modeling/feature_selection/select_k_best.py +1 -0
- snowflake/ml/modeling/feature_selection/select_percentile.py +1 -0
- snowflake/ml/modeling/feature_selection/sequential_feature_selector.py +1 -0
- snowflake/ml/modeling/feature_selection/variance_threshold.py +1 -0
- snowflake/ml/modeling/gaussian_process/gaussian_process_classifier.py +1 -0
- snowflake/ml/modeling/gaussian_process/gaussian_process_regressor.py +1 -0
- snowflake/ml/modeling/impute/iterative_imputer.py +1 -0
- snowflake/ml/modeling/impute/knn_imputer.py +1 -0
- snowflake/ml/modeling/impute/missing_indicator.py +1 -0
- snowflake/ml/modeling/kernel_approximation/additive_chi2_sampler.py +1 -0
- snowflake/ml/modeling/kernel_approximation/nystroem.py +1 -0
- snowflake/ml/modeling/kernel_approximation/polynomial_count_sketch.py +1 -0
- snowflake/ml/modeling/kernel_approximation/rbf_sampler.py +1 -0
- snowflake/ml/modeling/kernel_approximation/skewed_chi2_sampler.py +1 -0
- snowflake/ml/modeling/kernel_ridge/kernel_ridge.py +1 -0
- snowflake/ml/modeling/lightgbm/lgbm_classifier.py +1 -0
- snowflake/ml/modeling/lightgbm/lgbm_regressor.py +1 -0
- snowflake/ml/modeling/linear_model/ard_regression.py +1 -0
- snowflake/ml/modeling/linear_model/bayesian_ridge.py +1 -0
- snowflake/ml/modeling/linear_model/elastic_net.py +1 -0
- snowflake/ml/modeling/linear_model/elastic_net_cv.py +1 -0
- snowflake/ml/modeling/linear_model/gamma_regressor.py +1 -0
- snowflake/ml/modeling/linear_model/huber_regressor.py +1 -0
- snowflake/ml/modeling/linear_model/lars.py +1 -0
- snowflake/ml/modeling/linear_model/lars_cv.py +1 -0
- snowflake/ml/modeling/linear_model/lasso.py +1 -0
- snowflake/ml/modeling/linear_model/lasso_cv.py +1 -0
- snowflake/ml/modeling/linear_model/lasso_lars.py +1 -0
- snowflake/ml/modeling/linear_model/lasso_lars_cv.py +1 -0
- snowflake/ml/modeling/linear_model/lasso_lars_ic.py +1 -0
- snowflake/ml/modeling/linear_model/linear_regression.py +1 -0
- snowflake/ml/modeling/linear_model/logistic_regression.py +1 -0
- snowflake/ml/modeling/linear_model/logistic_regression_cv.py +1 -0
- snowflake/ml/modeling/linear_model/multi_task_elastic_net.py +1 -0
- snowflake/ml/modeling/linear_model/multi_task_elastic_net_cv.py +1 -0
- snowflake/ml/modeling/linear_model/multi_task_lasso.py +1 -0
- snowflake/ml/modeling/linear_model/multi_task_lasso_cv.py +1 -0
- snowflake/ml/modeling/linear_model/orthogonal_matching_pursuit.py +1 -0
- snowflake/ml/modeling/linear_model/passive_aggressive_classifier.py +1 -0
- snowflake/ml/modeling/linear_model/passive_aggressive_regressor.py +1 -0
- snowflake/ml/modeling/linear_model/perceptron.py +1 -0
- snowflake/ml/modeling/linear_model/poisson_regressor.py +1 -0
- snowflake/ml/modeling/linear_model/ransac_regressor.py +1 -0
- snowflake/ml/modeling/linear_model/ridge.py +1 -0
- snowflake/ml/modeling/linear_model/ridge_classifier.py +1 -0
- snowflake/ml/modeling/linear_model/ridge_classifier_cv.py +1 -0
- snowflake/ml/modeling/linear_model/ridge_cv.py +1 -0
- snowflake/ml/modeling/linear_model/sgd_classifier.py +1 -0
- snowflake/ml/modeling/linear_model/sgd_one_class_svm.py +1 -0
- snowflake/ml/modeling/linear_model/sgd_regressor.py +1 -0
- snowflake/ml/modeling/linear_model/theil_sen_regressor.py +1 -0
- snowflake/ml/modeling/linear_model/tweedie_regressor.py +1 -0
- snowflake/ml/modeling/manifold/isomap.py +1 -0
- snowflake/ml/modeling/manifold/mds.py +1 -0
- snowflake/ml/modeling/manifold/spectral_embedding.py +1 -0
- snowflake/ml/modeling/manifold/tsne.py +1 -0
- 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 +1 -0
- snowflake/ml/modeling/mixture/gaussian_mixture.py +1 -0
- snowflake/ml/modeling/multiclass/one_vs_one_classifier.py +1 -0
- snowflake/ml/modeling/multiclass/one_vs_rest_classifier.py +1 -0
- snowflake/ml/modeling/multiclass/output_code_classifier.py +1 -0
- snowflake/ml/modeling/naive_bayes/bernoulli_nb.py +1 -0
- snowflake/ml/modeling/naive_bayes/categorical_nb.py +1 -0
- snowflake/ml/modeling/naive_bayes/complement_nb.py +1 -0
- snowflake/ml/modeling/naive_bayes/gaussian_nb.py +1 -0
- snowflake/ml/modeling/naive_bayes/multinomial_nb.py +1 -0
- snowflake/ml/modeling/neighbors/k_neighbors_classifier.py +1 -0
- snowflake/ml/modeling/neighbors/k_neighbors_regressor.py +1 -0
- snowflake/ml/modeling/neighbors/kernel_density.py +1 -0
- snowflake/ml/modeling/neighbors/local_outlier_factor.py +1 -0
- snowflake/ml/modeling/neighbors/nearest_centroid.py +1 -0
- snowflake/ml/modeling/neighbors/nearest_neighbors.py +1 -0
- snowflake/ml/modeling/neighbors/neighborhood_components_analysis.py +1 -0
- snowflake/ml/modeling/neighbors/radius_neighbors_classifier.py +1 -0
- snowflake/ml/modeling/neighbors/radius_neighbors_regressor.py +1 -0
- snowflake/ml/modeling/neural_network/bernoulli_rbm.py +1 -0
- snowflake/ml/modeling/neural_network/mlp_classifier.py +1 -0
- snowflake/ml/modeling/neural_network/mlp_regressor.py +1 -0
- snowflake/ml/modeling/pipeline/pipeline.py +0 -1
- snowflake/ml/modeling/preprocessing/polynomial_features.py +1 -0
- snowflake/ml/modeling/semi_supervised/label_propagation.py +1 -0
- snowflake/ml/modeling/semi_supervised/label_spreading.py +1 -0
- snowflake/ml/modeling/svm/linear_svc.py +1 -0
- snowflake/ml/modeling/svm/linear_svr.py +1 -0
- snowflake/ml/modeling/svm/nu_svc.py +1 -0
- snowflake/ml/modeling/svm/nu_svr.py +1 -0
- snowflake/ml/modeling/svm/svc.py +1 -0
- snowflake/ml/modeling/svm/svr.py +1 -0
- snowflake/ml/modeling/tree/decision_tree_classifier.py +1 -0
- snowflake/ml/modeling/tree/decision_tree_regressor.py +1 -0
- snowflake/ml/modeling/tree/extra_tree_classifier.py +1 -0
- snowflake/ml/modeling/tree/extra_tree_regressor.py +1 -0
- snowflake/ml/modeling/xgboost/xgb_classifier.py +1 -0
- snowflake/ml/modeling/xgboost/xgb_regressor.py +1 -0
- snowflake/ml/modeling/xgboost/xgbrf_classifier.py +1 -0
- snowflake/ml/modeling/xgboost/xgbrf_regressor.py +1 -0
- 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 -4
- snowflake/ml/registry/registry.py +165 -6
- snowflake/ml/version.py +1 -1
- {snowflake_ml_python-1.6.2.dist-info → snowflake_ml_python-1.6.4.dist-info}/METADATA +30 -9
- {snowflake_ml_python-1.6.2.dist-info → snowflake_ml_python-1.6.4.dist-info}/RECORD +225 -249
- {snowflake_ml_python-1.6.2.dist-info → snowflake_ml_python-1.6.4.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/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 -269
- 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 -106
- 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.2.dist-info → snowflake_ml_python-1.6.4.dist-info}/LICENSE.txt +0 -0
- {snowflake_ml_python-1.6.2.dist-info → snowflake_ml_python-1.6.4.dist-info}/top_level.txt +0 -0
@@ -1,215 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
import os
|
3
|
-
import posixpath
|
4
|
-
from string import Template
|
5
|
-
from typing import List
|
6
|
-
|
7
|
-
import importlib_resources
|
8
|
-
|
9
|
-
from snowflake import snowpark
|
10
|
-
from snowflake.ml._internal import file_utils
|
11
|
-
from snowflake.ml._internal.container_services.image_registry import (
|
12
|
-
registry_client as image_registry_client,
|
13
|
-
)
|
14
|
-
from snowflake.ml._internal.exceptions import (
|
15
|
-
error_codes,
|
16
|
-
exceptions as snowml_exceptions,
|
17
|
-
)
|
18
|
-
from snowflake.ml._internal.utils import identifier
|
19
|
-
from snowflake.ml.model._deploy_client import image_builds
|
20
|
-
from snowflake.ml.model._deploy_client.image_builds import base_image_builder
|
21
|
-
from snowflake.ml.model._deploy_client.utils import constants, snowservice_client
|
22
|
-
|
23
|
-
logger = logging.getLogger(__name__)
|
24
|
-
|
25
|
-
|
26
|
-
class ServerImageBuilder(base_image_builder.ImageBuilder):
|
27
|
-
"""
|
28
|
-
Server-side image building and upload to model registry.
|
29
|
-
"""
|
30
|
-
|
31
|
-
def __init__(
|
32
|
-
self,
|
33
|
-
*,
|
34
|
-
context_dir: str,
|
35
|
-
full_image_name: str,
|
36
|
-
image_repo: str,
|
37
|
-
session: snowpark.Session,
|
38
|
-
artifact_stage_location: str,
|
39
|
-
compute_pool: str,
|
40
|
-
job_name: str,
|
41
|
-
external_access_integrations: List[str],
|
42
|
-
) -> None:
|
43
|
-
"""Initialization
|
44
|
-
|
45
|
-
Args:
|
46
|
-
context_dir: Local docker context dir.
|
47
|
-
full_image_name: Full image name consists of image name and image tag.
|
48
|
-
image_repo: Path to image repository.
|
49
|
-
session: Snowpark session
|
50
|
-
artifact_stage_location: Spec file and future deployment related artifacts will be stored under
|
51
|
-
{stage}/models/{model_id}
|
52
|
-
compute_pool: The compute pool used to run docker image build workload.
|
53
|
-
job_name: job_name to use.
|
54
|
-
external_access_integrations: EAIs for network connection.
|
55
|
-
"""
|
56
|
-
self.context_dir = context_dir
|
57
|
-
self.image_repo = image_repo
|
58
|
-
self.full_image_name = full_image_name
|
59
|
-
self.session = session
|
60
|
-
self.artifact_stage_location = artifact_stage_location
|
61
|
-
self.compute_pool = compute_pool
|
62
|
-
self.external_access_integrations = external_access_integrations
|
63
|
-
self.job_name = job_name
|
64
|
-
self.client = snowservice_client.SnowServiceClient(session)
|
65
|
-
|
66
|
-
assert artifact_stage_location.startswith(
|
67
|
-
"@"
|
68
|
-
), f"stage path should start with @, actual: {artifact_stage_location}"
|
69
|
-
|
70
|
-
def build_and_upload_image(self) -> None:
|
71
|
-
"""
|
72
|
-
Builds and uploads an image to the model registry.
|
73
|
-
"""
|
74
|
-
logger.info("Starting server-side image build")
|
75
|
-
self._build_image_in_remote_job()
|
76
|
-
|
77
|
-
def _build_image_in_remote_job(self) -> None:
|
78
|
-
context_tarball_stage_location = f"{self.artifact_stage_location}/{constants.CONTEXT}.tar.gz"
|
79
|
-
spec_stage_location = f"{self.artifact_stage_location}/{constants.IMAGE_BUILD_JOB_SPEC_TEMPLATE}.yaml"
|
80
|
-
kaniko_shell_script_stage_location = f"{self.artifact_stage_location}/{constants.KANIKO_SHELL_SCRIPT_NAME}"
|
81
|
-
|
82
|
-
self._compress_and_upload_docker_context_tarball(context_tarball_stage_location=context_tarball_stage_location)
|
83
|
-
|
84
|
-
self._construct_and_upload_docker_entrypoint_script(
|
85
|
-
context_tarball_stage_location=context_tarball_stage_location
|
86
|
-
)
|
87
|
-
|
88
|
-
# This is more of a workaround to support non-spcs-registry images.
|
89
|
-
# TODO[shchen] remove such logic when first-party-image is supported on snowservice registry.
|
90
|
-
# The regular Kaniko image doesn't include a shell; only the debug image comes with a shell. We need a shell
|
91
|
-
# as we use an sh script to launch Kaniko
|
92
|
-
kaniko_image = "/".join([self.image_repo.rstrip("/"), constants.KANIKO_IMAGE])
|
93
|
-
registry_client = image_registry_client.ImageRegistryClient(self.session, kaniko_image)
|
94
|
-
if registry_client.image_exists(kaniko_image):
|
95
|
-
logger.debug(f"Kaniko image already existed at {kaniko_image}, skipping uploading")
|
96
|
-
else:
|
97
|
-
# Following Digest is corresponding to v1.16.0-debug tag. Note that we cannot copy from image that contains
|
98
|
-
# tag as the underlying image blob copying API supports digest only.
|
99
|
-
registry_client.copy_image(
|
100
|
-
source_image_with_digest="gcr.io/kaniko-project/executor@sha256:"
|
101
|
-
"b8c0977f88f24dbd7cbc2ffe5c5f824c410ccd0952a72cc066efc4b6dfbb52b6",
|
102
|
-
dest_image_with_tag=kaniko_image,
|
103
|
-
)
|
104
|
-
self._construct_and_upload_job_spec(
|
105
|
-
base_image=kaniko_image,
|
106
|
-
kaniko_shell_script_stage_location=kaniko_shell_script_stage_location,
|
107
|
-
)
|
108
|
-
self._launch_kaniko_job(spec_stage_location)
|
109
|
-
|
110
|
-
def _construct_and_upload_docker_entrypoint_script(self, context_tarball_stage_location: str) -> None:
|
111
|
-
"""Construct a shell script that invokes logic to uncompress the docker context tarball, then invoke Kaniko
|
112
|
-
executor to build images and push to image registry; the script will also ensure the docker credential(used to
|
113
|
-
authenticate to image registry) stays up-to-date when session token refreshes.
|
114
|
-
|
115
|
-
Args:
|
116
|
-
context_tarball_stage_location: Path context directory stage location.
|
117
|
-
"""
|
118
|
-
kaniko_shell_script_template = (
|
119
|
-
importlib_resources.files(image_builds)
|
120
|
-
.joinpath(f"templates/{constants.KANIKO_SHELL_SCRIPT_TEMPLATE}")
|
121
|
-
.read_text("utf-8")
|
122
|
-
)
|
123
|
-
|
124
|
-
kaniko_shell_file = os.path.join(self.context_dir, constants.KANIKO_SHELL_SCRIPT_NAME)
|
125
|
-
|
126
|
-
with file_utils.open_file(kaniko_shell_file, "w+") as script_file:
|
127
|
-
normed_artifact_stage_path = posixpath.normpath(identifier.remove_prefix(self.artifact_stage_location, "@"))
|
128
|
-
params = {
|
129
|
-
# Remove @ in the beginning, append "/" to denote root directory.
|
130
|
-
"tar_from": "/" + posixpath.normpath(identifier.remove_prefix(context_tarball_stage_location, "@")),
|
131
|
-
# Remove @ in the beginning, append "/" to denote root directory.
|
132
|
-
"tar_to": "/" + normed_artifact_stage_path,
|
133
|
-
"context_dir": f"dir:///{normed_artifact_stage_path}/{constants.CONTEXT}",
|
134
|
-
"image_repo": self.image_repo,
|
135
|
-
# All models will be sharing the same layer cache from the image_repo/cache directory.
|
136
|
-
"cache_repo": f"{self.image_repo.rstrip('/')}/cache",
|
137
|
-
"image_destination": self.full_image_name,
|
138
|
-
}
|
139
|
-
template = Template(kaniko_shell_script_template)
|
140
|
-
script = template.safe_substitute(params)
|
141
|
-
script_file.write(script)
|
142
|
-
logger.debug(f"script content: \n\n {script}")
|
143
|
-
self.session.file.put(
|
144
|
-
local_file_name=kaniko_shell_file,
|
145
|
-
stage_location=self.artifact_stage_location,
|
146
|
-
auto_compress=False,
|
147
|
-
overwrite=True,
|
148
|
-
)
|
149
|
-
|
150
|
-
def _compress_and_upload_docker_context_tarball(self, context_tarball_stage_location: str) -> None:
|
151
|
-
try:
|
152
|
-
with file_utils._create_tar_gz_stream(
|
153
|
-
source_dir=self.context_dir, arcname=constants.CONTEXT
|
154
|
-
) as input_stream:
|
155
|
-
self.session.file.put_stream(
|
156
|
-
input_stream=input_stream,
|
157
|
-
stage_location=context_tarball_stage_location,
|
158
|
-
auto_compress=False,
|
159
|
-
overwrite=True,
|
160
|
-
)
|
161
|
-
except Exception as e:
|
162
|
-
raise snowml_exceptions.SnowflakeMLException(
|
163
|
-
error_code=error_codes.INTERNAL_SNOWPARK_ERROR,
|
164
|
-
original_exception=RuntimeError(
|
165
|
-
"Exception occurred when compressing docker context dir as tarball and upload to stage."
|
166
|
-
),
|
167
|
-
) from e
|
168
|
-
|
169
|
-
def _construct_and_upload_job_spec(self, base_image: str, kaniko_shell_script_stage_location: str) -> None:
|
170
|
-
assert kaniko_shell_script_stage_location.startswith(
|
171
|
-
"@"
|
172
|
-
), f"stage path should start with @, actual: {kaniko_shell_script_stage_location}"
|
173
|
-
|
174
|
-
spec_template = (
|
175
|
-
importlib_resources.files(image_builds)
|
176
|
-
.joinpath(f"templates/{constants.IMAGE_BUILD_JOB_SPEC_TEMPLATE}")
|
177
|
-
.read_text("utf-8")
|
178
|
-
)
|
179
|
-
|
180
|
-
spec_file_path = os.path.join(self.context_dir, f"{constants.IMAGE_BUILD_JOB_SPEC_TEMPLATE}.yaml")
|
181
|
-
|
182
|
-
with file_utils.open_file(spec_file_path, "w+") as spec_file:
|
183
|
-
assert self.artifact_stage_location.startswith("@")
|
184
|
-
normed_artifact_stage_path = posixpath.normpath(identifier.remove_prefix(self.artifact_stage_location, "@"))
|
185
|
-
(db, schema, stage, path) = identifier.parse_snowflake_stage_path(normed_artifact_stage_path)
|
186
|
-
content = Template(spec_template).safe_substitute(
|
187
|
-
{
|
188
|
-
"base_image": base_image,
|
189
|
-
"container_name": constants.KANIKO_CONTAINER_NAME,
|
190
|
-
"stage": identifier.get_schema_level_object_identifier(db, schema, stage),
|
191
|
-
# Remove @ in the beginning, append "/" to denote root directory.
|
192
|
-
"script_path": "/"
|
193
|
-
+ posixpath.normpath(identifier.remove_prefix(kaniko_shell_script_stage_location, "@")),
|
194
|
-
"mounted_token_path": constants.SPCS_MOUNTED_TOKEN_PATH,
|
195
|
-
}
|
196
|
-
)
|
197
|
-
spec_file.write(content)
|
198
|
-
spec_file.seek(0)
|
199
|
-
logger.debug(f"Kaniko job spec file: \n\n {spec_file.read()}")
|
200
|
-
|
201
|
-
self.session.file.put(
|
202
|
-
local_file_name=spec_file_path,
|
203
|
-
stage_location=self.artifact_stage_location,
|
204
|
-
auto_compress=False,
|
205
|
-
overwrite=True,
|
206
|
-
)
|
207
|
-
|
208
|
-
def _launch_kaniko_job(self, spec_stage_location: str) -> None:
|
209
|
-
logger.debug(f"Submitting job {self.job_name} for building docker image with kaniko")
|
210
|
-
self.client.create_job(
|
211
|
-
job_name=self.job_name,
|
212
|
-
compute_pool=self.compute_pool,
|
213
|
-
spec_stage_location=spec_stage_location,
|
214
|
-
external_access_integrations=self.external_access_integrations,
|
215
|
-
)
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# Note that base image tag should not be 'latest' as it might cause false positive image cache hit.
|
2
|
-
FROM ${base_image} as build
|
3
|
-
|
4
|
-
COPY ${model_env_folder}/conda.yml conda.yml
|
5
|
-
COPY ${model_env_folder}/requirements.txt requirements.txt
|
6
|
-
COPY ${inference_server_dir} ./${inference_server_dir}
|
7
|
-
COPY ${entrypoint_script} ./${entrypoint_script}
|
8
|
-
|
9
|
-
USER root
|
10
|
-
RUN if id mambauser >/dev/null 2>&1; then \
|
11
|
-
echo "mambauser already exists."; \
|
12
|
-
else \
|
13
|
-
# Set environment variables
|
14
|
-
export USER=mambauser && \
|
15
|
-
export UID=1000 && \
|
16
|
-
export HOME=/home/$USER && \
|
17
|
-
echo "Creating $USER user..." && \
|
18
|
-
adduser --disabled-password \
|
19
|
-
--gecos "A non-root user for running inference server" \
|
20
|
-
--uid $UID \
|
21
|
-
--home $HOME \
|
22
|
-
$USER; \
|
23
|
-
fi
|
24
|
-
|
25
|
-
RUN chmod +rx conda.yml
|
26
|
-
RUN chmod +rx requirements.txt
|
27
|
-
RUN chmod +x ./${entrypoint_script}
|
28
|
-
|
29
|
-
USER mambauser
|
30
|
-
|
31
|
-
# Set MAMBA_DOCKERFILE_ACTIVATE=1 to activate the conda environment during build time.
|
32
|
-
ARG MAMBA_DOCKERFILE_ACTIVATE=1
|
33
|
-
ARG MAMBA_NO_LOW_SPEED_LIMIT=1
|
34
|
-
|
35
|
-
# Bitsandbytes uses this ENVVAR to determine CUDA library location
|
36
|
-
ENV CONDA_PREFIX=/opt/conda
|
37
|
-
|
38
|
-
# The micromamba image comes with an empty environment named base.
|
39
|
-
# CONDA_OVERRIDE_CUDA ref https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-virtual.html
|
40
|
-
RUN --mount=type=cache,target=/opt/conda/pkgs CONDA_OVERRIDE_CUDA="${cuda_override_env}" \
|
41
|
-
micromamba install -y -n base -f conda.yml && \
|
42
|
-
python -m pip install "uvicorn[standard]" gunicorn starlette==0.30.0 && \
|
43
|
-
python -m pip install -r requirements.txt && \
|
44
|
-
micromamba clean -afy
|
45
|
-
|
46
|
-
${copy_model_statement}
|
47
|
-
|
48
|
-
${extra_env_statement}
|
49
|
-
|
50
|
-
# Expose the port on which the Starlette app will run.
|
51
|
-
EXPOSE 5000
|
52
|
-
|
53
|
-
CMD ["./${entrypoint_script}"]
|
@@ -1,38 +0,0 @@
|
|
1
|
-
spec:
|
2
|
-
container:
|
3
|
-
- name: "${container_name}"
|
4
|
-
image: "${base_image}"
|
5
|
-
command:
|
6
|
-
- sh
|
7
|
-
args:
|
8
|
-
- -c
|
9
|
-
- |
|
10
|
-
wait_for_file() {
|
11
|
-
file_path="$1"
|
12
|
-
timeout="$2"
|
13
|
-
elapsed_time=0
|
14
|
-
while [ ! -f "${file_path}" ]; do
|
15
|
-
if [ "${elapsed_time}" -ge "${timeout}" ]; then
|
16
|
-
echo "Error: ${file_path} not found within ${timeout} seconds. Exiting."
|
17
|
-
exit 1
|
18
|
-
fi
|
19
|
-
elapsed_time=$((elapsed_time + 1))
|
20
|
-
remaining_time=$((timeout - elapsed_time))
|
21
|
-
echo "Awaiting the mounting of ${file_path}. Wait time remaining: ${remaining_time} seconds"
|
22
|
-
sleep 1
|
23
|
-
done
|
24
|
-
}
|
25
|
-
wait_for_file "${script_path}" 300
|
26
|
-
wait_for_file "${mounted_token_path}" 300
|
27
|
-
chmod +x "${script_path}"
|
28
|
-
sh "${script_path}"
|
29
|
-
volumeMounts:
|
30
|
-
- name: vol1
|
31
|
-
mountPath: /local/user/vol1
|
32
|
-
- name: stagemount
|
33
|
-
mountPath: "/${stage}"
|
34
|
-
volume:
|
35
|
-
- name: vol1
|
36
|
-
source: local # only local emptyDir volume is supported
|
37
|
-
- name: stagemount
|
38
|
-
source: "@${stage}"
|
@@ -1,105 +0,0 @@
|
|
1
|
-
#!/bin/sh
|
2
|
-
|
3
|
-
# Set the file path to monitor
|
4
|
-
REGISTRY_CRED_PATH="/kaniko/.docker/config.json"
|
5
|
-
SESSION_TOKEN_PATH="/snowflake/session/token"
|
6
|
-
|
7
|
-
# Function to gracefully terminate the file monitoring job
|
8
|
-
cleanup() {
|
9
|
-
echo "Stopping file monitoring job..."
|
10
|
-
trap - INT TERM # Remove the signal handlers
|
11
|
-
kill -- -$$$ # Kill the entire process group. Extra $ to escape, the generated shell script should have two $.
|
12
|
-
}
|
13
|
-
|
14
|
-
# SNOW-990976, This is an additional safety check to ensure token file exists, on top of the token file check upon
|
15
|
-
# launching SPCS job. This additional check could provide value in cases things go wrong with token refresh that result
|
16
|
-
# in token file to disappear.
|
17
|
-
wait_till_token_file_exists() {
|
18
|
-
timeout=60 # 1 minute timeout
|
19
|
-
elapsed_time=0
|
20
|
-
|
21
|
-
while [ ! -f "${SESSION_TOKEN_PATH}" ] && [ "$elapsed_time" -lt "$timeout" ]; do
|
22
|
-
sleep 1
|
23
|
-
elapsed_time=$((elapsed_time + 1))
|
24
|
-
remaining_time=$((timeout - elapsed_time))
|
25
|
-
echo "Waiting for token file to exist. Wait time remaining: ${remaining_time} seconds."
|
26
|
-
done
|
27
|
-
|
28
|
-
if [ ! -f "${SESSION_TOKEN_PATH}" ]; then
|
29
|
-
echo "Error: Token file '${SESSION_TOKEN_PATH}' does not show up within the ${timeout} seconds timeout period."
|
30
|
-
exit 1
|
31
|
-
fi
|
32
|
-
}
|
33
|
-
|
34
|
-
generate_registry_cred() {
|
35
|
-
wait_till_token_file_exists
|
36
|
-
AUTH_TOKEN=$(printf '0auth2accesstoken:%s' "$(cat ${SESSION_TOKEN_PATH})" | base64);
|
37
|
-
echo '{"auths":{"$image_repo":{"auth":"'"$AUTH_TOKEN"'"}}}' | tr -d '\n' > $REGISTRY_CRED_PATH;
|
38
|
-
}
|
39
|
-
|
40
|
-
on_session_token_change() {
|
41
|
-
wait_till_token_file_exists
|
42
|
-
# Get the initial checksum of the file
|
43
|
-
CHECKSUM=$(md5sum "${SESSION_TOKEN_PATH}" | awk '{ print $1 }')
|
44
|
-
# Run the command once before the loop
|
45
|
-
echo "Monitoring session token changes in the background..."
|
46
|
-
(
|
47
|
-
while true; do
|
48
|
-
wait_till_token_file_exists
|
49
|
-
# Get the current checksum of the file
|
50
|
-
CURRENT_CHECKSUM=$(md5sum "${SESSION_TOKEN_PATH}" | awk '{ print $1 }')
|
51
|
-
if [ "${CURRENT_CHECKSUM}" != "${CHECKSUM}" ]; then
|
52
|
-
# Session token file has changed, regenerate registry credential.
|
53
|
-
echo "Session token has changed. Regenerating registry auth credentials."
|
54
|
-
generate_registry_cred
|
55
|
-
CHECKSUM="${CURRENT_CHECKSUM}"
|
56
|
-
fi
|
57
|
-
# Wait for a short period of time before checking again
|
58
|
-
sleep 1
|
59
|
-
done
|
60
|
-
)
|
61
|
-
}
|
62
|
-
|
63
|
-
run_kaniko() {
|
64
|
-
# Run the Kaniko command in the foreground
|
65
|
-
echo "Starting Kaniko command..."
|
66
|
-
|
67
|
-
# Set cache ttl to a large value as snowservice registry doesn't support deleting cache anyway.
|
68
|
-
# Compression level set to 1 for fastest compression/decompression speed at the cost of compression ration.
|
69
|
-
/kaniko/executor \
|
70
|
-
--dockerfile Dockerfile \
|
71
|
-
--context ${context_dir} \
|
72
|
-
--destination=${image_destination} \
|
73
|
-
--cache=true \
|
74
|
-
--compressed-caching=false \
|
75
|
-
--cache-copy-layers=false \
|
76
|
-
--use-new-run \
|
77
|
-
--snapshot-mode=redo \
|
78
|
-
--cache-repo=${cache_repo} \
|
79
|
-
--cache-run-layers=true \
|
80
|
-
--cache-ttl=8760h \
|
81
|
-
--push-retry=3 \
|
82
|
-
--image-fs-extract-retry=5 \
|
83
|
-
--compression=zstd \
|
84
|
-
--compression-level=1 \
|
85
|
-
--log-timestamp
|
86
|
-
}
|
87
|
-
|
88
|
-
setup() {
|
89
|
-
tar -C "${tar_to}" -xf "${tar_from}";
|
90
|
-
generate_registry_cred
|
91
|
-
# Set up the signal handlers
|
92
|
-
trap cleanup TERM
|
93
|
-
}
|
94
|
-
|
95
|
-
setup
|
96
|
-
|
97
|
-
# Running kaniko job on the foreground and session token monitoring on the background. When session token changes,
|
98
|
-
# overwrite the existing registry cred file with the new session token.
|
99
|
-
on_session_token_change &
|
100
|
-
run_kaniko
|
101
|
-
|
102
|
-
# Capture the exit code from the previous kaniko command.
|
103
|
-
KANIKO_EXIT_CODE=$?
|
104
|
-
# Exit with the same exit code as the Kaniko command. This then triggers the cleanup function.
|
105
|
-
exit $KANIKO_EXIT_CODE
|