snowflake-ml-python 1.8.4__py3-none-any.whl → 1.8.5__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/ml/_internal/telemetry.py +42 -13
- snowflake/ml/data/data_connector.py +1 -1
- snowflake/ml/jobs/_utils/constants.py +9 -0
- snowflake/ml/jobs/_utils/interop_utils.py +1 -1
- snowflake/ml/jobs/_utils/payload_utils.py +12 -4
- snowflake/ml/jobs/_utils/scripts/constants.py +6 -0
- snowflake/ml/jobs/_utils/scripts/mljob_launcher.py +85 -2
- snowflake/ml/jobs/_utils/spec_utils.py +7 -5
- snowflake/ml/jobs/decorators.py +7 -3
- snowflake/ml/jobs/job.py +158 -25
- snowflake/ml/jobs/manager.py +29 -19
- snowflake/ml/model/_client/ops/service_ops.py +5 -3
- snowflake/ml/model/_client/service/model_deployment_spec.py +11 -0
- snowflake/ml/model/_client/sql/model_version.py +1 -1
- snowflake/ml/model/_client/sql/service.py +16 -19
- snowflake/ml/model/_model_composer/model_composer.py +3 -1
- snowflake/ml/model/_packager/model_handlers/sklearn.py +1 -1
- snowflake/ml/model/_packager/model_runtime/_snowml_inference_alternative_requirements.py +3 -2
- snowflake/ml/monitoring/explain_visualize.py +160 -22
- snowflake/ml/utils/connection_params.py +8 -2
- snowflake/ml/version.py +1 -1
- {snowflake_ml_python-1.8.4.dist-info → snowflake_ml_python-1.8.5.dist-info}/METADATA +27 -9
- {snowflake_ml_python-1.8.4.dist-info → snowflake_ml_python-1.8.5.dist-info}/RECORD +26 -26
- {snowflake_ml_python-1.8.4.dist-info → snowflake_ml_python-1.8.5.dist-info}/WHEEL +1 -1
- {snowflake_ml_python-1.8.4.dist-info → snowflake_ml_python-1.8.5.dist-info}/licenses/LICENSE.txt +0 -0
- {snowflake_ml_python-1.8.4.dist-info → snowflake_ml_python-1.8.5.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Union, cast, overload
|
1
|
+
from typing import Any, Union, cast, overload
|
2
2
|
|
3
3
|
import altair as alt
|
4
4
|
import numpy as np
|
@@ -6,16 +6,22 @@ import pandas as pd
|
|
6
6
|
|
7
7
|
import snowflake.snowpark.dataframe as sp_df
|
8
8
|
from snowflake import snowpark
|
9
|
+
from snowflake.ml._internal.exceptions import error_codes, exceptions
|
9
10
|
from snowflake.ml.model import model_signature, type_hints
|
10
11
|
from snowflake.ml.model._signatures import snowpark_handler
|
11
12
|
|
13
|
+
DEFAULT_FIGSIZE = (1400, 500)
|
14
|
+
DEFAULT_VIOLIN_FIGSIZE = (1400, 100)
|
15
|
+
MAX_ANNOTATION_LENGTH = 20
|
16
|
+
MIN_DISTANCE = 10 # Increase minimum distance between labels for more spreading in plot_force
|
17
|
+
|
12
18
|
|
13
19
|
@overload
|
14
20
|
def plot_force(
|
15
21
|
shap_row: snowpark.Row,
|
16
22
|
features_row: snowpark.Row,
|
17
23
|
base_value: float = 0.0,
|
18
|
-
figsize: tuple[float, float] =
|
24
|
+
figsize: tuple[float, float] = DEFAULT_FIGSIZE,
|
19
25
|
contribution_threshold: float = 0.05,
|
20
26
|
) -> alt.LayerChart:
|
21
27
|
...
|
@@ -26,7 +32,7 @@ def plot_force(
|
|
26
32
|
shap_row: pd.Series,
|
27
33
|
features_row: pd.Series,
|
28
34
|
base_value: float = 0.0,
|
29
|
-
figsize: tuple[float, float] =
|
35
|
+
figsize: tuple[float, float] = DEFAULT_FIGSIZE,
|
30
36
|
contribution_threshold: float = 0.05,
|
31
37
|
) -> alt.LayerChart:
|
32
38
|
...
|
@@ -36,7 +42,7 @@ def plot_force(
|
|
36
42
|
shap_row: Union[pd.Series, snowpark.Row],
|
37
43
|
features_row: Union[pd.Series, snowpark.Row],
|
38
44
|
base_value: float = 0.0,
|
39
|
-
figsize: tuple[float, float] =
|
45
|
+
figsize: tuple[float, float] = DEFAULT_FIGSIZE,
|
40
46
|
contribution_threshold: float = 0.05,
|
41
47
|
) -> alt.LayerChart:
|
42
48
|
"""
|
@@ -53,7 +59,17 @@ def plot_force(
|
|
53
59
|
|
54
60
|
Returns:
|
55
61
|
Altair chart object
|
62
|
+
|
63
|
+
Raises:
|
64
|
+
SnowflakeMLException: If the contribution threshold is not between 0 and 1,
|
65
|
+
or if no features with significant contributions are found.
|
56
66
|
"""
|
67
|
+
if not (0 < contribution_threshold and contribution_threshold < 1):
|
68
|
+
raise exceptions.SnowflakeMLException(
|
69
|
+
error_code=error_codes.INVALID_ARGUMENT,
|
70
|
+
original_exception=ValueError("contribution_threshold must be between 0 and 1."),
|
71
|
+
)
|
72
|
+
|
57
73
|
if isinstance(shap_row, snowpark.Row):
|
58
74
|
shap_row = pd.Series(shap_row.as_dict())
|
59
75
|
if isinstance(features_row, snowpark.Row):
|
@@ -67,7 +83,7 @@ def plot_force(
|
|
67
83
|
{
|
68
84
|
"feature": feature,
|
69
85
|
"feature_value": features_row.iloc[index],
|
70
|
-
"feature_annotated": f"{feature}: {features_row.iloc[index]}",
|
86
|
+
"feature_annotated": f"{feature}: {features_row.iloc[index]}"[:MAX_ANNOTATION_LENGTH],
|
71
87
|
"influence_value": shap_row.iloc[index],
|
72
88
|
"bar_direction": positive_label if shap_row.iloc[index] >= 0 else negative_label,
|
73
89
|
}
|
@@ -95,11 +111,11 @@ def plot_force(
|
|
95
111
|
|
96
112
|
if row_influence_value >= 0:
|
97
113
|
start = current_position_pos - spacing
|
98
|
-
end = current_position_pos - row_influence_value
|
114
|
+
end = current_position_pos - row_influence_value - spacing
|
99
115
|
current_position_pos = end
|
100
116
|
else:
|
101
117
|
start = current_position_neg + spacing
|
102
|
-
end = current_position_neg + abs(row_influence_value)
|
118
|
+
end = current_position_neg + abs(row_influence_value) + spacing
|
103
119
|
current_position_neg = end
|
104
120
|
|
105
121
|
positions.append(
|
@@ -108,13 +124,23 @@ def plot_force(
|
|
108
124
|
"end": end,
|
109
125
|
"avg": (start + end) / 2,
|
110
126
|
"influence_value": row_influence_value,
|
111
|
-
"influence_annotated": f"Influence: {row_influence_value}",
|
112
127
|
"feature_value": row["feature_value"],
|
113
128
|
"feature_annotated": row["feature_annotated"],
|
114
129
|
"bar_direction": row["bar_direction"],
|
130
|
+
"bar_y": 0,
|
131
|
+
"feature": row["feature"],
|
115
132
|
}
|
116
133
|
)
|
117
134
|
|
135
|
+
if len(positions) == 0:
|
136
|
+
raise exceptions.SnowflakeMLException(
|
137
|
+
error_code=error_codes.INVALID_ARGUMENT,
|
138
|
+
original_exception=ValueError(
|
139
|
+
"No features with significant contributions found. Try lowering the contribution_threshold,"
|
140
|
+
"and verify the input is non-empty."
|
141
|
+
),
|
142
|
+
)
|
143
|
+
|
118
144
|
position_df = pd.DataFrame(positions)
|
119
145
|
|
120
146
|
# Create force plot using Altair
|
@@ -127,12 +153,13 @@ def plot_force(
|
|
127
153
|
.encode(
|
128
154
|
x=alt.X("start:Q", title="Feature Impact"),
|
129
155
|
x2=alt.X2("end:Q"),
|
156
|
+
y=alt.Y("bar_y:Q", axis=None),
|
130
157
|
color=alt.Color(
|
131
158
|
"bar_direction:N",
|
132
159
|
scale=alt.Scale(domain=[positive_label, negative_label], range=[red_color, blue_color]),
|
133
160
|
legend=alt.Legend(title="Influence Direction"),
|
134
161
|
),
|
135
|
-
tooltip=["influence_value", "feature_value"],
|
162
|
+
tooltip=["feature", "influence_value", "feature_value"],
|
136
163
|
)
|
137
164
|
.properties(title="Feature Influence (SHAP values)", width=width, height=height)
|
138
165
|
).interactive()
|
@@ -142,6 +169,7 @@ def plot_force(
|
|
142
169
|
.mark_point(shape="triangle", filled=True, fillOpacity=1)
|
143
170
|
.encode(
|
144
171
|
x=alt.X("start:Q"),
|
172
|
+
y=alt.Y("bar_y:Q", axis=None),
|
145
173
|
angle=alt.Angle("bar_direction:N", scale=alt.Scale(domain=["Positive", "Negative"], range=[90, -90])),
|
146
174
|
color=alt.Color(
|
147
175
|
"bar_direction:N", scale=alt.Scale(domain=["Positive", "Negative"], range=["#1f77b4", "#d62728"])
|
@@ -154,37 +182,147 @@ def plot_force(
|
|
154
182
|
# Add a vertical line at the base value
|
155
183
|
zero_line: alt.Chart = alt.Chart(pd.DataFrame({"x": [base_value]})).mark_rule(strokeDash=[3, 3]).encode(x="x:Q")
|
156
184
|
|
157
|
-
#
|
185
|
+
# Calculate label positions to avoid overlap and ensure labels are spread apart horizontally
|
186
|
+
|
187
|
+
# Sort by bar center (avg) for label placement
|
188
|
+
sorted_positions = sorted(positions, key=lambda x: x["avg"])
|
189
|
+
|
190
|
+
# Improved label spreading algorithm:
|
191
|
+
# Calculate the minimum and maximum x positions (avg) for the bars
|
192
|
+
min_x = min(pos["avg"] for pos in sorted_positions)
|
193
|
+
max_x = max(pos["avg"] for pos in sorted_positions)
|
194
|
+
n_labels = len(sorted_positions)
|
195
|
+
# Calculate the minimum required distance between labels
|
196
|
+
spread_width = max_x - min_x
|
197
|
+
if n_labels > 1:
|
198
|
+
space_per_label = spread_width / (n_labels - 1)
|
199
|
+
# If space_per_label is less than min_distance, use min_distance instead
|
200
|
+
effective_distance = max(space_per_label, MIN_DISTANCE)
|
201
|
+
else:
|
202
|
+
effective_distance = 0
|
203
|
+
|
204
|
+
# Start from min_x - offset, and assign label_x for each label from left to right
|
205
|
+
offset = -effective_distance # Start a bit to the left
|
206
|
+
label_positions = []
|
207
|
+
label_lines = []
|
208
|
+
placed_label_xs: list[float] = []
|
209
|
+
for i, pos in enumerate(sorted_positions):
|
210
|
+
if i == 0:
|
211
|
+
label_x = min_x + offset
|
212
|
+
else:
|
213
|
+
label_x = placed_label_xs[-1] + effective_distance
|
214
|
+
placed_label_xs.append(label_x)
|
215
|
+
label_positions.append(
|
216
|
+
{
|
217
|
+
"label_x": label_x,
|
218
|
+
"label_y": 1, # Place labels below the bars
|
219
|
+
"feature_annotated": pos["feature_annotated"],
|
220
|
+
"feature_value": pos["feature_value"],
|
221
|
+
}
|
222
|
+
)
|
223
|
+
# Draw a diagonal line from the bar to the label
|
224
|
+
label_lines.append(
|
225
|
+
{
|
226
|
+
"x": pos["avg"],
|
227
|
+
"x2": label_x,
|
228
|
+
"y": 0,
|
229
|
+
"y2": 1,
|
230
|
+
}
|
231
|
+
)
|
232
|
+
|
233
|
+
label_positions_df = pd.DataFrame(label_positions)
|
234
|
+
label_lines_df = pd.DataFrame(label_lines)
|
235
|
+
|
236
|
+
# Draw diagonal lines from bar to label
|
237
|
+
label_connectors = (
|
238
|
+
alt.Chart(label_lines_df)
|
239
|
+
.mark_rule(strokeDash=[2, 2], color="grey")
|
240
|
+
.encode(
|
241
|
+
x="x:Q",
|
242
|
+
x2="x2:Q",
|
243
|
+
y=alt.Y("y:Q", axis=None),
|
244
|
+
y2="y2:Q",
|
245
|
+
)
|
246
|
+
)
|
247
|
+
|
248
|
+
# Place labels at adjusted positions
|
158
249
|
feature_labels = (
|
159
|
-
alt.Chart(
|
160
|
-
.mark_text(align="center", baseline="line-bottom", dy=
|
250
|
+
alt.Chart(label_positions_df)
|
251
|
+
.mark_text(align="center", baseline="line-bottom", dy=0, fontSize=11)
|
161
252
|
.encode(
|
162
|
-
x=alt.X("
|
163
|
-
|
164
|
-
|
253
|
+
x=alt.X("label_x:Q"),
|
254
|
+
y=alt.Y("label_y:Q", axis=None),
|
255
|
+
text=alt.Text("feature_annotated:N"),
|
256
|
+
color=alt.value("grey"),
|
165
257
|
tooltip=["feature_value"],
|
166
258
|
)
|
167
259
|
)
|
168
260
|
|
169
|
-
return cast(alt.LayerChart, bars + feature_labels + zero_line + arrow)
|
261
|
+
return cast(alt.LayerChart, bars + feature_labels + zero_line + arrow + label_connectors)
|
170
262
|
|
171
263
|
|
172
264
|
def plot_influence_sensitivity(
|
173
|
-
|
174
|
-
|
265
|
+
shap_values: type_hints.SupportedDataType,
|
266
|
+
feature_values: type_hints.SupportedDataType,
|
267
|
+
figsize: tuple[float, float] = DEFAULT_FIGSIZE,
|
268
|
+
) -> Any:
|
175
269
|
"""
|
176
|
-
Create a SHAP dependence scatter plot for a specific feature.
|
270
|
+
Create a SHAP dependence scatter plot for a specific feature. If a DataFrame is provided, a select box
|
271
|
+
will be displayed to select the feature. This is only supported in Snowflake notebooks.
|
272
|
+
If Streamlit is not available and a DataFrame is passed in, an ImportError will be raised.
|
177
273
|
|
178
274
|
Args:
|
179
|
-
feature_values: pandas Series containing the feature values for a specific feature
|
180
|
-
shap_values: pandas Series containing the SHAP values for the same feature
|
275
|
+
feature_values: pandas Series or 2D array containing the feature values for a specific feature
|
276
|
+
shap_values: pandas Series or 2D array containing the SHAP values for the same feature
|
181
277
|
figsize: tuple of (width, height) for the plot
|
182
278
|
|
183
279
|
Returns:
|
184
280
|
Altair chart object
|
185
281
|
|
282
|
+
Raises:
|
283
|
+
ValueError: If the types of feature_values and shap_values are not the same
|
284
|
+
|
186
285
|
"""
|
187
286
|
|
287
|
+
use_streamlit = False
|
288
|
+
feature_values_df = _convert_to_pandas_df(feature_values)
|
289
|
+
shap_values_df = _convert_to_pandas_df(shap_values)
|
290
|
+
|
291
|
+
if len(shap_values_df.shape) > 1:
|
292
|
+
feature_values, shap_values, st = _prepare_feature_values_for_streamlit(feature_values_df, shap_values_df)
|
293
|
+
use_streamlit = True
|
294
|
+
elif feature_values_df.shape[0] != shap_values_df.shape[0]:
|
295
|
+
raise ValueError("Feature values and SHAP values must have the same number of rows.")
|
296
|
+
|
297
|
+
scatter = _create_scatter_plot(feature_values, shap_values, figsize)
|
298
|
+
return st.altair_chart(scatter) if use_streamlit else scatter
|
299
|
+
|
300
|
+
|
301
|
+
def _prepare_feature_values_for_streamlit(
|
302
|
+
feature_values_df: pd.DataFrame, shap_values: pd.DataFrame
|
303
|
+
) -> tuple[pd.Series, pd.Series, Any]:
|
304
|
+
try:
|
305
|
+
from IPython import get_ipython
|
306
|
+
from snowbook.executor.python_transformer import IPythonProxy
|
307
|
+
|
308
|
+
assert isinstance(
|
309
|
+
get_ipython(), IPythonProxy
|
310
|
+
), "Influence sensitivity plots for a DataFrame are not supported outside of Snowflake notebooks."
|
311
|
+
except ImportError:
|
312
|
+
raise RuntimeError(
|
313
|
+
"Influence sensitivity plots for a DataFrame are not supported outside of Snowflake notebooks."
|
314
|
+
)
|
315
|
+
|
316
|
+
import streamlit as st
|
317
|
+
|
318
|
+
feature_columns = feature_values_df.columns
|
319
|
+
chosen_ft: str = st.selectbox("Feature:", feature_columns)
|
320
|
+
feature_values = feature_values_df[chosen_ft]
|
321
|
+
shap_values = shap_values.iloc[:, feature_columns.get_loc(chosen_ft)]
|
322
|
+
return feature_values, shap_values, st
|
323
|
+
|
324
|
+
|
325
|
+
def _create_scatter_plot(feature_values: pd.Series, shap_values: pd.Series, figsize: tuple[float, float]) -> alt.Chart:
|
188
326
|
unique_vals = np.sort(np.unique(feature_values.values))
|
189
327
|
max_points_per_unique_value = float(np.max(np.bincount(np.searchsorted(unique_vals, feature_values.values))))
|
190
328
|
points_per_value = len(feature_values.values) / len(unique_vals)
|
@@ -224,7 +362,7 @@ def plot_influence_sensitivity(
|
|
224
362
|
def plot_violin(
|
225
363
|
shap_df: type_hints.SupportedDataType,
|
226
364
|
feature_df: type_hints.SupportedDataType,
|
227
|
-
figsize: tuple[float, float] =
|
365
|
+
figsize: tuple[float, float] = DEFAULT_VIOLIN_FIGSIZE,
|
228
366
|
) -> alt.Chart:
|
229
367
|
"""
|
230
368
|
Create a violin plot per feature showing the distribution of SHAP values.
|
@@ -113,6 +113,10 @@ def _load_from_snowsql_config_file(connection_name: str, login_file: str = "") -
|
|
113
113
|
|
114
114
|
config = configparser.ConfigParser(inline_comment_prefixes="#")
|
115
115
|
|
116
|
+
snowflake_connection_name = os.getenv("SNOWFLAKE_CONNECTION_NAME")
|
117
|
+
if snowflake_connection_name is not None:
|
118
|
+
connection_name = snowflake_connection_name
|
119
|
+
|
116
120
|
if connection_name:
|
117
121
|
if not connection_name.startswith("connections."):
|
118
122
|
connection_name = "connections." + connection_name
|
@@ -153,9 +157,11 @@ def SnowflakeLoginOptions(connection_name: str = "", login_file: Optional[str] =
|
|
153
157
|
Ideally one should have a snowsql config file. Read more here:
|
154
158
|
https://docs.snowflake.com/en/user-guide/snowsql-start.html#configuring-default-connection-settings
|
155
159
|
|
160
|
+
If snowsql config file does not exist, it tries auth from env variables.
|
161
|
+
|
156
162
|
Args:
|
157
|
-
connection_name: Name of the connection to look for inside the config file. If
|
158
|
-
it
|
163
|
+
connection_name: Name of the connection to look for inside the config file. If environment variable
|
164
|
+
SNOWFLAKE_CONNECTION_NAME is provided, it will override the input connection_name.
|
159
165
|
login_file: If provided, this is used as config file instead of default one (_DEFAULT_CONNECTION_FILE).
|
160
166
|
|
161
167
|
Returns:
|
snowflake/ml/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# This is parsed by regex in conda recipe meta file. Make sure not to break it.
|
2
|
-
VERSION = "1.8.
|
2
|
+
VERSION = "1.8.5"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: snowflake-ml-python
|
3
|
-
Version: 1.8.
|
3
|
+
Version: 1.8.5
|
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:
|
@@ -242,7 +242,7 @@ Requires-Dist: fsspec[http]<2026,>=2024.6.1
|
|
242
242
|
Requires-Dist: importlib_resources<7,>=6.1.1
|
243
243
|
Requires-Dist: numpy<2,>=1.23
|
244
244
|
Requires-Dist: packaging<25,>=20.9
|
245
|
-
Requires-Dist: pandas<3,>=1.
|
245
|
+
Requires-Dist: pandas<3,>=2.1.4
|
246
246
|
Requires-Dist: pyarrow
|
247
247
|
Requires-Dist: pydantic<3,>=2.8.2
|
248
248
|
Requires-Dist: pyjwt<3,>=2.0.0
|
@@ -253,11 +253,12 @@ Requires-Dist: s3fs<2026,>=2024.6.1
|
|
253
253
|
Requires-Dist: scikit-learn<1.6
|
254
254
|
Requires-Dist: scipy<2,>=1.9
|
255
255
|
Requires-Dist: shap<1,>=0.46.0
|
256
|
-
Requires-Dist: snowflake-connector-python[pandas]<4,>=3.
|
256
|
+
Requires-Dist: snowflake-connector-python[pandas]<4,>=3.15.0
|
257
257
|
Requires-Dist: snowflake-snowpark-python!=1.26.0,<2,>=1.17.0
|
258
258
|
Requires-Dist: snowflake.core<2,>=1.0.2
|
259
259
|
Requires-Dist: sqlparse<1,>=0.4
|
260
260
|
Requires-Dist: typing-extensions<5,>=4.1.0
|
261
|
+
Requires-Dist: xgboost<3,>=1.7.3
|
261
262
|
Provides-Extra: all
|
262
263
|
Requires-Dist: altair<6,>=5; extra == "all"
|
263
264
|
Requires-Dist: catboost<2,>=1.2.0; extra == "all"
|
@@ -266,13 +267,12 @@ Requires-Dist: lightgbm<5,>=4.1.0; extra == "all"
|
|
266
267
|
Requires-Dist: mlflow<3,>=2.16.0; extra == "all"
|
267
268
|
Requires-Dist: sentence-transformers<4,>=2.7.0; extra == "all"
|
268
269
|
Requires-Dist: sentencepiece<0.2.0,>=0.1.95; extra == "all"
|
269
|
-
Requires-Dist: streamlit<2,>=1.
|
270
|
+
Requires-Dist: streamlit<2,>=1.30.0; extra == "all"
|
270
271
|
Requires-Dist: tensorflow<3,>=2.17.0; extra == "all"
|
271
272
|
Requires-Dist: tokenizers<1,>=0.15.1; extra == "all"
|
272
273
|
Requires-Dist: torch<3,>=2.0.1; extra == "all"
|
273
274
|
Requires-Dist: torchdata<1,>=0.4; extra == "all"
|
274
275
|
Requires-Dist: transformers<5,>=4.39.3; extra == "all"
|
275
|
-
Requires-Dist: xgboost<3,>=1.7.3; extra == "all"
|
276
276
|
Provides-Extra: altair
|
277
277
|
Requires-Dist: altair<6,>=5; extra == "altair"
|
278
278
|
Provides-Extra: catboost
|
@@ -286,7 +286,7 @@ Requires-Dist: lightgbm<5,>=4.1.0; extra == "lightgbm"
|
|
286
286
|
Provides-Extra: mlflow
|
287
287
|
Requires-Dist: mlflow<3,>=2.16.0; extra == "mlflow"
|
288
288
|
Provides-Extra: streamlit
|
289
|
-
Requires-Dist: streamlit<2,>=1.
|
289
|
+
Requires-Dist: streamlit<2,>=1.30.0; extra == "streamlit"
|
290
290
|
Provides-Extra: tensorflow
|
291
291
|
Requires-Dist: tensorflow<3,>=2.17.0; extra == "tensorflow"
|
292
292
|
Provides-Extra: torch
|
@@ -298,8 +298,6 @@ Requires-Dist: sentencepiece<0.2.0,>=0.1.95; extra == "transformers"
|
|
298
298
|
Requires-Dist: tokenizers<1,>=0.15.1; extra == "transformers"
|
299
299
|
Requires-Dist: torch<3,>=2.0.1; extra == "transformers"
|
300
300
|
Requires-Dist: transformers<5,>=4.39.3; extra == "transformers"
|
301
|
-
Provides-Extra: xgboost
|
302
|
-
Requires-Dist: xgboost<3,>=1.7.3; extra == "xgboost"
|
303
301
|
Dynamic: license-file
|
304
302
|
|
305
303
|
# Snowpark ML
|
@@ -410,7 +408,27 @@ NOTE: Version 1.7.0 is used as example here. Please choose the the latest versio
|
|
410
408
|
|
411
409
|
# Release History
|
412
410
|
|
413
|
-
## 1.8.
|
411
|
+
## 1.8.5
|
412
|
+
|
413
|
+
### Bug Fixes
|
414
|
+
|
415
|
+
- Registry: Fixed a bug when listing and deleting container services.
|
416
|
+
- Registry: Fixed explainability issue with scikit-learn pipelines, skipping explain function creation.
|
417
|
+
- Explainability: bump minimum streamlit version down to 1.30
|
418
|
+
- Modeling: Make XGBoost a required dependency (xgboost is not a required dependency in snowflake-ml-python 1.8.4).
|
419
|
+
|
420
|
+
### Breaking change
|
421
|
+
|
422
|
+
- ML Job: Rename argument `num_instances` to `target_instances` in job submission APIs and
|
423
|
+
change type from `Optional[int]` to `int`
|
424
|
+
|
425
|
+
### New Features
|
426
|
+
|
427
|
+
- Registry: No longer checks if the snowflake-ml-python version is available in the Snowflake Conda channel when logging
|
428
|
+
an SPCS-only model.
|
429
|
+
- ML Job: Add `min_instances` argument to the job decorator to allow waiting for workers to be ready.
|
430
|
+
|
431
|
+
## 1.8.4 (2025-05-12)
|
414
432
|
|
415
433
|
### Bug Fixes
|
416
434
|
|
@@ -10,7 +10,7 @@ snowflake/cortex/_sse_client.py,sha256=sLYgqAfTOPADCnaWH2RWAJi8KbU_7gSRsTUDcDD5T
|
|
10
10
|
snowflake/cortex/_summarize.py,sha256=7GH8zqfIdOiHA5w4b6EvJEKEWhaTrL4YA6iDGbn7BNM,1307
|
11
11
|
snowflake/cortex/_translate.py,sha256=9ZGjvAnJFisbzJ_bXnt4pyug5UzhHJRXW8AhGQEersM,1652
|
12
12
|
snowflake/cortex/_util.py,sha256=krNTpbkFLXwdFqy1bd0xi7ZmOzOHRnIfHdQCPiLZJxk,3288
|
13
|
-
snowflake/ml/version.py,sha256=
|
13
|
+
snowflake/ml/version.py,sha256=VKHkHHe4NuU45p9rVSgxnJnhI_HRO0RG73jfubIU-xE,98
|
14
14
|
snowflake/ml/_internal/env.py,sha256=EY_2KVe8oR3LgKWdaeRb5rRU-NDNXJppPDsFJmMZUUY,265
|
15
15
|
snowflake/ml/_internal/env_utils.py,sha256=tzz8BziiwJEnZwkzDEYCMO20Sb-mnXwDtSakGfgG--M,29364
|
16
16
|
snowflake/ml/_internal/file_utils.py,sha256=7sA6loOeSfmGP4yx16P4usT9ZtRqG3ycnXu7_Tk7dOs,14206
|
@@ -18,7 +18,7 @@ snowflake/ml/_internal/init_utils.py,sha256=WhrlvS-xcmKErSpwg6cUk6XDQ5lQcwDqPJnU
|
|
18
18
|
snowflake/ml/_internal/migrator_utils.py,sha256=k3erO8x3YJcX6nkKeyJAUNGg1qjE3RFmD-W6dtLzIH0,161
|
19
19
|
snowflake/ml/_internal/platform_capabilities.py,sha256=2l3GeuKIbeoMh5m3z1mWx7niWsnPvNTSVrlK5bnRNpk,5290
|
20
20
|
snowflake/ml/_internal/relax_version_strategy.py,sha256=MYEIZrx1HfKNhl9Na3GN50ipX8c0MKIj9nwxjB0IC0Y,484
|
21
|
-
snowflake/ml/_internal/telemetry.py,sha256=
|
21
|
+
snowflake/ml/_internal/telemetry.py,sha256=04IFfNU-1V2EMD-5jgasCtXbUSxVqXABRRm5LGAHhtM,31949
|
22
22
|
snowflake/ml/_internal/type_utils.py,sha256=fGnxGx9Tb9G1Fh9EaD23CxChx0Jfc4KnRZv-M-Dcblk,2197
|
23
23
|
snowflake/ml/_internal/exceptions/dataset_error_messages.py,sha256=h7uGJbxBM6se-TW_64LKGGGdBCbwflzbBnmijWKX3Gc,285
|
24
24
|
snowflake/ml/_internal/exceptions/dataset_errors.py,sha256=TqESe8cDfWurJdv5X0DOwgzBfHCEqga_F3WQipYbdqg,741
|
@@ -50,7 +50,7 @@ snowflake/ml/_internal/utils/sql_identifier.py,sha256=YHIwXpb8E1U6LVUVpT8q7s9Zyg
|
|
50
50
|
snowflake/ml/_internal/utils/table_manager.py,sha256=Wf3JXLUzdCiffKF9PJj7edHY7usCXNNZf1P0jRWff-E,4963
|
51
51
|
snowflake/ml/_internal/utils/temp_file_utils.py,sha256=0-HTjXdxVt0kE6XcgyvRvY0btflWlmotP2bMXVpFJPA,1553
|
52
52
|
snowflake/ml/data/__init__.py,sha256=nm5VhN98Lzxr4kb679kglQfqbDbHhd9zYsnFJiQiThg,351
|
53
|
-
snowflake/ml/data/data_connector.py,sha256=
|
53
|
+
snowflake/ml/data/data_connector.py,sha256=m8OqV1HAm0QGJriV1XUSTV5tSS4t8as1xQK6AbaCfHA,10133
|
54
54
|
snowflake/ml/data/data_ingestor.py,sha256=w9PbcAKtAjP6TTzILOwwpFgF1qVYFhTDEryXBOsQq_o,972
|
55
55
|
snowflake/ml/data/data_source.py,sha256=HjBO1xqTyJfAvEAGESUIdke0KvSj5S5-FcI2D2zgejI,512
|
56
56
|
snowflake/ml/data/ingestor_utils.py,sha256=JOv7Kvs0DNhsXUjl940ZULDkeTjIcePCfQ9aL_NteV0,2721
|
@@ -94,17 +94,17 @@ snowflake/ml/fileset/sfcfs.py,sha256=FJFc9-gc0KXaNyc10ZovN_87aUCShb0WztVwa02t0io
|
|
94
94
|
snowflake/ml/fileset/snowfs.py,sha256=uF5QluYtiJ-HezGIhF55dONi3t0E6N7ByaVAIAlM3nk,5133
|
95
95
|
snowflake/ml/fileset/stage_fs.py,sha256=V4pysouSKKDPLzuW3u_extxfvjkQa5OlwIRES9Srpzo,20151
|
96
96
|
snowflake/ml/jobs/__init__.py,sha256=ORX_0blPSpl9u5442R-i4e8cqWYfO_vVjFFtX3as184,420
|
97
|
-
snowflake/ml/jobs/decorators.py,sha256=
|
98
|
-
snowflake/ml/jobs/job.py,sha256=
|
99
|
-
snowflake/ml/jobs/manager.py,sha256=
|
100
|
-
snowflake/ml/jobs/_utils/constants.py,sha256=
|
101
|
-
snowflake/ml/jobs/_utils/interop_utils.py,sha256=
|
102
|
-
snowflake/ml/jobs/_utils/payload_utils.py,sha256=
|
103
|
-
snowflake/ml/jobs/_utils/spec_utils.py,sha256=
|
97
|
+
snowflake/ml/jobs/decorators.py,sha256=8QGjpQBqFjAAN2nF-g8mqQoTnaC8Z9FZzTY-2PYtQAE,3614
|
98
|
+
snowflake/ml/jobs/job.py,sha256=dfioi8n_O74gC9mQ1-fjSJHZJI8ztLHmBrMeo2nSVi8,16055
|
99
|
+
snowflake/ml/jobs/manager.py,sha256=MjbZWSOoMJYqmPv0Bn1s9DHsQPKSu-P2-DxowVYgjuw,15705
|
100
|
+
snowflake/ml/jobs/_utils/constants.py,sha256=9M284dk1xr_r7JFgNz-_eVZViYYh7B4VLkFUXowvtZs,3586
|
101
|
+
snowflake/ml/jobs/_utils/interop_utils.py,sha256=8_HzGyz1bl-We6_tBp1NKxlYZ2VqWT4svJzKTEh7Wx4,18844
|
102
|
+
snowflake/ml/jobs/_utils/payload_utils.py,sha256=Jl1TxlTjJBbK-OaCYp_69VE_snwJEbtamEYKdc3C1tI,22499
|
103
|
+
snowflake/ml/jobs/_utils/spec_utils.py,sha256=WdZhVHxoMNNSQSLbS4UdOovzePY7jBV3J7bSOOzY_oM,12348
|
104
104
|
snowflake/ml/jobs/_utils/types.py,sha256=IRDZZAShUA_trwoSUFqbSRexvLefi2CFcBmQTYN11Yc,972
|
105
|
-
snowflake/ml/jobs/_utils/scripts/constants.py,sha256=
|
105
|
+
snowflake/ml/jobs/_utils/scripts/constants.py,sha256=4AL4x5pyrvj8gYZFhOY5dgxY4ouSRbvIVaQRCE1j7ao,457
|
106
106
|
snowflake/ml/jobs/_utils/scripts/get_instance_ip.py,sha256=DmWs5cVpNmUcrqnwhrUvxE5PycDWFN88Pdut8vFDHPg,5293
|
107
|
-
snowflake/ml/jobs/_utils/scripts/mljob_launcher.py,sha256=
|
107
|
+
snowflake/ml/jobs/_utils/scripts/mljob_launcher.py,sha256=vgorJ7RTRwlfEOjj4ynx6AEPiDa8IFyDSaFi9ThOdtY,9767
|
108
108
|
snowflake/ml/jobs/_utils/scripts/signal_workers.py,sha256=AR1Pylkm4-FGh10WXfrCtcxaV0rI7IQ2ZiO0Li7zZ3U,7433
|
109
109
|
snowflake/ml/jobs/_utils/scripts/worker_shutdown_listener.py,sha256=SeJ8v5XDriwHAjIGpcQkwVP-f-lO9QIdVjVD7Fkgafs,7893
|
110
110
|
snowflake/ml/lineage/__init__.py,sha256=8p1YGynC-qOxAZ8jZX2z84Reg5bv1NoJMoJmNJCrzI4,65
|
@@ -117,16 +117,16 @@ snowflake/ml/model/_client/model/model_impl.py,sha256=I_bwFX1N7EVS1GdCTjHeyDJ7Ox
|
|
117
117
|
snowflake/ml/model/_client/model/model_version_impl.py,sha256=Nk8J1iHLV0g68txvoQf8Wgfay8UXumOJs8BQBY_2bRg,43273
|
118
118
|
snowflake/ml/model/_client/ops/metadata_ops.py,sha256=qpK6PL3OyfuhyOmpvLCpHLy6vCxbZbp1HlEvakFGwv4,4884
|
119
119
|
snowflake/ml/model/_client/ops/model_ops.py,sha256=Olj5ccsAviHw3Kbhv-_c5JaPvXpAHj1qckOf2IpThu0,47978
|
120
|
-
snowflake/ml/model/_client/ops/service_ops.py,sha256=
|
121
|
-
snowflake/ml/model/_client/service/model_deployment_spec.py,sha256=
|
120
|
+
snowflake/ml/model/_client/ops/service_ops.py,sha256=7b7wafDNHQP_9w3HaE6_TWWk1BCGH_OwDrj7npu33mU,28362
|
121
|
+
snowflake/ml/model/_client/service/model_deployment_spec.py,sha256=V1j1WJ-gYrXN9SBsbg-908MbsJejl86rmaXHg4-tZiw,17508
|
122
122
|
snowflake/ml/model/_client/service/model_deployment_spec_schema.py,sha256=cr1yNVlbLzpHIDeyIIHb6m06-w3LfJc12DLQAqEHQqQ,1895
|
123
123
|
snowflake/ml/model/_client/sql/_base.py,sha256=Qrm8M92g3MHb-QnSLUlbd8iVKCRxLhG_zr5M2qmXwJ8,1473
|
124
124
|
snowflake/ml/model/_client/sql/model.py,sha256=nstZ8zR7MkXVEfhqLt7PWMik6dZr06nzq7VsF5NVNow,5840
|
125
|
-
snowflake/ml/model/_client/sql/model_version.py,sha256=
|
126
|
-
snowflake/ml/model/_client/sql/service.py,sha256=
|
125
|
+
snowflake/ml/model/_client/sql/model_version.py,sha256=QwzFlDH5laTqK2qF7SJQSbt28DgspWj3R11l-yD1Da0,23496
|
126
|
+
snowflake/ml/model/_client/sql/service.py,sha256=uzVenElisFwBxYO2NmC2-CJ_VDMVJp-8QHib6XjyoN8,11212
|
127
127
|
snowflake/ml/model/_client/sql/stage.py,sha256=DIFP1m7Itt_FJR4GCt5CNngEHn9OcK-fshoQAYnkNOY,820
|
128
128
|
snowflake/ml/model/_client/sql/tag.py,sha256=9sI0VoldKmsfToWSjMQddozPPGCxYUI6n0gPBiqd6x8,4333
|
129
|
-
snowflake/ml/model/_model_composer/model_composer.py,sha256=
|
129
|
+
snowflake/ml/model/_model_composer/model_composer.py,sha256=SJyaw8Pcp-n_VYLEraIxrispRYMkIU90DuEisZj4z-U,11631
|
130
130
|
snowflake/ml/model/_model_composer/model_manifest/model_manifest.py,sha256=0z0TKJ-qI1cGJ9gQOfmxAoWzo0-tBmMkl80bO-P0TKg,9157
|
131
131
|
snowflake/ml/model/_model_composer/model_manifest/model_manifest_schema.py,sha256=eqv-4-tvA9Lgrp7kQAQGS_CJVR9D6uOd8-SxADNOkeM,2887
|
132
132
|
snowflake/ml/model/_model_composer/model_method/constants.py,sha256=hoJwIopSdZiYn0fGq15_NiirC0l02d5LEs2D-4J_tPk,35
|
@@ -149,7 +149,7 @@ snowflake/ml/model/_packager/model_handlers/lightgbm.py,sha256=DAFMiqpXEUmKqeq5r
|
|
149
149
|
snowflake/ml/model/_packager/model_handlers/mlflow.py,sha256=xSpoXO0UOfBUpzx2W1O8P2WF0Xi1vrZ_J-DdgzQG0o8,9177
|
150
150
|
snowflake/ml/model/_packager/model_handlers/pytorch.py,sha256=jHYRjPUlCpSU2yvrJwuKAYLbG6CethxQx4brQ5ZmiVM,9784
|
151
151
|
snowflake/ml/model/_packager/model_handlers/sentence_transformers.py,sha256=sKp-bt-fAnruDMZJ5cN6F_m9dJRY0G2FjJ4-KjNLgcg,11380
|
152
|
-
snowflake/ml/model/_packager/model_handlers/sklearn.py,sha256=
|
152
|
+
snowflake/ml/model/_packager/model_handlers/sklearn.py,sha256=dH6S7FhJBqVOWPPXyEhN9Kj9tzDdDrD0phaGacoXQ14,18094
|
153
153
|
snowflake/ml/model/_packager/model_handlers/snowmlmodel.py,sha256=4YKX6BktNIjRSSUOStOMx4NVmRBE0o9pes3wyKYZ1Y0,17173
|
154
154
|
snowflake/ml/model/_packager/model_handlers/tensorflow.py,sha256=2J2XWYOC70axWaoNJa9aQLMyjLAKIskrT31t_LgqcIk,11350
|
155
155
|
snowflake/ml/model/_packager/model_handlers/torchscript.py,sha256=3IbMoVGlBR-RsQAdYZxjAz1ST-jDMQIyhhdwM5e3NeE,9531
|
@@ -165,7 +165,7 @@ snowflake/ml/model/_packager/model_meta/model_meta_schema.py,sha256=e4TUbWl998xQ
|
|
165
165
|
snowflake/ml/model/_packager/model_meta_migrator/base_migrator.py,sha256=8zTgq3n6TBXv7Vcwmf7b9wjK3m-9HHMsY0Qy1Rs-sZ4,1305
|
166
166
|
snowflake/ml/model/_packager/model_meta_migrator/migrator_plans.py,sha256=5butM-lyaDRhCAO2BaCOIQufpAxAfSAinsNuGqbbjMU,1029
|
167
167
|
snowflake/ml/model/_packager/model_meta_migrator/migrator_v1.py,sha256=cyZVvBGM3nF1IVqDKfYstLCchNO-ZhSkPvLM4aU7J5c,2066
|
168
|
-
snowflake/ml/model/_packager/model_runtime/_snowml_inference_alternative_requirements.py,sha256=
|
168
|
+
snowflake/ml/model/_packager/model_runtime/_snowml_inference_alternative_requirements.py,sha256=jRa_AmJd6H4VHeMSAp-2v1dDj1w7sEFtgmXv5BxxGPI,893
|
169
169
|
snowflake/ml/model/_packager/model_runtime/model_runtime.py,sha256=CDjbfBvZNrW6AI5xapYPFSEEQInd3RVo7_08mru2xx4,5487
|
170
170
|
snowflake/ml/model/_packager/model_task/model_task_utils.py,sha256=_nm3Irl5W6Oa8_OnJyp3bLeA9QAbV9ygGCsgHI70GX4,6641
|
171
171
|
snowflake/ml/model/_signatures/base_handler.py,sha256=4CTZKKbg4WIz_CmXjyVy8tKZW-5OFcz0J8XVPHm2dfQ,1269
|
@@ -396,7 +396,7 @@ snowflake/ml/modeling/xgboost/xgb_classifier.py,sha256=SF5F4elDdHmt8Wtth8BIH2Sc6
|
|
396
396
|
snowflake/ml/modeling/xgboost/xgb_regressor.py,sha256=5x-N1Yym0OfF3D7lHNzLByaazc4aoDNVmCQ-TgbYOGg,63580
|
397
397
|
snowflake/ml/modeling/xgboost/xgbrf_classifier.py,sha256=H3SAtx-2mIwS3N_ltBXVHlbLeYun5TtdBBN_goeKrBg,64253
|
398
398
|
snowflake/ml/modeling/xgboost/xgbrf_regressor.py,sha256=Up3rbL7pfeglVKx920UpLhBzHxteXLTWHqIk5WX9iPY,63778
|
399
|
-
snowflake/ml/monitoring/explain_visualize.py,sha256=
|
399
|
+
snowflake/ml/monitoring/explain_visualize.py,sha256=w0_ETgUq0mjKTbbpCXeLxAZGd7t2iLv3yPh90nbjVYY,15789
|
400
400
|
snowflake/ml/monitoring/model_monitor.py,sha256=8vJf1YROmJgBLUtpaH-lGKSSJv9R7PxPaQnOdr_j5YE,2200
|
401
401
|
snowflake/ml/monitoring/model_monitor_version.py,sha256=TlmDJZDE0lCVatRaBRgXIjzDF538nrMIc-zWj9MM_nk,46
|
402
402
|
snowflake/ml/monitoring/shap.py,sha256=Dp9nYquPEZjxMTW62YYA9g9qUdmCEFxcSk7ejvOP7PE,3597
|
@@ -409,11 +409,11 @@ snowflake/ml/registry/__init__.py,sha256=XdPQK9ejYkSJVrSQ7HD3jKQO0hKq2mC4bPCB6qr
|
|
409
409
|
snowflake/ml/registry/registry.py,sha256=FImEpQghF9tiSVwKAH5w0ePo2HG9i5AZNJ_4dw_6J54,30634
|
410
410
|
snowflake/ml/registry/_manager/model_manager.py,sha256=5HMLGSEJK8uYD4OVlxJqa83g9OPvdj-K7j_UaW-dde8,18271
|
411
411
|
snowflake/ml/utils/authentication.py,sha256=E1at4TIAQRDZDsMXSbrKvSJaT6_kSYJBkkr37vU9P2s,2606
|
412
|
-
snowflake/ml/utils/connection_params.py,sha256=
|
412
|
+
snowflake/ml/utils/connection_params.py,sha256=kJeFLfF1CHECYJGgPWIFdg__WMK9428yD0HsArms7aQ,8287
|
413
413
|
snowflake/ml/utils/sparse.py,sha256=zLBNh-ynhGpKH5TFtopk0YLkHGvv0yq1q-sV59YQKgg,3819
|
414
414
|
snowflake/ml/utils/sql_client.py,sha256=pSe2od6Pkh-8NwG3D-xqN76_uNf-ohOtVbT55HeQg1Y,668
|
415
|
-
snowflake_ml_python-1.8.
|
416
|
-
snowflake_ml_python-1.8.
|
417
|
-
snowflake_ml_python-1.8.
|
418
|
-
snowflake_ml_python-1.8.
|
419
|
-
snowflake_ml_python-1.8.
|
415
|
+
snowflake_ml_python-1.8.5.dist-info/licenses/LICENSE.txt,sha256=PdEp56Av5m3_kl21iFkVTX_EbHJKFGEdmYeIO1pL_Yk,11365
|
416
|
+
snowflake_ml_python-1.8.5.dist-info/METADATA,sha256=zAAUouCztUjL9nVVP5NEeggoiuiAULPSJRTld4iNOLA,84951
|
417
|
+
snowflake_ml_python-1.8.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
418
|
+
snowflake_ml_python-1.8.5.dist-info/top_level.txt,sha256=TY0gFSHKDdZy3THb0FGomyikWQasEGldIR1O0HGOHVw,10
|
419
|
+
snowflake_ml_python-1.8.5.dist-info/RECORD,,
|
{snowflake_ml_python-1.8.4.dist-info → snowflake_ml_python-1.8.5.dist-info}/licenses/LICENSE.txt
RENAMED
File without changes
|
File without changes
|