NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI
The machine learning client library that is used for interacting with Snowflake to build machine learning solutions.
Last release 5 days ago
29 Sep 2026
Ships on a steady schedule
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
2 versions withdrawn
withdrawn after publishing
3 years old
99 releases · first in 2023
One column per quarter.
Experiment Tracking: ExperimentTracking accepts an optional model_registry parameter. When provided, log_model stores models in the registry's databas
ExperimentTracking accepts an optional model_registry parameter. When provided,log_model stores models in the registry's database and schema instead of the experiment's, so experimentsDependencies: Support scikit-learn < 2, including 1.9.
Dependencies: Support scikit-learn < 2, including 1.9.
Feature Store: The Postgres-backed Online Feature Store (Public Preview) now supports feature views with
Iceberg-backed offline storage (StorageConfig(format=StorageFormat.ICEBERG)).
ML Jobs: runtime_environment version pins without a Python suffix now select an image matching the submitting
client's Python version. Pins with an explicit suffix, such as -py311, continue to select that Python version.
Dependencies: Support scikit-learn < 2, including 1.9.
Feature Store: The Postgres-backed Online Feature Store (Public Preview) now supports feature views with
Iceberg-backed offline storage (StorageConfig(format=StorageFormat.ICEBERG)).
ML Jobs: runtime_environment version pins without a Python suffix now select an image matching the submitting
client's Python version. Pins with an explicit suffix, such as -py311, continue to select that Python version.
ModelVersion.load() now compares the model owner to CURRENT_ROLE() (the role that
executes SQL) instead of Session.get_current_role(). Owner's-rights Streamlit apps and
EXECUTE AS OWNER procedures can load when statements run as the owner even if the caller's
primary role is not the owner.scipy is no longer a required dependency of snowflake-ml-python. It is still
installed transitively with pip install snowflake-ml-python[scikit-learn]. Direct scipy usage
in snowflake.ml.modeling.preprocessing already requires that extra.Experiment Tracking: Added ExperimentTracking.get_metric_history , which returns every logged step of a metric instead of only the value at the highes
Experiment Tracking: Added ExperimentTracking.get_metric_history, which returns every logged step of a
metric instead of only the value at the highest step reported by list_metrics. Pass a metric name to scope
the result to one metric, or omit it to get every metric of the run. The result is a lazy Snowpark DataFrame
with name, step, value, and timestamp columns, so filtering and aggregation run in Snowflake.
Feature Store: list_feature_views() now surfaces the online feature table's setup readiness in the
online_config JSON as setup_status, setup_error_msg and setup_time, for both batch/streaming
and realtime feature views. The keys are present only when setup-readiness information is available
for the table, so test for key presence. SETUP_NOTREADY means setup has not concluded yet, not
that setup failed; SETUP_FAILED is the failure signal. Note that SETUP_READY is also reported
when nothing has ever been reported for the table, and in that case setup_status may later change
to SETUP_FAILED.
mlflow.sklearn.save_model(). The model isRelease candidate for the snowflake-ml-python 2.0 major release. This is a breaking release that removes deprecated APIs and slims down the default in…
Release candidate for the snowflake-ml-python 2.0 major release. This is a breaking
release that removes deprecated APIs and slims down the default install footprint.
alter_online_service(size=...), which changes the size of an existing Online Service. Theget_online_service_status() until status is RUNNING at the requested size.delete_feature_view now drops the online feature table before thetarget_platforms now default to both Warehouse and Snowpark Container Services instead ofscikit-learn, xgboost, and shap are no longer required dependencies ofsnowflake-ml-python. They are now optional extras. Install them withpip install snowflake-ml-python[scikit-learn], [xgboost], [shap], or [all] when using[xgboost] and [lightgbm] installscikit-learn. Native XGBoost or LightGBM models (for example[xgboost] or [lightgbm].snowflake.ml.modeling estimators always require scikit-learn, so the XGBoost and LightGBMpip install "snowflake-ml-python[xgboost,scikit-learn]" or"snowflake-ml-python[lightgbm,scikit-learn]".feature_store extra. Install snowflake-ml-python[feature_store]httpx, which is required for online feature serving reads. httpx is not installed bysnowflake-ml-python install. Conda users still need to install httpx separatelyconda install httpx) to use the online Feature Store.snowflake.ml.modeling subpackage (for examplesnowflake.ml.modeling.linear_model, snowflake.ml.modeling.xgboost,snowflake.ml.modeling.lightgbm, or snowflake.ml.modeling.preprocessing) without the optionalImportError that names only the missingscikit-learn and xgboost are attributed to the 2.0 dependency change; lightgbm wassnowflake.ml.modeling estimators and preprocessing transformers are deprecated andsnowflake.ml.modeling subpackage now emits aDeprecationWarning. Train models with the native scikit-learn, XGBoost, or LightGBM estimatorssnowflake.ml.registry) instead.snowflake.ml.utils.connection_params.SnowflakeLoginOptions public APIModelVersion.run_batch now runs on EXECUTE INFERENCE JOB SERVICE. The singlejob_spec argument is replaced by the resources_spec, inference_spec, and image_build_specX) or an existing stage pathinput_stage_location). output_spec.stage_location is treated as a base: results are written<stage_location>/<job_name>/. output_spec.base_stage_location,job_spec.job_name_prefix, and job_spec.block no longer exist.snowflake.ml.model.batch module. Use snowflake.ml.model.batch_inference,BatchInferenceTask alongside the input, output, resources, inference, and imagelast_distinct_n orfirst_distinct_n aggregation function can no longer be read offline. generate_dataset,generate_training_set, retrieve_feature_values, and read_feature_view now raise aValueError for such feature views. Re-create the feature view to restore offline reads.snowflake-snowpark-python must now be >=1.37.0. Earlier releases importpkg_resources, which setuptools removed in 82.0.0, so they fail to import in environmentssetuptools.Registry: log_model(..., options={"case_sensitive": True}) and options={"max_batch_size": N} apply those settings to all methods. Per-method method_op
Registry: log_model(..., options={"case_sensitive": True}) and
options={"max_batch_size": N} apply those settings to all methods. Per-method
method_options still override the global values.
Feature Store: create_online_service accepts a size kwarg naming the size to provision the Online
Service at, one of "XS", "S", "M", "L", "XL", "2XL", "3XL" (case-insensitive). When
omitted, the server-side default applies; accounts that cap the available size provision at their
cap. get_online_service_status() now reports the provisioned size, which is None for services
created before sizes were recorded.
Experiment Tracking: Source provenance now also records the id of the enclosing ML job when a run is created from
inside one.
refresh_mode)refresh_mode.ModelVersion.load() failing with ValueError: ... is not a valid SQL identifierSQL compilation error: invalid value 'ADAPTIVE' for property 'REFRESH_MODE' when enabling online storage for an existingRegistry: log_model(..., options={"case_sensitive": True}) and
options={"max_batch_size": N} apply those settings to all methods. Per-method
method_options still override the global values.
Feature Store: create_online_service accepts a size kwarg naming the size to provision the Online
Service at, one of "XS", "S", "M", "L", "XL", "2XL", "3XL" (case-insensitive). When
omitted, the server-side default applies; accounts that cap the available size provision at their
cap. get_online_service_status() now reports the provisioned size, which is None for services
created before sizes were recorded.
Experiment Tracking: Source provenance now also records the id of the enclosing ML job when a run is created from inside one.
refresh_mode)
no longer fail to deserialize; unknown keys are ignored on read and the tag still does not persist
refresh_mode.ModelVersion.load() failing with ValueError: ... is not a valid SQL identifier
when the model's owner role is a quoted identifier.SQL compilation error: invalid value 'ADAPTIVE' for property 'REFRESH_MODE' when enabling online storage for an existing
feature view.UPDATING_SIZE). The service serves reads and writes throughout a size
change, which can take hours, so it is now treated as serviceable like UPDATING already was.ML Jobs: submit_file , submit_directory , and submit_from_stage accept a parallel kwarg (default False ). With parallel=True , the entrypoint is execu
ML Jobs: submit_file, submit_directory, and submit_from_stage accept a parallel kwarg (default False).
With parallel=True, the entrypoint is executed directly on every instance with the job topology injected into the
environment (SNOWFLAKE_JOB_INDEX, SNOWFLAKE_JOBS_COUNT, MLRS_HEAD_IP, MLRS_RDZV_PORT, MLRS_NODE_IPS).
Not supported for callable (@remote) payloads.
ML Jobs: added MLJob.distributed_result(), the result API for distributed (e.g. parallel=True) jobs, which
have no single head result. On full success it returns a DistributedResult (success, per-instance exit_codes,
failed_instance, and instance 0's return_value); if any instance failed it raises DistributedJobError, which
carries that DistributedResult as .result and the earliest-failing instance's reconstructed exception as its
cause. DistributedResult and DistributedJobError are exported from snowflake.ml.jobs.
ML Jobs: submit_file, submit_directory, and submit_from_stage accept a preflight kwarg, supported only
together with parallel=True. It takes the name of a check level, run on every instance before the entrypoint:
"wiring" checks the rendezvous plus a small collective, and "reference" additionally times a short synthetic
DDP step and reports its step times from instance 0. If a requested check fails, the job aborts without running
the entrypoint and the failure surfaces through distributed_result(). A check that does not apply to the job
("reference" on a CPU pool or a single instance) is reported as skipped and the job continues. Covers only the
PyTorch c10d rendezvous backend.
Feature Store: Iceberg-backed feature views can enable online storage when using the Postgres online store
(OnlineConfig(store_type=OnlineStoreType.POSTGRES)). Online storage with Iceberg remains unsupported for
other store types.
register_feature_view now records FV_SOURCE_REFS metadata for managed batchfeature_df schema) when the caller does not supplysource_refs. Streaming and realtime feature views are unaffected.1.52.0 New Features Bug Fixes Behavior Changes Deprecations
stream_ingest now reuses the Online Service ingest endpoint cached on the
StreamSource by get_stream_source, avoiding a per-call server status round-trip.ML Jobs: artifact_repositories now accepts a list of repositories, allowing multiple artifact repositories to be specified for a job.
artifact_repositories now accepts a list of repositories, allowing multiple artifacttarget_platforms=["SNOWPARK_CONTAINER_SERVICES"] could drop its pip dependencies, leaving the1.50.0 New Features Bug Fixes Behavior Changes Deprecations
Registry: Fixed a bug where logging a model with explainability enabled could fail with a data validation error ("There is no non-null data in column
Registry: Fixed a bug where logging a model with explainability enabled could fail with a data validation error
("There is no non-null data in column ...") when a numeric input column was entirely null within the background
sample. The explain method now reuses the model's existing input signature instead of re-inferring it from the
sample.
Feature Store: Fixed a bug where get_feature_view() could return stale metadata after re-registering a feature
view with overwrite=True. Metadata reads now select the most recently written row.
ExperimentTracking now captures best-effort source provenance (entry-point filename and any
surrounding git commit, branch, and remote URL) for each new run by default. Pass capture_source_info=False to
disable it. Collection is always non-fatal and never blocks run creation.ModelVersion.load() failing with Result for query <id> has expired inside Snowflake Container
Runtime notebooks. Model file downloads now use the session.file.get FileOperation API (the same mechanism used
when logging a model) instead of a raw GET query, avoiding a dependency on collect() result sets.Experiment Tracking: ExperimentTracking now captures best-effort source provenance (entry-point filename and any surrounding git commit, branch, and r
ExperimentTracking now captures best-effort source provenance (entry-point filename and anycapture_source_info=False toExperimentTracking now captures best-effort source provenance (entry-point filename and any
surrounding git commit, branch, and remote URL) for each new run by default. Pass capture_source_info=False to
disable it. Collection is always non-fatal and never blocks run creation.explain method now reuses the model's existing input signature instead of re-inferring it from the
sample.Experiment Tracking: Added ExperimentTracking.list_model_versions to retrieve the model versions that were logged under a run. Models logged via log_m
ExperimentTracking.list_model_versions to retrieve the model versions that werelog_model inside a run are linked to that run through Snowflake lineage,ModelVersion objects.from snowflake.ml.experiment import ExperimentTracking
exp = ExperimentTracking(session)
exp.set_experiment("MY_EXPERIMENT")
with exp.start_run(run_name="MY_RUN"):
exp.log_model(model, model_name="MY_MODEL", sample_input_data=X)
model_versions = exp.list_model_versions(run_name="MY_RUN").set_experiment does not recreate an experiment deleted in Snowsightenable_explainability now defaults to False for all model types when logging a model. Previously itTrue for XGBoost, LightGBM, and CatBoost models and was auto-enabled for supported scikit-learn andexplain method, explicitly passoptions={"enable_explainability": True} to log_model (this requires sample_input_data for supported modelRegistry: For Snowpark ML Pipeline models with explainability enabled, explanations now cover only the columns the final estimator was actually traine
input_cols). Untransformed passthrough columns (e.g. raw stringoutput_cols, or the label column) are no longer included in thelog_model(..., enable_explainability=True).Feature Store: FeatureView now supports an initialization_warehouse that is used for the initial build and any subsequent reinitializations of the bac
FeatureView now supports an initialization_warehouse that is used for the initial build and anywarehouseINITIALIZATION_WAREHOUSEupdate_feature_view(initialization_warehouse=...), and is surfaced by list_feature_views(verbose=True).draft_fv = FeatureView(
name="F_TRIP",
entities=[entity],
feature_df=feature_df,
refresh_freq="1d",
warehouse="SMALL_WH", # incremental refreshes
initialization_warehouse="LARGE_WH", # initial build / reinitialization
)
fv = fs.register_feature_view(draft_fv, version="1.0")response_format param matching the OpenAI Chat Completions API{"type": "json_schema", "json_schema": {"name": "...", "schema": {...}}}), letting callersfrom pydantic import BaseModel
import pandas as pd
class CityCountry(BaseModel):
city: str
country: str
response_format = {
"type": "json_schema",
"json_schema": {
"name": "city_country",
"schema": CityCountry.model_json_schema(),
},
}
x_df = pd.DataFrame.from_records(
[
{
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "What is the capital of France?"},
],
},
],
}
]
)
mv.run(
X=x_df,
params={"response_format": response_format},
service_name=...,
)1.44.0 New Features Bug Fixes Behavior Changes Deprecations
Registry: inference_engine_options["engine"] now accepts case-insensitive strings in addition to InferenceEngine enum members. Supported values are "v
inference_engine_options["engine"] now accepts case-insensitive strings in addition toInferenceEngine enum members. Supported values are "vllm" and "python_generic" (for example,"vLLM", "VLLM", and "PYTHON_GENERIC" are all accepted). This applies to ModelVersion.create_service()ModelVersion.run_batch().from snowflake.ml.registry import Registry
registry = Registry(session)
mv = registry.get_model("my_model").version("v1")
mv.create_service(
service_name="my_vllm_service",
service_compute_pool="GPU_COMPUTE_POOL",
gpu_requests="1",
inference_engine_options={
"engine": "vLLM",
"engine_args_override": ["--max-model-len=4096"],
},
)
job = mv.run_batch(
compute_pool="GPU_COMPUTE_POOL",
X=input_df,
output_spec=output_spec,
inference_engine_options={
"engine": "python_generic",
},
)explain() failing with type mismatch errors when passing a Snowpark DataFrame.explain) enforce stricter type coercion than scalar functionspredict), so columns that were implicitly coerced for predict would be rejected byexplain.SentenceTransformers models no longer hard-code a default inference batch size of 32.batch_size is not specified at log_model time and is not overridden at inference, thesentence-transformers library default is used. To pin a specific size, pass batch_size vialog_model(..., options={"batch_size": N}) or as an inference-time parameter. AllSentenceTransformers models logged with this release require a client/serving runtime on versionbatch_size was specified).Registry: Support truncate_dim for SentenceTransformers models. Truncation set at construction (SentenceTransformer(..., truncate_dim=N)) is captured
Registry: Support truncate_dim for SentenceTransformers models. Truncation set at
construction (SentenceTransformer(..., truncate_dim=N)) is captured when the model is logged
and restored on reload. On clients with sentence-transformers 5.0.0 or later, truncate_dim
is also exposed as a runtime parameter in the model signature.
Registry: log_model() now captures a representative row from sample_input_data and stores it alongside the model
so inference code snippets shown in the model registry UI can be pre-filled with realistic values. Pass
options={"capture_sample_input_data": False} to opt out (e.g., for sensitive data); generic placeholder values
will be used in the snippets instead.
transformers<5 for additional HuggingFace pipeline tasks removed in
transformers 5.x (summarization, text2text-generation, question-answering, and
translation_*), preventing deployment failures from missing pipeline classes.Registry: Extended ParamSpec support to MLflow PyFunc, LightGBM, XGBoost, and CatBoost models. Parameters declared in the model signature can now be p
ParamSpec support to MLflow PyFunc, LightGBM, XGBoost, and CatBoost models.
Parameters declared in the model signature can now be passed at inference time.Feature Store: get_feature_view() now correctly preserves online_config for feature views whose names require SQL quoting (mixed case or special chara
get_feature_view() now correctly preserves online_config for feature views whose
names require SQL quoting (mixed case or special characters such as a space). Previously the returned
FeatureView reported online=False even when online was enabled at registration, causing
read_feature_view(store_type=ONLINE) to fail with "Online store is not enabled".get_feature_view() now correctly preserves online_config for feature views whose
names require SQL quoting (mixed case or special characters such as a space). Previously the returned
FeatureView reported online=False even when online was enabled at registration, causing
read_feature_view(store_type=ONLINE) to fail with "Online store is not enabled".Registry: log_model(..., options=...) now rejects unknown top-level keys and unknown keys inside each
method_options entry (for example misspellings or options that belong to a different model framework).
Previously those keys were ignored. Validation is based on the public save-option TypedDicts and runs
before dependency reconciliation.
Registry: use_gpu is declared on the CatBoost, XGBoost, PyTorch, and TorchScript save-option
TypedDicts to match the save paths that already read this flag.
Feature Store: update_feature_view now correctly handles every transition between duration-based and CRON-based refresh_freq. Previously a CRON expres
update_feature_view now correctly handles every transition between duration-based
and CRON-based refresh_freq. Previously a CRON expression was forwarded to the Dynamic Table's
TARGET_LAG (which Snowflake rejects), duration → cron failed because the companion Task did not
yet exist, and cron → duration left the Task orphaned and continuing to fire on its old schedule.
All four (old, new) transitions now correctly create, alter, or drop the Task as needed, with
symmetric rollback on failure.Feature Store: For CRON-based feature views, get_feature_view(), list_feature_views(), and
register_feature_view() now return the original cron expression as refresh_freq instead of
"DOWNSTREAM". The underlying Dynamic Table still uses TARGET_LAG = 'DOWNSTREAM' with a companion
Task — this is purely a display change so the round-trip preserves what the user passed in.
Registry: When target_platforms includes WAREHOUSE and pip installs are needed without a user-supplied
pip artifact repository, log_model injects snowflake.snowpark.pypi_shared_repository after
verifying access. This applies to explicit pip_requirements and to pip-only packaging when there are
no user conda dependencies. If pypi_shared_repository is inaccessible in the pip-only case, automatic packaging
dependencies fall back to conda instead of forcing pip-only without an index.
Registry: For HuggingFace text-generation pipelines whose tokenizer defines a chat template, the auto-inferred signature now matches the OpenAI Chat C
Registry: For HuggingFace text-generation pipelines whose tokenizer defines a chat template, the
auto-inferred signature now matches the OpenAI Chat Completions API
(_OPENAI_CHAT_SIGNATURE_WITH_PARAMS_SPEC). Inputs are a single messages column and inference
controls (temperature, max_completion_tokens, stop, n, stream, top_p, frequency_penalty,
presence_penalty) move from inputs to params with default values. Predictions return the OpenAI
response shape (id, object, created, model, choices, usage); the generated text is at
choices[0].message.content instead of outputs[0].generated_text.
Registry: For HuggingFace image-text-to-text, video-text-to-text, and audio-text-to-text
pipelines, the auto-inferred signature now uses _OPENAI_CHAT_SIGNATURE_WITH_PARAMS_SPEC instead of
_OPENAI_CHAT_SIGNATURE_SPEC. The input column set narrows to just messages, and the inference
controls move to params with default values; the output schema is unchanged.
ParamSpecs,
allowing users to control inference behavior at prediction time via params. Generative tasks expose
GenerationConfig parameters (e.g. temperature, max_new_tokens, top_p); non-generative tasks expose
their own task-specific parameters (e.g. top_k for fill-mask, aggregation_strategy for
zero-shot-classification).Registry: For HuggingFace text-generation pipelines whose tokenizer defines a chat template, the
auto-inferred signature now matches the OpenAI Chat Completions API
(_OPENAI_CHAT_SIGNATURE_WITH_PARAMS_SPEC). Inputs are a single messages column and inference
controls (temperature, max_completion_tokens, stop, n, stream, top_p, frequency_penalty,
presence_penalty) move from inputs to params with default values. Predictions return the OpenAI
response shape (id, object, created, model, choices, usage); the generated text is at
choices[0].message.content instead of outputs[0].generated_text.
Registry: For HuggingFace image-text-to-text, video-text-to-text, and audio-text-to-text
pipelines, the auto-inferred signature now uses _OPENAI_CHAT_SIGNATURE_WITH_PARAMS_SPEC instead of
_OPENAI_CHAT_SIGNATURE_SPEC. The input column set narrows to just messages, and the inference
controls move to params with default values; the output schema is unchanged.
Experiment Tracking: end_run now accepts an optional status argument ("FINISHED" or "FAILED") to explicitly set the final run status. When a run's con
end_run now accepts an optional status argument ("FINISHED" or "FAILED") to explicitly
set the final run status. When a run's context manager exits with an exception, the status is automatically set to
"FAILED".Registry: Fixed log_model() failing for some Snowpark ML Pipeline models with explainability when the
full pipeline could not be converted to a native object; task inference now uses the final estimator instead.
Registry: run_batch() now raises a clear ValueError when a partitioned model's output signature
includes the partition column. Previously this produced duplicate columns in the output, causing
cryptic Ray/Arrow errors (AttributeError or KeyError) deep in the batch inference pipeline.
Registry (PrPr): The model_init_once save option now applies to TABLE_FUNCTION model methods (including
partitioned table functions) for warehouse deployments, in addition to scalar FUNCTION methods. The generated
handler uses the same eager @udf_init_once model load path as UDFs.
Experiment Tracking: end_run now accepts an optional status argument ("FINISHED" or "FAILED") to explicitly
set the final run status. When a run's context manager exits with an exception, the status is automatically set to
"FAILED".
Registry: Fixed log_model() failing for some Snowpark ML Pipeline models with explainability when the
full pipeline could not be converted to a native object; task inference now uses the final estimator instead.
Registry: run_batch() now raises a clear ValueError when a partitioned model's output signature
includes the partition column. Previously this produced duplicate columns in the output, causing
cryptic Ray/Arrow errors (AttributeError or KeyError) deep in the batch inference pipeline.
Feature Store: for latency-sensitive online feature view reads, set use_session_warehouse=True to re-use the warehouse from the current session and ac
transformers<5 when saving HuggingFace pipeline models that use tasks removed in
transformers 5.x (image-to-text, visual-question-answering, conversational), preventing
deployment failures from missing pipeline classes.pip_requirements and no artifact_repository_map now raises a ValueError
when target_platforms explicitly includes "WAREHOUSE". Previously this combination would silently proceed,
resulting in the warehouse deployment being silently dropped.Registry: Fixed ParamSpec.from_mlflow_spec dropping shape, which caused shaped scalar params (e.g., array of ints) from MLflow to fail validation duri
ParamSpec.from_mlflow_spec dropping shape, which caused shaped scalar params
(e.g., array of ints) from MLflow to fail validation during model import.spec_overrides now validates container keys and warns when keys other than name and secrets
are provided. Additional keys are not officially supported and may not behave as expected.Experiment Tracking: Added list_params and list_metrics methods to retrieve parameters and metrics for runs within an experiment. Both methods return
list_params and list_metrics methods to retrieve parameters and metrics
for runs within an experiment. Both methods return a Dataframe and accept an optional run_name argument
to filter to a specific run.generate_dataset()/generate_training_set() SQL generation for Unicode and case-sensitive
identifiers (for example Japanese column names), ensuring columns are quoted exactly once and preventing SQL
compilation errors such as unexpected '<column_name>'.enable_explainability=True is now allowed for SPCS-only and non-warehouse-runnable models. Previously
this raised a ValueError.Registry: Extended ParamSpec support to PyTorch models. Parameters declared in the model signature can now be passed at inference time, matching the e
ParamSpec support to PyTorch models. Parameters declared in the model signature
can now be passed at inference time, matching the existing support for custom models.model_init_once model save option to log_model. When set to True, the
model is loaded once per worker process at startup, eliminating model-loading overhead. Defaults to False.transformers upper bound to <6, adding compatibility with Hugging Face Transformers v5.with exp.start_run() block.create_service(block=True) where the log-streaming thread could outlive the
error handler when service deployment fails.This creates safetensors files instead of PyTorch binaries or pt files, addressing security vulnerability CVE-2025-32434.
ParamSpec support to scikit-learn models. Parameters declared in the model signature
can now be passed at inference time, matching the existing support for custom models.infer_signature() now accepts a dict for the params argument (e.g.,
params={"temperature": 0.7, "max_tokens": 100}), automatically inferring ParamSpec objects
from the Python value types. The existing Sequence[BaseParamSpec] form is still supported.huggingface.TransformersPipeline and transformers.Pipeline will default to safetensors
file format by default by using safe_serialization=True parameter to the save_pretrained call. This creates
safetensors files instead of PyTorch binaries or pt files, addressing security vulnerability CVE-2025-32434.Registry: Fixed custom model handler to explicitly persist PARTITIONED=False in model metadata for @inference_api methods. Previously, custom models u
PARTITIONED=False in model metadata for
@inference_api methods. Previously, custom models using @inference_api with TABLE_FUNCTION type
were incorrectly reported as partitioned.PARTITIONED=False metadata for
the explain method, preventing it from being incorrectly reported as partitioned at read time.infer_signature for columns containing NaN values. Previously,
the inferred dtype (DOUBLE vs INT64) depended on whether NaN rows survived truncation, causing
downstream validation failures. Now, the original pandas column dtype is respected during infer_signature,
so columns with mix of integer and np.nan or None are consistently inferred as DOUBLE regardless of NaN position.model.run(max_tokens="100") or model.run(some_int_param=True)).MLJobDefinition objects so they can be overwritten in place and invoked
repeatedly without job name collisions; the generate_suffix argument has been removed.Experiment Tracking live logging (PrPr): In SPCS, call set_live_logging_status(True) to automatically capture and persist outputs to stdout and stderr
set_live_logging_status(True) to automatically capture and
persist outputs to stdout and stderr while a run is active. The captured logs can be viewed from the Experiments UI.mlflow.*.save_model() to the Snowflake Model
Registry. Previously, only models logged through mlflow.*.log_model() were supported. This also
enables logging custom mlflow.pyfunc.PythonModel subclasses saved locally.predict method as partitioned, ensuring it
uses a partitioned TABLE_FUNCTION when deployed to Snowflake.text-generation models without chat template. The model will have signatures to automatically take
plain strings as input without needing to specify the signatures in log_model.
The signature can be overridden if the user chooses to.text-generation that do not have chat templates will be logged with signature
that supports plain text (string) as input.Model serving: Introducing InferenceEngine.PYTHON_GENERIC enum value. Users can pass InferenceEngine.PYTHON_GENERIC to use a Python-based inference se
InferenceEngine.PYTHON_GENERIC enum value.
Users can pass InferenceEngine.PYTHON_GENERIC to use a Python-based inference server for model serving.NameError.pd.StringDtype correctly.InferenceEngine.PYTHON_GENERIC enum value.
Users can pass InferenceEngine.PYTHON_GENERIC to use a Python-based inference server for model serving.NameError.pd.StringDtype correctly.snowflake.core as a runtime dependency. If you use snowflake.core (e.g.,
TaskDag, Root, Task), add snowflake.core explicitly to your dependencies.## 1.28.0 ### New Features ### Bug Fixes ### Behavior Changes ### Deprecations
Registry: Fixed a bug where model_version.run() required READ privilege on the model instead of USAGE, causing inference to fail for users with only U
Registry: Fixed a bug where model_version.run() required READ privilege on the model instead of
USAGE, causing inference to fail for users with only USAGE privilege granted (introduced in 1.21.0).
Feature Store: Fixed register_feature_view() with overwrite=True failing when changing between
external and managed feature views.
ML Job: Added support for creating MLJobDefinition (PrPr) and launching jobs with different arguments without re-uploading payloads.
MLJobDefinition (PrPr) and launching jobs with different
arguments without re-uploading payloads.# /path/to/repo/my_script.py
def main(*args):
print("Hello world", *args)
if __name__ == '__main__':
import sys
main(*sys.argv[1:])
from snowflake.ml.jobs.job_definition import MLJobDefinition
job_def = MLJobDefinition.register(
"/path/to/repo/my_script.py",
# If you register a source directory, provide the entrypoint file:
# entrypoint="/path/to/repo/my_script.py",
compute_pool= "test_comput_pool",
stage_name="payload_stage",
)
job1 = job_def()
job2 = job_def(arg1="ML Job")
from snowflake.ml import jobs
@jobs.remote(compute_pool = "test_compute_pool", stage_name = "payload_stage")
def test_job(arg1: str = "world") -> None:
print(f"hello {arg1}")
# this is a job definition handle
job_def_remote = test_job
job1 = job_def_remote()
job2 = job_def_remote(arg1="ML Job")
ModelVersion.run_batch for job-based batch inference in Snowpark Container
Services is now in public preview.from snowflake.ml.registry import Registry
from snowflake.ml.model import OutputSpec
registry = Registry(session)
mv = registry.log_model( ... )
job = mv.run_batch(
compute_pool = "SYSTEM_COMPUTE_POOL_GPU",
X=input_df,
output_spec=OutputSpec(stage_location="@my_db.my_schema.my_stage/output/"),
)
ParamSpec in model signatures. This allows you to define
constant parameters that can be passed at inference time without being part of the input data.import pandas as pd
from snowflake.ml.model import custom_model, model_signature
from snowflake.ml.registry import Registry
# Define a custom model with inference parameters
class MyModelWithParams(custom_model.CustomModel):
@custom_model.inference_api
def predict(
self,
input_df: pd.DataFrame,
*,
temperature: float = 1.0, # keyword-only param with default
) -> pd.DataFrame:
return pd.DataFrame({"output": input_df["feature"] * temperature})
# Create sample data
model = MyModelWithParams(custom_model.ModelContext())
sample_input = pd.DataFrame({"feature": [1.0, 2.0, 3.0]})
sample_output = model.predict(sample_input, temperature=1.0)
# Define ParamSpec for the inference parameter
params = [
model_signature.ParamSpec(
name="temperature",
dtype=model_signature.DataType.FLOAT,
default_value=1.0,
),
]
# Infer signature with params
sig = model_signature.infer_signature(
input_data=sample_input,
output_data=sample_output,
params=params,
)
# Log model with the signature
registry = Registry(session)
mv = registry.log_model(
model=model,
model_name="my_model_with_params",
version_name="v1",
signatures={"predict": sig},
)
# Run inference with custom parameter value
result = mv.run(sample_input, function_name="predict", params={"temperature": 2.0})
Feature Store: Added auto_prefix parameter and with_name() method to avoid column name collisions when
joining multiple feature views in dataset generation.
Feature Store: Added support for Dynamic Iceberg Tables as the backing storage for Feature Views.
Use StorageConfig with StorageFormat.ICEBERG to create Iceberg-backed Feature Views that store
data in open Apache Iceberg format on external cloud storage. A new default_iceberg_external_volume
parameter is available in FeatureStore to set a default external volume for Iceberg Feature Views.
ML Job: Reverted changes related to the introduction of ML Job Definitions.
ML Job: Added support for creating ML job definitions and launching jobs with different arguments without re-uploading payloads.
ML Job: Added support for creating ML job definitions and launching jobs with different arguments without re-uploading payloads.
Inference Autocapture (PuPr): The create_service API will now accept autocapture as a new argument to indicate
whether inference data will be captured.
Model serving: Introduced the min_instances field in the mv.create_service() and
HuggingFacePipelineModel.log_model_and_create_service() APIs (defaulting to 0). The service now launches
with the min_instances and automatically scales between min_instances and max_instances based on
traffic and hardware utilization. When min_instances is set to 0, the service will automatically suspend
if no traffic is detected for a period of time.
Inference Autocapture (PuPr): list_services() now shows autocapture_enabled column to indicate if model
service has autocapture enabled.
Model serving: The mv.create_service() and HuggingFacePipelineModel.log_model_and_create_service() APIs now
include a min_instances field (defaulting to 0). When these APIs are called without specifying min_instances,
the system will now launch the service with 1 instance and enable auto scaling. This replaces the previous behavior,
where min_instances was automatically set to match max_instances, resulting in the immediate launch of the
maximum number of instances.
Feature Store: Added tile-based aggregation support with a new Feature API for efficient and point-in-time correct time-series feature computation usi
Feature Store: Added tile-based aggregation support with a new Feature API for efficient and
point-in-time correct time-series feature computation using pre-computed tiles stored in Dynamic Tables.
Registry: Added auto-signature inference for SentenceTransformer models. When logging a SentenceTransformer
model, sample_input_data is now optional. If not provided, the signature is automatically inferred from
the model's embedding dimension. Supported methods: encode, encode_query, encode_document,
encode_queries, encode_documents.
import sentence_transformers
from snowflake.ml.registry import Registry
# Create model
model = sentence_transformers.SentenceTransformer("all-MiniLM-L6-v2")
# Log model without sample_input_data - signature is auto-inferred
registry = Registry(session)
mv = registry.log_model(
model=model,
model_name="my_sentence_transformer",
version_name="v1",
)
# Run inference with auto-inferred signature (input: "text", output: "output")
import pandas as pd
result = mv.run(pd.DataFrame({"text": ["Hello world"]}))
ML Jobs: Enabled support for Python 3.11 and Python 3.12 by default. Jobs will automatically select a runtime environment matching the client Python v
Registry: Introducing remotely logging a transformer pipeline model using SPCS job.
# create reference of the model
model = huggingface.TransformersPipeline(
model="TinyLlama/TinyLlama-1.1B-Chat-v1.0",
task="text-generation",
)
# Remotely log the model, a SPCS job will run async and log the model
mv = registry.log_model(
model=model,
model_name="tinyllama_remote_log",
target_platforms=["SNOWPARK_CONTAINER_SERVICES"],
signatures=openai_signatures.OPENAI_CHAT_SIGNATURE,
)
# create reference of the model
model = huggingface.TransformersPipeline(
model="TinyLlama/TinyLlama-1.1B-Chat-v1.0",
task="text-generation",
)
# Remotely log the model, a SPCS job will run async and log the model
mv = registry.log_model(
model=model,
model_name="tinyllama_remote_log",
target_platforms=["SNOWPARK_CONTAINER_SERVICES"],
signatures=openai_signatures.OPENAI_CHAT_SIGNATURE,
)
Registry: Added support for image-text-to-text task type in huggingface.TransformersPipeline.
Note: Requires vLLM inference engine while creating the service.
ML Job: Added support for custom command entrypoints. The entrypoint parameter now accepts a
list[str] (e.g., ["arctic_training", "run_causal.yml"]), which is executed directly as a
command rather than being treated as a Python script.
openai_signatures.OPENAI_CHAT_SIGNATURE signature now handles content parts and
requires input data to be passed in list of dictionary. To use string content (previous behavior),
use openai_signatures.OPENAI_CHAT_SIGNATURE_WITH_CONTENT_FORMAT_STRING.from snowflake.ml.model import openai_signatures
import pandas as pd
mv = snowflake_registry.log_model(
model=generator,
model_name=...,
...,
signatures=openai_signatures.OPENAI_CHAT_SIGNATURE,
)
# create a pd.DataFrame with openai.client.chat.completions arguments like below:
x_df = pd.DataFrame.from_records(
[
{
"messages": [
{
"role": "system",
"content": [
{
"type": "text",
"text": "Complete the sentence."
},
]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "A descendant of the Lost City of Atlantis, who swam to Earth while saying, ",
}
],
},
],
"max_completion_tokens": 250,
"temperature": 0.9,
"stop": None,
"n": 3,
"stream": False,
"top_p": 1.0,
"frequency_penalty": 0.1,
"presence_penalty": 0.2,
}
],
)
# OpenAI Chat Completion compatible output
output_df = mv.run(X=x_df)
Deprecating snowflake.ml.model.models.huggingface_pipeline.HuggingfacePipelineModel and will be removed in later version with a notice.
create_service API will now accept autocapture as a new argument to indicate
whether inference data will be captured.to_huggingface_dataset() method for converting Snowflake data to HuggingFace datasets.
Supports both in-memory Dataset (streaming=False) and streaming IterableDataset (streaming=True) modes.snowflake.ml.model.models.huggingface.TransformersPipeline model which will replace object
snowflake.ml.model.models.huggingface_pipeline.HuggingfacePipelineModel. This is a wrapper class to
transformers.Pipeline model. Currently, following tasks
are supported to log without manually specifying model signatures:
log_metrics or log_params will warn the user
instead of raising an exception.ModelVersion.run() will now raise a ValueError if the model does not support running on warehouse
(e.g. SPCS-only models) and service_name is not provided.additional_payloads (Preview API) behavior is changing.
Use the imports argument to declare additional dependencies, such as zip files and Python modules.
Local directories and Python files are automatically compressed, and their internal layout is determined by the
specified import path. The import path applies only to local directories, Python files and staged python files;
it has no effect on other import types. When referencing files in a stage, only individual files
are supported—not directories.list_services() now shows internal endpoint that does not need EAI to call from another
SPCS node or Notebook.list_services() now shows if model service has autocapture enabled.ExperimentTracking is now a singleton class.snowflake.ml.model.models.huggingface_pipeline.HuggingfacePipelineModel and will be removed in later
version with a notice.Experiment Tracking (PuPr): Reaching the run metadata size limit in log_metrics or log_params will warn the user instead of raising an exception.
log_metrics or log_params will warn the user
instead of raising an exception.create_service API will now
accept inference_engine_options as an argument.from snowflake.ml.model.inference_engine import InferenceEngine
mv = snowflake_registry.log_model(
model=generator,
model_name=...,
...,
# Specifying OPENAI_CHAT_SIGNATURE is necessary to use vLLM inference engine
signatures=openai_signatures.OPENAI_CHAT_SIGNATURE,
)
mv.create_service(
service_name=my_serv,
service_compute_pool=...,
...,
inference_engine_options={
"engine": InferenceEngine.VLLM,
"engine_args_override": [
"--max-model-len=2048",
"--gpu-memory-utilization=0.9"
]
}
)
Experiment Tracking (PrPr): No longer throw an exception in list_artifacts when run does not have artifacts.
list_artifacts when run does not have artifacts.get_version_by_alias: now requires an exact match of snowflake identifier.snowflake.ml.experiment) is in public preview.Registry: The create_service API now validates that a model has a GPU runtime configuration and will throw a descriptive error if the configuration is
ModelVersion.run_batch for batch inference in Snowpark Container Services.version_name argument to the autologging callbacks
to specify the version name for the autologged model.Python 3.9 is deprecated.ML Job: Added support for retrieving details of deleted jobs, including status, compute pool, and target instances.
MLJob.result() API with broader cross-version
compatibility and support for additional data types, namely:
snowflake-ml-python>=1.17.0 to be installed inside remote container environment.MLRS_USE_SUBMIT_JOB_V2 to falseRegistry: Remove redundant pip dependency warnings when artifact_repository_map is provided for warehouse model deployments.
artifact_repository_map is provided for warehouse model deployments.runtime_environment
(image tag or full image URL) at submission time.
Examples:
Volatility.VOLATILE or Volatility.IMMUTABLE.from snowflake.ml.model.volatility import Volatility
options = {
"embed_local_ml_library": True,
"relax_version": True,
"save_location": "/path/to/my/directory",
"function_type": "TABLE_FUNCTION",
"volatility": Volatility.IMMUTABLE,
"method_options": {
"predict": {
"case_sensitive": False,
"max_batch_size": 100,
"function_type": "TABLE_FUNCTION",
"volatility": Volatility.VOLATILE,
},
}
Registry: Dropping support for deprecated conversational task type for Huggingface models. To read more
conversational task type for Huggingface models.
To read more https://github.com/huggingface/transformers/pull/31165ML Job: The additional_payloads argument is now deprecated in favor of imports.
additional_payloads argument is now deprecated in favor of imports.Registry: Log a HuggingFace model without having to load the model in memory using the huggingface_pipeline.HuggingFacePipelineModel. Requires hugging
huggingface_pipeline.HuggingFacePipelineModel. Requires huggingface_hub package to installed.
To disable downloading HuggingFace repository, provide download_snapshot=False while creating the
huggingface_pipeline.HuggingFacePipelineModel object.enable_categorical=True with pandas DataFrameRegistry: Fixed an issue where the string representation of dictionary-type output columns was being incorrectly created during structured output dese
text-generation models.from snowflake.ml.model import openai_signatures
import pandas as pd
mv = snowflake_registry.log_model(
model=generator,
model_name=...,
...,
signatures=openai_signatures.OPENAI_CHAT_SIGNATURE,
)
# create a pd.DataFrame with openai.client.chat.completions arguments like below:
x_df = pd.DataFrame.from_records(
[
{
"messages": [
{"role": "system", "content": "Complete the sentence."},
{
"role": "user",
"content": "A descendant of the Lost City of Atlantis, who swam to Earth while saying, ",
},
],
"max_completion_tokens": 250,
"temperature": 0.9,
"stop": None,
"n": 3,
"stream": False,
"top_p": 1.0,
"frequency_penalty": 0.1,
"presence_penalty": 0.2,
}
],
)
# OpenAI Chat Completion compatible output
output_df = mv.run(X=x_df)
segment_columns parameter to ModelMonitorSourceConfig to specify columns for segmenting monitoring dataadd_segment_column(): Add a new segment column to an existing monitordrop_segment_column(): Remove a segment column from an existing monitorlog_artifactlist_artifactsdownload_artifactsML Job: Fix Error: Unable to retrieve head IP address if not all instances start within the timeout.
Error: Unable to retrieve head IP address if not all instances start within the timeout.TypeError: SnowflakeCursor.execute() got an unexpected keyword argument '_force_qmark_paramstyle'
when running inside Stored Procedures.ModelVersion.create_service(): Made image_repo argument optional. By
default it will use a default image repo, which is
being rolled out in server version 9.22+.snowflake.ml.experiment.callback.keras.SnowflakeKerasCallback.Registry: add progress bars for ModelVersion.create_service and ModelVersion.log_model.
ModelVersion.create_service and ModelVersion.log_model.ModelVersion.create_service will be written to a file. The file location
will be shown in the console.snowflake.ml.experiment.callback.xgboost.SnowflakeXgboostCallback and
snowflake.ml.experiment.callback.lightgbm.SnowflakeLightgbmCallback.ModelVersion.create_service and ModelVersion.log_model.ModelVersion.create_service will be written to a file. The file location
will be shown in the console.DataConnector: Fix self._session related errors inside Container Runtime.
self._session related errors inside Container Runtime.None to array (pd.dtype('O')) in signature and pandas data handler.from snowflake.ml.experiment import ExperimentTracking
from snowflake.ml.experiment.callback import SnowflakeXgboostCallback, SnowflakeLightgbmCallback
exp = ExperimentTracking(session=sp_session, database_name="ML", schema_name="PUBLIC")
exp.set_experiment("MY_EXPERIMENT")
# XGBoost
callback = SnowflakeXgboostCallback(
exp, log_model=True, log_metrics=True, log_params=True, model_name="model_name", model_signature=sig
)
model = XGBClassifier(callbacks=[callback])
with exp.start_run():
model.fit(X, y, eval_set=[(X_test, y_test)])
# LightGBM
callback = SnowflakeLightgbmCallback(
exp, log_model=True, log_metrics=True, log_params=True, model_name="model_name", model_signature=sig
)
model = LGBMClassifier()
with exp.start_run():
model.fit(X, y, eval_set=[(X_test, y_test)], callbacks=[callback])
Registry: Fix a bug when trying to set the PAD token the HuggingFace text-generation model had multiple EOS tokens. The handler picks the first EOS to
text-generation model had multiple EOS tokens.
The handler picks the first EOS token as PAD token now.create_service function in snowflake/ml/model/models/huggingface_pipeline.py
which creates a service to log a HF model and upon successful logging, an inference service is created.from snowflake.ml.model.models import huggingface_pipeline
hf_model_ref = huggingface_pipeline.HuggingFacePipelineModel(
model="gpt2",
task="text-generation", # Optional
)
hf_model_ref.create_service(
session=session,
service_name="test_service",
service_compute_pool="test_compute_pool",
image_repo="test_repo",
...
)
from snowflake.ml.experiment import ExperimentTracking
exp = ExperimentTracking(session=sp_session, database_name="ML", schema_name="PUBLIC")
exp.set_experiment("MY_EXPERIMENT")
with exp.start_run():
exp.log_param("batch_size", 32)
exp.log_metrics("accuracy", 0.98, step=10)
exp.log_model(my_model, model_name="MY_MODEL")
Registry: Fixed bug causing snowpark to pandas dataframe conversion to fail when QUOTED_IDENTIFIERS_IGNORE_CASE parameter is enabled
QUOTED_IDENTIFIERS_IGNORE_CASE
parameter is enabledlist_jobs() API has been modified. The scope parameter has been removed,
optional database and schema parameters have been added, the return type has changed
from snowpark.DataFrame to pandas.DataFrame, and the returned columns have been updated
to name, status, message, database_name, schema_name, owner, compute_pool,
target_instances, created_time, and completed_time.relax_version to false when pip_requirements are specified while logging modeltarget_platforms supports TargetPlatformMode: WAREHOUSE_ONLY, SNOWPARK_CONTAINER_SERVICES_ONLY,
or BOTH_WAREHOUSE_AND_SNOWPARK_CONTAINER_SERVICES.snowflake.ml.model.target_platform.TargetPlatform, target platform constants, and
snowflake.ml.model.task.Task.**kwargslist_jobs() behavior changed, see Behavior Changes for more infoQUOTED_IDENTIFIERS_IGNORE_CASE
parameter is enabled{% for message in messages %}
{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}
{% endfor %}
{% if add_generation_prompt %}
{{ '<|im_start|>assistant\n' }}
{% endif %}"
list_jobs() API has been modified. The scope parameter has been removed,
optional database and schema parameters have been added, the return type has changed
from snowpark.DataFrame to pandas.DataFrame, and the returned columns have been updated
to name, status, message, database_name, schema_name, owner, compute_pool,
target_instances, created_time, and completed_time.relax_version to false when pip_requirements are specified while logging modeltarget_platforms supports TargetPlatformMode: WAREHOUSE_ONLY, SNOWPARK_CONTAINER_SERVICES_ONLY,
or BOTH_WAREHOUSE_AND_SNOWPARK_CONTAINER_SERVICES.snowflake.ml.model.target_platform.TargetPlatform, target platform constants, and
snowflake.ml.model.task.Task.**kwargslist_jobs() behavior changed, see Behavior Changes for more infoRegistry: Add service container info to logs.
submit_from_stage() API for submitting a payload from an existing stage path.snowpark.Session objects in the argument list of
@remote decorated functions. Session object will be injected from context in
the job execution environment.Registry: Fixed a bug when listing and deleting container services.
num_instances to target_instances in job submission APIs and
change type from Optional[int] to intmin_instances argument to the job decorator to allow waiting for workers to be ready.SnowflakeLoginOptions is deprecated and will be removed in a future release.Registry: Add custom_model.partitioned_api decorator and deprecate partitioned_inference_api.
enable_explainability to True when the model can be deployed to Warehouse.custom_model.partitioned_api decorator and deprecate partitioned_inference_api.UnboundLocalError: local variable 'multiple_inputs' referenced before assignment.id to be fully qualified name; Introduced new property name to represent the ML Job namelist_jobs() to return ML Job name instead of idlog_model if enable_explainability is True and model is only deployed to
Snowpark Container Services, instead of just user warning.@remote function decorator, submit_file() and submit_directory() to accept database and
schema parametersget_job()snowflake.ml.monitoring to plot explanations in notebooks.xgboost.DMatrix inputs.Registry: Default to the runtime cuda version if available when logging a GPU model in Container Runtime.
as_list argument to MLJob.get_logs() to enable retrieving logs
as a list of stringsModelVersion.run_job to run inference with a single-node Snowpark Container Services job.as_list argument to MLJob.get_logs() to enable retrieving logs
as a list of stringsModelVersion.run_job to run inference with a single-node Snowpark Container Services job.ML Job now available as a PuPr feature
@remote decorated functions using
new MLJobWithResult.result() API, which will return the unpickled result
or raise an exception if the job execution failed.snowflake.snowpark.context.get_active_session()save_location to log_model using the options argument.
User's can provide the path to write the model version's files that get stored in Snowflake's stage.reg.log_model(
model=...,
model_name=...,
version_name=...,
...,
options={"save_location": "./model_directory"},
)
instance_id argument to get_logs and show_logs method to support multi node log retrievaljob.get_instance_status(instance_id=...) API to support multi node status retrieval@remote decorated functions using
new MLJobWithResult.result() API, which will return the unpickled result
or raise an exception if the job execution failed.snowflake.snowpark.context.get_active_session()save_location to log_model using the options argument.
Users can use the save_location option to specify a local directory where the model files and configuration are written.
This is useful when the default temporary directory has space limitations.reg.log_model(
model=...,
model_name=...,
version_name=...,
...,
options={"save_location": "./model_directory"},
)
instance_id argument to get_logs and show_logs method to support multi node log retrievaljob.get_instance_status(instance_id=...) API to support multi node status retrievalRegistry: Fix a bug that caused unsupported model type error while logging a sklearn model with score_samples inference method.
unsupported model type error while logging a sklearn model with score_samples
inference method.1.0.1enable_metrics argument to job submission APIs to enable publishing service metrics to Event Table.
See Accessing Event Table service metrics
for retrieving published metrics
and Costs of telemetry data collection
for cost implications.ModelVersion with log_model, raise an exception if unsupported arguments are provided.Modeling: Fix a bug in some metrics that allowed an unsupported version of numpy to be installed automatically in the stored procedure, resulting in a
Model is does not have _is_inference_api error message when assigning
a supported model as a property of a CustomModel.Registry: With FeatureGroupSpec support, auto inferred model signature for transformers.Pipeline models have been
updated, including:
Signature for fill-mask task has been changed from
ModelSignature(
inputs=[
FeatureSpec(name="inputs", dtype=DataType.STRING),
],
outputs=[
FeatureSpec(name="outputs", dtype=DataType.STRING),
],
)
to
ModelSignature(
inputs=[
FeatureSpec(name="inputs", dtype=DataType.STRING),
],
outputs=[
FeatureGroupSpec(
name="outputs",
specs=[
FeatureSpec(name="sequence", dtype=DataType.STRING),
FeatureSpec(name="score", dtype=DataType.DOUBLE),
FeatureSpec(name="token", dtype=DataType.INT64),
FeatureSpec(name="token_str", dtype=DataType.STRING),
],
shape=(-1,),
),
],
)
Signature for token-classification task has been changed from
ModelSignature(
inputs=[
FeatureSpec(name="inputs", dtype=DataType.STRING),
],
outputs=[
FeatureSpec(name="outputs", dtype=DataType.STRING),
],
)
to
ModelSignature(
inputs=[FeatureSpec(name="inputs", dtype=DataType.STRING)],
outputs=[
FeatureGroupSpec(
name="outputs",
specs=[
FeatureSpec(name="word", dtype=DataType.STRING),
FeatureSpec(name="score", dtype=DataType.DOUBLE),
FeatureSpec(name="entity", dtype=DataType.STRING),
FeatureSpec(name="index", dtype=DataType.INT64),
FeatureSpec(name="start", dtype=DataType.INT64),
FeatureSpec(name="end", dtype=DataType.INT64),
],
shape=(-1,),
),
],
)
Signature for question-answering task when top_k is larger than 1 has been changed from
ModelSignature(
inputs=[
FeatureSpec(name="question", dtype=DataType.STRING),
FeatureSpec(name="context", dtype=DataType.STRING),
],
outputs=[
FeatureSpec(name="outputs", dtype=DataType.STRING),
],
)
to
ModelSignature(
inputs=[
FeatureSpec(name="question", dtype=DataType.STRING),
FeatureSpec(name="context", dtype=DataType.STRING),
],
outputs=[
FeatureGroupSpec(
name="answers",
specs=[
FeatureSpec(name="score", dtype=DataType.DOUBLE),
FeatureSpec(name="start", dtype=DataType.INT64),
FeatureSpec(name="end", dtype=DataType.INT64),
FeatureSpec(name="answer", dtype=DataType.STRING),
],
shape=(-1,),
),
],
)
Signature for text-classification task when top_k is None has been changed from
ModelSignature(
inputs=[
FeatureSpec(name="text", dtype=DataType.STRING),
FeatureSpec(name="text_pair", dtype=DataType.STRING),
],
outputs=[
FeatureSpec(name="label", dtype=DataType.STRING),
FeatureSpec(name="score", dtype=DataType.DOUBLE),
],
)
to
ModelSignature(
inputs=[
FeatureSpec(name="text", dtype=DataType.STRING),
],
outputs=[
FeatureSpec(name="label", dtype=DataType.STRING),
FeatureSpec(name="score", dtype=DataType.DOUBLE),
],
)
Signature for text-classification task when top_k is not None has been changed from
ModelSignature(
inputs=[
FeatureSpec(name="text", dtype=DataType.STRING),
FeatureSpec(name="text_pair", dtype=DataType.STRING),
],
outputs=[
FeatureSpec(name="outputs", dtype=DataType.STRING),
],
)
to
ModelSignature(
inputs=[
FeatureSpec(name="text", dtype=DataType.STRING),
],
outputs=[
FeatureGroupSpec(
name="labels",
specs=[
FeatureSpec(name="label", dtype=DataType.STRING),
FeatureSpec(name="score", dtype=DataType.DOUBLE),
],
shape=(-1,),
),
],
)
Signature for text-generation task has been changed from
ModelSignature(
inputs=[FeatureSpec(name="inputs", dtype=DataType.STRING)],
outputs=[
FeatureSpec(name="outputs", dtype=DataType.STRING),
],
)
to
ModelSignature(
inputs=[
FeatureGroupSpec(
name="inputs",
specs=[
FeatureSpec(name="role", dtype=DataType.STRING),
FeatureSpec(name="content", dtype=DataType.STRING),
],
shape=(-1,),
),
],
outputs=[
FeatureGroupSpec(
name="outputs",
specs=[
FeatureSpec(name="generated_text", dtype=DataType.STRING),
],
shape=(-1,),
)
],
)
Registry: PyTorch and TensorFlow models now expect a single tensor input/output by default when logging to Model
Registry. To use multiple tensors (previous behavior), set options={"multiple_inputs": True}.
Example with single tensor input:
import torch
class TorchModel(torch.nn.Module):
def __init__(self, n_input: int, n_hidden: int, n_out: int, dtype: torch.dtype = torch.float32) -> None:
super().__init__()
self.model = torch.nn.Sequential(
torch.nn.Linear(n_input, n_hidden, dtype=dtype),
torch.nn.ReLU(),
torch.nn.Linear(n_hidden, n_out, dtype=dtype),
torch.nn.Sigmoid(),
)
def forward(self, tensor: torch.Tensor) -> torch.Tensor:
return cast(torch.Tensor, self.model(tensor))
# Sample usage:
data_x = torch.rand(size=(batch_size, n_input))
# Log model with single tensor
reg.log_model(
model=model,
...,
sample_input_data=data_x
)
# Run inference with single tensor
mv.run(data_x)
For multiple tensor inputs/outputs, use:
reg.log_model(
model=model,
...,
sample_input_data=[data_x_1, data_x_2],
options={"multiple_inputs": True}
)
Registry: Default enable_explainability to False when the model can be deployed to Snowpark Container Services.
torch.Tensor, tensorflow.Tensor and tensorflow.Variable as input or output
data.xgboost.DMatrix
datatype for XGBoost models.Your coding agent can read these notes before it upgrades. Set up the MCP server →