diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b5701b1..8bd71e29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,31 @@ # Release History -## 1.6.0 +## 1.6.1 (TBD) + +### Bug Fixes + +- Feature Store: Support large metadata blob when generating dataset +- Feature Store: Added a hidden knob in FeatureView as kargs for setting customized + refresh_mode +- Registry: Fix an error message in Model Version `run` when `function_name` is not mentioned and model has multiple + target methods. +- Cortex inference: snowflake.cortex.Complete now only uses the REST API for streaming and the use_rest_api_experimental + is no longer needed. +- Feature Store: Add a new API: FeatureView.list_columns() which list all column information. +- Data: Fix `DataFrame` ingestion with `ArrowIngestor`. + +### New Features + +- Enable `set_params` to set the parameters of the underlying sklearn estimator, if the snowflake-ml model has been fit. +- Data: Add top-level exports for `DataConnector` and `DataSource` to `snowflake.ml.data`. +- Data: Add `snowflake.ml.data.ingestor_utils` module with utility functions helpful for `DataIngestor` implementations. +- Data: Add new `to_torch_dataset()` connector to `DataConnector` to replace deprecated DataPipe. +- Registry: Option to `enable_explainability` set to True by default for XGBoost, LightGBM and CatBoost as PuPr feature. +- Registry: Option to `enable_explainability` when registering SHAP supported sklearn models. + +### Behavior Changes + +## 1.6.0 (2024-07-29) ### Bug Fixes @@ -29,6 +54,14 @@ distributed_hpo_trainer.ENABLE_EFFICIENT_MEMORY_USAGE = False ` - Registry: Option to `enable_explainability` when registering LightGBM models as a pre-PuPr feature. +- Data: Add new `snowflake.ml.data` preview module which contains data reading utilities like `DataConnector` + - `DataConnector` provides efficient connectors from Snowpark `DataFrame` + and Snowpark ML `Dataset` to external frameworks like PyTorch, TensorFlow, and Pandas. Create `DataConnector` + instances using the classmethod constructors `DataConnector.from_dataset()` and `DataConnector.from_dataframe()`. +- Data: Add new `DataConnector.from_sources()` classmethod constructor for constructing from `DataSource` objects. +- Data: Add new `ingestor_class` arg to `DataConnector` classmethod constructors for easier `DataIngestor` injection. +- Dataset: `DatasetReader` now subclasses new `DataConnector` class. + - Add optional `limit` arg to `DatasetReader.to_pandas()` ### Behavior Changes diff --git a/bazel/py_rules.bzl b/bazel/py_rules.bzl index 72283696..3a61b3e6 100644 --- a/bazel/py_rules.bzl +++ b/bazel/py_rules.bzl @@ -256,6 +256,7 @@ def _py_wheel_impl(ctx): ctx.file.pyproject_toml.path, execution_root_relative_path, "--wheel", + "--sdist", "--outdir", wheel_output_dir.path, ], diff --git a/ci/conda_recipe/meta.yaml b/ci/conda_recipe/meta.yaml index c20c56bb..7d2f84c3 100644 --- a/ci/conda_recipe/meta.yaml +++ b/ci/conda_recipe/meta.yaml @@ -17,7 +17,7 @@ build: noarch: python package: name: snowflake-ml-python - version: 1.6.0 + version: 1.6.1 requirements: build: - python diff --git a/ci/targets/quarantine/prod3.txt b/ci/targets/quarantine/prod3.txt index 29980980..a4b6155a 100644 --- a/ci/targets/quarantine/prod3.txt +++ b/ci/targets/quarantine/prod3.txt @@ -2,3 +2,4 @@ //tests/integ/snowflake/ml/registry:model_registry_snowservice_integ_test //tests/integ/snowflake/ml/model:spcs_llm_model_integ_test //tests/integ/snowflake/ml/extra_tests:xgboost_external_memory_training_test +//tests/integ/snowflake/ml/registry:model_registry_snowservice_merge_gate_integ_test diff --git a/codegen/build_file_autogen.py b/codegen/build_file_autogen.py index 41e5839d..402b014f 100644 --- a/codegen/build_file_autogen.py +++ b/codegen/build_file_autogen.py @@ -14,7 +14,7 @@ from absl import app from codegen import sklearn_wrapper_autogen as swa -from snowflake.ml._internal.snowpark_pandassnowpark_pandas import imports +from snowflake.ml._internal.snowpark_pandas import imports @dataclass(frozen=True) diff --git a/snowflake/cortex/_complete.py b/snowflake/cortex/_complete.py index ec2d9b04..bc9f6d82 100644 --- a/snowflake/cortex/_complete.py +++ b/snowflake/cortex/_complete.py @@ -90,7 +90,6 @@ def _call_complete_rest( prompt: Union[str, List[ConversationMessage]], options: Optional[CompleteOptions] = None, session: Optional[snowpark.Session] = None, - stream: bool = False, ) -> requests.Response: session = session or context.get_active_session() if session is None: @@ -121,7 +120,7 @@ def _call_complete_rest( data = { "model": model, - "stream": stream, + "stream": True, } if isinstance(prompt, List): data["messages"] = prompt @@ -137,32 +136,15 @@ def _call_complete_rest( if "top_p" in options: data["top_p"] = options["top_p"] - logger.debug(f"making POST request to {url} (model={model}, stream={stream})") + logger.debug(f"making POST request to {url} (model={model})") return requests.post( url, json=data, headers=headers, - stream=stream, + stream=True, ) -def _process_rest_response( - response: requests.Response, - stream: bool = False, - deadline: Optional[float] = None, -) -> Union[str, Iterator[str]]: - if stream: - return _return_stream_response(response, deadline) - - try: - content = response.json()["choices"][0]["message"]["content"] - assert isinstance(content, str) - return content - except (KeyError, IndexError, AssertionError) as e: - # Unlike the streaming case, errors are not ignored because a message must be returned. - raise ResponseParseException("Failed to parse message from response.") from e - - def _return_stream_response(response: requests.Response, deadline: Optional[float]) -> Iterator[str]: client = SSEClient(response) for event in client.events(): @@ -243,7 +225,6 @@ def _complete_impl( prompt: Union[str, List[ConversationMessage], snowpark.Column], options: Optional[CompleteOptions] = None, session: Optional[snowpark.Session] = None, - use_rest_api_experimental: bool = False, stream: bool = False, function: str = "snowflake.cortex.complete", timeout: Optional[float] = None, @@ -253,16 +234,14 @@ def _complete_impl( raise ValueError('only one of "timeout" and "deadline" must be set') if timeout is not None: deadline = time.time() + timeout - if use_rest_api_experimental: + if stream: if not isinstance(model, str): raise ValueError("in REST mode, 'model' must be a string") if not isinstance(prompt, str) and not isinstance(prompt, List): raise ValueError("in REST mode, 'prompt' must be a string or a list of ConversationMessage") - response = _call_complete_rest(model, prompt, options, session=session, stream=stream, deadline=deadline) + response = _call_complete_rest(model, prompt, options, session=session, deadline=deadline) assert response.status_code >= 200 and response.status_code < 300 - return _process_rest_response(response, stream=stream) - if stream is True: - raise ValueError("streaming can only be enabled in REST mode, set use_rest_api_experimental=True") + return _return_stream_response(response, deadline) return _complete_sql_impl(function, model, prompt, options, session) @@ -275,7 +254,6 @@ def Complete( *, options: Optional[CompleteOptions] = None, session: Optional[snowpark.Session] = None, - use_rest_api_experimental: bool = False, stream: bool = False, timeout: Optional[float] = None, deadline: Optional[float] = None, @@ -287,16 +265,13 @@ def Complete( prompt: A Column of prompts to send to the LLM. options: A instance of snowflake.cortex.CompleteOptions session: The snowpark session to use. Will be inferred by context if not specified. - use_rest_api_experimental (bool): Toggles between the use of SQL and REST implementation. This feature is - experimental and can be removed at any time. stream (bool): Enables streaming. When enabled, a generator function is returned that provides the streaming output as it is received. Each update is a string containing the new text content since the previous update. - The use of streaming requires the experimental use_rest_api_experimental flag to be enabled. timeout (float): Timeout in seconds to retry failed REST requests. deadline (float): Time in seconds since the epoch (as returned by time.time()) to retry failed REST requests. Raises: - ValueError: If `stream` is set to True and `use_rest_api_experimental` is set to False. + ValueError: incorrect argument. Returns: A column of string responses. @@ -307,7 +282,6 @@ def Complete( prompt, options=options, session=session, - use_rest_api_experimental=use_rest_api_experimental, stream=stream, timeout=timeout, deadline=deadline, diff --git a/snowflake/cortex/complete_test.py b/snowflake/cortex/complete_test.py index bf868581..84d40430 100644 --- a/snowflake/cortex/complete_test.py +++ b/snowflake/cortex/complete_test.py @@ -10,7 +10,6 @@ from typing import Dict, Iterable, Iterator, List, cast import _test_util -import requests from absl.testing import absltest from requests.exceptions import HTTPError @@ -111,14 +110,6 @@ def test_complete_snowpark_mode(self) -> None: res = df_out.collect()[0][0] self.assertEqual(self.complete_for_test(self.model, self.prompt), res) - def test_stream_in_sql_mode(self) -> None: - self.assertRaises( - ValueError, - lambda: _complete._complete_impl( - self.model, self.prompt, session=self._session, function="complete", stream=True - ), - ) - class CompleteOptionsSQLBackendTest(absltest.TestCase): model = "|model|" @@ -270,28 +261,8 @@ def tearDown(self) -> None: self.server.shutdown() self.server_thread.join() - def test_non_streaming(self) -> None: - result = _complete._complete_impl( - model="my_models", prompt="test_prompt", session=self.session, stream=False, use_rest_api_experimental=True - ) - self.assertEqual("This is a non streaming response", result) - - def test_wrong_token(self) -> None: - headers = {"Authorization": "Wrong Token=123"} - data = {"stream": "hh"} - - # Send the POST request - response = requests.post( - f"http://127.0.0.1:{self.server.server_address[1]}/api/v2/cortex/inference:complete", - headers=headers, - json=data, - ) - self.assertEqual(response.status_code, 401) - def test_streaming(self) -> None: - result = _complete._complete_impl( - model="my_models", prompt="test_prompt", session=self.session, stream=True, use_rest_api_experimental=True - ) + result = _complete._complete_impl(model="my_models", prompt="test_prompt", session=self.session, stream=True) self.assertIsInstance(result, GeneratorType) output = "".join(list(cast(Iterable[str], result))) self.assertEqual("This is a streaming response", output) @@ -303,45 +274,22 @@ def test_streaming_with_options(self) -> None: options=_OPTIONS, session=self.session, stream=True, - use_rest_api_experimental=True, ) self.assertIsInstance(result, GeneratorType) output = "".join(list(cast(Iterable[str], result))) self.assertEqual("This is a streaming response", output) - def test_non_streaming_with_options(self) -> None: - result = _complete._complete_impl( - model="my_models", - prompt="test_prompt", - options=_OPTIONS, - session=self.session, - stream=False, - use_rest_api_experimental=True, - ) - self.assertEqual("This is a non streaming response", result) - - def test_non_streaming_with_empty_options(self) -> None: + def test_streaming_with_empty_options(self) -> None: result = _complete._complete_impl( model="my_models", prompt="test_prompt", options=_complete.CompleteOptions(), session=self.session, - stream=False, - use_rest_api_experimental=True, - ) - self.assertEqual("This is a non streaming response", result) - - def test_non_streaming_unexpected_response_format(self) -> None: - self.assertRaises( - _complete.ResponseParseException, - lambda: _complete._complete_impl( - model=_UNEXPECTED_RESPONSE_FORMAT_MODEL_NAME, - prompt="test_prompt", - session=self.session, - stream=False, - use_rest_api_experimental=True, - ), + stream=True, ) + self.assertIsInstance(result, GeneratorType) + output = "".join(list(cast(Iterable[str], result))) + self.assertEqual("This is a streaming response", output) def test_streaming_unexpected_response_format(self) -> None: response = _complete._complete_impl( @@ -349,7 +297,6 @@ def test_streaming_unexpected_response_format(self) -> None: prompt="test_prompt", session=self.session, stream=True, - use_rest_api_experimental=True, ) assert isinstance(response, Iterator) message = "" @@ -357,19 +304,6 @@ def test_streaming_unexpected_response_format(self) -> None: message += part self.assertEqual("msg", message) - def test_non_streaming_error(self) -> None: - try: - _complete._complete_impl( - model=_MISSING_MODEL_NAME, - prompt="test_prompt", - session=self.session, - stream=False, - use_rest_api_experimental=True, - ) - except HTTPError as e: - self.assertEqual(400, e.response.status_code) - self.assertEqual(_MISSING_MODEL_RESPONSE, e.response.text) - def test_streaming_error(self) -> None: try: _complete._complete_impl( @@ -377,25 +311,11 @@ def test_streaming_error(self) -> None: prompt="test_prompt", session=self.session, stream=True, - use_rest_api_experimental=True, ) except HTTPError as e: self.assertEqual(400, e.response.status_code) self.assertEqual(_MISSING_MODEL_RESPONSE, e.response.text) - def test_non_streaming_timeout(self) -> None: - self.assertRaises( - TimeoutError, - lambda: _complete._complete_impl( - model=_RETRY_FOREVER_MODEL_NAME, - prompt="test_prompt", - session=self.session, - stream=False, - use_rest_api_experimental=True, - timeout=1, - ), - ) - def test_streaming_timeout(self) -> None: self.assertRaises( TimeoutError, @@ -404,7 +324,6 @@ def test_streaming_timeout(self) -> None: prompt="test_prompt", session=self.session, stream=True, - use_rest_api_experimental=True, timeout=1, ), ) @@ -417,41 +336,21 @@ def test_deadline(self) -> None: prompt="test_prompt", session=self.session, stream=True, - use_rest_api_experimental=True, deadline=time.time() + 1, ), ) - def test_non_streaming_retry_until_success(self) -> None: - result = _complete._complete_impl( - model=retry_until_model_name(time.time() + 1), - prompt="test_prompt", - session=self.session, - use_rest_api_experimental=True, - stream=False, - ) - self.assertEqual("This is a non streaming response", result) - def test_streaming_retry_until_success(self) -> None: result = _complete._complete_impl( model=retry_until_model_name(time.time() + 1), prompt="test_prompt", session=self.session, - use_rest_api_experimental=True, stream=True, ) self.assertIsInstance(result, GeneratorType) output = "".join(list(cast(Iterable[str], result))) self.assertEqual("This is a streaming response", output) - def test_column_in_rest_mode(self) -> None: - self.assertRaises( - ValueError, - lambda: _complete._complete_impl( - model="my_models", prompt=functions.col("prompt"), session=self.session, use_rest_api_experimental=True - ), - ) - if __name__ == "__main__": absltest.main() diff --git a/snowflake/ml/_internal/env_utils.py b/snowflake/ml/_internal/env_utils.py index 709d863c..7b3edf32 100644 --- a/snowflake/ml/_internal/env_utils.py +++ b/snowflake/ml/_internal/env_utils.py @@ -27,7 +27,6 @@ class CONDA_OS(Enum): NO_ARCH = "noarch" -_SNOWFLAKE_CONDA_CHANNEL_URL = "https://repo.anaconda.com/pkgs/snowflake" _NODEFAULTS = "nodefaults" _SNOWFLAKE_INFO_SCHEMA_PACKAGE_CACHE: Dict[str, List[version.Version]] = {} _SNOWFLAKE_CONDA_PACKAGE_CACHE: Dict[str, List[version.Version]] = {} @@ -36,6 +35,7 @@ class CONDA_OS(Enum): DEFAULT_CHANNEL_NAME = "" SNOWML_SPROC_ENV = "IN_SNOWML_SPROC" SNOWPARK_ML_PKG_NAME = "snowflake-ml-python" +SNOWFLAKE_CONDA_CHANNEL_URL = "https://repo.anaconda.com/pkgs/snowflake" def _validate_pip_requirement_string(req_str: str) -> requirements.Requirement: @@ -370,7 +370,7 @@ def get_matched_package_versions_in_snowflake_conda_channel( assert not snowpark_utils.is_in_stored_procedure() # type: ignore[no-untyped-call] - url = f"{_SNOWFLAKE_CONDA_CHANNEL_URL}/{conda_os.value}/repodata.json" + url = f"{SNOWFLAKE_CONDA_CHANNEL_URL}/{conda_os.value}/repodata.json" if req.name not in _SNOWFLAKE_CONDA_PACKAGE_CACHE: try: @@ -477,6 +477,7 @@ def save_conda_env_file( path: pathlib.Path, conda_chan_deps: DefaultDict[str, List[requirements.Requirement]], python_version: str, + default_channel_override: str = SNOWFLAKE_CONDA_CHANNEL_URL, ) -> None: """Generate conda.yml file given a dict of dependencies after validation. The channels part of conda.yml file will contains Snowflake Anaconda Channel, nodefaults and all channel names @@ -489,6 +490,7 @@ def save_conda_env_file( path: Path to the conda.yml file. conda_chan_deps: Dict of conda dependencies after validated. python_version: A string 'major.minor' showing python version relate to model. + default_channel_override: The default channel to be put in the first place of the channels section. """ assert path.suffix in [".yml", ".yaml"], "Conda environment file should have extension of yml or yaml." path.parent.mkdir(parents=True, exist_ok=True) @@ -499,7 +501,11 @@ def save_conda_env_file( channels = list(dict(sorted(conda_chan_deps.items(), key=lambda item: len(item[1]), reverse=True)).keys()) if DEFAULT_CHANNEL_NAME in channels: channels.remove(DEFAULT_CHANNEL_NAME) - env["channels"] = [_SNOWFLAKE_CONDA_CHANNEL_URL] + channels + [_NODEFAULTS] + + if default_channel_override in channels: + channels.remove(default_channel_override) + + env["channels"] = [default_channel_override] + channels + [_NODEFAULTS] env["dependencies"] = [f"python=={python_version}.*"] for chan, reqs in conda_chan_deps.items(): env["dependencies"].extend( @@ -567,8 +573,8 @@ def load_conda_env_file( python_version = None channels = env.get("channels", []) - if _SNOWFLAKE_CONDA_CHANNEL_URL in channels: - channels.remove(_SNOWFLAKE_CONDA_CHANNEL_URL) + if len(channels) >= 1: + channels = channels[1:] # Skip the first channel which is the default channel if _NODEFAULTS in channels: channels.remove(_NODEFAULTS) diff --git a/snowflake/ml/_internal/env_utils_test.py b/snowflake/ml/_internal/env_utils_test.py index f69ec27b..2ac7b698 100644 --- a/snowflake/ml/_internal/env_utils_test.py +++ b/snowflake/ml/_internal/env_utils_test.py @@ -831,6 +831,16 @@ def test_conda_env_file(self) -> None: loaded_cd, _, _ = env_utils.load_conda_env_file(env_file_path) self.assertEqual(cd, loaded_cd) + with tempfile.TemporaryDirectory() as tmpdir: + cd = collections.defaultdict(list) + cd[env_utils.DEFAULT_CHANNEL_NAME] = [requirements.Requirement("numpy>=1.22.4")] + env_file_path = pathlib.Path(tmpdir, "conda.yml") + env_utils.save_conda_env_file( + env_file_path, cd, python_version="3.8", default_channel_override="conda-forge" + ) + loaded_cd, _, _ = env_utils.load_conda_env_file(env_file_path) + self.assertEqual(cd, loaded_cd) + with tempfile.TemporaryDirectory() as tmpdir: cd = collections.defaultdict(list) cd.update( @@ -873,6 +883,37 @@ def test_conda_env_file(self) -> None: self.assertEqual(cd, loaded_cd) self.assertIsNone(pip_reqs) + with tempfile.TemporaryDirectory() as tmpdir: + cd = collections.defaultdict(list) + cd.update( + { + env_utils.DEFAULT_CHANNEL_NAME: [requirements.Requirement("numpy>=1.22.4")], + "apple": [], + "conda-forge": [requirements.Requirement("pytorch!=2.0")], + } + ) + env_file_path = pathlib.Path(tmpdir, "conda.yml") + env_utils.save_conda_env_file( + env_file_path, cd, python_version="3.8", default_channel_override="conda-forge" + ) + with open(env_file_path, encoding="utf-8") as f: + written_yaml = yaml.safe_load(f) + self.assertDictEqual( + written_yaml, + { + "name": "snow-env", + "channels": ["conda-forge", "apple", "nodefaults"], + "dependencies": [ + "python==3.8.*", + "numpy>=1.22.4", + "conda-forge::pytorch!=2.0", + ], + }, + ) + loaded_cd, pip_reqs, _ = env_utils.load_conda_env_file(env_file_path) + self.assertEqual(cd, loaded_cd) + self.assertIsNone(pip_reqs) + with tempfile.TemporaryDirectory() as tmpdir: env_file_path = pathlib.Path(tmpdir, "conda.yml") with open(env_file_path, "w", encoding="utf-8") as f: @@ -953,6 +994,34 @@ def test_conda_env_file(self) -> None: self.assertListEqual(pip_reqs, [requirements.Requirement("python-package")]) self.assertEqual(python_ver, "3.8") + with tempfile.TemporaryDirectory() as tmpdir: + env_file_path = pathlib.Path(tmpdir, "conda.yml") + with open(env_file_path, "w", encoding="utf-8") as f: + yaml.safe_dump( + stream=f, + data={ + "name": "snow-env", + "channels": ["conda-forge", "apple", "nodefaults"], + "dependencies": [ + "python=3.8", + "::numpy>=1.22.4", + "conda-forge::pytorch!=2.0", + {"pip": ["python-package"]}, + ], + }, + ) + loaded_cd, pip_reqs, python_ver = env_utils.load_conda_env_file(env_file_path) + self.assertEqual( + { + env_utils.DEFAULT_CHANNEL_NAME: [requirements.Requirement("numpy>=1.22.4")], + "conda-forge": [requirements.Requirement("pytorch!=2.0")], + "apple": [], + }, + loaded_cd, + ) + self.assertListEqual(pip_reqs, [requirements.Requirement("python-package")]) + self.assertEqual(python_ver, "3.8") + def test_generate_requirements_file(self) -> None: with tempfile.TemporaryDirectory() as tmpdir: rl: List[requirements.Requirement] = [] diff --git a/snowflake/ml/_internal/exceptions/modeling_error_messages.py b/snowflake/ml/_internal/exceptions/modeling_error_messages.py index affdc6d5..f75165be 100644 --- a/snowflake/ml/_internal/exceptions/modeling_error_messages.py +++ b/snowflake/ml/_internal/exceptions/modeling_error_messages.py @@ -4,7 +4,10 @@ "-differences." ) SIZE_MISMATCH = "Size mismatch: {}={}, {}={}." -INVALID_MODEL_PARAM = "Invalid parameter {} for model {}. Valid parameters: {}." +INVALID_MODEL_PARAM = ( + "Invalid parameter {} for model {}. Valid parameters: {}." + "Note: Scikit learn params cannot be set until the model has been fit." +) UNSUPPORTED_MODEL_CONVERSION = "Object doesn't support {}. Please use {}." INCOMPATIBLE_NEW_SKLEARN_PARAM = "Incompatible scikit-learn version: {} requires scikit-learn>={}. Installed: {}." REMOVED_SKLEARN_PARAM = "Incompatible scikit-learn version: {} is removed in scikit-learn>={}. Installed: {}." diff --git a/snowflake/ml/_internal/lineage/lineage_utils_test.py b/snowflake/ml/_internal/lineage/lineage_utils_test.py index 67d94fae..119bcc24 100644 --- a/snowflake/ml/_internal/lineage/lineage_utils_test.py +++ b/snowflake/ml/_internal/lineage/lineage_utils_test.py @@ -69,7 +69,7 @@ def setUp(self) -> None: # ), ) def test_get_data_sources( - self, args: List[TestSourcedObject], expected: Optional[List[data_source.DataSource]] + self, args: List[TestSourcedObject], expected: Optional[List[data_source.DatasetInfo]] ) -> None: self.assertEqual(expected, lineage_utils.get_data_sources(*args)) diff --git a/snowflake/ml/_internal/telemetry.py b/snowflake/ml/_internal/telemetry.py index b4321960..93e951a8 100644 --- a/snowflake/ml/_internal/telemetry.py +++ b/snowflake/ml/_internal/telemetry.py @@ -44,6 +44,20 @@ _ReturnValue = TypeVar("_ReturnValue") +@enum.unique +class TelemetryProject(enum.Enum): + MLOPS = "MLOps" + MODELING = "ModelDevelopment" + # TODO: Update with remaining projects. + + +@enum.unique +class TelemetrySubProject(enum.Enum): + MONITORING = "Monitoring" + REGISTRY = "ModelManagement" + # TODO: Update with remaining subprojects. + + @enum.unique class TelemetryField(enum.Enum): # constants diff --git a/snowflake/ml/_internal/utils/pkg_version_utils.py b/snowflake/ml/_internal/utils/pkg_version_utils.py index 99efb0a0..8112feb7 100644 --- a/snowflake/ml/_internal/utils/pkg_version_utils.py +++ b/snowflake/ml/_internal/utils/pkg_version_utils.py @@ -26,30 +26,11 @@ def get_valid_pkg_versions_supported_in_snowflake_conda_channel( pkg_versions: List[str], session: Session, subproject: Optional[str] = None ) -> List[str]: if snowpark_utils.is_in_stored_procedure(): # type: ignore[no-untyped-call] - return _get_valid_pkg_versions_supported_in_snowflake_conda_channel_sync(pkg_versions, session, subproject) + return pkg_versions else: return _get_valid_pkg_versions_supported_in_snowflake_conda_channel_async(pkg_versions, session, subproject) -def _get_valid_pkg_versions_supported_in_snowflake_conda_channel_sync( - pkg_versions: List[str], session: Session, subproject: Optional[str] = None -) -> List[str]: - for pkg_version in pkg_versions: - if pkg_version not in cache: - pkg_version_list = _query_pkg_version_supported_in_snowflake_conda_channel( - pkg_version=pkg_version, session=session, block=True, subproject=subproject - ) - assert isinstance(pkg_version_list, list) # keep mypy happy - try: - cache[pkg_version] = pkg_version_list[0]["VERSION"] - except IndexError: - cache[pkg_version] = None - - pkg_version_conda_list = _get_conda_packages_and_emit_warnings(pkg_versions) - - return pkg_version_conda_list - - def _get_valid_pkg_versions_supported_in_snowflake_conda_channel_async( pkg_versions: List[str], session: Session, subproject: Optional[str] = None ) -> List[str]: @@ -60,7 +41,11 @@ def _get_valid_pkg_versions_supported_in_snowflake_conda_channel_async( async_job = _query_pkg_version_supported_in_snowflake_conda_channel( pkg_version=pkg_version, session=session, block=False, subproject=subproject ) - assert isinstance(async_job, AsyncJob) + if isinstance(async_job, list): + raise RuntimeError( + "Async job was expected, executed query was returned. Please contact Snowflake support." + ) + pkg_version_async_job_list.append((pkg_version, async_job)) # Populate the cache. @@ -143,7 +128,8 @@ def _get_conda_packages_and_emit_warnings(pkg_versions: List[str]) -> List[str]: warnings.warn( f"Package {', '.join([pkg[0] for pkg in pkg_version_warning_list])} is not supported " f"in snowflake conda channel for python runtime " - f"{', '.join([pkg[1] for pkg in pkg_version_warning_list])}." + f"{', '.join([pkg[1] for pkg in pkg_version_warning_list])}.", + stacklevel=1, ) return pkg_version_conda_list diff --git a/snowflake/ml/_internal/utils/pkg_version_utils_test.py b/snowflake/ml/_internal/utils/pkg_version_utils_test.py index ed762e1f..d770690b 100644 --- a/snowflake/ml/_internal/utils/pkg_version_utils_test.py +++ b/snowflake/ml/_internal/utils/pkg_version_utils_test.py @@ -12,6 +12,7 @@ class PackageVersionUtilsTest(absltest.TestCase): + @mock.patch.dict(pkg_version_utils.cache, {}) def test_happy_case_async(self) -> None: pkg_name = "xgboost" major_version, minor_version, micro_version = 1, 7, 3 @@ -53,41 +54,17 @@ def test_happy_case_async(self) -> None: @mock.patch("snowflake.ml._internal.utils.pkg_version_utils.snowpark_utils.is_in_stored_procedure") def test_happy_case(self, mock_is_in_stored_procedure: mock.Mock) -> None: mock_is_in_stored_procedure.return_value = True - pkg_name = "xgboost" - major_version, minor_version, micro_version = 1, 7, 3 - query = f""" - SELECT PACKAGE_NAME, VERSION, LANGUAGE - FROM ( - SELECT *, - SUBSTRING(VERSION, LEN(VERSION) - CHARINDEX('.', REVERSE(VERSION)) + 2, LEN(VERSION)) as micro_version - FROM information_schema.packages - WHERE package_name = '{pkg_name}' - AND version LIKE '{major_version}.{minor_version}.%' - ORDER BY abs({micro_version}-micro_version), -micro_version - ) - """ m_session = mock_session.MockSession(conn=None, test_case=self) - m_session.add_mock_sql( - query=query, - result=mock_data_frame.MockDataFrame( - collect_result=[Row(PACKAGE_NAME="xgboost", VERSION="1.7.3", LANGUAGE="python")], - columns=["PACKAGE_NAME", "VERSION", "LANGUAGE"], - collect_block=True, - ), - ) c_session = cast(session.Session, m_session) # Test - pkg_version_utils.get_valid_pkg_versions_supported_in_snowflake_conda_channel( - pkg_versions=["xgboost==1.7.3"], session=c_session - ) - - # Test subsequent calls are served through cache. - pkg_version_utils.get_valid_pkg_versions_supported_in_snowflake_conda_channel( + valid_pkg_versions = pkg_version_utils.get_valid_pkg_versions_supported_in_snowflake_conda_channel( pkg_versions=["xgboost==1.7.3"], session=c_session ) + self.assertEqual(valid_pkg_versions, ["xgboost==1.7.3"]) + @mock.patch.dict(pkg_version_utils.cache, {}) def test_happy_case_with_runtime_version_column_async(self) -> None: pkg_name = "xgboost" major_version, minor_version, micro_version = 1, 7, 3 @@ -108,45 +85,23 @@ def test_happy_case_with_runtime_version_column_async(self) -> None: columns=["PACKAGE_NAME", "VERSION", "LANGUAGE", "RUNTIME_VERSION"], collect_block=False ) mock_df = mock_df.add_mock_filter( - expr=f"RUNTIME_VERSION = {_RUNTIME_VERSION}", result=mock_data_frame.MockDataFrame(count_result=1) - ) - m_session.add_mock_sql(query=query, result=mock_df) - c_session = cast(session.Session, m_session) - - # Test - pkg_version_utils.get_valid_pkg_versions_supported_in_snowflake_conda_channel( - pkg_versions=["xgboost==1.7.3"], session=c_session - ) - - # Test subsequent calls are served through cache. - pkg_version_utils.get_valid_pkg_versions_supported_in_snowflake_conda_channel( - pkg_versions=["xgboost==1.7.3"], session=c_session + expr=f"RUNTIME_VERSION = {_RUNTIME_VERSION}", + result=mock_data_frame.MockDataFrame( + collect_result=mock_data_frame.MockAsyncJob( + result=[ + Row( + PACKAGE_NAME="xgboost", + VERSION="1.7.3", + LANGUAGE="python", + RUNTIME_VERSION=_RUNTIME_VERSION, + ) + ] + ), + columns=["PACKAGE_NAME", "VERSION", "LANGUAGE", "RUNTIME_VERSION"], + collect_block=False, + ), ) - @mock.patch("snowflake.ml._internal.utils.pkg_version_utils.snowpark_utils.is_in_stored_procedure") - def test_happy_case_with_runtime_version_column(self, mock_is_in_stored_procedure: mock.Mock) -> None: - mock_is_in_stored_procedure.return_value = True - pkg_name = "xgboost" - major_version, minor_version, micro_version = 1, 7, 3 - query = f""" - SELECT PACKAGE_NAME, VERSION, LANGUAGE - FROM ( - SELECT *, - SUBSTRING(VERSION, LEN(VERSION) - CHARINDEX('.', REVERSE(VERSION)) + 2, LEN(VERSION)) as micro_version - FROM information_schema.packages - WHERE package_name = '{pkg_name}' - AND version LIKE '{major_version}.{minor_version}.%' - ORDER BY abs({micro_version}-micro_version), -micro_version - ) - """ - - m_session = mock_session.MockSession(conn=None, test_case=self) - mock_df = mock_data_frame.MockDataFrame( - columns=["PACKAGE_NAME", "VERSION", "LANGUAGE", "RUNTIME_VERSION"], collect_block=True - ) - mock_df = mock_df.add_mock_filter( - expr=f"RUNTIME_VERSION = {_RUNTIME_VERSION}", result=mock_data_frame.MockDataFrame(count_result=1) - ) m_session.add_mock_sql(query=query, result=mock_df) c_session = cast(session.Session, m_session) @@ -198,44 +153,6 @@ def test_unsupported_version_async(self) -> None: pkg_versions=["xgboost==1.0.0"], session=c_session ) - @mock.patch("snowflake.ml._internal.utils.pkg_version_utils.snowpark_utils.is_in_stored_procedure") - def test_unsupported_version(self, mock_is_in_stored_procedure: mock.Mock) -> None: - mock_is_in_stored_procedure.return_value = True - pkg_name = "xgboost" - major_version, minor_version, micro_version = 1, 0, 0 - query = f""" - SELECT PACKAGE_NAME, VERSION, LANGUAGE - FROM ( - SELECT *, - SUBSTRING(VERSION, LEN(VERSION) - CHARINDEX('.', REVERSE(VERSION)) + 2, LEN(VERSION)) as micro_version - FROM information_schema.packages - WHERE package_name = '{pkg_name}' - AND version LIKE '{major_version}.{minor_version}.%' - ORDER BY abs({micro_version}-micro_version), -micro_version - ) - """ - - m_session = mock_session.MockSession(conn=None, test_case=self) - m_session.add_mock_sql( - query=query, - result=mock_data_frame.MockDataFrame( - collect_result=[], columns=["PACKAGE_NAME", "VERSION", "LANGUAGE"], collect_block=True - ), - ) - c_session = cast(session.Session, m_session) - - # Test - with self.assertRaises(RuntimeError): - pkg_version_utils.get_valid_pkg_versions_supported_in_snowflake_conda_channel( - pkg_versions=["xgboost==1.0.0"], session=c_session - ) - - # Test subsequent calls are served through cache. - with self.assertRaises(RuntimeError): - pkg_version_utils.get_valid_pkg_versions_supported_in_snowflake_conda_channel( - pkg_versions=["xgboost==1.0.0"], session=c_session - ) - def test_unsupported_version_with_runtime_version_column_async(self) -> None: query = """SELECT PACKAGE_NAME, VERSION, LANGUAGE FROM ( @@ -269,41 +186,6 @@ def test_unsupported_version_with_runtime_version_column_async(self) -> None: pkg_versions=["xgboost==1.0.0"], session=c_session ) - @mock.patch("snowflake.ml._internal.utils.pkg_version_utils.snowpark_utils.is_in_stored_procedure") - def test_unsupported_version_with_runtime_version_column(self, mock_is_in_stored_procedure: mock.Mock) -> None: - mock_is_in_stored_procedure.return_value = True - query = """SELECT PACKAGE_NAME, VERSION, LANGUAGE - FROM ( - SELECT *, - SUBSTRING(VERSION, LEN(VERSION) - CHARINDEX('.', REVERSE(VERSION)) + 2, LEN(VERSION)) as micro_version - FROM information_schema.packages - WHERE package_name = 'xgboost' - AND version LIKE '1.0.%' - ORDER BY abs(0-micro_version), -micro_version - )""" - - m_session = mock_session.MockSession(conn=None, test_case=self) - mock_df = mock_data_frame.MockDataFrame( - columns=["PACKAGE_NAME", "VERSION", "LANGUAGE", "RUNTIME_VERSION"], collect_block=True - ) - mock_df.add_mock_filter( - expr=f"RUNTIME_VERSION = {_RUNTIME_VERSION}", result=mock_data_frame.MockDataFrame(count_result=0) - ) - m_session.add_mock_sql(query=query, result=mock_df) - c_session = cast(session.Session, m_session) - - # Test - with self.assertRaises(RuntimeError): - pkg_version_utils.get_valid_pkg_versions_supported_in_snowflake_conda_channel( - pkg_versions=["xgboost==1.0.0"], session=c_session - ) - - # Test subsequent calls are served through cache. - with self.assertRaises(RuntimeError): - pkg_version_utils.get_valid_pkg_versions_supported_in_snowflake_conda_channel( - pkg_versions=["xgboost==1.0.0"], session=c_session - ) - def test_invalid_package_name(self) -> None: m_session = mock_session.MockSession(conn=None, test_case=self) c_session = cast(session.Session, m_session) diff --git a/snowflake/ml/data/BUILD.bazel b/snowflake/ml/data/BUILD.bazel index 8757bad8..e71ce8f9 100644 --- a/snowflake/ml/data/BUILD.bazel +++ b/snowflake/ml/data/BUILD.bazel @@ -15,11 +15,26 @@ py_library( ], ) +py_library( + name = "ingestor_utils", + srcs = ["ingestor_utils.py"], + deps = [ + ":data_source", + "//snowflake/ml/fileset:snowfs", + ], +) + +py_library( + name = "torch_dataset", + srcs = ["torch_dataset.py"], +) + py_library( name = "data_connector", srcs = ["data_connector.py"], deps = [ ":data_ingestor", + ":torch_dataset", "//snowflake/ml/_internal:telemetry", "//snowflake/ml/data/_internal:arrow_ingestor", ], @@ -33,3 +48,12 @@ py_test( "//snowflake/ml/fileset:parquet_test_util", ], ) + +py_library( + name = "data", + srcs = ["__init__.py"], + deps = [ + ":data_connector", + ":data_source", + ], +) diff --git a/snowflake/ml/data/__init__.py b/snowflake/ml/data/__init__.py index e69de29b..ff099fd0 100644 --- a/snowflake/ml/data/__init__.py +++ b/snowflake/ml/data/__init__.py @@ -0,0 +1,5 @@ +from .data_connector import DataConnector +from .data_ingestor import DataIngestor, DataIngestorType +from .data_source import DataFrameInfo, DatasetInfo, DataSource + +__all__ = ["DataConnector", "DataSource", "DataFrameInfo", "DatasetInfo", "DataIngestor", "DataIngestorType"] diff --git a/snowflake/ml/data/_internal/BUILD.bazel b/snowflake/ml/data/_internal/BUILD.bazel index c7ce4e74..82895d85 100644 --- a/snowflake/ml/data/_internal/BUILD.bazel +++ b/snowflake/ml/data/_internal/BUILD.bazel @@ -2,20 +2,12 @@ load("//bazel:py_rules.bzl", "py_library", "py_test") package(default_visibility = ["//visibility:public"]) -py_library( - name = "ingestor_utils", - srcs = ["ingestor_utils.py"], - deps = [ - "//snowflake/ml/fileset:snowfs", - ], -) - py_library( name = "arrow_ingestor", srcs = ["arrow_ingestor.py"], deps = [ - ":ingestor_utils", "//snowflake/ml/data:data_ingestor", + "//snowflake/ml/data:ingestor_utils", ], ) diff --git a/snowflake/ml/data/_internal/arrow_ingestor.py b/snowflake/ml/data/_internal/arrow_ingestor.py index 520c5e6a..a6edebe8 100644 --- a/snowflake/ml/data/_internal/arrow_ingestor.py +++ b/snowflake/ml/data/_internal/arrow_ingestor.py @@ -2,17 +2,17 @@ import logging import os import time -from typing import Any, Deque, Dict, Iterator, List, Optional +from typing import Any, Deque, Dict, Iterator, List, Optional, Union import numpy as np import numpy.typing as npt import pandas as pd import pyarrow as pa -import pyarrow.dataset as ds +import pyarrow.dataset as pds from snowflake import snowpark -from snowflake.ml.data import data_ingestor, data_source -from snowflake.ml.data._internal import ingestor_utils +from snowflake.connector import result_batch +from snowflake.ml.data import data_ingestor, data_source, ingestor_utils _EMPTY_RECORD_BATCH = pa.RecordBatch.from_arrays([], []) @@ -67,6 +67,10 @@ def __init__( self._schema: Optional[pa.Schema] = None + @classmethod + def from_sources(cls, session: snowpark.Session, sources: List[data_source.DataSource]) -> "ArrowIngestor": + return cls(session, sources) + @property def data_sources(self) -> List[data_source.DataSource]: return self._data_sources @@ -115,9 +119,9 @@ def to_pandas(self, limit: Optional[int] = None) -> pd.DataFrame: table = ds.to_table() if limit is None else ds.head(num_rows=limit) return table.to_pandas() - def _get_dataset(self, shuffle: bool) -> ds.Dataset: + def _get_dataset(self, shuffle: bool) -> pds.Dataset: format = self._format - sources = [] + sources: List[Any] = [] source_format = None for source in self._data_sources: if isinstance(source, str): @@ -137,8 +141,16 @@ def _get_dataset(self, shuffle: bool) -> ds.Dataset: # in-memory (first batch) and file URLs (subsequent batches) and creating a # union dataset. result_batches = ingestor_utils.get_dataframe_result_batches(self._session, source) - sources.extend(b.to_arrow() for b in result_batches) - source_format = "arrow" + sources.extend( + b.to_arrow(self._session.connection) + if isinstance(b, result_batch.ArrowResultBatch) + else b.to_arrow() + for b in result_batches + ) + # HACK: Mitigate typing inconsistencies in Snowpark results + if len(sources) > 0: + sources = [_cast_if_needed(s, sources[-1].schema) for s in sources] + source_format = None # Arrow Dataset expects "None" for in-memory datasets else: raise RuntimeError(f"Unsupported data source type: {type(source)}") @@ -150,7 +162,7 @@ def _get_dataset(self, shuffle: bool) -> ds.Dataset: # Re-shuffle input files on each iteration start if shuffle: np.random.shuffle(sources) - pa_dataset: ds.Dataset = ds.dataset(sources, format=format, **self._kwargs) + pa_dataset: pds.Dataset = pds.dataset(sources, format=format, **self._kwargs) return pa_dataset def _get_batches_from_buffer(self, batch_size: int) -> Dict[str, npt.NDArray[Any]]: @@ -201,7 +213,7 @@ def _record_batch_to_arrays(rb: pa.RecordBatch) -> Dict[str, npt.NDArray[Any]]: def _retryable_batches( - dataset: ds.Dataset, batch_size: int, max_retries: int = 3, delay: int = 0 + dataset: pds.Dataset, batch_size: int, max_retries: int = 3, delay: int = 0 ) -> Iterator[pa.RecordBatch]: """Make the Dataset to_batches retryable.""" retries = 0 @@ -226,3 +238,47 @@ def _retryable_batches( time.sleep(delay) else: raise e + + +def _cast_if_needed( + batch: Union[pa.Table, pa.RecordBatch], schema: Optional[pa.Schema] = None +) -> Union[pa.Table, pa.RecordBatch]: + """ + Cast the batch to be compatible with downstream frameworks. Returns original batch if cast is not necessary. + Besides casting types to match `schema` (if provided), this function also applies the following casting: + - Decimal (fixed-point) types: Convert to float or integer types based on scale and byte length + + Args: + batch: The PyArrow batch to cast if needed + schema: Optional schema the batch should be casted to match. Note that compatibility type casting takes + precedence over the provided schema, e.g. if the schema has decimal types the result will be further + cast into integer/float types. + + Returns: + The type-casted PyArrow batch, or the original batch if casting was not necessary + """ + schema = schema or batch.schema + assert len(batch.schema) == len(schema) + fields = [] + cast_needed = False + for field, target in zip(batch.schema, schema): + # Need to convert decimal types to supported types. This behavior supersedes target schema data types + if pa.types.is_decimal(target.type): + byte_length = int(target.metadata.get(b"byteLength", 8)) + if int(target.metadata.get(b"scale", 0)) > 0: + target = target.with_type(pa.float32() if byte_length == 4 else pa.float64()) + else: + if byte_length == 2: + target = target.with_type(pa.int16()) + elif byte_length == 4: + target = target.with_type(pa.int32()) + else: # Cap out at 64-bit + target = target.with_type(pa.int64()) + if not field.equals(target): + cast_needed = True + field = target + fields.append(field) + + if cast_needed: + return batch.cast(pa.schema(fields)) + return batch diff --git a/snowflake/ml/data/data_connector.py b/snowflake/ml/data/data_connector.py index fac622b7..777c515c 100644 --- a/snowflake/ml/data/data_connector.py +++ b/snowflake/ml/data/data_connector.py @@ -1,11 +1,12 @@ from typing import TYPE_CHECKING, Any, Dict, Generator, List, Optional, Type, TypeVar import numpy.typing as npt +from typing_extensions import deprecated from snowflake import snowpark from snowflake.ml._internal import telemetry from snowflake.ml.data import data_ingestor, data_source -from snowflake.ml.data._internal.arrow_ingestor import ArrowIngestor as DefaultIngestor +from snowflake.ml.data._internal.arrow_ingestor import ArrowIngestor if TYPE_CHECKING: import pandas as pd @@ -24,6 +25,8 @@ class DataConnector: """Snowflake data reader which provides application integration connectors""" + DEFAULT_INGESTOR_CLASS: Type[data_ingestor.DataIngestor] = ArrowIngestor + def __init__( self, ingestor: data_ingestor.DataIngestor, @@ -31,22 +34,48 @@ def __init__( self._ingestor = ingestor @classmethod - def from_dataframe(cls: Type[DataConnectorType], df: snowpark.DataFrame, **kwargs: Any) -> DataConnectorType: + @snowpark._internal.utils.private_preview(version="1.6.0") + def from_dataframe( + cls: Type[DataConnectorType], + df: snowpark.DataFrame, + ingestor_class: Optional[Type[data_ingestor.DataIngestor]] = None, + **kwargs: Any + ) -> DataConnectorType: if len(df.queries["queries"]) != 1 or len(df.queries["post_actions"]) != 0: raise ValueError("DataFrames with multiple queries and/or post-actions not supported") source = data_source.DataFrameInfo(df.queries["queries"][0]) assert df._session is not None - ingestor = DefaultIngestor(df._session, [source]) - return cls(ingestor, **kwargs) + return cls.from_sources(df._session, [source], ingestor_class=ingestor_class, **kwargs) @classmethod - def from_dataset(cls: Type[DataConnectorType], ds: "dataset.Dataset", **kwargs: Any) -> DataConnectorType: + def from_dataset( + cls: Type[DataConnectorType], + ds: "dataset.Dataset", + ingestor_class: Optional[Type[data_ingestor.DataIngestor]] = None, + **kwargs: Any + ) -> DataConnectorType: dsv = ds.selected_version assert dsv is not None source = data_source.DatasetInfo( ds.fully_qualified_name, dsv.name, dsv.url(), exclude_cols=(dsv.label_cols + dsv.exclude_cols) ) - ingestor = DefaultIngestor(ds._session, [source]) + return cls.from_sources(ds._session, [source], ingestor_class=ingestor_class, **kwargs) + + @classmethod + @telemetry.send_api_usage_telemetry( + project=_PROJECT, + subproject_extractor=lambda cls: cls.__name__, + func_params_to_log=["sources", "ingestor_class"], + ) + def from_sources( + cls: Type[DataConnectorType], + session: snowpark.Session, + sources: List[data_source.DataSource], + ingestor_class: Optional[Type[data_ingestor.DataIngestor]] = None, + **kwargs: Any + ) -> DataConnectorType: + ingestor_class = ingestor_class or cls.DEFAULT_INGESTOR_CLASS + ingestor = ingestor_class.from_sources(session, sources) return cls(ingestor, **kwargs) @property @@ -87,6 +116,9 @@ def generator() -> Generator[Dict[str, npt.NDArray[Any]], None, None]: return tf.data.Dataset.from_generator(generator, output_signature=tf_signature) + @deprecated( + "to_torch_datapipe() is deprecated and will be removed in a future release. Use to_torch_dataset() instead" + ) @telemetry.send_api_usage_telemetry( project=_PROJECT, subproject_extractor=lambda self: type(self).__name__, @@ -116,6 +148,27 @@ def to_torch_datapipe( self._ingestor.to_batches(batch_size, shuffle, drop_last_batch) ) + @telemetry.send_api_usage_telemetry( + project=_PROJECT, + subproject_extractor=lambda self: type(self).__name__, + func_params_to_log=["shuffle"], + ) + def to_torch_dataset(self, *, shuffle: bool = False) -> "torch_data.IterableDataset": # type: ignore[type-arg] + """Transform the Snowflake data into a PyTorch Iterable Dataset to be used with a DataLoader. + + Return a PyTorch Dataset which iterates on rows of data. + + Args: + shuffle: It specifies whether the data will be shuffled. If True, files will be shuffled, and + rows in each file will also be shuffled. + + Returns: + A PyTorch Iterable Dataset that yields data. + """ + from snowflake.ml.data import torch_dataset + + return torch_dataset.TorchDataset(self._ingestor, shuffle) + @telemetry.send_api_usage_telemetry( project=_PROJECT, subproject_extractor=lambda self: type(self).__name__, diff --git a/snowflake/ml/data/data_connector_test.py b/snowflake/ml/data/data_connector_test.py index 3764e243..ddc6809f 100644 --- a/snowflake/ml/data/data_connector_test.py +++ b/snowflake/ml/data/data_connector_test.py @@ -45,6 +45,31 @@ def test_to_torch_datapipe(self) -> None: if col != "col3": self.assertIsInstance(tensor, torch.Tensor) + def test_to_torch_dataset(self) -> None: + expected_res = [ + {"col1": np.array([0, 1]), "col2": np.array([10, 11]), "col3": ["a", "ab"]}, + {"col1": np.array([2, 3]), "col2": np.array([12, 13]), "col3": ["abc", "m"]}, + {"col1": np.array([4, 5]), "col2": np.array([14, np.NaN]), "col3": ["mn", "mnm"]}, + ] + ds = self._sut.to_torch_dataset(shuffle=False) + count = 0 + for batch in torch_data.DataLoader(ds, batch_size=2, shuffle=False, drop_last=True): + np.testing.assert_array_equal(batch["col1"], expected_res[count]["col1"]) # type: ignore[arg-type] + np.testing.assert_array_equal(batch["col2"], expected_res[count]["col2"]) # type: ignore[arg-type] + np.testing.assert_array_equal(batch["col3"], expected_res[count]["col3"]) # type: ignore[arg-type] + count += 1 + self.assertEqual(count, len(expected_res)) + + def test_to_torch_dataset_multiprocessing(self) -> None: + ds = self._sut.to_torch_dataset(shuffle=False) + + # FIXME: This test runs pretty slowly, probably due to multiprocessing overhead + # Make sure dataset works with num_workers > 0 (and doesn't duplicate data) + self.assertEqual( + len(list(torch_data.DataLoader(ds, batch_size=2, shuffle=False, drop_last=True, num_workers=2))), + 3, + ) + def test_to_tf_dataset(self) -> None: expected_res = [ {"col1": np.array([0, 1]), "col2": np.array([10, 11]), "col3": np.array([b"a", b"ab"], dtype="object")}, diff --git a/snowflake/ml/data/data_ingestor.py b/snowflake/ml/data/data_ingestor.py index e8c9e9bc..a8c93fa9 100644 --- a/snowflake/ml/data/data_ingestor.py +++ b/snowflake/ml/data/data_ingestor.py @@ -1,7 +1,18 @@ -from typing import TYPE_CHECKING, Any, Dict, Iterator, List, Optional, Protocol, TypeVar +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Iterator, + List, + Optional, + Protocol, + Type, + TypeVar, +) from numpy import typing as npt +from snowflake import snowpark from snowflake.ml.data import data_source if TYPE_CHECKING: @@ -12,6 +23,12 @@ class DataIngestor(Protocol): + @classmethod + def from_sources( + cls: Type[DataIngestorType], session: snowpark.Session, sources: List[data_source.DataSource] + ) -> DataIngestorType: + raise NotImplementedError + @property def data_sources(self) -> List[data_source.DataSource]: raise NotImplementedError diff --git a/snowflake/ml/data/_internal/ingestor_utils.py b/snowflake/ml/data/ingestor_utils.py similarity index 88% rename from snowflake/ml/data/_internal/ingestor_utils.py rename to snowflake/ml/data/ingestor_utils.py index bc961417..907a73c3 100644 --- a/snowflake/ml/data/_internal/ingestor_utils.py +++ b/snowflake/ml/data/ingestor_utils.py @@ -13,6 +13,7 @@ def get_dataframe_result_batches( session: snowpark.Session, df_info: data_source.DataFrameInfo ) -> List[result_batch.ResultBatch]: + """Retrieve the ResultBatches for a given query""" cursor = session._conn._cursor if df_info.query_id: @@ -39,6 +40,7 @@ def get_dataframe_result_batches( def get_dataset_filesystem( session: snowpark.Session, ds_info: Optional[data_source.DatasetInfo] = None ) -> fsspec.AbstractFileSystem: + """Get the fsspec filesystem for a given Dataset""" # We can't directly load the Dataset to avoid a circular dependency # Dataset -> DatasetReader -> DataConnector -> DataIngestor -> (?) ingestor_utils -> Dataset # TODO: Automatically pick appropriate fsspec implementation based on protocol in URL @@ -52,7 +54,9 @@ def get_dataset_filesystem( def get_dataset_files( session: snowpark.Session, ds_info: data_source.DatasetInfo, filesystem: Optional[fsspec.AbstractFileSystem] = None ) -> List[str]: + """Get the list of files in a given Dataset""" if filesystem is None: filesystem = get_dataset_filesystem(session, ds_info) assert bool(ds_info.url) # Not null or empty - return sorted(filesystem.ls(ds_info.url)) + files = sorted(filesystem.ls(ds_info.url)) + return [filesystem.unstrip_protocol(f) for f in files] diff --git a/snowflake/ml/data/torch_dataset.py b/snowflake/ml/data/torch_dataset.py new file mode 100644 index 00000000..bc11849f --- /dev/null +++ b/snowflake/ml/data/torch_dataset.py @@ -0,0 +1,33 @@ +from typing import Any, Dict, Iterator + +import torch.utils.data + +from snowflake.ml.data import data_ingestor + + +class TorchDataset(torch.utils.data.IterableDataset[Dict[str, Any]]): + """Implementation of PyTorch IterableDataset""" + + def __init__(self, ingestor: data_ingestor.DataIngestor, shuffle: bool = False) -> None: + """Not intended for direct usage. Use DataConnector.to_torch_dataset() instead""" + self._ingestor = ingestor + self._shuffle = shuffle + + def __iter__(self) -> Iterator[Dict[str, Any]]: + max_idx = 0 + filter_idx = 0 + worker_info = torch.utils.data.get_worker_info() + if worker_info is not None: + max_idx = worker_info.num_workers - 1 + filter_idx = worker_info.id + + counter = 0 + for batch in self._ingestor.to_batches(batch_size=1, shuffle=self._shuffle, drop_last_batch=False): + # Skip indices during multi-process data loading to prevent data duplication + if counter == filter_idx: + yield {k: v.item() for k, v in batch.items()} + + if counter < max_idx: + counter += 1 + else: + counter = 0 diff --git a/snowflake/ml/dataset/dataset_metadata.py b/snowflake/ml/dataset/dataset_metadata.py index bcf1eea9..7724d424 100644 --- a/snowflake/ml/dataset/dataset_metadata.py +++ b/snowflake/ml/dataset/dataset_metadata.py @@ -15,11 +15,13 @@ class FeatureStoreMetadata: Properties: spine_query: The input query on source table which will be joined with features. serialized_feature_views: A list of serialized feature objects in the feature store. + compact_feature_views: A compact representation of a FeatureView or FeatureViewSlice. spine_timestamp_col: Timestamp column which was used for point-in-time correct feature lookup. """ spine_query: str - serialized_feature_views: List[str] + serialized_feature_views: Optional[List[str]] = None + compact_feature_views: Optional[List[str]] = None spine_timestamp_col: Optional[str] = None def to_json(self) -> str: diff --git a/snowflake/ml/dataset/dataset_reader.py b/snowflake/ml/dataset/dataset_reader.py index 929810c0..57e970ab 100644 --- a/snowflake/ml/dataset/dataset_reader.py +++ b/snowflake/ml/dataset/dataset_reader.py @@ -1,10 +1,9 @@ -from typing import List, Optional +from typing import Any, List, Optional, Type from snowflake import snowpark from snowflake.ml._internal import telemetry from snowflake.ml._internal.lineage import lineage_utils -from snowflake.ml.data import data_connector, data_ingestor, data_source -from snowflake.ml.data._internal import ingestor_utils +from snowflake.ml.data import data_connector, data_ingestor, data_source, ingestor_utils from snowflake.ml.fileset import snowfs _PROJECT = "Dataset" @@ -27,6 +26,13 @@ def __init__( self._fs: snowfs.SnowFileSystem = ingestor_utils.get_dataset_filesystem(self._session) self._files: Optional[List[str]] = None + @classmethod + def from_dataframe( + cls, df: snowpark.DataFrame, ingestor_class: Optional[Type[data_ingestor.DataIngestor]] = None, **kwargs: Any + ) -> "DatasetReader": + # Block superclass constructor from Snowpark DataFrames + raise RuntimeError("Creating DatasetReader from DataFrames not supported") + def _list_files(self) -> List[str]: """Private helper function that lists all files in this DatasetVersion and caches the results.""" if self._files: diff --git a/snowflake/ml/feature_store/BUILD.bazel b/snowflake/ml/feature_store/BUILD.bazel index b867813b..2d7f2bd7 100644 --- a/snowflake/ml/feature_store/BUILD.bazel +++ b/snowflake/ml/feature_store/BUILD.bazel @@ -37,6 +37,7 @@ py_library( "//snowflake/ml/_internal/utils:sql_identifier", "//snowflake/ml/dataset", "//snowflake/ml/lineage", + "//snowflake/ml/utils:sql_client", ], ) diff --git a/snowflake/ml/feature_store/examples/End-to-End Snowflake ML workflow.ipynb b/snowflake/ml/feature_store/examples/End-to-End Snowflake ML workflow.ipynb deleted file mode 100644 index 9e81696c..00000000 --- a/snowflake/ml/feature_store/examples/End-to-End Snowflake ML workflow.ipynb +++ /dev/null @@ -1,1349 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "0bb54abc", - "metadata": {}, - "source": [ - "- Required snowflake-ml-python version **1.5.5** or higher\n", - "- Last updated on: 7/22/2024" - ] - }, - { - "cell_type": "markdown", - "id": "aeae3429", - "metadata": {}, - "source": [ - "# End-to-End Snowflake ML workflow\n", - "\n", - "This notebook demonstrates an end-to-end ML experiment cycle including feature creation, training data generation, model training and inference. The workflow touches on key Snowflake ML features including [Snowflake Feature Store](https://docs.snowflake.com/en/developer-guide/snowpark-ml/feature-store/overview), [Dataset](https://docs.snowflake.com/en/developer-guide/snowpark-ml/dataset), ML Lineage, [Snowpark ML Modeling](https://docs.snowflake.com/en/developer-guide/snowpark-ml/modeling) and [Snowflake Model Registry](https://docs.snowflake.com/en/developer-guide/snowpark-ml/model-registry/overview). \n", - "\n", - "**Table of contents**\n", - "- [Set up test environment](#setup-test-env)\n", - " - [Connect to Snowflake](#connect-to-snowflake)\n", - " - [Select your example](#select-your-example)\n", - "- [Create features with Feature Store](#create-features-with-feature-store)\n", - " - [Initialize Feature Store](#initialize-feature-store)\n", - " - [Register entities and feature views](#register-new-entities-and-feature-views)\n", - "- [Generate Training Data](#gen-training-data)\n", - "- [Train model with Snowpark ML](#train-with-snowpark-ml)\n", - "- [Log models in Model Registry](#log-models-in-model-registry)\n", - "- [Query lineage](#query-lineage)\n", - "- [Predict with model](#predict-with-model)\n", - " - [Predict with local model](#predict-with-local-model)\n", - " - [Predict with Model Registry](#predict-with-model-registry)\n", - "- [Clean up notebook](#cleanup)" - ] - }, - { - "cell_type": "markdown", - "id": "9f16e6a8", - "metadata": {}, - "source": [ - "\n", - "## Set up test environment\n", - "\n", - "\n", - "### Connect to Snowflake\n", - "\n", - "Let's start with setting up our test environment. We will create a session and a schema. The schema `FS_DEMO_SCHEMA` will be used as the Feature Store. It will be cleaned up at the end of the demo. You need to fill the `connection_parameters` with your Snowflake connection information. Follow this **[guide](https://docs.snowflake.com/en/developer-guide/snowpark/python/creating-session)** for more details about how to connect to Snowflake.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "d9622928", - "metadata": {}, - "outputs": [], - "source": [ - "from snowflake.snowpark import Session\n", - "\n", - "connection_parameters = {\n", - " \"account\": \"\",\n", - " \"user\": \"\",\n", - " \"password\": \"\",\n", - " \"role\": \"\",\n", - " \"warehouse\": \"\",\n", - " \"database\": \"\",\n", - " \"schema\": \"\",\n", - "}\n", - "\n", - "session = Session.builder.configs(connection_parameters).create()\n", - "\n", - "assert session.get_current_database() != None, \"Session must have a database for the demo.\"\n", - "assert session.get_current_warehouse() != None, \"Session must have a warehouse for the demo.\"" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "1f38d70d-ccc2-40b9-8020-50e3ad3ff165", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Row(status='Schema SNOWFLAKE_FEATURE_STORE_NOTEBOOK_DEMO_MODEL successfully created.')]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# The schema where Feature Store will initialize on and test dataset stores.\n", - "FS_DEMO_SCHEMA = \"SNOWFLAKE_FEATURE_STORE_NOTEBOOK_DEMO\"\n", - "# the schema model lives.\n", - "MODEL_DEMO_SCHEMA = \"SNOWFLAKE_FEATURE_STORE_NOTEBOOK_DEMO_MODEL\"\n", - "\n", - "# Make sure your role has CREATE SCHEMA privileges or USAGE privileges on the schema if it already exists.\n", - "session.sql(f\"CREATE OR REPLACE SCHEMA {FS_DEMO_SCHEMA}\").collect()\n", - "session.sql(f\"CREATE OR REPLACE SCHEMA {MODEL_DEMO_SCHEMA}\").collect()" - ] - }, - { - "cell_type": "markdown", - "id": "9b3f89f3-d84d-4226-830d-3a967499fed7", - "metadata": {}, - "source": [ - "\n", - "### Select your example\n", - "\n", - "We have prepared some examples that you can find in our [open source repo](https://github.com/snowflakedb/snowflake-ml-python/tree/main/snowflake/ml/feature_store/examples). Each example contains the source dataset, feature view and entity definitions which will be used in this demo. `ExampleHelper` (included in snowflake-ml-python) will setup everything with simple APIs and you don't have to worry about the details." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "2cbb04de-193c-44e1-b400-802e22eb6941", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "All examples: ['new_york_taxi_features', 'citibike_trip_features', 'wine_quality_features']\n" - ] - } - ], - "source": [ - "from snowflake.ml.feature_store.examples.example_helper import ExampleHelper\n", - "\n", - "example_helper = ExampleHelper(session, session.get_current_database(), FS_DEMO_SCHEMA)\n", - "print(f\"All examples: {example_helper.list_examples()}\")" - ] - }, - { - "cell_type": "markdown", - "id": "2f909c72-e3c0-4834-a935-24a689101979", - "metadata": {}, - "source": [ - "`load_example()` will load the source data into Snowflake tables. In the example below, we are using the “wine_quality_features” example. You can replace this with any example listed above. Execution of the cell below may take some time depending on the size of the dataset." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "42c12da2-71cc-4c90-89aa-b1bd474ae975", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['\"REGTEST_DB\".SNOWFLAKE_FEATURE_STORE_NOTEBOOK_DEMO.nyc_yellow_trips']\n" - ] - } - ], - "source": [ - "# replace the value with the example you want to run\n", - "source_tables = example_helper.load_example('new_york_taxi_features')\n", - "print(source_tables)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "c5a73b0c-41dd-47f7-b7a1-1da492d23b5e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
VENDORIDPASSENGER_COUNTTRIP_DISTANCERATECODEIDSTORE_AND_FWD_FLAGPULOCATIONIDDOLOCATIONIDPAYMENT_TYPEFARE_AMOUNTEXTRAMTA_TAXTIP_AMOUNTTOLLS_AMOUNTIMPROVEMENT_SURCHARGETOTAL_AMOUNTCONGESTION_SURCHARGEAIRPORT_FEETPEP_PICKUP_DATETIMETPEP_DROPOFF_DATETIME
0113.21N48262114.00.50.53.060.00.318.36NaNNaN2016-01-01 00:12:222016-01-01 00:29:14
1121.01N1624829.50.50.50.000.00.310.80NaNNaN2016-01-01 00:41:312016-01-01 00:55:10
2110.91N2469026.00.50.50.000.00.37.30NaNNaN2016-01-01 00:53:372016-01-01 00:59:57
3110.81N17016225.00.50.50.000.00.36.30NaNNaN2016-01-01 00:13:282016-01-01 00:18:07
4111.81N161140211.00.50.50.000.00.312.30NaNNaN2016-01-01 00:33:042016-01-01 00:47:14
\n", - "
" - ], - "text/plain": [ - " VENDORID PASSENGER_COUNT TRIP_DISTANCE RATECODEID STORE_AND_FWD_FLAG \\\n", - "0 1 1 3.2 1 N \n", - "1 1 2 1.0 1 N \n", - "2 1 1 0.9 1 N \n", - "3 1 1 0.8 1 N \n", - "4 1 1 1.8 1 N \n", - "\n", - " PULOCATIONID DOLOCATIONID PAYMENT_TYPE FARE_AMOUNT EXTRA MTA_TAX \\\n", - "0 48 262 1 14.0 0.5 0.5 \n", - "1 162 48 2 9.5 0.5 0.5 \n", - "2 246 90 2 6.0 0.5 0.5 \n", - "3 170 162 2 5.0 0.5 0.5 \n", - "4 161 140 2 11.0 0.5 0.5 \n", - "\n", - " TIP_AMOUNT TOLLS_AMOUNT IMPROVEMENT_SURCHARGE TOTAL_AMOUNT \\\n", - "0 3.06 0.0 0.3 18.36 \n", - "1 0.00 0.0 0.3 10.80 \n", - "2 0.00 0.0 0.3 7.30 \n", - "3 0.00 0.0 0.3 6.30 \n", - "4 0.00 0.0 0.3 12.30 \n", - "\n", - " CONGESTION_SURCHARGE AIRPORT_FEE TPEP_PICKUP_DATETIME \\\n", - "0 NaN NaN 2016-01-01 00:12:22 \n", - "1 NaN NaN 2016-01-01 00:41:31 \n", - "2 NaN NaN 2016-01-01 00:53:37 \n", - "3 NaN NaN 2016-01-01 00:13:28 \n", - "4 NaN NaN 2016-01-01 00:33:04 \n", - "\n", - " TPEP_DROPOFF_DATETIME \n", - "0 2016-01-01 00:29:14 \n", - "1 2016-01-01 00:55:10 \n", - "2 2016-01-01 00:59:57 \n", - "3 2016-01-01 00:18:07 \n", - "4 2016-01-01 00:47:14 " - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# display as Pandas DataFrame\n", - "session.table(source_tables[0]).limit(5).to_pandas()" - ] - }, - { - "cell_type": "markdown", - "id": "3038124f-123b-4d22-9058-4fe2e57af6fe", - "metadata": {}, - "source": [ - "\n", - "## Create features with Feature Store" - ] - }, - { - "cell_type": "markdown", - "id": "4ece7a2b", - "metadata": {}, - "source": [ - "\n", - "### Initialize Feature Store\n", - "\n", - "Let's first create a feature store client. With `CREATE_IF_NOT_EXIST` mode, it will try to create a new Feature Store schema and all necessary feature store metadata if it doesn't exist already. It is required for the first time to set up a Feature Store. Afterwards, you can use `FAIL_IF_NOT_EXIST` mode to connect to an existing Feature Store. \n", - "\n", - "Note that the database being used must already exist. Feature Store will **NOT** try to create the database even in `CREATE_IF_NOT_EXIST` mode." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "fe850ccd", - "metadata": {}, - "outputs": [], - "source": [ - "from snowflake.ml.feature_store import (\n", - " FeatureStore,\n", - " FeatureView,\n", - " Entity,\n", - " CreationMode\n", - ")\n", - "\n", - "fs = FeatureStore(\n", - " session=session, \n", - " database=session.get_current_database(), \n", - " name=FS_DEMO_SCHEMA, \n", - " default_warehouse=session.get_current_warehouse(),\n", - " creation_mode=CreationMode.CREATE_IF_NOT_EXIST,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "b50b7ad1", - "metadata": {}, - "source": [ - "\n", - "### Register entities and feature views\n", - "\n", - "Next we register new entities and feature views in Feature Store. Entities will be the join keys used to generate training data. Feature Views contains all the features you need for your model training and inference. We have entities and feature views for this example defined in our [open source repo](https://github.com/snowflakedb/snowflake-ml-python/tree/main/snowflake/ml/feature_store/examples). We will load the definitions with `load_entities()` and `load_draft_feature_views()` for simplicity. " - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "ebe57406-6834-428d-8772-8d7e1265b08b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-----------------------------------------------------------------------\n", - "|\"NAME\" |\"JOIN_KEYS\" |\"DESC\" |\"OWNER\" |\n", - "-----------------------------------------------------------------------\n", - "|TRIP_DROPOFF |[\"DOLOCATIONID\"] |Trip dropoff entity. |REGTEST_RL |\n", - "|TRIP_PICKUP |[\"PULOCATIONID\"] |Trip pickup entity. |REGTEST_RL |\n", - "-----------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "all_entities = []\n", - "for e in example_helper.load_entities():\n", - " entity = fs.register_entity(e)\n", - " all_entities.append(entity)\n", - "fs.list_entities().show()" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "415e5e69-d605-4285-bb8b-e4d378cc35e9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "----------------------------------------------------------------------------------------------------\n", - "|\"NAME\" |\"VERSION\" |\"DESC\" |\"REFRESH_FREQ\" |\n", - "----------------------------------------------------------------------------------------------------\n", - "|F_TRIP_DROPOFF |1.0 |Managed feature view trip dropoff refreshed eve... |12 hours |\n", - "|F_TRIP_PICKUP |1.0 |Managed feature view trip pickup refreshed ever... |1 day |\n", - "----------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "all_feature_views = []\n", - "for fv in example_helper.load_draft_feature_views():\n", - " rf = fs.register_feature_view(\n", - " feature_view=fv,\n", - " version='1.0'\n", - " )\n", - " all_feature_views.append(rf)\n", - "\n", - "fs.list_feature_views().select('name', 'version', 'desc', 'refresh_freq').show()" - ] - }, - { - "cell_type": "markdown", - "id": "4dc1a7dc", - "metadata": {}, - "source": [ - "\n", - "## Generate Training Data\n", - "\n", - "After our feature pipelines are fully setup, we can use them to generate [Snowflake Dataset](https://docs.snowflake.com/en/developer-guide/snowpark-ml/dataset) and later do model training. Generating training data is easy since materialized FeatureViews already carry most of the metadata like join keys, timestamp for point-in-time lookup, etc. We just need to provide the spine data (it's called spine because it is the list of entity IDs that we are essentially enriching by joining features with it).\n", - "\n", - "`generate_dataset()` returns a Snowflake Dataset object, which is best for distributed training with deep learning frameworks like TensorFlow or Pytorch which requires fine-grained file-level access. It creates a new Dataset object (which is versioned and immutable) in Snowflake which materializes the data in Parquet files. If you train models with classic ML libraries like Snowpark ML or scikit-learn, you can use `generate_training_set()` which returns a classic Snowflake table. The Cell below demonstrates `generate_dataset()`." - ] - }, - { - "cell_type": "markdown", - "id": "ec901a65-f3ee-4c12-b8ff-ec0f630e5372", - "metadata": {}, - "source": [ - "Retrieve some metadata columns that are essential when generating training data." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "a6c80b76-99a4-4eb0-b0cb-583afa434ecf", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "timestamp col: TPEP_PICKUP_DATETIME\n", - "excluded cols: []\n", - "label cols: ['FARE_AMOUNT']\n", - "join keys: ['PULOCATIONID', 'DOLOCATIONID']\n" - ] - } - ], - "source": [ - "label_cols = example_helper.get_label_cols()\n", - "timestamp_col = example_helper.get_training_data_timestamp_col()\n", - "excluded_cols = example_helper.get_excluded_cols()\n", - "join_keys = [key for entity in all_entities for key in entity.join_keys]\n", - "print(f'timestamp col: {timestamp_col}')\n", - "print(f'excluded cols: {excluded_cols}')\n", - "print(f'label cols: {label_cols}')\n", - "print(f'join keys: {join_keys}')" - ] - }, - { - "cell_type": "markdown", - "id": "5f66ad1d-5ad1-4ad8-92f9-c65be491e0c3", - "metadata": {}, - "source": [ - "Create a spine dataframe that's sampled from source table." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "ea00fe3a-ac16-45d7-95c0-7ea7ed344e79", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
FARE_AMOUNTPULOCATIONIDDOLOCATIONIDTPEP_PICKUP_DATETIME
08.5161682016-01-08 10:47:49
16.02341142016-01-09 17:14:42
25.0872312016-01-08 13:26:55
37.5170792016-01-09 10:45:00
428.0971432016-01-07 22:11:59
...............
50713.0231482016-01-04 18:00:32
50852.01322442016-01-06 06:16:31
50912.52261622016-01-05 08:29:48
5107.0791072016-01-06 18:02:51
51122.0161332016-01-05 22:55:57
\n", - "

512 rows × 4 columns

\n", - "
" - ], - "text/plain": [ - " FARE_AMOUNT PULOCATIONID DOLOCATIONID TPEP_PICKUP_DATETIME\n", - "0 8.5 161 68 2016-01-08 10:47:49\n", - "1 6.0 234 114 2016-01-09 17:14:42\n", - "2 5.0 87 231 2016-01-08 13:26:55\n", - "3 7.5 170 79 2016-01-09 10:45:00\n", - "4 28.0 97 143 2016-01-07 22:11:59\n", - ".. ... ... ... ...\n", - "507 13.0 231 48 2016-01-04 18:00:32\n", - "508 52.0 132 244 2016-01-06 06:16:31\n", - "509 12.5 226 162 2016-01-05 08:29:48\n", - "510 7.0 79 107 2016-01-06 18:02:51\n", - "511 22.0 161 33 2016-01-05 22:55:57\n", - "\n", - "[512 rows x 4 columns]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sample_count = 512\n", - "source_df = session.sql(f\"\"\"\n", - " select {','.join(label_cols)}, \n", - " {','.join(join_keys)} \n", - " {',' + timestamp_col if timestamp_col is not None else ''} \n", - " from {source_tables[0]}\"\"\")\n", - "spine_df = source_df.sample(n=sample_count)\n", - "# preview spine dataframe\n", - "spine_df.to_pandas()" - ] - }, - { - "cell_type": "markdown", - "id": "35b8b59a-dcae-41a4-8954-db6719c5cf60", - "metadata": {}, - "source": [ - "Generate dataset object from spine dataframe and feature views." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "574a810b", - "metadata": {}, - "outputs": [], - "source": [ - "my_dataset = fs.generate_dataset(\n", - " name=\"my_cool_training_dataset\",\n", - " spine_df=spine_df, \n", - " features=all_feature_views,\n", - " version=\"4.0\",\n", - " spine_timestamp_col=timestamp_col,\n", - " spine_label_cols=label_cols,\n", - " exclude_columns=excluded_cols,\n", - " desc=\"This is the dataset joined spine dataframe with feature views\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "0a1cf2f4-59b3-40da-8c43-bee27129105d", - "metadata": {}, - "source": [ - "Convert dataset to a snowpark dataframe and examine all the features in it." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "5f3c71aa-1c6b-4bf4-83f9-2176dc249f83", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
FARE_AMOUNTPULOCATIONIDDOLOCATIONIDTPEP_PICKUP_DATETIMETRIP_COUNT_1HTRIP_COUNT_5HMEAN_FARE_2HMEAN_FARE_5H
015.0125522016-01-09 01:51:544216411.9207791.0
15.01252312016-01-20 18:24:09317153211.2569171.0
27.0125882016-01-22 00:49:056531714.4587631.0
332.5138482016-01-05 21:56:43591297428.4016691.0
441.0138452016-01-06 23:03:195022528.5840571.0
...........................
5076.51622302016-01-19 08:05:4788519469.1936981.0
5087.51622342016-01-20 00:37:15165199511.3855781.0
50910.01621072016-01-21 19:45:20692230711.1645761.0
51010.01621132016-01-22 18:56:25460169210.9099461.0
51151.0162212016-01-28 00:52:0472911.7245871.0
\n", - "

512 rows × 8 columns

\n", - "
" - ], - "text/plain": [ - " FARE_AMOUNT PULOCATIONID DOLOCATIONID TPEP_PICKUP_DATETIME \\\n", - "0 15.0 125 52 2016-01-09 01:51:54 \n", - "1 5.0 125 231 2016-01-20 18:24:09 \n", - "2 7.0 125 88 2016-01-22 00:49:05 \n", - "3 32.5 138 48 2016-01-05 21:56:43 \n", - "4 41.0 138 45 2016-01-06 23:03:19 \n", - ".. ... ... ... ... \n", - "507 6.5 162 230 2016-01-19 08:05:47 \n", - "508 7.5 162 234 2016-01-20 00:37:15 \n", - "509 10.0 162 107 2016-01-21 19:45:20 \n", - "510 10.0 162 113 2016-01-22 18:56:25 \n", - "511 51.0 162 21 2016-01-28 00:52:04 \n", - "\n", - " TRIP_COUNT_1H TRIP_COUNT_5H MEAN_FARE_2H MEAN_FARE_5H \n", - "0 42 164 11.920779 1.0 \n", - "1 317 1532 11.256917 1.0 \n", - "2 65 317 14.458763 1.0 \n", - "3 591 2974 28.401669 1.0 \n", - "4 50 225 28.584057 1.0 \n", - ".. ... ... ... ... \n", - "507 885 1946 9.193698 1.0 \n", - "508 165 1995 11.385578 1.0 \n", - "509 692 2307 11.164576 1.0 \n", - "510 460 1692 10.909946 1.0 \n", - "511 7 29 11.724587 1.0 \n", - "\n", - "[512 rows x 8 columns]" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "training_data_df = my_dataset.read.to_snowpark_dataframe()\n", - "assert training_data_df.count() == sample_count\n", - "# drop rows that have any nulls in value. \n", - "training_data_df = training_data_df.dropna(how='any')\n", - "training_data_df.to_pandas()" - ] - }, - { - "cell_type": "markdown", - "id": "ddca7543", - "metadata": {}, - "source": [ - "\n", - "## Train model with Snowpark ML\n", - "\n", - "Now let's train a simple random forest model, and evaluate the prediction accuracy. When you call fit() on a DataFrame that is created from a Dataset, the linkage between the trained model and dataset is automatically wired up. Later, you can easily retrieve the training dataset from this model, or you can query the lineage about the dataset and model. This is work-in-progress and will be available soon in an upcoming release." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "352603a9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "feature cols: ['MEAN_FARE_2H', 'MEAN_FARE_5H', 'TRIP_COUNT_5H', 'TRIP_COUNT_1H']\n", - "MSE: 101.03885521242017, Accuracy: 99.50167389473202\n" - ] - } - ], - "source": [ - "from snowflake.ml.modeling.ensemble import RandomForestRegressor\n", - "from snowflake.ml.modeling import metrics as snowml_metrics\n", - "from snowflake.snowpark.functions import abs as sp_abs, mean, col\n", - "\n", - "def train_model_using_snowpark_ml(training_data_df):\n", - " train, test = training_data_df.random_split([0.8, 0.2], seed=42)\n", - " feature_columns = list(set(training_data_df.columns) - set(label_cols) - set(join_keys) - set([timestamp_col]))\n", - " print(f\"feature cols: {feature_columns}\")\n", - " \n", - " rf = RandomForestRegressor(\n", - " input_cols=feature_columns, label_cols=label_cols, \n", - " max_depth=3, n_estimators=20, random_state=42\n", - " )\n", - "\n", - " rf.fit(train)\n", - " predictions = rf.predict(test)\n", - "\n", - " output_label_names = ['OUTPUT_' + col for col in label_cols]\n", - " mse = snowml_metrics.mean_squared_error(\n", - " df=predictions, \n", - " y_true_col_names=label_cols, \n", - " y_pred_col_names=output_label_names\n", - " )\n", - "\n", - " accuracy = 100 - snowml_metrics.mean_absolute_percentage_error(\n", - " df=predictions,\n", - " y_true_col_names=label_cols,\n", - " y_pred_col_names=output_label_names\n", - " )\n", - "\n", - " print(f\"MSE: {mse}, Accuracy: {accuracy}\")\n", - " return rf\n", - "\n", - "random_forest_model = train_model_using_snowpark_ml(training_data_df) " - ] - }, - { - "cell_type": "markdown", - "id": "28b12493-3339-4369-82d4-46a4389f6bf1", - "metadata": {}, - "source": [ - "\n", - "## Log model in Model Registry\n", - "\n", - "After the model is trained, we can save the model into Model Registry so we can manage the model, its metadata including metrics, versions, and use it later for inference. Also, ML lineage is built automatically between the model, dataset and feature views." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "cf1209a6-4c8c-4441-9c5d-7688f4ec0233", - "metadata": {}, - "outputs": [], - "source": [ - "from snowflake.ml.registry import Registry\n", - "\n", - "registry = Registry(\n", - " session=session, \n", - " database_name=session.get_current_database(), \n", - " schema_name=MODEL_DEMO_SCHEMA,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "94bcf485-9c9a-4a74-a8a2-3154c8f5aa74", - "metadata": {}, - "source": [ - "Log model into Model Registry." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "ded2ec74-fd46-445d-8fe9-1b133e4284eb", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/wezhou/miniconda3/envs/py38/lib/python3.8/contextlib.py:113: UserWarning: `relax_version` is not set and therefore defaulted to True. Dependency version constraints relaxed from ==x.y.z to >=x.y, <(x+1). To use specific dependency versions for compatibility, reproducibility, etc., set `options={'relax_version': False}` when logging the model.\n", - " return next(self.gen)\n" - ] - }, - { - "data": { - "text/plain": [ - "ModelVersion(\n", - " name='MY_RANDOM_FOREST_REGRESSOR_MODEL',\n", - " version='V1',\n", - ")" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "model_name = \"MY_RANDOM_FOREST_REGRESSOR_MODEL\"\n", - "\n", - "registry.log_model(\n", - " model_name=model_name,\n", - " version_name=\"v1\",\n", - " model=random_forest_model,\n", - " comment=\"My model trained with feature views, dataset\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "0df35d75-072d-484b-9ce4-c5b02fa4eae4", - "metadata": {}, - "source": [ - "\n", - "## Query lineage\n", - "We can now query the lineage from an object. You can call `lineage()` on any object and it returns a set of objects that it has dependency with." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "de446b09-c3d0-4c3b-91e8-aefa104229e8", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING:snowflake.snowpark:LineageNode.lineage() is in private preview since 1.5.3. Do not use it in production. \n", - "WARNING:snowflake.snowpark:Lineage.trace() is in private preview since 1.16.0. Do not use it in production. \n" - ] - }, - { - "data": { - "text/plain": [ - "[Dataset(\n", - " name='REGTEST_DB.SNOWFLAKE_FEATURE_STORE_NOTEBOOK_DEMO.MY_COOL_TRAINING_DATASET',\n", - " version='4.0',\n", - " )]" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "model = registry.get_model(model_name).version(\"v1\")\n", - "model.lineage(direction=\"upstream\")" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "79c97f25-d063-45e6-b073-fbe0f61ffc76", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[ModelVersion(\n", - " name='MY_RANDOM_FOREST_REGRESSOR_MODEL',\n", - " version='V1',\n", - " )]" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "my_dataset.lineage(direction=\"downstream\")" - ] - }, - { - "cell_type": "markdown", - "id": "a99250b6-9ede-416e-b5d0-14693c8ecc43", - "metadata": {}, - "source": [ - "There's a bug causing below cell not return Dataset as downstream lineage object of feature view. We are working on fixing it." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "2c0828fa-e56f-43d7-89fc-dafa7dcce9a5", - "metadata": {}, - "outputs": [], - "source": [ - "for fv in all_feature_views:\n", - " fv.lineage(direction='downstream')" - ] - }, - { - "cell_type": "markdown", - "id": "1ad8031f", - "metadata": {}, - "source": [ - "\n", - "## Predict with model" - ] - }, - { - "cell_type": "markdown", - "id": "ee15a59b-5201-4772-a376-0bb2043da37f", - "metadata": {}, - "source": [ - "Finally we are almost ready for prediction! For this, we can look up the latest feature values from Feature Store for the specific data records that we are running prediction on. One of the key benefits of using the Feature Store is that it provides a way to automatically serve up the right feature values during prediction with point-in-time correct feature values. `load_feature_views_from_dataset()` gets the same feature views used in training, then `retrieve_feature_values()` lookups the latest feature values." - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "9452d138", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--------------------------------------------------------------------------------------------------------------------\n", - "|\"FARE_AMOUNT\" |\"TPEP_PICKUP_DATETIME\" |\"TRIP_COUNT_1H\" |\"TRIP_COUNT_5H\" |\"MEAN_FARE_2H\" |\"MEAN_FARE_5H\" |\n", - "--------------------------------------------------------------------------------------------------------------------\n", - "|33.0 |2016-01-10 20:11:11 |27 |112 |11.381987577639752 |1.000000 |\n", - "|15.5 |2016-01-28 03:18:50 |35 |907 |12.427487352445194 |1.000000 |\n", - "|6.5 |2016-01-07 16:49:59 |495 |3035 |10.373705179282869 |1.000000 |\n", - "--------------------------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "test_df = source_df.sample(n=3)\n", - "\n", - "# load back feature views from dataset\n", - "fvs = fs.load_feature_views_from_dataset(my_dataset)\n", - "enriched_df = fs.retrieve_feature_values(\n", - " test_df, \n", - " features=fvs,\n", - " exclude_columns=join_keys,\n", - " spine_timestamp_col=timestamp_col\n", - ")\n", - "enriched_df = enriched_df.drop(join_keys)\n", - "enriched_df.show()" - ] - }, - { - "cell_type": "markdown", - "id": "7db2f69f-1597-4f43-9b59-554c48112a47", - "metadata": {}, - "source": [ - "\n", - "### [Optional 1] predict with local model\n", - "Now we can predict with a local model and the feature values retrieved from feature store. " - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "46c2546e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " FARE_AMOUNT TPEP_PICKUP_DATETIME TRIP_COUNT_1H TRIP_COUNT_5H \\\n", - "0 10.0 2016-01-28 08:57:11 1559 4636 \n", - "1 6.5 2016-01-29 07:02:50 137 239 \n", - "2 7.0 2016-01-09 10:06:25 225 521 \n", - "\n", - " MEAN_FARE_2H MEAN_FARE_5H OUTPUT_FARE_AMOUNT \n", - "0 9.863181 1.0 8.751825 \n", - "1 23.330000 1.0 21.714971 \n", - "2 9.970138 1.0 10.083706 \n" - ] - } - ], - "source": [ - "pred = random_forest_model.predict(enriched_df.to_pandas())\n", - "print(pred)" - ] - }, - { - "cell_type": "markdown", - "id": "21b81639", - "metadata": {}, - "source": [ - "\n", - "### [Option 2] Predict with Model Registry\n", - "\n", - "We can also retrieve the model from model registry and run predictions on the model using latest feature values." - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "2d7fd017", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " MEAN_FARE_2H MEAN_FARE_5H TRIP_COUNT_5H TRIP_COUNT_1H \\\n", - "0 12.713693 1.0 4544 739 \n", - "1 13.123772 1.0 3463 245 \n", - "2 9.186856 1.0 4495 878 \n", - "\n", - " OUTPUT_FARE_AMOUNT \n", - "0 10.083857 \n", - "1 10.548088 \n", - "2 8.751825 \n" - ] - } - ], - "source": [ - "# model is retrieved from Model Registry in earlier step.\n", - "restored_prediction = model.run(\n", - " enriched_df.to_pandas(), function_name=\"predict\")\n", - "\n", - "print(restored_prediction)" - ] - }, - { - "cell_type": "markdown", - "id": "8173da73", - "metadata": {}, - "source": [ - "\n", - "## Clean up notebook\n", - "\n", - "This cell will drop the schemas have been created at beginning of this notebook, and also drop all objects live in the schemas including source data tables, feature views, datasets, and models." - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "ea4e1ad9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Row(status='SNOWFLAKE_FEATURE_STORE_NOTEBOOK_DEMO_MODEL successfully dropped.')]" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.sql(f\"DROP SCHEMA IF EXISTS {FS_DEMO_SCHEMA}\").collect()\n", - "session.sql(f\"DROP SCHEMA IF EXISTS {MODEL_DEMO_SCHEMA}\").collect()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.19" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/snowflake/ml/feature_store/examples/Feature Store API Overview.ipynb b/snowflake/ml/feature_store/examples/Feature Store API Overview.ipynb deleted file mode 100644 index 947dedca..00000000 --- a/snowflake/ml/feature_store/examples/Feature Store API Overview.ipynb +++ /dev/null @@ -1,967 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Last updated on: 7/20/2024\n", - "- Required snowflake-ml-python version: >=1.5.5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Feature Store API Overview\n", - "\n", - "This notebook provides an overview of Feature Store APIs. It demonstrates how to manage Feature Store, Feature Views, Feature Entities and how to retrieve features and generate training datasets etc. The goal is to provide a quick walkthrough of the most common APIs. For a full list of APIs, please refer to [API Reference page](https://docs.snowflake.com/en/developer-guide/snowpark-ml/reference/latest/feature_store)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Table of contents**:\n", - "- [Set up connection and test dataset](#setup-test-environment)\n", - "- [Manage features in Feature Store](#manage-features-in-feature-store)\n", - " - [Initialize a Feature Store](#initialize-a-feature-store)\n", - " - [Create entities](#create-entities)\n", - " - [Create feature views](#create-feature-views)\n", - " - [Add feature view versions](#add-feature-view-versions)\n", - " - [Update feature views](#update-feature-views)\n", - " - [Operate feature views](#operate-feature-views)\n", - " - [Retrieve values from a feature view](#read-values-from-a-feature-view)\n", - " - [Generate training data](#generate-training-data)\n", - " - [Delete feature views](#delete-feature-views)\n", - " - [Delete entities](#delete-entities)\n", - " - [Cleanup Feature Store](#cleanup-feature-store)\n", - "- [Clean up notebook](#cleanup-notebook)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## Set up connection and test dataset\n", - "\n", - "Let's start with setting up out test environment. We will create a session and a schema. The schema `FS_DEMO_SCHEMA` will be used as the Feature Store. It will be cleaned up at the end of the demo. You need to fill the `connection_parameters` with your Snowflake connection information. Follow this **[guide](https://docs.snowflake.com/en/developer-guide/snowpark/python/creating-session)** for more details about how to connect to Snowflake." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from snowflake.snowpark import Session\n", - "\n", - "connection_parameters = {\n", - " \"account\": \"\",\n", - " \"user\": \"\",\n", - " \"password\": \"\",\n", - " \"role\": \"\",\n", - " \"warehouse\": \"\",\n", - " \"database\": \"\",\n", - " \"schema\": \"\",\n", - "}\n", - "\n", - "session = Session.builder.configs(connection_parameters).create()\n", - "\n", - "assert session.get_current_database() != None, \"Session must have a database for the demo.\"\n", - "assert session.get_current_warehouse() != None, \"Session must have a warehouse for the demo.\"" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Row(status='Schema SNOWFLAKE_FEATURE_STORE_NOTEBOOK_DEMO successfully created.')]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# The schema where Feature Store will be initialized and test datasets stored.\n", - "FS_DEMO_SCHEMA = \"SNOWFLAKE_FEATURE_STORE_NOTEBOOK_DEMO\"\n", - "\n", - "# Make sure your role has CREATE SCHEMA privileges or USAGE privileges on the schema if it already exists.\n", - "session.sql(f\"CREATE OR REPLACE SCHEMA {FS_DEMO_SCHEMA}\").collect()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We have prepared some examples which you can find in our [open source repo](https://github.com/snowflakedb/snowflake-ml-python/tree/main/snowflake/ml/feature_store/examples). Each example contains the source dataset, feature view and entity definitions which will be used in this demo. `ExampleHelper` (included in snowflake-ml-python) will setup everything with simple APIs and you don't have to worry about the details." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "All examples: ['new_york_taxi_features', 'citibike_trip_features', 'wine_quality_features']\n" - ] - } - ], - "source": [ - "from snowflake.ml.feature_store.examples.example_helper import ExampleHelper\n", - "\n", - "helper = ExampleHelper(session, session.get_current_database(), FS_DEMO_SCHEMA)\n", - "print(f\"All examples: {helper.list_examples()}\")\n", - "\n", - "source_tables = helper.load_example('citibike_trip_features')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can quickly look at the newly generated source tables." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "# display as Pandas dataframe\n", - "for s in source_tables:\n", - " total_rows = session.table(s).to_pandas()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## Manage features in Feature Store\n", - "\n", - "Now we're ready to create a Feature Store. The sections below showcase how to create a Feature Store, entities, feature views and how to work with them." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Initialize a Feature Store\n", - "\n", - "Firstly, we create a new (or connect to an existing) Feature Store." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "from snowflake.ml.feature_store import (\n", - " FeatureStore,\n", - " FeatureView,\n", - " Entity,\n", - " CreationMode,\n", - " FeatureViewStatus,\n", - ")\n", - "\n", - "fs = FeatureStore(\n", - " session=session, \n", - " database=session.get_current_database(), \n", - " name=FS_DEMO_SCHEMA, \n", - " default_warehouse=session.get_current_warehouse(),\n", - " creation_mode=CreationMode.CREATE_IF_NOT_EXIST,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Create entities\n", - "\n", - "Before we can create feature views, we need to create entities. The cell below registers the entities that are pre-defined for this example, and loaded by `helper.load_entities()`." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--------------------------------------------------------------------------------\n", - "|\"NAME\" |\"JOIN_KEYS\" |\"DESC\" |\"OWNER\" |\n", - "--------------------------------------------------------------------------------\n", - "|END_STATION_ID |[\"END_STATION_ID\"] |The id of an end station. |REGTEST_RL |\n", - "|TRIP_ID |[\"TRIP_ID\"] |The id of a trip. |REGTEST_RL |\n", - "--------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "for e in helper.load_entities():\n", - " fs.register_entity(e)\n", - "all_entities_df = fs.list_entities()\n", - "all_entities_df.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can get registered entities by name from Feature Store." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "# if you are running with other examples besides citibike_trip_features, replace with other entity name.\n", - "entity_name = 'end_station_id'\n", - "my_entity = fs.get_entity(entity_name)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Create feature views" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, we can register feature views. Feature views also are pre-defined in our repository. You can find the definitions [here](https://github.com/snowflakedb/snowflake-ml-python/tree/main/snowflake/ml/feature_store/examples)." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-------------------------------------------------------------------------------------\n", - "|\"NAME\" |\"VERSION\" |\"DESC\" |\"REFRESH_FREQ\" |\n", - "-------------------------------------------------------------------------------------\n", - "|F_STATION_1D |1.0 |Station features refreshed every day. |1 day |\n", - "|F_TRIP |1.0 |Static trip features |NULL |\n", - "-------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "for fv in helper.load_draft_feature_views():\n", - " fs.register_feature_view(\n", - " feature_view=fv,\n", - " version='1.0'\n", - " )\n", - "\n", - "all_fvs_df = fs.list_feature_views().select('name', 'version', 'desc', 'refresh_freq')\n", - "all_fvs_df.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that you can specify feature view versions and attach descriptive comments in the “DESC” field to make search and discovery of features easier. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Add feature view versions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can also add new versions in a feature view by using the same name as an existing feature view but a different version." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/kw/c3pzglr908q2p0w5w9vzhy0m0000gn/T/ipykernel_78291/3965221163.py:2: UserWarning: You must call register_feature_view() to make it effective. Or use update_feature_view(desc=).\n", - " fv.desc = f'{fv.name}/2.0 with new desc.'\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-------------------------------------------------------------------------------------\n", - "|\"NAME\" |\"VERSION\" |\"DESC\" |\"REFRESH_FREQ\" |\n", - "-------------------------------------------------------------------------------------\n", - "|F_STATION_1D |1.0 |Station features refreshed every day. |1 day |\n", - "|F_STATION_1D |2.0 |F_STATION_1D/2.0 with new desc. |1 day |\n", - "|F_TRIP |1.0 |Static trip features |NULL |\n", - "|F_TRIP |2.0 |F_TRIP/2.0 with new desc. |NULL |\n", - "-------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "for fv in helper.load_draft_feature_views():\n", - " fv.desc = f'{fv.name}/2.0 with new desc.'\n", - " fs.register_feature_view(\n", - " feature_view=fv,\n", - " version='2.0'\n", - " )\n", - "\n", - "all_fvs_df = fs.list_feature_views().select('name', 'version', 'desc', 'refresh_freq')\n", - "all_fvs_df.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Update feature views" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After a feature view is registered, it is materialized to Snowflake backend. You can still update some metadata for a registered feature view with `update_feature_view`. Below cell updates the `desc` of a managed feature view. You can check our [API reference](https://docs.snowflake.com/en/developer-guide/snowpark-ml/reference/latest/api/feature_store/snowflake.ml.feature_store.FeatureStore) page to find the full list of metadata that can be updated." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "----------------------------------------------------------------------------------------------------\n", - "|\"NAME\" |\"VERSION\" |\"DESC\" |\"REFRESH_FREQ\" |\"SCHEDULING_STATE\" |\n", - "----------------------------------------------------------------------------------------------------\n", - "|F_STATION_1D |1.0 |Updated desc for f_station_1d. |1 day |ACTIVE |\n", - "|F_STATION_1D |2.0 |F_STATION_1D/2.0 with new desc. |1 day |ACTIVE |\n", - "----------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "# if you are running other examples besides citibike_trip_features, replace with other feature view name.\n", - "target_feature_view = 'f_station_1d'\n", - "updated_fv = fs.update_feature_view(\n", - " name=target_feature_view,\n", - " version='1.0',\n", - " desc=f'Updated desc for {target_feature_view}.', \n", - ")\n", - "\n", - "assert updated_fv.desc == f'Updated desc for {target_feature_view}.'\n", - "fs.list_feature_views(feature_view_name=target_feature_view) \\\n", - " .select('name', 'version', 'desc', 'refresh_freq', 'scheduling_state').show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Operate feature views\n", - "\n", - "For **managed feature views**, you can suspend, resume, or manually refresh the backend pipelines. A managed feature view is an automated feature pipeline that computes the features on a given schedule. You create a managed feature view by setting the `refresh_freq`. In contrast, a **static feature view** is created when `refresh_freq` is set to None." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "----------------------------------------------------------------------------------------------------\n", - "|\"NAME\" |\"VERSION\" |\"DESC\" |\"REFRESH_FREQ\" |\"SCHEDULING_STATE\" |\n", - "----------------------------------------------------------------------------------------------------\n", - "|F_STATION_1D |1.0 |Updated desc for f_station_1d. |1 day |SUSPENDED |\n", - "|F_STATION_1D |2.0 |F_STATION_1D/2.0 with new desc. |1 day |ACTIVE |\n", - "|F_TRIP |1.0 |Static trip features |NULL |NULL |\n", - "|F_TRIP |2.0 |F_TRIP/2.0 with new desc. |NULL |NULL |\n", - "----------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "registered_fv = fs.get_feature_view(target_feature_view, '1.0')\n", - "suspended_fv = fs.suspend_feature_view(registered_fv)\n", - "assert suspended_fv.status == FeatureViewStatus.SUSPENDED\n", - "fs.list_feature_views().select('name', 'version', 'desc', 'refresh_freq', 'scheduling_state').show()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "----------------------------------------------------------------------------------------------------\n", - "|\"NAME\" |\"VERSION\" |\"DESC\" |\"REFRESH_FREQ\" |\"SCHEDULING_STATE\" |\n", - "----------------------------------------------------------------------------------------------------\n", - "|F_STATION_1D |1.0 |Updated desc for f_station_1d. |1 day |ACTIVE |\n", - "|F_STATION_1D |2.0 |F_STATION_1D/2.0 with new desc. |1 day |ACTIVE |\n", - "|F_TRIP |1.0 |Static trip features |NULL |NULL |\n", - "|F_TRIP |2.0 |F_TRIP/2.0 with new desc. |NULL |NULL |\n", - "----------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "resumed_fv = fs.resume_feature_view(suspended_fv)\n", - "assert resumed_fv.status == FeatureViewStatus.ACTIVE\n", - "fs.list_feature_views().select('name', 'version', 'desc', 'refresh_freq', 'scheduling_state').show()" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-------------------------------------------------------------------------------------------------------------------------\n", - "|\"NAME\" |\"STATE\" |\"REFRESH_START_TIME\" |\"REFRESH_END_TIME\" |\"REFRESH_ACTION\" |\n", - "-------------------------------------------------------------------------------------------------------------------------\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:51:22.421000-07:00 |2024-07-19 11:51:23.089000-07:00 |INCREMENTAL |\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:51:56.100000-07:00 |2024-07-19 11:51:56.474000-07:00 |INCREMENTAL |\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:52:58.376000-07:00 |2024-07-19 11:52:58.943000-07:00 |INCREMENTAL |\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:53:33.424000-07:00 |2024-07-19 11:53:33.777000-07:00 |INCREMENTAL |\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:54:30.754000-07:00 |2024-07-19 11:54:31.446000-07:00 |INCREMENTAL |\n", - "-------------------------------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "history_df_before = fs.get_refresh_history(resumed_fv).order_by('REFRESH_START_TIME')\n", - "history_df_before.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The cell below manually refreshes a feature view. It triggers the feature computation on the latest source data. You can check the refresh history with `get_refresh_history()` and you will see updated results from previous `get_refresh_history()`." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-------------------------------------------------------------------------------------------------------------------------\n", - "|\"NAME\" |\"STATE\" |\"REFRESH_START_TIME\" |\"REFRESH_END_TIME\" |\"REFRESH_ACTION\" |\n", - "-------------------------------------------------------------------------------------------------------------------------\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:51:22.421000-07:00 |2024-07-19 11:51:23.089000-07:00 |INCREMENTAL |\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:51:56.100000-07:00 |2024-07-19 11:51:56.474000-07:00 |INCREMENTAL |\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:52:58.376000-07:00 |2024-07-19 11:52:58.943000-07:00 |INCREMENTAL |\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:53:33.424000-07:00 |2024-07-19 11:53:33.777000-07:00 |INCREMENTAL |\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:54:30.754000-07:00 |2024-07-19 11:54:31.446000-07:00 |INCREMENTAL |\n", - "|F_STATION_1D$1.0 |SUCCEEDED |2024-07-19 11:55:04.462000-07:00 |2024-07-19 11:55:04.830000-07:00 |INCREMENTAL |\n", - "-------------------------------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "fs.refresh_feature_view(resumed_fv)\n", - "history_df_after = fs.get_refresh_history(resumed_fv).order_by('REFRESH_START_TIME')\n", - "history_df_after.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Retrieve values from a feature view " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can read the feature value of a registered feature view with `read_feature_view()`." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "---------------------------------------------------------------------------------\n", - "|\"END_STATION_ID\" |\"F_COUNT_1D\" |\"F_AVG_LATITUDE_1D\" |\"F_AVG_LONGTITUDE_1D\" |\n", - "---------------------------------------------------------------------------------\n", - "|505 |483 |40.74901271 |-73.98848395 |\n", - "|161 |429 |40.72917025 |-73.99810231 |\n", - "|347 |440 |40.72873888 |-74.00748842 |\n", - "|466 |425 |40.74395411 |-73.99144871 |\n", - "|459 |456 |40.746745 |-74.007756 |\n", - "|247 |241 |40.73535398 |-74.00483090999998 |\n", - "|127 |481 |40.73172428 |-74.00674436 |\n", - "|2000 |121 |40.70255088 |-73.98940236 |\n", - "|514 |272 |40.76087502 |-74.00277668 |\n", - "|195 |219 |40.70905623 |-74.01043382 |\n", - "---------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "feature_value_df = fs.read_feature_view(resumed_fv)\n", - "feature_value_df.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Generate training data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can generate training data easily from Feature Store and output it either as a [Dataset object](https://docs.snowflake.com/en/developer-guide/snowpark-ml/dataset), or as Snowpark DataFrame.\n", - "The cell below creates a spine dataframe by randomly sampling some entity keys from source table. generate_dataset() then creates a Dataset object by populating the spine_df with respective feature values from selected feature views. " - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "entity_key_names = ','.join(my_entity.join_keys)\n", - "spine_df = session.sql(f\"select {entity_key_names} from {source_tables[0]}\").sample(n=1000)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Use generate_dataset() to output a Dataset object." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "training_fv = fs.get_feature_view(target_feature_view, '1.0')\n", - "\n", - "my_dataset = fs.generate_dataset(\n", - " name='my_cool_dataset',\n", - " version='first',\n", - " spine_df=spine_df,\n", - " features=[training_fv],\n", - " desc='This is my dataset joined with feature views',\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Convert dataset to Pandas DataFrame and look at the first 10 rows." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
END_STATION_IDF_COUNT_1DF_AVG_LATITUDE_1DF_AVG_LONGTITUDE_1D
044118740.756016-73.967415
129520340.714066-73.992943
248632340.746201-73.988556
330818740.713078-73.998512
428468840.739017-74.002640
5202214040.758492-73.959206
617337440.760647-73.984428
712748140.731724-74.006744
831736440.724537-73.981857
928575840.734547-73.990738
\n", - "
" - ], - "text/plain": [ - " END_STATION_ID F_COUNT_1D F_AVG_LATITUDE_1D F_AVG_LONGTITUDE_1D\n", - "0 441 187 40.756016 -73.967415\n", - "1 295 203 40.714066 -73.992943\n", - "2 486 323 40.746201 -73.988556\n", - "3 308 187 40.713078 -73.998512\n", - "4 284 688 40.739017 -74.002640\n", - "5 2022 140 40.758492 -73.959206\n", - "6 173 374 40.760647 -73.984428\n", - "7 127 481 40.731724 -74.006744\n", - "8 317 364 40.724537 -73.981857\n", - "9 285 758 40.734547 -73.990738" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "my_dataset.read.to_pandas().head(10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Dataset object materializes data in Parquet files on internal stages. Alternatively, you can use `generate_training_set()` to output training data as a DataFrame." - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "---------------------------------------------------------------------------------\n", - "|\"END_STATION_ID\" |\"F_COUNT_1D\" |\"F_AVG_LATITUDE_1D\" |\"F_AVG_LONGTITUDE_1D\" |\n", - "---------------------------------------------------------------------------------\n", - "|478 |268 |40.76030096 |-73.99884222 |\n", - "|318 |550 |40.75320159 |-73.9779874 |\n", - "|167 |326 |40.7489006 |-73.97604882 |\n", - "|505 |483 |40.74901271 |-73.98848395 |\n", - "|515 |394 |40.76009437 |-73.99461843 |\n", - "|517 |431 |40.75149263 |-73.97798848 |\n", - "|233 |183 |40.69246277 |-73.98963911 |\n", - "|254 |297 |40.73532427 |-73.99800419 |\n", - "|529 |388 |40.7575699 |-73.99098507 |\n", - "|345 |451 |40.73649403 |-73.99704374 |\n", - "---------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "training_data_df = fs.generate_training_set(\n", - " spine_df=spine_df,\n", - " features=[training_fv]\n", - ")\n", - "\n", - "training_data_df.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Delete feature views\n", - "\n", - "Feature views can be deleted via `delete_feature_view()`.\n", - "\n", - "Warning: Deleting a feature view may break downstream dependencies for other feature views or models that depend on the feature view being deleted." - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "----------------------\n", - "|\"NAME\" |\"VERSION\" |\n", - "----------------------\n", - "| | |\n", - "----------------------\n", - "\n" - ] - } - ], - "source": [ - "for row in fs.list_feature_views().collect():\n", - " fv = fs.get_feature_view(row['NAME'], row['VERSION'])\n", - " fs.delete_feature_view(fv)\n", - "\n", - "all_fvs_df = fs.list_feature_views().select('name', 'version') \n", - "assert all_fvs_df.count() == 0, \"0 feature views left after deletion.\"\n", - "all_fvs_df.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Delete entities" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can delete entity with `delete_entity()`. Note it will check whether there are feature views registered on this entity before it gets deleted, otherwise the deletion will fail." - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-------------------------------------------\n", - "|\"NAME\" |\"JOIN_KEYS\" |\"DESC\" |\"OWNER\" |\n", - "-------------------------------------------\n", - "| | | | |\n", - "-------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "for row in fs.list_entities().collect():\n", - " fs.delete_entity(row['NAME'])\n", - "\n", - "all_entities_df = fs.list_entities()\n", - "assert all_entities_df.count() == 0, \"0 entities after deletion.\"\n", - "all_entities_df.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Cleanup Feature Store (experimental) \n", - "\n", - "Currently we provide an experimental API to delete all entities and feature views in a Feature Store for easy cleanup. If \"dryrun\" is set to True (the default) then `fs._clear()` only prints the objects that will be deleted. If \"dryrun\" is set to False, it performs the deletion." - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/tmp/snowml/snowflake/ml/feature_store/feature_store.py:190: UserWarning: It will clear ALL feature views and entities in this Feature Store. Make sure your role has sufficient access to all feature views and entities. Insufficient access to some feature views or entities will leave Feature Store in an incomplete state.\n", - " return f(self, *args, **kargs)\n" - ] - } - ], - "source": [ - "fs._clear(dryrun=False)\n", - "\n", - "assert fs.list_feature_views().count() == 0, \"0 feature views left after deletion.\"\n", - "assert fs.list_entities().count() == 0, \"0 entities left after deletion.\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## Clean up notebook" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Row(status='SNOWFLAKE_FEATURE_STORE_NOTEBOOK_DEMO successfully dropped.')]" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.sql(f\"DROP SCHEMA IF EXISTS {FS_DEMO_SCHEMA}\").collect()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.19" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/snowflake/ml/feature_store/examples/Feature Store Quickstart.ipynb b/snowflake/ml/feature_store/examples/Feature Store Quickstart.ipynb deleted file mode 100644 index 3d5a9463..00000000 --- a/snowflake/ml/feature_store/examples/Feature Store Quickstart.ipynb +++ /dev/null @@ -1,771 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "8cc93dd0", - "metadata": {}, - "source": [ - "## Prepare Snowpark Session\n", - "\n", - "Create a Snowpark Session using your Snowflake account credentials. For more information about creating a\n", - "`Session`, see [Creating a Session for Snowpark Python](https://docs.snowflake.com/en/developer-guide/snowpark/python/creating-session)." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "c950d9e7-8da7-40a1-926f-ea47ffc02bd0", - "metadata": {}, - "outputs": [], - "source": [ - "from snowflake.snowpark import Session, context, exceptions\n", - "\n", - "try:\n", - " # Retrieve active session if in Snowpark Notebook\n", - " session = context.get_active_session()\n", - "except exceptions.SnowparkSessionException:\n", - " # ACTION REQUIRED: Need to manually configure Snowflake connection if using Jupyter\n", - " connection_parameters = {\n", - " \"account\": \"\",\n", - " \"user\": \"\",\n", - " \"password\": \"\",\n", - " }\n", - "\n", - " session = Session.builder.configs(connection_parameters).create()" - ] - }, - { - "cell_type": "markdown", - "id": "1a6edfcc", - "metadata": {}, - "source": [ - "Prepare a database and schema to use for this example. We recommend creating a new schema for easy cleanup." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "32d9cdcd-417c-421f-97ab-3712d4143423", - "metadata": {}, - "outputs": [], - "source": [ - "# ACTION REQUIRED: Set these values based on your environment.\n", - "# We recommend creating a new schema for this example.\n", - "DATABASE_NAME = \"\"\n", - "SCHEMA_NAME = \"\"\n", - "WAREHOUSE_NAME = \"\"\n", - "\n", - "# Uncomment the line below to create a new database\n", - "# session.sql(f\"CREATE DATABASE IF NOT EXISTS {DATABASE_NAME}\").collect()\n", - "\n", - "# Create a new schema and select a warehouse to use\n", - "session.sql(f\"CREATE SCHEMA {DATABASE_NAME}.{SCHEMA_NAME}\").collect()\n", - "session.use_warehouse(WAREHOUSE_NAME)" - ] - }, - { - "cell_type": "markdown", - "id": "d5b9bb8c-b174-4a04-8c0e-e59d79545978", - "metadata": {}, - "source": [ - "## Prepare sample data\n", - "\n", - "For this exercise, we will use the Citi Bike NYC bike share dataset from the\n", - "[Zero to Snowflake tutorial](https://developers.snowflake.com/solution/citi-bike-data-analysis-create-and-manage-snowflake-objects-using-notebooks/).\n", - "The data is hosted in an Amazon AWS S3 bucket as CSV files; we'll mount the data as an\n", - "[External Stage](https://docs.snowflake.com/en/user-guide/data-load-s3-create-stage)\n", - "and load the data into a temporary table." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "2c010068-eec3-4f97-8949-0cd27753c415", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
TRIPDURATIONSTARTTIMESTOPTIMESTART_STATION_IDSTART_STATION_NAMESTART_STATION_LATITUDESTART_STATION_LONGITUDEEND_STATION_IDEND_STATION_NAMEEND_STATION_LATITUDEEND_STATION_LONGITUDEBIKEIDMEMBERSHIP_TYPEUSERTYPEBIRTH_YEARGENDER
07452015-06-08 07:30:002015-06-08 07:43:003002South End Ave & Liberty St40.711512-74.015756127Barrow St & Hudson St40.731724-74.00674417771NoneSubscriber1978.01
131842015-06-08 07:31:002015-06-08 08:24:00217Old Fulton St40.702772-73.993836398Atlantic Ave & Furman St40.691652-73.99997916156NoneCustomerNaN0
28632015-06-08 07:31:002015-06-08 07:45:00251Mott St & Prince St40.723180-73.994800387Centre St & Chambers St40.712733-74.00460715659NoneSubscriber1961.01
33182015-06-08 07:31:002015-06-08 07:36:00271Ashland Pl & Hanson Pl40.685282-73.978058310State St & Smith St40.689269-73.98912921499NoneSubscriber1980.01
44662015-06-08 07:31:002015-06-08 07:39:00285Broadway & E 14 St40.734546-73.990741472E 32 St & Park Ave40.745712-73.98194815947NoneSubscriber1971.01
\n", - "
" - ], - "text/plain": [ - " TRIPDURATION STARTTIME STOPTIME START_STATION_ID \\\n", - "0 745 2015-06-08 07:30:00 2015-06-08 07:43:00 3002 \n", - "1 3184 2015-06-08 07:31:00 2015-06-08 08:24:00 217 \n", - "2 863 2015-06-08 07:31:00 2015-06-08 07:45:00 251 \n", - "3 318 2015-06-08 07:31:00 2015-06-08 07:36:00 271 \n", - "4 466 2015-06-08 07:31:00 2015-06-08 07:39:00 285 \n", - "\n", - " START_STATION_NAME START_STATION_LATITUDE \\\n", - "0 South End Ave & Liberty St 40.711512 \n", - "1 Old Fulton St 40.702772 \n", - "2 Mott St & Prince St 40.723180 \n", - "3 Ashland Pl & Hanson Pl 40.685282 \n", - "4 Broadway & E 14 St 40.734546 \n", - "\n", - " START_STATION_LONGITUDE END_STATION_ID END_STATION_NAME \\\n", - "0 -74.015756 127 Barrow St & Hudson St \n", - "1 -73.993836 398 Atlantic Ave & Furman St \n", - "2 -73.994800 387 Centre St & Chambers St \n", - "3 -73.978058 310 State St & Smith St \n", - "4 -73.990741 472 E 32 St & Park Ave \n", - "\n", - " END_STATION_LATITUDE END_STATION_LONGITUDE BIKEID MEMBERSHIP_TYPE \\\n", - "0 40.731724 -74.006744 17771 None \n", - "1 40.691652 -73.999979 16156 None \n", - "2 40.712733 -74.004607 15659 None \n", - "3 40.689269 -73.989129 21499 None \n", - "4 40.745712 -73.981948 15947 None \n", - "\n", - " USERTYPE BIRTH_YEAR GENDER \n", - "0 Subscriber 1978.0 1 \n", - "1 Customer NaN 0 \n", - "2 Subscriber 1961.0 1 \n", - "3 Subscriber 1980.0 1 \n", - "4 Subscriber 1971.0 1 " - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from snowflake.snowpark.types import (\n", - " StructType,\n", - " StructField,\n", - " IntegerType,\n", - " FloatType,\n", - " StringType,\n", - " TimestampType,\n", - ")\n", - "\n", - "# Create an external stage that points to the AWS S3 bucket.\n", - "STAGE_NAME = f\"{DATABASE_NAME}.{SCHEMA_NAME}.citibike_trips\"\n", - "S3_BUCKET_URL = \"s3://snowflake-workshop-lab/citibike-trips-csv/\"\n", - "session.sql(f\"CREATE STAGE IF NOT EXISTS {STAGE_NAME} URL = '{S3_BUCKET_URL}'\").collect()\n", - "\n", - "# Create a DataFrame that loads the data from the stage\n", - "schema = StructType([\n", - " StructField(\"tripduration\", IntegerType()),\n", - " StructField(\"starttime\", TimestampType()),\n", - " StructField(\"stoptime\", TimestampType()),\n", - " StructField(\"start_station_id\", IntegerType()),\n", - " StructField(\"start_station_name\", StringType()),\n", - " StructField(\"start_station_latitude\", FloatType()),\n", - " StructField(\"start_station_longitude\", FloatType()),\n", - " StructField(\"end_station_id\", IntegerType()),\n", - " StructField(\"end_station_name\", StringType()),\n", - " StructField(\"end_station_latitude\", FloatType()),\n", - " StructField(\"end_station_longitude\", FloatType()),\n", - " StructField(\"bikeid\", IntegerType()),\n", - " StructField(\"membership_type\", StringType()),\n", - " StructField(\"usertype\", StringType()),\n", - " StructField(\"birth_year\", IntegerType()),\n", - " StructField(\"gender\", IntegerType()),\n", - "])\n", - "options = {\n", - " \"FIELD_OPTIONALLY_ENCLOSED_BY\": '\"',\n", - " \"NULL_IF\": '',\n", - "}\n", - "raw_features = session.read.options(options).schema(schema).csv(f\"@{STAGE_NAME}\")\n", - "\n", - "# OPTIONAL: Limit to 100K rows and save to a temp table for this exercise.\n", - "# The source data is fairly large so queries may take a while to run\n", - "# if we use the entire dataset.\n", - "table_name = f\"{DATABASE_NAME}.{SCHEMA_NAME}.citibike_trips_table\"\n", - "raw_features.limit(100000).write.save_as_table(table_name, mode=\"overwrite\", table_type=\"temp\")\n", - "raw_features = session.table(table_name)\n", - "\n", - "# Show a preview of the data using snowpark.DataFrame.to_pandas()\n", - "raw_features.limit(5).to_pandas()" - ] - }, - { - "cell_type": "markdown", - "id": "970926a5", - "metadata": {}, - "source": [ - "Create a new Feature Store\n", - "=========================================\n", - "\n", - "Create a new Feature Store from ``DATABASE_NAME`` and ``SCHEMA_NAME``. Note that we also configure a\n", - "``default_warehouse`` to be used with the Feature Store. The choice of warehouse is not important at\n", - "this time so long as a valid warehouse is provided." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "0cd0cb4b-99f1-4e4a-9bc1-08b13824b37c", - "metadata": {}, - "outputs": [], - "source": [ - "from snowflake.ml.feature_store import FeatureStore, CreationMode, Entity, FeatureView\n", - "\n", - "fs = FeatureStore(\n", - " session=session,\n", - " database=DATABASE_NAME,\n", - " name=SCHEMA_NAME,\n", - " default_warehouse=WAREHOUSE_NAME,\n", - " creation_mode=CreationMode.CREATE_IF_NOT_EXIST,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "9aa83340-7c0a-4001-9d3c-7214222c3b27", - "metadata": {}, - "source": [ - "## Creating Entities\n", - "\n", - "An *entity* is an abstraction over a set of primary keys used for looking up feature data. An Entity represents a real-world \"thing\" that has data associated with it. Below cell registers an entity called \"route\" in Feature Store." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "84a2ab90-efe5-4c2f-85a7-21cf61620e3a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--------------------------------------------------------------------------------------------------------------\n", - "|\"NAME\" |\"JOIN_KEYS\" |\"DESC\" |\"OWNER\" |\n", - "--------------------------------------------------------------------------------------------------------------\n", - "|ROUTE |[\"START_STATION_ID,END_STATION_ID\"] |Starting and ending stations for the bike ride |REGTEST_RL |\n", - "--------------------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "entity = Entity(\n", - " name=\"route\",\n", - " join_keys=[\"START_STATION_ID\", \"END_STATION_ID\"],\n", - " desc=\"Starting and ending stations for the bike ride\"\n", - ")\n", - "fs.register_entity(entity)\n", - "\n", - "# Show our newly created entity\n", - "# snowpark.DataFrame.show() is another way to preview the DataFrame contents\n", - "fs.list_entities().show()" - ] - }, - { - "cell_type": "markdown", - "id": "32408fc5-af40-41fc-971b-5301807ebaeb", - "metadata": {}, - "source": [ - "## Creating Feature Views\n", - "\n", - "A *feature view* is a group of logically-related features that are refreshed on the same schedule. The\n", - "`FeatureView` constructor accepts a Snowpark DataFrame that contains the feature generation logic. The provided\n", - "DataFrame must contain the `join_keys` columns specified in the entities associated with the feature view. In\n", - "this example we are using time-series data, so we will also specify the timestamp column name. \n", - "\n", - "Below cell creates a feature view with 4 features. These 4 features are averaged TRIPDURATION value over past X (1 day, 7 days, 30 days and 1 year) time period and grouped by entity (START_STATION_ID and END_STATION_ID). It uses the [Snowpark analytics function](https://docs.snowflake.com/en/developer-guide/snowpark/reference/python/latest/snowpark/api/snowflake.snowpark.DataFrameAnalyticsFunctions.time_series_agg) for time-series aggreation. " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "16a665c3-4397-4c3a-81cd-a940075fc595", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "DataFrameAnalyticsFunctions.time_series_agg() is experimental since 1.12.0. Do not use it in production. \n", - "DataFrame.alias() is experimental since 1.5.0. Do not use it in production. \n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
NAMEVERSIONDATABASE_NAMESCHEMA_NAMECREATED_ONOWNERDESCENTITIESREFRESH_FREQREFRESH_MODESCHEDULING_STATEWAREHOUSE
0TRIP_HISTORY1REGTEST_DBSNOWFLAKE_FEATURE_STORE_NOTEBOOK_QUICK_START2024-07-22 10:48:05.340REGTEST_RL[\\n \"ROUTE\"\\n]NoneNoneNoneNone
\n", - "
" - ], - "text/plain": [ - " NAME VERSION DATABASE_NAME \\\n", - "0 TRIP_HISTORY 1 REGTEST_DB \n", - "\n", - " SCHEMA_NAME CREATED_ON \\\n", - "0 SNOWFLAKE_FEATURE_STORE_NOTEBOOK_QUICK_START 2024-07-22 10:48:05.340 \n", - "\n", - " OWNER DESC ENTITIES REFRESH_FREQ REFRESH_MODE \\\n", - "0 REGTEST_RL [\\n \"ROUTE\"\\n] None None \n", - "\n", - " SCHEDULING_STATE WAREHOUSE \n", - "0 None None " - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from snowflake.snowpark import functions as F\n", - "\n", - "trip_stats = raw_features.select(\n", - " F.col(\"STOPTIME\"),\n", - " F.col(\"START_STATION_ID\"),\n", - " F.col(\"END_STATION_ID\"),\n", - " F.col(\"TRIPDURATION\"),\n", - ").dropna().analytics.time_series_agg(\n", - " time_col=\"STOPTIME\",\n", - " group_by=entity.join_keys,\n", - " aggs={\"TRIPDURATION\": [\"AVG\"]},\n", - " windows=[\"-1D\", \"-7D\", \"-30D\", \"-1Y\"],\n", - " sliding_interval=\"1D\",\n", - " col_formatter=lambda input_col, agg, window : f\"{input_col}_{agg}_{window.lstrip('-')}\",\n", - ").drop(F.col(\"SLIDING_POINT\"), F.col(\"TRIPDURATION\"))\n", - "\n", - "trip_stats_fv = FeatureView(\n", - " name=\"trip_history\",\n", - " entities=[entity],\n", - " feature_df=trip_stats,\n", - " timestamp_col=\"STOPTIME\",\n", - ")\n", - "\n", - "trip_stats_fv = fs.register_feature_view(trip_stats_fv, version=\"1\", overwrite=True)\n", - "\n", - "# Show our newly created Feature View and display as Pandas DataFrame\n", - "fs.list_feature_views().to_pandas()" - ] - }, - { - "cell_type": "markdown", - "id": "24bff365-4bbf-4d0c-b239-499eadde49e2", - "metadata": {}, - "source": [ - "## Generating Datasets for Training\n", - "\n", - "We are now ready to generate our training set. We'll define a spine DataFrame to form the backbone of our generated\n", - "dataset and pass it into ``FeatureStore.generate_dataset()`` along with our Feature Views.\n", - "\n", - "> NOTE: The spine serves as a request template and specifies the entities, labels and timestamps (when applicable). The\n", - " feature store then attaches feature values along the spine using an AS-OF join to efficiently combine and serve\n", - " the relevant, point-in-time correct feature data." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "6e73e71a-12fb-48ec-b776-5e83f812ce39", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
STARTTIMESTART_STATION_IDEND_STATION_IDTRIPDURATIONTRIPDURATION_AVG_1DTRIPDURATION_AVG_7DTRIPDURATION_AVG_30DTRIPDURATION_AVG_1Y
02013-10-16 18:39:51453521296NaNNaNNaNNaN
12013-12-17 22:17:16453521344296.0296.0296.0296.000000
22014-01-13 17:07:57453521252344.0344.0344.0320.000000
32014-02-26 21:46:39453521239252.0252.0298.0297.333344
42014-05-06 18:48:38453521400239.0239.0239.0282.750000
\n", - "
" - ], - "text/plain": [ - " STARTTIME START_STATION_ID END_STATION_ID TRIPDURATION \\\n", - "0 2013-10-16 18:39:51 453 521 296 \n", - "1 2013-12-17 22:17:16 453 521 344 \n", - "2 2014-01-13 17:07:57 453 521 252 \n", - "3 2014-02-26 21:46:39 453 521 239 \n", - "4 2014-05-06 18:48:38 453 521 400 \n", - "\n", - " TRIPDURATION_AVG_1D TRIPDURATION_AVG_7D TRIPDURATION_AVG_30D \\\n", - "0 NaN NaN NaN \n", - "1 296.0 296.0 296.0 \n", - "2 344.0 344.0 344.0 \n", - "3 252.0 252.0 298.0 \n", - "4 239.0 239.0 239.0 \n", - "\n", - " TRIPDURATION_AVG_1Y \n", - "0 NaN \n", - "1 296.000000 \n", - "2 320.000000 \n", - "3 297.333344 \n", - "4 282.750000 " - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Build our spine DF, filtering to rides that we have at least 10 records for to ensure statistical significance.\n", - "# Note that we use STARTTIME as the timestamp in our spine, which will be matched to the timestamp column(s) in\n", - "# the FeatureView. In this case, trip_stats_fv uses STOPTIME as its timestamp column, meaning each record in the\n", - "# spine will only be joined to rides that were completed prior to the current record.\n", - "query = f\"\"\"\n", - " WITH routes AS (\n", - " SELECT START_STATION_ID, END_STATION_ID\n", - " FROM {table_name}\n", - " GROUP BY START_STATION_ID, END_STATION_ID\n", - " HAVING COUNT(*) >= 10\n", - " )\n", - " SELECT t.STARTTIME, t.START_STATION_ID, t.END_STATION_ID, t.TRIPDURATION\n", - " FROM {table_name} t\n", - " JOIN routes r\n", - " ON t.START_STATION_ID = r.START_STATION_ID AND t.END_STATION_ID = r.END_STATION_ID\n", - "\"\"\"\n", - "spine_df = session.sql(query)\n", - "\n", - "ds = fs.generate_dataset(\n", - " name=\"trip_duration_ds\",\n", - " spine_df=spine_df,\n", - " features=[trip_stats_fv],\n", - " spine_timestamp_col=\"STARTTIME\",\n", - " spine_label_cols=[\"TRIPDURATION\"],\n", - " include_feature_view_timestamp_col=False, # optional\n", - ")\n", - "\n", - "# Show preview of the Dataset contents by loading into a Pandas DataFrame\n", - "ds.read.to_pandas().head(5)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "4014af14-5861-49bb-ab75-f5fcc5794a71", - "metadata": {}, - "outputs": [], - "source": [ - "# IGNORE: Sanity check output from previous cell\n", - "assert len(_) > 0" - ] - }, - { - "cell_type": "markdown", - "id": "d519bffa-79ea-4c4c-a6f9-9b261d3cbd2a", - "metadata": {}, - "source": [ - "You can now use this dataset in your downstream modeling workloads. Models trained using Snowpark ML Modeling\n", - "and Snowflake Model Registry will automatically benefit from model lineage and other MLOps features.\n", - "You can find full examples of using the Snowflake Feature Store on GitHub at\n", - "[`snowflake-ml-python`](https://github.com/snowflakedb/snowflake-ml-python/tree/main/snowflake/ml/feature_store/notebooks/customer_demo>)" - ] - }, - { - "cell_type": "markdown", - "id": "d027ab30-aaab-4ec5-928d-a602ba25d3f9", - "metadata": {}, - "source": [ - "## Clean Up\n", - "\n", - "To clean up the resources created during this example, just drop the schema we created at the beginning." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "6677711c-5abd-4914-8678-b4566a3cf96a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Row(status='SNOWFLAKE_FEATURE_STORE_NOTEBOOK_QUICK_START successfully dropped.')]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.sql(f\"DROP SCHEMA {DATABASE_NAME}.{SCHEMA_NAME}\").collect()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.19" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/snowflake/ml/feature_store/examples/Manage features in DBT with Feature Store.ipynb b/snowflake/ml/feature_store/examples/Manage features in DBT with Feature Store.ipynb deleted file mode 100644 index ea1d4939..00000000 --- a/snowflake/ml/feature_store/examples/Manage features in DBT with Feature Store.ipynb +++ /dev/null @@ -1,897 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "5f46aef7-1fc7-408e-acf1-0dc030981c58", - "metadata": {}, - "source": [ - "- Required snowflake-ml-python version **1.5.5** or higher\n", - "- Updated on: 7/20/2024" - ] - }, - { - "cell_type": "markdown", - "id": "70cdcdfb-a40f-4b5a-9ae8-6768b097f65a", - "metadata": {}, - "source": [ - "# Manage features in DBT with Feature Store\n", - "\n", - "This notebook showcases the interoperation between DBT and Snowflake Feature Store. The source data is managed in Snowflake database, while the feature pipelines are managed and executed from DBT. The output is stored as feature tables in Snowflake. Then We read from the feature tables and register them as external Feature View.\n", - "\n", - "This demo requires DBT account." - ] - }, - { - "cell_type": "markdown", - "id": "76628c92-5f51-4562-86a1-dadc2aeb85c0", - "metadata": {}, - "source": [ - "## Set up Snowflake connection" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "22427859-5cc8-43de-bdef-ebaa7ec33670", - "metadata": {}, - "outputs": [], - "source": [ - "from snowflake.snowpark import Session\n", - "\n", - "connection_parameters = {\n", - " \"account\": \"\",\n", - " \"user\": \"\",\n", - " \"password\": \"\",\n", - " \"role\": \"\",\n", - " \"warehouse\": \"\",\n", - " \"database\": \"\",\n", - " \"schema\": \"\",\n", - "}\n", - "\n", - "session = Session.builder.configs(connection_parameters).create()" - ] - }, - { - "cell_type": "markdown", - "id": "fdfb517c-c5fd-4119-b27f-5b3d778574de", - "metadata": {}, - "source": [ - "Create test schema. It will be deleted at the end of notebook." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "510d1d12-e5c1-4078-884a-771cc7ea257d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Row(status='Schema FS_DBT_DEMO successfully created.')]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# database name where test data and feature store lives.\n", - "# This name must be same with the one you used in schema.yaml in DBT.\n", - "FS_DEMO_DB = f\"SNOWML_FEATURE_STORE_DBT_DEMO\"\n", - "# feature store (schema) name.\n", - "# This must be same with the one you used in schema.yaml in DBT.\n", - "FS_DEMO_SCHEMA = \"FS_DBT_DEMO\"\n", - "\n", - "session.sql(f\"CREATE OR REPLACE DATABASE {FS_DEMO_DB}\").collect()\n", - "session.sql(f\"CREATE OR REPLACE SCHEMA {FS_DEMO_DB}.{FS_DEMO_SCHEMA}\").collect()" - ] - }, - { - "cell_type": "markdown", - "id": "320c79c9-d6aa-4d66-b270-8463a33f0d03", - "metadata": {}, - "source": [ - "## Load source data\n", - "\n", - "This notebook will use public `fraud_transactions` data as source. It contains transaction data range between [2019-04-01, 2019-09-01). We will split this dataset into two parts based on its timestamp. The first part includes rows before 2019-07-01, the second part includes rows after 2019-07-01. We copy the first part into `CUSTOMER_TRANSACTIONS_FRAUD` table now. And will copy second part into same table later." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "2af11339-5f7d-4f76-b352-d495353b6136", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "New source table: SNOWML_FEATURE_STORE_DBT_DEMO.FS_DBT_DEMO.fraud_transactions.\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
TRANSACTION_IDTX_DATETIMECUSTOMER_IDTERMINAL_IDTX_AMOUNTTX_TIME_SECONDSTX_TIME_DAYSTX_FRAUDTX_FRAUD_SCENARIO
012019-04-01 00:02:104961341281.51130000
122019-04-01 00:07:5621365146.00476000
232019-04-01 00:09:294128873764.49569000
342019-04-01 00:10:34927990650.99634000
452019-04-01 00:10:45568880344.71645000
\n", - "
" - ], - "text/plain": [ - " TRANSACTION_ID TX_DATETIME CUSTOMER_ID TERMINAL_ID TX_AMOUNT \\\n", - "0 1 2019-04-01 00:02:10 4961 3412 81.51 \n", - "1 2 2019-04-01 00:07:56 2 1365 146.00 \n", - "2 3 2019-04-01 00:09:29 4128 8737 64.49 \n", - "3 4 2019-04-01 00:10:34 927 9906 50.99 \n", - "4 5 2019-04-01 00:10:45 568 8803 44.71 \n", - "\n", - " TX_TIME_SECONDS TX_TIME_DAYS TX_FRAUD TX_FRAUD_SCENARIO \n", - "0 130 0 0 0 \n", - "1 476 0 0 0 \n", - "2 569 0 0 0 \n", - "3 634 0 0 0 \n", - "4 645 0 0 0 " - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from snowflake.ml.feature_store.examples.example_helper import ExampleHelper\n", - "\n", - "helper = ExampleHelper(session, FS_DEMO_DB, FS_DEMO_SCHEMA)\n", - "source_table = helper.load_source_data('fraud_transactions')[0]\n", - "print(f\"New source table: {source_table}.\")\n", - "session.table(source_table).limit(5).to_pandas()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "d26d7215-3845-4436-a4f7-486d48f7815b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "872794" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "fraud_data_path = f\"{FS_DEMO_DB}.{FS_DEMO_SCHEMA}.CUSTOMER_TRANSACTIONS_FRAUD\"\n", - "session.sql(f\"\"\"\n", - " CREATE OR REPLACE TABLE {fraud_data_path} AS\n", - " SELECT *\n", - " FROM {source_table}\n", - " WHERE TX_DATETIME < '2019-07-01'\n", - "\"\"\").collect()\n", - "session.table(fraud_data_path).count()" - ] - }, - { - "cell_type": "markdown", - "id": "2b6471b2-bcde-4470-89cf-8a6b1d7f3258", - "metadata": {}, - "source": [ - "## Define models in DBT\n", - "Now lets switch to [DBT IDE](https://cloud.getdbt.com/develop/15898/projects/334785)(this link will not work for you, you will need to create your own project) for a while. You will need a DBT account beforehand. Once you have DBT account, then you can clone the demo code from [here](https://github.com/sfc-gh-wezhou/FS_DBT_DEMO/tree/dev/models/example) (Snowflake repo). Below screenshot shows how DBT IDE looks like. In the file explorer section, you can see the code structure. Our [DBT models](https://docs.getdbt.com/docs/build/python-models) defined under models/example folder. We have 3 models: customers, terminals and transactions. These 3 models will later output 3 Snowflake DataFrame object. Lastly, Feature Store will register these DataFrames and make them FeatureViews." - ] - }, - { - "attachments": { - "b635b471-d26d-4374-abe0-41c284eaae6a.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABnMAAAOJCAYAAADGF9dHAAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAGc6ADAAQAAAABAAADiQAAAABjHNQIAABAAElEQVR4AeydCYBV8xfHzyzte2mT9j0lLVoopVQiIRIlKi2EiJLQnoQQIkuIULKk/NuTtO/aS7v2fd+maWb+5/t7c583d+57897Mm5rle2ju9ls/9767/M7vnBMyatSomGeeeUYoJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACKY9AaLly5VJeq9giEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABQyD0m2++IQoSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIEUSiD83LlzcuDgAbkSdSWFNpHNIgESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIH0SyBk9uzZMb1fe1P+3bM//VJgz0mABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEgghRIIPXnyZAptGptFAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiQQUq1atZiYDHlomcNrgQRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARSIIHQ/v37a7NiUmDT2CQSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIHQLFmyKIUQkiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEkiBBELDwsJSYLPYJBIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARAIJQYSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIGUS4DKnJR7btgyEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEqBlDq8BEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEkjJBEJjYmJScvvYNhIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARJI1wTCqcxJ1+efnScBEiABEiABEiABEiABEiABEiABEiABEiCB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zx9bnTwEYmPmJE/hLJUESIAESIAESIAESIAESIAESIAESIAESIAESIAErjaB6LNnJcPUPyRTlQoSASudXDlEQjmv/Wqfh4Dqi4428Y7gWi1aLXKiNTII4+UERJCJ0zgBKnPS+Alm90iABEiABEiABEiABEiABEiABEiABEiABEggvREwSgBVBsBNVwb8S28AUnF/ESMnhK7VUvEZZNOTi0B4TAxDSCUXXJZLAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRwDQmoUkB1OkZiJPoaNoRVJ0SAVjgJEeLx9E6Aypz0fgWw/yRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiSQDghQWZAOTjK7SAJpmECoShruHrtGAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAqmbQGhICAwN6WotdZ9Gtp4ESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESCCtEgiNiorSvlmeI9NqN9kvEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEkidBGItc1Jn49lqEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEkjrBEJjYuhiLa2fZPaPBEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEgg9RJgzJzUe+7YchIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIggXRAINYyhzFz0sG5ZhdJgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARSIYHwsLAwWbFolkTT3VoqPH1sMgmQAAnEJ7B5224pkDd3/APcQwJXkcCRE6d4HV5F3qzKmQCvQ2cu3Hv1CPAavHqsWZN3ArwOvbPhkatHgNfh1WPNmrwTwHVYsWwJ7wl4hASSmQDHa5IZcDoo3ljmREVFpYOusoskQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkkPoIGGVOSGho6ms5W0wCJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEAC6YBAqIqEhDBmTjo41+wiCZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZBAKiQQGh0dLTGMl5MKTx2bTAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkkB4IhB4+cpiWOenhTLOPJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACqZJAaI7sOSSUXtZS5cljo0mABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABNI+gVB0MfJKVNrvKXtIAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAqmQQGhISIiEhYelwqazySRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiSQ9gkYy5yY6Ji031P2kARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARSIYHQmJgYgXUOhQRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIIOURCEeToMrxxzbn0zHfy9btu6V504bSpNFtjr3xJ41jRu4kARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARKIRyA0OjpaYvwwzJk9d5FR5JQrU0Kmz5onUNrYxZ809jzcJgESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAES8E4gPDRUw+b4YZYDBQ4UOU91bmcUObDQsYs/aex5uE0CJEAC6Y3Auk1b5fCR43Lo8HF31wsVzGfWq95YXgrkzytIs3b9VvdxrCCNdTzOAW6QAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmkaQLh/sbLgSIHChxPN2p2Mv6ksefhNgmQAAmkNwJ2JQ36byl2ChY4JoeOHounyLHSHDq8WNq3aZHekLG/JEACJEACJEACJEACJEACJEACJEACJEACJJCuCRg3ayZoTgIYYJFjKWuwdIqZ408ap2q2/LNdfp401ekQ95EACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZBAuiagXtbUzZqfUrpUCZPSWjpls45ZS6c09n2HjhyVNes32XdzmwRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgATSPYHQmJgYiYmKDgqInbv2COLmQEqXLGqW/EMCJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACKYXAJ599JfjnTdp3eMrncW/5uJ8EkpNAeHR0tISEhUpMdIzf9ezYuVvwDzF0nKR504ZSqmQxp0PufStXr5XRY76Tg4ePSPnSpSRb9qzuY7/9b4aMn/i7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SIAESIAESIAESIAESIAESIAESCAULtbgao1CAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiSQ8gi43KyFhKS8lrFFJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACEhqiipxQ6nJ4KZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZBAiiQQilZFXolKkY1jo0iABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEggvRMIh2XOrj0H5HLklfTOgv0nARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIggRRHIBwtKl3ihhTXMDaIBEiABEggcQQ2b9uduIzMRQIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkkCIJhMbExAiscygkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIpj4CJmUNVTso7MWwRCZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACYBAaHR0tMRQm8OrgQRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARSJIFQFZGYFNk2NooESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAE0j2BUMbLSffXAAGQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmkYALGzZrQzVoKPkVsGgmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQHomEG7crKVnAuw7CZAACaRBAvny5U6DvWKXUhMBXoOp6Wyl3bbyOky75za19IzXYGo5U2m7nbwO0/b5TS2943WYWs5U2m4nr8O0fX5TQ+8qli2RGprJNqZgAuExMTESExUtEkLznBR8ntg0EiCBVELgXEyEHIg+I4ejz8nZmMsSEXMlwbBkuPtmCgmXHCEZpWBodrk+NKdkD8mUSnrMZpIACZAACZAACZAACZAACZAACZAACZAACZAACSQ3gfDo6GgJCQuVmOiY5K6L5ZMACZBAmiUAJc7mqCNyKPq85AzNJNnCMkjukCySISTUrz5HxkQbxc9BVQL9E3lcCoVmk4phBajU8YseE5EACZAACZAACZAACZAACZAACZAACZAACZBA2iYQniVLFhEqctL2WWbvSIAEkpXA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Ph1cVByddHaOcDKzykhoeuJO7b6y8olQ1ji3Ht2Hj72LjpHzIrpWs7YOeRgv1hzWUnzlYhkTO0aYPNA3PtSX+szubta6jLfs4NFABIeEKesNL1hzrRbfgUYLmfjqjeUiMj1rstaH+bqlf2tsEhv3adYuwpR5clIxf+TzPFP6dNZj8rgpkc+YjCKOcd94jRj3ZRtbxLkcfAWr1m7Cmo1b8dPkseZNmScBEiABEiABEiABEiABEiABEiABEiCBVEfAUd54dVDBrKNpmZPqTh4nTAIk8OIQENGlgmNOhEffx6VHtxCi3KNdiY7QAk1ido/iiUqEn0x2zvC1d0W5FzQ+zotDO+GZPKmQk3BvSVfbuUMb+Pr6JF2HVnp6UdduZapJVlS1Yjk4qn/HxE5RUZHIrtzhSewjT8/Msau5TwIkQAIkQAIkQAIkQAIkQAIkQAIkQAKpioDdunXrouvUrZeqJs3JkgAJkAAJxE8gJdysxT8b1pAACZAACZAACZAACZAACZAACZAACZAACZAACTwrAfvo6Oin8v3/rAPzeBIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIggcQJGMScxNuxBQmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQAoQ0GJOtARsYCIBEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEnjhCNjb2SklJ7Ho3C/ctDkhEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEkgbBOxVShsr5SpJgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIIBUSsI+KigLoZi0VnjpOmQRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIIC0QsHdwcEgL6+QaSYAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESCBVEnCMjo5G4KmziIx8lCoXwEmTAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQwMtMwFHcrBXKnxvRj6Jf5nVybSRAAiSQZggEnDiTZtbKhZIACZAACZAACZAACZAACZAACZAACZAACZBAWiBgcLNGISctnGuukQRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIIBUSsNdztrNLhVPnlEmA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/JV7tQxmhc7PnRrqOGhj1+7EZzPXYHG/ji9nMvGw16s3I5A3a2Sr03g4VU6JBEiABEiABEiABEiABEiABEiABEiABEggARFwFGWOWLrEB5HYOOtXzkPzZg3x8MFDFaenMg7sXo9iXp7xYXqcAwmQAAmQgCKwyuc0BsxZh1HrdmseYqnjF/DAio2jcqdZPn92HPG/i4CHQVZliXnnqHKxVjh3/PhNTcyceWwkQAIkQAIkQAIkQAIkQAIkQAIkQAIk8KYRcHZ0VGFzZN0pnrj4T5cuHbp0av+mnQceLwmQAAkkCAKWVja+l/y0m7VlyuWauFk7fOEanJ0ckT9zeq3cmbPDB6mSuiJFsiQJ4tj+6yQfPAY27QjHjx/Txdp/Zcn2JEACJEACJEACJEACJEACJEACJEACJEAC1gScxSonLm7WrJtzjwRIgARI4I0lYGOAcv3uffSeu96Mo3mRPJjarRkc44n1p3liLymx0BuoW80RJQq+pAHYLQmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQwBtLwDksLAxOyh1OWHg8Mc15Y08FD5wESIAEEhYBr+yZcObH3uZJNyhZCMeL5Vdu1R7DPUkSJE3yZsUyGzUzDH8NolWO+YJgggRIgARIgARIgARIgARIgARIgARIgARI4IUR0JY51OO8MJ7siARIgATeaAIuTk5In8L9jWTgM5eKnDfyxPOgSYAESIAESIAESIAESIAESIAESIAESOAVEHCMiIjQIXNewVgcggRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIII4EVCgDcbEWHsdmrE4CJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJPAqCGjLnDclOPWrAMoxSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESOBFEnB0UvENxDqHQgIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkEP8IOEvMnLCwMDg4Or7W2fkd24f9M38zzyFLsYoo2a6XeZ8JEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEngTCWhlzutS5IgCR0SUOFf2rrbiL/t7Jg1BtrINQcWOFRrukAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJvEEEnB2VRY64WRMLnVcpB+eO08oaY0xR2pTu2BeZPMvoLCkXEYWOodgp130orXU0FX6RAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAm8KQQcw8PDX7kiR+CKkkZElDg91t1C4++nmxU5ki8u1uQjZVJHxGijd/hFAiRAAiTw2giI/v+jyUuRb+AYBIWERprH9M0HdNm+s1cilTGDBEiABEiABEiABEiABEiABEiABEiABEiABEggbgRMbtZeg2WOMU2xuhlfLx3E6kbEiJNjxNCxdb9mtOOWBEiABEjg9RFY73MKuy/fsDuBy7cCMH2nj90yZpIACZAACZAACZAACZAACZAACZAACZAACZAACcSdgKO4WHN0iHvDF91CrG7kI4od+Sz9pIF2ryZWOc1HrzFb57zocY3+wsPDsGXs18YutyRAAiTw0gj4jumL9W974PgUk4WiDHTZe4bO2z2o0Usb90V1fO9REIat2IbhzatH6lIsdoYv3YQvm1SJVMYMEiABEiABEiABEiABEiABEiABEiABEiABEiCB5yOglTkhoWHP1/oltjKUOLbu117WkCEPH+D40j9fVvfslwRIgATMBMJDgnX6+sYpCA8zuSi7umG6zgsLfmSuF18TY9fsRLfKxZElTcpIU/Q+fFLnVfPME6mMGSRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAs9HwFGaOTk7PV/rl9RKFDlxVeJcObgds7tVM1n1DGiL0CdB2DpuCI6tnqNnGaFeF/+nQyk8CriJ8JAQrBvWE383y6XzLh/Yirk9aul609oVw6H5f+n0gdljMbllAf3ZP/MP89EuVf3v++dXnT+llScu7tmItd/2wMRG2bBp1ABzvQc3rmBh78Y6f8uYwXjyIABBgfcw/8O62DNlpM6/ffEUDswZB+lHxjq0cKK5vZGQ8cRqSMpljEOL/kbw44d67oE3r+tqsiA8q2slowm3JEACCYBAeEgA7hzbjSd3byDwwo4EMGPg4Plr2HTqItorZY6tBCiLnUFLN+OLptXgoP5RSIAESIAESIAESIAESIAESIAESIAESIAESIAEXgwBrcyJCFd+cRKwPPC/gpVfNEf5rgPx/srrKN3hEzgncUPgjWsIfnDXdGRKmfP41iVEhIbj3K718D++H+8uOo2mIxYiXd7CaDBkiq739qTtKNqiG06tX4IDs39G4x/mockP83F4wR84uX6RrvPg6gXcOH0Yb0/dgZwVGmLN4DYoUK812k7agZNrJiPg8jldb1GfRshbvSm6LjqFkEeBOL5uPhAWhjvnDuKe30V0nnMEST1SYe/kIWg3cRM6/rMPOcrU0G0tv2S8kMD76DR9P2r0H4fdfw2Eg6Mj0uYthhNr5uqq13z3IjQ4yLIZ0yRAAvGcgINTMvhtnge/Hcv1TB1dUsXzGQNDF29Ey1KFcO7GbZxVH5HjV/wRFBKKKRv3onz2jHgcHILjV03xdM7738adB/Hf2ijeg+cESYAESIAESIAESIAESIAESIAESIAESIAE3mgCWpkjcXMSslzZvx1p8pREnmqN4OjigmwlordQSZ+vCB7fvYYNP/dDWNAjJE2ZDi7J3TUCV3cPOLm44sLOtchftyMyFiqBDIWKI1+ddriwfa0ZU9EW3XW7XJUbwD1TXuSuWBcpM+dAyhxeuHX2KAKuXUSQGiNMLWoeXTZNK3HObzEt2EonVT8eBrcUqZE0VTp4ZCmA1UPexfWje5E6e17zGJaJ/HVaQ+aWv2YzNdc0uO67D8Vb98DRFZMhVkdn/l0Mz4ZdLJswTQIkEM8JpC/9Fm7smoOr/05DqiJNEBFucr8Wz6eNVT6nMWDOOoxat1tP9Yu56+AX8ABh4eG4dOe+Lhs411uXjdmwH3vOXorvh8T5kQAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEC8JuAsigBR5cRn2xy/Y/twZe/qKEGGPHmkrFKe2C0PsxMPSJQunWf74Niq2Vjcpz6q9R2NDJ4lrdqHBD+GR5Lk5jznJEkREhLZ8kUUP5YiFkHCNCzENJ9kaTPA2dUNydNlgauywjHE2SWJToqFTVtllXNu0wps+b0/shatjNpfPnPpZtQ3thFqsTQ8LBgRyq1a1lKmAON+R/fhzKZ5aDN+i1GNWxIggQRAIGutDvDfMwOPrh9C/g5DcPjoing/68X9Oprn6HvJDy3GLcCyzzrBzcUZnzetrj6m4nBl8Vlg0Fj80r4eyuTNZm7DBAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQNwJOIriIeI1GOaU6z402tmKAmflV51NMXA+aaDrRtUmc7EKuH/lGC4f2Kbr+Z/00du0uQrh2pGd6m33cKXseGYVI3FqQlUA8lJvf4Rirfvgwi5vZSVjCuQddN/kli1nuVo49e8cSEyawFt+OO09B5IXW0mTPR+c3Nx1nJy8NZogd+X6yFTIWmEkfUkMnTtnjqJA3bdQa8AYnN9pmuepf5dA3McZcvfSaZ08vXGZsiYKVNZCxSAWVcXa9MbGkX2RQlkHiZKKQgIkkHAIpMjjBbd0nsqiMBXSlqyZcCZuzPQ1/HYYQ3NLAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAm8SAWftYu01mOWUbNcL8jk4dxyu+ey0srwRKxzDEidb2YYo3bGvPieZPMvYPTfp8xRGxY9Gqtg17eHg7Aw3jwxoNW4V8tZsqt2Q/d0kB7KXa6SVKw6ODrh54hC2jR2g3JalQXDgHTT9cZF2mZatfBNMb18U+Rt0QfXew+B/4jBmdiyqx8xXpxOKNOlkd3zbTGEqFjfNRy7Hii/bYd/0H3SV6p/8huxlqum0lIvcv3oRq//3jk4HP7iD8j2GaeXT5l96o9z7Q1G8ZTdddmjOaOyZOESna305GUlTpNVpz/ptsWfCIH38OoNfJEACCYiAA0p8MQPhKt6Vo5Ozad4OpmdDQjgIr+yZcObH3nan6qietVGV2W3ATBIgARIgARIgARIgARIgARIgARIgARIgARIggSgJOHh7e0dUr1FTuwaLstYrKjAUO8ZwosSJSoFj1LHchoeH4UlggFnRIWVilRP8MBBJPFJYVtX5j+/d0kocQ7EiFR4F3IRr8pRwfuo+LUTF1BFxcUumt8/z9fj+bbgmSwEnZ5com0sdl6Qe5nGDHwWq/eTa+mZGx3Ko1u8XZMjvBZdk7lb9PLx1A7O6lEanOYetjjvKgVhAAiSQ6AkcP30BxT3zJfrjtHeAvr6+8PLyslfEPBIgARIgARIgARIgARIgARIgARIgARIgARJIsAScw5WyI74EzTGsdZ6XpqOjUySFhihqbBU50r/kJ0udIdJQyVKlt8r7L0ocoyPDisbYt7e1reOqlDa24pYitVXW0VWzcGjObyjSvGek47aqyB0SIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIEES8DZ8am7rwR7BG/AxMt2GYDU2XNHOtKIsFBUfO8b5K5iiikUqQIzSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAEEjwBHaQhIkyscxjJOr6ezYL1W9udmlfTLnbzmUkCJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJJB4CDiGhYXBwSnhBNxOPOh5JCRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiQQMwFHJycnIDwi5pqsQQIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIk8MoJmExy6GLtlYPngCRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiQQGwI6Zk5sKr6sOgfnjsOeSUOsus9WtiFKd+yr8zJ5lrEq4w4JkAAJkAAJkMCbQeDi7fO4HnAFFfJWfSMOODwiHBuOr0OlvFWQLIl7nI/55oObOHx5P+p4NohzWzYgARIgARIgARIgARIgARIgARIgARKI3wSeWua8vknaKnIsZ7L0kwbwO7bPMotpEiABEiCBeEAgQnnn/GjyUuQbOAZBIaF6RncfPtb7kmd8luz2jQezfTVTuPvwNqr8Vhph4aEYsKgvNp5YF6uB7z66A6dvHVDz9/Kxqh+fKy0/tAhTdox/YVPcfPJffLPmyxfWX3zvKCQ0GPXnN8TVgGvPNdXjfkfRekHr52rLRiRAAiRAAiRAAiRAAiRAAiRAAiRAAvGbgGOEWpGLeE0xc2KjqKFCJ35fQJwdCZDAm0lgvc8p7L58w+rgRcEjsrpPe+wa9K7+NChZ0JT5BnzvvrAT7i4ma4oJvpOQL33sjn3zyQ3wcEiOLXf3wP+Bf4Im5XvdB7su7EjQx/A6J+/qnATnPz6PXOnzvM5pcGwSIAESIAESIAESIAESIAESIAESIIF4SEArcxziacycct2HQj7Xj+yJh+g4JRIgARJ4MwncexSEYSu2YXjz6nYBpHFPijQeyZAuRXK4ubrYrZOYMg9eUm6txlTCR8t6YNet/aj+R3k8iHiId2e/jV1nt8Z4qCuPLsZnpfuiRPJC2HRyvbl+aFgoBi3ph1RD3VFuVDEMVNY+P6z+n7l81p5pyDIsLfL+kBXfLBuAFhPqmcskIXOav382Goyrri1/es99T5c/CQnCtyu/1G2l7yHLB0LGEoluzOCwYHSa2krPRyyJmo6vi/O3zup2+y7uQemRhfHT3pGYe2ahTsv+7cBbujy6MXWFaL5uPb6NdpOb6mNo/Xdj3Hra5x8bRmoLKMum7Se3wKID8yyz7KYfPHmAj+Z008ci/MZu/BXycovI6iNLYbCS/bl7Z+jzIGmR8zfP6PMh9eQYheGs3VN1WVRf/eb3wrx9syIVS76cIxE5h1V/L4MO01vB7+5Vc92VPkvQbXoHfDz3fT2WzFvcqRlieR3M3f+Pka23526eNp9/matYOonEZj7/7PhbW5rJuZbr76z/ad2WXyRAAiRAAiRAAiRAAiRAAiRAAiRAAq+HgKMSwOH1DB7VqFf2rsb+mb/hms9O8yc2VjxR9WeZf3LtApzesNQyK8Gkt48fipvnjieY+XKiJEACiZPA2DU70a1ycWRJk9LuAZYfPgUFvhyLL2etRsDDILt1ElNm7nR5MKzhCDwOC8KvdX5Bmcyl0SZ7c52XP2PhaA81OCwE888tRfUCddGscAssOTLfXH/r6Q0Y5zMB05pNw+fVBuLnI7/j/J0zuvze4wB0Xt0V/Sv0x5TWMzHj6Exs8rO2iNl3xwfvr3wf9Qs0xL5396F8jkq67c/rvsfsI7Mxo9UsLG23FDN9p2Pd8VW6LLoxw8PDUCJLKez6YA9OfHgCqd1So+OMVrpdkcxeWPjuSrzn2RX1s9XUadlPlSxVjGPqCtF8HXp4AgXSFcL2Tltw6f5ljN/yu65dOW81/KKYiHs7kRN+xzD/8lIVX6ey3o/ua8Taofj3wgYsarMQX1f/Bn229DMr0u48vIMTN4+Zm998cANn7zxTZDxRSq39D45g8NqB6F99ELw7eyONezpzfXuJDB6Z8O+ptVZFojyafPwfZE+dQ+f3qPYx/mw9GTsDDiAo9Im5bsCju5h2bjaypMiqx5J5r/FdrsuN6+CLSgPxd8upWHP+2RjSf3ulGHJxcsXud3ahdp56qDWnjlawxTQfUQK96/0+htQeiqufXMXQ+sPh5ORknhMTJEACJEACJEACJEACJEACJEACJEACr56Ao1jlvC43a9Edrih0LD/R1Y1L2fWTB5RC5GhcmsSbuue3rMDju6a3nOPNpDgREiCBOBPwHdMX69/2wPEpQ8xtL3vP0Hm7BzUy58XHxMHz17Dp1EW0V8ocW0nm6oyJnRpgw+edMK59Xey/dAOL9hyxrZbo9lMlS41CmYvgRtgdtC/TGXeUoqVl0dZKqVAFaWNY5N97foe24imXqzxqFqiPuZeWqBhEjzWjDae80S5fKzQv0Qpty3RA3fTVzOx2n92OjE5p8GmdgaiWvwZ6lu5lLrNMfODVXdcpmaM0OlfspotG7v8V1bJXwWM1TqCyUKmcpTJm7J2iy6Ib080lKT6v9xVSuHngjP8JFExfCLvvHdbtkromQ660eZA2eTqkckuj07Lv5Ogc45i6Qgxfgxt+p3hWxccVP8HKU8t07ZI5ysIzWT4sP7xY7y9QFi7NsjRAlpRZY+gNmHV0FnqU+RC1CtdH10ofoGbailh11NRvjI2fVvi27nC0L9sZZXNXRIMiTaJtVj5XBWy+tFnX6TKtLabumIBLdy7oc188WwmdnyVVdhTIELVrvv71Buux2hZpjx0XTBZfe87t0NdB31r9UbNQXXxY6kPzPK7cuaSVTl/V/R/KqOvr2ybDddmOM1sQm/kYHYmiSo5PzieFBEiABEiABEiABEiABEiABEiABEjg9RFwDgsLU4stDipg89NgB69vLhyZBEiABN4IAuEhwfo4r2+cgoJdhsDRyRlXN0zXeWHBj+I1g6GLN6JlqUI4d+M2zqqPyPEr/iicLYN2qVbTK5/Oy5EuFQKUO7a/txxE1xploN4c0PmJ7Ussa8ZtHIULd87quDfjt/yBZRdXIV2ydMiUIjOqF6wd7SGvObYCuVyzYP6+2XgUHKjr7jy7TS/Mb7uwBS292pjbF8tUAgHK5ZjI/st7US5DaXNZgSgsgGoVrGuuI4n7j+9pBYL/Q3+sOb5Sl6V0S4kM7hl0OroxQ8JDUV25Abvx+CZqZa+B+8H3dRtxzeasruGoJKYxo2pn5Iv7uSQubnq3UKbCWoEkCi9RLvUu9zEm7P0THSt0xbiD4zCh6d9Gsyi3YrFyIfgaimQqaq5TKktZXAq4aN6PTaJyvmfKtZjql8heGqefXNQKHLk+7qjzmEYpviqmKoWkrsljaq6VTQbjDMnT4+RN00sp+y7tsboOCmYqYu7rpjrHIgUzFtJbGUeUX9fvX0Ob/G9HO5886fPjp4rD0HChSUnVq9B7+K7pCGVplVr3xS8SIAESIAESIAESIAESIAESIAESIIFXT8BZLHPigx4nW9mGKN2xrxUBcbUm1jkxSXhICNb/1AeX9qyGq3sa1PpiLLIVr4grB7dj6x9f4v6VY8hUohYaf2fyJX/z1CHM+6A27l05iRLtP0PZLp/qIS7u2Yytv/VHSFAgSrb7GCXa9kRQ4D0s+aQ5cparB98l4+CeKQ9q9PsFW38fiPt+Z1Hxw+Eo0qgDgh8FYsdfQ3Fu6xI4qDeRS3cZgGLNu5qnHvz4IeZ0r4q3flsJ9/SZEa4Wv+Z0r4bGw+dg0+jPkdWrInwW/6nbyvxPrJ6DS7tXIn+dDmq8EeZ+mCABEkg8BMJDAnDn2G54ZMuHwAQUNH6Vz2nI5/6TEH0yvpi7DhO6N1dB260XepO7JcG5gECEqh8ZV6fEqcwRAOISa+ulraiasSKO+5vcc4kbK1F+xCRiIZLbIye2nDXFMhHFzmql4BEriwrZK+Lk0/6kn+PK9Vdm94y6yxLZSuKP/X+Yuz93y+R+zZzxNJFKKWosxV1Z1Yg09WyB7lUiW/NEN+Y63xVakXNywEWtvJE4MQsur0CExal1cHBEuM1xxzSm5fzspcXNWpjqU6x8LiprFlFIiCJHpGWp9ui1qS8mbfsLj8KfoI5nA3tdWOXJ3z1i1XT+tinejxQK21ypcul6oji6G3RXp+XrzO1nLtbMmSrhntSarWWZbTp18rR63n9s/AW9in2A5aeXKwu39aidO3pln20/tvuemYti2uGp5uyLt8+Z06mTmu7HS3cuQsYXxeOxR2eUEimt3heO0c1HrLA+rfMFtivlYvu5rVDyQCl0q9JT9y8KvJ/XDdPpD5V7OOmfQgIkQAIkQAIkQAIkQAIkQAIkQAIk8HIJOMsbqrIO87rtcuwpbezl2cNxbtd6+B/fj3cXqcVFvytw8/DAA/8rWPlFc9Qd/A9yVayLa0f3wjmJ6c3ee1fOoMkPcxH88B6WftIAxdt8gCf372LNYOXOZvQapMyWG4v7NEW2UtW04uXeJV+41WmHjrMOasXOuu+6o+mIhbit4tds/rWPVuY4uyVFRs/SqPThEDy67Y+53cuhcP22cHFLpqfsmjQ50uYthhNr5qJM509wzXcvQoODkDJLDjy4egE3kiTD21N3YOeEH9Q82qDet7NR4YOvMOedUijR5kOkyk73JvbOPfNIICETcHBKBr/N8/Awt8lCwNHFFF8kPh/T4n4dzdPzveSHFuMWYNlnndTiurOy0LmhFtwdkTtDGpzxu4Xp2w+jbv5sSpHjaG6T2BKuTi4Y2GAIlp1YhP61vsJ5FWtERPJiEonxIhYi3u02QSwhRCZv/wuDN36Fn1qORq0C9dBmYVu0PdkRwaHBWOW3Ht3zmfhXyFNFu3WbsmM8yuQoj0kHJsY0nC53VMqW9/J3wZT9k1A5Xw0UyuSpA9v7KWuNyvmqRztmeHi4jgv0UFkQ3VFxasbteqZMMgYvplyGTTw4HtcCLiOTcncm48U0ptE2uu2cPdNR36spZh74B80KNDNXzeCRAe1ytEDPjR+jf9E+ZiWPuUIUiSa5G2L6oWloUqylmusVzXZ26Zm6tljRiALplN8JiOJn3sn5qJrFFG8oiu5ilV03V12M8h2D9e3W6n5/PDQKK95aEqu2UVWqqFz5icXP+uNr4ZnZE7N9ZpirZkubSyutpuz8C9+mG4GFyg2diLhcE4luPhdvn1exiO6iRI5SKJW9DNImSYPA4Ie6nXyFhodg8J5v9b64mqMyx4yGCRIgARIgARIgARIgARIgARIgARJ4aQR0zJwwtUDzukUsc7IUq2j1kbzYSPp8RVQsmWvY8HM/hAU9QtKU6XBl/3akyVMSeao1gqOLC7KVeLYQk69Wa6TJmR+ZPJXrH2c3BFw6i8sHtsEleRr4KSXLyTXz4Jo8BS7s9DYPX7Tlu0iWKj2yla2N3FWb6fa5KtZR4wWqsW/C0dEJucrXwpnNK7Bjgult1VtnTW5QjE6Kt+6BoysmQxRoZ/5dDM+GXYwiFG3RXc87V+UGyvonL3IrBVTKzDmQMocXbPsxN2KCBEggQRNIX/ot3Ng1B1f/nYZUKiZFRLjJ/VqCOSgLiwyZ88Wbd9Ho97koPPhPNB0zH0mcnfD1W7USzOE870QfqLgzEjumTI4y2Hx2I6rni90xbzixTrtYMxQ5Mn71/LW1kubY9SOoXqgOOhZoq4PWf7y8p44Hk8TZZJEii+d/1vwDn67/DFUnV0HZTGWR1sWepYjNSVJjDG/2CzIlz4Qi44vA6VsHFPizgIqBc0offnRj1i2iLGjTl0KaEamRb2w+FM9YXLdxsHgbpGr+mqiTsw48fy8Ml6FO8H9wQ9eJbkxdIaovpUwRa6UhGwcj4y/p4XPLB90qfmhVu0u57nq/fZl3rPKj2/mm0Q/aUiXH7zlQ4Z9KWsHVslRb3SSvUqx1yd0OhccXRtnxpaNU5Fged3RjGWUVclfRyQp5KqNeoUY6LXF/RM4pJaCci2TDTee30F8F9f7GE95a8aMr2fnK4JERg0p+jvrzGiD7bzng4eJuruWiLJnmt1+EqSdm6XP2/r+9MKH2WHPsm+jm43/fD6WnlNZzSPmTBwqmLoB3K/cw9+2gXwMy7YrCi0ICJEACJEACJEACJEACJEACJEACJPDyCWjLHIllYLEW8/JHfcEjiNKj82wfHFs1W1nU1Ee1vqMR8uSRsnx5EuNIDs7Kz79SroiVjLhHS54ui25TvFVPpM6RL1J7Z6X8CX0anNrJxVWXi3Lm7pXzWPBBVZTpNgRVPx6KBcd2ISzU2sVO1mIVdH2/o/twZtM8tBm/JVL/Rp9GgVgTSf8UEiCBxEcga60O8N8zA4+uH0L+DkNw+OiKBHWQXtkz4cyPvc1zblCyEHxVzJyAh4+QLIkrUiQ1WUOaKyTShEcSD4R9Y3pOT+48K9ZH2avGJ5CPpeTNkN/cl+SPbT8Zv4dP0C7G6o+tghpK2WPIB9V6472qvdSyugN+8f4eKZI8W8iXOgFDTDF4jPrGNq0KaL/gvZUIVC8j3Ht8F+lTZFLWUy662NXJNcoxxbXZ8h7euB14C+5qLHFHNhaTjW71VliM7zAN4zHNKj+6Ma0q2ux0qdgd8gmPCIff/es6DpFY+ljKuZtnIHF1xIoktpI1dXbs6eejlU1J1XF5uKUwNxXlxJQuczAycIyKEZNKszcXqoRYMxnn2zI/pnTbMh0gHxGJpWTZhyj0LPdt++pQvqs5q3etz9Abn5n3v2v2M/rXHaz+jotAyqTW1n1ibXVn8D3F7hrSKcWPnF9DoptP2dwV8WRwiOJzHamTpVVxfUxWxkZbOffRzdeoxy0JkAAJkAAJkAAJkAAJkAAJkAAJkMCLI+Ds5OSk3/p83QqD2LpUs3foty+eQhJlSVPq7Y8QomLTXNjljVLKldnOcf21xU32UlXgf9IHGQoWs9dc52VVljs7x/ojRabsyl1aKTwKuAm3FGkQ/OBelG0sC/yPHUCydFlRsvUHCLh2EaGPTYGhQ548xinvhShYt7V281asTW9sHNlXjZNXW95Y9hGbdEQ8sKKKzTxZhwRIIGYCKfJ4wS2dJ4LvXUPakjVjbpAAaoi7tUypni2MJ4Apx9sp+j/wR7eZb6N+gYY4cGUfdt8+hDkF65rn235yC5TOWhp3lUJmnM8ELG+/3FwWm4S7mzvkYykxjSl1RTHzvGJvzNj0JQqcLMptm6WIK7fRG0bilyO/Y1HzBZZFsU6LZUtU8l+OM6o+X1Z+imji94jlcJZU2eM8tLOT83O1i/NAbEACJEACJEACJEACJEACJEACJEACJBArAtoyJywsTFmlWL/pGqvWL7hSdAodcYkWldw8cQjbxg6Aq7tSvgTeQdMfFyF9nsKo+NFIFX+mPcT6xk351W81blWkLhyfvqWaNmcBVP10DJZ93gzOSVMod0ehaPn7auX6LI1uY/Cx505E8nJVrI1dk77F5JYFkCxtFiRJlUErye5dPodtv3+CDCqejszJU8XR2TNhkJ5bpMlEkWGMmdmrPHZPHIqcZU2BsqOozmwSIIEEQ8ABJb6YgXBlGeioFk612FgdJJhD4URfOAGxCulSpjvO3jyFlsXbYpyy0rG0kOhRqRf2X9qD/BkK4ky/C0j3H5QsxuRjGtOoFx+2jsqaNmfqXNjScZOO9xMf5sQ5kAAJkAAJkAAJkAAJkAAJkAAJkAAJkMDLIuCwbt26iOo1Xt8b4QfnjsOeSdEHii7XfShKtusVLQOxWHl875aOO2MoXqRBeHgYngQGIGmKtNG2Nwp1P/dvm/pRSpq4StD9u8qiJ7VVs+DAB0rR5KHzHt66gVldSqPTnMOxnpNlZxKfJ2nq9JZZTJMACZCAFYHjpy+guGdkN5FWlRLpjq+vL7y8vBLp0fGwSIAESIAESIAESIAESIAESIAESIAESIAE3lQCzo7KIkcsP16XmzVR0sSkqInNyREFTrLUGSJVFfcisVXkSGPdT6rnV5bYKnKkT0ORc3TVLBya8xuKNO8ZpzlJH4ZQkWOQ4JYESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAE3gwCzuHKouV1KXLeDMTPjjIiLBQV3/sGuas0eJbJFAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAlEQ0DHzHmdljnRzC3RFXk17ZLojokHRAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIk8HIJOIoixzHuoWFe7qzYOwmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQgCaglTkhoWHEQQIkQAIkQAIvjMC9R0G4/zjohfXHjp6fQFhYGFatWoWHDx8+fyfxvOX+/ftx9erV557lzp07cenSpeduH98bnjt3Dr6+vnGeprji/ffff/Ho0aM4t31ZDWauAr74LfxldR/rflevXo3Fixfrj3CyJ6f9T6Lp1CYIj3hWfu/USQScOqGrB168gNtHDttryrznIOC/by8eXb+mW9729cGDC+etehm16Wf8s2eqVZ6xs3Yn8M6QZ+fJyH9V2/j0DOr9YzgWb4h4VYdudxz5vTLury1bttitI5nzD83D0LX/syqP6TqwqpxAd0IVnxt7diEk8CEi1P/jJR10547V0bSZ3go+Vw9Z5Rk73/0dgYkLX+85NubCLQmQAAmQAAmQAAmQQNwIOEp1J2enuLVibRIgARIggTeaQIRaA/ho8lLkGzgGQSGhZhYX/O+g5aiZKD30b5T69m9M8N5tLkvsiRUrVmDq1Knx7jBDQkLQuHFj3LhxI1ZzCw4OxgcffAB/f/9Y1X9ZlX7//XfUr18/UvfDhw9H27ZtrfK/+OILbNq0ySovLjtff/01tm/fHpcm8aruzz//DFkMjkoWLVoE4WkrJ06cwIABA2yzzfty7dSpUwfXrpkWyM0Fz5koWbIkxCJcPl5eXvjxxx8hysbYSlAw0P/3ULSpq/98NTd79913zf0a/X/77bfm8peROH78uFZ0vfXWWwgNffYMtBxrzPYxaFawqbKAfzbfI3/+AZ8/RutqZxbNx47+n+m0LEDPyJjR7ufElL8RePWK3TLJv3viuLlsXpFC2PPNYNzyMS3iHho9UpfdOnxQj/NQKT1lnG2ffaz3933/P3NbY/yrmzfi7OIFOv/4tEm6nnxdXLUC0r+lyLFIO/+9eyyzsbb9W5B5x1UurV0daT6HRo3Q3Ryf+re5bHXLJjg5YyrCLa6fdY2b4OrGf3XdXV8OwJn5c6yGb1y4Kcbs+xMPn0RWbFcvDSzdEo6DJj2bVbtXsfMinkF31GK+cf3LtkWLFliwYEGcpn9c6b9mrAlH3YrWbhuSJ09u1bf0v379+jj1HZfK8jvk4+ODSZMm4fvvv7fbNCg0CKN3/YamRZpalUd1HRyd+Jf5+jGudWN789ABrG3dAvu/f/bcEMWrlItiMDqRe83oZ3md6tj/4zCEPLhv1UT2pY53h2e/XdHNR+7XCyuXmfs1+l9YXl2oSh6q+967aXMEXr6I4MD7On376T1vDNzSsyVGbzM9a4w8Y9uqpgP6/xGGwMdGDrckQAIkQAIkQAIkQAIJhYCzTDQi/PW/meN3bB/2z/zNzC1LsYoo2a6XeZ8JEiABEiCB+ENgvc8p7L5srRwIU2+nfzB5GRoWzYvpvVrryd68Fxh/Jv2SZ3L06FFcuHABXbt2fckjvdzuZXF94sSJGDRo0MsdKIbe8+TJg8OHI1stiAVNwYIFrVrPnDkT7u7uVnlv0o5YXuXIkQMVK1a0e9jvv/++XYXDrVu38M8//2DECNNiuW1jV1dXXLx4EVmyZLEteu59UTx16dIFZ86cQd26dbVSp0mTJrHqb4E3kDuLI8p4WleXa7ZHjx743//+Zy5IliyZOf0yEv369cPp06cxduxYu92fu30WW67uwLcNhtott81MW6w4Wvke0dknpk6C//69qPbHX3rfJVlyBN01vXXfYN0aJM+S1dw8SZq0uHfftHDcbNdO9Td9OKT9tt490WLjNkQohZzI5bVrkK54SVzZqCAqCQ825Rfr+xmKfNALmz7ohizVa6JAx85wTZESF5Yv0fWOjPgZBdp1gJNbUtV3KIJv3dX5xtfFpYvhmi41rm7egAxlyxnZz73NUqOm5nBiyiTcOnQQVX4bA6ekSXV/Duq/K2krlUX1cRMQcPoUdipF2JM7d1Gsz6exGq9gxkIokCovFhyeh3fKvWvVxs0V+OY9J/w0JRxzfnqmfLOqlEB2NmzYoJ+RGzduRJs2bXD9+nVkypQpVrP/ZXo4PuvkBHcTcnMbsc6bPHkyGjZsaM5LlSqVOf2iE6lTp8Y333yDGTNmYPr06Xa7X+G7FOmTpkXJbCYFh91KFpkF3u6MPC3e0jlben6AjJUro2Cnd/R+klSpUXbo91hVsxbytm6LlPkLYu+w/6Fwn15I61XMohc7SXm7RUnz3bvw5P49HB71Mza82wX15i2Cg6PpWrqh7k25T278u1lb0LilSYOY5hN45RKS5sqGRitWmwd1sFAMmzOjSDQr0gI/7/wVR6/7okhmL6tannmBysUcMGtVBD5oZa24s6rIHRIgARIgARIgARIggXhHQP+FKW9XvQ4RBY58Vn7VGUs/aYAre1ebP3smDcH4eul02cG5417H9DgmCZAACZCAHQLiQm3Yim0Y3ry6VenB89dw50kwPqpfCcnUIrC7WxLkzpjWqk5i3BEXX2JxMHToUL0wLmn5yFvSImIRI5YD8mazKCEWLlxohUEWrMaPH6+tYaRO2bJltVsrsUoRqwjJEysDY2vVOIqdQ4cO6X6kjczLUtauXavnJ7/9Mp9x48Yh4uliVM+ePVGpUiVdXcaX4/jtt2cvWki/NWvW1G9oV6tWDUeOmBafLft/UelcuXJpdrJQL8x++eUX3bUoAfLly6fTS5cuhcxDFiy3bt1qNXSjRo303OUYxApk2bJl5nJRYrRu3VofR4cOHXD79m1zmbjMEiuWnDlzauZ9+/bV50MsMWQsW5daRr7B0NyRTULevP/888/N50XOqWGVIsckvOWcyKKrjGnpFk/m3qdPH/z666+6XOoI+ylTpuhzJFZJ0kaOtX379uaRxb2azLlp06ZaQWcUBAUF6Xl07NhRM5Z28rF0ZyTXZfXq1dGpUye9GGy0la24XpP6Ml95+18UPoZEx13qeHh4IEOGDPo6K168OPbs2aObyjiW94bcP3IvnD171ugaG/aGo0El+3+zSr/CxfikSJHC3C66xI4dOzQj436QYxOJ6jqIri/Lsn2X9yKnR1akSpraMjvKtJN6ZiZNn0F/XFOmgrNSnhj7zuo+NsQtXXpzvpQ7OjkZRUiiFsBT5s2Hwt3fR+DJc7hz8rguy9WpLc4tXKCtWGSbp2tHcxtXdw/dn2MSV6XESaHTTkmS6HJZfE5Z1BPnVyw117dMiBuze0dOoNxPP+Lc/Pnq7TDTorZlnbimnZO46Tm4KOWsk/oNkWOUORoi80yWOQuyVKuBst9+B5/vf0Too8iWNkZ9223lnJWx/aJ9K7xKanF7iXcYwuLgbS26e0HGlme4WMbJfSHXmNzHItE9g6R83rx5+rklbeTesHxGyUsDcm+Iqz+5D+U5P3v2bGmmJY1SFIgCViwyReRZERAQoNucOnVK58mX3O8yP+M5JHkLNoRDONiTtGnTmu8vuc/c3NzsVbPKk/tInlPyDJZjkd8P43kRGBiI3r176/nL8/bPP/80/xZZdRLFzvYL21EtZ9UoSiNnu7gn19eTXFNOyZLC1cN0vev7yMUFaTyLwLNfH+z7figurVmFeydPoWjffpE7iiInqXqupStWAhV/+Bk3t+7ErYP7zTWvKIuxwr16InW5krixa4fOj2k+RmOZn/FxS5fOyI5x6+7mjiJpCmLfJdMz1rZBnXKO2LDnv9+ztv1ynwRIgARIgARIgARI4OUScJbFB/mT/VX/KScKGlHYGJKtbEOU7tgXmTzL6CxDgSN1RMkj23Ldh9JaxwDGLQmQAAm8JgJj1+xEt8rFkSVNSqsZXLtzH4XU4t/guWux6Mg5dCpTCJ0ql0C+zLFffLDqMIHseHp6YsmSJRgzZgwuX76Mn376Sc88ZcqUekFYFtdlEUzceJ08eVIrEW7evIl0TxdlxNJEFC6fffYZNm/ejGPHjun227Ztw6hRo5A/f379RrS8ZV2+fHn06tUL6dOnj5aOLBjKIt9ff/2l3262rCyLayNHjkShQoUgigixjhClTu3atXVdWfQrXLiwXvyXBTZZJBeRxUfpU5QSogCaNWuWtrA4eNDkvslyDMu0LJbLGPbk3r17cHbWRsKRirNnz67zxN2bKJREWfPRRx/p2C9586rXipWIsqFIkSJ4++23rRY7pUxYiiJA3iYXF2RSRxYPZUFRuIjrMMkX93iWC6GyOCuKEXkjPKNyi9O9e3etfPj000/1HGQhVayGDNm7dy9EcSD9RieygClvmM+dO1cvgsp86tWrp61pxJ2ZKPwmTJiglYCdO3fW515Yi9y9exd//PEHmjdvrucqbr0c1RvfLVu2RK1atfQ1JQu+olhxUYuShmTNmlUfvygLRbFjSBK1WC/ul3bv3q3HletXxPK6+vDDD7U7O1mEffLkidFUu9+TBeDBgwfra2TIkCGQ+RqKoOi4SydiRSX3gZzP+8qixLBkE6siUdi1atVKj7V8+XI8fvzYivXh0xGorRYg7YkovKS+IV9++SXk+KMTOZeV1dv54qZPrNHkvjQWzaO6Dr766qvoujSXnb11FvlTm65Tc6ZKFOj4jlnpkaN+Q2QoVdayOMb04V9/hih7RBwcHVDmq//ptPEVrq6Na5s36V2PHLn1NlmGTEhfrizOLZ6PUBXLLE2Rosot2m6jSbTboj37YOeAz5RFQ+tI9fx2bEOm+rWQpUZtbOveAwFnzyBVvvyR6r2sjNSFCuuuHymFeYrceVBt2hSkLFBQ55XsPxD2Fr5zpc6JGUdm2Z1S9qfGK1f9gRyxMGSRZ1N094IMIs8Y+YirMHERKRacItE9g0Q5265dO/2Mld8XUfyOHj0a3333nW4r9+O+ffu09aRc5/I8Ml4ekApi/Sa/P6IcFau8KlWqIKmybpJnqjx/jOeKKFlKlSoFp6cKwdsBQND9COSM4thFyb1u3To9B7Hak9+nmESeLd26ddOKGrHqkWfOgwcPdDOxCPT29tbPYPkdlGeB/PbUqFEjpm51+cm7Z1ApV5VIdWNzHURq9DTD66M+WFK+LLau3YAas2daKRKjamObL8pGUYTeiWFyYwAAQABJREFUv3QR6UuXhdyTl5YuQ41p0/W9f/nftcjZKHbWiI8vXMHe774xDyH3V/63OyGpUqZVmTxRKTYzw1lZ7kk6lfpNt5W8afLi5O1nCjzL8jzq8fjzDNFc2n+mWtZlmgRIgARIgARIgARIIP4Q0MqciNegzTEUOaLEafy9+uPWRgwXa7IVyx1DoWPk21TnLgmQAAmQwCsgINY3m05dxPLPOuH09VtWIwY8eoxdyvXax7lLwPvTtzF96yF8v2wzpvQwLc5aVU5EO7JIJkoPUc6IskDShsiitSzMyUK8KA9EMSLKB1molsV7QyRPFCwiZcqYXmqQtCzCydvPsphfrlw5iOsoWbSzXHSXepYiyhhZKBf3Wbly5dILfitXrjRXkQU1iUcgVjZioVGgQAHtLkqUOfK2tSwCiojbLstjMfqQeZw/f14vAg4bNkwrhGQBLioR6wtZeLQVUX4Yi4i2ZbIv85DjlbHkeKpWrapjKIilk8xNRNz8yMeYs860+BIFmSzWi0Kif//++o1wYSIWPWIlU6FCBcj8LGMyiHJH3mgXqxURUSBJ3AZZxJc5yFvucg5k4VEUWWJZIkql2IgoY4x4P7IVhZ0oMYSfKNTkrfmrKqZJsWLF7Fo9ibJHrFosRY5fXMzJubM8X1JHlDZixSRKKVGcGSLspa4oH+WatG0n9TKrRUJ5w99WZM4iosyR/sUdn3CR8yLjiETFXcpk/nIO/Pz8tIJTtrIYLUoceUtfGMg1KcyFvaWS7OjxcGRM6yTdRBIZWxSUhshic0wii93SThbZRTkm58CQ6K4Do05028v3LiFP6mdKP6NuhjLPlDdpPL2M7Fhvk2fNpi1wpIGty6UV9etAFn9lIbmBsiyQN/8NydmoKbZ27YbSw79T7YzcmLdZqlRVFgzuuKzcu9nKJZWXtVZtveAtSp3r27e8UmWOy1OLneCAu3pqORo0Mk8xi7LcsSfp3TPgkYq1Eqpcxjk7WiuS0z+93P3UT1tslDmxuRdkDh9//DE++eQTPZ0SJUrobXTPoGnTpunfAXmuyfNAnhHiQlAUp5bKWnn+GtY30qmh0BGrHLnP5LkncbHk90N+p0Sp8t577+l7Vn6rpk6dqp9hekLqy+9WhE5miHzb63x57hr3mOU8jPb2tqJIFoWSKIdFLJ81cpyiJBdrHRFRdovLyNgqc64/vIEM6nzaSmyuA9s2xr5rcnekKV0SfkqZk9arqJEd523S7Nnw5KnFp8SyEfeEaYsW08qcw9/9gIrDR8KwgIupc/enLzZIvaTKMk9EXCHmatxMp+XLMm3OVImM7hmx68ouyyxzOkNaB9zxj0BoGOBs/7FqrssECZAACZAACZAACZBA/CHgrP+TbPrb/bXMSpQ04k5NrG5EDGWNEUNHyl+3hIUE4/SGJShQqyUcXZ698RrbeZ1cu0C3y1+reWybsB4JkAAJxEsCQxdvRMtShXDuxm2cVR+R41f8UThbBqRQLnFEutUsA4+kbuhctQTq/jobdx48QhqPZLrsTfu6cuWKPmSJrSEfEVGaGNYuOkN9iYWFPZEFafnIQpyItBMrjujE19dXFxsKD8OKxWgjFjWyuCYKCLH6kUV+S4sGo57tVt6cloVveZPaELEAEoVQdCKWNxL/wJ5YLtTbKxdllrgSEgWUpA2FUkwWF0Zf8la7iKHsEUsQif0gyiXDVZuwFWWaIbJ4Km+rGyJ9GK6JZJFR3OrJAqm8YS8KsU1KWSdWWbERUdIYIgutoqQSJZOcM7G6krFkK9eNbQwgUfLZKnKMvl7lVpQvMhdR5IjINSQilluGMsced11JfYmVlsS3kWtHFGpicSCu/UQZJdYI85W7LrFmEzaStpQihR3VgrNlzrO0cBNlUFxErKXE/ZUocmwluuvAtq69/ewpc+Dag+v2iv5TXr62b8NdKXTsicSXCX0ShF0DPseNfXuRrmRpc7XMVavpeDPZatfFta2bzPkxJpycUPTTfvD5fTS8en5krv5EKVCur16vrHy8cF7FzRE3cZdWr0Thd7qb67zsRIgK/C4i7uViKzcD/ZHS1SOSIkfa37xj6iWzab08xi5jcy9IJ2I9ZykxPYPkJQCxvhOXmIaIEkbaGc8yyRdFtT0RRbQoqeX+EgWlWK2JMkXuPbGKkXtLXi6Q556hXJJ+MqUzafluKA4p3CP3LJZ/zZo9UyBErhE5R+KeGYpxy1LxDCG/KZbPXnmuSF5sJXPyjLgZeCO21WNV78r6dbiz/yCytWiCg7/8hEo/jYpVO9tKjy9fgdtTC9qrWzbBvWAe7brNcAl46+ABZKxgP8aZZV8SM6dw1/css+KUvqH45EhhsnK1beh/OwKZszlQkWMLhvskQAIkQAIkQAIkEM8JmJQ58WCShqWOsTWmZLhf2z/zN22dY+Tbbg8umIB81RrBI4P9/+Da1o/LfuBNP2wbOwBZS1ZR/WeJS1Nd9/rJA3BN5g4qc+KMjg1IIFES8B3TF37bJyNrvU9R+N2h+hgve8/Ayck94ZG7KsoPXxWvj3uVz2nI5/4Tk1Lhi7nrMKF7c6RNYXoL3EUt3os4q0VAkeCwUL1N7F+imLCMPSDHa1jQyMK1rVLFkkdUyg7LOrFNG0oKcQEkC+SyaGeIzE8UOeJeRyxDxOWauN2xF+9FFhMtxViol7gt9ha/LetapsWtTlSWK2IhFN0b3kWLFtXur+StdlnoE1disvgXnUWP5dj2lEVi7SOWH6IwKV26tF40NVwfSVs5Z4byRvbFMshQjIklj7gwEo7yxrlYdkhbywVRcSMmfYuSQOZvKRIbxxDp1yj/8ccftaXP2LFjdbEsvNouahrXktHecis8bM+XZXl0acPlUXR1LMvEZaAow4SBjGsoLC0Xme1xt+zDSIvSR+JkGCLWau+8847elThIxjVnlJcs6IBz1+QNpDiYlqjaUZ0TuT/EOsCeRHcdGPUN6x9xe2WkjbL86fJh99Xdxu4r2YqbJQnkXunX0fi3ZWurt/Ul7kzDxStM84iLMke1yF63IfYrV5AXli8xH8cNFexdLICeKKuPG7t3aldPV5evQZBS6tlzb2Zu+AITt48e0b0lzRiFXzA7Y52/cwEFUuezUwJc9DNlZ7FR5si1blhOiiJSrOFEYnMvSD3b+E0xPYPkeSNKcMt4ZdKPrdgqfG3LZV+ecaJQEREFbL9+/bT7NnG7KBZDlpJWHZZbCgdcUhzym4wfLYujTUd1j8mz1sfHJ1JbeUbI/S3PQUNESW5puSP5cl9F9YwqlKYALt69aDT/z9vgwAfY8UlflFZu7TJXropFJUoif7sOSF/qmbVsbAZ5oNyriSWOR85cuvqFRQvhnkvFgFP3iYgodq4pBU9slDm6wX/4OnP7NOrlq2e3h7NXgPJKQU4hARIgARIgARIgARJIWAQcZSEnjv8nfiVHKEqc5qPXaBdsRhyd6AY+tmwSHt99+kpddBWfoyxllhx4b9mF51LkPMdwbEICJJDICYQraz+R6xunqIDUpgXzqxum67yw4Ed6G1+/FvfriOWfd9afsZ1NLm2WKZdrudKnRqncWfW0l+45isdK0bPy4AmUyZoemVKliK+H80LnJW9Cy5vUojzRv62qd3FJIwtzEmtAlCuyKLhr1y6roO4vdBKqM1mgFoWHuFkTqxtxpWOIKGFy586tg2GLIkUW4MQ9lqWIpYooJ9asWaNjpRiKHnm7XOpKv2LJIxY54iooJqseccElY9n7RKfIkTmJYkrGFEWO8JW0peLEct5xSYsllBy7uCWyjJcjfVSrVk27wRMXaqJQkXJxjyYiFjublCWOSOvWrXV8JGFtLO5KvijKBg4cqN3Pyb6lCC9ZWJU37yVmjaHkErdIsmApjMRtm7gbiouIGyaxYJLzbVx7sWkv7t3kbX+5JuXajI3IuRARLjKeHK8s2IpbttiIuAG8fv06JAaUKHIMt3PSVq4x4SAu3Lp27RqpuxqlHbF2Z9zNyaM6J/Xr19eKO+OaFusiUT6KRHcdGBOTe1sWpEWp9/DhQyuGpbKVxsUHVxHw2OQCzGjzX7eP/a7j0fVr5k+YumZsJXOlqkhfszJOTJtkWxRpP/hegO4r/EkwnjxNi3WPpYjVTbFPPoUoawy5ssEbOd9qiQrDR+hP5V//0Modv93bjSoIUtY7lnMNUvdbTBL6+JFuI3MJefRQp4Pv3zM3k3kGXrmMK95rtYKp+JBBcE4ae8vPHZd2oFIO+xYRu3wi0LSOE5xs1rfFGlLuafnINW/If7kXonsGGWUSZ03uS3lOidu/2IrEfhKrM3neyH1qxKGS9h06dNAKcokJJZY2ttK6liN2KA5xlajuMbG2k/tcYmrJs0mU3xcuXNDdy/gSm0ys4CT2mMxX7jtLEbeeEnNInpvyrLKUSjkrYuulbZZZ/yl9ZMxv8CiQD7mVIlTi3si1teebwYgQP2SxkIfquea/by92DPhU33/pi5fE/fPnEHjyHMoP+9F8rxTt8wnOLVxgjp0VXddhgaZ7wPI+iq6+ZdnDJ4E4dvc0Sme3r4z6d284apSJm2Lcsn+mSYAESIAESIAESIAEXg8Bta5j8z+W1zMPq1GNODqxUeJIw3XDeiLQ7yxWDGyNlV931X1d3LMZMzqWw5RWnjg0z/TW5+UD27Bp1AAs/7Ij/m6WC0GB9zDnvRrYOWE4JjbKhtndquG6717M+6C2Lj+6apbuS+pNa1cM4m7NaLN78ghdZ/6HdXH3kulN24t7N+u20tcKFefnwQ31ypONyLxmda2k2677riciRJlmIfumj8bGkZ9hZpfy2v2c9/e9EBYagkPz/8L28aY3+KX68dVzsWXMYIuWTJIACSQ0AuEhAbhzbLd6s/kGAi/sSGjTj/QiQHI3V0zs1BBfLd+Kot+Mx+5zV9G/cZWEd1zPOWNxeSPWGOJ2SiwWRHkjbxWLazBZOJNFX3nbWhawbN80js6SwbbMdt/edH/66Scd1F2UDGfPnjVXkbYSH0RiL8hb2qJkqlGjhlVcEqks5RKPQeL1SIBtEVGsLF68WMcxkTfLRekjcWQMZY+uZOdLxhSljb2PnepWWYY1kyhyxFJCFs8t4/OI4kr6F75itWMcn9GJ7FuKsd+9e3e9uChv1stxSr+GyMKnLECK4sZ4S1ziwojIeHIeRbkj8WREUSUu4GIr8pa8KKNEySdWPoabJJmPxOKRcyLxIywVHLHpW9wYiXJNzrelKzcj5oy4cps4caLmY8SnkH7l+EVxIsoguTYNN3by1r6wkvMvIte07G9Siiw5J7I427lzZz2eLOKKMsTSWsrgrBurL8t9WRAX5dWAAQPQtGlT/PDDD0Y1fY2I5YBcX+KO0FZa1QGOnguH0hNbieXYVgUx7Mj5kPmLNZCMKdeYYSkQ3XVgdCvHJbF9xGpDrCTWr19vFCGPssypmLkMFh1Wi7YvQp5ey2tV4HSxGDA+d475CuBIIxTt2QfHRyu3aw+tF8BtK/qMGa37ur1jL3x/HKnTN3aZLAgs6+Zu1lIrayRPFrfPTZ2prReMOo7qmZejZQtc2fCMgdGfMdfdXw80qke5vbZls56DzP3mxu06fXSC6e94ifEp81xSugyOjPsDRfv2RZEPY+9a77T/SZwKOIvWxdtFGj9YGZr+PCMM/btE/n+R5fVr2TA294LUt9c+umeQKIq/VdYh4lpS7ku5T41703J8e/1KubhTy5Url7YeFOsey3tenp+ihLJn+SZt+3V0xC+KwyNrfZ6+P6Q8riLu4cSaSRTXcp+KcsZ4AeDrr7/W6WzZsul8sUg0FOfGOHIccn+JK8bkyZOb4wJJeZMizXBNxc3xuXrIqP7c27vHj+G4UkiW+07Fz1LzFCnUpTsenruAc0tiuIef3n/LK1XG7oGfI71yb1jz72n6vvTbuU1b4njkyGmeW4ZyFXRsq4CzZ8x59hMO2sLHuH+MbWyVSyuOLkPRdIXhlaVYpO6PK4Oo7Upp16GxuqkoJEACJEACJEACJEACCYqAg/J9H1GtWnW7/xF8mUcicXKiEkOZY1m+UilHJH5Oj3W3LLN1OiToEaa+VQANf5iPjAWLI+jeHczqXEJb9qTMlhuL+zRFvcETcc/vMtYP7YTKH49CwbqtEabePJzWpgDKdfsOBRu0xpJPmiPkcSCajliI2+eOY/OvfbRFjvQn9bovv4JQNZaky3T9H4o06QjvH3ojXR4vVHz/S1w/uhfOLm5Ik6cQNv2sFiPSZdH5m34fpN2sVXpvkFYwVXj/a+Sp2hA3T/ogo+czv/xyMFLXz2cHGg+fod9oXPp5UzQcNgdJU6bFwp410XXRKbi4JcOCjxqgZNveyFu9SSQezCABEojfBHx+7Qn/PTPg4JRMudlor1yrFcXpGZ+q2Fqp4JYhLyqN3PSfDuD46Qso7pnvP/XxXxqHKSX1vYdBryVOjsQekVgk8VFuq2DI4gpLFoz/y4sUojyJzopCFv9ExPWTvEVuL86KtJf52CuLiZ28XS0WMqLMsbRIialdfCsXBvIGuzCwdz4kvo4wlPP1IqRLly5aQSQLltK3PfbC9b9eHy9irrHpQ9iIxYAot+zxi00f9uqIIkssfUTJZk/GL4jAkTMRGDMw8qK7vfqxyZNrQeKfiLtDUepYyn+5DnyvH0GPpR9ia4+tcHR4cfO1nF9CS4cr1g5RGX44OsDhJb5k9t26b5E2WVr0qtI7EraVW4A/5oVhzRjTQn6kCtFkPO+9ENMzSCyC5JkgimPb6zKa6URbJNYt8owRa7IGDRrYrdv+i3C0rOWAdvVf3EK/KJuNuFq2Fpny4oP8ntjGkrM7OZvMabsn4/jN4/ixyc82JS9wV/3mRoRZv3xn2buDc9yvGcv2Lytdf1I9fFfnO5TLWT7SEF/+EYH0yq1ev84v7hxHGoQZJEACJEACJEACJEACL4WAs/xHwkH5E4gIj+p/Vi9l3BfaqSg3HNTilatbcq3oOL1xGVySp4GfsrKRj2vyFLiw0xupcxeCe6a88GraRY8vyhyRoi3fhXMSN2Qrq94CVX+wp8mZHx4Zs2LDD4HKddtN9R/LyH+kF2/1nm6Ts0JdnN+2UveTqXBp+B3bj12TfsDVI9vhrpQ5tpKjUn1s//MrPFHWPgXqvGVbrPdzVKinY/9I/J+cFZvi4p4NEEVQ6txeOLdtDbKXqoK7532Ro4KaL4UESCDBEkhf+i3c2DUH988dQKoiTXDvxIYEeyyWE3dSi3FpPKwXRC3L39S0vF39IkSsI2wDalv2a1jKiJWHPYWB1JU3pKMqs+zLXloW7mPrUste+/iSJwzE0iYqsY1zEVW9uOaLtYth8WLbVhQjCUXk+nqR14G4l/vrr78wf/58XHjqhskeix6tZfHxxS5AyrWQNavJTaTtmP/lOvDKXBTbP3zmdsy27zdx37tdK9zcGtnyR1iUGzUCBTq+89KwfF3vmyj7blwNaFwt8t/7UTawKHjeeyGmZ5AoPcRq5UWJuHaUuFyiLK1Tp06U3c756cUrHuWZF9WxPO9vkRzAO+W7RXkcL6pALNW8W7SMsrtOSuEWH2Vt93VRTuuHj1/sMzTKgVhAAiRAAiRAAiRAAiTwwgmo+NTqPy7xXJHjd2yftsqJ7dGHBgcpBYwzkj9VphRv1ROpc+TTljlOrkmj7MbZ2Q2hIY91uZOLq97Kolh0f+46u5pckEjlLb+Jdc5uVPtkBFJkzY2Tq2fqPiy/qn30HfJUboh9//yCfdNHoPOM/eptfBfLKlZp8Rcertysichx+C6dpK2HclVuBpckUR+LVSfcIQESiJcEstbqoC10Hl0/hP+zdx5wUVxdFD8CKoJYsWEj9t577yYao0ajxpaYaGKJmmL3i8YeS2LvsWuMxt577L03VBR7Q7FQFFHgm/Nw1t1lWRYEBbzX37Az8/p/3q7wzt77crccgFPnbI+JHycHJJ16JwQYmovfZBaLXwS4V0VMefnEr5Hb1luGJGRYKYa008Pb2VZScsUnAtVnz9N+r7W8B0liJ/m9NjafJQUVhj1jaEjdgzM220sodacrVRpNPTwSynBkHEJACAgBISAEhIAQEALxnEBYLBbG+tVEi3dpZb4djMOzBkTYJAWcY4vGm4g4LBORObqkh//De0iftwgyF6uAA5O9kSJjVhXG7NmTB3BMkUaJORGVj4n7XnvXouov45GpQCl4/rfatMpgzUVfY3zj6G5kK1UFGUYsxOwGWeHrfRvPtf4x7rW+R9DTm15qU/Qnt67h9rEtyF9/rqrrIy00265x3fHs3/uo0n2Maf1yJQSEQLwjkEIL0ejoWgBBT+8gbfHq8a7/0uH3Q4CL3iIKvB/2b9NqRCGN3qbOhFSWewnxEEvYBJKkSJmwBxiHR/fppxKaOTqPh1+6c9RC3YkJASEgBISAEBACQkAICIG4QCBMzHkPPSnevDN4nFgyBXdOHzARbbg3Dg8a988p2aq7OtfFDnVh9qPQ5x2wfdg3OOyWCy3+2onKP03Cmh6fwSFZCi2E3Cs0nhBWn0mx1xtW6vG5LW0kqu4Z5zM+1yrTonsbqizeohu2D9VCtmltpstXUhNowsI1uOUvpfbfyf9pSxxbMBrbh3fQxJoguFdsglSZ3bFnUn8VI/zTYQtUXffO7sfsxrkQHOiP/A074aNyYaEQHDRvofyffguPdbM0waq8oV05EQJCIL4SSIRivRciRPMmtLN//XEs+yrE14cp/RYCQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAKxRiDR1q1bQ6tWrx4n9szRhR19tBRxrAk4ej799YWfr9r/J4lTcnUrVNuk+bmvD5KldFWeL3q+2HwNeh4AO4fEoPBibM+fPkRSl9TaJsH2eBngp5ISO7uo11cvg5QkxNBuOyf0A/tfuvWPYXm0/YCMbdfY3rB3TIZKnX4zvi3nQkAICAEDAQ/PayhaIJfh+kM6OXv2LAoVKvQhDVnGKgSEgBAQAkJACAgBISAEhIAQEAJCQAgIASHwARBwYOiv0DiyZ47urRNd7kldUpgUpceNU6p0Jvdi+yJJMmeLTVBQ0k0XcfRrc+GH9xObiTiPb13F6X+naeHbluDL2Yf0ovIqBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgkcAJKzGEoMYo6Yu+fQK6qDWDvED76XUjwS6TMlgtfTNsNZ9cM77+j0gMhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQuCdELDTjBu/iMURAlmKlkemgqXD9SZt9jwo1qQDUrplC5cmN4SAEBACQiDuE/Dy8gLDwMWGPXz4ENu3b7ep6uvXr2PlypXquHDhgk1lJJNlAlHhbrkGuRsXCAQGQdufMRjX78SF3kS/DzU6BuOEvKWjD1BKCgEhIASEgBAQAkJACAgBISAE4jgBO+WVE0fCrMVxVtI9ISAEhIAQeE2AzpxdZq9Grj6TEPjylbr7956T6pr3jI9Hfs+Em0ZgxYoVmDBhQqywuHjxIj777DOb6n78+DFOnz6NPn36YP369TaVeZ+ZgoKC8N1338Hb2/t9dsNi21HhzgoonvXq1ctiXfHl5ubNm9U+hPz90dnZGe3bt8exY8ds7n5cZLBkM5AtYyJkd7NtGJN2LYXziC/DHff9HtlWQTRznblzBe0XD1ftLjseXrxt84kdhv4VEs3apZgQEAJCQAgIASEgBISAEBACQkAIxHUCDsHBwbC3S4RgEXTi+rOS/gkBISAE4gyBbacv4dDN+yb9aVymIOoUzW24t2jvCRy5ehdpXJwM9z7kkw4dOuDVqzDh631yKFasGHjcvHnzfXbD5rb5e8rMmTPRr18/m8vE1Yz05Jk/fz5GjRoVV7toc78ePHgAX19fTJs2DV999ZUSCJW3dyQ1xDUGr4KBvpNfYdEQ+0h6/ib563KfoknxGoYbE3cvxZ4bHsjgksZwL6ZPfAKeoty8/6FT/gpIbmePEO2fuTWpnQidBr3CaU87FHnzUWyeTa6FgBAQAkJACAgBISAEhIAQEAJCIJ4SUJ45ouPE06cn3RYCQkAIvAcCT58FYui6vRjesKpJ68mSJoZrCmd1pEnuhPWnL+OLMgVM8iS0CwoNFSpUwKVLl0yGpt/39PQEw6tVqVIFDRo0UKKEccYhQ4Zg6NChqFevnvJy4CJ/SEj4RVrjMvr5P//8g4wZMyJ79uxYvHixflu93r9/H+3atVN15s2bF8uXLzdJj+ji8uXLqFu3rvK8YN3du3dHQECAyj558mTlzWNctmXLlli1apXxrRg979Spk+LLStmv4sWLY/z48YY2Tp48ierVq6v+kvGZM2cMaTypVauW8ogiX3qSdOvWDTdu3EDp0qVVXYUKFVKeMhzr6tWrTcpGdGGN+x9//KGeB9tiGzt37lTVBAYGqutWrVqBz4bj4LF7925DM0uXLgX7w7KtW7eGj4+PIc3aybVr11TdGzduVHXSW0afD5x7+tiN2+vRo4fFOcH79CCjLViwQM1bfSysy9hcXV2RI0cO9VzOnTuHJ0+eqOSI5p41BkuWLEHfvn2Nq1fnZK3ft/asraVx/JwzHD/5rlmzxqQdr9vAI+9QlCpge8zh5EmdkCmFqzoyJE+DZRePoEOJuib1xvSFi6MzrnSZhDGNuiKlQ2KL1afQdPOalexw4JTsg2kRkNwUAkJACAgBISAEhIAQEAJCQAjEcwJ2oVqsHNv/fI290d47fxTr+7cxHCeWTIm9xqRmISAEhIAQiDaByZsO4JuKReGWJmWEdZy6fhdeT/xRvVDOCPMkhAR7e3s4OTnh+PHjJsOhKHLgwAFky5YNmTNnxuzZs1G2bFkl7BhnpHfMr7/+CnrtUBTp3bt3uDzG+fXzp0+f4ssvv0T//v0xb948rF27Vk9SYlCLFi3g5+eHffv2YfDgwWjatCnoERGZvXz5UolAFAgoDnAfnj///FMVo2g1cuRIw6I9Q4xRNChXrpzVavfv369EJYoM5kdknkoDBw40CBP0ziGjNm3aqPY4Hi7QV65cGefPn0fVqlXRtm1bk77wGTB/nTp1cOLECfUMGLbt6NGjmDRpksp7584djBkzRrE0KWzhwhp3Zk+RIoUSQ7gvEYUbCk0Ma5c0aVIsW7YMo0ePVvOF4+BRqlQp1QpFn+bNm6s+UJh49uwZxo0bZ6EH4W+9ePFCjYeeSxQ+du3ahbRp04K/37HOJEmSqHSKYWT06NEjpE+fHtu2bTOpjPmnTp2KLFmyqDlIlpybd+/exbBhw8C5bmw9e/ZUvBneb+LEiUiTJo3VuWeNAd8jc+bMMa5enW/ZsgUZMmRQczeiZx3ZPCCPKVOmqOf99ddfq/cNx6rb1VuAY4pEcHHW70Tt9cDVM7gdFIgGRapErWAUcyexd0DGFGkjLZXPPRHOe70ZX6QFJIMQEAJCQAgIASEgBISAEBACQkAIxBsCDvzGZbD2LWC+vmujgEM7tmg8bh3ZaNI8rw/PGoAspT+BW5HyKN68s0m6XAgBISAEhMC7J3Di6h3svHQda39pDc+7EYsDa495oEXx3EiRzPHdd/Idt1itWjW1WN6wYUMVvoyL9hQ6atasqRbx2Z1cuXKpRWmKAebGBffGjRur21zcpzDE/NbsyJEjqr6uXbuqbHyl8EGjNxDFAS6wU6hwcXFBwYIFleBDbx1rlj9/ftCTh55Gt2/fRpEiRQzeLgzNptdDgYTjbNKkifIOslZn0aJFFR/zPPy9w1wgMM9Dj5mUKcNEQwpj9ELSTd/vp0yZMrh69SpKlCihvJw8PDzAcehGNj/++KO65BgotNEqVqyoPFrKly8PHqwjMrPGnWUpyvEZ8xlmzZpVVUdhJ3Xq1KrvFO/4PIzHwUwU5PjsOVZyZ39+++03DBgwAIkTW/bCUJUb/aCHV/369Q132BZFK3pUlSxZUjGhGEdxjV5Ds2bNUnk5JziHeVBEovfKvXv3DPVQpKEYZm4cA4VMij/cg4neaGRrbe6xjCUGnGf06KFwRGGSwhuFpQ0bNuDbb7817O1k6VkfPnxYdc1Smj4PfvnlF/W8OTaKUHwm7u7uqtyN+6HImz3878BzD65DcKgWg83MqucuiRyuWQx3Fx7bjGbZCyG1UwrDveie2Nqmtfozp0uE/47Z5t1nrR5JEwJCQAgIASEgBISAEBACQkAICIG4R8CB307UYq3hXX+Hj543FGt0o2hTslV3ZCwQ9i1V3TOHeXRhp8y3g0XU0YHJqxAQAkLgPRAYvPI/NC6RD173fXBFO2get7yRP0t6OCZ2UNd+zwMx/6gHFn3TQF0n9B/0uKFXBDeBpwiyY8cOtShNrwxbjB4HunGxWw9Xpd+z9Mq26CmjW758+fRT3LqluRpoRlGHB43CEkWEyOzs2bPKe6VAgQLqlXUlT55cFaP4wjBl9JBheDWKRbogYK1eBwcHJWZYyvM2XyRhuDR6bWzdutVQNfvHcF7GVqNGDeNLdU4RgkZvEXqusI8UMiIza9xZtk+fPooLhb106dKp6ug5E5lR/KOX0ubNmw1Z27dvr/qki1mGhAhOKE4Zm+6JlSdPHnWbY6YYR6GGnlqcq2TI8G7c/4bePPRyYj6GT2PIOF3EIVd6eBn35YcfflD1duzYEW5ubujcubMhNFxU5x49mihmcf7R24sCDVlS4KHQw/dURM/alnnA+UzT+8+9fnTLliERLl4P/1vw4ZseeKkJVOZWxC2XQcx58swP86+cwJrPfzLPFq1rW9qMrOLbD0KRM3N4cSqycpIuBISAEBACQkAICAEhIASEgBAQAnGfgAO/FcvFFOOQE++i27qQQxGn/rAF4ZrUPXH4yvBruqCj3w9XQG4IASEgBITAOyGw4bQnePi+eKna671kC2Z82xDu6VKr6x1nryBVsiQomTPMM+GddOo9NkJvD3pAMGzWjBkzwP0/KAxw8dsWs2XTePN66HHA0G260dNAN11E4AJ8zpwRh7lzdHQMJ2D8/vvvYCgqenPQuFDPxXLd6EH0/fffq5BYDONGkSgyO3TokArvZSkfQ57Z6nliHpKNi/u0sWPHwhpDCgUxZda4UySh5ws9fNzd3VWosgkTJoT7/YrczI1eRxSUjPcDMs7D58v9YyisdenSxTjJcK6LbvoNegPR+PxSpUoFhtDj3jb0tOE1hR2Gmvvpp5/U3KVHjbEA+fPPP6s9kw4ePKg8sDjPLXl2MWQbBSAKUronTGRzzxID7m9EMcvf3x/cK4meORR4KEJae9b0lqJZmwfWRMMcmpNNoG8ofP21MHlhuqWqb8oXPdWrtR9rTu9Ccjt7VNG8dcyNHlYMV0iBlt5LtpgtbUZWzzktxFrjanaRZZN0ISAEhIAQEAJCQAgIASEgBISAEIiHBNSeOQyN8b6MIs30Oq6gJ47ujcO+6HvoMI154rsFvwzChc1LEaItpogJASEgBOIrgZU/t8LaHm3UMblNPTWMNVrINV3I4Y3FB8/i2/JF4GD/YSwoUjyh9wM9GRgyjWG2uFcLF79jy7hPDT0ruKcNQ6ktWrTI0BS9dCgOUEjw9vZW4a+4IH/lyhVDHp7QC4ObwdP75vnz5yqNHhZcaKfIQu+IBQtMv2zBsXIvGIYT44I9BaHIjO2wPkuHLUJOsmTJFMtNmzaBXi76l0/ocUPPjfnz56v+0yNn9erVhrFE1q/opFvjrtdHzyrOAXoumRvFDgp9fB7Gv3tRJOMz5B5HvM99bdatW2cozmdET5UhQ4YY7kV2QgGBIgj3omF/Fi5cqIow5Brt448/Vnv4UJBj+5y/+v5HFI9OnTqlwuBxHru6uiIgIECV039QvKKAw719OCaKMbbMvYgYsG32gV5N9AiiMFa7dm3VnLVnbS1N76u1148yA2nSJ8Ixj/DeOdbKMW3a0Y3oUqQ6EmuCjrkxDGClSpVMnqN5nqheP/R/jFuP7+NFSDAe+D1R50HBrwzV+Glv4537Q1C2sHjmGKDIiRAQAkJACAgBISAEhIAQEAJCIAERUGJOIrv3v+BGTx0eFG94rP7xYyXi0HOn4bhNau8ca9xPLJsBP++w0DLW8r3LNOM++T+4h72TeyHg8YN32QVpSwgIgThI4Oyk7tj2pQs85rwJNXlz60J171C/MIEkDnY7fJcsrBde1vbROXr7AT4umjt8/gR8h5vLcwGaXiBcGKe4wwVwGj0p6BnAvToYooznugcEPUrMvQbMry1hozcEN6fnAjo3jzcOocawYVxIptDDxXx6fDRq1EiJNMZ1sc/cm4V7u+gh27g/yZkzZ1T4MfaxWbNmxkXUedu2bdVrixYtwqVZusHxULSxdFjKb+ke947hnjAUj/r27auycF+hlStXKr70DKHo079/f4PYo9djztP4muf6oee39mqNO/f3GTRoEBg2j54verg34/YYyux///uf4s7nou/7w7BnLMvFf95nPj2N/TGuI6L+medhPStWrFDeYuzPN998o7y56ClC47OnMUygLproIf8Ydo0iDuukxw/DlNFjy9gyZcqk9ini/jYU0dhnW+ZeRAz0tiku6X3TxSVrz9pamt5fczbG1w6aDjOkkz0mLYmamHPurhdO+T3CF8Vr6M2YvOrhEvXPAZPEaF50WT4Weaf9iIevXqLX/hXq/MK9q4balm8FalexQ7G8hltyIgSEgBAQAkJACAgBISAEhIAQEAIJiECibdu2hVapWi3c4kdsj5GCjTUz30NHD7X2/RbLG24vaqstRvSfifR5i1ir9p2mxcU+vVMA0pgQEAIWCZwe2wnehxfCLnEqVJtzFXb2DjjYty78r+2HU+aSqDBmp8Vytt708LyGogVy2Zo9QeXjnhvc5Dy+G70zdA8U87FwIZohUmnc+4P59L1AzPP6+PiovVjoUWMtFJl5OXq8RFRm2rRpmD59utqk3rzc+7gOCQlRHjoUcyhavI3FBHd6qTAkXHTCuzEUGtkzFBoFqpgwjol1UlSg2GKr6eUYro1so2rRnXvW2rH2rK2lWauTac+0bZbcPn6Fk387wN0tsty2pVNo5ecRvZy4N9O7sCLNgzGtnz0qFH0XrUkbQkAICAEhIASEgBAQAkJACAgBIfCuCdjxj9+IFozedWf09vR9dDIWKKXfsvq6ZWgn+N+7gnV9mmL9r18j0P8p/u1YG4fnjMHMelngffEUdv7ZC7Mb58GcJgVwevVcVR/z/dO+Gg7NHoW/PnNXZR7fuKzSrh/ehb+/rqDubxnSCaEap+tHdmHpdzVVneu0fXz87od5Ar3SQqjtGP2Lyss2vPZtgaU+zWteBAy3RmP9FHvYP+Z9+SIsxM3RBeOw/6/hhnaOzB+r8jM8G/Oxn/NblsCtUwfUff0Hx8L+/jfmF1Unx3nn7GEEPQ9Q+f0f3A2rRwvHwXxiQkAIvH8CIS+f4NH5Q3ihhc2hkCMmBHQCw4cPt+jJQu8WhnLTjYJBREIO89ALgt45URFyWM5Smbt376pQX9zPhF4kccU4NnqJvK2Qw/HEBHeKMNERctg+ny/Do8WUkMM6KfwxfF5UhBzjctERclg+unOPZSMya8/aWlpE9en3nbRogU92xpyQw3CADLXIEHTvSsjhWE4vESFHf6byKgSEgBAQAkJACAgBISAEhIAQSIgEwsKsad/yjc9WvccfsHNwRJ3f5qFO/ynQAs7jkdcJPL13HW3+OYO0OQsgQ4GSaL3oOBqPW4cDk3vgZeAzle/pjbNwcHRC64Un4Jg6vbavzb8KxZ7xPVHm6774ZuVlFG3SAQxFl0RboKneYxy+WXMVyZKnwtk1C8LyTuiHx9cvqDo+n7QF6XIX0PKF71Pg4ztKFHp69wY2/a8JSn/VFy3mHoa/903sHtdH1eX/2BuXdyxDrf7T0GDMKhxfOEwJMl4Ht8Hb4xjarfBEg1HLkdbdLISRNma/O5eQXhtn2yXnkbNGE+yfOgBJkjlr4y+CC5uWqPrvnD2CV0HaV1DFhIAQeO8EEtk74d6upbi3f63qCz11xIQACXDzee53Y+mYNWvWe4HExXKG6OK+Lp999tl76UNsNxoXucf2mKX+mCdAAYd7DNkaijDmeyA1CgEhIASEgBAQAkJACAgBISAEhEBCJODAcC12mpYTHLVQ4XGKRWJNjEmkxYZP4ugMnge/CBMrKnfV4usnT6n66l62Bi7vWodr+7eo64dXziF1lpzqvGiT9nBI6ojs5Wrj6t716l62CnWxb2p/vNA8XvLU+lzdy5i/JO6dP4aDs0bg9pl9SO4aFovj6t41qDNwLhxTpFaHyqz9sNQnpt0+uR/O6XIgT81GKmuxFt2x4/cO2vl4dZ2rRlOkyR4m1lCkenLjCtLlKojnmhi0Y/TPKP5FRyTL8pHKa/4jb83P1ViKf/E9/m49FUHP/FG06ffYPvx7lGzdHZe3r0SBT8L2OzAvK9dCQAi8WwLpSn6O+wf/ga/XcaQq+CmeXtjxbjsgrcVZAs7OzuARl4zeOvTKScgWF7knZN4yNiEgBISAEBACQkAICAEhIASEgBAQAkLAdgJ2FHNevgq2vcR7yHnv/FHcOrIxyi07JA6LUf741lUsbFUcLwJ8UbnrYCRxSY9gLZ69uTkk0eJsvLYqXYagZt9p8NyxEn9/VQ4Mc7Z7fF/sGtcTH1X8GMVb/oQQLWQZLfjFMwQHvXhdMvIXesY4JHsTC59CUqjWH0vh7igIaQlImSkb2iw+rXnk5MPKbnVxcfMyqw29fP7a+yYkFJmLlFN57507iss7lyL3a3HKagWSKASEQKwTyFyjJUKDn+HZ3ZPI/vE36jzWG5UGhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBCIdwTs2GN7h7CNlN9l78t8O9hqcxRw1mv70kyv44rVP36s8lor46gJNP4P71ms0/v8cTi5Zkbxpt9pIk4wXj33tZhPv0lRhfvjZC5aHvVHLATDo/l634bX3rUo801/ZNL28nl09YKeHZmKV8fJZVPxws9XecI8ueml0iLqU+ZiFcDwbhwjw72dWTULbiVrgcJaROZz/RK4N0+JL7ugSNNuuHZwq9pn59y6hXj12hOJZZ/cuabysU4XtzxIktxF1Vvkix+0/XS6I0XGnEoYiqgduS8EhMC7I5AiRyE4uhYAw6ul1T5HxISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAKWCGhuH5rjh+a98a6tePPO4HFiyRTcOX3AxPOGXji6J06W0p+gZKvuqnsZNRElIiv0eQdsH/YNDrvlQqM/V6ps3OeG5l6+phYabRBmN84Dp7RuSJoqfZhw8lo80fMlQpiY8sLvCY4tGK2FJuuged8Ewb1iE6TK7I7iLbph+9B2mldNCqTLV1KrI0wEq9lrLFb/0hTzmxdQ7ZVu/xuKZc2BiPqUNnseVOw+Hmt7NELIq0Ckdi+Kz0aH7dWjKjD6YWefRF09uHASeyf30sSZNAjyf4QGv6/AU0002jvhR7VPjkvaDCrfpv+1VeHY2MdGY9cYaipQtxkOz+iH8l3GGO7JiRAQAu+bQCIU670QIZq3np29+jjW4jOGfW69755J+0JACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAIxB0CibZu3RpatVp1iyG+3nU3dWFHb5cijjUBR8+nv9IzJpG9HZI4JddvmbwG+j422dPGJNHCxcsAP3U3sbOLITXoeQDsHBLDIXGYyGJI0E7YvoOjI+yN0qz1iWHaWJ++r49xXZbOQ0NC8PzpQyRL6aqt94Yt+Ab5+ynvm8CnjzDvizz4du0trU4/OKVKZ1JFwMP7+LttSbT+5xSSpUhrkiYXQkAIJCwCHp7XULRAroQ1KBtHc/bsWRQqVMjG3JJNCAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAIxA8CdgwpFnFwr3c7CHrq1B+2wHBERchhT5O6pIhQyGG6Y4rUfLHZKOIYCzksmCSZs0Uhh2ls31jI0e9FJC7xm/i2CjmsiwKOU2rNq+i1kMN7DKNmbuZCzrkNf2PVz5+hYMNOIuSYw5JrISAEYpyA9t8KfPV9u2K89vhboZeXFyg2vWsLDg7Ghg0bEBAQ8K6blvasEDhw4ABu3LhhJYckxQcCizYAvceHRLmrflqY3ZchcWPPyiF/hWLm8nfvpR9laHGgwAO/B9h2flMc6EnkXQjR5tf606vgH+hvMfOBy7tx49E1i2m23mTdbINtxRU7eu0Qlh//Rx3eft5xpVvR7kdIaIiac89eWH6OkVUc2TyIrHxCTn8U8BC7Lm6P9hDj0+dBtAcpBYWAEBACQkAICIE4R0CJOaFxRc2Jc3jiT4cSa95IZTsM0/beSByu06GaB1D59gNRvkPfcGlyQwgIASEQHQIUbLrMXo1cfSYh8OUrQxX/HjiFuiPnosSgv/DV1GU4efWOIe1DP1mxYgUmTJgQYxgoDH3zzTcqbOjy5csjrPfly5eoX78+7t+/H2Ee44SgoCB899138PaO/4tg69atw9y5c42HF2fOf/31V+zbt8+m/iSUZ1K8eHE1X7lHID3ofv/9d1BstNVGjx4NimBxxQKDgJ4TXuGL2raHx7zhcxdN5vRHxrHfIsvor/Dj8rEI4QdqLNpzLZTn3ANrkeePduowb6pJ9UToOTEY/s/NUyK/3nPpP/RY9oNazK8+oSy4uGnNGkyvjTFbhobLUml8SUzbOT7c/bh2w+PeOTRd1tTmbq09uQJz9k+3OX9MZgzSQkV/trIx7vvetVjtr5v6YK/nTotplm6O3DwEFICM7Z7vHdUG24pJ+3RaTdgPSoRUg5Oj1qQK2HpOU01ttJuPb+DU7ZNotvZLeN73sLFU3M328lUQ6v77CW4/id7vU5HNA/ORM3+Hha3g7Wfb7wzm5ePTtcfdc2i4pGG0uxzVz4NoNyQFhYAQEAJCQAgIASFgRMCOf1Ajdv+GNGpOTmOLAD2Cin3xPezswvbxMW6nUIO2yFGlnolHj3G6nAsBISAEokpg2+lLOHTT9A/9R37P0Hf1HgxoVBUewzqhlLsbxmywbbE6qu3Hx/wdOnTAiBEjYqTrjx49QuHChZEmTRo4OTlFaUE8sg5wcX3mzJl49uxZZFnjfPq5c+dw6NChON/PyDqYkJ4JBRkKizNmzMCQIUOwcePGyIZvSKeHWVzyZlq2FfjIzQ6lwrZMNPTT2snvOxbC72Ug7v/0F450GIOZlw5j56Wj1oq8ddqIrXMx4fA6VMyUCy8seFAUyAlULJIIf2+I+h8EmzzWwS1lZpy7exY3Am4hnYtpmF/zzudzzYdrj6+Z38bZpxfhnk7rSAKzs3dP4+C1/QliVJsursO1R9fe2Vh+KdwNRzsex5fFWuPjZfU1Qce2z4rGxb/A4Aa/wyWR8zvra2w2lMQhKa52vaq9P3LEZjOGuoO1LwHOvvI3AgLDwo0bEhLgScnsZXCua/wX/BLgo5EhCQEhIASEgBAQAlYIhIk5VjJIkhAQAkJACAgBYwJPnwVi6Lq9GN6wqvFt3H8a9od/oayZkNjeHoWypseFh48RrO33lVCNi+wVKlTApUuXTIao3/f09ATDq1WpUgUNGjRQIolxRi5mDx06FPXq1YOzszNGjRqlfcM9cl4uLi64e/cuxowZA1dXV+Mq1fnJkydRunRpVefgwYPDpUd0o1OnTmo8TK9bty7oSTF+/Jtvy7Pe6tWrK+8KjunMmTMmVdWqVQv0QOJ4+GWRbt26qcV39oV10RujV69eyJgxI1avXm1SNiYvjh07ptrj2OfPn6/O2T5FMNqLFy+UkMB+kPugQYNMBLE1a9aovo8dO1b1lfk4Vj4vcmGZvn37Im/evGjWrBmePn0aafcfPnyIpk2bKi4tW7aEj4+Poczly5dVvWTGtrp3724Ii/e2z8TQiIWTgQMHYvr06coTi2Pic6KIxzlIL7Ls2bOrsbI/vO/h4aHmsvkc1e8zdO+9e/fAPrM+HsOHDzdpmXM3ffr0ap4VLVoUhw8fNqQvXbpUzRFyaN26tYHRnDlz1DPcuXOnYsNn2aJFC5v6Q+GoXbt2qi98XsZebNbmAYWj9u3bq/Y4jh9++AF8hsa240gIPq4QNff2+/5PUEoTVZI7OiNbmoz4SHu94nPLuNoYP/+uQmMc7TYNn+YvH2HdtcrYYcdh28WcBQdmK4+JyaemY8ax6Wj5d1P4vHyq7j159jjCdnKny6uJOVdV+vANA7HqxDLNu/M5/EID4J42bLH6nyMLUHh0buWZ0XJOYzz0N+UeUeUfT6mKcdtGouSY/Kr86pNvPBZfaALaoPV94TY0rfL2GLC2D15pi9a6WWvz78PzVLmcIzJjybH5ehGrr0evH1b9GHlkDJZcXq7O2S+f12Pxe+GHLv98o/rCeif/N9am/UvpNdF6bhNVjp4r9HS6+vCKoS8nbhxDmT+LqPRB60w98uk11XjmJ4pri9mN8Dgw4udkqFA7mbV3iur/7seH8cuWn9R589kNjLNgxp7JihE9ak7fOmFI8/a9h7bzmqn+5PvdHUuP/m1Ii+wkRdIUyJVe2w+0Umd0ztceI/8bYihy8vpR0BOMDOjVZdymIZOFkw1n16j+sxz7M2nHHwbunGvG/eOzIsvL3qb/v1uoVvWl36qfDfPk32OLDdkiYzBwTS/llUZvGHoisc3nQWFhUZlWeUIptFzQBPce3zbUyZNtHpsNY+E8uO4T9r5imrV5wPSI7Pu/v0KlCSVV8iezaqn6+Z7SzVqbeh5Lr9bm+7ANAzBv/0xDsV4rumOZET++j39Y0h5/bh2h+PI9bO15B4e8QoVxxXDp3gVDnTzR73vev6ju0+Or1pRK6Lj0G5N8DBv4zYKW6Lqkg3oefJ8aexxa+zzweuAJfg5xfvH9rodw+/nfziZzS2+Q9/W5Mn//X2ousyznwBVvTz2bvAoBISAEhIAQEAJCwISAnfqDPGp/h5pUIBdCQAgIASHwYRGYvOkAvqlYFG5pUpoMPK9betTOnQXDV+3AqsPnMHn7EfxYvRTsjfb5MimQAC7sNdGKnjHHjx83GQ0X5xkOKlu2bMicOTNmz56NsmXLKmHHOOPNmzfBcFv02lm1ahV69+4dLo9xfv08sRZSk4v+ERlFFC547969G6dPn44oW7j7XNxfvDhsEYreOexTmzZtVD4uZLPOypUr4/z586hatSratm1rUgfHzPx16tTBiRMn1JgZIuzo0aOYNGmSynvnzh0lQvXv39+krPnF8+fPDYKALgzor6zPmhUoUED1vXPnzkpE4zh4pEwZNmcpgi1cuFCNlZ4hfD7btm0zVPn48WNMnDgRu3btUnkWLFigeb7agc+Lz5NjYYgwMqJgZ0u4tGnTpoFjJ6McOXKAwphuDIVHweHatWvKU2X79u34888/VfLbPhO9DUuv9HLp2LEjUqRIocbatWtXlY3tU8ChEEPRjewobFHc2bNnj+qncX1HjhxRdVCEoThEoYpzhGMsWLCgcVYsWrQIP//8sxKOmO/rr79W6RRqmjdvDs4LlqN4NG7cOJXWuHFj1YdSpUopEY39IZ/I+kNxiaKPn5+fekYU9yio6aKMtXnw5MkTzJo1C25ubmDftm7dis2bN5uM5ZRnKHK4Re2X6M4VGmLRhQOYtncFBqyfhgdaCLT6BSqZ1BvTF1lSZ4D27S2r1ebIDOw+FbmQrFdSNW8N/Fi5pxJhZjWdB5fEmsBZtjeGfjIKzo4uerZwrzlcc+HykyvwC/TFr0cGY+r+cbj3OgxY9jTu+O/CVrTa0BZ9q/THsXbH8OxlAMZut82j8eDDY5h2dCrGNpyKtkXa4qs1XxkW6kdvGYbFZxZjYZO/sbr5aiw6uwBbPMJCd1lr8+nzJ2iz8Wv0rtAHfzWei01XTedAuAG+vlEwUyEsb/sZsREAAEAASURBVLce7Qt8jbpZqqtzXqdySqVyjNo8GNuv7cCKL5bj16oD0W33z9h58c1nUET1cv+TYm4lcPC7w7jQ8QJSO6ZGq4VNDNm7rvwORdMXxra223HmvqnYPm33ONwPuIt9rXcjRxrtMyjAdLHbUInZyeclWqj+l3QpjF7leqnzsZ9PMcm179ourGuzEcmTuGDizjEqjXu9NJ/bEH5Bftj51U4MrDEYX65vZbIwblKJlYsy2crj6KOw/8u4sF5ybmlUcq+C0x1Ooap7NbT7p6WV0m+SEmmfCSPrjcWNbjcwscEUdN/TA9svbFEZymeviHF7Rxkyrz29As+DnyNnutyGexGdUOhacWEFFn+xFJ1KdkaLdS01QUYTxm1gcFXzVOuy60e4JE2JrW22oku5roZ5+32VrpjadDYOPDmOwFcvDM0zBFrdpR/j49z1cLDtfrzURL5WC5sa0q3NA0MmCycD6w/Hwlb/qpTpjWepZ92m3LfqOrI2LVRnuGVtvl97dAX3/O4Z8nr6XNJEzzfhGh8/88HUC7Pwn9cO9f6d22i+9qUIO0N+8xN7Owc4OTjh6I1DJkmemih36OkpTUTPru5PbzYPnct3w577B0zyUYye57UYbikyq+fB9+mms2tVHmufB+r/G010S2yfBIe+OoiaOeqgxj+1lICb3iUjtl8y/exg/tke85E1dTZQBGq3tQMG1ByM2z/exuC6w8HfL8WEgBAQAkJACAgBIWCJgLY2EfEvQ5YKyD0hIASEgBD4cAmc0PbA2XnpOlpoYk4409YK6xXNgxVnvDBlxxE80DZgKKaFWkvoVq1aNSVWUHzgN//pwcGjZs2aSJo0qTpy5cqFDBkyWETBBWwuVteuXRtcrDYXhiwWsnKTi9BccO/Xrx9KliypXq1kN0miQMQFchqFKJ4zlBtt/fr16rVMmTK4evUqSpQooRbd6ZVhbBQEfvzxRxQrVgytWrUyJFWsWFEt4NOjp3z58qoOQ6KFE7KjaGPpoFhjzZIlS6b6Tq+l1KlTq3OORV8coUhBDyM+M39/f9SoUQMUbMyNocCYj89GFyUoZtEbi8ax0JtFFwfMyxtfUxShQFKuXDklWBin5c+fX3n4sD+3b99GkSJFDF5PMfFMjNsyP+e4KGpw7lGcozjJvYa4zxKfH72tunTpojycmMbxc37zudDTikIUvWso7tHomcMvCiVJkgS5c+dGw4YNTZqkV467u7tKCwwMVPmZYd68eaoPFNzIgHOEgg3rT5UqlXqGyZMnVyImnyVFlsj6Q6GNQgzfoxTS6BXE8a5dG7YwZ8s86NGjh3rG9Kbav3+/yVjOeYQgQ1qTWzh75wpmHVgd7vj3eNhCfZaU6ZE2STIM3LcCf5zehTZ5y2oL/MlNK4niVWRt2lJd+rSJ8Mg7VPNWsSW39vmQxh2OiZOhlmtFlM+pCby+l9G8VCuUy1kJibXF1IjM3TUHPF9cV9+sr562PA75nMSNRzeQwT4NkiVxwpxDM0HRIGWyVNoeITdQPntl0PsnKPhlRFWa3P+p/M+okrsaOlT+QQlN1157rYw5NhZVslbCc80LyF/ziqnoVhELj8xRZa21edhrv+pb9xo9UT1fbXQs0dGkvYguOBZ6GqV1dkUqxzTqnNdcaKb9fe5vfF+qI2rkr4uvK3wHsthwbk1E1Rnuk3mPOv2RQhPMLntfQN50+dQCNTM8DvBRi/796g7SwpyWRd9aAwzleLL24lp0rfCz9owq49d64fctMslsdJHaKaz/zg7JkCFFJjUWt1RZjXIA/WoPQgktZNW3Zb/H+mubVNql+xdAkaN6zpq4/fSW1ucUKOCUC2tOhYkFJhVEcpFSE8HovcV5sP7MSpWbAs+1h14okbW0EqbO3Yn8iwufFG6IKpoQyX11nr8KRO6k2XHp9b46X5RsqVjqHh1/HZmOjqU6K2/KSLqnkjuW7oyqeWvil9r9VIi3I5p3lq0MyOXPL6ag9Efl8VWFDnBKGvaZQM550ucN1/yuSzvUvQH1hqky5E/Bh8JoZPMgXGVGNxgyUfeQo+ih5nByV5XDWptGVVg8je58N65sVsuF6v1Sp1B9FM5s4XdQo8xVP6qOo9cPKUGNHlj05Dl9S/Ms1t5nSRM7qpw50+cGBeSIrGed/ym2zQq2wP5re1Q2a58Ht7TPsWN+Z9C/9m/q/Tfo0+GqzH5tn6my7uWw68YudU1Ptbn7Z2ife9fUnC6apZhJF9JovD8u+KnhOZgkyoUQEAJCQAgIASEgBDQC6i+K0GDtm3iJtFU4MSEgBISAEBACVggMXvkfGpfIB6/7PriiHTSPW97InyU9Lt97iJ+W7cB/PVojq2sqrD5yDo2mLFP75zDsWkI1etxQOGFoL4Zb27FjhwqBRhHAFqO3i25cpKYY8zZ29uxZVZxiDC1nzpzq9W1/0IuDghQ9FHSjBxAX5I2Nwoi5cdGdRoGGi/wODg6R7slDLw8KMZaM5aNrvr6+qm1vb2+DpwU9U9KlM93rg+IGhQdzY9v0jNLHxPHQ+8ia0cuE4gdFPRrFJl0c4jWfGecRRSq+3rp1CxQuIjNbn4m1eigkmhvFFIp1urFfeihBCiOc6xcuXAD3JKIXDQUT3fOKXjc9e/ZUYgvHSO8aCkK6URj7/vvvVRg7CiVMpzh28eJFvHr1yvBMmJ9hzshO96jS6zB+tdYfcqRR1OFBo8hKUceWecC8ugDI+WEuXBbMbwftY8/E7vv54OB1U4GTGTK4pMIXqIXeG2egUpa8GNu4u7bQGIgSk39ArsMb0bHS5yb1ROUisjZtqcvbJxSZsiSCgw0f1dd8vLTwaP9i2+UtCHj1HL+t66cWJVeeWIoGRT5XobEiapPfQqdRuPg4T30EerzAds1Dpkz6kur+5ceXtHBIL7HJI0w85s02eb/Esxf+SOJk+fNAFXz9I79bEXWW6nVeX80DyPf5U9U/7wBvQ70pHVMiffKw97e1No/eOGzoGyvOm9HU0+x1s1F64TfyrwXdQcGMhQ3lSriVxo0n1w3XEZ281EJIVdXCbt1//gA1slaDb5CvysqQcWdvh4kZ2TXBjJbbSARg2C4uNOfOkE+lUWyigBBTlud1vWldXHE/OCyc5a3HN1X1ng8uggetWrZqcHEM805SN2z8QW8J7oGTxD4xrmth+ij+bbm40VCaYdheGHmuGBLMThYdnIMuW7qinGtJ5E6bB76v/FSYP2bLmNINTbN+iqXHFqFF6TZKHFlWcp1ZDRFfFsgQNjf4f1fZtMVwXJs7hdzCRIfIGHyW57OIK7aQcv/pHSV66sJEvtf8H/h540lAGH9L88BCVTbfstZmRk3ki8jeZr7rdVLgTe9i+Qsxeh7j17LZK+B/W/ri6LVDSjzeoXlf3fG9g2of1TTOFuE5RR8HeweVnt45HS4+OKfOrX0ePNA+X2h5De8xZ/Ueu6u1+0XuL1U/KOCsub4Bj577II0m9JZPVUITsZ2RQ/P+Gll+KD5Z/qmqg/N5SINRmtAf+WeeKiA/hIAQEAJCQAgIgQ+KgAPj+ieyt0NoSOgHNXAZrBAQAkJACESPwIbTnuDh+yLsm9K9l2zBjG8b4tyN+8iRKrkSclhzqRxZVAPXvR8jV6awb3ZGr8W4XYoeKFyoZ+gnenIsWbJELUDbuldNTHvI6oIBxQp6ddAjITrGhXVj0z2LGG7LWp8pjMSE0UslUybLC0T0kKDnRmTGRTX+nmNsukjCPYwY2iwiMxd39HysM6pG4SdPnjxKpKG3FNlSCNGNIdu+/vprTJ48Wd1i6DMKNeYWnWfCsGYUNbiPUeHCbxaP9botCWYcuy7eMB89sXRxkJ5Fo0ePVlwZUo170HAsfB/Q6I3D9wL3quFcoWcO9xSyJMBRJJo6daoqx/qZx3iPJpVg9IPCijkDa/3RGVJ0NBc19X1/IpsHRs2HOy2eNxG87vD35zdzombeMuBhyYK1EFlb713FguK1NA8Ne7VvTq1sBbDj8gkTMUf3ANI9wCzVZXzPWpvG+aydX9F0r7KaOGWLhWqeVwz5tPH+DrWXyaEbe9Wi5ItXQYbwUBHVw8VnekPMOTNXhaTy1bxkZp6aibYFWqsiWVNkhX0iB0xsPjOiKqJ8P/nrsG8NCjRS+6+YV2CtzQKZCmPeqbmGItc1ISsqxnBQIZoAY2z8DKEYcdXniuG2x4PzcE/lbriO6GTL2XVKyLnY67pabP770Fwsu7kOodoUzJ0hzIOD3hn0sLileZ/oxgVjcqf3QCnNg4ai0Plnl/Vkm145Z433GTIuZOlzMV3ydCpL9+o9rQp8xvVEdL7v6m4lwDA9Y/Kw/xfGN5uuhQ+MeM462SUF90rSjSHqKORM+2SqEmsYAm35sBUqFJqe56syHdB+Vdj/C40z14M1kUIvo79ee3RVP8WZxx7onqEXbGWQOlkaQ1lbTtJqbCnOcR8YenvdeHRdFUuVLLWhTUvzwJa69TyvzPbvs9amXsbSa2Tz3TGxE3wD33yJ5fTD05rQ+4lJVWm0cIJRsWLZSys+KzUvsMnVJ2DZ6cV49uoZBtUO85aJSl3Gea19HqTW2NP4LFI7p1VeZHyPpdHOeU3xdOJ/f6Bzke+w1nOt5uW+DTWNxCV63P1Uqzf2XdmLFkuaoPjxEvimUifj5uVcCAgBISAEhIAQEAKKgJ36xqEIOTIdhIAQEAJCwAYCK39uhbU92qhjcpt6qsSaX1rDPV1qlMmVBV5P/HH48k0EabF6Np+6iMwuTvgoQ9QWKWzoRpzKwoVvLtT/8ccfas8PLlxzXxR9cTu2OsvQXlyk5ybuDx48UOcMSUUBhx4R8+fPV4voc+fOjVIX6DXCvm/atEnVzW/V0uhxwwV61kuhhR45DB3G89gwCiD0eLF0cAHfFitatKjy9KCgpS/eU4iiWDJnzhzlDcJ6vLy8woXQsqX+qOShBwyFlUePHhn2JdLLM2QY93XhWBmyzDzk29s8E46zT58+4bxK9LYtvTJ8HEORcd8jCiLcR0kPl0aPHXri0Lj/zMiRI9V8Yyg0Gvfb4Vjo1USvM4a6M17opefZ3bt38d9//ykhp1mzZqqczof7D1GAIyeGezM2Cnjc44jvMf15WutPvnz5lAg1YcIEUNxkvQcPHsSVK1eUIPm286BaSTtsPmD7l6G4GN4seyEsObUTT575aYv5d7SQVFpIxlzFjYcJhiTkEVMWpHlt3Hp8Hw8CniBQW6Dl+UP/xybVbz8Sgmql3ohSJolmFx+ly4VOVbupuyMbjYWbSxZ0Kd8dfT4eYBAUzIqYXBZyLai8N4pkLY6y2cup8zzpwzxGGhX6AkturMJuz53aMw5W+02sObXCpHxUL7jg3z53W8w5NgsX7p1Xxbm5+L7Lu9S5tTbLa2HjGBaOG7/feXITi08vjFLzRbQQSjtu7lRlKR7o9ulHn2DByXm4rXmvHLl6ABvubUPlnNX15AhfOe+fBwciIMgfV7UQclMOTjTkpWcJF4znH5ilza/HmHPQVBD7LE9DLDw2RzFdfHCuoZytJ2Wzau+/C2vBfUOMxxJR+fxuheCexA3j/xsN7rfC53nwyh4tPNyliIqY3H+qLfB73D2LiTvG4C/P+ehdo79Kr5HvYzVn5h2YqcJoBWqh81adWKbOjStokONTLD+1BI+fPdIW1oPUPitZk2XCU40NrxcemG3wItLL1cr/CZ6FvMDAo0PRThN2omKLTy7APc1jZsPZNare8h9VxNsyiKj90lrYLtqiQ/NeP+vpSqxzS+WmPIyszYOI6tTv02urmHM+bNS85yiG6b8DWGtTLxvRq7X5Xk7zotnkqXmrBDzElrPrlddaRPXYej+9S3rFY/z5qWhZuq3mweavQugVy1ba1ios5rP2eZAlrbsSaeccmKbeIwsP/KXqYMhDWm332vjz7CTU1uYvPbHYt3LaHKFd97mKkzeOK2GuRNZSSJs0Dfw1bzoxISAEhIAQEAJCQAhYIhD2daZofMvUUmVyTwgIASEgBD4gAmbrfh9pm0f0rlUaPZdsRYH/TcWWc1cx9PPq2h+nEX9zNqHQqlu3LurUqaM2geeiNMUdLmLTuN8IF7MZemrmzJnqXA/BRmHBeKGb+c2vec+Sde7cGVmzZlUCyw8//KDO9TBQXGDv3bu32muEC9dRtQEDBmDo0KFwdHRUG86zPD1+Vq5cqcZDoYUCAzer1xd69DbM+298zXP90PNbe2U4M0uHcZ3WynNBnB4p9Bbhl1e4oE8bNmyYEr242M+66LVx+XLUvqWut8tnaM1TSc/37bffYvfu3UibNq1iq3u6MJ1p3IeGYeg4N3SBQy/L17d5Jsb1mJ9bYtmkSRMlTFIoYeg/GkMJ0igW0kuL4g73U+IeOp988uZb1BSP6J1FDyj2md5GeqgylqewRPGqV69eoFfMiBEjeFsJQ4MGDUKlSpWUhw456fs0qQzaD+7hQxGRwhH3FaJZ6w9D4LEOCkzsMz1/GjVqpMQmlrU2DyxxYRlja1ILOOcVghMXjO9aP/+lWgu80L5Nn3n8dyj3Vy/Udy+MlqU+NhTSxVHdE86Q8BYn5+96Ie+0H/HLnn/hry2o87zrinGGGj00h4J9p0PRsr7Zh7ohR/iT49ePqP0nuLfHymvrUFbb68NWy5++gBIduBdL8Wxh4dU+cs2linPfnV9L9kb1v6sj8RAHpP8jHdafW21r1ZpXj+kY9Oc4/LM/kNFZE7qnF4T9oETIMzWPQVSw1iZDO/Ur3kNtNp91fDa4JI48/KFxZyvnro5a2WuhwIT8SDxY+wzSRA3awHoj1Df3s03IhnLzKyixqXGJMGHTuLz5ee2Cn6BkuhJIMyo1ck3OhaIZwsJ4JXqtKY6oMwr9Dw1E2tGa589jUy+iDhU7Y/+9g4rp8N1DldBiXr+169Zl2ql9Zth20TFhXkDaJ7oqor8al0+ibQS/qs167LyxE5n+zKie5+eLG8H/ua9xtgjPufBdfmY5rD6/Apu/2KjtWVRH5c2dIQ/+bbAEP237BclHOMN5uBN+3dZX+7/ojVjGjN2q/YIbT2/CdXRaDFrXV33WD639OwbtGYRkQ5Ni0sEJqJK6jIl3D8O4dSn6vQrpViv/m/dlhJ00SqBYm3lcZjRY3hC/leqnvDFsZWDJw8jrgaeaq07Dk6lW8k3Lq67/u7BVeTpNrDoW7ba0V8960aWlmPvFQiUGMLO1eWDU5QhP+9UYiN/3jwDb7r3yR5UvV/o8sNZmhJVpCdbme/V8tZBM885JNyadCo3GkGqhZu9ja3VHlFbro1pqT68UyVKiYb5GStxJ5xLmLbb48HzFssqiaioEIz8TePhpnoL6Z4aleq19HnCvsH9brMDcC3+r92eH7Z0xo+Zkw9435T6qpKosl6Mi6uQL+zJU8dfikrfvPZScU1L1IeVIF+RNnQftKn5vqQtyTwgIASEgBISAEBACSKTFvg+tWq16uMUYYSMEhIAQEALxk4CH5zUULRC2MPY+RhCieXI8fRaoLWSELUC8yz5w7xFuyh7fjR4E5iKJPiYuNBgvjuv3zV/psUMPBuN9X6zVa6sowW+G00OHYo7ujWHedny5DggIUHsUkRFFo7cx8/BfxnXxefG5kT+9qNieJQGIXOnpZSnNuD7z89h6JtxXhvMoopBz5v3QrznvKEpQaImq0buMHCgU6fsSRbUOS/l9fHxUiDZLfN9mHkxfFoozl0MxqU/UROsnz/3hlMRR2wPEwaS7DLFGEZIecG3atDFJi62LvhNDkU5zrPq5jakQElvt2VIvN7q///Qu0jpr8+D1ZvC2lIssj3+gv/at+cdIlyKj2n/FOL+1NrnvTqj2L2WyMA8043Jvc05xJ1niZNo+MlELT+nj/xDJNS76ninGfaA3xdNA7bPfwh4j9I6553dPhQ+zJCAY1xOT5w+1/r7S9kJin2KqXXoH3Xt6WwkBDGNlqzE0mU+Aj0U+rKPpX/WRxzUvhjf609Yq1SL8vjZ7kS9jAU1Qsbf4PGODAZ+1T8ADzRsncziu1uaBzQOzkNFamxaym9yyNt+ZZmnOmlQQRy6sfR6o95i2T46rNtcp5tlqDGHo7XcXqZ3SavvoONlaTPIJASEgBISAEBACHyCBMDFH+xao7JnzAT59GbIQEAIJksD7FnPeJ9SEIuYMGTJEeTVYYkmviWXLlllKivQe9+BgCDhLNmXKFHTq1MlSktyLhADDilnbK4jhymI77F4kXZTkeEJg4sSJmDRpkvLUomeRmBAQAu+GwEGvfZi+dyLmX12Cy10u4yPXnDY3TK8Oijn0uhATAkJACAgBISAEhIAQEAKxSSDRli1blGdObDYidQsBISAEhMC7IyBiTvz3zKGnwLNnzyxOGi7wpkyZ0mJaZDe5Xwk9HyyZs7NzjHpCWGojod6jFxX3MIrIUqdOrUJ8RZQu94WAEBACQuD9Ejh5/SiO3jiEqnlqa3s/5YlSZ2bsnoRPizSEW6qsUSonmYWAEBACQkAICAEhIASEQFQJOHABgqE/IgrnEtUKJb8QEAJCQAgIASHwdgQorPCIaYvvYdFimkdM1cffo6Iaiiym2pZ6hIAQEAJC4O0JFMteCjyiY99V+SE6xaSMEBACQkAICAEhIASEgBCIMgEtLLsW4zvuhMiO8gCkgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIAQSMgE75ZUTEpqQxyhjEwJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhEC8JWAXHBwMeztxzYm3T1A6LgSEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAIJGgCyjNHHHMS9DOWwQkBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAvGYgF1oaKhsmROPH6B0XQgIASEQ1wiEaN8QePIsMK516733x8vLC2fPnn3n/aAH7oYNGxAQEPDO25YGIyZw4MAB3LhxI+IMkhIvCCzaAPQeHxIv+hqdTm4+AHw1IOGOLzpMpIwQEAJCQAgIASEgBISAEBACQuB9EVCeOcEh8kfa+3oA0q4QEAJCID4S0L4HgC6zVyNXn0kIfPnKMITFe0/i41HzUGrwX2g6fjHuPPI1pH3oJytWrMCECRNiBMOkSZPAPe/Mj/v374er/+XLl6hfvz4spYXLrN0ICgrCd999B29vb0vJ8ereunXrMHfu3DjZ519//RX79u2zqW8J5ZkUL17cMGcLFSqE33//HRQbbbXRo0eDIlhcscAgoOeEV/iitp3NXXoeFIi5B9Yizx/t1GGpIL9o1XB2XziP+BLMH5sWWX+qlgRW7w7BiQux2QupWwgIASEgBISAEBACQkAICAEhIARsIaA8czRFx5a8kkcICAEhIASEgCKw7fQlHLppKhzceeyLX9ftxegWdXBiYHt8lDYV/li/V4i9JtChQweMGDEiRni0a9cOd+/eNRx9+/ZF+fLlkSFDhreun4vrM2fOxLNnz966rvddwblz53Do0KH33Y23bj8hPRMKMhQWZ8yYgSFDhmDjxo0286GHWVzyZlq2FfjIzQ6lCtg8BIzYOhcTDq9DxUy58CLEspC1/MQOHHxw0/ZK3yJnZP1xTAIMbG+PkXPki19vgVmKCgEhIASEgBAQAkJACAgBISAEYoSAnb29vfqWZIzUJpUIASEgBIRAgifwVAuhNlQTbYY3rGoy1gMXr6FYprQo6u4Gl2SOaFQqH1af80Jg0EuTfAnpgovsFSpUwKVLl0yGpd/39PQEw6tVqVIFDRo0UCKJcUYuZg8dOhT16tWDs7MzRo0ahRAbvGWZN2PGjOpIly4dFi1ahO+//95Q9cmTJ1G6dGlV5+DBgw33Izvp1KmTGg/z1a1bF/SkGD9+vKEY661evbr6vYFjOnPmjCGNJ7Vq1QI9kDgeeg1169ZNLb6zL6yL3hi9evVS/V69erVJ2Zi8OHbsmGqPY58/f746Z/uPHj1Szbx48UIJCWRIloMGDTLxEFmzZo3q+9ixYw2cOVY+L3JhGQpoefPmRbNmzfD06dNIu//w4UM0bdpUcWnZsiV8fHwMZS5fvqzqJTP2qXv37oaweG/7TAyNWDgZOHAgpk+frjyxOCY+J4p4nIP0IsuePbsaK/vD+x4eHmoum89R/T49Su7duwf2mfXxGD58uEnLLi4uSJ8+vZpnRYsWxeHDhw3pS5cuVXOEHFq3bm1gNGfOHPUMd+7cqdjwWbZo0cKm/lA4ovjJvvB5LV++3NCetXlA4ah9+/aqPZb94YcfwGdobDuOhODjClH7QtR3FRrjaLdp+DR/eeOqDOePAnzxy/Z5mFy7neFebJ5E1h+2XaFIIqzaGoxg0XNi81FI3UJACAgBISAEhIAQEAJCQAgIgUgJKM8cLjqJCQEhIASEgBCwhcDkTQfwTcWicEuT0iS7i2NSPPB/brgXwBhEmj0OeHPPkJhATviFCCcnJxw/ftxkRFycZziobNmyIXPmzJg9ezbKli2rhB3jjDdv3gTDbdFrZ9WqVejdu3e4PMb5LZ3T84TeCg0bNjQkU0Thgvfu3btx+vRpw/3ITri4v3jxYpWN3jnsU5s2bdQ1F7JZZ+XKlXH+/HlUrVoVbdu2NamSY2b+OnU076wTJ9SYGSLs6NGjYGg42p07dzBmzBj079/fpKz5xfPnzw2CgC4M6K+sz5oVKFBA9b1z585KROM4eKRMGTZn2f7ChQvVWOkZwuezbds2Q5WPHz/GxIkTsWvXLpVnwYIFsLOzA58XnyfHwhBhZETBzpZwadOmTVNjJ6McOXKAwphuDIVHweHatWvKU2X79u34888/VfLbPhO9DUuvnDcdO3ZEihQp1Fi7du2qsrF9CjgUYii6kR2FLYo7e/bsUf00ru/IkSOqDoowFIcoVHGOcIwFCxY0zqqEx59//lkJR8z39ddfq3QKNc2bN1fzguUoHo0bN06lNW7cWPWhVKlSSkRjf8gnsv5QXKLo4+fnp54RxT0KarooY20ePHnyBLNmzYKbmxvYt61bt2Lz5s0mYznlGYocblETc7KkzgBrHvEDN85E95J1kT1tRpO2Yusisv6w3ayvu3I7/kdejC2MUq8QEAJCQAgIASEgBISAEBACQuCdEHDgH7qJtAUKMSEgBISAEBACkRE4cfUOdl66jrW/tIbnXdNvqZfJnR23/bZi6f5TyJMpHWbvCVus1kWdyOqOr+nVqlVTYgXFlGLFimHZsmW4ePEiatasiaRJk6ph5cqVS4VAs+TBwQVsLlbTuFhNYYj5bTV6nnBBPFWqVKoIF6G54M777u7u6NevH9avX29TdfQK0QUPClFcLNdNr6NMmTK4evUqSpQoobyK6JWRP39+PRsoCPz444/qmjwobNEqVqyoFvAZDo4H67BmZBeRaGPcL0t1JEuWTPXd1dUV/v7+JuNgfooUFJ0oGNFq1KgBCjb0ujE2hgKjF4mxUcyiNxaN3kn0ZtHFAeN85ucURXr06IFy5cqBHinDhg0zZCE/eo3Qw+v27dsoUqSIwespJp6JoSELJxRbKGrQOP9o3GuI+yy1atVKXXfp0kUJGxTgOH56KdHLifOOoh29ayju0eiZQ8+dJEmSKO65c+dW9/Uf5Ml5yXwUwfhKcWvePG2vLa19zj8y4Bz57bffMGDAADW3Ob+TJ0+uPJeMn7+1/lBooxBDYY4iIr2CON61a9cq8cyWecBnRtGW3lT79+83MOF4znmEIENae31o6vXsnSs4dP2syT1epEjqjC9K1Ap33/jGviunsFkre7rhDzhzJ+x9Y5wenfOH/o+x+sxui0W/LFkHTkmSWUwzvpkuTdjVPe0jP9u70ZiMm5dzISAEhIAQEAJCQAgIASEgBISAEHhNwIHfNOU3KSnqiAkBISAEhIAQsEZg8Mr/0LhEPnjd98EV7aB53PJG/izpkcrZEQu+/hR/HziDyf8dw9cVCuPo7Qfa/cgXC621GdfT6HFDwYShvbgYv2PHDrWXDcOR2WL0dtGNi9QUY2w15qUnhLFXydmzYQvJFGNoOXPmtLU6q/noxcE9eeihoBs9gAIDA/VL9UphxNzovUSjQMNFfgcHh0j35OHvJqlTpzavSl2zfHTN19dXte3t7W3wtKBnCsPVGRuFBXMhh+lsO3HixMoji9ccD72PrBm9TChM6SIdxSZjjxU+M84jehTx9datW0q4sFYn02x9Jtbq0YVE4zwUUyjW6cZ+6aEEKV5yrl+4cAHck4heNBRMdM8ret307NlTebRwjPSuYfg93WrXrq1CAnLuUChhOsUxCqCvXr0yPBPmZ5gzstMFRr0O41dr/SFHGkUdHjSKrBR1bJkHzEshh8b5QeHS2ArmtwMFDmO77+eDg9dN8zE9g0sqfIE3HIzL6Odd101B6wKV4HHvKjzuhomdx29eRImseZEsiaOeLUqvz4JeWOwPK/m8aHWbxJwHYdEJoWn0YkJACAgBISAEhIAQEAJCQAgIASHwHgk48NuTIuS8xycgTQsBISAE4hmBDac9wcP3xUvV895LtmDGtw3hni41yudzVwcTDnveUOkJXcyh9wkX6hn6iZ4cS5YsUQvQtu5Vwy9VRNfo7UGhRPeKYD26YECxgl4d9EiIjnFh3dgo5NAYbstanymMxITRayZTpkwWq6KHBD03IjMKQuahZOndQeMeRgxtFpGZizt6PtYZVeMzypMnjxJpSpYsqUQLCiG6MWQbvVwmT56sbjH0GYUac4vOM+F+ShQ1uI9R4cKFzau0KJhx7Lp4wwL0otLFQXoWjR49WnGlkMg9aDgWvg9o9MThe4F71XCu0GONHmmWBDiKRFOnTlXlWD/zGO/RpBKMflBYMWdgrT86QwpH5qKmvu9PZPPAqPlwp8XzJoLXHX4Z6s2cqJm3DHhE15ZeOAAefq/CBMJ2q8ZhfZtByJ0+TJwla4q49N6iKBWZZUuTETNb9Iksm9X06/fCkt1EzLHKSRKFgBAQAkJACAgBISAEhIAQEAKxTUDtmROdhYnY7pjULwSEgBAQAnGPwMqfW2FtjzbqmNymnurgGi3kGoUc2tmb9xCk7ZJ94+ETjNqwD92rloCDffTFClVpHP/BhW8u1P/xxx9qzw8uXHNfFH1xOza7T28I7rNjvFBOAYceEQyzxr7MnTs3Sl2g1wj7vmnTJnCDeP0LH/S44QI966XQQo8cikl6qLIoNWJDZgog9HixdHAB3xZjODPuc0JBS1+8pxBFsWTOnDnKG4T1eHl5qRBattQZ3Tz0gKGwwvBk+r5Eel3cl4X7unCsDFnGkG/G9jbPhOPs06dPOK8S4/rNzxk+jqHIGEKNggj7q+/JRI8deuLQuP/MyJEj1XzTw/xxvx2OhV5N9DpjqDvj3zMpRNy9exf//fefEnKaNWum6tL5MPQaBThyYrg3Y6OAxz2OOK/152mtP/ny5VMi1IQJE0Bxk/UePHgQV65cUYLk286DaiXtsPlA1Dzbg4Jf4dbj+3gQ8ASB2heqeM5QaLTj3afj7E9/qWNZs97q3qmuUw1CDm8MGTIElSpVUmNQGd7yh7X+6FUfPB2KBrXskcA/yvXhyqsQEAJCQAgIASEgBISAEBACQiDOEtD2YE2kbcQaZ/snHRMCQkAICIG4SsDC/x19l2xFgf5TUGPMQuTLmAbta5SOq72P0X5xr5U6deqoTeC5KE1xh4vYNO43wv9rGXpq5syZ6lwPwaaHOjXujPHCt/F983N+Q58eQfpiuHE6F9gp8nCBnQvXUTXuUzJ06FA4OjqqDedZnh4/K1euVOOh0EKBgXuo6GKP3oZ5/42vea4fen5rrwxnZukwrtNaee7TQ48UeovQq4ML+jTuV0PRi4v9rIteG/rePtbqs5TGZ2jNU0kv8+2332L37t1ImzatYqt7ujCdadyHhmHoODcsPdO3eSZ6Hyy9WmLZpEkTJUxSKNH3p2EoQRq50UuL4k6aNGnUHjqffPKJoWqKR/TOogcU+0xvIz1UGTNRWKJ41atXL+UdNWLECFWWwtCgQYOUUEFxkpz0fZr0yrmHD0VEzmt6ptCs9Ych8FgHBSb2mfU2atRIiU0sa20eWOLCMsbWRIuads4rBCcuGN+1fn7+rhfyTvsRv+z5F/4hweq864px1gsZper7M0UUgtAoq02nkfUnSHPAHL0wGD3bJmxR3iZYkkkICAEhIASEgBAQAkJACAgBIfCeCSTSYt+HVqpcxaaFiPfcV2leCAgBISAEbCDg4XkNRQvksiFnzGcJ1r5p7uMXgBTJHOGYJHHMNxBJjdx7pFChQpHkivvJ9CAwF0n0XnOR2XhxXL9v/kqvGnowGO/7Yq1eW0UJekTQQ4diju6NYd52fLkOCAhQIavIiKLR25h5+C/juvi8+NzI/8GDB+qZWBKAyJWeXpbSjOszP4+tZ8J9ZTiPIgo5Z94P/Zrzjh5bFFqiai9fvlTzi0IRRcOYMh8fHxWizRLft5kH05eF4szlUEzqE/tiB/cPcnZ2VuEBZ8+eHVNorNazfjcwcWkwNk0K2zvIamZJFAJCQAgIASEgBISAEBACQkAICIFYJaDEnKrat0BDQ6IWJiJWeyWVCwEhIASEQLQJvE8xJ9qdjqGCCUXMYSglejVYMnpNLFu2zFJSpPe40TxDwFmyKVOmoFOnTpaS5F4kBBhWzNpeQQxX9i7C7kXSTUmO5wSOHDmCMmXKwNPT07A3VjwfknRfCAgBISAEhIAQEAJCQAgIASEgBKJAwIF5RciJAjHJKgSEgBAQAkIglgn8/PPPal8XS80wdFR0bcOGDaDngyXjN/7FokeAIcX0EG6WaoipkFiW6pZ7Hw6B0qVLR+ix9+FQkJEKASEgBISAEBACQkAICAEhIAQ+XAJKzGHoj4jCuXy4aGTkQkAICAEhIATeDwEKK7EhrsT3sGjv52lE3ip/j4pqKLLIa5UcQkAICAEhIASEgBAQAkJACAgBISAEhIAQeEPAjiKOhT2s3+SQMyEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIgfdGQIk5oaLmvLcHIA0LASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCwBoBO4YGQai1LJImBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASHwvgiEiTnvq3VpVwgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCwCoBu5CQEMimOVYZSaIQEAJCQAhEgYC2FRv8A19EocSHkdXLywtnz56NscHy/+8HDx7g2bNnEdbp6+sL7o1nzQ4cOIAbN25YyyJp75jApUuXcPLkyXfcqjQX0wQ8rgJlvwpGsPartq32MiQY93x98Co42NYi7y2f9yOgSPNg+D1/b12QhoWAEBACQkAICAEhIASEgBAQAh8UATvNPqgBy2CFgBAQAkIg+gT2aKuTufpMMjm87vsYKjx06TpKD56BYr/NRIuJS+D91M+Q9qGfrFixAhMmTIgRDBcuXICLiwvSp08PZ2dntGjRAtevXzfUzfPixYsjZcqUSJ48Ofbu3WtIMz/59ddfsW/fPvPbEV6PHj0aFIDiu5Fhr1694uQwVq9ejWnTptnct4TwTDgPGfqXR8aMGdGjRw/cvXs3XjMYNS8ErT+2g72Nv2ovProZqUa2Rs7JPyDzmK/w4/KxoLhDm7RrKZxHfBnuuO+nKSqxZCGaELzF4xBqTftJtXvDx/R5pE8DFM2dCAvWWBeMY6l7Uq0QEAJCQAgIASEgBISAEBACQuCDI6D+vAyNylcGPzhEMmAhIASEgBAwJpDfNSUO9mtnOLK5plbJgS9fodXstehTtxwO9Pta3Ru5Zo9x0Q/6vEOHDhgxYkSMMHB1dVUCzfPnz9WCt7+/P8aPH2+ou0uXLihWrBiePHmCtm3bom7duggMDDSkv83Jhg0bEoQnz8OHDzF//vy3QRFnyiaUZ1K/fn3lbbZ161blmWQ8pyODHdcYeN4AFq8JRuv62t6UNlqJLHlxuv1oPOm9ELu/GorFl49h/Zmwz9Cvy32Ky10mGo7uhSujREpXZHDRFJVYsi3nD6DNmokonimnaiHEwiabPzSzQ7+pwXguzpix9BSkWiEgBISAEBACQkAICAEhIASEwBsCdsFaGIdEtn5l8E05ORMCQkAICIEPlICD5tGZOnkyuKZwVofD6/9Djl+5pYg0LFUQdlr8zqO3H2D1OS/4J+BVPv4fWqFCBTAslrHp9z09PcHwalWqVEGDBg0wc+ZM42wYMmQIhg4dinr16ikPm1GjRkGFPzXJFf6CYg49bxwdHZUXQ9WqVbFlyxaV8dGjR1i/fj0o6NAr59y5cyoUm+5NQxGjadOmygOiZcuW8PF541kVvqU3d+bMmaPa3LlzJ7p3767O6RGk2/3799GuXTs1jrx582L58uV6knodOHAgpk+fju+++07lKV26NC5evAi+ciyFChVSnjL0yqBnSmwZRS222apVK7DPbJvH7t27DU0uXbpU9YdeIq1btzZhdO3aNVV+48aNqhw9oxYvXqyYUzTjNbmSMesl/8js1atX+N///mfgcuzYMUORy5cvKzFO91gh+4CAAJX+ts/E0IiFkzVr1qBbt24YO3asmmN8LmfOnFE5t2/frsbGPjVq1Eh5helz3tp7geMcMGAAOD9Y9tNPPzWZ705OTuDcLly4sHrPsB3dGHauevXqqhzfT3pfImJgS39evHih3oMcG5/boEGDwHK6RTQPbt68qebAlClTFBuOQ++PXvaghqpkMXukTqHfifw1b0Z35EyXBYnt7MHzoqkz4PDN86pg8qROyJTCVR0ZkqfBsotH0KFE3cgrfYscpbMXwLWf/kK3yk0jrKV4fiDQNxSaU6aYEBACQkAICAEhIASEgBAQAkJACMQyATt7e3sgRMIjxDJnqV4ICAEhkGAInPF+jLz9pqDUoBmYtvWgth9E2IYQ3k/9UTh9aiR2sMfYjXvxXflCasyPAhLuhgr8P5QL0MePHzd5vlyAp3iSLVs2ZM6cGbNnz0bZsmWVsGOckYvCDC9Fr51Vq1ahd+/e4fIY5zc/52IzF6B/++03VQ/TKVDQ3N3dsXDhQrU4zn7cuXNH3Wf4Lp6zfzly5LB5b5bGjRurPpYqVQp9+/ZV53/++aeqkwIUhR0/Pz8Vsm3w4MFKzKBwpBv35enYsSNSpEiBXbt2oWvXrggKCsLRo0cxadIklY39GjNmDPr3768Xi/CVIgIX4M2PyZMnR1iGCUmTJsWyZcvA0GR8duTOg+OiUaxq3ry56gMFBO5JNG7cOJXGHxQA2Od+/fopDhxL2rRplRcUhR4KEBR3qlWrpgQJPoPIbM+ePUo04fP86aefsGTJEkORly9fKpGMdVNAYv0697d9JoZGLJw8fvwYEydOVM+K41mwYAEYmtfb2xu1atVSQsyRI0fUM2zTpg1seS8w1OCMGTOUWHfr1i3F2XhPJwpqPXv2VHWPHDkSw4YNUz3jPKIwVrlyZZw/fx4UL+lxRouIgS394Vzj8+H4yJbv023btql6rc0Dfd6yvyzHOU1WxnbxeigK5rDdK0cv+9D/MRYf3YSuy/7APp87aF6slp5keD1w9QxuBwWiQZEqhnuxcZI2eSokS+JoteokiYFMWRLh8k35W8IqKEkUAkJACAgBISAEhIAQEAJCQAjEAAEHVYf27Uhth+QYqE6qEAJCQAgIgYRMIJtrKvzToRFcXZxwUIsj9L+1e1E6Z1aUzJEZTzUPnBTJkv6fvfOAj6LawviXSkISSELoJUgPvYTeFSkiRUQRkabiU8ECNp7lKSIodgWp0hQFG0gRpEmH0KQTahJCDS2UhITUN+eGGXY329Io4Tv+lrlz+/3PnUXu2XMOtmj5B85cxOSnu2Hypr2IT8zf/nfk0F4O97t166Zcm4miQCxOHnjgAaU4kP1QqVIlFC9eHJcvX860PURxIAfSIqJQEMWQ1HdG5HBcDp3LlCmD2rVrqyb6GFeuXMGLL76oDr/FSkRcromI1YvEI2nSpAnq1KljHJirQjt/+Pv7Qz5i7SOWDMHBwUZtsUCSeciBtihkJJ5PjRo1sHDhQqWI0CtKnhygi8haRekl0rx5c2Xp0LRpU8gnMjJS5dv7QxQs4mbOUsSyw56IRYjMXRRpMk/TdUi7mTNnqrlJvKGTJ0+q+YiyTCxKPDy0k+sbIhZV4hZMl59++kmtQbiKkkisRwIDAw3lgF7P2lXYiXJC70+UCrqEhIQoSxaxeJH5yHPWrUBy45no49i6ivJFYjPpIntORCyJRDEmSi1RsogS0dG7YGp1VrJkSYgSyFSEuTwPXVmix4ESSzORRo0aqb1Rv359ZdEWHh4O4WNrXzqaz+jRo9Uc9H10//33K6WVWFjZ2wf6nGXt8jyefvppZcElrHSJOpmOysHmyhxR1Mzfc9MCTK8r194N2qOgpzdir13F75prtb/PRKBjiQoo43+TvV5/1valeDy4JgIKFtKzsnV1Zj7OdFy1nAtOnHGmJuuQAAmQAAmQAAmQAAmQAAmQAAnkhECGMicnPbAtCZAACZDAPUMguGgA5CNSXot+vTXiFJbuPKSUOYU1RU7UxSsYOX8NPu71IFLTMyx2fLwK5Gs+YnEjh7riGksO3P/55x8Vx0ZcQjkjYnGgixxk60oXPc/edc6cOcotlCgbHnvsMezduxdyIC4i7sw++eQTdTguih058BYrE1E86coib29vpXSxN4YzZWJlISJKHfmIiDJLlCWmoiutTPNE8SEiigFPT0+4u7ureZrWsZaWvsXNnKXImnIioogTd2BLly41unn22WfVnHS2UiAKKEuR+esiafk4E6tILDweffRRvalSJun7QJ6p7LHq1aurq7AWhZojcfaZ2OtHFG6mihype+bMGTU/eV4ilStXVlexnnH0LoiyarWmuBIFjDx3iSElrtx0EeXikCFD1K0oVsT6Slz3iVWXKEMllo4u0s4RW3vzkXdC3gexNNKftVjYFC1aVA1hbx/oc9DXLpZZukWcXla+tAuOn5EfSt1U6FxLuo6wY+F6FbNrjzptlTKncrFy+GPgKCQmX0fH79/E56t+xsddXjTqXtKUPT8c3YEFPYYaedlNODMfZ/o+GJ2O53o4U5N1SIAESIAESIAESIAESIAESIAEckIgQ5kj/86kYU5OOLItCZAACdyTBPy8PbVfkieqtRcr7IuTV69prn9qoWbZEvg38qTKD9Ti6+RnqVu3rlKQiKsu+WW+uMiSQ2JxNeaMiOuqnIi4kxLFiViKSPwbOfQWkUN3cWsmcxElU6lSpdQBepUqVSAH/Q0aNFBKC2diupjOT8YTZYep6AfgcsBesWJGsHTTcj0dEJChCNTvc3IVayNRDFiKWP689tprltlW78UtnKWISzpRKH3zzTeWRWb31hQq2X2WojSJ0tyo6SLPS1eiiEJuwIAB0N3HyTMV5YapZPeZrF+/XrnFk3hFulWQab/6czXNE8WFKAQltoyMqyuNRNElc5YyW++CKODEzZ+4iRMLMYkt9OCDDyrljukYktYVjmK9pe9pid9ji7E1BvbeTf35SSwrURhZir19oLsPFCsvW1JNs8pZtc38f67LBZbAlCeG22pilu/lUQAdKtTFbwfC8LFJyYLda+CrxdRpVbmBSW5GUiy3ZB+JUlis9RxJVuZjq6+kZOD0iXRU1FytUUiABEiABEiABEiABEiABEiABPKWgKv4Kk9nzJy8pczeSYAESCCfENh0IAqnYq/genIKJD1r2wF0D62mVldfc7UmUtK/EJJTUjFn4y50rX4ffPO5ZY4ceIuC5IsvvlAxQMTNmcSjkYPkvBLpXyyBxDJBDrsl5oxYOoiyRFx7ycG8HNCLWytxFyVl4r5MRKxjxCXYxYsXVayQrM5R+pE4IbJO3W1WtWrVVHygb7/9Vlk6yEF/WFgYjh49mtXuna4vsU3EHZfl59VXX3WqD7EOEUWXzNM06L3OZ8OGDSpfOC1atMipPrNbSdyB/fbbb+pZ7tixA/PmzTO6EiWcKJ1knVu2bFFuwIzCG4nsPhPZR8OHD8fixYstu7R5L4onEYkzI3tg+vTpav+L2zRH74LsWVE4yH5s2LCh6keegS6SFiWk1JP3SZQ4opgQKx2xfPnhhx+Uaz3Z96IM0t2jSXtrDOzNR5RCohiT+YsVjkhERAQ2btyo0jndB41qAdt3pkL7unRa5u9ajaPnTiAxRYslFb0fE3evQvcqjczaT9y2BINrt4WHptCxFHFH16JFi1zdr6cuncXJyxmxr05eOge5N5UdmqGRVyEXVAk2zWWaBEiABEiABEiABEiABEiABEggLwgoZY69XxbmxaDskwRIgARI4O4ksGp/JFqN+QE13puIvjMWoV9oCBpXzjjF89IiYc8Y0Bnv/7UBIe9OQPjpC3i9S8u7c6FZnLXE2Gjfvr0KhC6HwKLc0WO3DB48GPL3rAR2nzJlikrrLtjkQNny72DLe2tTEcsMOVQXl2Li6kn6WbNmjWG1IEoVOagXN2QSN2fBggWGS7JnnnkG4tZLLCzEmkcsELIiffr0UUokcdumx+kRd2JykLxy5Up1AC+WLeIiy9LyxXJtpveS1j/OzEcsMSSGjeVH8p0RWb/EfRElgMxXj8siFj8jRoxQh+KSL/X0MtN+Tecu+ab3YoGSlbWIMkfiCcmzlHgwEoNGF3leEiNH3JrJvnn88cf1IuOa3Weiz1m/Gh3aSYjl1YQJE1SsGdkDogwRJYvO3d67IEoasRjx8fFR8ZokDpFYiOkinEUpJMpIYShKQ9njYqUjCi55l0QRJHnvvPOOFu4xXW8Kawyk0N58Ro0apeI/iTJSGMja9DhO9vaBzku/GpMwSVTRXquendwwe8nNOZoUW02uOrIDtb9/A0U+64/Os0ej6311MLjlo0bdfacjsOvqRTxW734jzzShu+bTv3tMy7KbrjzhFTwwZ5Rq3v7XTyD3pjJxbhpGDHKD5mWTQgIkQAIkQAIkQAIkQAIkQAIkkMcEXDT/4+mttcMBWufkMWl2TwIkQAK3iED44SjUqV4pz0a7kpCIuIQkBPoVhJdHhrdO08FSNWuQS3EJKFLIxzT7lqQlvohYpNztIpYipgfVpuuRA2Q5OE9OToa4e5I4H3I4binSXqwZxDpBP2jX60j/586dU26xdLdVzoypt7d3FVdv4oZNxtX7tlf/Ti0TvsJPLJ1EgZATscdWGOmcJH6LKEhMY+/o4+rPUq+r5ztzzYtncv36dWXdJdYzWZmTWNPIfERpY7kvHa1FLMGEgyhzhFNuSXx8vIpVJW7iRDloKjnZB7sOAZ1eTsHxxe5wczXt1XY6ISkRF+Ivo0ShILg7qZjUe2vXrp2Km3Xs2DGl/NPz8+p6RjPYqdYzBdGL3FHIN69GYb8kQAIkQAIkQAIkQAIkQAIkQAI6AVc5FKIiR8fBKwmQAAmQgCMChby9UCqwkFVFjrR10w6nb4cix9G876by0aNHZ7I40S1QevXqpZYi93Igbk2RIxXk7/cSJUpYPTCXQ3QpMz2Ed2ZMZxiKJUtWD/id6fdW1xG+YkWSU0WOzFssbfTnZ3mdNGmSsTRRJlhT5EiFnDDNi2cilkKy/0z3kLEQOwlRxAjXrCpypEsZS8bMTUWO9CvvUOnSpTMpcqQsJ/ugThXg1N/OK3JkPG9PL5QJKJ5lRY4o18Qa7+uvv74lihyZa4kg4NJqKnKEBYUESIAESIAESIAESIAESIAEbgUBl6VLl6ZL4ORUxs25Fbw5BgmQAAnkOYG8tszJ8wXkYID8YpkjlgKmsURMkchhvwSbz225HWPm9hru1P7E/ZVYeFhBTPjNAABAAElEQVQTUSTkhsLIWt/MIwESIAESIAESIAESIAESIAESIAESyD8E3OWXu9Tj5J8HypWQAAmQAAnc/QTkgN+WxU1ere52jJlXa7nT+s1tS5I7bX2cDwmQAAmQAAmQAAmQAAmQAAmQAAmQQN4TcBWf+i55Pw5HIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESyAYBFTNHglVTSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAE7jwCyjJH0+jceTPjjEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABODq5uYGiZtDIQESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESuPMIKMuc1NTUO29mnBEJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkADc09PT4eLqShQkQAIkQAIk4JDAuvBIDJz5l1m9ZUN7o0LxIirvyOnzmLn2X8zecQgTerfHg3WqmNXlDQmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQNYJuLtqihxxsyZKHQoJkAAJkAAJOCIQElQY05/rYVTz9/FW6UvXEtHxmzl4vnkt+Ht7IjU9zajDBAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQPYJuKelpVGRk31+bEkCJEAC9xwB7VcACPD1hpuFVadPAQ9sfnsgihTywbJ9kfccFy6YBEiABEiABEiABEiABEiABEiABEiABEiABPKKQIabNVrm5BVf9ksCJEAC+Y7AnrOxqPr2eGV982yz2hj0QCOl2PFwc1OKnHy3YC6IBEiABEiABEiABEiABEiABEiABEiABEiABG4zAXdxsebqAs0dzm2eCYcnARIgARK44wmUC/LHnEHdEeRXEGGHo/HuwvVoWLEsGlQofcfPnRMkARIgARIgARIgARIgARIgARIgARIgARIggbuVgFLmJKekQmLnUEiABEiABEjAHoHgogGQj0j5YoHYGnEKS3ceojLHHjSWkQAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEAOCSgNjpu7Ww67YXMSIAESIIF7kYCftydiryXei0vnmkmABEiABEiABEiABEiABEiABEiABEiABEjglhFQypz0NPpYu2XEORAJkAAJ3MUENh2IwqnYK7ienAJJz9p2AN1Dqxkrio1PQMylq7iemobYuESVTk5NNcqZIAESIAESIAESIAESIAESIAESIAESIAESIAESyDoBd2kicXPS06nQyTo+tiABEiCBe4vAqv2RmDZjkbHofqEhaFw52Lj/aO4qzN8Xoe7fW7Qe8ln8ci9UKVXUqMMECZAACZAACZAACZAACZAACZAACZAACZAACZBA1gi4ixLHRWtDVU7WwLE2CZAACdyLBN7u0RZDOjVFXEISAv0KwstD/SbAQPFF34fwhXHHBAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQG4QUMqcdGpzcoMl+yABEiCBe4JAIW8vyIdCAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRwawi4ios1muXcGtgchQRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgASySiBDmZPVVqxPAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRwSwi4pqWlQQXNuSXDcRASIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIIGsEHDVJCv1WZcESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESIAESOAWElCanPRUzTqHQgIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkcMcRcE1NTYWLG61z7rgnwwmRAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQgEbA3c3NDUhLJwwSIAESIAESyDGBdO2vkysJiSjg4Q4v7UPJewKJyQnYErUZVxMuoVPNLnB11f5evyFHzx7GtaR41CpTV8+6Ldedx7ahYAFfVClR7baMnxeDbtOYlyxcCqUDyua4+7jEOCzdv0j1E+RTFK2rPpCtPs9dPYddx7ejXfWOTre/GH8ee07sMhszt+ZjbxJRFyIQfmoP7itaGdVKVLdXlWUkQAIkQAIkQAIkQAIkQAIkQAIkQAIagQyTHBcXwiABEiABEiABhwTWhUei0vBxZp+ImAuq3cFT59BhzAw0+PB71HxvIt79ZSliLl112Gd+qRAbfwEtvmmA1LQUvDn3Faw6sMzu0qSe2wgX9Sn1URE8Ma07Dp05YLeNZeHV61dR4uOi+HTlSCzYOw8p6eZuU+fumINvV39m2SzP7hfunIvpGydl6v+7dV9h3q7fMuXnRsaYpSOx6cja3OgqS30MXzQU/xxYnqU2tionpSZi18mdmL5lCkaveN9WNYf54Wf2oefvPR3WM60Qfnofuv3SzTQLuTUfs05Nbr5a8QmaTWiIubt+xaGYrO15k27MkrdrH5hNgjckQAIkQAIkQAIkQAIkQAIkQAIkkIcE+LPpPITLrkmABEggPxIICSqM6c/1MJbm7+Ot0mlpaXi9Y1M0q1oecdev463Zy/Dzhp0Y2rmlUTc/JzZHbYKvh69a4uS9U/FS62FOLfeXh3/WLBNqYMamyQiZFILTw86gmF9xp9quO7wKZb1LYtHzK63Wf67VS0hOTbFalheZe0/vRlRsJAY2+09edG+1z78PLkK5gGA0RSur5XmV+XO/uSjomfG8czpGoE8QPuzyCX7YNBU//Ts9p91lqX2D4EbY91K4WZu8ns+snTMxscsUdK1z83vEbALZuLld+yAbU2UTEiABEiABEiABEiABEiABEiABEsgWgRuWOdlqy0YkQAIkQAL3IAF3V1cE+HojqJCP+rjfiLsWUqY42tetCl/vAijhXwid61TGnzsP53tCO6I1t1bjmmHwgv8g7Px2tB7bGFfT4zFwdm+EHV3ncP1FtIP8mqVr49Me36BygWDM3DjZaDNn64+o9VllZb3z5PRHcD7uvCo7fuEYGnwegmf/HIj9146otNxfT05U5eJeTayEOk9+AJPXjjX6k8SIv/6LkX+9g47jW8P/Q1988veHmrfVmxY9tsY068TiZtuxLWoOY7Z+jl+O/GHM58KN+Ur1aE3Jk5tjTl0/Xo2zNnYLXls2VKV7TetizOzslTPoN/NxtcZqn5THr9t+Nsok8f6CNzFx9TcYNKuPqtPoy9pI0FzSdfiuhXqewuZ/C4erMrnqMm/Hb4ptj+mdse6wuRJN1vf1ijFqLvLc5u/8Q2+GxXsXqHyxxpL5jPvnC6SLX8Icys9bZkIsuyp+XBq/bP/BrLfPl32k8mVMWd8qC0si2bftxrfA878+bdbO3s3Yfz5XlmemdcSqbO6/v5pmWU3L3pN9ujP+AIYufkmlp62fYNS1tfeSUpPw1IxH1bOQtXSZ9CAizx9V7Rztg4cnPgB5R3Vp9nVdHI45qN/a3AdSwdZ8pCwsYgN6ft9ZvZvCfsme+ZJNIQESIAESIAESIAESIAESIAESIIE8I+AqBwnpjJmTZ4DZMQmQAAnkNwJ7zsai6tvjETpiMiYuD9Pcit1UBJiuNezICbSuXNY0K1+m7wuqgI86fYoEzVXWV+2+QGjJBnisbDeVV7l4iNNrllg3Lcs0x/6YfaqNHLz3WdwP/231DrYP3I5ryfH4auXHqqxEQGn8MfAvvNHkDTQuXEel5d7TvYAqL6PFcZn+xGw0Kd0UkRePmM3hRGw0Ptg2GoOavIBfe/yCdza/j6NnM+rYG9OsE4ubGiVrqjk8W30AOpRpa8zHv6C/UXPiwem5OmaP+k+ocRr41cKbTd5U6a96jFfjiXKq14xuuJp0Fav7r8b793+I3n/1gcSU0SUyNgqD17wKvwKFsbzvcgxu8pJSrmy+sBM9a/ZCr0qP4qe9P+Lvp5Zi1L9jcPbqWdW0jRbPRtgmpSZryrUMF4N6n6LMm7htAr7qNgH9avdD/wX9DYWNi/b/W2Me+grRL0djbJfxeGXd61jpwBWf3q+t62UtTlLfJQPwVrPh+P6RGfg7cqlZVV+vwvjlyXmIfCkSvWs/iXa/tIfEyNFl0uMz8WLTl7EuZpOe5fDavGIrfLHnW4hbQZEDZ/bjt+Pz0aRic4dtX2w1TD0nPxcfjG43RqUfqd9LtbO399LSUlG3VH2EPbcFB54/gACvAPSZ9ahqZ28fSIX1Z7V4Upo7Ql02X96l4kjp97b2gb35SNthCwYjtExjHH/1BH7pPReFvG/udb1vXkmABEiABEiABEiABEiABEiABEggNwkoZY6LC2Pm5CZU9kUCJEAC+ZVAuSB/zBnUHSuGPYnX2zXC5yu3YWfU6UzL/XvHASzYH4khHZpkKstvGf4FA1CtZA3EpF7EE6F9cVE7YH+kVk/tcLsFivgGZWm5AQWDcOrqCdVm+uYpEEVFYe2Q+OSlaDQNbonvdk1SSgQPV3eUL1IBxf1KoKB7QZWWe/3v8wIeXqhcvIpWbt1dW8+yD+NRTRnSvmZnNcb26M0Ox7S3EG/PjDmIlZG/V6AxHzdtnrrk9pgBBTPG8XH3RvFCJdWYpfwzlIcSh0UsdtpWfAAnL59AIa9CqF6wEhZYxO2RvC8fG4+G9zVF/2aDULBAhtu0FpXbomn55ggtXh9NKjSHKB90JYiMK2wL2XCxNrTpMLSq3AaDWg5RFlpRNyxIOtXqhlZV78dxTZmWkJKorLAOxZi7N9NZOXvdErERxd0C8cr9b6BttQfxfP3nzZo+r7nZq1ysiqasO4TS/uVU2THNqkuXisUqIziwvH7r1LVeuYaK5cJd81T937fPRtdSHVGqcGmH7Yv6FVXPSSqW9C+j0sJTxN5+9/Lwxuvt39Geox+OnD2AqkWrQZQyIvb2gargxB/W9oG9+YiyMCruuKaoS4Ovtg9CyzdG80qtnRiJVUiABEiABEiABEiABEiABEiABEgg+wQ0bzmapzXR5eTc00f2Z8GWJEACJEACdwWB4KIBkI9I+WKB2BpxCkt3HkKDCjcPcrdHnMSQX1YopU+xwn53xbqyO0mxzhi/6ktEXTyqDvwnaS7NFhxbjCBNKVNCUzC01qw4siLn48+hdKGMQ/cjsYc0q6dk/B3+l9FF36q9ce16HDw1BVJOpK5mPaRLab/SuHwtVt3mlzFPxB5X6zl87iDkI9KmXBv4eZlbT3St0lWVWf5RQLNw8nTzRAE3b1VU0LUAklOSLKtZvQ8pVVvli5JP5EriFXX9KWw6Bi97CU2CGqBykSq4knIVickJqiy7f2yL3oJGxW4+y6pa7CVTeXPuK5D4TR3LtENRn6Kq6HoOxxSF4ZBGL2Hy1gno02QAxu8Yj8ldvjcdNltpe3vPRVPitP42FDEJ53B/2Ta4kpTBNEWLB+XudlNhmK2BtUbW9oG9+ciznfnILAxb/DLe3TICnYrfjy+7f4cqJapldwpsRwIkQAIkQAIkQAIkQAIkQAIkQAIOCbjLP8rpZs0hJ1YgARIgARKwQsDP2xOx1zLitEjxoVPn0GvyPEzu0xGhFctYaZH/shJTrmNd9Dq0LN4U4Wf3qwUW0yxmktNSsrTYVK3+mhNr8EKDF1W7soXKws3FHWN7TclSP85UFpdu1iSnY7q4uCLNxrrzakw3bS1yqG8qRX0zFBevtH0DlTTLFFsS4J1hFWKrPLfyxU2YKHImdpqAJxr2VTGK/hg11yxWkYwlSqSryXFOD1u9ZC3M3DXDqH/sQoSRPnP5lHKHduTFw7ivaCXNOucwxh8QpYvzv96xNZ9HNKuuF1e/gqnrJ+Ja2nW0q97RGDe7CXt776/dfypFzsE3jynlzc+bZ+D344uQbmJYbm0fyFyKeBTW3KplMD11KUPJZzlHa/vA3nyk/YM1OmFPjcPKzdwrfzyHD5b8Fz8PzLBWsuyf9yRAAiRAAiRAAiRAAiRAAiRAAiSQGwRcU1NT4eZq8q/h3OiVfZAACZAACeRLApsOROFU7BVcT06BpGdtO4DuoRm/Rj954TKenDIPQ1rVRfWyxXDm0hX1yZcgbizK080Dwzv+Tx3Cv3H/O2hWvoWKtSJ57UI6OLX0c3HnVID2Ib8MQlTSKfRv+pxq173mY/gl+k+sPbxaU5Ck4kLcec1N2Fyn+sxupZyOWbtMXfxzfDXk0FxcUTkjOR2zcdmmWHJgISR+jD5mSKmaKO9ZCt+s+kyLdROj+IUdXae56DrkzJRyvY4oucp6l1QWUEmpSZi1aZpyy2c5UKPyTZT7sJ3R/yoLLMtyy/ummiu/w9ePYUX4UsV89u5ZRpW0G0qbSwmXcUmzvBq7+jOjzNmErfkU8yuGXuW644VVL+H5ms9A3KDlVOztgzQtLpfEpIrXlDKRmtu68WFjMw1nbR9IJbHkWbhnroqbM32j84pRe/ORZ7h832KlRKyoKQurBIWgsIXVV6YJMoMESIAESIAESIAESIAESIAESIAEckhAWeakOf8jzRwOx+YkQAIkQAJ3M4FVWhycaTMWGUvoFxqCxpWD1f3OY6dxKSEJ49buVB+90sHRL2o/GtBceuZTkeDqEr8jtFwoZoRNRruqzilxdBy9/+qj4p60KtVSC+5+EBJXRKRXaB8c1Cx92v7cVq+KZyv3Q9c6PYx7W4kXZg/E5EMzjOJpI35Gq4BGWPXyZhVXx/JppN+InZeTMWWwllqsmXbB7VD92xAVL+b0sDMopsXtESvgvBrzqUYD8faiNxD4aYCK5bLnjcPKRdqfff/Ck7Mfw/gvSygOEltmcd+lBhNJuGpKFptyg4lRfuO+1EdFDEXMqmWbMGDZM/iw4Xt456EPVVU3i3aydvl89OAneGHRc8qiRWIhyfOwHF8saMY0HYk2M1opfmdfO2c37pKwfbve6+jwa4ZlTLug5sZ0JYbNew3eQuj0UJUneydDMn7AM3vLD3hqSX+jvtuIjPxLw6/Ar0CGe0R78+nX6BmlbHwi9GYfRmfZSNjbe2IF02BzffWMpevnqw7Epkv/wiX95kDW9oGU9m08CE/88igmfjJdvT+SJ8/DVCyfg5TZm0+K5nKv/7y+xj5o6l8f3/f60bRLpkmABEiABEiABEiABEiABEiABEgg1wm4LF26NP3++x/Qfs1q8i/iXB+GHZIACZAACdwqAuGHo1CneqU8G+5KQiLiNKVNoF9B7Rf5OY9XkZsT3bt3L2rWrJmbXd72viQuT8zl0yjiE4iCBXxvyXzy05jnNYumFC32kCg+rB3a3xKgNwYRV3oX4i+oueTmuFc065t07b/C3uYxgWQMibGUoll2FfIunJtDYvzqrzF12yRsfz08V/u1t/fEOs1XewcKeHhlaUxxw3cl8RICfYKy1E4q25pPuvb/zWJVpwWfzFa/WZ4IG5AACZAACZAACZAACZAACZAACdzzBJRlTqrmvsLyV4r3PBkCIAESIAESsEqgkLeXdjCctcNUqx0x0ykC4sqtbGA5p+rmVqX8NGaQb9YP8HOLo2U/bq7uua7IkTHsKWpyWwEoLvS+/udzFY9nbrffLZeY43t7e69INp+lu5t7thUutuYj/98s7uYoJEACJEACJEACJEACJEACJEACJHCrCLjLLwtdtX+Q0i7nViHnOCRAAiRAAiRAAiRwdxJw1RRSwQHlsbbPajSv1PruXARnTQIkQAIkQAIkQAIkQAIkQAIkQAJ3IQF3Nzc3ZZUjSh0KCZAACZAACZAACZAACdgiUKJQSQxuO9RWMfNJgARIgARIgARIgARIgARIgARIgATyiICrKHFSU1PzqHt2SwIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkkBMCys2aixa8lUICJEACJEACJEACJEACJEACjggsW7bMZpX27dvbLGMBCZAACZAACZAACZAACZAACZBA9gm4u2qKHAniSjdr2YfIliRAAiRAAiRAAiRAAiRwLxGo36RepuX+G7YjUx4zSIAESIAESIAESIAESIAESIAEcoeAa1paGhU5ucOSvZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZBArhNQMXPEModCAiRAAiRAAjklkKbFYbsYl4DEpOScdnXXtpc4dIsXL0Z8fLzZGuTHEzt37lRl58+fNyu7224SExOxfv16tZY7Je6eMF25cuVdg3LTpk2Ijo7ONN9Lly5hxYoV2LhxY6YyZmQmEBcXhyVLlkDer7yUQ4cOqfc3L8fISd/bt2/HvHnz1OfcuXM56SrLbX9fXgAjJhbMcjs2IAESIAESIAESIAESIAESIAESyBoBV1HkuFKXkzVqrE0CJEAC9yiBdeGRqDR8nNknIuaCohGpXRt9OAWNPpqKmv+bhDdmLcGp2Cv3HKnk5GR07twZMTExZmvv2rUrBg4ciIULF+LChQxmZhWs3CQlJeG5557D2bNnrZTeniw5PC9SpAg++eQTtZbcOEQ/cOAA3nzzzRwt6ODBgxDGd4u899572LBhg9l0w8LCEBAQgBkzZkCUPc7KZ599lqX6zvab3XqLFi1Sa8hu+6y0O3XqFB566CHktVJx/vz5mDhxYlamdkvrnjhxArt370aPHj1w+PDhXBvb0XfQ9evA/yZ7oVvbe1eBn2uw2REJkAAJkAAJkAAJkAAJkAAJOCCglDnJKakOqrGYBEiABEiABDIIhAQVRtjbA41PuaAAVeDvWxA/PtMN+z96AZu18muaImLWun+JTSMgypu//voLf//9NyZMmICqVas6xUUOqKdMmYJr1645Vf9WVBIFxH333Qc5sJe1eHh45HhYsar54YcfctzP3d6B7JG33noLs2bNwmuvveb0csQSzJqVj9Md5HLFffv2YfPmzbncK7uzR6Bbt254//33UbBg7lrIOPoOWrCmAIJLpKNuVSpz7D0flpEACZAACZAACZAACZAACZBAbhBwlU7c3N1yoy/2QQIkQAIkcA8QcHd1RYCvN4IK+aiPu5v6qwQBPt4IKVMcntrfKUW0stD7SmHTkZP3ABEo90sN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78Gjki9Xdjc53CddvXZDbty8LXfv36flpntU0ZIKBRpi5MC1mjuLHMfGg4ODJDAwSIKCAuWPTX/L7r0H5cy5CxL4INAxK/djiACC2mfVGDlws1VVLXJ8dUIfijkftb5xJ4GBD+SBjtuJE6flnx175Jh+X7x0xV0RpnlIIF+enHJYlZ3RJbYxL5xfypV9UhInSiyJEvmbsXfXJu9f13RsTMN5HznWeP36TUmpSm4KCZAACZAACZAACZAACZAACXgrAaPMeabms1y5660jyH6TAAmQgAOByCpzHKrjrhcRwIRwkC7OCFSFjmri8D8VcrE4fiEutLQDqqCDZYavL1ziuVfkoLuwzoJSDhYJDx480PEMkmAdV7rFjbrBjA6WakAlPnCnpuOM8fZXJY6/xqaEEs8T4f3rnFJE7yPH2qjMcSTCfRIgARIgARIgARIgARIgAW8j4A8f3ljxhkkCCgmQAAmQAAmQgPcSgKLA1zfYuMezJqutb+89K+/tueWmMGQyOiS2kSdng/x+fv5G8QNFQJAq6SB8V/OEnus8itUoOPEdbaKVm//028RA0vdsT4X3r3NSEb2PnNfGoyRAAiRAAiRAAiRAAiRAAiTgvQT80XVODnjvALLnJEACJEACJGBPwFIcUIljTyV2t63J6PD2wlIGBKlljhHPDDzC20yCym+NRXTeH9Y9GBGwVtno7F9E+hUXylhjFxf6wj6QAAmQAAmQAAmQAAmQAAmQQGwQ8Mc/FvGPI/6jMTbws00SIAESIAESiB4CnPiMHq6xUSuUOpSoJRDX74+43r+oHQ3WRgIkQAIkQAIkQAIkQAIkQAIk4AkBX6PM8SQn85AACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACcQ4AaPMCY5O3+ExfkpskARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgATiDwF/48YhOP6cEM+EBEiABEiABEiABEiABEiABEiABEiABBIqgW8W/ZJQTz3C5/1aozoRLsuCJEACJEACJBBTBNQNO/2wxxRstkMCJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEAC4SXgHxgYKAI3a7TOCS875icBEiCBOEsgRUCyONs3dowESIAESIAEYpoAn4sxTZztkQAJxCaBti0bxmbzbJsESIAESIAESCCaCPj6+flFU9WslgRIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIILIEfIODgyU4MCiy9bA8CZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZBANBDwhZs1Hz/GzYkGtqySBEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABCJN4P84ENf2mtig3gAAAABJRU5ErkJggg==" - } - }, - "cell_type": "markdown", - "id": "77d60dc3-bb36-4b19-8dfd-22a5f15ffb29", - "metadata": {}, - "source": [ - "![image.png](attachment:b635b471-d26d-4374-abe0-41c284eaae6a.png)" - ] - }, - { - "cell_type": "markdown", - "id": "18fba209-f034-4fe3-b9d7-0daa8b7376c3", - "metadata": {}, - "source": [ - "## Run models in DBT\n", - "After we defined models, now we can run and generate our feature tables. Simple exeucte `dbt run` in the terminal and it will do all the work. " - ] - }, - { - "attachments": { - "5b91a161-f657-45a8-b48d-ad595e00e7e6.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAB0cAAAKYCAYAAAAIfPBPAAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAHR6ADAAQAAAABAAACmAAAAABQaIM2AABAAElEQVR4Aey9SWwkyZauZwwG53nIgZkkkzlWVtZwb49qNR4ErQW8pTaC8FZaaK21GtBCa6210ErQTg31QnraNCA8ARf91N339u17qyqrcmYmmRySyXmedT4LGul0unsMDDIjyP9UMSPCBxs+Nzc3P8fOsYa//du/Pfx/fvOvbn5hyUlEQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQARE4KoSaHz16tX/MDL2ldvc3LqqdVS9REAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAERMDl/uZv/kYYREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAERODKE8h1dnZaJQ+vfEVVQREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQgetNINfQ0HC9Caj2IiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiAC14JA7uDgwCoqA+m1uNqqpAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAhcYwI5k2tcfVVdBERABERABERABERABERABERABERABERABERABERABERABERABETguhAoWEYPtebodbngqqcIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIXFcCuf39fYuqq7C617UBqN4iIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIicF0I5BsbG52T5+h1ud6qpwiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAhcGwIN7a2uobnZNeRNB+rkIFLbF/7QHe7tu8OdHXe4sVXbRVXpREAEREAE6ppA3pde44K6vogqvAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIwAmBhsaca+jqNKNoQf15skffapdAg79eXLNDM2gfrq65w/2D2i2uSiYCIiACIlC3BAprjtZt8VVwERABERABERABERABERABERABERABERABERABEThNQIbR0zzq7RcGUq6hRAREQAREQAQugsDR1KmLdx3tzefcaEfe8flhY8+Nb+5VVJ+xtrzrbs65lZ3CrKFK06koc50kAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJQ0wR8KF15jNb0NSqlcN5AamGRFWK3FFo6RgREQAREoBwC+f/yf3rt/qsnh+WcU/axGDRH209CWPCdv3KMpFHjKgXgN7K0e+CW9hRewcPQPyIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJwzQmwxqjkahDgWso4ejWupWohAiIgArVE4IuuORoMplnen3GjaBwe3qhLyzvxzfotAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJwDQk05BuvYa2vZpV1La/mdVWtREAEROBLE8j/7//dI/d3/37qQstBGNw0yfIijXucJqURPEiT9p1nW293l1taWT1PEjpXBERABERABERABERABERABERABERABERABETg0glc/BJil16la5uhruW1vfSquAiIwJUg8PDBfdfZ2eHrsra27t68fVcT9co3NNgD5vBiw+qyPmgxI2aWkTSLFKF5K5HR0buup6vb9fR0ud/8wz8dJ8H20eG7bnl51S399PPxdn0RAREQAREQAREQAREQAREQAREQAREQAREQARGodQIXq+es9dpfzfJxTWUkvZrXVrUSARH4EgQ6OzrcrVs3fdYYLmdnP/nvM0ef1SrTbcsjGEZJk+/kvba+Xq0sKk4nv7+/77yBtOIkip9I2Fy8R4sZSEkphNplLdFSzssKyZtWMrxCMYDGJRhG49tL+R2MrT9cc4NqLpfz7Yl2dd2F+woeYlFZSxC/yrjpLBEQAREQAREQAREQAREQAREQAREQAREQgXQCwSgQVdhzNB5NGAhqQWmfXnrtEQEREIHzEcBgGQyjIaXo72obSEMe4ZO81mrAe9R7jh66i59R9WF9z/X2lLYYuvciNVJ4hWZ5nVbqNRouQjU+MbR+++3X1Uiqqmm0t7e5rs5OnybGufWNDbe5uVXVPJIS++bZU28Q/MMff0zaXVPb8rb+xEB/vy8T98DmxqYNfjbMkbo69wPu4h0d7e7Dhwm3uLRcU3WvZmGiHKPprtvsD3hWKteFX6V8dJ4IiIAIiIAIiIAIiIAIiIAIiIAIiIAIiED5BFDM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QASuIIHDnR0ZR6/IdeVaSkRABERABESg2gSOjKPVTvZsesfGUDNwnkeCkfQ8aehcERABERABERABERABERABERABERABERABERCBq0ngcGPTHTY3y0Ba55f3cG/PcS3lOVrnF1LFFwEREIEaJJA7OGDNTsXgr8FroyKJgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiUTcBC666sWXjdQiS7sk/XCV+cgDeM2jWU3vqLXwoVQAREQASuJIF8LlcIUXsla6dKiYAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIXDsChwf77nBp2TW0t7kG70XaaAzkIFLbDeHQrxdLKN2Cxyil1TWr7Wum0omACIhAfRIorEx+eLFrjtYnGpVaBERABERABERABERABERABERABERABERABESgPgkUjGo+xK4PzVqftbi+pZZR9Ppee9VcBERABC6eQH5/f98m4Ohhc/GolYMIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiMDlEojqPeUgcrnsy80teq3KPVfHi4AIiIAIiEDpBPKNjRZSQp6jpRPTkSIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAnVIQMa3OrxoKrIIiIAIiIAIVJ1AYcFRjQuqDlYJioAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAI1BaBgnG0tsqk0oiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIhA1QkcGUflOlp1skpQBERABERABERABERABERABERABERABERABERABERABERABERABESgpgjkDllvVGuO1tRFUWFEQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQASqT6BgHJXjaPXJKkUREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREIGaIpAzsQLJOlpTV0WFEQEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAERqDqBXEODGUYVVrfqYJWgCIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIhAbRHI7+/vuz//s1+71bX12iqZSiMCIiACIlARgfWNTdfclK/oXJ0kAtUisLO7p3ZYLZhKp2ICaocVo9OJVSKgNlglkErmXATUDs+FTydXiYDaYZVAKplzEaAddrS3nSsNnSwC5yEgfc156OncahHQM7laJJXOeQjQDpEvqcOW5+h5rqDOFQEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAERqBsCuUOF1K2bi6WCioAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIVE7Ae44eyEBaOUGdKQIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiUBcEvOdoQ0NDXRRWhRQBERABERABERABERABERABERABERABERABERABERABERABERABERCBSgnk5hfmnUyjleLTeSIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAvVCINfR3uEODg/qpbwqpwiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAhUREBhdSvCppNEQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQATqjUCusbHRyqzAuvV24VReERABERABERABERABERABERABERABERABERABERABERABERABERCB8gjk9vf3yztDR4uACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIhAHRIohNWtw4KryCIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJQDoF8Q4OF1OWvBJmcmnYbG1tuoL/P/noTzyjlmMQTtVEEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAELpBAjrQPSgitO7+w5A2j7e2tbn5h0WEEjUspx8TP0W8REAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAERuAwC3nM0l/M20sz8MIhiGB2+M+QNo3iQxqWUY+Ln6LcIiIAIXDcCq2sbbmdn1+3s7hxXvbmp2X/v6mxzzc3NjmPW1teP9/OFY8L+Uzv0QwREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREoCQC3ip6eHhY9GAMoxhEo2Fz4yeVckz8HP0WAREQgetGAKNn1DBK/fnN3/bOXqJhNBwzv7h83XCpviIgAiIgAiIgAiIgAiIg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AiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAtUiUAirW63UlI4IiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAI1CiBXENDg3P8SURABERABERABERABERABERABERABERABERABERABERABERABERABETgChPIUbcDC60rEQEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREIGrTMB7juZy3kZ6leupuomACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACFxzAt4qenh4eM0xqPoiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAJXnUDOG0a15uhVv86qnwiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAhcewJ5CDRcewwCIAIiIAJXi0BTU9PVqpBqU3cE1Abr7pJdyQKrHV7Jy1pXlVIbrKvLdWULq3Z4ZS9tXVVM7bCuLteVLaza4ZW9tHVTsY72tropqwp6dQmoL7y617aealYL7TB/cHBQT8xUVhEQARGoaQJ77sDtHu65Lbdv3w7s39LCljfaNJWc/dfqGl1TQ97l7btEBERABERABERABERABERABERABERABERABERABERABESgugTyuVzOVPf71U1VqYmACIjANSOAUXTd7bidw32Xb8DM2eCNnA0l+uYf0hPb+s8YVdcOd11zQ6PrcM0ykl6zdqTqioAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIXCyBfGtrq3PLuxebi1IXAREQgStMYMuMmStu2xs023OVhbPFiJo/Wv8Zw+iuGVkXDjdct2txrQ2VpXmFkatqIiACIiACIiACIiACIiACIiACIiACIiACIiACIlB3BHb3dt3enkUd9EFdS4s6WHeVrHqBLeqiBVrM5y3qYr46uvL8/v6+azhSyFe9vEpQBERABOqMwL9t+d98iW81/MbNHv4bN73/wP12769Ta7F5uOM23K5rs1C4OfMYrZY0mYGUULvrlv6heZS2NTRXK2mlIwIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIicIkEDg8P3Nb2jhn5cq65uck1Yu0rMergJRazRrOyqItmTcaovLm15Vpbms2ueT5dfL6xsbFGK6tiiYAIiMDlEbiTm3T/RfP/eCpDDKS38r9xv87/r+7/3vnv3dTB8Kn9eIxiGG3J5e0x1nBqXzV+YGxtsckrGwe7ruGwQR6k1YCqNERABERABERABERABERABERABERABERABERABETgkglgGK2m5+MlF/8LZ9dgxmRzJmq2iIvmeQvLNqLinkNyeCQdFvx3z5GMThUBERCB+iYQDKN4i2II/de9f3eqQmF/2MgaoyGU7kUYRkM+pE2YXfIiT4kIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiED9EMCgh8dotULC1k/Nq19SGMISpueR3FUPq4ur8nWTAzN2X8d6X7frrPpWj8Cf5//BJ4ZB9P/c/q/dnzX9B+8tGs8hhNxl+7rb8UbLaobSjecXfpMHBlLylIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACNQPAcLB4jUqqQ4BWML0PJIjrO5lLvmK4W5padmtrq2dKvf+/p7fvrm5eWr7eX5MfJxy//Eff+fW1jfOk0xdnXtwsO/+v3/6nXv56m1dlVuFFYEvSWCosXC/TB2MOgylhNPNEjw4dw73HeuCXpaQF3nKe/SyiCsfERABERABERABERABERABERABERABERABERABETg/AYK3FtYYPX9aSqHA8rwBcc+3YmkFV6Eh1+BevXnrnv/8wrwbT8yyCwtL7vkvL93K6mmjaQVZHJ/S0tTs2tvaXL6x+msBHmdSxS9Lyyvun3/3e7exUbmBOIK0iiVTUiJwtQlEjaGsL5om4bjdwz2XN2/OyuTQTU5Nu7nP82WfTp7kLREBERABERABERABERABERABERABERABERABERABEagXAtjC6sNOVR9EYXliX6ykzF67f5mXhPXzBvv73f7+gVuPeHRiGET6envKqEe88qd/37w56H79q29da2tbGWmGQ0+nFbae/Uw7Lm372RTClh1bRHZ3d88uaVoo4PLTDGnrUwREIJ0A64wi8XVF42eE47bcvstV+DBbWFx2C8vLbnun/BC55EneEhEQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQgcoI5Ms97e37D25tLTtM7a1bg+7W4GBq0n39fW569pNbNoNoZ2eHGQMP3cLiouvsaHfNzc3eo3Ti40f36dO8Xzvz5s0bbnTkrpkFzOv09VtbtDbvmlqa3OTklBu5e9cNDPa5Cfs+P7/gmm0x1hs3Bt3du0NudnbOzXz65J4+eWQG0laf7uTUlPts6e5Z+Nn+vj43dm/YNTbmHeF+//jjc4dBFc9N0urp6najo8Ouvf2scXVhcclNT8245dVVX+6xsXuuu6vTh/CdmJh0ixY6mN937gxZPr2eBWXHdbq5tdnNzMz5GNOjI8N+/+ynOffBzkNevnjjmpqb3LfffJ1Y36GhW+Z5llwPn4D+EQERuBAC0/sPfLoHNoGhqaHs7tPt7O64aeuTbtoEkb398o2cjQ0Nbs9C60rSCawePZ+6OtvTD7qie65z3a/oJVW1REAEREAEREAEREAEREAEREAEREAEREAEREAELoBAHqPgZfsjdnd3+qosLi15I+bGxob3JB0Y7Pfb341/cDNmPMUI2GDGgI8fp70h8e7QkNva2nJza+tm0Mx5Q2Z3d5d7/37SfTZj5sP799zOzq4ZIHb9eTt7O97QuW+GUCSk22PndDQ1OQyS5P3tt197wylG0fHxCdfb3e0GzHD6ycJesrDro0cFg4hPxP6ZX1h0L16+9mUYHh5ya6vrZrBtdJtbm+6n5z/7wyj7Zzv/lxev3NdPn3iPWMq+amVvM0PtwECvm57+5N68fef6/+zXrqWlxbXaH56j3T1drqW5xaeTVN+seoQy6lMERKB0Ar/b/c/NazR7nVFS++3eX/tE963XZLJGeXLoPtqEiqEbN1yDTZLYs76nXCFP8pakEyg8A3b8s2Cgv5xIBOlp1sue61z3erlGKqcIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIVEpgc9Mc+ywyYbGlGQfMQXGgv+C0V2leV/28ssPqPrg3at6e6R457MvyGgVoztbNuzHQ79cX3d/fc8srq55zX0+vOzg88IZR73V5+5YbunXTGxOXFpZPXYtnT79y9+/d856n+0ceWBgc8Bh9YEbSuIR0MUx+8+ype/L4obsxOOCNlZsbW8eHYzh99uyJN4g2NeXdooW/jMusGW6R77995kaHh92zr79ybba26cL8kjfyPnr4wMo26r61fJC5uc/+M/zzq++f+bLjpYoxdGtr2/X2dLseM8oit2/fdMPDd8Lh/jPUt72jzfMpVo9TJ+uHCIhAJoGpg2H3r3v/LvOYYvszT7adi/bQslkbrv8aP5Q+Ts+47e3tVFRM1hk3D/roetSpB6fswCDabOtN46U7H3tupJzyxTdXo95UopbqfmjPckJIV3otib4Qwu1/8QukAoiACIiACIiACIiACIiACIiACIiACIiACIhADRAoxTBKMXHwmzRHHUk6gRyemSjsy5E0AymGUfaVIv1muUaWV9bckilQCadL+Fos38jK6pr73e//6P82zeNyM6ZQ77KQtUHG7o34c1+/eef++Xe/d3PmsRmXkC6epkG6OgtprEc8uPIWsjcsjBs8OcPx4ROFLYZTDKJRWVtf9z8JD4y0tbX6z+WVwnqq/of9k8s1+q8tpsBHWH+1mIT6llqPYulpvwiIwGkCeIWGNUVP73HecBq8RtnXaB6chAMvR5hosWH923PzOp+YnvbrjmIsLEfIk7zrVTCW7WX0dxjUFm2SyXkX064lI2Ep16pa9Savcuo+93nBR1oopYzlHsPEn8mpabe3t1fuqf547hWe/RIREAEREAEREAEREAEREAEREAEREAEREAEREIECgeAximfok0f3E//Yh3BsJQZSnFvQ4y4trVh0vp1Cxlfw33xjY6M7NG+dcgUjaHT90XIMo+TV01vwkmRtT4yNeHwirS0Fg2KXrUX67Osnfpv/J8OAi5Hy199/4w2qb96M+3U6+/pOh1MM6a4fGTBJMxhFgxHzJLPsb5SN8Lg7O9tm1C2Ev+UMvDqxyG9sbvkwudvbhYbT1XFiyM1M2fvxmlkg43JUsx6ZZdFOEbiGBEoNr5tzObd/eOjyGf1SHN8DW5c4CF5x9D93h26HTSV9kid5S4oTwEiI52jwIOX3dZFS6z6/sGBrZtskHwszX21hwtP33zytdrJKTwREQAREQAREQAREQAREQAREQAREQAREQASuPYGskLnsw06FBAPp8J3S9NDorXGoyJtzIKpvlp68Ycth9vVePd1qHq8OwtFWIhhIZz9/duvrGyV7jIZ88o15DzR4efb3FuIfY6zt7+s1y/SS+zA55fp6etzaxro/tqO9I5x+/InHzS8vXvt1Ojs7OrxHp9kmzwjpDli685bum7fjtkZo3q852mbrfHa0tzvCGpYqrI2KcfT5L6/cHQv9u2bf2dZndZiYmPLp37lzy81bI0LCWqrF0u88qt/0zKytSdrvOcTPKVaPcPymQcAoQHhJiQiIQGkECK/7v2z9z0UPbjX/zS1b/fOyhRWi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96bBUNcvbr1NM5u3si56yT1piQACCCCAAAIIIIAAAggggAACCCCAAAIIIHB8CLiSj1xL6ern7RQEEEDgeBOwmaOr1m6WVN38tAKWJSvXux+VyXbNDorqrfsqHEUAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIFsAbMwoynZKzSaZRphQQABBI5LAacGGBs2qC1ZmZUzwkjW6HH5umXSCCCAAAIIHJcCG7fskNYtGh+Xc2fSCCCAAAIIIIAAAggggAACpSPAMrql48hVEECg8gpk7zlaSQOjys4v8sr74mPkCCCAAAIIIOClwJH9171sRXUEEEAAAQQQQAABBBBAAAEEEEAAAQQQOCLg0MxLsud5PSCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQFUXcOjGy0RHq/rTzPwQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQMBmjmZmZCKBAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIVGkBGxx1OHyq9CSZHAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIOAwxSyrCwQCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBQtQUcmZlmSd2sqj1JZocAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgjYZXXFh9RRXgoIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIFC1BRw+JjCq/1EQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBqixgg6MZGRlVeY7MDQEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEBCHGjh87Q0cCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQJUVyI6KZmV5PcG09AxJTk/LaZeSliZ6jIIAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAghURIHs4GgJthy96csv5dz3P7RzOpyWKgM/+FDG/TitIs6RMSGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAALiyLJZo95HR7PbZQtmFpN4eig5WQa+/758v3w55AgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggMAxETgSHPW8b1cc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QAABBBBAAAEEEEAAAQQQQAABBIJZwMwcDeYBMjYEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEBAC1hZUpc3AgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIhIIAe46Gwl1mjAgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggEDdzlD1HeScggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggECwC1htNluwj5HxIYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAnEzR51OJxQIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBAUAtYXS6XsKxuUN9jBocAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAkrAqhLBUd4KCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQ9AJWltQN+nvMABFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAQAmYZXWRQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBIJdwMp+o8F+ixkfAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAghoARMcZWld3gwIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIBDsAlY9QKvVPAX7WBkfAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgiEsICJirpcrhAmYOgIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIBAKAiY4yr6joXCrGSMCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACoS1gZ9ZoaL8BGD0CCCCAAAIIIJCYwMWL0RJ9KUZiHbFiYZGRxIg4hwACCCCAAAIIIIAAAggggAACCCBwjQIui4jdZpcs4WGSLVuWa6zNu+IER71zIhcCCCCAAAIIIBASAg6HU86euyBhdptE5M4hYWF2YZWRkLj1DBIBBBBAAAEEEEAAAQQQQAABBBDwu4CexBkTEyvnL0TJ6chzkitndrHZzMK3PuuLnQ+7fGZLxQgggAACCCCAQKYT0IHRHNmzqEe2TNd3OowAAggggAACCCCAAAIIIIAAAgggkLkEdJwyXM0a1Y/zFy6aL+1H5Mnp00FY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AQIECBAgUFYCk9/7R1m1R2MIECBAgAABAgQIECBAgAABAgQINBQQHG2oYZsAAQIECBAgUOECPVdfpcIFNJ8AAQIECBAgQIAAAQIECBAgQKA1BZq7836hrq6uNdvn2gQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEGgRgUKWWuRCLkKAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHWFMgjo8VisTXr4NoECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBBodoFCbW1tVFVVNfuFXIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQKtKVCorq5uzeu7NgECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFpEwIKjLcLsIgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQItLaA4Ghr3wHXJ0CAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgRQRqWuQqLkKAAAECBAgQIECgGQXGTX49xr77ajw56dW4etJL+ZWG9uofA3v1jcO33K0Zr6xoAgQIECBAgAABAgQIECBAgACBtiRQUywW21J91ZUAAQIECBAgQIBAI4GRf7k3ho25s9G+9CYFSdNfOnbZgL0FSRcRsoMAAQIECBAgQIAAAQIECBAgUHkCBcHRyrvpWkyAAAECBAgQKBeBJQVGF25fCpCmvBIBAgQIECBAgAABAgQIECBAgEBlCxSyVNkCWk+AAAECBAgQILDMAmec9/NIfy2ZljYwWqqTAGlJwisBAgQIECBAgAABAgQIECBAoHIFClVVVWH0aOV+ALScAAECBAgQIPB5CDw7/sVIfy0ZIF3cVLpNtSWdk9Ynbe708KhH47Irr23uyyifAAECBAgQIECAAAECBAgQIPCZBH570y2xxz4HxSFDhsWDDz1SX8Zjo8fk+9OxMU+Prd/fcOOaa38TO+y8dww75sR4480J+aEZM2bG+T8bke8/Ytjx8dSYvzQ8ZbnaLtTW1kYKkEoECBAgQIAAAQIEllWgpQKkSztFblprNP01TGPffbXh2yVuL0sHwtFPjIkHHvzTEstujgPLUt/mqI8yCRAgQIAAAQIECBAgQIAAgeVT4JVXX49bb787/veXP42jhh0eBx46LGbOnBXTp38ce+//zTjr9B/Eaad8LwYfNixmzZrV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EChngTwqWiwWy7mN2kaAAAECBAgQILAUAsWqCN8LlwJKFgIECBAgQIAAAQIECBAgQIAAgWYRSM+m0jOq5kx5cNS6o81JrGwCBAgQIECAQNsQqKmuiXnz5reNyqolAQIECBAgQIAAAQIECBAgQIBA2QmkZ1PpGVVzpoLRAc3Jq2wCBAgQIECAQNsR6NC+XcyYObvtVFhNCRAgQIAAAQIECBAgQIAAAQIEykogPZtKz6iaMwmONqeusgkQIECAAAECbUhghRU6xLz5tVmAdFYbqrWqEiBAgAABAgQIECBAgAABAgQIlINAeiaVnk2lZ1TNmWpMqducvMomQIAAAQIECLQtgS4rdorpH8+MuXPnR+dOHaNdu5rwfbFt3UO1JUCAAAECBAgQIECAAAECBAi0FYE0w22aSjeNGE2B0fRsqrmT4GhzCyufAAECBAgQINCGBKqrC9F15RVj1qw5MWXajJhfOz+qim2oAapKgAABAgQIECBAgAABAgQIECDQZgSKVZGvMZqm0u268gotUu+aurq6FrmQixAgQIAAAQIECLQdgTR9SXNPYdJ2NNSUAAECBAgQIECAAAECBAgQIECgXAQKWSqXtmgHAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEliiQR0bTfL4SAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEylmgUFtbG1VV2YS+EgECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBMpYoFBdXV3GzdM0AgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQILBCw4KhPAgECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECFSEgOFoRt1kjCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAQHPUZIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgIgQKxWKxIhqqkQQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVLaA4Ghl33+tJ0CAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFAxAoUsVUxjNZQAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgcoVKFRVVYWpdSv3A6DlBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBCpFoFBbWxspQCoRIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgnAXykaPl3EBtI0CAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAQBIomFLXB4EAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgUoQsOZoJdxlbSRAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAYMHIUWuO+iQQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDuAoXq6upyb6P2ESBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAYMHI0bq6OhQECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAoa4FCsVgM0+qW9T3WOAIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEMoFClgRHfRQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECh7gYIpdcv+HmsgAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQKZQD6tLgkCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAiUu0DBeqPlfou1jwABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBJJAHR02t68NAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC5CxRSAwuF/KXc26p9BAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAhUsEAeFS0WixVMoOkECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECFSCQB4cte5oJdxqbSRAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQ2QIFo0Yr+wOg9QQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQqRUBwtFLutHYSIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQqHCBgil1K/wToPkECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEKkRAcLRCbrRmEiBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEKh0gUJdXV2lG2g/AQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIVIFDIUgU0UxMJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEKh0gTwyWiwWK91B+wkQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQKHOBQm1tbVRVVZV5MzWPAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFKFyhUV1dXuoH2EyBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQAQIWHK2Am6yJBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAhECI76FBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUBECgqMVcZs1kgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBQrFYpECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIGyFxAcLftbrIEECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECCSBQpZIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoOwFClVVVWFq3bK/zxpIgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoOIFCrW1tZECpBIBAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTKWSAfOVrODdQ2AgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIJIGCKXV9EAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQqAQBa45Wwl3WRgIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEFowcteaoTwIBAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAuUuUKiuri73NmofAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEFowcraurQ0GAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIGyFvh/AvWHtoXgO0gAAAAASUVORK5CYII=" - } - }, - "cell_type": "markdown", - "id": "45d69561-52ef-430b-9401-e188c9d126d0", - "metadata": {}, - "source": [ - "![image.png](attachment:5b91a161-f657-45a8-b48d-ad595e00e7e6.png)" - ] - }, - { - "cell_type": "markdown", - "id": "83d8259b-1449-40c2-87f7-d34c81d11903", - "metadata": {}, - "source": [ - "After the run success, we will see feature tables are populated with values." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "da97a2f6-af82-4258-9ba5-9e1b3c13d70b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n", - "|\"TRANSACTION_ID\" |\"CUSTOMER_ID\" |\"TERMINAL_ID\" |\"TX_DATETIME\" |\"EVENT_TIMESTAMP\" |\"CT_DATETIME\" |\"TX_AMOUNT\" |\"TX_TIME_SECONDS\" |\"TX_TIME_DAYS\" |\"TX_FRAUD\" |\"TX_FRAUD_SCENARIO\" |\"TX_DURING_WEEKEND\" |\"TX_DURING_NIGHT\" |\n", - "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n", - "|1 |4961 |3412 |2019-04-01 00:02:10 |2019-04-01 00:02:10 |2024-07-19 14:28:36.956000-07:00 |81.51 |130 |0 |0 |0 |0 |1 |\n", - "|2 |2 |1365 |2019-04-01 00:07:56 |2019-04-01 00:07:56 |2024-07-19 14:28:36.956000-07:00 |146.0 |476 |0 |0 |0 |0 |1 |\n", - "|3 |4128 |8737 |2019-04-01 00:09:29 |2019-04-01 00:09:29 |2024-07-19 14:28:36.956000-07:00 |64.49 |569 |0 |0 |0 |0 |1 |\n", - "|4 |927 |9906 |2019-04-01 00:10:34 |2019-04-01 00:10:34 |2024-07-19 14:28:36.956000-07:00 |50.99 |634 |0 |0 |0 |0 |1 |\n", - "|5 |568 |8803 |2019-04-01 00:10:45 |2019-04-01 00:10:45 |2024-07-19 14:28:36.956000-07:00 |44.71 |645 |0 |0 |0 |0 |1 |\n", - "|6 |2803 |5490 |2019-04-01 00:11:30 |2019-04-01 00:11:30 |2024-07-19 14:28:36.956000-07:00 |96.03 |690 |0 |0 |0 |0 |1 |\n", - "|7 |4684 |2486 |2019-04-01 00:11:44 |2019-04-01 00:11:44 |2024-07-19 14:28:36.956000-07:00 |24.36 |704 |0 |0 |0 |0 |1 |\n", - "|8 |4128 |8354 |2019-04-01 00:11:53 |2019-04-01 00:11:53 |2024-07-19 14:28:36.956000-07:00 |26.34 |713 |0 |0 |0 |0 |1 |\n", - "|9 |541 |6212 |2019-04-01 00:13:44 |2019-04-01 00:13:44 |2024-07-19 14:28:36.956000-07:00 |59.07 |824 |0 |0 |0 |0 |1 |\n", - "|10 |4554 |2198 |2019-04-01 00:16:59 |2019-04-01 00:16:59 |2024-07-19 14:28:36.956000-07:00 |58.06 |1019 |0 |0 |0 |0 |1 |\n", - "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "# replace 'transactions' with 'customers' or 'terminals' to show \n", - "# respective table.\n", - "table_schema = f\"{FS_DEMO_DB}.FS_DBT_DEMO_{FS_DEMO_SCHEMA}\"\n", - "session.sql(f\"SELECT * FROM {table_schema}.transactions\").show()" - ] - }, - { - "cell_type": "markdown", - "id": "5c85ca3a-baf5-4fb1-a74a-d45a90182bb1", - "metadata": {}, - "source": [ - "## Register feature tables as Feature Views\n", - "\n", - "Now lets create Feature Views with Feature Store. Since DBT is responsible for executing the pipeline, the feature tables will be registered as external pipeline. Underlying, it creates views, instead of dynamic tables, from the feature tables.\n", - "\n", - "Replace below `default_warehouse` with your warehouse in your environment." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "1d04b1b8-dd0d-47a5-a980-3c3f34b276f8", - "metadata": {}, - "outputs": [], - "source": [ - "from snowflake.ml.feature_store import (\n", - " FeatureStore,\n", - " FeatureView,\n", - " Entity,\n", - " CreationMode\n", - ")\n", - "\n", - "fs = FeatureStore(\n", - " session=session, \n", - " database=FS_DEMO_DB, \n", - " name=FS_DEMO_SCHEMA, \n", - " default_warehouse='REGTEST_ML_4XL_MULTI',\n", - " creation_mode=CreationMode.CREATE_IF_NOT_EXIST,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "be6784b7-b96e-4c0a-9b8e-44a48b3d5951", - "metadata": {}, - "source": [ - "Register entities for features." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "806ad73d-b0fc-48ea-b63d-0f9669828486", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "----------------------------------------------------------\n", - "|\"NAME\" |\"JOIN_KEYS\" |\"DESC\" |\"OWNER\" |\n", - "----------------------------------------------------------\n", - "|CUSTOMER |[\"CUSTOMER_ID\"] | |REGTEST_RL |\n", - "|TERMINAL |[\"TERMINAL_ID\"] | |REGTEST_RL |\n", - "|TRANSACTION |[\"TRANSACTION_ID\"] | |REGTEST_RL |\n", - "----------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "customer = Entity(name=\"CUSTOMER\", join_keys=[\"CUSTOMER_ID\"])\n", - "terminal = Entity(name=\"TERMINAL\", join_keys=[\"TERMINAL_ID\"])\n", - "transaction = Entity(name=\"TRANSACTION\", join_keys=[\"TRANSACTION_ID\"])\n", - "fs.register_entity(customer)\n", - "fs.register_entity(terminal)\n", - "fs.register_entity(transaction)\n", - "fs.list_entities().show()" - ] - }, - { - "cell_type": "markdown", - "id": "96f49f77-25cf-4c0c-a1d0-a04808a222a2", - "metadata": {}, - "source": [ - "Define feature views. `feature_df` is a dataframe object that selects from a subset of columns of feature tables. `refresh_freq` is None indicates it is static and won't be refreshed. Underlying it will create views on the feature tables." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "399984e1-a89c-486f-9370-fef9a8921c99", - "metadata": {}, - "outputs": [], - "source": [ - "# terminal features\n", - "terminals_df = session.sql(f\"\"\"\n", - " SELECT \n", - " TERMINAL_ID,\n", - " EVENT_TIMESTAMP,\n", - " TERM_RISK_1,\n", - " TERM_RISK_7,\n", - " TERM_RISK_30\n", - " FROM {FS_DEMO_DB}.FS_DBT_DEMO_{FS_DEMO_SCHEMA}.terminals\n", - " \"\"\")\n", - "terminals_fv = FeatureView(\n", - " name=\"terminal_features\", \n", - " entities=[terminal],\n", - " feature_df=terminals_df,\n", - " timestamp_col=\"EVENT_TIMESTAMP\",\n", - " refresh_freq=None,\n", - " desc=\"A bunch of terminal related features\")\n", - "\n", - "# customer features\n", - "customers_df = session.sql(f\"\"\"\n", - " SELECT \n", - " CUSTOMER_ID,\n", - " EVENT_TIMESTAMP,\n", - " CUST_AVG_AMOUNT_1,\n", - " CUST_AVG_AMOUNT_7,\n", - " CUST_AVG_AMOUNT_30\n", - " FROM {FS_DEMO_DB}.FS_DBT_DEMO_{FS_DEMO_SCHEMA}.customers\n", - " \"\"\")\n", - "customers_fv = FeatureView(\n", - " name=\"customers_features\", \n", - " entities=[customer],\n", - " feature_df=customers_df,\n", - " timestamp_col=\"EVENT_TIMESTAMP\",\n", - " refresh_freq=None,\n", - " desc=\"A bunch of customer related features\")\n", - "\n", - "# transaction features\n", - "transactions_df = session.sql(f\"\"\"\n", - " SELECT \n", - " TRANSACTION_ID, \n", - " EVENT_TIMESTAMP, \n", - " TX_AMOUNT,\n", - " TX_FRAUD\n", - " FROM {FS_DEMO_DB}.FS_DBT_DEMO_{FS_DEMO_SCHEMA}.transactions\n", - " \"\"\")\n", - "transactions_fv = FeatureView(\n", - " name=\"transactions_features\", \n", - " entities=[transaction],\n", - " feature_df=transactions_df,\n", - " timestamp_col=\"EVENT_TIMESTAMP\",\n", - " refresh_freq=None,\n", - " desc=\"A bunch of transaction related features\")" - ] - }, - { - "cell_type": "markdown", - "id": "49df8d25-bba1-4fcf-9b80-df292d4d6cbf", - "metadata": {}, - "source": [ - "Register these feature views in feature store so you can retrieve them back later even after notebook session is destroyed. " - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "a7c18556-290b-418a-9dd8-b98b0e9acf8d", - "metadata": {}, - "outputs": [], - "source": [ - "terminals_fv = fs.register_feature_view(\n", - " feature_view=terminals_fv,\n", - " version=\"1\",\n", - " block=True)\n", - "\n", - "customers_fv = fs.register_feature_view(\n", - " feature_view=customers_fv,\n", - " version=\"1\",\n", - " block=True)\n", - "\n", - "transactions_fv = fs.register_feature_view(\n", - " feature_view=transactions_fv,\n", - " version=\"1\",\n", - " block=True)" - ] - }, - { - "cell_type": "markdown", - "id": "59befe8d-86a4-41f8-aeff-73d3756a2f48", - "metadata": {}, - "source": [ - "Lets check whether feature views are reigstered successfully in feature store. You will see 3 registerd feature views." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "bdab88b1-2b92-41ac-88d1-c91d25f3155e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
NAMEVERSIONDATABASE_NAMESCHEMA_NAMECREATED_ONOWNERDESCENTITIESREFRESH_FREQREFRESH_MODESCHEDULING_STATEWAREHOUSE
0CUSTOMERS_FEATURES1SNOWML_FEATURE_STORE_DBT_DEMOFS_DBT_DEMO2024-07-19 14:30:04.939REGTEST_RLA bunch of customer related features[\\n \"CUSTOMER\"\\n]NoneNoneNoneNone
1TERMINAL_FEATURES1SNOWML_FEATURE_STORE_DBT_DEMOFS_DBT_DEMO2024-07-19 14:30:00.791REGTEST_RLA bunch of terminal related features[\\n \"TERMINAL\"\\n]NoneNoneNoneNone
2TRANSACTIONS_FEATURES1SNOWML_FEATURE_STORE_DBT_DEMOFS_DBT_DEMO2024-07-19 14:30:08.696REGTEST_RLA bunch of transaction related features[\\n \"TRANSACTION\"\\n]NoneNoneNoneNone
\n", - "
" - ], - "text/plain": [ - " NAME VERSION DATABASE_NAME SCHEMA_NAME \\\n", - "0 CUSTOMERS_FEATURES 1 SNOWML_FEATURE_STORE_DBT_DEMO FS_DBT_DEMO \n", - "1 TERMINAL_FEATURES 1 SNOWML_FEATURE_STORE_DBT_DEMO FS_DBT_DEMO \n", - "2 TRANSACTIONS_FEATURES 1 SNOWML_FEATURE_STORE_DBT_DEMO FS_DBT_DEMO \n", - "\n", - " CREATED_ON OWNER \\\n", - "0 2024-07-19 14:30:04.939 REGTEST_RL \n", - "1 2024-07-19 14:30:00.791 REGTEST_RL \n", - "2 2024-07-19 14:30:08.696 REGTEST_RL \n", - "\n", - " DESC ENTITIES \\\n", - "0 A bunch of customer related features [\\n \"CUSTOMER\"\\n] \n", - "1 A bunch of terminal related features [\\n \"TERMINAL\"\\n] \n", - "2 A bunch of transaction related features [\\n \"TRANSACTION\"\\n] \n", - "\n", - " REFRESH_FREQ REFRESH_MODE SCHEDULING_STATE WAREHOUSE \n", - "0 None None None None \n", - "1 None None None None \n", - "2 None None None None " - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# display as pandas dataframe\n", - "fs.list_feature_views().to_pandas()" - ] - }, - { - "cell_type": "markdown", - "id": "0f96f221-274d-4a0e-8e46-72748e1f7a92", - "metadata": {}, - "source": [ - "## Generate training dataset with point-in-time correctness\n", - "We can now generate training dataset with feature views. Firstly, we create a mock spine dataframe which has 3 columns: instance_id, customer_id and event_timestamp. Note the event_timestamp of 3 rows are same: \"2019-09-01 00:00:00.000\". Later, we will update the source table (`CUSTOMER_TRANSACTIONS_FRAUD`) and feature tables with newer events. We will still use this `spine_df` with same timestamp to generate dataset but it is expected to output a different training data. The new training data will join spine_df with latest feature values from newer events. " - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "6d04c095-0702-4fe5-905d-fb8e576710a5", - "metadata": {}, - "outputs": [], - "source": [ - "spine_df = session.create_dataframe(\n", - " [\n", - " (1, 2443, \"2019-09-01 00:00:00.000\"), \n", - " (2, 1889, \"2019-09-01 00:00:00.000\"),\n", - " (3, 1309, \"2019-09-01 00:00:00.000\")\n", - " ], \n", - " schema=[\"INSTANCE_ID\", \"CUSTOMER_ID\", \"EVENT_TIMESTAMP\"])\n", - "\n", - "my_dataset = fs.generate_dataset(\n", - " name=\"my_training_dataset_from_dbt\",\n", - " version=\"1_0\",\n", - " spine_df=spine_df,\n", - " features=[customers_fv],\n", - " spine_timestamp_col=\"EVENT_TIMESTAMP\",\n", - " spine_label_cols = []\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "7428960d-9e59-46e6-addd-bcc585f3f8bf", - "metadata": {}, - "source": [ - "We can convert dataset to snowpark dataframe and examine feature values." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "bbadca7a-b1f8-4bd2-b907-153a3fb576a7", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "------------------------------------------------------------------------------------------------------------------------------\n", - "|\"INSTANCE_ID\" |\"CUSTOMER_ID\" |\"EVENT_TIMESTAMP\" |\"CUST_AVG_AMOUNT_1\" |\"CUST_AVG_AMOUNT_7\" |\"CUST_AVG_AMOUNT_30\" |\n", - "------------------------------------------------------------------------------------------------------------------------------\n", - "|2 |1889 |2019-09-01 00:00:00.000 |112.26750183105469 |102.57643127441406 |101.19486236572266 |\n", - "|1 |2443 |2019-09-01 00:00:00.000 |61.54777908325195 |88.3499984741211 |96.53591918945312 |\n", - "|3 |1309 |2019-09-01 00:00:00.000 |38.52000045776367 |81.85333251953125 |93.1205062866211 |\n", - "------------------------------------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "training_data_df = my_dataset.read.to_snowpark_dataframe()\n", - "training_data_df.show()" - ] - }, - { - "cell_type": "markdown", - "id": "b0a7eab2-493b-44a4-ae5c-08bd25daa93a", - "metadata": {}, - "source": [ - "## Update features from DBT\n", - "Now we are injecting newer events into source, then refresh the pipeline and generate new feature values. We firstly check how many rows the source table currently has." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "f62a45b2-b966-4230-959f-206e54202599", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "872794" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.table(fraud_data_path).count()" - ] - }, - { - "cell_type": "markdown", - "id": "5256584e-4048-4d1c-930d-7cb312b36e4d", - "metadata": {}, - "source": [ - "We inject new events with timestamp later than '2019-07-01'. Then check how many rows in the source table after the injection." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "5494dd0a-dce3-40c2-8810-6aa1a8d7f31b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1466281" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.sql(f\"\"\"\n", - " INSERT INTO {fraud_data_path}\n", - " SELECT *\n", - " FROM {source_table}\n", - " WHERE TX_DATETIME >= '2019-07-01'\n", - "\"\"\").collect()\n", - "session.table(fraud_data_path).count()" - ] - }, - { - "cell_type": "markdown", - "id": "3df454f3-590f-4547-8051-5eb053b18d2b", - "metadata": {}, - "source": [ - "Then, we go back to DBT IDE and run the pipelines again." - ] - }, - { - "cell_type": "markdown", - "id": "810025ca-7d9d-4e99-b9af-1643d0647c29", - "metadata": {}, - "source": [ - "## Generate new training dataset\n", - "We don't need to update feature views because the underlying tables are updated by DBT. We only need to generate dataset again with same timestamp and it will join with newer feature values." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "69299109-9cd9-433d-b38c-c980af589765", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "------------------------------------------------------------------------------------------------------------------------------\n", - "|\"INSTANCE_ID\" |\"CUSTOMER_ID\" |\"EVENT_TIMESTAMP\" |\"CUST_AVG_AMOUNT_1\" |\"CUST_AVG_AMOUNT_7\" |\"CUST_AVG_AMOUNT_30\" |\n", - "------------------------------------------------------------------------------------------------------------------------------\n", - "|3 |1309 |2019-09-01 00:00:00.000 |38.52000045776367 |81.85333251953125 |93.1205062866211 |\n", - "|2 |1889 |2019-09-01 00:00:00.000 |112.26750183105469 |102.57643127441406 |101.19486236572266 |\n", - "|1 |2443 |2019-09-01 00:00:00.000 |61.54777908325195 |88.3499984741211 |96.53591918945312 |\n", - "------------------------------------------------------------------------------------------------------------------------------\n", - "\n" - ] - } - ], - "source": [ - "new_dataset = fs.generate_dataset(\n", - " name=\"my_training_dataset_from_dbt\",\n", - " version=\"2_0\",\n", - " spine_df=spine_df,\n", - " features=[customers_fv],\n", - " spine_timestamp_col=\"EVENT_TIMESTAMP\",\n", - " spine_label_cols = [],\n", - ")\n", - "\n", - "new_training_data_df = new_dataset.read.to_snowpark_dataframe()\n", - "new_training_data_df.show()" - ] - }, - { - "cell_type": "markdown", - "id": "57aee19d-b0b5-4d9c-bfc7-4714a57aab2d", - "metadata": {}, - "source": [ - "## Cleanup notebook" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "c942f02a-10ad-4cae-b15f-69b530193ae7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Row(status='SNOWML_FEATURE_STORE_DBT_DEMO successfully dropped.')]" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.sql(f\"DROP DATABASE IF EXISTS {FS_DEMO_DB}\").collect()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.19" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/snowflake/ml/feature_store/examples/README.md b/snowflake/ml/feature_store/examples/README.md index 10d42cc8..e3130a42 100644 --- a/snowflake/ml/feature_store/examples/README.md +++ b/snowflake/ml/feature_store/examples/README.md @@ -1,7 +1,38 @@ # Feature Store examples -This folder contains some feature examples and the required source data. -All the source data are publicly available. You can easily get everything with `ExampleHelper`. +## Example notebooks + +You can find end-to-end demo notebooks from [Snowflake-Labs](https://github.com/Snowflake-Labs/snowflake-demo-notebooks). +Specifically these 4 notebooks use Feature Store: + +- Feature Store Quickstart +- Feature Store API Overview +- End-to-end ML with Feature Store and Model Registry +- Manage features in DBT with Feature Store + +## Example features + +We have prepared some example features with publicly available datasets. The feature views, entities and datasets can +be easily loade by `ExampleHelper` (see below section). And some of notebooks, like *End-to-end ML with Feature Store +and Model Registry*, use these features as well. + + +| Name | Data sources | Feature views | +| ------------------------ | ------------------------------------------------------------ | ---------------------------- | +| citibike_trip_features | | trip_features | +| | | location_features | +| new_york_taxi_features | | station_feature | +| | | trip_feature | +| wine_quality_features | | managed_wine_features | +| | | static_wine_features | +| airline_features | | plane_features | +| | | weather_features | + + +## ExampleHelper + +`ExampleHelper` is a helper class to load public datasets into Snowflake, load pre-defined feature views and entities. +It is available in `snowflake-ml-python` since 1.5.5. ```python from snowflake.ml.feature_store.examples.example_helper import ExampleHelper @@ -20,18 +51,3 @@ example_helper.load_entities() # load draft feature views for the selected example. example_helper.load_draft_feature_views() ``` - -## Examples - -Below table briefly describes all available examples. You can find all examples in this directory. - - -| Name | Data sources | Feature views | -| ------------------------ | ------------------------------------------------------------ | ---------------------------- | -| citibike_trip_features | | dropoff_features | -| | | pickup_features | -| new_york_taxi_features | | station_feature | -| | | trip_feature | -| wine_quality_features | | managed_wine_features | -| | | static_wine_features | - diff --git a/snowflake/ml/feature_store/examples/airline_features/entities.py b/snowflake/ml/feature_store/examples/airline_features/entities.py new file mode 100644 index 00000000..453e7782 --- /dev/null +++ b/snowflake/ml/feature_store/examples/airline_features/entities.py @@ -0,0 +1,16 @@ +from typing import List + +from snowflake.ml.feature_store import Entity + +zipcode_entity = Entity( + name="AIRPORT_ZIP_CODE", + join_keys=["AIRPORT_ZIP_CODE"], + desc="Zip code of the airport.", +) + +plane_entity = Entity(name="PLANE_MODEL", join_keys=["PLANE_MODEL"], desc="The model of an airplane.") + + +# This will be invoked by example_helper.py. Do not change function name. +def get_all_entities() -> List[Entity]: + return [zipcode_entity, plane_entity] diff --git a/snowflake/ml/feature_store/examples/airline_features/features/plane_features.py b/snowflake/ml/feature_store/examples/airline_features/features/plane_features.py new file mode 100644 index 00000000..8800abdd --- /dev/null +++ b/snowflake/ml/feature_store/examples/airline_features/features/plane_features.py @@ -0,0 +1,31 @@ +from typing import List + +from snowflake.ml.feature_store import FeatureView +from snowflake.ml.feature_store.examples.airline_features.entities import plane_entity +from snowflake.snowpark import DataFrame, Session + + +# This function will be invoked by example_helper.py. Do not change the name. +def create_draft_feature_view(session: Session, source_dfs: List[DataFrame], source_tables: List[str]) -> FeatureView: + """Create a feature view about airplane model.""" + query = session.sql( + """ + select + PLANE_MODEL, + SEATING_CAPACITY + from + PLANE_MODEL_ATTRIBUTES + """ + ) + + return FeatureView( + name="f_plane", # name of feature view + entities=[plane_entity], # entities + feature_df=query, # definition query + refresh_freq=None, # refresh frequency + desc="Plane features never refresh.", + ).attach_feature_desc( + { + "SEATING_CAPACITY": "The seating capacity of a plane.", + } + ) diff --git a/snowflake/ml/feature_store/examples/airline_features/features/weather_features.py b/snowflake/ml/feature_store/examples/airline_features/features/weather_features.py new file mode 100644 index 00000000..3838436e --- /dev/null +++ b/snowflake/ml/feature_store/examples/airline_features/features/weather_features.py @@ -0,0 +1,42 @@ +from typing import List + +from snowflake.ml.feature_store import FeatureView +from snowflake.ml.feature_store.examples.airline_features.entities import zipcode_entity +from snowflake.snowpark import DataFrame, Session + + +# This function will be invoked by example_helper.py. Do not change the name. +def create_draft_feature_view(session: Session, source_dfs: List[DataFrame], source_tables: List[str]) -> FeatureView: + """Create a feature view about airport weather.""" + query = session.sql( + """ + select + DATETIME_UTC AS TS, + AIRPORT_ZIP_CODE, + sum(RAIN_MM_H) over ( + partition by AIRPORT_ZIP_CODE + order by DATETIME_UTC + range between interval '30 minutes' preceding and current row + ) RAIN_SUM_30M, + sum(RAIN_MM_H) over ( + partition by AIRPORT_ZIP_CODE + order by DATETIME_UTC + range between interval '1 day' preceding and current row + ) RAIN_SUM_60M + from AIRPORT_WEATHER_STATION + """ + ) + + return FeatureView( + name="f_weather", # name of feature view + entities=[zipcode_entity], # entities + feature_df=query, # definition query + timestamp_col="TS", # timestamp column + refresh_freq="1d", # refresh frequency + desc="Airport weather features refreshed every day.", + ).attach_feature_desc( + { + "RAIN_SUM_30M": "The sum of rain fall over past 30 minutes for one zipcode.", + "RAIN_SUM_60M": "The sum of rain fall over past 1 day for one zipcode.", + } + ) diff --git a/snowflake/ml/feature_store/examples/airline_features/source.yaml b/snowflake/ml/feature_store/examples/airline_features/source.yaml new file mode 100644 index 00000000..c9012fb1 --- /dev/null +++ b/snowflake/ml/feature_store/examples/airline_features/source.yaml @@ -0,0 +1,7 @@ +--- +source_data: airline +label_columns: DEPARTING_DELAY +timestamp_column: SCHEDULED_DEPARTURE_UTC +desc: Features using synthetic airline data to predict the departing delay. +model_category: classification +training_spine_table: US_FLIGHT_SCHEDULES diff --git a/snowflake/ml/feature_store/examples/citibike_trip_features/features/station_feature.py b/snowflake/ml/feature_store/examples/citibike_trip_features/features/station_feature.py index a45eee7d..c37ca68b 100644 --- a/snowflake/ml/feature_store/examples/citibike_trip_features/features/station_feature.py +++ b/snowflake/ml/feature_store/examples/citibike_trip_features/features/station_feature.py @@ -14,18 +14,24 @@ def create_draft_feature_view(session: Session, source_dfs: List[DataFrame], sou f""" select end_station_id, - count(end_station_id) as f_count_1d, - avg(end_station_latitude) as f_avg_latitude_1d, - avg(end_station_longitude) as f_avg_longtitude_1d + count(end_station_id) as f_count, + avg(end_station_latitude) as f_avg_latitude, + avg(end_station_longitude) as f_avg_longtitude from {source_tables[0]} group by end_station_id """ ) return FeatureView( - name="f_station_1d", # name of feature view + name="f_station", # name of feature view entities=[end_station_id], # entities feature_df=query, # definition query refresh_freq="1d", # refresh frequency. '1d' means it refreshes everyday desc="Station features refreshed every day.", + ).attach_feature_desc( + { + "f_count": "How many times this station appears in 1 day.", + "f_avg_latitude": "Averaged latitude of a station.", + "f_avg_longtitude": "Averaged longtitude of a station.", + } ) diff --git a/snowflake/ml/feature_store/examples/citibike_trip_features/features/trip_feature.py b/snowflake/ml/feature_store/examples/citibike_trip_features/features/trip_feature.py index c7a4f52d..6d7987ef 100644 --- a/snowflake/ml/feature_store/examples/citibike_trip_features/features/trip_feature.py +++ b/snowflake/ml/feature_store/examples/citibike_trip_features/features/trip_feature.py @@ -21,4 +21,10 @@ def create_draft_feature_view(session: Session, source_dfs: List[DataFrame], sou feature_df=feature_df, # definition query refresh_freq=None, # refresh frequency. None indicates it never refresh desc="Static trip features", + ).attach_feature_desc( + { + "f_birth_year": "The birth year of a trip passenger.", + "f_gender": "The gender of a trip passenger.", + "f_bikeid": "The bike id of a trip passenger.", + } ) diff --git a/snowflake/ml/feature_store/examples/citibike_trip_features/source.yaml b/snowflake/ml/feature_store/examples/citibike_trip_features/source.yaml index 43c1caf2..8ec59713 100644 --- a/snowflake/ml/feature_store/examples/citibike_trip_features/source.yaml +++ b/snowflake/ml/feature_store/examples/citibike_trip_features/source.yaml @@ -1,4 +1,7 @@ --- source_data: citibike_trips +training_spine_table: citibike_trips label_columns: tripduration add_id_column: trip_id +desc: Features using citibike trip data trying to predict the duration of a trip. +model_category: regression diff --git a/snowflake/ml/feature_store/examples/example_helper.py b/snowflake/ml/feature_store/examples/example_helper.py index f2f7e3ad..34419f40 100644 --- a/snowflake/ml/feature_store/examples/example_helper.py +++ b/snowflake/ml/feature_store/examples/example_helper.py @@ -10,7 +10,7 @@ from snowflake.ml._internal.utils import identifier, sql_identifier from snowflake.ml.feature_store import Entity, FeatureView # type: ignore[attr-defined] from snowflake.snowpark import DataFrame, Session, functions as F -from snowflake.snowpark.types import TimestampType +from snowflake.snowpark.types import TimestampTimeZone, TimestampType logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) @@ -28,6 +28,9 @@ def __init__(self, session: Session, database_name: str, dataset_schema: str) -> self._session = session self._database_name = database_name self._dataset_schema = dataset_schema + self._clear() + + def _clear(self) -> None: self._selected_example = None self._source_tables: List[str] = [] self._source_dfs: List[DataFrame] = [] @@ -36,15 +39,18 @@ def __init__(self, session: Session, database_name: str, dataset_schema: str) -> self._timestamp_column: Optional[sql_identifier.SqlIdentifier] = None self._epoch_to_timestamp_cols: List[str] = [] self._add_id_column: Optional[sql_identifier.SqlIdentifier] = None + self._training_spine_table: str = "" - def list_examples(self) -> List[str]: - """Return a list of examples.""" + def list_examples(self) -> Optional[DataFrame]: + """Return a dataframe object about descriptions of all examples.""" root_dir = Path(__file__).parent - result = [] + rows = [] for f_name in os.listdir(root_dir): if os.path.isdir(os.path.join(root_dir, f_name)) and f_name[0].isalpha() and f_name != "source_data": - result.append(f_name) - return result + source_file_path = root_dir.joinpath(f"{f_name}/source.yaml") + source_dict = self._read_yaml(str(source_file_path)) + rows.append((f_name, source_dict["model_category"], source_dict["desc"], source_dict["label_columns"])) + return self._session.create_dataframe(rows, schema=["NAME", "MODEL_CATEGORY", "DESC", "LABEL_COLS"]) def load_draft_feature_views(self) -> List[FeatureView]: """Return all feature views in an example. @@ -101,7 +107,7 @@ def _create_file_format(self, format_dict: Dict[str, str], format_name: str) -> """ ).collect() - def _load_csv(self, schema_dict: Dict[str, str], destination_table: str, temp_stage_name: str) -> None: + def _load_csv(self, schema_dict: Dict[str, str], temp_stage_name: str) -> List[str]: # create temp file format file_format_name = f"{self._database_name}.{self._dataset_schema}.feature_store_temp_format" format_str = "" @@ -116,6 +122,8 @@ def _load_csv(self, schema_dict: Dict[str, str], destination_table: str, temp_st cols_type_str = ( f"{self._add_id_column.resolved()} number autoincrement start 1 increment 1, " + cols_type_str ) + + destination_table = f"{self._database_name}.{self._dataset_schema}.{schema_dict['destination_table_name']}" self._session.sql( f""" create or replace table {destination_table} ({cols_type_str}) @@ -132,25 +140,50 @@ def _load_csv(self, schema_dict: Dict[str, str], destination_table: str, temp_st """ ).collect() - def _load_parquet(self, schema_dict: Dict[str, str], destination_table: str, temp_stage_name: str) -> None: + return [destination_table] + + def _load_parquet(self, schema_dict: Dict[str, str], temp_stage_name: str) -> List[str]: regex_pattern = schema_dict["load_files_pattern"] all_files = self._session.sql(f"list @{temp_stage_name}").collect() filtered_files = [item["name"] for item in all_files if re.match(regex_pattern, item["name"])] - assert len(filtered_files) == 1, "Current code only works for one file" - file_name = filtered_files[0].rsplit("/", 1)[-1] + file_count = len(filtered_files) + result = [] + + for file in filtered_files: + file_name = file.rsplit("/", 1)[-1] - df = self._session.read.parquet(f"@{temp_stage_name}/{file_name}") - for old_col_name in df.columns: - df = df.with_column_renamed(old_col_name, identifier.get_unescaped_names(old_col_name)) + df = self._session.read.parquet(f"@{temp_stage_name}/{file_name}") + for old_col_name in df.columns: + df = df.with_column_renamed(old_col_name, identifier.get_unescaped_names(old_col_name)) - for ts_col in self._epoch_to_timestamp_cols: - if "timestamp" != dict(df.dtypes)[ts_col]: - df = df.with_column(f"{ts_col}_NEW", F.cast(df[ts_col] / 1000000, TimestampType())) - df = df.drop(ts_col).rename(f"{ts_col}_NEW", ts_col) + # convert timestamp column to ntz + for name, type in dict(df.dtypes).items(): + if type == "timestamp": + df = df.with_column(name, F.to_timestamp_ntz(name)) - df.write.mode("overwrite").save_as_table(destination_table) + # convert epoch column to ntz timestamp + for ts_col in self._epoch_to_timestamp_cols: + if "timestamp" != dict(df.dtypes)[ts_col]: + df = df.with_column(ts_col, F.cast(df[ts_col] / 1000000, TimestampType(TimestampTimeZone.NTZ))) - def _load_source_data(self, schema_yaml_file: str) -> str: + if self._add_id_column: + df = df.withColumn(self._add_id_column, F.monotonically_increasing_id()) + + if file_count == 1: + dest_table_name = ( + f"{self._database_name}.{self._dataset_schema}.{schema_dict['destination_table_name']}" + ) + else: + regex_pattern = schema_dict["destination_table_name"] + dest_table_name = re.match(regex_pattern, file_name).group("table_name") # type: ignore[union-attr] + dest_table_name = f"{self._database_name}.{self._dataset_schema}.{dest_table_name}" + + df.write.mode("overwrite").save_as_table(dest_table_name) + result.append(dest_table_name) + + return result + + def _load_source_data(self, schema_yaml_file: str) -> List[str]: """Parse a yaml schema file and load data into Snowflake. Args: @@ -162,7 +195,6 @@ def _load_source_data(self, schema_yaml_file: str) -> str: # load schema file schema_dict = self._read_yaml(schema_yaml_file) temp_stage_name = f"{self._database_name}.{self._dataset_schema}.feature_store_temp_stage" - destination_table = f"{self._database_name}.{self._dataset_schema}.{schema_dict['destination_table_name']}" # create a temp stage from S3 URL self._session.sql(f"create or replace stage {temp_stage_name} url = '{schema_dict['s3_url']}'").collect() @@ -170,11 +202,9 @@ def _load_source_data(self, schema_yaml_file: str) -> str: # load csv or parquet # TODO: this could be more flexible and robust. if "parquet" in schema_dict["load_files_pattern"]: - self._load_parquet(schema_dict, destination_table, temp_stage_name) + return self._load_parquet(schema_dict, temp_stage_name) else: - self._load_csv(schema_dict, destination_table, temp_stage_name) - - return destination_table + return self._load_csv(schema_dict, temp_stage_name) def load_example(self, example_name: str) -> List[str]: """Select the active example and load its datasets to Snowflake. @@ -186,6 +216,7 @@ def load_example(self, example_name: str) -> List[str]: Returns: Returns a list of table names with populated datasets. """ + self._clear() self._selected_example = example_name # type: ignore[assignment] # load source yaml file @@ -195,7 +226,7 @@ def load_example(self, example_name: str) -> List[str]: self._source_tables = [] self._source_dfs = [] - source_ymal_data = source_dict["source_data"] + source_yaml_data = source_dict["source_data"] if "excluded_columns" in source_dict: self._excluded_columns = sql_identifier.to_sql_identifiers(source_dict["excluded_columns"].split(",")) if "label_columns" in source_dict: @@ -206,8 +237,11 @@ def load_example(self, example_name: str) -> List[str]: self._epoch_to_timestamp_cols = source_dict["epoch_to_timestamp_cols"].split(",") if "add_id_column" in source_dict: self._add_id_column = sql_identifier.SqlIdentifier(source_dict["add_id_column"]) + self._training_spine_table = ( + f"{self._database_name}.{self._dataset_schema}.{source_dict['training_spine_table']}" + ) - return self.load_source_data(source_ymal_data) + return self.load_source_data(source_yaml_data) def load_source_data(self, source_data_name: str) -> List[str]: """Load source data into Snowflake. @@ -220,11 +254,12 @@ def load_source_data(self, source_data_name: str) -> List[str]: """ root_dir = Path(__file__).parent schema_file = root_dir.joinpath(f"source_data/{source_data_name}.yaml") - destination_table = self._load_source_data(str(schema_file)) - source_df = self._session.table(destination_table) - self._source_tables.append(destination_table) - self._source_dfs.append(source_df) - logger.info(f"source data {source_data_name} has been successfully loaded into table {destination_table}.") + destination_tables = self._load_source_data(str(schema_file)) + for dest_table in destination_tables: + source_df = self._session.table(dest_table) + self._source_tables.append(dest_table) + self._source_dfs.append(source_df) + logger.info(f"{dest_table} has been created successfully.") return self._source_tables def get_current_schema(self) -> str: @@ -238,3 +273,6 @@ def get_excluded_cols(self) -> List[str]: def get_training_data_timestamp_col(self) -> Optional[str]: return self._timestamp_column.resolved() if self._timestamp_column is not None else None + + def get_training_spine_table(self) -> str: + return self._training_spine_table diff --git a/snowflake/ml/feature_store/examples/new_york_taxi_features/entities.py b/snowflake/ml/feature_store/examples/new_york_taxi_features/entities.py index e58aeaf2..075c1d6f 100644 --- a/snowflake/ml/feature_store/examples/new_york_taxi_features/entities.py +++ b/snowflake/ml/feature_store/examples/new_york_taxi_features/entities.py @@ -2,11 +2,11 @@ from snowflake.ml.feature_store import Entity -trip_pickup = Entity(name="TRIP_PICKUP", join_keys=["PULOCATIONID"], desc="Trip pickup entity.") +trip_id = Entity(name="TRIP_ID", join_keys=["TRIP_ID"], desc="Trip id.") -trip_dropoff = Entity(name="TRIP_DROPOFF", join_keys=["DOLOCATIONID"], desc="Trip dropoff entity.") +location_id = Entity(name="DOLOCATIONID", join_keys=["DOLOCATIONID"], desc="Drop off location id.") # This will be invoked by example_helper.py. Do not change function name. def get_all_entities() -> List[Entity]: - return [trip_pickup, trip_dropoff] + return [trip_id, location_id] diff --git a/snowflake/ml/feature_store/examples/new_york_taxi_features/features/dropoff_features.py b/snowflake/ml/feature_store/examples/new_york_taxi_features/features/location_features.py similarity index 64% rename from snowflake/ml/feature_store/examples/new_york_taxi_features/features/dropoff_features.py rename to snowflake/ml/feature_store/examples/new_york_taxi_features/features/location_features.py index fe992de3..63e7d81d 100644 --- a/snowflake/ml/feature_store/examples/new_york_taxi_features/features/dropoff_features.py +++ b/snowflake/ml/feature_store/examples/new_york_taxi_features/features/location_features.py @@ -2,7 +2,7 @@ from snowflake.ml.feature_store import FeatureView from snowflake.ml.feature_store.examples.new_york_taxi_features.entities import ( - trip_dropoff, + location_id, ) from snowflake.snowpark import DataFrame, Session @@ -15,25 +15,30 @@ def create_draft_feature_view(session: Session, source_dfs: List[DataFrame], sou select TPEP_DROPOFF_DATETIME as TS, DOLOCATIONID, - count(FARE_AMOUNT) over ( + avg(FARE_AMOUNT) over ( partition by DOLOCATIONID order by TPEP_DROPOFF_DATETIME range between interval '1 hours' preceding and current row - ) TRIP_COUNT_1H, - count(FARE_AMOUNT) over ( + ) AVG_FARE_1H, + avg(FARE_AMOUNT) over ( partition by DOLOCATIONID order by TPEP_DROPOFF_DATETIME - range between interval '5 hours' preceding and current row - ) TRIP_COUNT_5H + range between interval '10 hours' preceding and current row + ) AVG_FARE_10h from {source_tables[0]} """ ) return FeatureView( - name="f_trip_dropoff", # name of feature view - entities=[trip_dropoff], # entities + name="f_location", # name of feature view + entities=[location_id], # entities feature_df=feature_df, # definition query refresh_freq="12h", # the frequency this feature view re-compute timestamp_col="TS", # timestamp column. Used when generate training data - desc="Managed feature view trip dropoff refreshed every 12 hours.", + desc="Features aggregated by location id and refreshed every 12 hours.", + ).attach_feature_desc( + { + "AVG_FARE_1H": "Averaged fare in past 1 hour window aggregated by location.", + "AVG_FARE_10H": "Averaged fare in past 10 hours aggregated by location.", + } ) diff --git a/snowflake/ml/feature_store/examples/new_york_taxi_features/features/pickup_features.py b/snowflake/ml/feature_store/examples/new_york_taxi_features/features/pickup_features.py deleted file mode 100644 index 81bfd5ad..00000000 --- a/snowflake/ml/feature_store/examples/new_york_taxi_features/features/pickup_features.py +++ /dev/null @@ -1,58 +0,0 @@ -from typing import List - -from snowflake.ml.feature_store import FeatureView -from snowflake.ml.feature_store.examples.new_york_taxi_features.entities import ( - trip_pickup, -) -from snowflake.snowpark import DataFrame, Session - - -# This function will be invoked by example_helper.py. Do not change the name. -def create_draft_feature_view(session: Session, source_dfs: List[DataFrame], source_tables: List[str]) -> FeatureView: - """Create a draft feature view.""" - feature_df = session.sql( - f""" - with - cte_1 (TS, PULOCATIONID, TRIP_COUNT_2H, TRIP_COUNT_5H, TRIP_FARE_SUM_2H, TRIP_FARE_SUM_5H) as ( - select - TPEP_PICKUP_DATETIME as TS, - PULOCATIONID, - count(FARE_AMOUNT) over ( - partition by PULOCATIONID - order by TPEP_PICKUP_DATETIME - range between interval '2 hours' preceding and current row - ) TRIP_COUNT_2H, - count(FARE_AMOUNT) over ( - partition by PULOCATIONID - order by TPEP_PICKUP_DATETIME - range between interval '5 hours' preceding and current row - ) TRIP_COUNT_5H, - sum(FARE_AMOUNT) over ( - partition by PULOCATIONID - order by TPEP_PICKUP_DATETIME - range between interval '2 hours' preceding and current row - ) TRIP_FARE_SUM_2H, - count(FARE_AMOUNT) over ( - partition by PULOCATIONID - order by TPEP_PICKUP_DATETIME - range between interval '5 hours' preceding and current row - ) TRIP_FARE_SUM_5H - from {source_tables[0]} - ) - select - TS, - PULOCATIONID, - TRIP_FARE_SUM_2H / TRIP_COUNT_2H as MEAN_FARE_2H, - TRIP_FARE_SUM_5H / TRIP_COUNT_5H as MEAN_FARE_5H, - from cte_1 - """ - ) - - return FeatureView( - name="f_trip_pickup", # name of feature view - entities=[trip_pickup], # entities - feature_df=feature_df, # definition query - refresh_freq="1d", # the frequency this feature view re-compute - timestamp_col="TS", # timestamp column. Used when generate training data - desc="Managed feature view trip pickup refreshed everyday.", - ) diff --git a/snowflake/ml/feature_store/examples/new_york_taxi_features/features/trip_features.py b/snowflake/ml/feature_store/examples/new_york_taxi_features/features/trip_features.py new file mode 100644 index 00000000..d13204b2 --- /dev/null +++ b/snowflake/ml/feature_store/examples/new_york_taxi_features/features/trip_features.py @@ -0,0 +1,36 @@ +from typing import List + +from snowflake.ml.feature_store import FeatureView +from snowflake.ml.feature_store.examples.new_york_taxi_features.entities import trip_id +from snowflake.snowpark import DataFrame, Session + + +# This function will be invoked by example_helper.py. Do not change the name. +def create_draft_feature_view(session: Session, source_dfs: List[DataFrame], source_tables: List[str]) -> FeatureView: + """Create a draft feature view.""" + feature_df = session.sql( + f""" + select + TRIP_ID, + PASSENGER_COUNT, + TRIP_DISTANCE, + FARE_AMOUNT + from + {source_tables[0]} + """ + ) + + return FeatureView( + name="f_trip", # name of feature view + entities=[trip_id], # entities + feature_df=feature_df, # definition query + refresh_freq="1d", # the frequency this feature view re-compute + timestamp_col=None, # timestamp column. Used when generate training data + desc="Features per trip refreshed every day.", + ).attach_feature_desc( + { + "PASSENGER_COUNT": "The count of passenger of a trip.", + "TRIP_DISTANCE": "The distance of a trip.", + "FARE_AMOUNT": "The fare of a trip.", + } + ) diff --git a/snowflake/ml/feature_store/examples/new_york_taxi_features/source.yaml b/snowflake/ml/feature_store/examples/new_york_taxi_features/source.yaml index b71901d9..f08e64a3 100644 --- a/snowflake/ml/feature_store/examples/new_york_taxi_features/source.yaml +++ b/snowflake/ml/feature_store/examples/new_york_taxi_features/source.yaml @@ -1,5 +1,9 @@ --- source_data: nyc_yellow_trips -label_columns: FARE_AMOUNT +training_spine_table: nyc_yellow_trips +label_columns: TOTAL_AMOUNT +add_id_column: TRIP_ID timestamp_column: TPEP_PICKUP_DATETIME epoch_to_timestamp_cols: TPEP_PICKUP_DATETIME,TPEP_DROPOFF_DATETIME +desc: Features using taxi trip data trying to predict the total fare of a trip. +model_category: regression diff --git a/snowflake/ml/feature_store/examples/source_data/airline.yaml b/snowflake/ml/feature_store/examples/source_data/airline.yaml new file mode 100644 index 00000000..9902b9ba --- /dev/null +++ b/snowflake/ml/feature_store/examples/source_data/airline.yaml @@ -0,0 +1,4 @@ +--- +s3_url: s3://sfquickstarts/misc/demos/airline/ +load_files_pattern: .*[.]parquet +destination_table_name: (?P.*)_0_0_0[.]snappy[.]parquet diff --git a/snowflake/ml/feature_store/examples/source_data/citibike_trips.yaml b/snowflake/ml/feature_store/examples/source_data/citibike_trips.yaml index 720d5f7d..b2ed1195 100644 --- a/snowflake/ml/feature_store/examples/source_data/citibike_trips.yaml +++ b/snowflake/ml/feature_store/examples/source_data/citibike_trips.yaml @@ -1,7 +1,7 @@ --- s3_url: s3://snowflake-workshop-lab/citibike-trips-csv/ destination_table_name: citibike_trips -load_files_pattern: trips_2013_6_4_0.csv.gz +load_files_pattern: .*trips_2013_6_.*[.]csv[.]gz format: type: csv compression: auto diff --git a/snowflake/ml/feature_store/examples/wine_quality_features/entities.py b/snowflake/ml/feature_store/examples/wine_quality_features/entities.py index a6f1252e..9a810cba 100644 --- a/snowflake/ml/feature_store/examples/wine_quality_features/entities.py +++ b/snowflake/ml/feature_store/examples/wine_quality_features/entities.py @@ -2,13 +2,13 @@ from snowflake.ml.feature_store import Entity -wine_entity = Entity( +wine_id = Entity( name="WINE", join_keys=["WINE_ID"], - desc="Wine ID column.", + desc="Wine ID.", ) # This will be invoked by example_helper.py. Do not change function name. def get_all_entities() -> List[Entity]: - return [wine_entity] + return [wine_id] diff --git a/snowflake/ml/feature_store/examples/wine_quality_features/features/managed_wine_features.py b/snowflake/ml/feature_store/examples/wine_quality_features/features/managed_wine_features.py index 44a145ed..42e9cad5 100644 --- a/snowflake/ml/feature_store/examples/wine_quality_features/features/managed_wine_features.py +++ b/snowflake/ml/feature_store/examples/wine_quality_features/features/managed_wine_features.py @@ -1,9 +1,7 @@ from typing import List from snowflake.ml.feature_store import FeatureView -from snowflake.ml.feature_store.examples.wine_quality_features.entities import ( - wine_entity, -) +from snowflake.ml.feature_store.examples.wine_quality_features.entities import wine_id from snowflake.snowpark import DataFrame, Session, functions as F @@ -17,13 +15,22 @@ def create_draft_feature_view(session: Session, source_dfs: List[DataFrame], sou "CHLORIDES", "TOTAL_SULFUR_DIOXIDE", "PH", - (F.col("FIXED_ACIDITY") * F.col("CITRIC_ACID")).alias("MY_NEW_FEATURE"), + (F.col("FIXED_ACIDITY") * F.col("CITRIC_ACID")).alias("HYBRID_ACID"), ) return FeatureView( name="WINE_FEATURES", # name of feature view - entities=[wine_entity], # entities + entities=[wine_id], # entities feature_df=feature_df, # definition dataframe refresh_freq="1d", # refresh frequency. '1d' means it refreshes everyday - desc="Managed feature view about wine quality which refreshes everyday.", + desc="Managed features about wine quality which refreshes everyday.", + ).attach_feature_desc( + { + "FIXED_ACIDITY": "Fixed acidity.", + "CITRIC_ACID": "Citric acid.", + "CHLORIDES": "Chlorides", + "TOTAL_SULFUR_DIOXIDE": "Total sulfur dioxide.", + "PH": "PH.", + "HYBRID_ACID": "Hybrid acid generated by a production of fixed and citric acid.", + } ) diff --git a/snowflake/ml/feature_store/examples/wine_quality_features/features/static_wine_features.py b/snowflake/ml/feature_store/examples/wine_quality_features/features/static_wine_features.py index 6c7a307b..6d09ebad 100644 --- a/snowflake/ml/feature_store/examples/wine_quality_features/features/static_wine_features.py +++ b/snowflake/ml/feature_store/examples/wine_quality_features/features/static_wine_features.py @@ -1,9 +1,7 @@ from typing import List from snowflake.ml.feature_store import FeatureView -from snowflake.ml.feature_store.examples.wine_quality_features.entities import ( - wine_entity, -) +from snowflake.ml.feature_store.examples.wine_quality_features.entities import wine_id from snowflake.snowpark import DataFrame, Session @@ -14,8 +12,13 @@ def create_draft_feature_view(session: Session, source_dfs: List[DataFrame], sou return FeatureView( name="EXTRA_WINE_FEATURES", # name of feature view - entities=[wine_entity], # entities + entities=[wine_id], # entities feature_df=feature_df, # feature dataframe refresh_freq=None, # refresh frequency. None means it never refresh - desc="Static feature view about wine quality which never refresh.", + desc="Static features about wine quality which never refresh.", + ).attach_feature_desc( + { + "SULPHATES": "Sulphates.", + "ALCOHOL": "Alcohol.", + } ) diff --git a/snowflake/ml/feature_store/examples/wine_quality_features/source.yaml b/snowflake/ml/feature_store/examples/wine_quality_features/source.yaml index d160028f..4c3f1ae2 100644 --- a/snowflake/ml/feature_store/examples/wine_quality_features/source.yaml +++ b/snowflake/ml/feature_store/examples/wine_quality_features/source.yaml @@ -1,5 +1,8 @@ --- source_data: winequality_red +training_spine_table: winedata add_id_column: wine_id label_columns: quality excluded_columns: wine_id +desc: Features using wine quality data trying to predict the quality of wine. +model_category: regression diff --git a/snowflake/ml/feature_store/feature_store.py b/snowflake/ml/feature_store/feature_store.py index 540ed120..4b4ff2dc 100644 --- a/snowflake/ml/feature_store/feature_store.py +++ b/snowflake/ml/feature_store/feature_store.py @@ -52,6 +52,7 @@ FeatureViewVersion, _FeatureViewMetadata, ) +from snowflake.ml.utils import sql_client from snowflake.snowpark import DataFrame, Row, Session, functions as F from snowflake.snowpark.exceptions import SnowparkSQLException from snowflake.snowpark.types import ( @@ -94,13 +95,12 @@ def from_json(cls, json_str: str) -> _FeatureStoreObjInfo: return cls(**state_dict) # type: ignore[arg-type] -# TODO: remove "" after dataset is updated class _FeatureStoreObjTypes(Enum): UNKNOWN = "UNKNOWN" # for forward compatibility MANAGED_FEATURE_VIEW = "MANAGED_FEATURE_VIEW" EXTERNAL_FEATURE_VIEW = "EXTERNAL_FEATURE_VIEW" FEATURE_VIEW_REFRESH_TASK = "FEATURE_VIEW_REFRESH_TASK" - TRAINING_DATA = "" + TRAINING_DATA = "TRAINING_DATA" @classmethod def parse(cls, val: str) -> _FeatureStoreObjTypes: @@ -140,9 +140,8 @@ def parse(cls, val: str) -> _FeatureStoreObjTypes: ) -class CreationMode(Enum): - FAIL_IF_NOT_EXIST = 1 - CREATE_IF_NOT_EXIST = 2 +CreationMode = sql_client.CreationOption +CreationMode.__module__ = __name__ @dataclass(frozen=True) @@ -426,7 +425,9 @@ def update_entity(self, name: str, *, desc: Optional[str] = None) -> Optional[En """ name = SqlIdentifier(name) - found_rows = self.list_entities().filter(F.col("NAME") == name.resolved()).collect() + found_rows = ( + self.list_entities().filter(F.col("NAME") == name.resolved()).collect(statement_params=self._telemetry_stmp) + ) if len(found_rows) == 0: warnings.warn( @@ -853,7 +854,9 @@ def get_feature_view(self, name: str, version: str) -> FeatureView: original_exception=ValueError(f"Failed to find FeatureView {name}/{version}: {results}"), ) - return self._compose_feature_view(results[0][0], results[0][1], self.list_entities().collect()) + return self._compose_feature_view( + results[0][0], results[0][1], self.list_entities().collect(statement_params=self._telemetry_stmp) + ) @overload def refresh_feature_view(self, feature_view: FeatureView) -> None: @@ -1223,7 +1226,11 @@ def get_entity(self, name: str) -> Entity: """ name = SqlIdentifier(name) try: - result = self.list_entities().filter(F.col("NAME") == name.resolved()).collect() + result = ( + self.list_entities() + .filter(F.col("NAME") == name.resolved()) + .collect(statement_params=self._telemetry_stmp) + ) except Exception as e: raise snowml_exceptions.SnowflakeMLException( error_code=error_codes.INTERNAL_SNOWPARK_ERROR, @@ -1357,7 +1364,7 @@ def retrieve_feature_values( if len(features) == 0: raise ValueError("features cannot be empty") if isinstance(features[0], str): - features = self._load_serialized_feature_objects(cast(List[str], features)) + features = self._load_serialized_feature_views(cast(List[str], features)) df, _ = self._join_features( spine_df, @@ -1441,8 +1448,19 @@ def generate_training_set( if save_as is not None: try: save_as = self._get_fully_qualified_name(save_as) - result_df.write.mode("errorifexists").save_as_table(save_as) + result_df.write.mode("errorifexists").save_as_table(save_as, statement_params=self._telemetry_stmp) + + # Add tag + task_obj_info = _FeatureStoreObjInfo(_FeatureStoreObjTypes.TRAINING_DATA, snowml_version.VERSION) + self._session.sql( + f""" + ALTER TABLE {save_as} + SET TAG {self._get_fully_qualified_name(_FEATURE_STORE_OBJECT_TAG)}='{task_obj_info.to_json()}' + """ + ).collect(statement_params=self._telemetry_stmp) + return self._session.table(save_as) + except SnowparkSQLException as e: if e.sql_error_code == sql_error_codes.OBJECT_ALREADY_EXISTS: raise snowml_exceptions.SnowflakeMLException( @@ -1572,7 +1590,7 @@ def generate_dataset( fs_meta = FeatureStoreMetadata( spine_query=spine_df.queries["queries"][-1], - serialized_feature_views=[fv.to_json() for fv in features], + compact_feature_views=[fv._get_compact_repr().to_json() for fv in features], spine_timestamp_col=spine_timestamp_col, ) @@ -1607,6 +1625,7 @@ def generate_dataset( " to generate the data as a Snowflake Table." ), ) + # TODO: Add feature store tag once Dataset (version) supports tags ds: dataset.Dataset = dataset.create_from_dataframe( self._session, name, @@ -1675,11 +1694,18 @@ def load_feature_views_from_dataset(self, ds: dataset.Dataset) -> List[Union[Fea if ( source_meta is None or not isinstance(source_meta.properties, FeatureStoreMetadata) - or source_meta.properties.serialized_feature_views is None + or ( + source_meta.properties.serialized_feature_views is None + and source_meta.properties.compact_feature_views is None + ) ): raise ValueError(f"Dataset {ds} does not contain valid feature view information.") - return self._load_serialized_feature_objects(source_meta.properties.serialized_feature_views) + properties = source_meta.properties + if properties.serialized_feature_views: + return self._load_serialized_feature_views(properties.serialized_feature_views) + else: + return self._load_compact_feature_views(properties.compact_feature_views) # type: ignore[arg-type] @dispatch_decorator() def _clear(self, dryrun: bool = True) -> None: @@ -1700,8 +1726,8 @@ def _clear(self, dryrun: bool = True) -> None: all_fvs_df = self.list_feature_views() all_entities_df = self.list_entities() - all_fvs_rows = all_fvs_df.collect() - all_entities_rows = all_entities_df.collect() + all_fvs_rows = all_fvs_df.collect(statement_params=self._telemetry_stmp) + all_entities_rows = all_entities_df.collect(statement_params=self._telemetry_stmp) if dryrun: logger.info( @@ -1768,6 +1794,7 @@ def _create_dynamic_table( {tagging_clause} ) WAREHOUSE = {warehouse} + REFRESH_MODE = {feature_view.refresh_mode} AS {feature_view.query} """ self._session.sql(query).collect(block=block, statement_params=self._telemetry_stmp) @@ -1985,7 +2012,7 @@ def _is_asof_join_enabled(self) -> bool: MATCH_CONDITION ( spine.ts >= feature.ts ) ON spine.id = feature.id; """ - ).collect() + ).collect(statement_params=self._telemetry_stmp) except SnowparkSQLException: return False return result is not None and len(result) == 1 @@ -2366,11 +2393,11 @@ def _find_object( result.append(row) return result - def _load_serialized_feature_objects( - self, serialized_feature_objs: List[str] + def _load_serialized_feature_views( + self, serialized_feature_views: List[str] ) -> List[Union[FeatureView, FeatureViewSlice]]: results: List[Union[FeatureView, FeatureViewSlice]] = [] - for obj in serialized_feature_objs: + for obj in serialized_feature_views: try: obj_type = json.loads(obj)[_FEATURE_OBJ_TYPE] except Exception as e: @@ -2384,6 +2411,14 @@ def _load_serialized_feature_objects( raise ValueError(f"Unsupported feature object type: {obj_type}") return results + def _load_compact_feature_views( + self, compact_feature_views: List[str] + ) -> List[Union[FeatureView, FeatureViewSlice]]: + results: List[Union[FeatureView, FeatureViewSlice]] = [] + for obj in compact_feature_views: + results.append(FeatureView._load_from_compact_repr(self._session, obj)) + return results + def _exclude_columns(self, df: DataFrame, exclude_columns: List[str]) -> DataFrame: exclude_columns = to_sql_identifiers(exclude_columns) # type: ignore[assignment] df_cols = to_sql_identifiers(df.columns) @@ -2399,12 +2434,12 @@ def _exclude_columns(self, df: DataFrame, exclude_columns: List[str]) -> DataFra def _is_dataset_enabled(self) -> bool: try: - self._session.sql(f"SHOW DATASETS IN SCHEMA {self._config.full_schema_path}").collect() + self._session.sql(f"SHOW DATASETS IN SCHEMA {self._config.full_schema_path}").collect( + statement_params=self._telemetry_stmp + ) return True - except SnowparkSQLException as e: - if "'DATASETS' does not exist" in e.message: - return False - raise + except SnowparkSQLException: + return False def _check_feature_store_object_versions(self) -> None: versions = self._collapse_object_versions() diff --git a/snowflake/ml/feature_store/feature_view.py b/snowflake/ml/feature_store/feature_view.py index cc84afb3..d697f340 100644 --- a/snowflake/ml/feature_store/feature_view.py +++ b/snowflake/ml/feature_store/feature_view.py @@ -6,7 +6,7 @@ from collections import OrderedDict from dataclasses import asdict, dataclass from enum import Enum -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, Union from snowflake.ml._internal.exceptions import ( error_codes, @@ -60,6 +60,29 @@ def from_json(cls, json_str: str) -> _FeatureViewMetadata: return cls(**state_dict) +@dataclass(frozen=True) +class _CompactRepresentation: + """ + A compact representation for FeatureView and FeatureViewSlice, which contains fully qualified name + and optionally a list of feature indices (None means all features will be included). + This is to make the metadata much smaller when generating dataset. + """ + + db: str + sch: str + name: str + version: str + feature_indices: Optional[List[int]] = None + + def to_json(self) -> str: + return json.dumps(asdict(self)) + + @classmethod + def from_json(cls, json_str: str) -> _CompactRepresentation: + state_dict = json.loads(json_str) + return cls(**state_dict) + + class FeatureViewVersion(str): def __new__(cls, version: str) -> FeatureViewVersion: if not _FEATURE_VIEW_VERSION_RE.match(version) or len(version) > _FEATURE_VIEW_VERSION_MAX_LENGTH: @@ -115,6 +138,19 @@ def from_json(cls, json_str: str, session: Session) -> FeatureViewSlice: json_dict["feature_view_ref"] = FeatureView.from_json(json_dict["feature_view_ref"], session) return cls(**json_dict) + def _get_compact_repr(self) -> _CompactRepresentation: + return _CompactRepresentation( + db=self.feature_view_ref.database.identifier(), # type: ignore[union-attr] + sch=self.feature_view_ref.schema.identifier(), # type: ignore[union-attr] + name=self.feature_view_ref.name.identifier(), + version=self.feature_view_ref.version, # type: ignore[arg-type] + feature_indices=self._feature_names_to_indices(), + ) + + def _feature_names_to_indices(self) -> List[int]: + name_to_indices_map = {name: idx for idx, name in enumerate(self.feature_view_ref.feature_names)} + return [name_to_indices_map[n] for n in self.names] + class FeatureView(lineage_node.LineageNode): """ @@ -196,7 +232,7 @@ def __init__( self._database: Optional[SqlIdentifier] = None self._schema: Optional[SqlIdentifier] = None self._warehouse: Optional[SqlIdentifier] = SqlIdentifier(warehouse) if warehouse is not None else None - self._refresh_mode: Optional[str] = None + self._refresh_mode: Optional[str] = _kwargs.get("refresh_mode", "AUTO") self._refresh_mode_reason: Optional[str] = None self._owner: Optional[str] = None self._validate() @@ -394,6 +430,54 @@ def feature_names(self) -> List[SqlIdentifier]: def feature_descs(self) -> Dict[SqlIdentifier, str]: return self._feature_desc + def list_columns(self) -> DataFrame: + """List all columns and their information. + + Returns: + A Snowpark DataFrame contains feature information. + + Example:: + + >>> fs = FeatureStore(...) + >>> e = Entity("foo", ["id"], desc='my entity') + >>> fs.register_entity(e) + + >>> draft_fv = FeatureView( + ... name="fv", + ... entities=[e], + ... feature_df=self._session.table().select(["NAME", "ID", "TITLE", "AGE", "TS"]), + ... timestamp_col="ts", + >>> ).attach_feature_desc({"AGE": "my age", "TITLE": '"my title"'}) + >>> fv = fs.register_feature_view(draft_fv, '1.0') + + >>> fv.list_columns().show() + -------------------------------------------------- + |"NAME" |"CATEGORY" |"DTYPE" |"DESC" | + -------------------------------------------------- + |NAME |FEATURE |string(64) | | + |ID |ENTITY |bigint |my entity | + |TITLE |FEATURE |string(128) |"my title" | + |AGE |FEATURE |bigint |my age | + |TS |TIMESTAMP |bigint |NULL | + -------------------------------------------------- + + """ + session = self._feature_df.session + rows = [] + for name, type in self._feature_df.dtypes: + if SqlIdentifier(name) in self.feature_descs: + desc = self.feature_descs[SqlIdentifier(name)] + rows.append((name, "FEATURE", type, desc)) + elif SqlIdentifier(name) == self._timestamp_col: + rows.append((name, "TIMESTAMP", type, None)) # type: ignore[arg-type] + else: + for e in self._entities: + if SqlIdentifier(name) in e.join_keys: + rows.append((name, "ENTITY", type, e.desc)) + break + + return session.create_dataframe(rows, schema=["name", "category", "dtype", "desc"]) + @property def refresh_freq(self) -> Optional[str]: return self._refresh_freq @@ -599,12 +683,50 @@ def _to_dict(self) -> Dict[str, str]: return fv_dict - def to_df(self, session: Session) -> DataFrame: + def to_df(self, session: Optional[Session] = None) -> DataFrame: + """Convert feature view to a Snowpark DataFrame object. + + Args: + session: [deprecated] This argument has no effect. No need to pass a session object. + + Returns: + A Snowpark Dataframe object contains the information about feature view. + + Example:: + + >>> fs = FeatureStore(...) + >>> e = Entity("foo", ["id"], desc='my entity') + >>> fs.register_entity(e) + + >>> draft_fv = FeatureView( + ... name="fv", + ... entities=[e], + ... feature_df=self._session.table().select(["NAME", "ID", "TITLE", "AGE", "TS"]), + ... timestamp_col="ts", + >>> ).attach_feature_desc({"AGE": "my age", "TITLE": '"my title"'}) + >>> fv = fs.register_feature_view(draft_fv, '1.0') + + fv.to_df().show() + ----------------------------------------------------------------... + |"NAME" |"ENTITIES" |"TIMESTAMP_COL" |"DESC" | + ----------------------------------------------------------------... + |FV |[ |TS |foobar | + | | { | | | + | | "desc": "my entity", | | | + | | "join_keys": [ | | | + | | "ID" | | | + | | ], | | | + | | "name": "FOO", | | | + | | "owner": null | | | + | | } | | | + | |] | | | + ----------------------------------------------------------------... + """ values = list(self._to_dict().values()) schema = [x.lstrip("_") for x in list(self._to_dict().keys())] values.append(str(FeatureView._get_physical_name(self._name, self._version))) # type: ignore[arg-type] schema.append("physical_name") - return session.create_dataframe([values], schema=schema) + return self._feature_df.session.create_dataframe([values], schema=schema) def to_json(self) -> str: state_dict = self._to_dict() @@ -643,6 +765,14 @@ def from_json(cls, json_str: str, session: Session) -> FeatureView: session=session, ) + def _get_compact_repr(self) -> _CompactRepresentation: + return _CompactRepresentation( + db=self.database.identifier(), # type: ignore[union-attr] + sch=self.schema.identifier(), # type: ignore[union-attr] + name=self.name.identifier(), + version=self.version, # type: ignore[arg-type] + ) + @staticmethod def _get_physical_name(fv_name: SqlIdentifier, fv_version: FeatureViewVersion) -> SqlIdentifier: return SqlIdentifier( @@ -655,6 +785,20 @@ def _get_physical_name(fv_name: SqlIdentifier, fv_version: FeatureViewVersion) - ) ) + @staticmethod + def _load_from_compact_repr(session: Session, serialized_repr: str) -> Union[FeatureView, FeatureViewSlice]: + compact_repr = _CompactRepresentation.from_json(serialized_repr) + + fs = feature_store.FeatureStore( + session, compact_repr.db, compact_repr.sch, default_warehouse=session.get_current_warehouse() + ) + fv = fs.get_feature_view(compact_repr.name, compact_repr.version) + + if compact_repr.feature_indices is not None: + feature_names = [fv.feature_names[i] for i in compact_repr.feature_indices] + return fv.slice(feature_names) # type: ignore[no-any-return] + return fv # type: ignore[no-any-return] + @staticmethod def _load_from_lineage_node(session: Session, name: str, version: str) -> FeatureView: db_name, feature_store_name, feature_view_name, _ = identifier.parse_schema_level_object_identifier(name) diff --git a/snowflake/ml/lineage/notebooks/ML Lineage Workflows.ipynb b/snowflake/ml/lineage/notebooks/ML Lineage Workflows.ipynb new file mode 100644 index 00000000..4d50b555 --- /dev/null +++ b/snowflake/ml/lineage/notebooks/ML Lineage Workflows.ipynb @@ -0,0 +1,1796 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0bb54abc", + "metadata": {}, + "source": [ + "- **Required Versions**:\n", + " - Snowflake: 8.27 or higher and Enterprise Edition or higher \n", + " - Snowflake ML Python: **1.6.0** or higher\n", + " - Snowpark Python: **1.21.0** or higher\n", + "\n", + "- **Last Updated**: 8/1/2024" + ] + }, + { + "cell_type": "markdown", + "id": "aeae3429", + "metadata": {}, + "source": [ + "# ML Lineage workflows {-}\n", + "\n", + "This notebook showcases various machine learning workflows, delving into the lineage of each process. It highlights essential features of Snowflake's ML, including [Snowflake Feature Store](https://docs.snowflake.com/en/developer-guide/snowpark-ml/feature-store/overview), [Dataset](https://docs.snowflake.com/en/developer-guide/snowpark-ml/dataset), ML Lineage, [Snowpark ML Modeling](https://docs.snowflake.com/en/developer-guide/snowpark-ml/modeling) and [Snowflake Model Registry](https://docs.snowflake.com/en/developer-guide/snowpark-ml/model-registry/overview). \n", + "\n", + "\n", + "**Table of contents**\n", + "\n", + "1. [Set up environment](#set-up-environment) \n", + " 1.1. [Connect to Snowflake](#connect-to-snowflake) \n", + " 1.2. [Select your example](#select-your-example) \n", + "\n", + "2. [Feature View Lineage](#feature-view-lineage) \n", + "\n", + "3. [Training Data Lineage](#training-data-lineage) \n", + " 3.1. [Training data from feature views](#training-data-from-feature-views) \n", + " 3.1.1. [Dataset as training data](#dataset-as-training-data) \n", + " 3.1.2. [Tables as training data](#tables-as-training-data) \n", + " 3.2. [Training data from source tables](#training-data-from-source-tables) \n", + " 3.2.1. [Dataset from source table as training data](#dataset-from-source-table-as-training-data) \n", + "\n", + "4. [Model Lineage](#model-lineage) \n", + " 4.1. [Model trained in Snowflake ecosystem](#model-trained-in-snowflake-ecosystem) \n", + " 4.1.1. [Model trained using dataset](#model-trained-using-dataset) \n", + " 4.1.2. [Model trained using source tables](#model-trained-using-source-tables) \n", + " 4.2. [Model trained in non-Snowflake ecosystem](#model-trained-in-non-snowflake-ecosystem)\n", + "\n", + "5. [Visualization of lineage](#visualization-of-lineage)\n", + "\n", + "5. [Clean up notebook](#clean-up-notebook)" + ] + }, + { + "cell_type": "markdown", + "id": "9f16e6a8", + "metadata": {}, + "source": [ + "## 1. Set up environment {-}\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "bb535ff6", + "metadata": {}, + "source": [ + "### 1.1 Connect to Snowflake {-}\n", + "\n", + "Let's start with setting up our test environment. We will create a session and a schema. The schema `FS_DEMO_SCHEMA` will be used as the Feature Store. It will be cleaned up at the end of the demo. You need to fill the `connection_parameters` with your Snowflake connection information. Follow this **[guide](https://docs.snowflake.com/en/developer-guide/snowpark/python/creating-session)** for more details about how to connect to Snowflake.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d9622928", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "from snowflake.snowpark import Session, context, exceptions\n", + "\n", + "try:\n", + " # Retrieve active session if in Snowpark Notebook\n", + " session = context.get_active_session()\n", + "except exceptions.SnowparkSessionException:\n", + " # ACTION REQUIRED: Need to manually configure Snowflake connection if using Jupyter\n", + " connection_parameters = {\n", + " \"account\": \"\",\n", + " \"user\": \"\",\n", + " \"password\": \"\",\n", + " \"role\": \"\",\n", + " \"warehouse\": \"\",\n", + " \"database\": \"\",\n", + " \"schema\": \"\",\n", + " }\n", + "\n", + "\n", + " session = Session.builder.configs(connection_parameters).create()\n", + " print(session)\n", + "\n", + "assert session.get_current_database() != None, \"Session must have a database for the demo.\"\n", + "assert session.get_current_warehouse() != None, \"Session must have a warehouse for the demo.\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "1f38d70d-ccc2-40b9-8020-50e3ad3ff165", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Row(status='Schema MODEL_SCHEMA successfully created.')]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# The schema where Feature Store lives.\n", + "FS_DEMO_SCHEMA = \"FEATURE_STORE\"\n", + "# The schema model lives.\n", + "MODEL_DEMO_SCHEMA = \"MODEL_SCHEMA\"\n", + "\n", + "# Make sure your role has CREATE SCHEMA privileges or USAGE privileges on the schema if it already exists.\n", + "session.sql(f\"CREATE OR REPLACE SCHEMA {FS_DEMO_SCHEMA}\").collect()\n", + "session.sql(f\"CREATE OR REPLACE SCHEMA {MODEL_DEMO_SCHEMA}\").collect()" + ] + }, + { + "cell_type": "markdown", + "id": "9b3f89f3-d84d-4226-830d-3a967499fed7", + "metadata": {}, + "source": [ + "\n", + "\n", + "### 1.2 Select your example {-}\n", + "\n", + "We have prepared some examples that you can find in our [open source repo](https://github.com/snowflakedb/snowflake-ml-python/tree/main/snowflake/ml/feature_store/examples). Each example contains the source dataset, feature view and entity definitions which will be used in this demo. `ExampleHelper` (included in snowflake-ml-python) will setup everything with simple APIs and you don't have to worry about the details.\n", + "\n", + "`load_example()` will load the source data into Snowflake tables. In the example below, we are using the “wine_quality_features” example. You can replace this with any example listed above. Execution of the cell below may take some time depending on the size of the dataset." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "2cbb04de-193c-44e1-b400-802e22eb6941", + "metadata": {}, + "outputs": [], + "source": [ + "from snowflake.ml.feature_store.examples.example_helper import ExampleHelper\n", + "\n", + "example_helper = ExampleHelper(session, session.get_current_database(), FS_DEMO_SCHEMA)\n", + "source_tables = example_helper.load_example('wine_quality_features')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "c5a73b0c-41dd-47f7-b7a1-1da492d23b5e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
WINE_IDFIXED_ACIDITYVOLATILE_ACIDITYCITRIC_ACIDRESIDUAL_SUGARCHLORIDESFREE_SULFUR_DIOXIDETOTAL_SULFUR_DIOXIDEDENSITYPHSULPHATESALCOHOLQUALITY
017.40.700.001.90.07611340.99783.510.569.45
127.80.880.002.60.09825670.99683.200.689.85
237.80.760.042.30.09215540.99703.260.659.85
3411.20.280.561.90.07517600.99803.160.589.86
457.40.700.001.90.07611340.99783.510.569.45
\n", + "
" + ], + "text/plain": [ + " WINE_ID FIXED_ACIDITY VOLATILE_ACIDITY CITRIC_ACID RESIDUAL_SUGAR \\\n", + "0 1 7.4 0.70 0.00 1.9 \n", + "1 2 7.8 0.88 0.00 2.6 \n", + "2 3 7.8 0.76 0.04 2.3 \n", + "3 4 11.2 0.28 0.56 1.9 \n", + "4 5 7.4 0.70 0.00 1.9 \n", + "\n", + " CHLORIDES FREE_SULFUR_DIOXIDE TOTAL_SULFUR_DIOXIDE DENSITY PH \\\n", + "0 0.076 11 34 0.9978 3.51 \n", + "1 0.098 25 67 0.9968 3.20 \n", + "2 0.092 15 54 0.9970 3.26 \n", + "3 0.075 17 60 0.9980 3.16 \n", + "4 0.076 11 34 0.9978 3.51 \n", + "\n", + " SULPHATES ALCOHOL QUALITY \n", + "0 0.56 9.4 5 \n", + "1 0.68 9.8 5 \n", + "2 0.65 9.8 5 \n", + "3 0.58 9.8 6 \n", + "4 0.56 9.4 5 " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.table(source_tables[0]).limit(5).to_pandas()" + ] + }, + { + "cell_type": "markdown", + "id": "3038124f-123b-4d22-9058-4fe2e57af6fe", + "metadata": {}, + "source": [ + "\n", + "\n", + "## 2. Feature View Lineage {-}" + ] + }, + { + "cell_type": "markdown", + "id": "4ece7a2b", + "metadata": {}, + "source": [ + "Create a new feature store and register and entities and feature views. More details on feature store APIs can be found [here](https://docs.snowflake.com/en/developer-guide/snowpark-ml/feature-store/overview)). For the detailed workflow of feature store refer to the notebook [here](https://github.com/Snowflake-Labs/snowflake-demo-notebooks/blob/main/End-to-end%20ML%20with%20Feature%20Store%20and%20Model%20Registry/End-to-end%20ML%20with%20Feature%20Store%20and%20Model%20Registry.ipynb) " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "fe850ccd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "---------------------------------------------------------------------------------------------------------\n", + "|\"NAME\" |\"VERSION\" |\"DESC\" |\"REFRESH_FREQ\" |\n", + "---------------------------------------------------------------------------------------------------------\n", + "|WINE_FEATURES |1.0 |Managed feature view about wine quality which r... |1 day |\n", + "|EXTRA_WINE_FEATURES |1.0 |Static feature view about wine quality which ne... |NULL |\n", + "---------------------------------------------------------------------------------------------------------\n", + "\n" + ] + } + ], + "source": [ + "from snowflake.ml.feature_store import (\n", + " FeatureStore,\n", + " FeatureView,\n", + " Entity,\n", + " CreationMode\n", + ")\n", + "\n", + "fs = FeatureStore(\n", + " session=session, \n", + " database=session.get_current_database(), \n", + " name=FS_DEMO_SCHEMA, \n", + " default_warehouse=session.get_current_warehouse(),\n", + " creation_mode=CreationMode.CREATE_IF_NOT_EXIST,\n", + ")\n", + "\n", + "all_entities = []\n", + "for e in example_helper.load_entities():\n", + " entity = fs.register_entity(e)\n", + " all_entities.append(entity)\n", + "\n", + "all_feature_views = []\n", + "for fv in example_helper.load_draft_feature_views():\n", + " rf = fs.register_feature_view(\n", + " feature_view=fv,\n", + " version='1.0'\n", + " )\n", + " all_feature_views.append(rf)\n", + "\n", + "fs.list_feature_views().select('name', 'version', 'desc', 'refresh_freq').show()" + ] + }, + { + "cell_type": "markdown", + "id": "d3bbf57e", + "metadata": {}, + "source": [ + "##### Query Lineage\n", + "\n", + "\n", + "\n", + "Query the upstream lineage of the feature views we just created. " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "8b9cec24", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "LineageNode.lineage() is in private preview since 1.5.3. Do not use it in production. \n", + "Lineage.trace() is in private preview since 1.16.0. Do not use it in production. \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Upstream Lineage of feature view 'EXTRA_WINE_FEATURES'\n", + "[LineageNode(\n", + " name='LINEAGE_DEMO_DB.FEATURE_STORE.WINEDATA',\n", + " version='None',\n", + " domain='table',\n", + " status='ACTIVE',\n", + " created_on='2024-08-01 22:44:14'\n", + ")]\n", + "Upstream Lineage of feature view 'WINE_FEATURES'\n", + "[LineageNode(\n", + " name='LINEAGE_DEMO_DB.FEATURE_STORE.WINEDATA',\n", + " version='None',\n", + " domain='table',\n", + " status='ACTIVE',\n", + " created_on='2024-08-01 22:44:14'\n", + ")]\n" + ] + } + ], + "source": [ + "for fv in all_feature_views:\n", + " print(\"Upstream Lineage of feature view '\" + fv.name + \"'\")\n", + " print(fv.lineage(direction='upstream'))" + ] + }, + { + "cell_type": "markdown", + "id": "4dc1a7dc", + "metadata": {}, + "source": [ + "\n", + "\n", + "## 3. Training Data Lineage {-}\n", + "\n", + "Next step in ML workflows will be generating training data that is needed to train the model. There are 2 ways to generate training data. \n", + "1. Using feature views.\n", + "2. Using source tables directly. " + ] + }, + { + "cell_type": "markdown", + "id": "6c705ac1", + "metadata": {}, + "source": [ + "\n", + "\n", + "### 3.1 Training Data from Feature views {-}\n", + "\n", + "Lets explore the workflow of creating training data sets using the feature views. " + ] + }, + { + "cell_type": "markdown", + "id": "ec901a65-f3ee-4c12-b8ff-ec0f630e5372", + "metadata": {}, + "source": [ + "Retrieve some metadata columns that are essential when generating training data." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "a6c80b76-99a4-4eb0-b0cb-583afa434ecf", + "metadata": {}, + "outputs": [], + "source": [ + "label_cols = example_helper.get_label_cols()\n", + "timestamp_col = example_helper.get_training_data_timestamp_col()\n", + "excluded_cols = example_helper.get_excluded_cols()\n", + "join_keys = [key for entity in all_entities for key in entity.join_keys]\n" + ] + }, + { + "cell_type": "markdown", + "id": "5f66ad1d-5ad1-4ad8-92f9-c65be491e0c3", + "metadata": {}, + "source": [ + "Create a spine dataframe that's sampled from source table." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ea00fe3a-ac16-45d7-95c0-7ea7ed344e79", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
QUALITYWINE_ID
06544
15978
25679
351459
455
.........
5076508
5086624
50951132
5105511
51151568
\n", + "

512 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " QUALITY WINE_ID\n", + "0 6 544\n", + "1 5 978\n", + "2 5 679\n", + "3 5 1459\n", + "4 5 5\n", + ".. ... ...\n", + "507 6 508\n", + "508 6 624\n", + "509 5 1132\n", + "510 5 511\n", + "511 5 1568\n", + "\n", + "[512 rows x 2 columns]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sample_count = 512\n", + "source_df = session.sql(f\"\"\"\n", + " select {','.join(label_cols)}, \n", + " {','.join(join_keys)} \n", + " {',' + timestamp_col if timestamp_col is not None else ''} \n", + " from {source_tables[0]}\"\"\")\n", + "spine_df = source_df.sample(n=sample_count)\n", + "# preview spine dataframe\n", + "spine_df.to_pandas()" + ] + }, + { + "cell_type": "markdown", + "id": "7e69a065", + "metadata": {}, + "source": [ + "\n", + "\n", + "#### 3.1.1 Dataset as training data {-}\n", + "\n", + "\n", + "\n", + "[Snowflake Dataset](https://docs.snowflake.com/en/developer-guide/snowpark-ml/dataset) generated from feature views created above. Dataset is a readonly objects helps in reproducability of the ML model. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "e3a03f64", + "metadata": {}, + "outputs": [], + "source": [ + "my_dataset = fs.generate_dataset(\n", + " name=\"my_dataset\",\n", + " spine_df=spine_df, \n", + " features=all_feature_views,\n", + " version=\"4.0\",\n", + " spine_timestamp_col=timestamp_col,\n", + " spine_label_cols=label_cols,\n", + " exclude_columns=excluded_cols,\n", + " desc=\"This is the dataset joined spine dataframe with feature views\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "6ac0d146", + "metadata": {}, + "source": [ + "##### Query Lineage\n", + "\n", + "\n", + "\n", + "Query Upstream lineage of the dataset we just generated. " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "5023adaf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[LineageNode(\n", + " name='LINEAGE_DEMO_DB.FEATURE_STORE.WINEDATA',\n", + " version='None',\n", + " domain='table',\n", + " status='ACTIVE',\n", + " created_on='2024-08-01 22:44:14'\n", + " ),\n", + " FeatureView(_name=EXTRA_WINE_FEATURES, _entities=[Entity(name=WINE, join_keys=['WINE_ID'], owner=None, desc=Wine ID column.)], _feature_df=, _timestamp_col=None, _desc=Static feature view about wine quality which never refresh., _infer_schema_df=, _query=SELECT \"WINE_ID\", \"SULPHATES\", \"ALCOHOL\" FROM \"LINEAGE_DEMO_DB\".FEATURE_STORE.winedata, _version=1.0, _status=FeatureViewStatus.STATIC, _feature_desc=OrderedDict([('SULPHATES', ''), ('ALCOHOL', '')]), _refresh_freq=None, _database=LINEAGE_DEMO_DB, _schema=FEATURE_STORE, _warehouse=None, _refresh_mode=None, _refresh_mode_reason=None, _owner=ACCOUNTADMIN, _lineage_node_name=LINEAGE_DEMO_DB.FEATURE_STORE.EXTRA_WINE_FEATURES, _lineage_node_domain=feature_view, _lineage_node_version=1.0, _lineage_node_status=None, _lineage_node_created_on=None, _session=),\n", + " FeatureView(_name=WINE_FEATURES, _entities=[Entity(name=WINE, join_keys=['WINE_ID'], owner=None, desc=Wine ID column.)], _feature_df=, _timestamp_col=None, _desc=Managed feature view about wine quality which refreshes everyday., _infer_schema_df=, _query=SELECT \"WINE_ID\", \"FIXED_ACIDITY\", \"CITRIC_ACID\", \"CHLORIDES\", \"TOTAL_SULFUR_DIOXIDE\", \"PH\", (\"FIXED_ACIDITY\" * \"CITRIC_ACID\") AS \"MY_NEW_FEATURE\" FROM \"LINEAGE_DEMO_DB\".FEATURE_STORE.winedata, _version=1.0, _status=FeatureViewStatus.ACTIVE, _feature_desc=OrderedDict([('FIXED_ACIDITY', ''), ('CITRIC_ACID', ''), ('CHLORIDES', ''), ('TOTAL_SULFUR_DIOXIDE', ''), ('PH', ''), ('MY_NEW_FEATURE', '')]), _refresh_freq=1 day, _database=LINEAGE_DEMO_DB, _schema=FEATURE_STORE, _warehouse=AX_XL, _refresh_mode=INCREMENTAL, _refresh_mode_reason=None, _owner=ACCOUNTADMIN, _lineage_node_name=LINEAGE_DEMO_DB.FEATURE_STORE.WINE_FEATURES, _lineage_node_domain=feature_view, _lineage_node_version=1.0, _lineage_node_status=None, _lineage_node_created_on=None, _session=)]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "my_dataset.lineage(direction=\"upstream\")" + ] + }, + { + "cell_type": "markdown", + "id": "0d4469c8", + "metadata": {}, + "source": [ + "Query the downstream of feature views we used to create the dataset. " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "7cb60b63", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downstream Lineage of feature view 'EXTRA_WINE_FEATURES'\n", + "[Dataset(\n", + " name='LINEAGE_DEMO_DB.FEATURE_STORE.MY_DATASET',\n", + " version='4.0',\n", + ")]\n", + "Downstream Lineage of feature view 'WINE_FEATURES'\n", + "[Dataset(\n", + " name='LINEAGE_DEMO_DB.FEATURE_STORE.MY_DATASET',\n", + " version='4.0',\n", + ")]\n" + ] + } + ], + "source": [ + "for fv in all_feature_views:\n", + " print(\"Downstream Lineage of feature view '\" + fv.name + \"'\")\n", + " print(fv.lineage(direction='downstream'))" + ] + }, + { + "cell_type": "markdown", + "id": "dfd71162", + "metadata": {}, + "source": [ + "\n", + "\n", + "#### 3.1.2 Tables as Training data {-}\n", + "\n", + "Alternatively, you can create a regular table as a dataset from feature views. The downside is that tables are mutable, so reproducibility cannot be guaranteed." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "5eefec90", + "metadata": {}, + "outputs": [], + "source": [ + "my_table_data = fs.generate_dataset(\n", + " name=\"my_table_dataset\",\n", + " spine_df=spine_df, \n", + " features=all_feature_views,\n", + " version=\"4.0\",\n", + " spine_timestamp_col=timestamp_col,\n", + " spine_label_cols=label_cols,\n", + " exclude_columns=excluded_cols,\n", + " desc=\"This is the dataset joined spine dataframe with feature views\",\n", + " output_type=\"table\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "8e480986", + "metadata": {}, + "source": [ + "##### Query Lineage\n", + "\n", + "\n", + "You can also explore lineage of generated table from the feature view. You filter the results to see just table entities. " + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "a253f3b4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downstream Lineage of feature view 'EXTRA_WINE_FEATURES'\n", + "[LineageNode(\n", + " name='LINEAGE_DEMO_DB.FEATURE_STORE.MY_TABLE_DATASET_4',\n", + " version='None',\n", + " domain='table',\n", + " status='ACTIVE',\n", + " created_on='2024-08-01 22:44:28'\n", + ")]\n", + "Downstream Lineage of feature view 'WINE_FEATURES'\n", + "[LineageNode(\n", + " name='LINEAGE_DEMO_DB.FEATURE_STORE.MY_TABLE_DATASET_4',\n", + " version='None',\n", + " domain='table',\n", + " status='ACTIVE',\n", + " created_on='2024-08-01 22:44:28'\n", + ")]\n" + ] + } + ], + "source": [ + "for fv in all_feature_views:\n", + " print(\"Downstream Lineage of feature view '\" + fv.name + \"'\")\n", + " print(fv.lineage(direction='downstream', domain_filter=[\"table\"]))" + ] + }, + { + "cell_type": "markdown", + "id": "cb38ac0b", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "### 3.2 Training Data from source tables {-}\n", + "\n", + "We will explore the workflow of creating training dataset directly from source tables instead of feature views. " + ] + }, + { + "cell_type": "markdown", + "id": "761f1296", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "#### 3.2.1 Dataset from source table as training data\n", + "\n", + "\n", + "Create the dataset from a source table. Lineage works in a similar way even when its trained with source view or a stage. " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "35b8b59a-dcae-41a4-8954-db6719c5cf60", + "metadata": {}, + "outputs": [], + "source": [ + "from snowflake.ml import dataset\n", + "\n", + "my_table_based_dataset = dataset.create_from_dataframe(\n", + " session=session,\n", + " name=\"my_dataset_from_table\",\n", + " version=\"v1\",\n", + " input_dataframe=session.table(source_tables[0]),\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "6a4a2444", + "metadata": {}, + "source": [ + "##### Query Lineage\n", + "\n", + "\n", + "Query the upstream lineage of the dataset we just created. " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "190cac1a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[LineageNode(\n", + " name='LINEAGE_DEMO_DB.FEATURE_STORE.WINEDATA',\n", + " version='None',\n", + " domain='table',\n", + " status='ACTIVE',\n", + " created_on='2024-08-01 22:44:14'\n", + " )]" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "my_table_based_dataset.lineage(direction=\"upstream\")" + ] + }, + { + "cell_type": "markdown", + "id": "c2d0acfc", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "## 4. Model Lineage {-}\n", + "\n", + "Now let's train a simple random forest model, and evaluate the prediction accuracy." + ] + }, + { + "cell_type": "markdown", + "id": "e03addbc", + "metadata": {}, + "source": [ + "Let's create a registry to save the trained models. All models need to be logged into the registry for their lineage to be tracked." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "cf1209a6-4c8c-4441-9c5d-7688f4ec0233", + "metadata": {}, + "outputs": [], + "source": [ + "from snowflake.ml.registry import Registry\n", + "\n", + "registry = Registry(\n", + " session=session, \n", + " database_name=session.get_current_database(), \n", + " schema_name=MODEL_DEMO_SCHEMA,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "ec35fef9", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "### 4.1 Model trained in snowflake ecosystem {-}" + ] + }, + { + "cell_type": "markdown", + "id": "aea11101", + "metadata": {}, + "source": [ + "Lets define a training function that uses Random forest to build the model" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "fd5035d9", + "metadata": {}, + "outputs": [], + "source": [ + "from snowflake.ml.modeling.ensemble import RandomForestRegressor\n", + "from snowflake.ml.modeling import metrics as snowml_metrics\n", + "from snowflake.snowpark.functions import abs as sp_abs, mean, col\n", + "\n", + "def train_model_using_snowpark_ml(training_data_df):\n", + " train, test = training_data_df.random_split([0.8, 0.2], seed=42)\n", + " feature_columns = list(set(training_data_df.columns) - set(label_cols) - set(join_keys) - set([timestamp_col]))\n", + " print(f\"feature cols: {feature_columns}\")\n", + " \n", + " rf = RandomForestRegressor(\n", + " input_cols=feature_columns, label_cols=label_cols, \n", + " max_depth=3, n_estimators=20, random_state=42\n", + " )\n", + "\n", + " rf.fit(train)\n", + " predictions = rf.predict(test)\n", + "\n", + " output_label_names = ['OUTPUT_' + col for col in label_cols]\n", + " mse = snowml_metrics.mean_squared_error(\n", + " df=predictions, \n", + " y_true_col_names=label_cols, \n", + " y_pred_col_names=output_label_names\n", + " )\n", + "\n", + " accuracy = 100 - snowml_metrics.mean_absolute_percentage_error(\n", + " df=predictions,\n", + " y_true_col_names=label_cols,\n", + " y_pred_col_names=output_label_names\n", + " )\n", + "\n", + " print(f\"MSE: {mse}, Accuracy: {accuracy}\")\n", + " return rf" + ] + }, + { + "cell_type": "markdown", + "id": "574a810b", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "#### 4.1.1 Model trained using Dataset {-}" + ] + }, + { + "cell_type": "markdown", + "id": "0a1cf2f4-59b3-40da-8c43-bee27129105d", + "metadata": {}, + "source": [ + "Convert dataset to a snowpark dataframe and examine all the features in it." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "5f3c71aa-1c6b-4bf4-83f9-2176dc249f83", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
QUALITYSULPHATESALCOHOLFIXED_ACIDITYCITRIC_ACIDCHLORIDESTOTAL_SULFUR_DIOXIDEPHMY_NEW_FEATURE
050.569.47.40.000.076343.510.000
150.689.87.80.000.098673.200.000
250.649.57.60.290.075663.402.204
350.7011.17.90.400.062203.283.160
470.7610.711.80.490.093803.305.782
..............................
50740.469.68.10.000.081243.380.000
50850.649.76.70.080.064343.330.536
50970.6811.413.30.750.084433.049.975
51060.4810.55.60.780.074923.394.368
51160.6310.210.00.310.090623.183.100
\n", + "

512 rows × 9 columns

\n", + "
" + ], + "text/plain": [ + " QUALITY SULPHATES ALCOHOL FIXED_ACIDITY CITRIC_ACID CHLORIDES \\\n", + "0 5 0.56 9.4 7.4 0.00 0.076 \n", + "1 5 0.68 9.8 7.8 0.00 0.098 \n", + "2 5 0.64 9.5 7.6 0.29 0.075 \n", + "3 5 0.70 11.1 7.9 0.40 0.062 \n", + "4 7 0.76 10.7 11.8 0.49 0.093 \n", + ".. ... ... ... ... ... ... \n", + "507 4 0.46 9.6 8.1 0.00 0.081 \n", + "508 5 0.64 9.7 6.7 0.08 0.064 \n", + "509 7 0.68 11.4 13.3 0.75 0.084 \n", + "510 6 0.48 10.5 5.6 0.78 0.074 \n", + "511 6 0.63 10.2 10.0 0.31 0.090 \n", + "\n", + " TOTAL_SULFUR_DIOXIDE PH MY_NEW_FEATURE \n", + "0 34 3.51 0.000 \n", + "1 67 3.20 0.000 \n", + "2 66 3.40 2.204 \n", + "3 20 3.28 3.160 \n", + "4 80 3.30 5.782 \n", + ".. ... ... ... \n", + "507 24 3.38 0.000 \n", + "508 34 3.33 0.536 \n", + "509 43 3.04 9.975 \n", + "510 92 3.39 4.368 \n", + "511 62 3.18 3.100 \n", + "\n", + "[512 rows x 9 columns]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "training_data_df = my_dataset.read.to_snowpark_dataframe()\n", + "assert training_data_df.count() == sample_count\n", + "# drop rows that have any nulls in value. \n", + "training_data_df = training_data_df.dropna(how='any')\n", + "training_data_df.to_pandas()" + ] + }, + { + "cell_type": "markdown", + "id": "8eee34d3", + "metadata": {}, + "source": [ + "Train the random forest model using Snowpark-ML and the dataset, then log the model in the registry." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "352603a9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "feature cols: ['MY_NEW_FEATURE', 'PH', 'TOTAL_SULFUR_DIOXIDE', 'CITRIC_ACID', 'CHLORIDES', 'SULPHATES', 'FIXED_ACIDITY', 'ALCOHOL']\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "The version of package 'snowflake-snowpark-python' in the local environment is 1.20.2, which does not fit the criteria for the requirement 'snowflake-snowpark-python'. Your UDF might not work when the package version is different between the server and your local environment.\n", + "The version of package 'numpy' in the local environment is 1.24.4, which does not fit the criteria for the requirement 'numpy==1.24.3'. Your UDF might not work when the package version is different between the server and your local environment.\n", + "The version of package 'scikit-learn' in the local environment is 1.3.2, which does not fit the criteria for the requirement 'scikit-learn==1.3.0'. Your UDF might not work when the package version is different between the server and your local environment.\n", + "/opt/homebrew/anaconda3/envs/py38_env/lib/python3.8/site-packages/sklearn/base.py:348: InconsistentVersionWarning: Trying to unpickle estimator DecisionTreeRegressor from version 1.3.0 when using version 1.3.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n", + "/opt/homebrew/anaconda3/envs/py38_env/lib/python3.8/site-packages/sklearn/base.py:348: InconsistentVersionWarning: Trying to unpickle estimator RandomForestRegressor from version 1.3.0 when using version 1.3.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n", + "The version of package 'numpy' in the local environment is 1.24.4, which does not fit the criteria for the requirement 'numpy==1.24.3'. Your UDF might not work when the package version is different between the server and your local environment.\n", + "The version of package 'scikit-learn' in the local environment is 1.3.2, which does not fit the criteria for the requirement 'scikit-learn==1.3.0'. Your UDF might not work when the package version is different between the server and your local environment.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MSE: 0.25267477340674793, Accuracy: 99.92349333548655\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/anaconda3/envs/py38_env/lib/python3.8/contextlib.py:113: UserWarning: `relax_version` is not set and therefore defaulted to True. Dependency version constraints relaxed from ==x.y.z to >=x.y, <(x+1). To use specific dependency versions for compatibility, reproducibility, etc., set `options={'relax_version': False}` when logging the model.\n", + " return next(self.gen)\n" + ] + } + ], + "source": [ + "random_forest_model = train_model_using_snowpark_ml(training_data_df) \n", + "\n", + "model_version = registry.log_model(\n", + " model_name=\"MODEL_TRAINED_ON_DATASET\",\n", + " version_name=\"v1\",\n", + " model=random_forest_model,\n", + " comment=\"Model trained with feature views, dataset\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "ed343e67", + "metadata": {}, + "source": [ + "##### Query Lineage" + ] + }, + { + "cell_type": "markdown", + "id": "83d44553", + "metadata": {}, + "source": [ + "Query the upstream of the model we just trained. " + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "ae53f591", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Dataset(\n", + " name='LINEAGE_DEMO_DB.FEATURE_STORE.MY_DATASET',\n", + " version='4.0',\n", + " )]" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ds = model_version.lineage(direction=\"upstream\")\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "d9599921", + "metadata": {}, + "source": [ + "The model can also be explored as part of the downstream path of the dataset used to train the model." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "fc4f5bf2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[ModelVersion(\n", + " name='MODEL_TRAINED_ON_DATASET',\n", + " version='V1',\n", + " )]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ds[0].lineage(direction=\"downstream\")" + ] + }, + { + "cell_type": "markdown", + "id": "8c9e42b7", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "#### 4.1.2 Model trained using source tables {-}" + ] + }, + { + "cell_type": "markdown", + "id": "703ceeda", + "metadata": {}, + "source": [ + "Train the random forest model using Snowpark-ML and the source tables, then log the model in the registry.\n", + "\n", + "Lineage works in a similar way even when its trained with source view or a stage. " + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "95fb5cbf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "feature cols: ['VOLATILE_ACIDITY', 'RESIDUAL_SUGAR', 'TOTAL_SULFUR_DIOXIDE', 'CITRIC_ACID', 'PH', 'CHLORIDES', 'SULPHATES', 'DENSITY', 'FIXED_ACIDITY', 'ALCOHOL', 'FREE_SULFUR_DIOXIDE']\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/anaconda3/envs/py38_env/lib/python3.8/site-packages/sklearn/base.py:348: InconsistentVersionWarning: Trying to unpickle estimator DecisionTreeRegressor from version 1.3.0 when using version 1.3.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n", + "/opt/homebrew/anaconda3/envs/py38_env/lib/python3.8/site-packages/sklearn/base.py:348: InconsistentVersionWarning: Trying to unpickle estimator RandomForestRegressor from version 1.3.0 when using version 1.3.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n", + "WARNING:snowflake.snowpark.session:The version of package 'numpy' in the local environment is 1.24.4, which does not fit the criteria for the requirement 'numpy==1.24.3'. Your UDF might not work when the package version is different between the server and your local environment.\n", + "WARNING:snowflake.snowpark.session:The version of package 'scikit-learn' in the local environment is 1.3.2, which does not fit the criteria for the requirement 'scikit-learn==1.3.0'. Your UDF might not work when the package version is different between the server and your local environment.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MSE: 0.39049050644031114, Accuracy: 99.90829288453038\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/anaconda3/envs/py38_env/lib/python3.8/contextlib.py:113: UserWarning: `relax_version` is not set and therefore defaulted to True. Dependency version constraints relaxed from ==x.y.z to >=x.y, <(x+1). To use specific dependency versions for compatibility, reproducibility, etc., set `options={'relax_version': False}` when logging the model.\n", + " return next(self.gen)\n" + ] + } + ], + "source": [ + "table_training_data_df = session.table(source_tables[0])\n", + "table_training_data_df.dropna(how='any')\n", + "\n", + "random_forest_model = train_model_using_snowpark_ml(table_training_data_df) \n", + "\n", + "model_version = registry.log_model(\n", + " model_name=\"MODEL_TRAINED_ON_TABLE\",\n", + " version_name=\"v1\",\n", + " model=random_forest_model,\n", + " comment=\"Model trained with table\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "2af23e31", + "metadata": {}, + "source": [ + "##### Query Lineage\n", + "\n", + "\n", + "Query the upstream of the model we just trained. " + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "23f99177", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[LineageNode(\n", + " name='LINEAGE_DEMO_DB.MODEL_SCHEMA.SNOWPARK_TEMP_TABLE_Q9VM0X2LP8',\n", + " version='None',\n", + " domain='table',\n", + " status='ACTIVE',\n", + " created_on='2024-08-01 22:45:06'\n", + " )]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "table = model_version.lineage(direction=\"upstream\")\n", + "\n", + "table" + ] + }, + { + "cell_type": "markdown", + "id": "99d426c9", + "metadata": {}, + "source": [ + "The model can also be explored as part of the downstream path of the table used to train the model." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "21e4cd1c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[ModelVersion(\n", + " name='MODEL_TRAINED_ON_TABLE',\n", + " version='V1',\n", + " )]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "table[0].lineage(direction=\"downstream\")" + ] + }, + { + "cell_type": "markdown", + "id": "be2ce5b3", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "### 4.2 Model trained in non-snowflake ecosystem {-}" + ] + }, + { + "cell_type": "markdown", + "id": "33cb95c7", + "metadata": {}, + "source": [ + "For the workflows such as:\n", + "A model trained using snowpark.ml but not a Snowpark DataFrame (like pandas).\n", + "A model trained without using snowpark.ml or a Snowpark DataFrame.\n", + "A model trained outside of Snowflake.\n", + "\n", + "\n", + "You can still associate the lineage between the source data object and the trained model by passing the snowpark dataframe backed by the source data object to model registry’s log_model API as sample_input_data. \n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "63e5f294", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "feature cols: ['MY_NEW_FEATURE', 'PH', 'TOTAL_SULFUR_DIOXIDE', 'CITRIC_ACID', 'CHLORIDES', 'SULPHATES', 'FIXED_ACIDITY', 'ALCOHOL']\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/anaconda3/envs/py38_env/lib/python3.8/site-packages/sklearn/base.py:1152: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples,), for example using ravel().\n", + " return fit_method(estimator, *args, **kwargs)\n", + "/opt/homebrew/anaconda3/envs/py38_env/lib/python3.8/contextlib.py:113: UserWarning: `relax_version` is not set and therefore defaulted to True. Dependency version constraints relaxed from ==x.y.z to >=x.y, <(x+1). To use specific dependency versions for compatibility, reproducibility, etc., set `options={'relax_version': False}` when logging the model.\n", + " return next(self.gen)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MSE: 0.4896289668292035, Accuracy: 99.89502779572355\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/anaconda3/envs/py38_env/lib/python3.8/site-packages/snowflake/ml/model/model_signature.py:69: UserWarning: The sample input has 512 rows, thus a truncation happened before inferring signature. This might cause inaccurate signature inference. If that happens, consider specifying signature manually.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestRegressor\n", + "from sklearn.metrics import mean_squared_error, mean_absolute_percentage_error\n", + "from sklearn.model_selection import train_test_split\n", + "import pandas as pd\n", + "\n", + "def train_model_using_sklearn(training_data_df, feature_columns):\n", + " train, test = train_test_split(training_data_df, test_size=0.2, random_state=42)\n", + " \n", + " X_train = train[feature_columns]\n", + " y_train = train[label_cols]\n", + " \n", + " X_test = test[feature_columns]\n", + " y_test = test[label_cols]\n", + "\n", + " rf = RandomForestRegressor(max_depth=3, n_estimators=20, random_state=42)\n", + " rf.fit(X_train, y_train)\n", + "\n", + " predictions = rf.predict(X_test)\n", + "\n", + " mse = mean_squared_error(y_test, predictions)\n", + " accuracy = 100 - mean_absolute_percentage_error(y_test, predictions)\n", + " \n", + " print(f\"MSE: {mse}, Accuracy: {accuracy}\")\n", + " return rf\n", + "\n", + "\n", + "feature_columns = list(set(training_data_df.columns) - set(label_cols) - set(join_keys) - set([timestamp_col]))\n", + "print(f\"feature cols: {feature_columns}\")\n", + "\n", + "sklearn_trained_model = train_model_using_sklearn(training_data_df.to_pandas(), feature_columns)\n", + "\n", + "training_data_df = training_data_df.select(feature_columns)\n", + "model_version = registry.log_model(\n", + " model_name=\"MODEL_TRAINED_ON_PANDAS\",\n", + " version_name=\"v1\",\n", + " model=sklearn_trained_model,\n", + " comment=\"Model trained with pandas dataframe\",\n", + " # Passing the snowpark dataframe as sample input data\n", + " sample_input_data = training_data_df\n", + ")\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "05e551d1", + "metadata": {}, + "source": [ + "##### Query lineage\n", + "\n", + "\n", + "Query the upstream of the model we just trained. " + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "ff87faf8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Dataset(\n", + " name='LINEAGE_DEMO_DB.FEATURE_STORE.MY_DATASET',\n", + " version='4.0',\n", + " )]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ds = model_version.lineage(direction=\"upstream\")\n", + "\n", + "ds" + ] + }, + { + "cell_type": "markdown", + "id": "e95a48d1", + "metadata": {}, + "source": [ + "The model can also be explored as part of the downstream path of the dataset used to train the model." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "cb9cbf8c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ModelVersion(\n", + " name='MODEL_TRAINED_ON_DATASET',\n", + " version='V1',\n", + "), ModelVersion(\n", + " name='MODEL_TRAINED_ON_PANDAS',\n", + " version='V1',\n", + ")]\n" + ] + } + ], + "source": [ + "print(ds[0].lineage(direction=\"downstream\"))\n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "fad0070f", + "metadata": {}, + "source": [ + "\n", + "\n", + "## 5. Visualization of lineage\n", + "\n", + "\n", + "The below image shows the screenshot of complete visualization of lineages of all the objects we created in the notebook from Snowsight UI. " + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "a31c0e66", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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KEjn7/PL2ZEACZBAtgh4EqRPqDC9a88BWbx8s2zTx+0rlCkpxYsVVTGJHrDZgs2dSSAfE0hL+1f2HTgsG7fulpRSCVK/VjkplVhMIlWIpiCdj088p0YCJEACJEACJEACJEACHghQkPYAhatIgARIgAROE7AZ0q4saRWkkS2dpq+Dh1ONB+whfU9/3ib9oRs+enOaH5dIoKASOH2LqpCpWRhXtIiUVjE6Xt8jVIhGVjQEaZsdbTOkCyovzpsESIAESIAESIAESIAECgoBCtIF5UxzniRAAiSQDQI2UzqDOK02Hv/qKw1KNKw90H+6Kp2NI3FXEiCBfEdAixUacfpUgdRCas1RWF8QoK0IDZsOWnXkuzPPCZEACZAACZAACZAACZCARwKRHtdyJQmQAAmQAAk4CDiFIqeA9K8KSkasRlsrSjv24yIJkAAJWDEa71Z4dl5H7DqSIgESIAESIAESIAESIAESKBgEKEgXjPPMWZIACZBAtglYURrvEKHtOzrGZwYJkAAJ+CLgvIZg2fnZ137cRgIkQAIkQAIkQAIkQAIkkL8I0LIjf51PzoYESIAEcpyAU3x2Luf4gXkAEiCBfEHACtGYjHM5X0yOkyABEiABEiABEiABEiABEvBLIMJvCzYgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIggRAQYIZ0CCCyCxIgARIgARIgARIgARIgARIgARIgARIgARIgARIgAf8EmCHtnxFbkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJhIAABekQQGQXJEACJEACJEACJEACJEACJEACJEACJEACJEACJEAC/glQkPbPiC1IgARIgARIgARIgARIgARIgARIgARIgARIgARIgARCQICCdAggsgsSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAH/BChI+2fEFiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiEgQEE6BBDZBQmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQgH8CFKT9M2ILEiABEiABEiABEiABEiABEiABEiABEiABEiABEiCBEBCgIB0CiOyCBEiABEiABEiABEiABEiABEiABEiABEiABEiABEjAPwEK0v4ZsQUJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEAICFCQDgFEdkECJEACJEACJEACJEACJEACJEACJEACJEACJEACJOCfAAVp/4zYggRIgARIgARIgARIgARIgARIgARIgARIgARIgARIIAQEKEiHACK7IAESIAESIAESIAESIAESIAESIAESIAESIAESIAES8E+AgrR/RmxBAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiQQAgIUpEMAkV2QAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAn4J0BB2j8jtiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEggBAQrSIYDILkiABEiABEiABEiABEiABEiABEiABEiABEiABEiABPwToCDtnxFbkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJhIAABekQQGQXJEACJEACJEACJEACJEACJEACJEACJEACJEACJEAC/glQkPbPiC1IgARIgARIgARIgARIgARIgARIgARIgARIgARIgARCQICCdAggsgsSIAESIAESIAESIAESIAESIAESIAESIAESIAESIAH/BChI+2fEFiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiEgQEE6BBDZBQmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQgH8CFKT9M2ILEiABEiABEiABEiABEiABEiABEiABEiABEiABEiCBEBCgIB0CiOyCBEiABEiABEiABEiABEiABEiABEiABEiABEiABEjAPwEK0v4ZsQUJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkEAICFCQDgFEdkECJEACJEACJEACJEACJEACJEACJEACJEACJEACJOCfAAVp/4zYggRIgARIgARIgARIgARIgARIgARIgARIgARIgARIIAQEKEiHACK7IAESIAESIAESIAESIAESIAESIAESIAESIAESIAES8E+AgrR/RmxBAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiQQAgIUpEMAkV2QAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAn4J0BB2j8jtiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEggBAQrSIYDILkiABEiABEiABEiABEiABEiABEiABEiABEiABEiABPwToCDtnxFbkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJhIAABekQQGQXJEACJEACJEACJEACJEACJEACJEACJEACJEACJEAC/glQkPbPiC1IgARIgARIgARIgARIgARIgARIgARIgARIgARIgARCQOD/AZojx4DfCcWaAAAAAElFTkSuQmCC", + "text/plain": [ + "" + ] + }, + "metadata": { + "image/png": { + "height": 1000, + "width": 1000 + } + }, + "output_type": "display_data" + } + ], + "source": [ + "from IPython.display import Image, display\n", + "\n", + "# Path to your image file\n", + "image_path = 'lineage-graph.png'\n", + "\n", + "# Display the image\n", + "display(Image(filename=image_path,width=1000, height=1000))" + ] + }, + { + "cell_type": "markdown", + "id": "d7e23443", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "## 6. Clean up notebook {-}\n", + "\n", + "\n", + "This cell will drop the schemas have been created at beginning of this notebook, and also drop all objects live in the schemas including source data tables, feature views, datasets, and models.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "dee533e4", + "metadata": {}, + "outputs": [], + "source": [ + "session.sql(f\"DROP SCHEMA IF EXISTS {FS_DEMO_SCHEMA}\").collect()\n", + "session.sql(f\"DROP SCHEMA IF EXISTS {MODEL_DEMO_SCHEMA}\").collect()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.18" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/snowflake/ml/lineage/notebooks/ML Lineage Workflows.pdf b/snowflake/ml/lineage/notebooks/ML Lineage Workflows.pdf new file mode 100644 index 00000000..4910f54c Binary files /dev/null and b/snowflake/ml/lineage/notebooks/ML Lineage Workflows.pdf differ diff --git a/snowflake/ml/lineage/notebooks/lineage-graph.png b/snowflake/ml/lineage/notebooks/lineage-graph.png new file mode 100644 index 00000000..feefb605 Binary files /dev/null and b/snowflake/ml/lineage/notebooks/lineage-graph.png differ diff --git a/snowflake/ml/model/_client/model/BUILD.bazel b/snowflake/ml/model/_client/model/BUILD.bazel index cd8945e4..17e6bbdf 100644 --- a/snowflake/ml/model/_client/model/BUILD.bazel +++ b/snowflake/ml/model/_client/model/BUILD.bazel @@ -11,6 +11,7 @@ py_library( "//snowflake/ml/_internal/utils:sql_identifier", "//snowflake/ml/lineage", "//snowflake/ml/model/_client/ops:model_ops", + "//snowflake/ml/model/_client/ops:service_ops", ], ) @@ -35,6 +36,7 @@ py_library( "//snowflake/ml/lineage", "//snowflake/ml/model:type_hints", "//snowflake/ml/model/_client/ops:model_ops", + "//snowflake/ml/model/_client/ops:service_ops", "//snowflake/ml/model/_model_composer/model_manifest:model_manifest_schema", ], ) @@ -49,6 +51,7 @@ py_test( "//snowflake/ml/model:type_hints", "//snowflake/ml/model/_client/ops:metadata_ops", "//snowflake/ml/model/_client/ops:model_ops", + "//snowflake/ml/model/_client/ops:service_ops", "//snowflake/ml/test_utils:mock_data_frame", "//snowflake/ml/test_utils:mock_session", ], diff --git a/snowflake/ml/model/_client/model/model_impl.py b/snowflake/ml/model/_client/model/model_impl.py index e6c11bc0..2e295467 100644 --- a/snowflake/ml/model/_client/model/model_impl.py +++ b/snowflake/ml/model/_client/model/model_impl.py @@ -5,7 +5,7 @@ from snowflake.ml._internal import telemetry from snowflake.ml._internal.utils import sql_identifier from snowflake.ml.model._client.model import model_version_impl -from snowflake.ml.model._client.ops import model_ops +from snowflake.ml.model._client.ops import model_ops, service_ops _TELEMETRY_PROJECT = "MLOps" _TELEMETRY_SUBPROJECT = "ModelManagement" @@ -19,6 +19,7 @@ class Model: """Model Object containing multiple versions. Mapping to SQL's MODEL object.""" _model_ops: model_ops.ModelOperator + _service_ops: service_ops.ServiceOperator _model_name: sql_identifier.SqlIdentifier def __init__(self) -> None: @@ -29,17 +30,23 @@ def _ref( cls, model_ops: model_ops.ModelOperator, *, + service_ops: service_ops.ServiceOperator, model_name: sql_identifier.SqlIdentifier, ) -> "Model": self: "Model" = object.__new__(cls) self._model_ops = model_ops + self._service_ops = service_ops self._model_name = model_name return self def __eq__(self, __value: object) -> bool: if not isinstance(__value, Model): return False - return self._model_ops == __value._model_ops and self._model_name == __value._model_name + return ( + self._model_ops == __value._model_ops + and self._service_ops == __value._service_ops + and self._model_name == __value._model_name + ) @property def name(self) -> str: @@ -208,6 +215,7 @@ def version(self, version_or_alias: str) -> model_version_impl.ModelVersion: return model_version_impl.ModelVersion._ref( self._model_ops, + service_ops=self._service_ops, model_name=self._model_name, version_name=version_id, ) @@ -235,6 +243,7 @@ def versions(self) -> List[model_version_impl.ModelVersion]: return [ model_version_impl.ModelVersion._ref( self._model_ops, + service_ops=self._service_ops, model_name=self._model_name, version_name=version_name, ) diff --git a/snowflake/ml/model/_client/model/model_impl_test.py b/snowflake/ml/model/_client/model/model_impl_test.py index c31b23e9..d46f981f 100644 --- a/snowflake/ml/model/_client/model/model_impl_test.py +++ b/snowflake/ml/model/_client/model/model_impl_test.py @@ -6,7 +6,7 @@ from snowflake.ml._internal.utils import sql_identifier from snowflake.ml.model._client.model import model_impl, model_version_impl -from snowflake.ml.model._client.ops import model_ops +from snowflake.ml.model._client.ops import model_ops, service_ops from snowflake.ml.test_utils import mock_session from snowflake.snowpark import Row, Session @@ -21,6 +21,11 @@ def setUp(self) -> None: database_name=sql_identifier.SqlIdentifier("TEMP"), schema_name=sql_identifier.SqlIdentifier("test", case_sensitive=True), ), + service_ops=service_ops.ServiceOperator( + self.c_session, + database_name=sql_identifier.SqlIdentifier("TEMP"), + schema_name=sql_identifier.SqlIdentifier("test", case_sensitive=True), + ), model_name=sql_identifier.SqlIdentifier("MODEL"), ) @@ -32,6 +37,7 @@ def test_version(self) -> None: with mock.patch.object(model_version_impl.ModelVersion, "_get_functions", return_value=[]): m_mv = model_version_impl.ModelVersion._ref( self.m_model._model_ops, + service_ops=self.m_model._service_ops, model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("V1"), ) @@ -61,6 +67,7 @@ def test_version_with_alias(self) -> None: with mock.patch.object(model_version_impl.ModelVersion, "_get_functions", return_value=[]): m_mv = model_version_impl.ModelVersion._ref( self.m_model._model_ops, + service_ops=self.m_model._service_ops, model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("V1"), ) @@ -100,11 +107,13 @@ def test_versions(self) -> None: with mock.patch.object(model_version_impl.ModelVersion, "_get_functions", return_value=[]): m_mv_1 = model_version_impl.ModelVersion._ref( self.m_model._model_ops, + service_ops=self.m_model._service_ops, model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("V1"), ) m_mv_2 = model_version_impl.ModelVersion._ref( self.m_model._model_ops, + service_ops=self.m_model._service_ops, model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("v1", case_sensitive=True), ) @@ -267,6 +276,7 @@ def test_default_setter(self) -> None: ): mv = model_version_impl.ModelVersion._ref( self.m_model._model_ops, + service_ops=self.m_model._service_ops, model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("V2"), ) diff --git a/snowflake/ml/model/_client/model/model_version_impl.py b/snowflake/ml/model/_client/model/model_version_impl.py index 74c61d07..e8ae6c93 100644 --- a/snowflake/ml/model/_client/model/model_version_impl.py +++ b/snowflake/ml/model/_client/model/model_version_impl.py @@ -2,7 +2,7 @@ import pathlib import tempfile import warnings -from typing import Any, Callable, Dict, List, Optional, Union +from typing import Any, Callable, Dict, List, Optional, Union, overload import pandas as pd @@ -10,7 +10,7 @@ from snowflake.ml._internal.utils import sql_identifier from snowflake.ml.lineage import lineage_node from snowflake.ml.model import type_hints as model_types -from snowflake.ml.model._client.ops import metadata_ops, model_ops +from snowflake.ml.model._client.ops import metadata_ops, model_ops, service_ops from snowflake.ml.model._model_composer import model_composer from snowflake.ml.model._model_composer.model_manifest import model_manifest_schema from snowflake.ml.model._packager.model_handlers import snowmlmodel @@ -29,6 +29,7 @@ class ModelVersion(lineage_node.LineageNode): """Model Version Object representing a specific version of the model that could be run.""" _model_ops: model_ops.ModelOperator + _service_ops: service_ops.ServiceOperator _model_name: sql_identifier.SqlIdentifier _version_name: sql_identifier.SqlIdentifier _functions: List[model_manifest_schema.ModelFunctionInfo] @@ -41,11 +42,13 @@ def _ref( cls, model_ops: model_ops.ModelOperator, *, + service_ops: service_ops.ServiceOperator, model_name: sql_identifier.SqlIdentifier, version_name: sql_identifier.SqlIdentifier, ) -> "ModelVersion": self: "ModelVersion" = object.__new__(cls) self._model_ops = model_ops + self._service_ops = service_ops self._model_name = model_name self._version_name = version_name self._functions = self._get_functions() @@ -65,6 +68,7 @@ def __eq__(self, __value: object) -> bool: return False return ( self._model_ops == __value._model_ops + and self._service_ops == __value._service_ops and self._model_name == __value._model_name and self._version_name == __value._version_name ) @@ -318,10 +322,7 @@ def show_functions(self) -> List[model_manifest_schema.ModelFunctionInfo]: """ return self._functions - @telemetry.send_api_usage_telemetry( - project=_TELEMETRY_PROJECT, - subproject=_TELEMETRY_SUBPROJECT, - ) + @overload def run( self, X: Union[pd.DataFrame, dataframe.DataFrame], @@ -339,6 +340,53 @@ def run( partition_column: The partition column name to partition by. strict_input_validation: Enable stricter validation for the input data. This will result value range based type validation to make sure your input data won't overflow when providing to the model. + """ + ... + + @overload + def run( + self, + X: Union[pd.DataFrame, dataframe.DataFrame], + *, + service_name: str, + function_name: Optional[str] = None, + strict_input_validation: bool = False, + ) -> Union[pd.DataFrame, dataframe.DataFrame]: + """Invoke a method in a model version object via a service. + + Args: + X: The input data, which could be a pandas DataFrame or Snowpark DataFrame. + service_name: The service name. + function_name: The function name to run. It is the name used to call a function in SQL. + strict_input_validation: Enable stricter validation for the input data. This will result value range based + type validation to make sure your input data won't overflow when providing to the model. + """ + ... + + @telemetry.send_api_usage_telemetry( + project=_TELEMETRY_PROJECT, + subproject=_TELEMETRY_SUBPROJECT, + func_params_to_log=["function_name", "service_name"], + ) + def run( + self, + X: Union[pd.DataFrame, "dataframe.DataFrame"], + *, + service_name: Optional[str] = None, + function_name: Optional[str] = None, + partition_column: Optional[str] = None, + strict_input_validation: bool = False, + ) -> Union[pd.DataFrame, "dataframe.DataFrame"]: + """Invoke a method in a model version object via the warehouse or a service. + + Args: + X: The input data, which could be a pandas DataFrame or Snowpark DataFrame. + service_name: The service name. If None, the function is invoked via the warehouse. Otherwise, the function + is invoked via the given service. + function_name: The function name to run. It is the name used to call a function in SQL. + partition_column: The partition column name to partition by. + strict_input_validation: Enable stricter validation for the input data. This will result value range based + type validation to make sure your input data won't overflow when providing to the model. Raises: ValueError: When no method with the corresponding name is available. @@ -375,23 +423,37 @@ def run( elif len(functions) != 1: raise ValueError( f"There are more than 1 target methods available in the model {self.fully_qualified_model_name}" - f" version {self.version_name}. Please specify a `method_name` when calling the `run` method." + f" version {self.version_name}. Please specify a `function_name` when calling the `run` method." ) else: target_function_info = functions[0] - return self._model_ops.invoke_method( - method_name=sql_identifier.SqlIdentifier(target_function_info["name"]), - method_function_type=target_function_info["target_method_function_type"], - signature=target_function_info["signature"], - X=X, - database_name=None, - schema_name=None, - model_name=self._model_name, - version_name=self._version_name, - strict_input_validation=strict_input_validation, - partition_column=partition_column, - statement_params=statement_params, - ) + + if service_name: + return self._model_ops.invoke_method( + method_name=sql_identifier.SqlIdentifier(target_function_info["name"]), + signature=target_function_info["signature"], + X=X, + database_name=None, + schema_name=None, + service_name=sql_identifier.SqlIdentifier(service_name), + strict_input_validation=strict_input_validation, + statement_params=statement_params, + ) + else: + return self._model_ops.invoke_method( + method_name=sql_identifier.SqlIdentifier(target_function_info["name"]), + method_function_type=target_function_info["target_method_function_type"], + signature=target_function_info["signature"], + X=X, + database_name=None, + schema_name=None, + model_name=self._model_name, + version_name=self._version_name, + strict_input_validation=strict_input_validation, + partition_column=partition_column, + statement_params=statement_params, + is_partitioned=target_function_info["is_partitioned"], + ) @telemetry.send_api_usage_telemetry( project=_TELEMETRY_PROJECT, subproject=_TELEMETRY_SUBPROJECT, func_params_to_log=["export_mode"] @@ -525,9 +587,98 @@ def _load_from_lineage_node(session: Session, name: str, version: str) -> "Model database_name=database_name_id, schema_name=schema_name_id, ), + service_ops=service_ops.ServiceOperator( + session, + database_name=database_name_id, + schema_name=schema_name_id, + ), model_name=model_name_id, version_name=sql_identifier.SqlIdentifier(version), ) + @telemetry.send_api_usage_telemetry( + project=_TELEMETRY_PROJECT, + subproject=_TELEMETRY_SUBPROJECT, + func_params_to_log=[ + "service_name", + "image_build_compute_pool", + "service_compute_pool", + "image_repo_database", + "image_repo_schema", + "image_repo", + "image_name", + "gpu_requests", + ], + ) + def create_service( + self, + *, + service_name: str, + image_build_compute_pool: Optional[str] = None, + service_compute_pool: str, + image_repo: str, + image_name: Optional[str] = None, + ingress_enabled: bool = False, + min_instances: int = 1, + max_instances: int = 1, + gpu_requests: Optional[str] = None, + force_rebuild: bool = False, + build_external_access_integration: str, + ) -> str: + """Create an inference service with the given spec. + + Args: + service_name: The name of the service, can be fully qualified. If not fully qualified, the database or + schema of the model will be used. + image_build_compute_pool: The name of the compute pool used to build the model inference image. Use + the service compute pool if None. + service_compute_pool: The name of the compute pool used to run the inference service. + image_repo: The name of the image repository, can be fully qualified. If not fully qualified, the database + or schema of the model will be used. + image_name: The name of the model inference image. Use a generated name if None. + ingress_enabled: Whether to enable ingress. + min_instances: The minimum number of inference service instances to run. + max_instances: The maximum number of inference service instances to run. + gpu_requests: The gpu limit for GPU based inference. Can be integer, fractional or string values. Use CPU + if None. + force_rebuild: Whether to force a model inference image rebuild. + build_external_access_integration: The external access integration for image build. + + Returns: + The service name. + """ + statement_params = telemetry.get_statement_params( + project=_TELEMETRY_PROJECT, + subproject=_TELEMETRY_SUBPROJECT, + ) + service_db_id, service_schema_id, service_id = sql_identifier.parse_fully_qualified_name(service_name) + image_repo_db_id, image_repo_schema_id, image_repo_id = sql_identifier.parse_fully_qualified_name(image_repo) + return self._service_ops.create_service( + database_name=None, + schema_name=None, + model_name=self._model_name, + version_name=self._version_name, + service_database_name=service_db_id, + service_schema_name=service_schema_id, + service_name=service_id, + image_build_compute_pool_name=( + sql_identifier.SqlIdentifier(image_build_compute_pool) + if image_build_compute_pool + else sql_identifier.SqlIdentifier(service_compute_pool) + ), + service_compute_pool_name=sql_identifier.SqlIdentifier(service_compute_pool), + image_repo_database_name=image_repo_db_id, + image_repo_schema_name=image_repo_schema_id, + image_repo_name=image_repo_id, + image_name=sql_identifier.SqlIdentifier(image_name) if image_name else None, + ingress_enabled=ingress_enabled, + min_instances=min_instances, + max_instances=max_instances, + gpu_requests=gpu_requests, + force_rebuild=force_rebuild, + build_external_access_integration=sql_identifier.SqlIdentifier(build_external_access_integration), + statement_params=statement_params, + ) + lineage_node.DOMAIN_LINEAGE_REGISTRY["model"] = ModelVersion diff --git a/snowflake/ml/model/_client/model/model_version_impl_test.py b/snowflake/ml/model/_client/model/model_version_impl_test.py index 9937b68b..9b4e449e 100644 --- a/snowflake/ml/model/_client/model/model_version_impl_test.py +++ b/snowflake/ml/model/_client/model/model_version_impl_test.py @@ -9,7 +9,7 @@ from snowflake.ml._internal.utils import sql_identifier from snowflake.ml.model import model_signature, type_hints as model_types from snowflake.ml.model._client.model import model_version_impl -from snowflake.ml.model._client.ops import metadata_ops, model_ops +from snowflake.ml.model._client.ops import metadata_ops, model_ops, service_ops from snowflake.ml.model._model_composer import model_composer from snowflake.ml.model._model_composer.model_manifest import model_manifest_schema from snowflake.ml.test_utils import mock_data_frame, mock_session @@ -28,6 +28,16 @@ ], outputs=[model_signature.FeatureSpec(name="output", dtype=model_signature.DataType.FLOAT)], ), + "explain_table": model_signature.ModelSignature( + inputs=[ + model_signature.FeatureSpec(dtype=model_signature.DataType.FLOAT, name="input1"), + model_signature.FeatureSpec(dtype=model_signature.DataType.FLOAT, name="input2"), + ], + outputs=[ + model_signature.FeatureSpec(name="output1", dtype=model_signature.DataType.FLOAT), + model_signature.FeatureSpec(name="output2", dtype=model_signature.DataType.FLOAT), + ], + ), } @@ -42,6 +52,11 @@ def setUp(self) -> None: database_name=sql_identifier.SqlIdentifier("TEMP"), schema_name=sql_identifier.SqlIdentifier("test", case_sensitive=True), ), + service_ops=service_ops.ServiceOperator( + self.c_session, + database_name=sql_identifier.SqlIdentifier("TEMP"), + schema_name=sql_identifier.SqlIdentifier("test", case_sensitive=True), + ), model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("v1", case_sensitive=True), ) @@ -54,6 +69,11 @@ def test_ref(self) -> None: database_name=sql_identifier.SqlIdentifier("TEMP"), schema_name=sql_identifier.SqlIdentifier("test", case_sensitive=True), ), + service_ops=service_ops.ServiceOperator( + self.c_session, + database_name=sql_identifier.SqlIdentifier("TEMP"), + schema_name=sql_identifier.SqlIdentifier("test", case_sensitive=True), + ), model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("v1", case_sensitive=True), ) @@ -212,6 +232,7 @@ def test_run(self) -> None: "target_method": "predict", "target_method_function_type": "FUNCTION", "signature": _DUMMY_SIG["predict"], + "is_partitioned": False, } ), model_manifest_schema.ModelFunctionInfo( @@ -220,6 +241,7 @@ def test_run(self) -> None: "target_method": "__call__", "target_method_function_type": "FUNCTION", "signature": _DUMMY_SIG["predict"], + "is_partitioned": False, } ), ] @@ -244,6 +266,7 @@ def test_run(self) -> None: strict_input_validation=False, partition_column=None, statement_params=mock.ANY, + is_partitioned=False, ) with mock.patch.object(self.m_mv._model_ops, "invoke_method", return_value=m_df) as mock_invoke_method: @@ -260,6 +283,7 @@ def test_run(self) -> None: strict_input_validation=False, partition_column=None, statement_params=mock.ANY, + is_partitioned=False, ) def test_run_without_method_name(self) -> None: @@ -271,6 +295,7 @@ def test_run_without_method_name(self) -> None: "target_method": "predict", "target_method_function_type": "FUNCTION", "signature": _DUMMY_SIG["predict"], + "is_partitioned": False, } ), ] @@ -291,6 +316,7 @@ def test_run_without_method_name(self) -> None: strict_input_validation=False, partition_column=None, statement_params=mock.ANY, + is_partitioned=False, ) def test_run_strict(self) -> None: @@ -302,6 +328,7 @@ def test_run_strict(self) -> None: "target_method": "predict", "target_method_function_type": "FUNCTION", "signature": _DUMMY_SIG["predict"], + "is_partitioned": False, } ), ] @@ -322,6 +349,7 @@ def test_run_strict(self) -> None: version_name=sql_identifier.SqlIdentifier("v1", case_sensitive=True), partition_column=None, statement_params=mock.ANY, + is_partitioned=False, ) def test_run_table_function_method(self) -> None: @@ -333,6 +361,7 @@ def test_run_table_function_method(self) -> None: "target_method": "predict_table", "target_method_function_type": "TABLE_FUNCTION", "signature": _DUMMY_SIG["predict_table"], + "is_partitioned": True, } ), model_manifest_schema.ModelFunctionInfo( @@ -341,6 +370,7 @@ def test_run_table_function_method(self) -> None: "target_method": "__call__", "target_method_function_type": "TABLE_FUNCTION", "signature": _DUMMY_SIG["predict_table"], + "is_partitioned": True, } ), ] @@ -360,6 +390,7 @@ def test_run_table_function_method(self) -> None: strict_input_validation=False, partition_column=None, statement_params=mock.ANY, + is_partitioned=True, ) with mock.patch.object(self.m_mv._model_ops, "invoke_method", return_value=m_df) as mock_invoke_method: @@ -376,6 +407,77 @@ def test_run_table_function_method(self) -> None: strict_input_validation=False, partition_column="PARTITION_COLUMN", statement_params=mock.ANY, + is_partitioned=True, + ) + + def test_run_table_function_method_no_partition(self) -> None: + m_df = mock_data_frame.MockDataFrame() + m_methods = [ + model_manifest_schema.ModelFunctionInfo( + { + "name": '"predict_table"', + "target_method": "predict_table", + "target_method_function_type": "TABLE_FUNCTION", + "signature": _DUMMY_SIG["predict_table"], + "is_partitioned": True, + } + ), + model_manifest_schema.ModelFunctionInfo( + { + "name": '"explain_table"', + "target_method": "explain_table", + "target_method_function_type": "TABLE_FUNCTION", + "signature": _DUMMY_SIG["explain_table"], + "is_partitioned": False, + } + ), + ] + self.m_mv._functions = m_methods + + with mock.patch.object(self.m_mv._model_ops, "invoke_method", return_value=m_df) as mock_invoke_method: + self.m_mv.run(m_df, function_name='"explain_table"') + mock_invoke_method.assert_called_once_with( + method_name='"explain_table"', + method_function_type="TABLE_FUNCTION", + signature=_DUMMY_SIG["explain_table"], + X=m_df, + database_name=None, + schema_name=None, + model_name=sql_identifier.SqlIdentifier("MODEL"), + version_name=sql_identifier.SqlIdentifier("v1", case_sensitive=True), + strict_input_validation=False, + partition_column=None, + statement_params=mock.ANY, + is_partitioned=False, + ) + + def test_run_service(self) -> None: + m_df = mock_data_frame.MockDataFrame() + m_methods = [ + model_manifest_schema.ModelFunctionInfo( + { + "name": '"predict"', + "target_method": "predict", + "target_method_function_type": "FUNCTION", + "signature": _DUMMY_SIG["predict"], + "is_partitioned": False, + } + ), + ] + + self.m_mv._functions = m_methods + + with mock.patch.object(self.m_mv._model_ops, "invoke_method", return_value=m_df) as mock_invoke_method: + self.m_mv.run(m_df, service_name="SERVICE", function_name='"predict"') + mock_invoke_method.assert_called_once_with( + method_name='"predict"', + signature=_DUMMY_SIG["predict"], + X=m_df, + database_name=None, + schema_name=None, + service_name=sql_identifier.SqlIdentifier("SERVICE"), + strict_input_validation=False, + statement_params=mock.ANY, ) def test_description_getter(self) -> None: @@ -605,6 +707,43 @@ def test_unset_alias(self) -> None: statement_params=mock.ANY, ) + def test_create_service(self) -> None: + with mock.patch.object(self.m_mv._service_ops, "create_service") as mock_create_service: + self.m_mv.create_service( + service_name="SERVICE", + image_build_compute_pool="IMAGE_BUILD_COMPUTE_POOL", + service_compute_pool="SERVICE_COMPUTE_POOL", + image_repo="IMAGE_REPO", + image_name="IMAGE_NAME", + min_instances=2, + max_instances=3, + gpu_requests="GPU", + force_rebuild=True, + build_external_access_integration="EAI", + ) + mock_create_service.assert_called_once_with( + database_name=None, + schema_name=None, + model_name=sql_identifier.SqlIdentifier(self.m_mv.model_name), + version_name=sql_identifier.SqlIdentifier(self.m_mv.version_name), + service_database_name=None, + service_schema_name=None, + service_name=sql_identifier.SqlIdentifier("SERVICE"), + image_build_compute_pool_name=sql_identifier.SqlIdentifier("IMAGE_BUILD_COMPUTE_POOL"), + service_compute_pool_name=sql_identifier.SqlIdentifier("SERVICE_COMPUTE_POOL"), + image_repo_database_name=None, + image_repo_schema_name=None, + image_repo_name=sql_identifier.SqlIdentifier("IMAGE_REPO"), + image_name=sql_identifier.SqlIdentifier("IMAGE_NAME"), + ingress_enabled=False, + min_instances=2, + max_instances=3, + gpu_requests=sql_identifier.SqlIdentifier("GPU"), + force_rebuild=True, + build_external_access_integration=sql_identifier.SqlIdentifier("EAI"), + statement_params=mock.ANY, + ) + if __name__ == "__main__": absltest.main() diff --git a/snowflake/ml/model/_client/ops/BUILD.bazel b/snowflake/ml/model/_client/ops/BUILD.bazel index b007d67a..af02b5e3 100644 --- a/snowflake/ml/model/_client/ops/BUILD.bazel +++ b/snowflake/ml/model/_client/ops/BUILD.bazel @@ -17,6 +17,7 @@ py_library( "//snowflake/ml/model:type_hints", "//snowflake/ml/model/_client/sql:model", "//snowflake/ml/model/_client/sql:model_version", + "//snowflake/ml/model/_client/sql:service", "//snowflake/ml/model/_client/sql:stage", "//snowflake/ml/model/_client/sql:tag", "//snowflake/ml/model/_model_composer:model_composer", @@ -63,3 +64,14 @@ py_test( "//snowflake/ml/test_utils:mock_session", ], ) + +py_library( + name = "service_ops", + srcs = ["service_ops.py"], + deps = [ + "//snowflake/ml/_internal/utils:sql_identifier", + "//snowflake/ml/model/_client/service:model_deployment_spec", + "//snowflake/ml/model/_client/sql:service", + "//snowflake/ml/model/_client/sql:stage", + ], +) diff --git a/snowflake/ml/model/_client/ops/model_ops.py b/snowflake/ml/model/_client/ops/model_ops.py index 5874f767..67357b52 100644 --- a/snowflake/ml/model/_client/ops/model_ops.py +++ b/snowflake/ml/model/_client/ops/model_ops.py @@ -2,7 +2,7 @@ import pathlib import tempfile import warnings -from typing import Any, Dict, List, Literal, Optional, Union, cast +from typing import Any, Dict, List, Literal, Optional, Union, cast, overload import yaml @@ -12,6 +12,7 @@ from snowflake.ml.model._client.sql import ( model as model_sql, model_version as model_version_sql, + service as service_sql, stage as stage_sql, tag as tag_sql, ) @@ -21,7 +22,7 @@ model_manifest_schema, ) from snowflake.ml.model._packager.model_env import model_env -from snowflake.ml.model._packager.model_meta import model_meta +from snowflake.ml.model._packager.model_meta import model_meta, model_meta_schema from snowflake.ml.model._packager.model_runtime import model_runtime from snowflake.ml.model._signatures import snowpark_handler from snowflake.snowpark import dataframe, row, session @@ -60,6 +61,11 @@ def __init__( database_name=database_name, schema_name=schema_name, ) + self._service_client = service_sql.ServiceSQLClient( + session, + database_name=database_name, + schema_name=schema_name, + ) self._metadata_ops = metadata_ops.MetadataOperator( session, database_name=database_name, @@ -597,16 +603,38 @@ def get_functions( function_names, list(signatures.keys()) ) - return [ - model_manifest_schema.ModelFunctionInfo( - name=function_name.identifier(), - target_method=function_name_mapping[function_name], - target_method_function_type=function_type, - signature=model_signature.ModelSignature.from_dict(signatures[function_name_mapping[function_name]]), + model_func_info = [] + + for function_name, function_type in function_names_and_types: + + target_method = function_name_mapping[function_name] + + is_partitioned = False + if function_type == model_manifest_schema.ModelMethodFunctionTypes.TABLE_FUNCTION.value: + # better to set default True here because worse case it will be slow but not error out + is_partitioned = ( + ( + model_spec["function_properties"] + .get(target_method, {}) + .get(model_meta_schema.FunctionProperties.PARTITIONED.value, True) + ) + if "function_properties" in model_spec + else True + ) + + model_func_info.append( + model_manifest_schema.ModelFunctionInfo( + name=function_name.identifier(), + target_method=target_method, + target_method_function_type=function_type, + signature=model_signature.ModelSignature.from_dict(signatures[target_method]), + is_partitioned=is_partitioned, + ) ) - for function_name, function_type in function_names_and_types - ] + return model_func_info + + @overload def invoke_method( self, *, @@ -621,6 +649,41 @@ def invoke_method( strict_input_validation: bool = False, partition_column: Optional[sql_identifier.SqlIdentifier] = None, statement_params: Optional[Dict[str, str]] = None, + is_partitioned: Optional[bool] = None, + ) -> Union[type_hints.SupportedDataType, dataframe.DataFrame]: + ... + + @overload + def invoke_method( + self, + *, + method_name: sql_identifier.SqlIdentifier, + signature: model_signature.ModelSignature, + X: Union[type_hints.SupportedDataType, dataframe.DataFrame], + database_name: Optional[sql_identifier.SqlIdentifier], + schema_name: Optional[sql_identifier.SqlIdentifier], + service_name: sql_identifier.SqlIdentifier, + strict_input_validation: bool = False, + statement_params: Optional[Dict[str, str]] = None, + ) -> Union[type_hints.SupportedDataType, dataframe.DataFrame]: + ... + + def invoke_method( + self, + *, + method_name: sql_identifier.SqlIdentifier, + method_function_type: Optional[str] = None, + signature: model_signature.ModelSignature, + X: Union[type_hints.SupportedDataType, dataframe.DataFrame], + database_name: Optional[sql_identifier.SqlIdentifier], + schema_name: Optional[sql_identifier.SqlIdentifier], + model_name: Optional[sql_identifier.SqlIdentifier] = None, + version_name: Optional[sql_identifier.SqlIdentifier] = None, + service_name: Optional[sql_identifier.SqlIdentifier] = None, + strict_input_validation: bool = False, + partition_column: Optional[sql_identifier.SqlIdentifier] = None, + statement_params: Optional[Dict[str, str]] = None, + is_partitioned: Optional[bool] = None, ) -> Union[type_hints.SupportedDataType, dataframe.DataFrame]: identifier_rule = model_signature.SnowparkIdentifierRule.INFERRED @@ -657,31 +720,46 @@ def invoke_method( if output_name in original_cols: original_cols.remove(output_name) - if method_function_type == model_manifest_schema.ModelMethodFunctionTypes.FUNCTION.value: - df_res = self._model_version_client.invoke_function_method( + if service_name: + df_res = self._service_client.invoke_function_method( method_name=method_name, input_df=s_df, input_args=input_args, returns=returns, database_name=database_name, schema_name=schema_name, - model_name=model_name, - version_name=version_name, - statement_params=statement_params, - ) - elif method_function_type == model_manifest_schema.ModelMethodFunctionTypes.TABLE_FUNCTION.value: - df_res = self._model_version_client.invoke_table_function_method( - method_name=method_name, - input_df=s_df, - input_args=input_args, - partition_column=partition_column, - returns=returns, - database_name=database_name, - schema_name=schema_name, - model_name=model_name, - version_name=version_name, + service_name=service_name, statement_params=statement_params, ) + else: + assert model_name is not None + assert version_name is not None + if method_function_type == model_manifest_schema.ModelMethodFunctionTypes.FUNCTION.value: + df_res = self._model_version_client.invoke_function_method( + method_name=method_name, + input_df=s_df, + input_args=input_args, + returns=returns, + database_name=database_name, + schema_name=schema_name, + model_name=model_name, + version_name=version_name, + statement_params=statement_params, + ) + elif method_function_type == model_manifest_schema.ModelMethodFunctionTypes.TABLE_FUNCTION.value: + df_res = self._model_version_client.invoke_table_function_method( + method_name=method_name, + input_df=s_df, + input_args=input_args, + partition_column=partition_column, + returns=returns, + database_name=database_name, + schema_name=schema_name, + model_name=model_name, + version_name=version_name, + statement_params=statement_params, + is_partitioned=is_partitioned or False, + ) if keep_order: # if it's a partitioned table function, _ID will be null and we won't be able to sort. diff --git a/snowflake/ml/model/_client/ops/model_ops_test.py b/snowflake/ml/model/_client/ops/model_ops_test.py index 4662f534..c6ad955b 100644 --- a/snowflake/ml/model/_client/ops/model_ops_test.py +++ b/snowflake/ml/model/_client/ops/model_ops_test.py @@ -862,6 +862,7 @@ def test_invoke_method_table_function(self) -> None: model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("V1"), statement_params=self.m_statement_params, + is_partitioned=True, ) mock_convert_from_df.assert_called_once_with( self.c_session, mock.ANY, keep_order=True, features=m_sig.inputs @@ -877,6 +878,7 @@ def test_invoke_method_table_function(self) -> None: model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("V1"), statement_params=self.m_statement_params, + is_partitioned=True, ) mock_convert_to_df.assert_called_once_with(m_df, features=m_sig.outputs) @@ -907,6 +909,7 @@ def test_invoke_method_table_function_partition_column(self) -> None: version_name=sql_identifier.SqlIdentifier("V1"), partition_column=partition_column, statement_params=self.m_statement_params, + is_partitioned=True, ) mock_convert_from_df.assert_called_once_with( self.c_session, mock.ANY, keep_order=True, features=m_sig.inputs @@ -922,9 +925,47 @@ def test_invoke_method_table_function_partition_column(self) -> None: model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("V1"), statement_params=self.m_statement_params, + is_partitioned=True, ) mock_convert_to_df.assert_called_once_with(m_df, features=m_sig.outputs) + def test_invoke_method_service(self) -> None: + m_sig = _DUMMY_SIG["predict"] + m_df = mock_data_frame.MockDataFrame() + m_df.__setattr__("columns", ["COL1", "COL2"]) + with mock.patch.object( + snowpark_handler.SnowparkDataFrameHandler, "convert_from_df" + ) as mock_convert_from_df, mock.patch.object( + model_signature, "_validate_snowpark_data", return_value=model_signature.SnowparkIdentifierRule.NORMALIZED + ) as mock_validate_snowpark_data, mock.patch.object( + self.m_ops._service_client, "invoke_function_method", return_value=m_df + ) as mock_invoke_method, mock.patch.object( + snowpark_handler.SnowparkDataFrameHandler, "convert_to_df" + ) as mock_convert_to_df: + self.m_ops.invoke_method( + method_name=sql_identifier.SqlIdentifier("PREDICT"), + signature=m_sig, + X=cast(DataFrame, m_df), + database_name=sql_identifier.SqlIdentifier("TEMP"), + schema_name=sql_identifier.SqlIdentifier("test", case_sensitive=True), + service_name=sql_identifier.SqlIdentifier("SERVICE"), + statement_params=self.m_statement_params, + ) + mock_convert_from_df.assert_not_called() + mock_validate_snowpark_data.assert_called_once_with(m_df, m_sig.inputs, strict=False) + + mock_invoke_method.assert_called_once_with( + method_name=sql_identifier.SqlIdentifier("PREDICT"), + input_df=m_df, + input_args=["INPUT"], + returns=[("output", spt.FloatType(), "OUTPUT")], + database_name=sql_identifier.SqlIdentifier("TEMP"), + schema_name=sql_identifier.SqlIdentifier("test", case_sensitive=True), + service_name=sql_identifier.SqlIdentifier("SERVICE"), + statement_params=self.m_statement_params, + ) + mock_convert_to_df.assert_not_called() + def test_get_comment_1(self) -> None: m_list_res = [ Row( diff --git a/snowflake/ml/model/_client/ops/service_ops.py b/snowflake/ml/model/_client/ops/service_ops.py new file mode 100644 index 00000000..1010e575 --- /dev/null +++ b/snowflake/ml/model/_client/ops/service_ops.py @@ -0,0 +1,121 @@ +import pathlib +import tempfile +from typing import Any, Dict, Optional + +from snowflake.ml._internal import file_utils +from snowflake.ml._internal.utils import sql_identifier +from snowflake.ml.model._client.service import model_deployment_spec +from snowflake.ml.model._client.sql import service as service_sql, stage as stage_sql +from snowflake.snowpark import session +from snowflake.snowpark._internal import utils as snowpark_utils + + +class ServiceOperator: + """Service operator for container services logic.""" + + def __init__( + self, + session: session.Session, + *, + database_name: sql_identifier.SqlIdentifier, + schema_name: sql_identifier.SqlIdentifier, + ) -> None: + self._session = session + self._database_name = database_name + self._schema_name = schema_name + self._workspace = tempfile.TemporaryDirectory() + self._service_client = service_sql.ServiceSQLClient( + session, + database_name=database_name, + schema_name=schema_name, + ) + self._stage_client = stage_sql.StageSQLClient( + session, + database_name=database_name, + schema_name=schema_name, + ) + self._model_deployment_spec = model_deployment_spec.ModelDeploymentSpec( + workspace_path=pathlib.Path(self._workspace.name) + ) + + def __eq__(self, __value: object) -> bool: + if not isinstance(__value, ServiceOperator): + return False + return self._service_client == __value._service_client + + @property + def workspace_path(self) -> pathlib.Path: + return pathlib.Path(self._workspace.name) + + def create_service( + self, + *, + database_name: Optional[sql_identifier.SqlIdentifier], + schema_name: Optional[sql_identifier.SqlIdentifier], + model_name: sql_identifier.SqlIdentifier, + version_name: sql_identifier.SqlIdentifier, + service_database_name: Optional[sql_identifier.SqlIdentifier], + service_schema_name: Optional[sql_identifier.SqlIdentifier], + service_name: sql_identifier.SqlIdentifier, + image_build_compute_pool_name: sql_identifier.SqlIdentifier, + service_compute_pool_name: sql_identifier.SqlIdentifier, + image_repo_database_name: Optional[sql_identifier.SqlIdentifier], + image_repo_schema_name: Optional[sql_identifier.SqlIdentifier], + image_repo_name: sql_identifier.SqlIdentifier, + image_name: Optional[sql_identifier.SqlIdentifier], + ingress_enabled: bool, + min_instances: int, + max_instances: int, + gpu_requests: Optional[str], + force_rebuild: bool, + build_external_access_integration: sql_identifier.SqlIdentifier, + statement_params: Optional[Dict[str, Any]] = None, + ) -> str: + # create a temp stage + stage_name = sql_identifier.SqlIdentifier( + snowpark_utils.random_name_for_temp_object(snowpark_utils.TempObjectType.STAGE) + ) + self._stage_client.create_tmp_stage( + database_name=database_name, + schema_name=schema_name, + stage_name=stage_name, + statement_params=statement_params, + ) + stage_path = self._stage_client.fully_qualified_object_name(database_name, schema_name, stage_name) + + self._model_deployment_spec.save( + database_name=database_name or self._database_name, + schema_name=schema_name or self._schema_name, + model_name=model_name, + version_name=version_name, + service_database_name=service_database_name, + service_schema_name=service_schema_name, + service_name=service_name, + image_build_compute_pool_name=image_build_compute_pool_name, + service_compute_pool_name=service_compute_pool_name, + image_repo_database_name=image_repo_database_name, + image_repo_schema_name=image_repo_schema_name, + image_repo_name=image_repo_name, + image_name=image_name, + ingress_enabled=ingress_enabled, + min_instances=min_instances, + max_instances=max_instances, + gpu=gpu_requests, + force_rebuild=force_rebuild, + external_access_integration=build_external_access_integration, + ) + file_utils.upload_directory_to_stage( + self._session, + local_path=self.workspace_path, + stage_path=pathlib.PurePosixPath(stage_path), + statement_params=statement_params, + ) + + # deploy the model service + self._service_client.deploy_model( + stage_path=stage_path, + model_deployment_spec_file_rel_path=model_deployment_spec.ModelDeploymentSpec.DEPLOY_SPEC_FILE_REL_PATH, + statement_params=statement_params, + ) + + return service_name diff --git a/snowflake/ml/model/_client/service/BUILD.bazel b/snowflake/ml/model/_client/service/BUILD.bazel new file mode 100644 index 00000000..953408b3 --- /dev/null +++ b/snowflake/ml/model/_client/service/BUILD.bazel @@ -0,0 +1,20 @@ +load("//bazel:py_rules.bzl", "py_library") + +package(default_visibility = [ + "//bazel:snowml_public_common", + "//snowflake/ml/model/_client/ops:__pkg__", +]) + +py_library( + name = "model_deployment_spec_schema", + srcs = ["model_deployment_spec_schema.py"], + deps = [], +) + +py_library( + name = "model_deployment_spec", + srcs = ["model_deployment_spec.py"], + deps = [ + ":model_deployment_spec_schema", + ], +) diff --git a/snowflake/ml/model/_client/service/model_deployment_spec.py b/snowflake/ml/model/_client/service/model_deployment_spec.py new file mode 100644 index 00000000..b3d67b28 --- /dev/null +++ b/snowflake/ml/model/_client/service/model_deployment_spec.py @@ -0,0 +1,95 @@ +import pathlib +from typing import Optional + +import yaml + +from snowflake.ml._internal.utils import identifier, sql_identifier +from snowflake.ml.model._client.service import model_deployment_spec_schema + + +class ModelDeploymentSpec: + """Class to construct deploy.yml file for Model container services deployment. + + Attributes: + workspace_path: A local path where model related files should be dumped to. + """ + + DEPLOY_SPEC_FILE_REL_PATH = "deploy.yml" + + def __init__(self, workspace_path: pathlib.Path) -> None: + self.workspace_path = workspace_path + + def save( + self, + *, + database_name: sql_identifier.SqlIdentifier, + schema_name: sql_identifier.SqlIdentifier, + model_name: sql_identifier.SqlIdentifier, + version_name: sql_identifier.SqlIdentifier, + service_database_name: Optional[sql_identifier.SqlIdentifier], + service_schema_name: Optional[sql_identifier.SqlIdentifier], + service_name: sql_identifier.SqlIdentifier, + image_build_compute_pool_name: sql_identifier.SqlIdentifier, + service_compute_pool_name: sql_identifier.SqlIdentifier, + image_repo_database_name: Optional[sql_identifier.SqlIdentifier], + image_repo_schema_name: Optional[sql_identifier.SqlIdentifier], + image_repo_name: sql_identifier.SqlIdentifier, + image_name: Optional[sql_identifier.SqlIdentifier], + ingress_enabled: bool, + min_instances: int, + max_instances: int, + gpu: Optional[str], + force_rebuild: bool, + external_access_integration: sql_identifier.SqlIdentifier, + ) -> None: + # create the deployment spec + # models spec + fq_model_name = identifier.get_schema_level_object_identifier( + database_name.identifier(), schema_name.identifier(), model_name.identifier() + ) + model_dict = model_deployment_spec_schema.ModelDict(name=fq_model_name, version=version_name.identifier()) + + # image_build spec + saved_image_repo_database = image_repo_database_name or database_name + saved_image_repo_schema = image_repo_schema_name or schema_name + fq_image_repo_name = identifier.get_schema_level_object_identifier( + saved_image_repo_database.identifier(), saved_image_repo_schema.identifier(), image_repo_name.identifier() + ) + image_build_dict = model_deployment_spec_schema.ImageBuildDict( + compute_pool=image_build_compute_pool_name.identifier(), + image_repo=fq_image_repo_name, + force_rebuild=force_rebuild, + external_access_integrations=[external_access_integration.identifier()], + ) + if image_name: + image_build_dict["image_name"] = image_name.identifier() + + # service spec + saved_service_database = service_database_name or database_name + saved_service_schema = service_schema_name or schema_name + fq_service_name = identifier.get_schema_level_object_identifier( + saved_service_database.identifier(), saved_service_schema.identifier(), service_name.identifier() + ) + service_dict = model_deployment_spec_schema.ServiceDict( + name=fq_service_name, + compute_pool=service_compute_pool_name.identifier(), + ingress_enabled=ingress_enabled, + min_instances=min_instances, + max_instances=max_instances, + ) + if gpu: + service_dict["gpu"] = gpu + + # model deployment spec + model_deployment_spec_dict = model_deployment_spec_schema.ModelDeploymentSpecDict( + models=[model_dict], + image_build=image_build_dict, + service=service_dict, + ) + + # save the yaml + file_path = self.workspace_path / self.DEPLOY_SPEC_FILE_REL_PATH + with file_path.open("w", encoding="utf-8") as f: + # Anchors are not supported in the server, avoid that. + yaml.SafeDumper.ignore_aliases = lambda *args: True # type: ignore[method-assign] + yaml.safe_dump(model_deployment_spec_dict, f) diff --git a/snowflake/ml/model/_client/service/model_deployment_spec_schema.py b/snowflake/ml/model/_client/service/model_deployment_spec_schema.py new file mode 100644 index 00000000..d77d9d98 --- /dev/null +++ b/snowflake/ml/model/_client/service/model_deployment_spec_schema.py @@ -0,0 +1,31 @@ +from typing import List, TypedDict + +from typing_extensions import NotRequired, Required + + +class ModelDict(TypedDict): + name: Required[str] + version: Required[str] + + +class ImageBuildDict(TypedDict): + compute_pool: Required[str] + image_repo: Required[str] + image_name: NotRequired[str] + force_rebuild: Required[bool] + external_access_integrations: Required[List[str]] + + +class ServiceDict(TypedDict): + name: Required[str] + compute_pool: Required[str] + ingress_enabled: Required[bool] + min_instances: Required[int] + max_instances: Required[int] + gpu: NotRequired[str] + + +class ModelDeploymentSpecDict(TypedDict): + models: Required[List[ModelDict]] + image_build: Required[ImageBuildDict] + service: Required[ServiceDict] diff --git a/snowflake/ml/model/_client/sql/BUILD.bazel b/snowflake/ml/model/_client/sql/BUILD.bazel index cbebcc0a..d012fa0b 100644 --- a/snowflake/ml/model/_client/sql/BUILD.bazel +++ b/snowflake/ml/model/_client/sql/BUILD.bazel @@ -3,6 +3,7 @@ load("//bazel:py_rules.bzl", "py_library", "py_test") package(default_visibility = [ "//bazel:snowml_public_common", "//snowflake/ml/model/_client/ops:__pkg__", + "//snowflake/ml/model/_client/service:__pkg__", ]) py_library( @@ -100,3 +101,13 @@ py_test( "//snowflake/ml/test_utils:mock_session", ], ) + +py_library( + name = "service", + srcs = ["service.py"], + deps = [ + ":_base", + "//snowflake/ml/_internal/utils:query_result_checker", + "//snowflake/ml/_internal/utils:sql_identifier", + ], +) diff --git a/snowflake/ml/model/_client/sql/model_version.py b/snowflake/ml/model/_client/sql/model_version.py index 617fc458..6af568da 100644 --- a/snowflake/ml/model/_client/sql/model_version.py +++ b/snowflake/ml/model/_client/sql/model_version.py @@ -371,6 +371,7 @@ def invoke_table_function_method( returns: List[Tuple[str, spt.DataType, sql_identifier.SqlIdentifier]], partition_column: Optional[sql_identifier.SqlIdentifier], statement_params: Optional[Dict[str, Any]] = None, + is_partitioned: bool = True, ) -> dataframe.DataFrame: with_statements = [] if len(input_df.queries["queries"]) == 1 and len(input_df.queries["post_actions"]) == 0: @@ -409,12 +410,20 @@ def invoke_table_function_method( sql = textwrap.dedent( f"""WITH {','.join(with_statements)} - SELECT *, - FROM {INTERMEDIATE_TABLE_NAME}, - TABLE({module_version_alias}!{method_name.identifier()}({args_sql}) - OVER (PARTITION BY {partition_by}))""" + SELECT *, + FROM {INTERMEDIATE_TABLE_NAME}, + TABLE({module_version_alias}!{method_name.identifier()}({args_sql}))""" ) + if is_partitioned or partition_column is not None: + sql = textwrap.dedent( + f"""WITH {','.join(with_statements)} + SELECT *, + FROM {INTERMEDIATE_TABLE_NAME}, + TABLE({module_version_alias}!{method_name.identifier()}({args_sql}) + OVER (PARTITION BY {partition_by}))""" + ) + output_df = self._session.sql(sql) # Prepare the output diff --git a/snowflake/ml/model/_client/sql/model_version_test.py b/snowflake/ml/model/_client/sql/model_version_test.py index b1baeda7..2271eb30 100644 --- a/snowflake/ml/model/_client/sql/model_version_test.py +++ b/snowflake/ml/model/_client/sql/model_version_test.py @@ -493,6 +493,51 @@ def test_invoke_function_method_2(self) -> None: statement_params=m_statement_params, ) + def test_invoke_table_function_method_no_partition_col(self) -> None: + m_statement_params = {"test": "1"} + m_df = mock_data_frame.MockDataFrame() + self.m_session.add_mock_sql( + """WITH MODEL_VERSION_ALIAS AS MODEL TEMP."test".MODEL VERSION V1 + SELECT *, + FROM TEMP."test".SNOWPARK_TEMP_TABLE_ABCDEF0123, + TABLE(MODEL_VERSION_ALIAS!EXPLAIN(COL1, COL2)) + """, + m_df, + ) + m_df.add_mock_with_columns(["OUTPUT_1"], [F.col("OUTPUT_1")]) + c_session = cast(Session, self.m_session) + mock_writer = mock.MagicMock() + m_df.__setattr__("write", mock_writer) + m_df.add_query("queries", "query_1") + m_df.add_query("queries", "query_2") + with mock.patch.object(mock_writer, "save_as_table") as mock_save_as_table, mock.patch.object( + snowpark_utils, "random_name_for_temp_object", return_value="SNOWPARK_TEMP_TABLE_ABCDEF0123" + ) as mock_random_name_for_temp_object: + model_version_sql.ModelVersionSQLClient( + c_session, + database_name=sql_identifier.SqlIdentifier("TEMP"), + schema_name=sql_identifier.SqlIdentifier("test", case_sensitive=True), + ).invoke_table_function_method( + database_name=None, + schema_name=None, + model_name=sql_identifier.SqlIdentifier("MODEL"), + version_name=sql_identifier.SqlIdentifier("V1"), + method_name=sql_identifier.SqlIdentifier("EXPLAIN"), + input_df=cast(DataFrame, m_df), + input_args=[sql_identifier.SqlIdentifier("COL1"), sql_identifier.SqlIdentifier("COL2")], + returns=[("output_1", spt.IntegerType(), sql_identifier.SqlIdentifier("OUTPUT_1"))], + partition_column=None, + statement_params=m_statement_params, + is_partitioned=False, + ) + mock_random_name_for_temp_object.assert_called_once_with(snowpark_utils.TempObjectType.TABLE) + mock_save_as_table.assert_called_once_with( + table_name='TEMP."test".SNOWPARK_TEMP_TABLE_ABCDEF0123', + mode="errorifexists", + table_type="temporary", + statement_params=m_statement_params, + ) + def test_invoke_table_function_method_partition_col(self) -> None: m_statement_params = {"test": "1"} m_df = mock_data_frame.MockDataFrame() diff --git a/snowflake/ml/model/_client/sql/service.py b/snowflake/ml/model/_client/sql/service.py new file mode 100644 index 00000000..b6acaeb8 --- /dev/null +++ b/snowflake/ml/model/_client/sql/service.py @@ -0,0 +1,129 @@ +import textwrap +from typing import Any, Dict, List, Optional, Tuple + +from snowflake.ml._internal.utils import ( + identifier, + query_result_checker, + sql_identifier, +) +from snowflake.ml.model._client.sql import _base +from snowflake.snowpark import dataframe, functions as F, types as spt +from snowflake.snowpark._internal import utils as snowpark_utils + + +class ServiceSQLClient(_base._BaseSQLClient): + def build_model_container( + self, + *, + database_name: Optional[sql_identifier.SqlIdentifier], + schema_name: Optional[sql_identifier.SqlIdentifier], + model_name: sql_identifier.SqlIdentifier, + version_name: sql_identifier.SqlIdentifier, + compute_pool_name: sql_identifier.SqlIdentifier, + image_repo_database_name: Optional[sql_identifier.SqlIdentifier], + image_repo_schema_name: Optional[sql_identifier.SqlIdentifier], + image_repo_name: sql_identifier.SqlIdentifier, + gpu: Optional[str], + force_rebuild: bool, + external_access_integration: sql_identifier.SqlIdentifier, + statement_params: Optional[Dict[str, Any]] = None, + ) -> None: + actual_image_repo_database = image_repo_database_name or self._database_name + actual_image_repo_schema = image_repo_schema_name or self._schema_name + fq_model_name = self.fully_qualified_object_name(database_name, schema_name, model_name) + fq_image_repo_name = "/" + "/".join( + [ + actual_image_repo_database.identifier(), + actual_image_repo_schema.identifier(), + image_repo_name.identifier(), + ] + ) + is_gpu = gpu is not None + query_result_checker.SqlResultValidator( + self._session, + ( + f"CALL SYSTEM$BUILD_MODEL_CONTAINER('{fq_model_name}', '{version_name}', '{compute_pool_name}'," + f" '{fq_image_repo_name}', '{is_gpu}', '{force_rebuild}', '', '{external_access_integration}')" + ), + statement_params=statement_params, + ).has_dimensions(expected_rows=1, expected_cols=1).validate() + + def deploy_model( + self, + *, + stage_path: str, + model_deployment_spec_file_rel_path: str, + statement_params: Optional[Dict[str, Any]] = None, + ) -> None: + query_result_checker.SqlResultValidator( + self._session, + f"CALL SYSTEM$DEPLOY_MODEL('@{stage_path}/{model_deployment_spec_file_rel_path}')", + statement_params=statement_params, + ).has_dimensions(expected_rows=1, expected_cols=1).validate() + + def invoke_function_method( + self, + *, + database_name: Optional[sql_identifier.SqlIdentifier], + schema_name: Optional[sql_identifier.SqlIdentifier], + service_name: sql_identifier.SqlIdentifier, + method_name: sql_identifier.SqlIdentifier, + input_df: dataframe.DataFrame, + input_args: List[sql_identifier.SqlIdentifier], + returns: List[Tuple[str, spt.DataType, sql_identifier.SqlIdentifier]], + statement_params: Optional[Dict[str, Any]] = None, + ) -> dataframe.DataFrame: + with_statements = [] + if len(input_df.queries["queries"]) == 1 and len(input_df.queries["post_actions"]) == 0: + INTERMEDIATE_TABLE_NAME = "SNOWPARK_ML_MODEL_INFERENCE_INPUT" + with_statements.append(f"{INTERMEDIATE_TABLE_NAME} AS ({input_df.queries['queries'][0]})") + else: + actual_database_name = database_name or self._database_name + actual_schema_name = schema_name or self._schema_name + tmp_table_name = snowpark_utils.random_name_for_temp_object(snowpark_utils.TempObjectType.TABLE) + INTERMEDIATE_TABLE_NAME = identifier.get_schema_level_object_identifier( + actual_database_name.identifier(), + actual_schema_name.identifier(), + tmp_table_name, + ) + input_df.write.save_as_table( + table_name=INTERMEDIATE_TABLE_NAME, + mode="errorifexists", + table_type="temporary", + statement_params=statement_params, + ) + + INTERMEDIATE_OBJ_NAME = "TMP_RESULT" + + with_sql = f"WITH {','.join(with_statements)}" if with_statements else "" + args_sql_list = [] + for input_arg_value in input_args: + args_sql_list.append(input_arg_value) + args_sql = ", ".join(args_sql_list) + + sql = textwrap.dedent( + f"""{with_sql} + SELECT *, + {service_name.identifier()}_{method_name.identifier()}({args_sql}) AS {INTERMEDIATE_OBJ_NAME} + FROM {INTERMEDIATE_TABLE_NAME}""" + ) + + output_df = self._session.sql(sql) + + # Prepare the output + output_cols = [] + output_names = [] + + for output_name, output_type, output_col_name in returns: + output_cols.append(F.col(INTERMEDIATE_OBJ_NAME)[output_name].astype(output_type)) + output_names.append(output_col_name) + + output_df = output_df.with_columns( + col_names=output_names, + values=output_cols, + ).drop(INTERMEDIATE_OBJ_NAME) + + if statement_params: + output_df._statement_params = statement_params # type: ignore[assignment] + + return output_df diff --git a/snowflake/ml/model/_model_composer/model_composer.py b/snowflake/ml/model/_model_composer/model_composer.py index 6165c0db..f80c5760 100644 --- a/snowflake/ml/model/_model_composer/model_composer.py +++ b/snowflake/ml/model/_model_composer/model_composer.py @@ -10,6 +10,7 @@ from packaging import requirements from typing_extensions import deprecated +from snowflake import snowpark from snowflake.ml._internal import env as snowml_env, env_utils, file_utils from snowflake.ml._internal.lineage import lineage_utils from snowflake.ml.data import data_source @@ -185,4 +186,6 @@ def _get_data_sources( data_sources = lineage_utils.get_data_sources(model) if not data_sources and sample_input_data is not None: data_sources = lineage_utils.get_data_sources(sample_input_data) + if not data_sources and isinstance(sample_input_data, snowpark.DataFrame): + data_sources = [data_source.DataFrameInfo(sample_input_data.queries["queries"][-1])] return data_sources diff --git a/snowflake/ml/model/_model_composer/model_manifest/BUILD.bazel b/snowflake/ml/model/_model_composer/model_manifest/BUILD.bazel index dcb2258b..e333e4c8 100644 --- a/snowflake/ml/model/_model_composer/model_manifest/BUILD.bazel +++ b/snowflake/ml/model/_model_composer/model_manifest/BUILD.bazel @@ -19,6 +19,7 @@ py_library( srcs = ["model_manifest.py"], deps = [ ":model_manifest_schema", + "//snowflake/ml/_internal:env_utils", "//snowflake/ml/model/_model_composer/model_method", "//snowflake/ml/model/_model_composer/model_method:function_generator", "//snowflake/ml/model/_packager/model_meta", @@ -42,6 +43,7 @@ py_test( ], deps = [ ":model_manifest", + "//snowflake/ml/_internal:env_utils", "//snowflake/ml/model:model_signature", "//snowflake/ml/model:type_hints", "//snowflake/ml/model/_packager/model_meta", diff --git a/snowflake/ml/model/_model_composer/model_manifest/model_manifest.py b/snowflake/ml/model/_model_composer/model_manifest/model_manifest.py index ccfa5f82..6fcc89bb 100644 --- a/snowflake/ml/model/_model_composer/model_manifest/model_manifest.py +++ b/snowflake/ml/model/_model_composer/model_manifest/model_manifest.py @@ -6,6 +6,7 @@ import yaml +from snowflake.ml._internal import env_utils from snowflake.ml.data import data_source from snowflake.ml.model import type_hints from snowflake.ml.model._model_composer.model_manifest import model_manifest_schema @@ -47,7 +48,9 @@ def save( runtime_to_use = copy.deepcopy(model_meta.runtimes["cpu"]) runtime_to_use.name = self._DEFAULT_RUNTIME_NAME runtime_to_use.imports.append(str(model_rel_path) + "/") - runtime_dict = runtime_to_use.save(self.workspace_path) + runtime_dict = runtime_to_use.save( + self.workspace_path, default_channel_override=env_utils.SNOWFLAKE_CONDA_CHANNEL_URL + ) self.function_generator = function_generator.FunctionGenerator(model_dir_rel_path=model_rel_path) self.methods: List[model_method.ModelMethod] = [] @@ -137,10 +140,15 @@ def _extract_lineage_info( if isinstance(source, data_source.DatasetInfo): result.append( model_manifest_schema.LineageSourceDict( - # Currently, we only support lineage from Dataset. type=model_manifest_schema.LineageSourceTypes.DATASET.value, entity=source.fully_qualified_name, version=source.version, ) ) + elif isinstance(source, data_source.DataFrameInfo): + result.append( + model_manifest_schema.LineageSourceDict( + type=model_manifest_schema.LineageSourceTypes.QUERY.value, entity=source.sql + ) + ) return result diff --git a/snowflake/ml/model/_model_composer/model_manifest/model_manifest_schema.py b/snowflake/ml/model/_model_composer/model_manifest/model_manifest_schema.py index 1df85a83..83aa3f60 100644 --- a/snowflake/ml/model/_model_composer/model_manifest/model_manifest_schema.py +++ b/snowflake/ml/model/_model_composer/model_manifest/model_manifest_schema.py @@ -57,12 +57,14 @@ class ModelFunctionInfo(TypedDict): target_method: actual target method name to be called. target_method_function_type: target method function type (FUNCTION or TABLE_FUNCTION). signature: The signature of the model method. + is_partitioned: Whether the function is partitioned. """ name: Required[str] target_method: Required[str] target_method_function_type: Required[str] signature: Required[model_signature.ModelSignature] + is_partitioned: Required[bool] class ModelFunctionInfoDict(TypedDict): @@ -78,6 +80,7 @@ class SnowparkMLDataDict(TypedDict): class LineageSourceTypes(enum.Enum): DATASET = "DATASET" + QUERY = "QUERY" class LineageSourceDict(TypedDict): diff --git a/snowflake/ml/model/_model_composer/model_manifest/model_manifest_test.py b/snowflake/ml/model/_model_composer/model_manifest/model_manifest_test.py index 6c24a635..7c19ca5f 100644 --- a/snowflake/ml/model/_model_composer/model_manifest/model_manifest_test.py +++ b/snowflake/ml/model/_model_composer/model_manifest/model_manifest_test.py @@ -6,6 +6,7 @@ import yaml from absl.testing import absltest +from snowflake.ml._internal import env_utils from snowflake.ml.model import model_signature, type_hints from snowflake.ml.model._model_composer.model_manifest import model_manifest from snowflake.ml.model._packager.model_meta import ( @@ -147,6 +148,10 @@ def test_model_manifest_mix(self) -> None: ), f.read(), ) + with open(pathlib.Path(workspace, "runtimes", "python_runtime", "env", "conda.yml"), encoding="utf-8") as f: + self.assertListEqual( + yaml.safe_load(f)["channels"], [env_utils.SNOWFLAKE_CONDA_CHANNEL_URL, "nodefaults"] + ) with open(pathlib.Path(workspace, "functions", "predict.py"), encoding="utf-8") as f: self.assertEqual( ( diff --git a/snowflake/ml/model/_packager/model_env/model_env.py b/snowflake/ml/model/_packager/model_env/model_env.py index 68b0d7b8..a002142d 100644 --- a/snowflake/ml/model/_packager/model_env/model_env.py +++ b/snowflake/ml/model/_packager/model_env/model_env.py @@ -363,9 +363,14 @@ def load_from_dict(self, base_dir: pathlib.Path, env_dict: model_meta_schema.Mod self.cuda_version = env_dict.get("cuda_version", None) self.snowpark_ml_version = env_dict["snowpark_ml_version"] - def save_as_dict(self, base_dir: pathlib.Path) -> model_meta_schema.ModelEnvDict: + def save_as_dict( + self, base_dir: pathlib.Path, default_channel_override: str = env_utils.SNOWFLAKE_CONDA_CHANNEL_URL + ) -> model_meta_schema.ModelEnvDict: env_utils.save_conda_env_file( - pathlib.Path(base_dir / self.conda_env_rel_path), self._conda_dependencies, self.python_version + pathlib.Path(base_dir / self.conda_env_rel_path), + self._conda_dependencies, + self.python_version, + default_channel_override=default_channel_override, ) env_utils.save_requirements_file( pathlib.Path(base_dir / self.pip_requirements_rel_path), self._pip_requirements diff --git a/snowflake/ml/model/_packager/model_env/model_env_test.py b/snowflake/ml/model/_packager/model_env/model_env_test.py index f21e456c..46ca0d44 100644 --- a/snowflake/ml/model/_packager/model_env/model_env_test.py +++ b/snowflake/ml/model/_packager/model_env/model_env_test.py @@ -954,6 +954,50 @@ def check_env_equality(this: model_env.ModelEnv, that: model_env.ModelEnv) -> bo loaded_env.load_from_dict(tmpdir_path, saved_dict) self.assertTrue(check_env_equality(env, loaded_env), "Loaded env object is different.") + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir_path = pathlib.Path(tmpdir) + env = model_env.ModelEnv() + saved_dict = env.save_as_dict(tmpdir_path, default_channel_override="conda-forge") + + loaded_env = model_env.ModelEnv() + loaded_env.load_from_dict(tmpdir_path, saved_dict) + self.assertTrue(check_env_equality(env, loaded_env), "Loaded env object is different.") + + env = model_env.ModelEnv() + env.conda_dependencies = ["another==1.3", "channel::some_package<1.2,>=1.0.1"] + env.pip_requirements = ["pip-package<1.2,>=1.0.1"] + env.python_version = "3.10.2" + env.cuda_version = "11.7.1" + env.snowpark_ml_version = "1.1.0" + + saved_dict = env.save_as_dict(tmpdir_path, default_channel_override="conda-forge") + + self.assertDictEqual( + saved_dict, + { + "conda": "env/conda.yml", + "pip": "env/requirements.txt", + "python_version": "3.10", + "cuda_version": "11.7", + "snowpark_ml_version": "1.1.0", + }, + ) + + with open(tmpdir_path / "env" / "conda.yml", encoding="utf-8") as f: + conda_yml = yaml.safe_load(f) + self.assertDictEqual( + conda_yml, + { + "channels": ["conda-forge", "channel", "nodefaults"], + "dependencies": ["python==3.10.*", "another==1.3", "channel::some-package<1.2,>=1.0.1"], + "name": "snow-env", + }, + ) + + loaded_env = model_env.ModelEnv() + loaded_env.load_from_dict(tmpdir_path, saved_dict) + self.assertTrue(check_env_equality(env, loaded_env), "Loaded env object is different.") + def test_validate_with_local_env(self) -> None: with mock.patch.object( env_utils, "validate_py_runtime_version" diff --git a/snowflake/ml/model/_packager/model_handlers/_base.py b/snowflake/ml/model/_packager/model_handlers/_base.py index 4bff0714..267759ec 100644 --- a/snowflake/ml/model/_packager/model_handlers/_base.py +++ b/snowflake/ml/model/_packager/model_handlers/_base.py @@ -1,7 +1,8 @@ +import os from abc import abstractmethod -from enum import Enum from typing import Dict, Generic, Optional, Protocol, Type, final +import pandas as pd from typing_extensions import TypeGuard, Unpack from snowflake.ml.model import custom_model, type_hints as model_types @@ -9,15 +10,6 @@ from snowflake.ml.model._packager.model_meta import model_meta -class ModelObjective(Enum): - # This is not getting stored anywhere as metadata yet so it should be fine to slowly extend it for better coverage - UNKNOWN = "unknown" - BINARY_CLASSIFICATION = "binary_classification" - MULTI_CLASSIFICATION = "multi_classification" - REGRESSION = "regression" - RANKING = "ranking" - - class _BaseModelHandlerProtocol(Protocol[model_types._ModelType]): HANDLER_TYPE: model_types.SupportedModelHandlerType HANDLER_VERSION: str @@ -106,6 +98,7 @@ def convert_as_custom_model( cls, raw_model: model_types._ModelType, model_meta: model_meta.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.BaseModelLoadOption], ) -> custom_model.CustomModel: """Create a custom model class wrap for unified interface when being deployed. The predict method will be @@ -114,6 +107,7 @@ def convert_as_custom_model( Args: raw_model: original model object, model_meta: The model metadata. + background_data: The background data used for the model explanations. kwargs: Options when converting the model. Raises: @@ -131,7 +125,8 @@ class BaseModelHandler(Generic[model_types._ModelType], _BaseModelHandlerProtoco _MIN_SNOWPARK_ML_VERSION: The minimal version of Snowpark ML library to use the current handler. _HANDLER_MIGRATOR_PLANS: Dict holding handler migrator plans. - MODELE_BLOB_FILE_OR_DIR: Relative path of the model blob file in the model subdir. Default to "model.pkl". + MODEL_BLOB_FILE_OR_DIR: Relative path of the model blob file in the model subdir. Default to "model.pkl". + BG_DATA_FILE_SUFFIX: Suffix of the background data file. Default to "_background_data.pqt". MODEL_ARTIFACTS_DIR: Relative path of the model artifacts dir in the model subdir. Default to "artifacts" DEFAULT_TARGET_METHODS: Default target methods to be logged if not specified in this kind of model. Default to ["predict"] @@ -139,8 +134,10 @@ class BaseModelHandler(Generic[model_types._ModelType], _BaseModelHandlerProtoco inputting sample data or model signature. Default to False. """ - MODELE_BLOB_FILE_OR_DIR = "model.pkl" + MODEL_BLOB_FILE_OR_DIR = "model.pkl" + BG_DATA_FILE_SUFFIX = "_background_data.pqt" MODEL_ARTIFACTS_DIR = "artifacts" + EXPLAIN_ARTIFACTS_DIR = "explain_artifacts" DEFAULT_TARGET_METHODS = ["predict"] IS_AUTO_SIGNATURE = False @@ -169,3 +166,23 @@ def try_upgrade(cls, name: str, model_meta: model_meta.ModelMetadata, model_blob model_meta=model_meta, model_blobs_dir_path=model_blobs_dir_path, ) + + @classmethod + @final + def load_background_data(cls, name: str, model_blobs_dir_path: str) -> Optional[pd.DataFrame]: + """Load the model into memory. + + Args: + name: Name of the model. + model_blobs_dir_path: Directory path to the whole model. + + Returns: + Optional[pd.DataFrame], background data as pandas DataFrame, if exists. + """ + data_blob_path = os.path.join(model_blobs_dir_path, cls.EXPLAIN_ARTIFACTS_DIR, name + cls.BG_DATA_FILE_SUFFIX) + if not os.path.exists(model_blobs_dir_path) or not os.path.isfile(data_blob_path): + return None + with open(data_blob_path, "rb") as f: + background_data = pd.read_parquet(f) + + return background_data diff --git a/snowflake/ml/model/_packager/model_handlers/catboost.py b/snowflake/ml/model/_packager/model_handlers/catboost.py index 7e48a78e..6177c843 100644 --- a/snowflake/ml/model/_packager/model_handlers/catboost.py +++ b/snowflake/ml/model/_packager/model_handlers/catboost.py @@ -30,24 +30,24 @@ class CatBoostModelHandler(_base.BaseModelHandler["catboost.CatBoost"]): _MIN_SNOWPARK_ML_VERSION = "1.3.1" _HANDLER_MIGRATOR_PLANS: Dict[str, Type[base_migrator.BaseModelHandlerMigrator]] = {} - MODELE_BLOB_FILE_OR_DIR = "model.bin" + MODEL_BLOB_FILE_OR_DIR = "model.bin" DEFAULT_TARGET_METHODS = ["predict", "predict_proba"] @classmethod - def get_model_objective(cls, model: "catboost.CatBoost") -> _base.ModelObjective: + def get_model_objective(cls, model: "catboost.CatBoost") -> model_meta_schema.ModelObjective: import catboost if isinstance(model, catboost.CatBoostClassifier): num_classes = handlers_utils.get_num_classes_if_exists(model) if num_classes == 2: - return _base.ModelObjective.BINARY_CLASSIFICATION - return _base.ModelObjective.MULTI_CLASSIFICATION + return model_meta_schema.ModelObjective.BINARY_CLASSIFICATION + return model_meta_schema.ModelObjective.MULTI_CLASSIFICATION if isinstance(model, catboost.CatBoostRanker): - return _base.ModelObjective.RANKING + return model_meta_schema.ModelObjective.RANKING if isinstance(model, catboost.CatBoostRegressor): - return _base.ModelObjective.REGRESSION + return model_meta_schema.ModelObjective.REGRESSION # TODO: Find out model type from the generic Catboost Model - return _base.ModelObjective.UNKNOWN + return model_meta_schema.ModelObjective.UNKNOWN @classmethod def can_handle(cls, model: model_types.SupportedModelType) -> TypeGuard["catboost.CatBoost"]: @@ -105,9 +105,11 @@ def get_prediction( sample_input_data=sample_input_data, get_prediction_fn=get_prediction, ) - if kwargs.get("enable_explainability", False): + model_objective = cls.get_model_objective(model) + model_meta.model_objective = model_objective + if kwargs.get("enable_explainability", True): output_type = model_signature.DataType.DOUBLE - if cls.get_model_objective(model) == _base.ModelObjective.MULTI_CLASSIFICATION: + if model_objective == model_meta_schema.ModelObjective.MULTI_CLASSIFICATION: output_type = model_signature.DataType.STRING model_meta = handlers_utils.add_explain_method_signature( model_meta=model_meta, @@ -115,10 +117,13 @@ def get_prediction( target_method="predict", output_return_type=output_type, ) + model_meta.function_properties = { + "explain": {model_meta_schema.FunctionProperties.PARTITIONED.value: False} + } model_blob_path = os.path.join(model_blobs_dir_path, name) os.makedirs(model_blob_path, exist_ok=True) - model_save_path = os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR) + model_save_path = os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR) model.save_model(model_save_path) @@ -126,7 +131,7 @@ def get_prediction( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, options=model_meta_schema.CatBoostModelBlobOptions({"catboost_estimator_type": model.__class__.__name__}), ) model_meta.models[name] = base_meta @@ -138,11 +143,12 @@ def get_prediction( ], check_local_version=True, ) - if kwargs.get("enable_explainability", False): + if kwargs.get("enable_explainability", True): model_meta.env.include_if_absent( [model_env.ModelDependency(requirement="shap", pip_name="shap")], check_local_version=True, ) + model_meta.explain_algorithm = model_meta_schema.ModelExplainAlgorithm.SHAP model_meta.env.cuda_version = kwargs.get("cuda_version", model_env.DEFAULT_CUDA_VERSION) return None @@ -188,6 +194,7 @@ def convert_as_custom_model( cls, raw_model: "catboost.CatBoost", model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.CatBoostModelLoadOptions], ) -> custom_model.CustomModel: import catboost diff --git a/snowflake/ml/model/_packager/model_handlers/custom.py b/snowflake/ml/model/_packager/model_handlers/custom.py index 5c8b7611..66a984e5 100644 --- a/snowflake/ml/model/_packager/model_handlers/custom.py +++ b/snowflake/ml/model/_packager/model_handlers/custom.py @@ -51,6 +51,9 @@ def save_model( **kwargs: Unpack[model_types.CustomModelSaveOption], ) -> None: assert isinstance(model, custom_model.CustomModel) + enable_explainability = kwargs.get("enable_explainability", False) + if enable_explainability: + raise NotImplementedError("Explainability is not supported for custom model.") def get_prediction( target_method_name: str, sample_input_data: model_types.SupportedLocalDataType @@ -108,13 +111,13 @@ def get_prediction( # Make sure that the module where the model is defined get pickled by value as well. cloudpickle.register_pickle_by_value(sys.modules[model.__module__]) pickled_obj = (model.__class__, model.context) - with open(os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR), "wb") as f: + with open(os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR), "wb") as f: cloudpickle.dump(pickled_obj, f) # model meta will be saved by the context manager model_meta.models[name] = model_blob_meta.ModelBlobMeta( name=name, model_type=cls.HANDLER_TYPE, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, handler_version=cls.HANDLER_VERSION, function_properties=model_meta.function_properties, artifacts={ @@ -183,6 +186,7 @@ def convert_as_custom_model( cls, raw_model: custom_model.CustomModel, model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.CustomModelLoadOption], ) -> custom_model.CustomModel: return raw_model diff --git a/snowflake/ml/model/_packager/model_handlers/huggingface_pipeline.py b/snowflake/ml/model/_packager/model_handlers/huggingface_pipeline.py index 57c98ef1..e7f973cc 100644 --- a/snowflake/ml/model/_packager/model_handlers/huggingface_pipeline.py +++ b/snowflake/ml/model/_packager/model_handlers/huggingface_pipeline.py @@ -89,7 +89,7 @@ class HuggingFacePipelineHandler( _MIN_SNOWPARK_ML_VERSION = "1.0.12" _HANDLER_MIGRATOR_PLANS: Dict[str, Type[base_migrator.BaseModelHandlerMigrator]] = {} - MODELE_BLOB_FILE_OR_DIR = "model" + MODEL_BLOB_FILE_OR_DIR = "model" ADDITIONAL_CONFIG_FILE = "pipeline_config.pt" DEFAULT_TARGET_METHODS = ["__call__"] IS_AUTO_SIGNATURE = True @@ -133,6 +133,9 @@ def save_model( is_sub_model: Optional[bool] = False, **kwargs: Unpack[model_types.HuggingFaceSaveOptions], ) -> None: + enable_explainability = kwargs.get("enable_explainability", False) + if enable_explainability: + raise NotImplementedError("Explainability is not supported for huggingface model.") if type_utils.LazyType("transformers.Pipeline").isinstance(model): task = model.task # type:ignore[attr-defined] framework = model.framework # type:ignore[attr-defined] @@ -193,7 +196,7 @@ def save_model( if type_utils.LazyType("transformers.Pipeline").isinstance(model): model.save_pretrained( # type:ignore[attr-defined] - os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR) + os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR) ) pipeline_params = { "_batch_size": model._batch_size, # type:ignore[attr-defined] @@ -205,7 +208,7 @@ def save_model( with open( os.path.join( model_blob_path, - cls.MODELE_BLOB_FILE_OR_DIR, + cls.MODEL_BLOB_FILE_OR_DIR, cls.ADDITIONAL_CONFIG_FILE, ), "wb", @@ -213,7 +216,7 @@ def save_model( cloudpickle.dump(pipeline_params, f) else: with open( - os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR), + os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR), "wb", ) as f: cloudpickle.dump(model, f) @@ -222,7 +225,7 @@ def save_model( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, options=model_meta_schema.HuggingFacePipelineModelBlobOptions( { "task": task, @@ -329,6 +332,7 @@ def convert_as_custom_model( cls, raw_model: Union[huggingface_pipeline.HuggingFacePipelineModel, "transformers.Pipeline"], model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.HuggingFaceLoadOptions], ) -> custom_model.CustomModel: import transformers diff --git a/snowflake/ml/model/_packager/model_handlers/lightgbm.py b/snowflake/ml/model/_packager/model_handlers/lightgbm.py index 4da53c91..83461abf 100644 --- a/snowflake/ml/model/_packager/model_handlers/lightgbm.py +++ b/snowflake/ml/model/_packager/model_handlers/lightgbm.py @@ -41,7 +41,7 @@ class LGBMModelHandler(_base.BaseModelHandler[Union["lightgbm.Booster", "lightgb _MIN_SNOWPARK_ML_VERSION = "1.3.1" _HANDLER_MIGRATOR_PLANS: Dict[str, Type[base_migrator.BaseModelHandlerMigrator]] = {} - MODELE_BLOB_FILE_OR_DIR = "model.pkl" + MODEL_BLOB_FILE_OR_DIR = "model.pkl" DEFAULT_TARGET_METHODS = ["predict", "predict_proba"] _BINARY_CLASSIFICATION_OBJECTIVES = ["binary"] _MULTI_CLASSIFICATION_OBJECTIVES = ["multiclass", "multiclassova"] @@ -59,29 +59,31 @@ class LGBMModelHandler(_base.BaseModelHandler[Union["lightgbm.Booster", "lightgb ] @classmethod - def get_model_objective(cls, model: Union["lightgbm.Booster", "lightgbm.LGBMModel"]) -> _base.ModelObjective: + def get_model_objective( + cls, model: Union["lightgbm.Booster", "lightgbm.LGBMModel"] + ) -> model_meta_schema.ModelObjective: import lightgbm # does not account for cross-entropy and custom if isinstance(model, lightgbm.LGBMClassifier): num_classes = handlers_utils.get_num_classes_if_exists(model) if num_classes == 2: - return _base.ModelObjective.BINARY_CLASSIFICATION - return _base.ModelObjective.MULTI_CLASSIFICATION + return model_meta_schema.ModelObjective.BINARY_CLASSIFICATION + return model_meta_schema.ModelObjective.MULTI_CLASSIFICATION if isinstance(model, lightgbm.LGBMRanker): - return _base.ModelObjective.RANKING + return model_meta_schema.ModelObjective.RANKING if isinstance(model, lightgbm.LGBMRegressor): - return _base.ModelObjective.REGRESSION + return model_meta_schema.ModelObjective.REGRESSION model_objective = model.params["objective"] if model_objective in cls._BINARY_CLASSIFICATION_OBJECTIVES: - return _base.ModelObjective.BINARY_CLASSIFICATION + return model_meta_schema.ModelObjective.BINARY_CLASSIFICATION if model_objective in cls._MULTI_CLASSIFICATION_OBJECTIVES: - return _base.ModelObjective.MULTI_CLASSIFICATION + return model_meta_schema.ModelObjective.MULTI_CLASSIFICATION if model_objective in cls._RANKING_OBJECTIVES: - return _base.ModelObjective.RANKING + return model_meta_schema.ModelObjective.RANKING if model_objective in cls._REGRESSION_OBJECTIVES: - return _base.ModelObjective.REGRESSION - return _base.ModelObjective.UNKNOWN + return model_meta_schema.ModelObjective.REGRESSION + return model_meta_schema.ModelObjective.UNKNOWN @classmethod def can_handle( @@ -144,11 +146,13 @@ def get_prediction( sample_input_data=sample_input_data, get_prediction_fn=get_prediction, ) - if kwargs.get("enable_explainability", False): + model_objective = cls.get_model_objective(model) + model_meta.model_objective = model_objective + if kwargs.get("enable_explainability", True): output_type = model_signature.DataType.DOUBLE - if cls.get_model_objective(model) in [ - _base.ModelObjective.BINARY_CLASSIFICATION, - _base.ModelObjective.MULTI_CLASSIFICATION, + if model_objective in [ + model_meta_schema.ModelObjective.BINARY_CLASSIFICATION, + model_meta_schema.ModelObjective.MULTI_CLASSIFICATION, ]: output_type = model_signature.DataType.STRING model_meta = handlers_utils.add_explain_method_signature( @@ -157,11 +161,14 @@ def get_prediction( target_method="predict", output_return_type=output_type, ) + model_meta.function_properties = { + "explain": {model_meta_schema.FunctionProperties.PARTITIONED.value: False} + } model_blob_path = os.path.join(model_blobs_dir_path, name) os.makedirs(model_blob_path, exist_ok=True) - model_save_path = os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR) + model_save_path = os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR) with open(model_save_path, "wb") as f: cloudpickle.dump(model, f) @@ -169,7 +176,7 @@ def get_prediction( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, options=model_meta_schema.LightGBMModelBlobOptions({"lightgbm_estimator_type": model.__class__.__name__}), ) model_meta.models[name] = base_meta @@ -182,11 +189,12 @@ def get_prediction( ], check_local_version=True, ) - if kwargs.get("enable_explainability", False): + if kwargs.get("enable_explainability", True): model_meta.env.include_if_absent( [model_env.ModelDependency(requirement="shap", pip_name="shap")], check_local_version=True, ) + model_meta.explain_algorithm = model_meta_schema.ModelExplainAlgorithm.SHAP return None @@ -226,6 +234,7 @@ def convert_as_custom_model( cls, raw_model: Union["lightgbm.Booster", "lightgbm.XGBModel"], model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.LGBMModelLoadOptions], ) -> custom_model.CustomModel: import lightgbm diff --git a/snowflake/ml/model/_packager/model_handlers/llm.py b/snowflake/ml/model/_packager/model_handlers/llm.py index 73b7f5c9..591bb048 100644 --- a/snowflake/ml/model/_packager/model_handlers/llm.py +++ b/snowflake/ml/model/_packager/model_handlers/llm.py @@ -28,7 +28,7 @@ class LLMHandler(_base.BaseModelHandler[llm.LLM]): _MIN_SNOWPARK_ML_VERSION = "1.0.12" _HANDLER_MIGRATOR_PLANS: Dict[str, Type[base_migrator.BaseModelHandlerMigrator]] = {} - MODELE_BLOB_FILE_OR_DIR = "model" + MODEL_BLOB_FILE_OR_DIR = "model" LLM_META = "llm_meta" IS_AUTO_SIGNATURE = True @@ -59,9 +59,12 @@ def save_model( **kwargs: Unpack[model_types.LLMSaveOptions], ) -> None: assert not is_sub_model, "LLM can not be sub-model." + enable_explainability = kwargs.get("enable_explainability", False) + if enable_explainability: + raise NotImplementedError("Explainability is not supported for llm model.") model_blob_path = os.path.join(model_blobs_dir_path, name) os.makedirs(model_blob_path, exist_ok=True) - model_blob_dir_path = os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR) + model_blob_dir_path = os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR) sig = model_signature.ModelSignature( inputs=[ @@ -86,7 +89,7 @@ def save_model( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, options=model_meta_schema.LLMModelBlobOptions( { "batch_size": model.max_batch_size, @@ -143,6 +146,7 @@ def convert_as_custom_model( cls, raw_model: llm.LLM, model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.LLMLoadOptions], ) -> custom_model.CustomModel: import gc diff --git a/snowflake/ml/model/_packager/model_handlers/mlflow.py b/snowflake/ml/model/_packager/model_handlers/mlflow.py index 10cb8202..57118f71 100644 --- a/snowflake/ml/model/_packager/model_handlers/mlflow.py +++ b/snowflake/ml/model/_packager/model_handlers/mlflow.py @@ -63,7 +63,7 @@ class MLFlowHandler(_base.BaseModelHandler["mlflow.pyfunc.PyFuncModel"]): _MIN_SNOWPARK_ML_VERSION = "1.0.12" _HANDLER_MIGRATOR_PLANS: Dict[str, Type[base_migrator.BaseModelHandlerMigrator]] = {} - MODELE_BLOB_FILE_OR_DIR = "model" + MODEL_BLOB_FILE_OR_DIR = "model" _DEFAULT_TARGET_METHOD = "predict" DEFAULT_TARGET_METHODS = [_DEFAULT_TARGET_METHOD] IS_AUTO_SIGNATURE = True @@ -97,6 +97,10 @@ def save_model( is_sub_model: Optional[bool] = False, **kwargs: Unpack[model_types.MLFlowSaveOptions], ) -> None: + enable_explainability = kwargs.get("enable_explainability", False) + if enable_explainability: + raise NotImplementedError("Explainability is not supported for MLFlow model.") + import mlflow assert isinstance(model, mlflow.pyfunc.PyFuncModel) @@ -142,13 +146,13 @@ def save_model( except (mlflow.MlflowException, OSError): raise ValueError("Cannot load MLFlow model artifacts.") - file_utils.copy_file_or_tree(local_path, os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR)) + file_utils.copy_file_or_tree(local_path, os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR)) base_meta = model_blob_meta.ModelBlobMeta( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, options=model_meta_schema.MLFlowModelBlobOptions({"artifact_path": model_info.artifact_path}), ) model_meta.models[name] = base_meta @@ -194,6 +198,7 @@ def convert_as_custom_model( cls, raw_model: "mlflow.pyfunc.PyFuncModel", model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.MLFlowLoadOptions], ) -> custom_model.CustomModel: from snowflake.ml.model import custom_model diff --git a/snowflake/ml/model/_packager/model_handlers/pytorch.py b/snowflake/ml/model/_packager/model_handlers/pytorch.py index f78045fd..819302aa 100644 --- a/snowflake/ml/model/_packager/model_handlers/pytorch.py +++ b/snowflake/ml/model/_packager/model_handlers/pytorch.py @@ -37,7 +37,7 @@ class PyTorchHandler(_base.BaseModelHandler["torch.nn.Module"]): _MIN_SNOWPARK_ML_VERSION = "1.0.12" _HANDLER_MIGRATOR_PLANS: Dict[str, Type[base_migrator.BaseModelHandlerMigrator]] = {} - MODELE_BLOB_FILE_OR_DIR = "model.pt" + MODEL_BLOB_FILE_OR_DIR = "model.pt" DEFAULT_TARGET_METHODS = ["forward"] @classmethod @@ -73,6 +73,10 @@ def save_model( is_sub_model: Optional[bool] = False, **kwargs: Unpack[model_types.PyTorchSaveOptions], ) -> None: + enable_explainability = kwargs.get("enable_explainability", False) + if enable_explainability: + raise NotImplementedError("Explainability is not supported for PyTorch model.") + import torch assert isinstance(model, torch.nn.Module) @@ -115,13 +119,13 @@ def get_prediction( cloudpickle.register_pickle_by_value(sys.modules[model.__module__]) model_blob_path = os.path.join(model_blobs_dir_path, name) os.makedirs(model_blob_path, exist_ok=True) - with open(os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR), "wb") as f: + with open(os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR), "wb") as f: torch.save(model, f, pickle_module=cloudpickle) base_meta = model_blob_meta.ModelBlobMeta( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, ) model_meta.models[name] = base_meta model_meta.min_snowpark_ml_version = cls._MIN_SNOWPARK_ML_VERSION @@ -156,6 +160,7 @@ def convert_as_custom_model( cls, raw_model: "torch.nn.Module", model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.PyTorchLoadOptions], ) -> custom_model.CustomModel: import torch diff --git a/snowflake/ml/model/_packager/model_handlers/sentence_transformers.py b/snowflake/ml/model/_packager/model_handlers/sentence_transformers.py index cf1f15f1..aa3f6348 100644 --- a/snowflake/ml/model/_packager/model_handlers/sentence_transformers.py +++ b/snowflake/ml/model/_packager/model_handlers/sentence_transformers.py @@ -31,7 +31,7 @@ class SentenceTransformerHandler(_base.BaseModelHandler["sentence_transformers.S _MIN_SNOWPARK_ML_VERSION = "1.3.1" _HANDLER_MIGRATOR_PLANS: Dict[str, Type[base_migrator.BaseModelHandlerMigrator]] = {} - MODELE_BLOB_FILE_OR_DIR = "model" + MODEL_BLOB_FILE_OR_DIR = "model" DEFAULT_TARGET_METHODS = ["encode"] @classmethod @@ -64,6 +64,10 @@ def save_model( is_sub_model: Optional[bool] = False, **kwargs: Unpack[model_types.SentenceTransformersSaveOptions], # registry.log_model(options={...}) ) -> None: + enable_explainability = kwargs.get("enable_explainability", False) + if enable_explainability: + raise NotImplementedError("Explainability is not supported for Sentence Transformer model.") + # Validate target methods and signature (if possible) if not is_sub_model: target_methods = handlers_utils.get_target_methods( @@ -101,14 +105,14 @@ def get_prediction( # save model model_blob_path = os.path.join(model_blobs_dir_path, name) os.makedirs(model_blob_path, exist_ok=True) - model.save(os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR)) + model.save(os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR)) # save model metadata base_meta = model_blob_meta.ModelBlobMeta( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, ) model_meta.models[name] = base_meta model_meta.min_snowpark_ml_version = cls._MIN_SNOWPARK_ML_VERSION @@ -154,6 +158,7 @@ def convert_as_custom_model( cls, raw_model: "sentence_transformers.SentenceTransformer", model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.SentenceTransformersLoadOptions], ) -> custom_model.CustomModel: import sentence_transformers diff --git a/snowflake/ml/model/_packager/model_handlers/sklearn.py b/snowflake/ml/model/_packager/model_handlers/sklearn.py index c16d3248..d9ab8d5d 100644 --- a/snowflake/ml/model/_packager/model_handlers/sklearn.py +++ b/snowflake/ml/model/_packager/model_handlers/sklearn.py @@ -6,6 +6,7 @@ import pandas as pd from typing_extensions import TypeGuard, Unpack +import snowflake.snowpark.dataframe as sp_df from snowflake.ml._internal import type_utils from snowflake.ml.model import custom_model, model_signature, type_hints as model_types from snowflake.ml.model._packager.model_env import model_env @@ -14,8 +15,13 @@ from snowflake.ml.model._packager.model_meta import ( model_blob_meta, model_meta as model_meta_api, + model_meta_schema, +) +from snowflake.ml.model._signatures import ( + numpy_handler, + snowpark_handler, + utils as model_signature_utils, ) -from snowflake.ml.model._signatures import numpy_handler, utils as model_signature_utils if TYPE_CHECKING: import sklearn.base @@ -36,6 +42,27 @@ class SKLModelHandler(_base.BaseModelHandler[Union["sklearn.base.BaseEstimator", DEFAULT_TARGET_METHODS = ["predict", "transform", "predict_proba", "predict_log_proba", "decision_function"] + @classmethod + def get_model_objective( + cls, model: Union["sklearn.base.BaseEstimator", "sklearn.pipeline.Pipeline"] + ) -> model_meta_schema.ModelObjective: + import sklearn.pipeline + from sklearn.base import is_classifier, is_regressor + + if isinstance(model, sklearn.pipeline.Pipeline): + return model_meta_schema.ModelObjective.UNKNOWN + if is_regressor(model): + return model_meta_schema.ModelObjective.REGRESSION + if is_classifier(model): + classes_list = getattr(model, "classes_", []) + num_classes = getattr(model, "n_classes_", None) or len(classes_list) + if isinstance(num_classes, int): + if num_classes > 2: + return model_meta_schema.ModelObjective.MULTI_CLASSIFICATION + return model_meta_schema.ModelObjective.BINARY_CLASSIFICATION + return model_meta_schema.ModelObjective.UNKNOWN + return model_meta_schema.ModelObjective.UNKNOWN + @classmethod def can_handle( cls, @@ -79,11 +106,33 @@ def save_model( is_sub_model: Optional[bool] = False, **kwargs: Unpack[model_types.SKLModelSaveOptions], ) -> None: + enable_explainability = kwargs.get("enable_explainability", False) + import sklearn.base import sklearn.pipeline assert isinstance(model, sklearn.base.BaseEstimator) or isinstance(model, sklearn.pipeline.Pipeline) + enable_explainability = kwargs.get("enable_explainability", False) + if enable_explainability: + # TODO: Currently limited to pandas df, need to extend to other types. + if sample_input_data is None or not ( + isinstance(sample_input_data, pd.DataFrame) or isinstance(sample_input_data, sp_df.DataFrame) + ): + raise ValueError( + "Sample input data is required to enable explainability. Currently we only support this for " + + "`pandas.DataFrame` and `snowflake.snowpark.dataframe.DataFrame`." + ) + sample_input_data_pandas = ( + sample_input_data + if isinstance(sample_input_data, pd.DataFrame) + else snowpark_handler.SnowparkDataFrameHandler.convert_to_df(sample_input_data) + ) + data_blob_path = os.path.join(model_blobs_dir_path, cls.EXPLAIN_ARTIFACTS_DIR) + os.makedirs(data_blob_path, exist_ok=True) + with open(os.path.join(data_blob_path, name + cls.BG_DATA_FILE_SUFFIX), "wb") as f: + sample_input_data_pandas.to_parquet(f) + if not is_sub_model: target_methods = handlers_utils.get_target_methods( model=model, @@ -110,19 +159,36 @@ def get_prediction( get_prediction_fn=get_prediction, ) + if enable_explainability: + output_type = model_signature.DataType.DOUBLE + if cls.get_model_objective(model) == model_meta_schema.ModelObjective.MULTI_CLASSIFICATION: + output_type = model_signature.DataType.STRING + model_meta = handlers_utils.add_explain_method_signature( + model_meta=model_meta, + explain_method="explain", + target_method="predict", + output_return_type=output_type, + ) + model_blob_path = os.path.join(model_blobs_dir_path, name) os.makedirs(model_blob_path, exist_ok=True) - with open(os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR), "wb") as f: + with open(os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR), "wb") as f: cloudpickle.dump(model, f) base_meta = model_blob_meta.ModelBlobMeta( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, ) model_meta.models[name] = base_meta model_meta.min_snowpark_ml_version = cls._MIN_SNOWPARK_ML_VERSION + if enable_explainability: + model_meta.env.include_if_absent( + [model_env.ModelDependency(requirement="shap", pip_name="shap")], + check_local_version=True, + ) + model_meta.env.include_if_absent( [model_env.ModelDependency(requirement="scikit-learn", pip_name="scikit-learn")], check_local_version=True ) @@ -153,6 +219,7 @@ def convert_as_custom_model( cls, raw_model: Union["sklearn.base.BaseEstimator", "sklearn.pipeline.Pipeline"], model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.SKLModelLoadOptions], ) -> custom_model.CustomModel: from snowflake.ml.model import custom_model @@ -165,6 +232,7 @@ def fn_factory( raw_model: Union["sklearn.base.BaseEstimator", "sklearn.pipeline.Pipeline"], signature: model_signature.ModelSignature, target_method: str, + background_data: Optional[pd.DataFrame], ) -> Callable[[custom_model.CustomModel, pd.DataFrame], pd.DataFrame]: @custom_model.inference_api def fn(self: custom_model.CustomModel, X: pd.DataFrame) -> pd.DataFrame: @@ -179,11 +247,26 @@ def fn(self: custom_model.CustomModel, X: pd.DataFrame) -> pd.DataFrame: return model_signature_utils.rename_pandas_df(df, signature.outputs) + @custom_model.inference_api + def explain_fn(self: custom_model.CustomModel, X: pd.DataFrame) -> pd.DataFrame: + import shap + + # TODO: if not resolved by explainer, we need to pass the callable function + try: + explainer = shap.Explainer(raw_model, background_data) + df = handlers_utils.convert_explanations_to_2D_df(raw_model, explainer(X).values) + except TypeError as e: + raise ValueError(f"Explanation for this model type not supported yet: {str(e)}") + return model_signature_utils.rename_pandas_df(df, signature.outputs) + + if target_method == "explain": + return explain_fn + return fn type_method_dict = {} for target_method_name, sig in model_meta.signatures.items(): - type_method_dict[target_method_name] = fn_factory(raw_model, sig, target_method_name) + type_method_dict[target_method_name] = fn_factory(raw_model, sig, target_method_name, background_data) _SKLModel = type( "_SKLModel", diff --git a/snowflake/ml/model/_packager/model_handlers/snowmlmodel.py b/snowflake/ml/model/_packager/model_handlers/snowmlmodel.py index 9821e024..0152298b 100644 --- a/snowflake/ml/model/_packager/model_handlers/snowmlmodel.py +++ b/snowflake/ml/model/_packager/model_handlers/snowmlmodel.py @@ -73,6 +73,10 @@ def save_model( is_sub_model: Optional[bool] = False, **kwargs: Unpack[model_types.SNOWModelSaveOptions], ) -> None: + enable_explainability = kwargs.get("enable_explainability", False) + if enable_explainability: + raise NotImplementedError("Explainability is not supported for Snowpark ML model.") + from snowflake.ml.modeling.framework.base import BaseEstimator assert isinstance(model, BaseEstimator) @@ -103,13 +107,13 @@ def save_model( model_blob_path = os.path.join(model_blobs_dir_path, name) os.makedirs(model_blob_path, exist_ok=True) - with open(os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR), "wb") as f: + with open(os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR), "wb") as f: cloudpickle.dump(model, f) base_meta = model_blob_meta.ModelBlobMeta( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, ) model_meta.models[name] = base_meta model_meta.min_snowpark_ml_version = cls._MIN_SNOWPARK_ML_VERSION @@ -146,6 +150,7 @@ def convert_as_custom_model( cls, raw_model: "BaseEstimator", model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.SNOWModelLoadOptions], ) -> custom_model.CustomModel: from snowflake.ml.model import custom_model diff --git a/snowflake/ml/model/_packager/model_handlers/tensorflow.py b/snowflake/ml/model/_packager/model_handlers/tensorflow.py index bed2f907..9360da17 100644 --- a/snowflake/ml/model/_packager/model_handlers/tensorflow.py +++ b/snowflake/ml/model/_packager/model_handlers/tensorflow.py @@ -36,7 +36,7 @@ class TensorFlowHandler(_base.BaseModelHandler["tensorflow.Module"]): _MIN_SNOWPARK_ML_VERSION = "1.0.12" _HANDLER_MIGRATOR_PLANS: Dict[str, Type[base_migrator.BaseModelHandlerMigrator]] = {} - MODELE_BLOB_FILE_OR_DIR = "model" + MODEL_BLOB_FILE_OR_DIR = "model" DEFAULT_TARGET_METHODS = ["__call__"] @classmethod @@ -68,6 +68,10 @@ def save_model( is_sub_model: Optional[bool] = False, **kwargs: Unpack[model_types.TensorflowSaveOptions], ) -> None: + enable_explainability = kwargs.get("enable_explainability", False) + if enable_explainability: + raise NotImplementedError("Explainability is not supported for Tensorflow model.") + import tensorflow assert isinstance(model, tensorflow.Module) @@ -114,15 +118,15 @@ def get_prediction( model_blob_path = os.path.join(model_blobs_dir_path, name) os.makedirs(model_blob_path, exist_ok=True) if isinstance(model, tensorflow.keras.Model): - tensorflow.keras.models.save_model(model, os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR)) + tensorflow.keras.models.save_model(model, os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR)) else: - tensorflow.saved_model.save(model, os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR)) + tensorflow.saved_model.save(model, os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR)) base_meta = model_blob_meta.ModelBlobMeta( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, ) model_meta.models[name] = base_meta model_meta.min_snowpark_ml_version = cls._MIN_SNOWPARK_ML_VERSION @@ -156,6 +160,7 @@ def convert_as_custom_model( cls, raw_model: "tensorflow.Module", model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.TensorflowLoadOptions], ) -> custom_model.CustomModel: import tensorflow diff --git a/snowflake/ml/model/_packager/model_handlers/torchscript.py b/snowflake/ml/model/_packager/model_handlers/torchscript.py index 1058b87c..9dc6bb43 100644 --- a/snowflake/ml/model/_packager/model_handlers/torchscript.py +++ b/snowflake/ml/model/_packager/model_handlers/torchscript.py @@ -34,7 +34,7 @@ class TorchScriptHandler(_base.BaseModelHandler["torch.jit.ScriptModule"]): # t _MIN_SNOWPARK_ML_VERSION = "1.0.12" _HANDLER_MIGRATOR_PLANS: Dict[str, Type[base_migrator.BaseModelHandlerMigrator]] = {} - MODELE_BLOB_FILE_OR_DIR = "model.pt" + MODEL_BLOB_FILE_OR_DIR = "model.pt" DEFAULT_TARGET_METHODS = ["forward"] @classmethod @@ -66,6 +66,10 @@ def save_model( is_sub_model: Optional[bool] = False, **kwargs: Unpack[model_types.TorchScriptSaveOptions], ) -> None: + enable_explainability = kwargs.get("enable_explainability", False) + if enable_explainability: + raise NotImplementedError("Explainability is not supported for Torch Script model.") + import torch assert isinstance(model, torch.jit.ScriptModule) # type:ignore[attr-defined] @@ -106,13 +110,13 @@ def get_prediction( model_blob_path = os.path.join(model_blobs_dir_path, name) os.makedirs(model_blob_path, exist_ok=True) - with open(os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR), "wb") as f: + with open(os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR), "wb") as f: torch.jit.save(model, f) # type:ignore[attr-defined] base_meta = model_blob_meta.ModelBlobMeta( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, ) model_meta.models[name] = base_meta model_meta.min_snowpark_ml_version = cls._MIN_SNOWPARK_ML_VERSION @@ -152,6 +156,7 @@ def convert_as_custom_model( cls, raw_model: "torch.jit.ScriptModule", # type:ignore[name-defined] model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.TorchScriptLoadOptions], ) -> custom_model.CustomModel: from snowflake.ml.model import custom_model diff --git a/snowflake/ml/model/_packager/model_handlers/xgboost.py b/snowflake/ml/model/_packager/model_handlers/xgboost.py index 05469e45..f1b5e009 100644 --- a/snowflake/ml/model/_packager/model_handlers/xgboost.py +++ b/snowflake/ml/model/_packager/model_handlers/xgboost.py @@ -45,7 +45,7 @@ class XGBModelHandler(_base.BaseModelHandler[Union["xgboost.Booster", "xgboost.X _MIN_SNOWPARK_ML_VERSION = "1.0.12" _HANDLER_MIGRATOR_PLANS: Dict[str, Type[base_migrator.BaseModelHandlerMigrator]] = {} - MODELE_BLOB_FILE_OR_DIR = "model.ubj" + MODEL_BLOB_FILE_OR_DIR = "model.ubj" DEFAULT_TARGET_METHODS = ["predict", "predict_proba"] _BINARY_CLASSIFICATION_OBJECTIVE_PREFIX = ["binary:"] _MULTI_CLASSIFICATION_OBJECTIVE_PREFIX = ["multi:"] @@ -53,33 +53,35 @@ class XGBModelHandler(_base.BaseModelHandler[Union["xgboost.Booster", "xgboost.X _REGRESSION_OBJECTIVE_PREFIX = ["reg:"] @classmethod - def get_model_objective(cls, model: Union["xgboost.Booster", "xgboost.XGBModel"]) -> _base.ModelObjective: + def get_model_objective( + cls, model: Union["xgboost.Booster", "xgboost.XGBModel"] + ) -> model_meta_schema.ModelObjective: import xgboost if isinstance(model, xgboost.XGBClassifier) or isinstance(model, xgboost.XGBRFClassifier): num_classes = handlers_utils.get_num_classes_if_exists(model) if num_classes == 2: - return _base.ModelObjective.BINARY_CLASSIFICATION - return _base.ModelObjective.MULTI_CLASSIFICATION + return model_meta_schema.ModelObjective.BINARY_CLASSIFICATION + return model_meta_schema.ModelObjective.MULTI_CLASSIFICATION if isinstance(model, xgboost.XGBRegressor) or isinstance(model, xgboost.XGBRFRegressor): - return _base.ModelObjective.REGRESSION + return model_meta_schema.ModelObjective.REGRESSION if isinstance(model, xgboost.XGBRanker): - return _base.ModelObjective.RANKING + return model_meta_schema.ModelObjective.RANKING model_params = json.loads(model.save_config()) model_objective = model_params["learner"]["objective"] for classification_objective in cls._BINARY_CLASSIFICATION_OBJECTIVE_PREFIX: if classification_objective in model_objective: - return _base.ModelObjective.BINARY_CLASSIFICATION + return model_meta_schema.ModelObjective.BINARY_CLASSIFICATION for classification_objective in cls._MULTI_CLASSIFICATION_OBJECTIVE_PREFIX: if classification_objective in model_objective: - return _base.ModelObjective.MULTI_CLASSIFICATION + return model_meta_schema.ModelObjective.MULTI_CLASSIFICATION for ranking_objective in cls._RANKING_OBJECTIVE_PREFIX: if ranking_objective in model_objective: - return _base.ModelObjective.RANKING + return model_meta_schema.ModelObjective.RANKING for regression_objective in cls._REGRESSION_OBJECTIVE_PREFIX: if regression_objective in model_objective: - return _base.ModelObjective.REGRESSION - return _base.ModelObjective.UNKNOWN + return model_meta_schema.ModelObjective.REGRESSION + return model_meta_schema.ModelObjective.UNKNOWN @classmethod def can_handle( @@ -146,9 +148,11 @@ def get_prediction( sample_input_data=sample_input_data, get_prediction_fn=get_prediction, ) - if kwargs.get("enable_explainability", False): + model_objective = cls.get_model_objective(model) + model_meta.model_objective = model_objective + if kwargs.get("enable_explainability", True): output_type = model_signature.DataType.DOUBLE - if cls.get_model_objective(model) == _base.ModelObjective.MULTI_CLASSIFICATION: + if model_objective == model_meta_schema.ModelObjective.MULTI_CLASSIFICATION: output_type = model_signature.DataType.STRING model_meta = handlers_utils.add_explain_method_signature( model_meta=model_meta, @@ -156,15 +160,18 @@ def get_prediction( target_method="predict", output_return_type=output_type, ) + model_meta.function_properties = { + "explain": {model_meta_schema.FunctionProperties.PARTITIONED.value: False} + } model_blob_path = os.path.join(model_blobs_dir_path, name) os.makedirs(model_blob_path, exist_ok=True) - model.save_model(os.path.join(model_blob_path, cls.MODELE_BLOB_FILE_OR_DIR)) + model.save_model(os.path.join(model_blob_path, cls.MODEL_BLOB_FILE_OR_DIR)) base_meta = model_blob_meta.ModelBlobMeta( name=name, model_type=cls.HANDLER_TYPE, handler_version=cls.HANDLER_VERSION, - path=cls.MODELE_BLOB_FILE_OR_DIR, + path=cls.MODEL_BLOB_FILE_OR_DIR, options=model_meta_schema.XgboostModelBlobOptions({"xgb_estimator_type": model.__class__.__name__}), ) model_meta.models[name] = base_meta @@ -177,11 +184,12 @@ def get_prediction( ], check_local_version=True, ) - if kwargs.get("enable_explainability", False): + if kwargs.get("enable_explainability", True): model_meta.env.include_if_absent( [model_env.ModelDependency(requirement="shap", pip_name="shap")], check_local_version=True, ) + model_meta.explain_algorithm = model_meta_schema.ModelExplainAlgorithm.SHAP model_meta.env.cuda_version = kwargs.get("cuda_version", model_env.DEFAULT_CUDA_VERSION) @classmethod @@ -224,6 +232,7 @@ def convert_as_custom_model( cls, raw_model: Union["xgboost.Booster", "xgboost.XGBModel"], model_meta: model_meta_api.ModelMetadata, + background_data: Optional[pd.DataFrame] = None, **kwargs: Unpack[model_types.XGBModelLoadOptions], ) -> custom_model.CustomModel: import xgboost diff --git a/snowflake/ml/model/_packager/model_handlers_test/catboost_test.py b/snowflake/ml/model/_packager/model_handlers_test/catboost_test.py index 2ceca39c..d14ff98b 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/catboost_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/catboost_test.py @@ -15,7 +15,7 @@ class CatBoostHandlerTest(absltest.TestCase): - def test_catboost_classifier(self) -> None: + def test_catboost_classifier_explain_disabled(self) -> None: cal_data = datasets.load_breast_cancer() cal_X = pd.DataFrame(cal_data.data, columns=cal_data.feature_names) cal_y = pd.Series(cal_data.target) @@ -34,6 +34,7 @@ def test_catboost_classifier(self) -> None: model=classifier, signatures={**s, "another_predict": s["predict"]}, metadata={"author": "halu", "version": "1"}, + options=model_types.CatBoostModelSaveOptions(enable_explainability=False), ) model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( @@ -41,6 +42,7 @@ def test_catboost_classifier(self) -> None: model=classifier, signatures=s, metadata={"author": "halu", "version": "1"}, + options=model_types.CatBoostModelSaveOptions(enable_explainability=False), ) with warnings.catch_warnings(): @@ -65,6 +67,7 @@ def test_catboost_classifier(self) -> None: model=classifier, sample_input_data=cal_X_test, metadata={"author": "halu", "version": "1"}, + options=model_types.CatBoostModelSaveOptions(enable_explainability=False), ) pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) @@ -103,18 +106,17 @@ def test_catboost_explainablity_enabled(self) -> None: with tempfile.TemporaryDirectory() as tmpdir: s = {"predict": model_signature.infer_signature(cal_X_test, y_pred)} - model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( - name="model1", + model_packager.ModelPackager(os.path.join(tmpdir, "model1_default_explain")).save( + name="model1_default_explain", model=classifier, signatures=s, metadata={"author": "halu", "version": "1"}, - options=model_types.CatBoostModelSaveOptions(enable_explainability=True), ) with warnings.catch_warnings(): warnings.simplefilter("error") - pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1")) + pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_default_explain")) pk.load(as_custom_model=True) predict_method = getattr(pk.model, "predict", None) explain_method = getattr(pk.model, "explain", None) @@ -128,7 +130,6 @@ def test_catboost_explainablity_enabled(self) -> None: model=classifier, sample_input_data=cal_X_test, metadata={"author": "halu", "version": "1"}, - options=model_types.CatBoostModelSaveOptions(enable_explainability=True), ) pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) @@ -143,6 +144,19 @@ def test_catboost_explainablity_enabled(self) -> None: assert callable(explain_method) np.testing.assert_allclose(explain_method(cal_X_test), explanations) + model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig_explain_enabled")).save( + name="model1_no_sig_explain_enabled", + model=classifier, + sample_input_data=cal_X_test, + metadata={"author": "halu", "version": "1"}, + options=model_types.CatBoostModelSaveOptions(enable_explainability=True), + ) + pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig_explain_enabled")) + pk.load(as_custom_model=True) + explain_method = getattr(pk.model, "explain", None) + assert callable(explain_method) + np.testing.assert_allclose(explain_method(cal_X_test), explanations) + def test_catboost_multiclass_explainablity_enabled(self) -> None: cal_data = datasets.load_iris() cal_X = pd.DataFrame(cal_data.data, columns=cal_data.feature_names) @@ -163,7 +177,6 @@ def test_catboost_multiclass_explainablity_enabled(self) -> None: model=classifier, signatures=s, metadata={"author": "halu", "version": "1"}, - options=model_types.CatBoostModelSaveOptions(enable_explainability=True), ) with warnings.catch_warnings(): @@ -185,7 +198,6 @@ def test_catboost_multiclass_explainablity_enabled(self) -> None: model=classifier, sample_input_data=cal_X_test, metadata={"author": "halu", "version": "1"}, - options=model_types.CatBoostModelSaveOptions(enable_explainability=True), ) pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) diff --git a/snowflake/ml/model/_packager/model_handlers_test/custom_test.py b/snowflake/ml/model/_packager/model_handlers_test/custom_test.py index 516cd35c..af3cf174 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/custom_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/custom_test.py @@ -102,6 +102,15 @@ def test_custom_model_with_multiple_artifacts(self) -> None: arr = np.array([[1, 2, 3], [4, 2, 5]]) d = pd.DataFrame(arr, columns=["c1", "c2", "c3"]) s = {"predict": model_signature.infer_signature(d, lm.predict(d))} + with self.assertRaises(NotImplementedError): + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1", + model=lm, + signatures=s, + metadata={"author": "halu", "version": "1"}, + options={"enable_explainability": True}, + ) + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( name="model1", model=lm, diff --git a/snowflake/ml/model/_packager/model_handlers_test/huggingface_pipeline_test.py b/snowflake/ml/model/_packager/model_handlers_test/huggingface_pipeline_test.py index fed0b116..f4373cfa 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/huggingface_pipeline_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/huggingface_pipeline_test.py @@ -108,6 +108,14 @@ def _basic_test_case( signatures={**s, "another_predict": s["__call__"]}, metadata={"author": "halu", "version": "1"}, ) + with self.assertRaises(NotImplementedError): + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1", + model=model, + signatures=s, + metadata={"author": "halu", "version": "1"}, + options={"enable_explainability": True}, + ) model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( name="model1", diff --git a/snowflake/ml/model/_packager/model_handlers_test/lightgbm_test.py b/snowflake/ml/model/_packager/model_handlers_test/lightgbm_test.py index e093d8b7..a3ad3ba8 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/lightgbm_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/lightgbm_test.py @@ -15,7 +15,7 @@ class LightGBMHandlerTest(absltest.TestCase): - def test_lightgbm_booster(self) -> None: + def test_lightgbm_booster_explainability_disabled(self) -> None: cal_data = datasets.load_breast_cancer() cal_X = pd.DataFrame(cal_data.data, columns=cal_data.feature_names) cal_y = pd.Series(cal_data.target) @@ -32,6 +32,7 @@ def test_lightgbm_booster(self) -> None: model=regressor, signatures={**s, "another_predict": s["predict"]}, metadata={"author": "halu", "version": "1"}, + options=model_types.LGBMModelSaveOptions(enable_explainability=False), ) model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( @@ -39,6 +40,7 @@ def test_lightgbm_booster(self) -> None: model=regressor, signatures=s, metadata={"author": "halu", "version": "1"}, + options=model_types.LGBMModelSaveOptions(enable_explainability=False), ) with warnings.catch_warnings(): @@ -63,6 +65,7 @@ def test_lightgbm_booster(self) -> None: model=regressor, sample_input_data=cal_X_test, metadata={"author": "halu", "version": "1"}, + options=model_types.LGBMModelSaveOptions(enable_explainability=False), ) pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) @@ -100,7 +103,6 @@ def test_lightgbm_booster_explainablity_enabled(self) -> None: model=regressor, signatures=s, metadata={"author": "halu", "version": "1"}, - options=model_types.LGBMModelSaveOptions(enable_explainability=True), ) with warnings.catch_warnings(): @@ -130,7 +132,6 @@ def test_lightgbm_booster_explainablity_enabled(self) -> None: model=regressor, sample_input_data=cal_X_test, metadata={"author": "halu", "version": "1"}, - options=model_types.LGBMModelSaveOptions(enable_explainability=True), ) pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) @@ -148,7 +149,7 @@ def test_lightgbm_booster_explainablity_enabled(self) -> None: test_utils.convert2D_json_to_3D(explain_method(cal_X_test).to_numpy()), explanations ) - def test_lightgbm_classifier(self) -> None: + def test_lightgbm_classifier_explainability_disabled(self) -> None: cal_data = datasets.load_breast_cancer() cal_X = pd.DataFrame(cal_data.data, columns=cal_data.feature_names) cal_y = pd.Series(cal_data.target) @@ -167,6 +168,7 @@ def test_lightgbm_classifier(self) -> None: model=classifier, signatures={**s, "another_predict": s["predict"]}, metadata={"author": "halu", "version": "1"}, + options=model_types.LGBMModelSaveOptions(enable_explainability=False), ) model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( @@ -174,6 +176,7 @@ def test_lightgbm_classifier(self) -> None: model=classifier, signatures=s, metadata={"author": "halu", "version": "1"}, + options=model_types.LGBMModelSaveOptions(enable_explainability=False), ) with warnings.catch_warnings(): @@ -198,6 +201,7 @@ def test_lightgbm_classifier(self) -> None: model=classifier, sample_input_data=cal_X_test, metadata={"author": "halu", "version": "1"}, + options=model_types.LGBMModelSaveOptions(enable_explainability=False), ) pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) @@ -241,7 +245,6 @@ def test_lightgbm_classifier_explainablity_enabled(self) -> None: model=classifier, signatures=s, metadata={"author": "halu", "version": "1"}, - options=model_types.LGBMModelSaveOptions(enable_explainability=True), ) with warnings.catch_warnings(): @@ -271,7 +274,6 @@ def test_lightgbm_classifier_explainablity_enabled(self) -> None: model=classifier, sample_input_data=cal_X_test, metadata={"author": "halu", "version": "1"}, - options=model_types.LGBMModelSaveOptions(enable_explainability=True), ) pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) diff --git a/snowflake/ml/model/_packager/model_handlers_test/mlflow_test.py b/snowflake/ml/model/_packager/model_handlers_test/mlflow_test.py index 86b65592..17d6c767 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/mlflow_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/mlflow_test.py @@ -209,6 +209,7 @@ def test_mlflow_model_bad_case(self) -> None: local_path = mlflow.artifacts.download_artifacts(f"runs:/{run_id}/model", dst_path=tmpdir) mlflow_pyfunc_model = mlflow.pyfunc.load_model(local_path) mlflow_pyfunc_model.metadata.run_id = uuid.uuid4().hex.lower() + with self.assertRaisesRegex(ValueError, "Cannot load MLFlow model artifacts."): model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( name="model1", @@ -227,6 +228,18 @@ def test_mlflow_model_bad_case(self) -> None: self.assertEmpty(pk.meta.env.pip_requirements) + with self.assertRaises(NotImplementedError): + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1", + model=mlflow_pyfunc_model, + options={ + "model_uri": local_path, + "ignore_mlflow_dependencies": True, + "relax_version": False, + "enable_explainability": True, + }, + ) + with self.assertRaisesRegex(ValueError, "Cannot load MLFlow model dependencies."): model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( name="model1", model=mlflow_pyfunc_model, options={"relax_version": False} diff --git a/snowflake/ml/model/_packager/model_handlers_test/pytorch_test.py b/snowflake/ml/model/_packager/model_handlers_test/pytorch_test.py index 43f56084..652c1e23 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/pytorch_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/pytorch_test.py @@ -62,6 +62,15 @@ def test_pytorch(self) -> None: metadata={"author": "halu", "version": "1"}, ) + with self.assertRaises(NotImplementedError): + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1", + model=model, + signatures=s, + metadata={"author": "halu", "version": "1"}, + options={"enable_explainability": True}, + ) + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( name="model1", model=model, diff --git a/snowflake/ml/model/_packager/model_handlers_test/sentence_transformers_test.py b/snowflake/ml/model/_packager/model_handlers_test/sentence_transformers_test.py index 58fdb337..a1b93202 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/sentence_transformers_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/sentence_transformers_test.py @@ -63,6 +63,15 @@ def test_sentence_transformers(self) -> None: metadata={"author": "halu", "version": "1"}, ) + with self.assertRaises(NotImplementedError): + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1", + model=model, + signatures=sig, + metadata={"author": "halu", "version": "1"}, + options={"enable_explainability": True}, + ) + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( name="model1", model=model, diff --git a/snowflake/ml/model/_packager/model_handlers_test/sklearn_test.py b/snowflake/ml/model/_packager/model_handlers_test/sklearn_test.py index 2f3e7123..d49cd837 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/sklearn_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/sklearn_test.py @@ -4,6 +4,7 @@ import numpy as np import pandas as pd +import shap from absl.testing import absltest from sklearn import datasets, ensemble, linear_model, multioutput @@ -94,6 +95,70 @@ def test_skl_multiple_output_proba(self) -> None: assert callable(predict_method) np.testing.assert_allclose(model.predict(iris_X_df[-10:]), predict_method(iris_X_df[-10:]).to_numpy()) + def test_skl_unsupported_explain(self) -> None: + iris_X, iris_y = datasets.load_iris(return_X_y=True) + target2 = np.random.randint(0, 6, size=iris_y.shape) + dual_target = np.vstack([iris_y, target2]).T + model = multioutput.MultiOutputClassifier(ensemble.RandomForestClassifier(random_state=42)) + iris_X_df = pd.DataFrame(iris_X, columns=["c1", "c2", "c3", "c4"]) + model.fit(iris_X_df[:-10], dual_target[:-10]) + with tempfile.TemporaryDirectory() as tmpdir: + s = {"predict_proba": model_signature.infer_signature(iris_X_df, model.predict_proba(iris_X_df))} + with self.assertRaisesRegex( + ValueError, + "Sample input data is required to enable explainability. Currently we only support this for " + + "`pandas.DataFrame` and `snowflake.snowpark.dataframe.DataFrame`.", + ): + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1", + model=model, + signatures=s, + metadata={"author": "halu", "version": "1"}, + conda_dependencies=["scikit-learn"], + options=model_types.SKLModelSaveOptions(enable_explainability=True), + ) + + model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")).save( + name="model1_no_sig", + model=model, + sample_input_data=iris_X_df, + metadata={"author": "halu", "version": "1"}, + options=model_types.SKLModelSaveOptions(enable_explainability=True), + ) + + pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) + pk.load() + assert pk.model + assert pk.meta + assert isinstance(pk.model, multioutput.MultiOutputClassifier) + np.testing.assert_allclose( + np.hstack(model.predict_proba(iris_X_df[-10:])), np.hstack(pk.model.predict_proba(iris_X_df[-10:])) + ) + np.testing.assert_allclose(model.predict(iris_X_df[-10:]), pk.model.predict(iris_X_df[-10:])) + self.assertEqual(s["predict_proba"], pk.meta.signatures["predict_proba"]) + + pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) + pk.load(as_custom_model=True) + assert pk.model + assert pk.meta + + predict_method = getattr(pk.model, "predict_proba", None) + assert callable(predict_method) + udf_res = predict_method(iris_X_df[-10:]) + np.testing.assert_allclose( + np.hstack(model.predict_proba(iris_X_df[-10:])), + np.hstack([np.array(udf_res[col].to_list()) for col in udf_res]), + ) + + predict_method = getattr(pk.model, "predict", None) + assert callable(predict_method) + np.testing.assert_allclose(model.predict(iris_X_df[-10:]), predict_method(iris_X_df[-10:]).to_numpy()) + + explain_method = getattr(pk.model, "explain", None) + assert callable(explain_method) + with self.assertRaises(ValueError): + explain_method(iris_X_df[-10:]) + def test_skl(self) -> None: iris_X, iris_y = datasets.load_iris(return_X_y=True) regr = linear_model.LinearRegression() @@ -157,6 +222,49 @@ def test_skl(self) -> None: assert callable(predict_method) np.testing.assert_allclose(np.array([[-0.08254936]]), predict_method(iris_X_df[:1])) + def test_skl_explain(self) -> None: + iris_X, iris_y = datasets.load_iris(return_X_y=True) + regr = linear_model.LinearRegression() + iris_X_df = pd.DataFrame(iris_X, columns=["c1", "c2", "c3", "c4"]) + regr.fit(iris_X_df, iris_y) + explanations = shap.Explainer(regr, iris_X_df)(iris_X_df).values + with tempfile.TemporaryDirectory() as tmpdir: + s = {"predict": model_signature.infer_signature(iris_X_df, regr.predict(iris_X_df))} + with self.assertRaisesRegex( + ValueError, + "Sample input data is required to enable explainability. Currently we only support this for " + + "`pandas.DataFrame` and `snowflake.snowpark.dataframe.DataFrame`.", + ): + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1", + model=regr, + signatures=s, + metadata={"author": "halu", "version": "1"}, + options=model_types.SKLModelSaveOptions(enable_explainability=True), + ) + + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1_no_sig", + model=regr, + sample_input_data=iris_X_df, + metadata={"author": "halu", "version": "1"}, + options=model_types.SKLModelSaveOptions(enable_explainability=True), + ) + + with warnings.catch_warnings(): + warnings.simplefilter("error") + + pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1")) + pk.load(as_custom_model=True) + assert pk.model + assert pk.meta + predict_method = getattr(pk.model, "predict", None) + explain_method = getattr(pk.model, "explain", None) + assert callable(predict_method) + assert callable(explain_method) + np.testing.assert_allclose(np.array([[-0.08254936]]), predict_method(iris_X_df[:1])) + np.testing.assert_allclose(explain_method(iris_X_df), explanations) + if __name__ == "__main__": absltest.main() diff --git a/snowflake/ml/model/_packager/model_handlers_test/snowmlmodel_test.py b/snowflake/ml/model/_packager/model_handlers_test/snowmlmodel_test.py index 8157fb1a..5fbb8147 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/snowmlmodel_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/snowmlmodel_test.py @@ -31,6 +31,14 @@ def test_snowml_all_input(self) -> None: with tempfile.TemporaryDirectory() as tmpdir: s = {"predict": model_signature.infer_signature(df[INPUT_COLUMNS], regr.predict(df)[[OUTPUT_COLUMNS]])} + with self.assertRaises(NotImplementedError): + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1", + model=regr, + metadata={"author": "halu", "version": "1"}, + options={"enable_explainability": True}, + ) + with self.assertWarnsRegex(UserWarning, "Model signature will automatically be inferred during fitting"): model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( name="model1", diff --git a/snowflake/ml/model/_packager/model_handlers_test/tensorflow_test.py b/snowflake/ml/model/_packager/model_handlers_test/tensorflow_test.py index 17a80b0e..aacd7307 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/tensorflow_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/tensorflow_test.py @@ -72,6 +72,15 @@ def test_tensorflow(self) -> None: metadata={"author": "halu", "version": "1"}, ) + with self.assertRaises(NotImplementedError): + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1", + model=simple_module, + signatures=s, + metadata={"author": "halu", "version": "1"}, + options={"enable_explainability": True}, + ) + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( name="model1", model=simple_module, diff --git a/snowflake/ml/model/_packager/model_handlers_test/torchscript_test.py b/snowflake/ml/model/_packager/model_handlers_test/torchscript_test.py index d9b8d610..4ad227ab 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/torchscript_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/torchscript_test.py @@ -63,6 +63,14 @@ def test_torchscript(self) -> None: signatures={**s, "another_forward": s["forward"]}, metadata={"author": "halu", "version": "1"}, ) + with self.assertRaises(NotImplementedError): + model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( + name="model1", + model=model_script, + signatures=s, + metadata={"author": "halu", "version": "1"}, + options={"enable_explainability": True}, + ) model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( name="model1", diff --git a/snowflake/ml/model/_packager/model_handlers_test/xgboost_test.py b/snowflake/ml/model/_packager/model_handlers_test/xgboost_test.py index e1ffcbc9..2886d869 100644 --- a/snowflake/ml/model/_packager/model_handlers_test/xgboost_test.py +++ b/snowflake/ml/model/_packager/model_handlers_test/xgboost_test.py @@ -14,7 +14,7 @@ class XgboostHandlerTest(absltest.TestCase): - def test_xgb_booster(self) -> None: + def test_xgb_booster_explainability_disabled(self) -> None: cal_data = datasets.load_breast_cancer() cal_X = pd.DataFrame(cal_data.data, columns=cal_data.feature_names) cal_y = pd.Series(cal_data.target) @@ -30,6 +30,7 @@ def test_xgb_booster(self) -> None: model=regressor, signatures={**s, "another_predict": s["predict"]}, metadata={"author": "halu", "version": "1"}, + options=model_types.XGBModelSaveOptions(enable_explainability=False), ) model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( @@ -61,6 +62,7 @@ def test_xgb_booster(self) -> None: model=regressor, sample_input_data=cal_X_test, metadata={"author": "halu", "version": "1"}, + options=model_types.XGBModelSaveOptions(enable_explainability=False), ) pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) @@ -79,7 +81,7 @@ def test_xgb_booster(self) -> None: assert callable(predict_method) np.testing.assert_allclose(predict_method(cal_X_test), np.expand_dims(y_pred, axis=1)) - def test_xgb(self) -> None: + def test_xgb_explainability_disabled(self) -> None: cal_data = datasets.load_breast_cancer() cal_X = pd.DataFrame(cal_data.data, columns=cal_data.feature_names) cal_y = pd.Series(cal_data.target) @@ -96,6 +98,7 @@ def test_xgb(self) -> None: model=classifier, signatures={**s, "another_predict": s["predict"]}, metadata={"author": "halu", "version": "1"}, + options=model_types.XGBModelSaveOptions(enable_explainability=False), ) model_packager.ModelPackager(os.path.join(tmpdir, "model1")).save( @@ -127,6 +130,7 @@ def test_xgb(self) -> None: model=classifier, sample_input_data=cal_X_test, metadata={"author": "halu", "version": "1"}, + options=model_types.XGBModelSaveOptions(enable_explainability=False), ) pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) @@ -167,7 +171,6 @@ def test_xgb_explainablity_enabled(self) -> None: model=classifier, signatures={"predict": model_signature.infer_signature(cal_X_test, y_pred)}, metadata={"author": "halu", "version": "1"}, - options=model_types.XGBModelSaveOptions(enable_explainability=True), ) with warnings.catch_warnings(): @@ -187,7 +190,6 @@ def test_xgb_explainablity_enabled(self) -> None: model=classifier, sample_input_data=cal_X_test, metadata={"author": "halu", "version": "1"}, - options=model_types.XGBModelSaveOptions(enable_explainability=True), ) pk = model_packager.ModelPackager(os.path.join(tmpdir, "model1_no_sig")) diff --git a/snowflake/ml/model/_packager/model_meta/model_meta.py b/snowflake/ml/model/_packager/model_meta/model_meta.py index 22df3877..78704618 100644 --- a/snowflake/ml/model/_packager/model_meta/model_meta.py +++ b/snowflake/ml/model/_packager/model_meta/model_meta.py @@ -237,6 +237,7 @@ class ModelMetadata: function_properties: A dict mapping function names to dict mapping function property key to value. metadata: User provided key-value metadata of the model. Defaults to None. creation_timestamp: Unix timestamp when the model metadata is created. + model_objective: Model objective like regression, classification etc. """ def telemetry_metadata(self) -> ModelMetadataTelemetryDict: @@ -260,6 +261,8 @@ def __init__( min_snowpark_ml_version: Optional[str] = None, models: Optional[Dict[str, model_blob_meta.ModelBlobMeta]] = None, original_metadata_version: Optional[str] = model_meta_schema.MODEL_METADATA_VERSION, + model_objective: Optional[model_meta_schema.ModelObjective] = model_meta_schema.ModelObjective.UNKNOWN, + explain_algorithm: Optional[model_meta_schema.ModelExplainAlgorithm] = None, ) -> None: self.name = name self.signatures: Dict[str, model_signature.ModelSignature] = dict() @@ -284,6 +287,11 @@ def __init__( self.original_metadata_version = original_metadata_version + self.model_objective: model_meta_schema.ModelObjective = ( + model_objective or model_meta_schema.ModelObjective.UNKNOWN + ) + self.explain_algorithm: Optional[model_meta_schema.ModelExplainAlgorithm] = explain_algorithm + @property def min_snowpark_ml_version(self) -> str: return self._min_snowpark_ml_version.base_version @@ -321,9 +329,11 @@ def save(self, model_dir_path: str) -> None: model_dict = model_meta_schema.ModelMetadataDict( { "creation_timestamp": self.creation_timestamp, - "env": self.env.save_as_dict(pathlib.Path(model_dir_path)), + "env": self.env.save_as_dict( + pathlib.Path(model_dir_path), default_channel_override=env_utils.SNOWFLAKE_CONDA_CHANNEL_URL + ), "runtimes": { - runtime_name: runtime.save(pathlib.Path(model_dir_path)) + runtime_name: runtime.save(pathlib.Path(model_dir_path), default_channel_override="conda-forge") for runtime_name, runtime in self.runtimes.items() }, "metadata": self.metadata, @@ -333,6 +343,13 @@ def save(self, model_dir_path: str) -> None: "signatures": {func_name: sig.to_dict() for func_name, sig in self.signatures.items()}, "version": model_meta_schema.MODEL_METADATA_VERSION, "min_snowpark_ml_version": self.min_snowpark_ml_version, + "model_objective": self.model_objective.value, + "explainability": ( + model_meta_schema.ExplainabilityMetadataDict(algorithm=self.explain_algorithm.value) + if self.explain_algorithm + else None + ), + "function_properties": self.function_properties, } ) @@ -370,6 +387,9 @@ def _validate_model_metadata(loaded_meta: Any) -> model_meta_schema.ModelMetadat signatures=loaded_meta["signatures"], version=original_loaded_meta_version, min_snowpark_ml_version=loaded_meta_min_snowpark_ml_version, + model_objective=loaded_meta.get("model_objective", model_meta_schema.ModelObjective.UNKNOWN.value), + explainability=loaded_meta.get("explainability", None), + function_properties=loaded_meta.get("function_properties", {}), ) @classmethod @@ -406,6 +426,11 @@ def load(cls, model_dir_path: str) -> "ModelMetadata": else: runtimes = None + explanation_algorithm_dict = model_dict.get("explainability", None) + explanation_algorithm = None + if explanation_algorithm_dict: + explanation_algorithm = model_meta_schema.ModelExplainAlgorithm(explanation_algorithm_dict["algorithm"]) + return cls( name=model_dict["name"], model_type=model_dict["model_type"], @@ -417,4 +442,9 @@ def load(cls, model_dir_path: str) -> "ModelMetadata": min_snowpark_ml_version=model_dict["min_snowpark_ml_version"], models=models, original_metadata_version=model_dict["version"], + model_objective=model_meta_schema.ModelObjective( + model_dict.get("model_objective", model_meta_schema.ModelObjective.UNKNOWN.value) + ), + explain_algorithm=explanation_algorithm, + function_properties=model_dict.get("function_properties", {}), ) diff --git a/snowflake/ml/model/_packager/model_meta/model_meta_schema.py b/snowflake/ml/model/_packager/model_meta/model_meta_schema.py index 1e068005..22efeb01 100644 --- a/snowflake/ml/model/_packager/model_meta/model_meta_schema.py +++ b/snowflake/ml/model/_packager/model_meta/model_meta_schema.py @@ -71,6 +71,10 @@ class XgboostModelBlobOptions(BaseModelBlobOptions): ] +class ExplainabilityMetadataDict(TypedDict): + algorithm: Required[str] + + class ModelBlobMetadataDict(TypedDict): name: Required[str] model_type: Required[type_hints.SupportedModelHandlerType] @@ -92,3 +96,18 @@ class ModelMetadataDict(TypedDict): signatures: Required[Dict[str, Dict[str, Any]]] version: Required[str] min_snowpark_ml_version: Required[str] + model_objective: Required[str] + explainability: NotRequired[Optional[ExplainabilityMetadataDict]] + function_properties: NotRequired[Dict[str, Dict[str, Any]]] + + +class ModelObjective(Enum): + UNKNOWN = "unknown" + BINARY_CLASSIFICATION = "binary_classification" + MULTI_CLASSIFICATION = "multi_classification" + REGRESSION = "regression" + RANKING = "ranking" + + +class ModelExplainAlgorithm(Enum): + SHAP = "shap" diff --git a/snowflake/ml/model/_packager/model_meta/model_meta_test.py b/snowflake/ml/model/_packager/model_meta/model_meta_test.py index 6aaab867..be3f9432 100644 --- a/snowflake/ml/model/_packager/model_meta/model_meta_test.py +++ b/snowflake/ml/model/_packager/model_meta/model_meta_test.py @@ -9,7 +9,11 @@ from snowflake.ml._internal import env as snowml_env, env_utils from snowflake.ml.model import model_signature from snowflake.ml.model._packager.model_env import model_env -from snowflake.ml.model._packager.model_meta import model_blob_meta, model_meta +from snowflake.ml.model._packager.model_meta import ( + model_blob_meta, + model_meta, + model_meta_schema, +) _DUMMY_SIG = { "predict": model_signature.ModelSignature( @@ -641,6 +645,9 @@ def test_model_meta_metadata(self) -> None: ) as meta: meta.models["model1"] = _DUMMY_BLOB + self.assertEqual(meta.model_objective, model_meta_schema.ModelObjective.UNKNOWN) + self.assertEqual(meta.explain_algorithm, None) + saved_meta = meta loaded_meta = model_meta.ModelMetadata.load(tmpdir) @@ -669,6 +676,38 @@ def test_model_meta_check(self) -> None: with self.assertRaisesRegex(ValueError, "Unable to get the version of the metadata file."): model_meta.ModelMetadata.load(tmpdir) + def test_model_meta_model_specified_objective(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + with model_meta.create_model_metadata( + model_dir_path=tmpdir, + name="model1", + model_type="custom", + signatures=_DUMMY_SIG, + metadata={"foo": "bar"}, + ) as meta: + meta.models["model1"] = _DUMMY_BLOB + meta.model_objective = model_meta_schema.ModelObjective.REGRESSION + + loaded_meta = model_meta.ModelMetadata.load(tmpdir) + self.assertEqual(loaded_meta.model_objective, model_meta_schema.ModelObjective.REGRESSION) + + def test_model_meta_explain_algorithm(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + with model_meta.create_model_metadata( + model_dir_path=tmpdir, + name="model1", + model_type="custom", + signatures=_DUMMY_SIG, + metadata={"foo": "bar"}, + ) as meta: + meta.models["model1"] = _DUMMY_BLOB + meta.model_objective = model_meta_schema.ModelObjective.REGRESSION + meta.explain_algorithm = model_meta_schema.ModelExplainAlgorithm.SHAP + + loaded_meta = model_meta.ModelMetadata.load(tmpdir) + self.assertEqual(loaded_meta.model_objective, model_meta_schema.ModelObjective.REGRESSION) + self.assertEqual(loaded_meta.explain_algorithm, model_meta_schema.ModelExplainAlgorithm.SHAP) + def test_model_meta_new_fields(self) -> None: with tempfile.TemporaryDirectory() as tmpdir: with model_meta.create_model_metadata( @@ -737,6 +776,8 @@ def test_model_meta_runtimes(self) -> None: self.assertContainsSubset(["pytorch"], meta.env.conda_dependencies) self.assertContainsSubset(["pytorch"], meta.runtimes["cpu"].runtime_env.conda_dependencies) + with open(os.path.join(tmpdir, "runtimes", "cpu", "env", "conda.yml"), encoding="utf-8") as f: + self.assertListEqual(yaml.safe_load(f)["channels"], ["conda-forge", "nodefaults"]) loaded_meta = model_meta.ModelMetadata.load(tmpdir) self.assertContainsSubset(["pytorch"], loaded_meta.runtimes["cpu"].runtime_env.conda_dependencies) @@ -753,10 +794,14 @@ def test_model_meta_runtimes_gpu(self) -> None: self.assertContainsSubset(["pytorch"], meta.env.conda_dependencies) self.assertContainsSubset(["pytorch"], meta.runtimes["cpu"].runtime_env.conda_dependencies) + with open(os.path.join(tmpdir, "runtimes", "cpu", "env", "conda.yml"), encoding="utf-8") as f: + self.assertListEqual(yaml.safe_load(f)["channels"], ["conda-forge", "nodefaults"]) self.assertContainsSubset( ["nvidia::cuda==11.7.*", "pytorch::pytorch", "pytorch::pytorch-cuda==11.7.*"], meta.runtimes["gpu"].runtime_env.conda_dependencies, ) + with open(os.path.join(tmpdir, "runtimes", "gpu", "env", "conda.yml"), encoding="utf-8") as f: + self.assertListEqual(yaml.safe_load(f)["channels"], ["conda-forge", "pytorch", "nvidia", "nodefaults"]) loaded_meta = model_meta.ModelMetadata.load(tmpdir) self.assertContainsSubset(["pytorch"], loaded_meta.runtimes["cpu"].runtime_env.conda_dependencies) diff --git a/snowflake/ml/model/_packager/model_packager.py b/snowflake/ml/model/_packager/model_packager.py index 6c4185d2..2f06f385 100644 --- a/snowflake/ml/model/_packager/model_packager.py +++ b/snowflake/ml/model/_packager/model_packager.py @@ -146,7 +146,8 @@ def load( m = handler.load_model(self.meta.name, self.meta, model_blobs_path, **options) if as_custom_model: - m = handler.convert_as_custom_model(m, self.meta, **options) + background_data = handler.load_background_data(self.meta.name, model_blobs_path) + m = handler.convert_as_custom_model(m, self.meta, background_data, **options) assert isinstance(m, custom_model.CustomModel) self.model = m diff --git a/snowflake/ml/model/_packager/model_runtime/model_runtime.py b/snowflake/ml/model/_packager/model_runtime/model_runtime.py index 2936498b..81502522 100644 --- a/snowflake/ml/model/_packager/model_runtime/model_runtime.py +++ b/snowflake/ml/model/_packager/model_runtime/model_runtime.py @@ -67,7 +67,9 @@ def __init__( def runtime_rel_path(self) -> pathlib.PurePosixPath: return pathlib.PurePosixPath(ModelRuntime.RUNTIME_DIR_REL_PATH) / self.name - def save(self, packager_path: pathlib.Path) -> model_meta_schema.ModelRuntimeDict: + def save( + self, packager_path: pathlib.Path, default_channel_override: str = env_utils.SNOWFLAKE_CONDA_CHANNEL_URL + ) -> model_meta_schema.ModelRuntimeDict: runtime_base_path = packager_path / self.runtime_rel_path runtime_base_path.mkdir(parents=True, exist_ok=True) @@ -80,7 +82,7 @@ def save(self, packager_path: pathlib.Path) -> model_meta_schema.ModelRuntimeDic self.runtime_env.conda_env_rel_path = self.runtime_rel_path / self.runtime_env.conda_env_rel_path self.runtime_env.pip_requirements_rel_path = self.runtime_rel_path / self.runtime_env.pip_requirements_rel_path - env_dict = self.runtime_env.save_as_dict(packager_path) + env_dict = self.runtime_env.save_as_dict(packager_path, default_channel_override=default_channel_override) return model_meta_schema.ModelRuntimeDict( imports=list(map(str, self.imports)), diff --git a/snowflake/ml/model/_packager/model_runtime/model_runtime_test.py b/snowflake/ml/model/_packager/model_runtime/model_runtime_test.py index 8f50bc51..03f55db8 100644 --- a/snowflake/ml/model/_packager/model_runtime/model_runtime_test.py +++ b/snowflake/ml/model/_packager/model_runtime/model_runtime_test.py @@ -44,6 +44,30 @@ def test_model_runtime(self) -> None: self.assertContainsSubset(["snowflake-ml-python==1.0.0"], dependencies["dependencies"]) + def test_model_runtime_with_channel_override(self) -> None: + with tempfile.TemporaryDirectory() as workspace: + m_env = model_env.ModelEnv() + m_env.snowpark_ml_version = "1.0.0" + + mr = model_runtime.ModelRuntime("cpu", m_env, []) + returned_dict = mr.save(pathlib.Path(workspace), default_channel_override="conda-forge") + + self.assertDictEqual( + returned_dict, + { + "imports": [], + "dependencies": { + "conda": "runtimes/cpu/env/conda.yml", + "pip": "runtimes/cpu/env/requirements.txt", + }, + }, + ) + with open(os.path.join(workspace, "runtimes/cpu/env/conda.yml"), encoding="utf-8") as f: + dependencies = yaml.safe_load(f) + + self.assertContainsSubset(["snowflake-ml-python==1.0.0"], dependencies["dependencies"]) + self.assertEqual(["conda-forge", "nodefaults"], dependencies["channels"]) + def test_model_runtime_with_import(self) -> None: with tempfile.TemporaryDirectory() as workspace: m_env = model_env.ModelEnv() diff --git a/snowflake/ml/model/type_hints.py b/snowflake/ml/model/type_hints.py index 3522bc5e..1726baec 100644 --- a/snowflake/ml/model/type_hints.py +++ b/snowflake/ml/model/type_hints.py @@ -233,12 +233,12 @@ class BaseModelSaveOption(TypedDict): function_type: NotRequired[Literal["FUNCTION", "TABLE_FUNCTION"]] method_options: NotRequired[Dict[str, ModelMethodSaveOptions]] include_pip_dependencies: NotRequired[bool] + enable_explainability: NotRequired[bool] class CatBoostModelSaveOptions(BaseModelSaveOption): target_methods: NotRequired[Sequence[str]] cuda_version: NotRequired[str] - enable_explainability: NotRequired[bool] class CustomModelSaveOption(BaseModelSaveOption): @@ -252,12 +252,10 @@ class SKLModelSaveOptions(BaseModelSaveOption): class XGBModelSaveOptions(BaseModelSaveOption): target_methods: NotRequired[Sequence[str]] cuda_version: NotRequired[str] - enable_explainability: NotRequired[bool] class LGBMModelSaveOptions(BaseModelSaveOption): target_methods: NotRequired[Sequence[str]] - enable_explainability: NotRequired[bool] class SNOWModelSaveOptions(BaseModelSaveOption): diff --git a/snowflake/ml/modeling/framework/base.py b/snowflake/ml/modeling/framework/base.py index 96382c0a..ecfe8b74 100644 --- a/snowflake/ml/modeling/framework/base.py +++ b/snowflake/ml/modeling/framework/base.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import inspect from abc import abstractmethod -from collections import defaultdict from datetime import datetime from typing import Any, Dict, Iterable, List, Mapping, Optional, Union, overload @@ -18,6 +17,7 @@ ) from snowflake.ml._internal.lineage import lineage_utils from snowflake.ml._internal.utils import identifier, parallelize +from snowflake.ml.data import data_source from snowflake.ml.modeling.framework import _utils from snowflake.snowpark import functions as F @@ -246,7 +246,7 @@ def _get_param_names(cls) -> List[str]: def get_params(self, deep: bool = True) -> Dict[str, Any]: """ - Get parameters for this transformer. + Get the snowflake-ml parameters for this transformer. Args: deep: If True, will return the parameters for this transformer and @@ -265,13 +265,13 @@ def get_params(self, deep: bool = True) -> Dict[str, Any]: out[key] = value return out - def set_params(self, **params: Dict[str, Any]) -> None: + def set_params(self, **params: Any) -> None: """ Set the parameters of this transformer. - The method works on simple transformers as well as on nested objects. - The latter have parameters of the form ``__`` - so that it's possible to update each component of a nested object. + The method works on simple transformers as well as on sklearn compatible pipelines with nested + objects, once the transformer has been fit. Nested objects have parameters of the form + ``__`` so that it's possible to update each component of a nested object. Args: **params: Transformer parameter names mapped to their values. @@ -283,12 +283,28 @@ def set_params(self, **params: Dict[str, Any]) -> None: # simple optimization to gain speed (inspect is slow) return valid_params = self.get_params(deep=True) + valid_skl_params = {} + if hasattr(self, "_sklearn_object") and self._sklearn_object is not None: + valid_skl_params = self._sklearn_object.get_params() - nested_params: Dict[str, Any] = defaultdict(dict) # grouped by prefix for key, value in params.items(): - key, delim, sub_key = key.partition("__") - if key not in valid_params: - local_valid_params = self._get_param_names() + if valid_params.get("steps"): + # Recurse through pipeline steps + key, _, sub_key = key.partition("__") + for name, nested_object in valid_params["steps"]: + if name == key: + nested_object.set_params(**{sub_key: value}) + + elif key in valid_params: + setattr(self, key, value) + valid_params[key] = value + elif key in valid_skl_params: + # This dictionary would be empty if the following assert were not true, as specified above. + assert hasattr(self, "_sklearn_object") and self._sklearn_object is not None + setattr(self._sklearn_object, key, value) + valid_skl_params[key] = value + else: + local_valid_params = self._get_param_names() + list(valid_skl_params.keys()) raise exceptions.SnowflakeMLException( error_code=error_codes.INVALID_ARGUMENT, original_exception=ValueError( @@ -298,15 +314,6 @@ def set_params(self, **params: Dict[str, Any]) -> None: ), ) - if delim: - nested_params[key][sub_key] = value - else: - setattr(self, key, value) - valid_params[key] = value - - for key, sub_params in nested_params.items(): - valid_params[key].set_params(**sub_params) - def get_sklearn_args( self, default_sklearn_obj: Optional[object] = None, @@ -427,6 +434,8 @@ def _get_dependencies(self) -> List[str]: def fit(self, dataset: Union[snowpark.DataFrame, pd.DataFrame]) -> "BaseEstimator": """Runs universal logics for all fit implementations.""" data_sources = lineage_utils.get_data_sources(dataset) + if not data_sources and isinstance(dataset, snowpark.DataFrame): + data_sources = [data_source.DataFrameInfo(dataset.queries["queries"][-1])] lineage_utils.set_data_sources(self, data_sources) return self._fit(dataset) diff --git a/snowflake/ml/modeling/pipeline/pipeline.py b/snowflake/ml/modeling/pipeline/pipeline.py index 71168f9f..e4baf152 100644 --- a/snowflake/ml/modeling/pipeline/pipeline.py +++ b/snowflake/ml/modeling/pipeline/pipeline.py @@ -19,6 +19,7 @@ from snowflake.ml._internal.exceptions import error_codes, exceptions from snowflake.ml._internal.lineage import lineage_utils from snowflake.ml._internal.utils import snowpark_dataframe_utils, temp_file_utils +from snowflake.ml.data import data_source from snowflake.ml.model.model_signature import ModelSignature, _infer_signature from snowflake.ml.modeling._internal.model_transformer_builder import ( ModelTransformerBuilder, @@ -431,6 +432,8 @@ def fit(self, dataset: Union[snowpark.DataFrame, pd.DataFrame], squash: Optional # Extract lineage information here since we're overriding fit() directly data_sources = lineage_utils.get_data_sources(dataset) + if not data_sources and isinstance(dataset, snowpark.DataFrame): + data_sources = [data_source.DataFrameInfo(dataset.queries["queries"][-1])] lineage_utils.set_data_sources(self, data_sources) if self._can_be_trained_in_ml_runtime(dataset): diff --git a/snowflake/ml/registry/_manager/BUILD.bazel b/snowflake/ml/registry/_manager/BUILD.bazel index 5e2f75c5..a1015142 100644 --- a/snowflake/ml/registry/_manager/BUILD.bazel +++ b/snowflake/ml/registry/_manager/BUILD.bazel @@ -20,6 +20,7 @@ py_library( "//snowflake/ml/model/_client/model:model_version_impl", "//snowflake/ml/model/_client/ops:metadata_ops", "//snowflake/ml/model/_client/ops:model_ops", + "//snowflake/ml/model/_client/ops:service_ops", "//snowflake/ml/model/_model_composer:model_composer", ], ) diff --git a/snowflake/ml/registry/_manager/model_manager.py b/snowflake/ml/registry/_manager/model_manager.py index bb6a25df..eb347ed2 100644 --- a/snowflake/ml/registry/_manager/model_manager.py +++ b/snowflake/ml/registry/_manager/model_manager.py @@ -9,7 +9,7 @@ from snowflake.ml._internal.utils import sql_identifier from snowflake.ml.model import model_signature, type_hints as model_types from snowflake.ml.model._client.model import model_impl, model_version_impl -from snowflake.ml.model._client.ops import metadata_ops, model_ops +from snowflake.ml.model._client.ops import metadata_ops, model_ops, service_ops from snowflake.ml.model._model_composer import model_composer from snowflake.ml.model._packager.model_meta import model_meta from snowflake.snowpark import session @@ -30,6 +30,9 @@ def __init__( self._model_ops = model_ops.ModelOperator( session, database_name=self._database_name, schema_name=self._schema_name ) + self._service_ops = service_ops.ServiceOperator( + session, database_name=self._database_name, schema_name=self._schema_name + ) self._hrid_generator = hrid_generator.HRID16() def log_model( @@ -173,11 +176,16 @@ def _log_model( ) mv = model_version_impl.ModelVersion._ref( - model_ops.ModelOperator( + model_ops=model_ops.ModelOperator( self._model_ops._session, database_name=database_name_id or self._database_name, schema_name=schema_name_id or self._schema_name, ), + service_ops=service_ops.ServiceOperator( + self._service_ops._session, + database_name=database_name_id or self._database_name, + schema_name=schema_name_id or self._schema_name, + ), model_name=model_name_id, version_name=version_name_id, ) @@ -216,6 +224,11 @@ def get_model( database_name=database_name_id or self._database_name, schema_name=schema_name_id or self._schema_name, ), + service_ops=service_ops.ServiceOperator( + self._service_ops._session, + database_name=database_name_id or self._database_name, + schema_name=schema_name_id or self._schema_name, + ), model_name=model_name_id, ) else: @@ -234,6 +247,7 @@ def models( return [ model_impl.Model._ref( self._model_ops, + service_ops=self._service_ops, model_name=model_name, ) for model_name in model_names diff --git a/snowflake/ml/registry/_manager/model_manager_test.py b/snowflake/ml/registry/_manager/model_manager_test.py index 274515f0..6b988284 100644 --- a/snowflake/ml/registry/_manager/model_manager_test.py +++ b/snowflake/ml/registry/_manager/model_manager_test.py @@ -7,6 +7,7 @@ from snowflake.ml._internal import telemetry from snowflake.ml._internal.utils import sql_identifier from snowflake.ml.model._client.model import model_impl, model_version_impl +from snowflake.ml.model._client.ops import service_ops from snowflake.ml.model._client.ops.model_ops import ModelOperator from snowflake.ml.model._model_composer import model_composer from snowflake.ml.model._packager.model_meta import model_meta @@ -44,6 +45,7 @@ def setUp(self) -> None: with mock.patch.object(model_version_impl.ModelVersion, "_get_functions", return_value=[]): self.m_mv = model_version_impl.ModelVersion._ref( self.m_r._model_ops, + service_ops=self.m_r._service_ops, model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("V1"), ) @@ -51,6 +53,7 @@ def setUp(self) -> None: def test_get_model_1(self) -> None: m_model = model_impl.Model._ref( self.m_r._model_ops, + service_ops=self.m_r._service_ops, model_name=sql_identifier.SqlIdentifier("MODEL"), ) with mock.patch.object(self.m_r._model_ops, "validate_existence", return_value=True) as mock_validate_existence: @@ -83,6 +86,11 @@ def test_get_model_3(self) -> None: database_name=sql_identifier.SqlIdentifier("FOO"), schema_name=sql_identifier.SqlIdentifier("BAR"), ), + service_ops=service_ops.ServiceOperator( + self.c_session, + database_name=sql_identifier.SqlIdentifier("FOO"), + schema_name=sql_identifier.SqlIdentifier("BAR"), + ), model_name=sql_identifier.SqlIdentifier("MODEL"), ) with mock.patch.object(self.m_r._model_ops, "validate_existence", return_value=True) as mock_validate_existence: @@ -98,10 +106,12 @@ def test_get_model_3(self) -> None: def test_models(self) -> None: m_model_1 = model_impl.Model._ref( self.m_r._model_ops, + service_ops=self.m_r._service_ops, model_name=sql_identifier.SqlIdentifier("MODEL"), ) m_model_2 = model_impl.Model._ref( self.m_r._model_ops, + service_ops=self.m_r._service_ops, model_name=sql_identifier.SqlIdentifier("Model", case_sensitive=True), ) with mock.patch.object( @@ -215,6 +225,7 @@ def test_log_model_minimal(self) -> None: mv, model_version_impl.ModelVersion._ref( self.m_r._model_ops, + service_ops=self.m_r._service_ops, model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("angry_yeti_1"), ), @@ -550,6 +561,11 @@ def test_log_model_fully_qualified(self) -> None: database_name=sql_identifier.SqlIdentifier("FOO"), schema_name=sql_identifier.SqlIdentifier("BAR"), ), + service_ops=service_ops.ServiceOperator( + self.c_session, + database_name=sql_identifier.SqlIdentifier("FOO"), + schema_name=sql_identifier.SqlIdentifier("BAR"), + ), model_name=sql_identifier.SqlIdentifier("MODEL"), version_name=sql_identifier.SqlIdentifier("V1"), ), diff --git a/snowflake/ml/utils/BUILD.bazel b/snowflake/ml/utils/BUILD.bazel index 8027be05..8f7a0452 100644 --- a/snowflake/ml/utils/BUILD.bazel +++ b/snowflake/ml/utils/BUILD.bazel @@ -28,6 +28,20 @@ py_test( ], ) +py_library( + name = "sql_client", + srcs = ["sql_client.py"], + deps = [], +) + +py_test( + name = "sql_client_test", + srcs = ["sql_client_test.py"], + deps = [ + ":sql_client", + ], +) + py_package( name = "utils_pkg", packages = ["snowflake.ml"], diff --git a/snowflake/ml/utils/sql_client.py b/snowflake/ml/utils/sql_client.py new file mode 100644 index 00000000..cd335b57 --- /dev/null +++ b/snowflake/ml/utils/sql_client.py @@ -0,0 +1,22 @@ +from enum import Enum +from typing import Dict + + +class CreationOption(Enum): + FAIL_IF_NOT_EXIST = 1 + CREATE_IF_NOT_EXIST = 2 + OR_REPLACE = 3 + + +class CreationMode: + def __init__(self, *, if_not_exists: bool = False, or_replace: bool = False) -> None: + self.if_not_exists = if_not_exists + self.or_replace = or_replace + + def get_ddl_phrases(self) -> Dict[CreationOption, str]: + if_not_exists_sql = " IF NOT EXISTS" if self.if_not_exists else "" + or_replace_sql = " OR REPLACE" if self.or_replace else "" + return { + CreationOption.CREATE_IF_NOT_EXIST: if_not_exists_sql, + CreationOption.OR_REPLACE: or_replace_sql, + } diff --git a/snowflake/ml/utils/sql_client_test.py b/snowflake/ml/utils/sql_client_test.py new file mode 100644 index 00000000..59f5ec44 --- /dev/null +++ b/snowflake/ml/utils/sql_client_test.py @@ -0,0 +1,25 @@ +from absl.testing import absltest + +from snowflake.ml.utils import sql_client + + +class SqlClientTest(absltest.TestCase): + def test_creation_mode_if_not_exists(self) -> None: + creation_mode = sql_client.CreationMode(if_not_exists=True) + self.assertEqual( + creation_mode.get_ddl_phrases()[sql_client.CreationOption.CREATE_IF_NOT_EXIST], " IF NOT EXISTS" + ) + + creation_mode = sql_client.CreationMode(if_not_exists=False) + self.assertEqual(creation_mode.get_ddl_phrases()[sql_client.CreationOption.CREATE_IF_NOT_EXIST], "") + + def test_creation_mode_or_replace(self) -> None: + creation_mode = sql_client.CreationMode(or_replace=True) + self.assertEqual(creation_mode.get_ddl_phrases()[sql_client.CreationOption.OR_REPLACE], " OR REPLACE") + + creation_mode = sql_client.CreationMode(or_replace=False) + self.assertEqual(creation_mode.get_ddl_phrases()[sql_client.CreationOption.OR_REPLACE], "") + + +if __name__ == "__main__": + absltest.main() diff --git a/snowflake/ml/version.bzl b/snowflake/ml/version.bzl index 92abea7a..442fac15 100644 --- a/snowflake/ml/version.bzl +++ b/snowflake/ml/version.bzl @@ -1,2 +1,2 @@ # This is parsed by regex in conda reciper meta file. Make sure not to break it. -VERSION = "1.6.0" +VERSION = "1.6.1" diff --git a/tests/integ/snowflake/cortex/complete_test.py b/tests/integ/snowflake/cortex/complete_test.py index b292d770..7e22f8de 100644 --- a/tests/integ/snowflake/cortex/complete_test.py +++ b/tests/integ/snowflake/cortex/complete_test.py @@ -92,24 +92,12 @@ def setUp(self) -> None: def tearDown(self) -> None: self._session.close() - def test_non_streaming(self) -> None: - result = Complete( - model=_MODEL_NAME, - prompt=_PROMPT, - session=self._session, - stream=False, - use_rest_api_experimental=True, - ) - self.assertIsInstance(result, str) - self.assertTrue(result) - def test_streaming(self) -> None: result = Complete( model=_MODEL_NAME, prompt=_PROMPT, session=self._session, stream=True, - use_rest_api_experimental=True, ) self.assertIsInstance(result, GeneratorType) for out in result: @@ -122,24 +110,12 @@ def test_streaming_conversation_history(self) -> None: prompt=_CONVERSATION_HISTORY_PROMPT, session=self._session, stream=True, - use_rest_api_experimental=True, ) self.assertIsInstance(result, GeneratorType) for out in result: self.assertIsInstance(out, str) self.assertTrue(out) # nonempty - def test_non_streaming_conversation_history(self) -> None: - result = Complete( - model=_MODEL_NAME, - prompt=_CONVERSATION_HISTORY_PROMPT, - session=self._session, - stream=False, - use_rest_api_experimental=True, - ) - self.assertIsInstance(result, str) - self.assertTrue(result) - def test_streaming_with_options(self) -> None: result = Complete( model=_MODEL_NAME, @@ -147,37 +123,12 @@ def test_streaming_with_options(self) -> None: options=_OPTIONS, session=self._session, stream=True, - use_rest_api_experimental=True, ) self.assertIsInstance(result, GeneratorType) for out in result: self.assertIsInstance(out, str) self.assertTrue(out) # nonempty - def test_non_streaming_with_options(self) -> None: - result = Complete( - model=_MODEL_NAME, - prompt=_PROMPT, - options=_OPTIONS, - session=self._session, - stream=False, - use_rest_api_experimental=True, - ) - self.assertIsInstance(result, str) - self.assertTrue(result) - - def test_non_streaming_with_empty_options(self) -> None: - result = Complete( - model=_MODEL_NAME, - prompt=_PROMPT, - options=CompleteOptions(), - session=self._session, - stream=False, - use_rest_api_experimental=True, - ) - self.assertIsInstance(result, str) - self.assertTrue(result) - if __name__ == "__main__": absltest.main() diff --git a/tests/integ/snowflake/ml/data/BUILD.bazel b/tests/integ/snowflake/ml/data/BUILD.bazel new file mode 100644 index 00000000..2392dc8e --- /dev/null +++ b/tests/integ/snowflake/ml/data/BUILD.bazel @@ -0,0 +1,18 @@ +load("//bazel:py_rules.bzl", "py_test") + +package(default_visibility = [ + "//bazel:snowml_public_common", +]) + +py_test( + name = "data_connector_integ_test", + srcs = ["data_connector_integ_test.py"], + shard_count = 8, + deps = [ + "//snowflake/ml/data", + "//snowflake/ml/dataset", + "//tests/integ/snowflake/ml/fileset:fileset_integ_utils", + "//tests/integ/snowflake/ml/test_utils:common_test_base", + "//tests/integ/snowflake/ml/test_utils:db_manager", + ], +) diff --git a/tests/integ/snowflake/ml/data/data_connector_integ_test.py b/tests/integ/snowflake/ml/data/data_connector_integ_test.py new file mode 100644 index 00000000..dc081730 --- /dev/null +++ b/tests/integ/snowflake/ml/data/data_connector_integ_test.py @@ -0,0 +1,251 @@ +import random +from typing import Any, Dict, Generator, List + +import numpy as np +import pandas as pd +import tensorflow # noqa: F401 # SNOW-1502273 test fails if TensorFlow not imported globally +from absl.testing import absltest, parameterized +from numpy import typing as npt + +from snowflake import snowpark +from snowflake.ml import data, dataset +from snowflake.ml.utils import sql_client +from snowflake.snowpark._internal import utils as snowpark_utils +from tests.integ.snowflake.ml.fileset import fileset_integ_utils +from tests.integ.snowflake.ml.test_utils import ( + common_test_base, + db_manager, + test_env_utils, +) + +DC_INTEG_TEST_DB = "DC_INTEG_TEST_DB" +DC_INTEG_TEST_SCHEMA = "DC_INTEG_TEST_SCHEMA" + +np.random.seed(0) +random.seed(0) + + +def create_data_connectors(session: snowpark.Session, create: bool, num_rows: int) -> List[data.DataConnector]: + rst = [] + + # DataFrame connector + query = fileset_integ_utils.get_fileset_query(num_rows) + df = session.sql(query) + rst.append(data.DataConnector.from_dataframe(df)) + + # Dataset connector + ds_name = "test_dataset" + ds_version = "v1" + if create: + ds = dataset.create_from_dataframe(session, ds_name, ds_version, input_dataframe=df) + else: + ds = dataset.load_dataset(session, ds_name, ds_version) + + rst.append(data.DataConnector.from_dataset(ds)) + + return rst + + +class TestDataConnector(common_test_base.CommonTestBase): + """Integration tests for Snowflake Dataset.""" + + def setUp(self) -> None: + # Disable base class setup/teardown in favor of classmethods + pass + + def tearDown(self) -> None: + # Disable base class setup/teardown in favor of classmethods + pass + + @classmethod + def setUpClass(cls) -> None: + super().setUpClass() + cls.session = test_env_utils.get_available_session() + cls.dbm = db_manager.DBManager(cls.session) + + if not snowpark_utils.is_in_stored_procedure(): # type: ignore[no-untyped-call] + cls.dbm.create_database(DC_INTEG_TEST_DB, creation_mode=sql_client.CreationMode(if_not_exists=True)) + cls.dbm.cleanup_schemas(DC_INTEG_TEST_SCHEMA, DC_INTEG_TEST_DB) + cls.dbm.use_database(DC_INTEG_TEST_DB) + + cls.db = cls.session.get_current_database() + cls.schema = cls.dbm.create_random_schema(DC_INTEG_TEST_SCHEMA) + cls.schema = f'"{cls.schema}"' # Need quotes around schema name for regex matches later + else: + cls.db = cls.session.get_current_database() + cls.schema = cls.session.get_current_schema() + + cls.num_rows = 10000 + cls.suts = create_data_connectors( + cls.session, create=(not snowpark_utils.is_in_stored_procedure()), num_rows=cls.num_rows + ) + + @classmethod + def tearDownClass(cls) -> None: + if not snowpark_utils.is_in_stored_procedure(): # type: ignore[no-untyped-call] + cls.dbm.drop_schema(cls.schema, if_exists=True) + cls.session.close() + super().tearDownClass() + + @common_test_base.CommonTestBase.sproc_test() + @parameterized.parameters( # type: ignore[misc] + {"batch_size": 2048, "shuffle": False, "drop_last_batch": False}, + ) + def test_to_tf_dataset(self, batch_size: int, shuffle: bool, drop_last_batch: bool) -> None: + import tensorflow as tf + + def numpy_batch_generator(ds: tf.data.Dataset) -> Generator[Dict[str, npt.NDArray[Any]], None, None]: + for batch in ds: + numpy_batch = {} + for k, v in batch.items(): + self.assertIsInstance(v, tf.Tensor) + self.assertEqual(1, v.shape.rank) + numpy_batch[k] = v.numpy() + yield numpy_batch + + for sut in self.suts: + with self.subTest(type(sut.data_sources[0]).__name__): + self._validate_batches( + batch_size, + drop_last_batch, + numpy_batch_generator( + sut.to_tf_dataset(batch_size=batch_size, shuffle=shuffle, drop_last_batch=drop_last_batch) + ), + ) + + @common_test_base.CommonTestBase.sproc_test() + @parameterized.parameters( # type: ignore[misc] + {"batch_size": 2048, "shuffle": False, "drop_last_batch": False}, + ) + def test_to_torch_datapipe(self, batch_size: int, shuffle: bool, drop_last_batch: bool) -> None: + import torch + import torch.utils.data as torch_data + + def numpy_batch_generator(dp: torch_data.IterDataPipe) -> Generator[Dict[str, npt.NDArray[Any]], None, None]: + for batch in torch_data.DataLoader(dp, batch_size=None, num_workers=0): + numpy_batch = {} + for k, v in batch.items(): + self.assertIsInstance(v, torch.Tensor) + self.assertEqual(1, v.dim()) + numpy_batch[k] = v.numpy() + yield numpy_batch + + for sut in self.suts: + with self.subTest(type(sut.data_sources[0]).__name__): + self._validate_batches( + batch_size, + drop_last_batch, + numpy_batch_generator( + sut.to_torch_datapipe(batch_size=batch_size, shuffle=shuffle, drop_last_batch=drop_last_batch) + ), + ) + + @common_test_base.CommonTestBase.sproc_test() + @parameterized.parameters( # type: ignore[misc] + {"batch_size": 2048, "shuffle": False, "drop_last_batch": False}, + ) + def test_to_torch_dataset(self, batch_size: int, shuffle: bool, drop_last_batch: bool) -> None: + import torch + import torch.utils.data as torch_data + + def numpy_batch_generator(ds: torch_data.Dataset) -> Generator[Dict[str, npt.NDArray[Any]], None, None]: + for batch in torch_data.DataLoader(ds, batch_size=batch_size, drop_last=drop_last_batch, num_workers=0): + numpy_batch = {} + for k, v in batch.items(): + self.assertIsInstance(v, torch.Tensor) + self.assertEqual(1, v.dim()) + numpy_batch[k] = v.numpy() + yield numpy_batch + + for sut in self.suts: + with self.subTest(type(sut.data_sources[0]).__name__): + self._validate_batches( + batch_size, + drop_last_batch, + numpy_batch_generator(sut.to_torch_dataset(shuffle=shuffle)), + ) + + def test_to_pandas(self) -> None: + for sut in self.suts: + with self.subTest(type(sut.data_sources[0]).__name__): + self._validate_pandas(sut.to_pandas()) + + def _validate_batches( + self, + batch_size: int, + drop_last_batch: bool, + numpy_batch_generator: Generator[Dict[str, npt.NDArray[Any]], None, None], + ) -> None: + if drop_last_batch: + expected_num_rows = self.num_rows - self.num_rows % batch_size + else: + expected_num_rows = self.num_rows + + actual_min_counter = { + "NUMBER_INT_COL": float("inf"), + "NUMBER_FIXED_POINT_COL": float("inf"), + } + actual_max_counter = { + "NUMBER_INT_COL": 0.0, + "NUMBER_FIXED_POINT_COL": 0.0, + } + actual_sum_counter = { + "NUMBER_INT_COL": 0.0, + "NUMBER_FIXED_POINT_COL": 0.0, + } + actual_num_rows = 0 + for iteration, batch in enumerate(numpy_batch_generator): + # If drop_last_batch is False, the last batch might not have the same size as the other batches. + if not drop_last_batch and iteration == self.num_rows // batch_size: + expected_batch_size = self.num_rows % batch_size + else: + expected_batch_size = batch_size + + for col_name in ["NUMBER_INT_COL", "NUMBER_FIXED_POINT_COL"]: + col = batch[col_name] + self.assertEqual(col.size, expected_batch_size) + + actual_min_counter[col_name] = min(np.min(col), actual_min_counter[col_name]) + actual_max_counter[col_name] = max(np.max(col), actual_max_counter[col_name]) + actual_sum_counter[col_name] += np.sum(col) + + actual_num_rows += expected_batch_size + + self.assertEqual(actual_num_rows, expected_num_rows) + actual_avg_counter = {"NUMBER_INT_COL": 0.0, "NUMBER_FIXED_POINT_COL": 0.0} + for key, value in actual_sum_counter.items(): + actual_avg_counter[key] = value / actual_num_rows + + if not drop_last_batch: + # We can only get the whole set of data for comparison if drop_last_batch is False. + for key in ["NUMBER_INT_COL", "NUMBER_FIXED_POINT_COL"]: + self.assertAlmostEqual(fileset_integ_utils.get_column_min(key), actual_min_counter[key], 1) + self.assertAlmostEqual( + fileset_integ_utils.get_column_max(key, expected_num_rows), actual_max_counter[key], 1 + ) + self.assertAlmostEqual( + fileset_integ_utils.get_column_avg(key, expected_num_rows), actual_avg_counter[key], 1 + ) + + def _validate_pandas(self, df: pd.DataFrame) -> None: + for key in ["NUMBER_INT_COL", "FLOAT_COL"]: + with self.subTest(key): + self.assertAlmostEqual( + fileset_integ_utils.get_column_min(key), + df[key].min(), + 1, + ) + self.assertAlmostEqual( + fileset_integ_utils.get_column_max(key, self.num_rows), + df[key].max(), + 1, + ) + self.assertAlmostEqual( + fileset_integ_utils.get_column_avg(key, self.num_rows), + df[key].mean(), + delta=1, # FIXME: We lose noticeable precision from data casting (~0.5 error) + ) + + +if __name__ == "__main__": + absltest.main() diff --git a/tests/integ/snowflake/ml/dataset/dataset_integ_test.py b/tests/integ/snowflake/ml/dataset/dataset_integ_test.py index 78485558..3087f67f 100644 --- a/tests/integ/snowflake/ml/dataset/dataset_integ_test.py +++ b/tests/integ/snowflake/ml/dataset/dataset_integ_test.py @@ -462,9 +462,26 @@ def validate_dataset_connectors( ) self._validate_torch_datapipe(pt_dp, batch_size, drop_last_batch) + pt_ds = ds.read.to_torch_dataset(shuffle=datapipe_shuffle) + self._validate_torch_dataset(pt_ds, batch_size, drop_last_batch) + df = ds.read.to_snowpark_dataframe() self._validate_snowpark_dataframe(df) + def _validate_torch_dataset( + self, ds: "data.IterableDataset[Dict[str, Any]]", batch_size: int, drop_last_batch: bool + ) -> None: + def numpy_batch_generator() -> Generator[Dict[str, npt.NDArray[Any]], None, None]: + for batch in data.DataLoader(ds, batch_size=batch_size, drop_last=drop_last_batch, num_workers=0): + numpy_batch = {} + for k, v in batch.items(): + self.assertIsInstance(v, torch.Tensor) + self.assertEqual(1, v.dim()) + numpy_batch[k] = v.numpy() + yield numpy_batch + + self._validate_batches(batch_size, drop_last_batch, numpy_batch_generator) + def _validate_torch_datapipe( self, datapipe: "data.IterDataPipe[Dict[str, npt.NDArray[Any]]]", batch_size: int, drop_last_batch: bool ) -> None: diff --git a/tests/integ/snowflake/ml/dataset/dataset_integ_test_base.py b/tests/integ/snowflake/ml/dataset/dataset_integ_test_base.py index 19177e4d..97c3b707 100644 --- a/tests/integ/snowflake/ml/dataset/dataset_integ_test_base.py +++ b/tests/integ/snowflake/ml/dataset/dataset_integ_test_base.py @@ -6,6 +6,7 @@ from numpy import typing as npt from snowflake.ml import dataset +from snowflake.ml.utils import sql_client from snowflake.snowpark._internal import utils as snowpark_utils from tests.integ.snowflake.ml.fileset import fileset_integ_utils from tests.integ.snowflake.ml.test_utils import ( @@ -41,7 +42,7 @@ def setUpClass(cls) -> None: cls.query = fileset_integ_utils.get_fileset_query(cls.num_rows) cls.test_table = "test_table" if not snowpark_utils.is_in_stored_procedure(): # type: ignore[no-untyped-call] - cls.dbm.create_database(cls.DS_INTEG_TEST_DB, if_not_exists=True) + cls.dbm.create_database(cls.DS_INTEG_TEST_DB, creation_mode=sql_client.CreationMode(if_not_exists=True)) cls.dbm.cleanup_schemas(cls.DS_INTEG_TEST_SCHEMA, cls.DS_INTEG_TEST_DB) cls.dbm.use_database(cls.DS_INTEG_TEST_DB) diff --git a/tests/integ/snowflake/ml/extra_tests/grid_search_on_pipeline_test.py b/tests/integ/snowflake/ml/extra_tests/grid_search_on_pipeline_test.py index a84d0f6f..2aecbc74 100644 --- a/tests/integ/snowflake/ml/extra_tests/grid_search_on_pipeline_test.py +++ b/tests/integ/snowflake/ml/extra_tests/grid_search_on_pipeline_test.py @@ -108,6 +108,10 @@ def test_fit_and_compare_results(self) -> None: sk_predicted = sk_gs.predict(raw_data_pd[feature_cols]) assert gs._sklearn_object.best_params_ == sk_gs.best_params_ + pipeline.set_params(**gs.to_sklearn().best_params_) + assert pipeline.to_sklearn().steps[-1][1].penalty == "l2" + pipeline.set_params(**{"CLF__penalty": "l1"}) + assert pipeline.to_sklearn().steps[-1][1].penalty == "l1" np.testing.assert_allclose(gs._sklearn_object.best_score_, sk_gs.best_score_) np.testing.assert_allclose(predicted.flatten(), sk_predicted.flatten(), rtol=1.0e-1, atol=1.0e-2) diff --git a/tests/integ/snowflake/ml/feature_store/BUILD.bazel b/tests/integ/snowflake/ml/feature_store/BUILD.bazel index a0aad954..0bbe4271 100644 --- a/tests/integ/snowflake/ml/feature_store/BUILD.bazel +++ b/tests/integ/snowflake/ml/feature_store/BUILD.bazel @@ -108,3 +108,16 @@ py_test( "//snowflake/ml/utils:connection_params", ], ) + +py_test( + name = "feature_store_example_helper_test", + srcs = [ + "feature_store_example_helper_test.py", + ], + deps = [ + ":common_utils", + "//snowflake/ml/feature_store:feature_store_lib", + "//snowflake/ml/feature_store/examples:feature_store_examples", + "//snowflake/ml/utils:connection_params", + ], +) diff --git a/tests/integ/snowflake/ml/feature_store/common_utils.py b/tests/integ/snowflake/ml/feature_store/common_utils.py index 33136d63..f7892638 100644 --- a/tests/integ/snowflake/ml/feature_store/common_utils.py +++ b/tests/integ/snowflake/ml/feature_store/common_utils.py @@ -62,7 +62,7 @@ def compare_feature_views(actual_fvs: List[FeatureView], target_fvs: List[Featur assert actual_fv == target_fv, f"{actual_fv.name} doesn't match {target_fv.name}" -def create_mock_session(trouble_query: str, exception: Exception) -> Any: +def create_mock_session(trouble_query: str, exception: Exception, config: Optional[Dict[str, str]] = None) -> Any: def side_effect(session: Session) -> Callable[[Any], Any]: original_sql = session.sql @@ -73,7 +73,8 @@ def dispatch(*args: Any) -> Any: return dispatch - session = Session.builder.configs(SnowflakeLoginOptions()).create() + config = config or SnowflakeLoginOptions() + session = Session.builder.configs(config).create() session.sql = Mock(side_effect=side_effect(session)) return session diff --git a/tests/integ/snowflake/ml/feature_store/feature_store_example_helper_test.py b/tests/integ/snowflake/ml/feature_store/feature_store_example_helper_test.py new file mode 100644 index 00000000..c77be668 --- /dev/null +++ b/tests/integ/snowflake/ml/feature_store/feature_store_example_helper_test.py @@ -0,0 +1,76 @@ +from absl.testing import absltest +from common_utils import ( + FS_INTEG_TEST_DB, + cleanup_temporary_objects, + compare_dataframe, + create_random_schema, +) + +from snowflake.ml.feature_store import ( # type: ignore[attr-defined] + CreationMode, + FeatureStore, +) +from snowflake.ml.feature_store.examples.example_helper import ExampleHelper +from snowflake.ml.utils.connection_params import SnowflakeLoginOptions +from snowflake.snowpark import Session + + +class FeatureStoreExampleHelperTest(absltest.TestCase): + @classmethod + def setUpClass(self) -> None: + self._session = Session.builder.configs(SnowflakeLoginOptions()).create() + cleanup_temporary_objects(self._session) + + @classmethod + def tearDownClass(self) -> None: + self._session.close() + + def test_example_helper(self) -> None: + current_schema = create_random_schema(self._session, "FS_EXAMPLE_HELP_TEST") + default_warehouse = self._session.get_current_warehouse() + fs = FeatureStore( + self._session, + FS_INTEG_TEST_DB, + current_schema, + default_warehouse=default_warehouse, + creation_mode=CreationMode.CREATE_IF_NOT_EXIST, + ) + helper = ExampleHelper(self._session, FS_INTEG_TEST_DB, current_schema) + all_examples = helper.list_examples() + self.assertIsNotNone(all_examples) + expected_examples = [ + "citibike_trip_features", + "new_york_taxi_features", + "wine_quality_features", + "airline_features", + ] + compare_dataframe( + actual_df=all_examples.drop("desc", "label_cols", "model_category").to_pandas(), # type: ignore[union-attr] + target_data={ + "NAME": expected_examples, + }, + sort_cols=["NAME"], + ) + + for example in expected_examples: + loaded_tables = helper.load_example(example) + self.assertGreater(len(loaded_tables), 0) + self.assertEqual(helper.get_current_schema(), current_schema) + self.assertGreater(len(helper.get_label_cols()), 0) + self.assertIsNotNone(helper.get_excluded_cols()) + # assert entities + all_entities = helper.load_entities() + self.assertGreater(len(all_entities), 0) + for e in all_entities: + fs.register_entity(e) + self.assertGreater(fs.list_entities().count(), 0) + # assert feature view + all_fvs = helper.load_draft_feature_views() + self.assertGreater(len(all_fvs), 0) + for fv in all_fvs: + fs.register_feature_view(fv, version="1.0") + self.assertGreater(fs.list_feature_views().count(), 0) + + +if __name__ == "__main__": + absltest.main() diff --git a/tests/integ/snowflake/ml/feature_store/feature_store_large_scale_test.py b/tests/integ/snowflake/ml/feature_store/feature_store_large_scale_test.py index e4e55200..2b8a08e2 100644 --- a/tests/integ/snowflake/ml/feature_store/feature_store_large_scale_test.py +++ b/tests/integ/snowflake/ml/feature_store/feature_store_large_scale_test.py @@ -19,7 +19,6 @@ Entity, FeatureStore, FeatureView, - FeatureViewSlice, ) from snowflake.ml.feature_store._internal.synthetic_data_generator import ( SyntheticDataGenerator, @@ -150,9 +149,10 @@ def create_select_query(start: str, end: str) -> str: dsv0.url(), f"snow://dataset/{FS_INTEG_TEST_DB}.{current_schema}.{dataset_name}/versions/{dataset_version}/" ) self.assertIsNotNone(dsv0_meta.properties) - self.assertEqual(len(dsv0_meta.properties.serialized_feature_views), 1) - deserialized_fv_slice = FeatureViewSlice.from_json( - dsv0_meta.properties.serialized_feature_views[0], self._session + self.assertEqual(len(dsv0_meta.properties.compact_feature_views), 1) + deserialized_fv_slice = FeatureView._load_from_compact_repr( + self._session, + dsv0_meta.properties.compact_feature_views[0], ) # verify dataset rows count equal to spine df rows count df1_row_count = len(spine_df_1.collect()) diff --git a/tests/integ/snowflake/ml/feature_store/feature_store_test.py b/tests/integ/snowflake/ml/feature_store/feature_store_test.py index 50a1d078..fc55f1a6 100644 --- a/tests/integ/snowflake/ml/feature_store/feature_store_test.py +++ b/tests/integ/snowflake/ml/feature_store/feature_store_test.py @@ -1,4 +1,6 @@ import datetime +import random +import string from typing import List, Optional, Tuple, Union, cast from uuid import uuid4 @@ -167,6 +169,7 @@ def test_create_if_not_exist_failure(self) -> None: temp_session = create_mock_session( "CREATE TAG IF NOT EXISTS", snowpark_exceptions.SnowparkSQLException("IntentionalSQLError"), + config=self._session_config, ) schema_name = f"foo_{uuid4().hex.upper()}" @@ -346,6 +349,7 @@ def test_get_entity_system_error(self) -> None: fs._session = create_mock_session( "SHOW TAGS LIKE", snowpark_exceptions.SnowparkClientException("Intentional Integ Test Error"), + config=self._session_config, ) with self.assertRaisesRegex(RuntimeError, "Failed to list entities: .*"): @@ -356,6 +360,7 @@ def test_register_entity_system_error(self) -> None: fs._session = create_mock_session( "SHOW TAGS LIKE", snowpark_exceptions.SnowparkClientException("Intentional Integ Test Error"), + config=self._session_config, ) e = Entity("foo", ["id"]) @@ -538,6 +543,7 @@ def test_register_feature_view_system_error(self) -> None: fs._session = create_mock_session( "CREATE VIEW", snowpark_exceptions.SnowparkClientException("Intentional Integ Test Error"), + config=self._session_config, ) with self.assertRaisesRegex(RuntimeError, "(?s)Create view .* failed.*"): fs.register_feature_view(feature_view=fv, version="v1") @@ -545,6 +551,7 @@ def test_register_feature_view_system_error(self) -> None: fs._session = create_mock_session( "CREATE DYNAMIC TABLE", snowpark_exceptions.SnowparkClientException("Intentional Integ Test Error"), + config=self._session_config, ) fv2 = FeatureView( name="fv2", @@ -760,6 +767,7 @@ def test_resume_and_suspend_feature_view_system_error(self) -> None: fs._session = create_mock_session( "ALTER DYNAMIC TABLE", snowpark_exceptions.SnowparkClientException("Intentional Integ Test Error"), + config=self._session_config, ) with self.assertRaisesRegex(RuntimeError, "Failed to update feature view"): my_fv = fs.suspend_feature_view(my_fv) @@ -770,6 +778,7 @@ def test_resume_and_suspend_feature_view_system_error(self) -> None: fs._session = create_mock_session( "ALTER DYNAMIC TABLE", snowpark_exceptions.SnowparkClientException("Intentional Integ Test Error"), + config=self._session_config, ) with self.assertRaisesRegex(RuntimeError, "Failed to update feature view.*"): my_fv = fs.resume_feature_view(my_fv) @@ -1312,6 +1321,7 @@ def test_list_feature_views_system_error(self) -> None: fs._session = create_mock_session( "SHOW DYNAMIC TABLES LIKE", snowpark_exceptions.SnowparkClientException("Intentional Integ Test Error"), + config=self._session_config, ) with self.assertRaisesRegex(RuntimeError, "Failed to find object"): fs.list_feature_views() @@ -1319,6 +1329,7 @@ def test_list_feature_views_system_error(self) -> None: fs._session = create_mock_session( "SELECT ENTITY_DETAIL", snowpark_exceptions.SnowparkClientException("Intentional Integ Test Error"), + config=self._session_config, ) with self.assertRaisesRegex(RuntimeError, "Failed to lookup tagged objects for"): @@ -2525,6 +2536,114 @@ def test_invalid_argument_type(self) -> None: ): fs.read_feature_view(123, "v1") # type: ignore[call-overload] + def test_large_feature_metadata(self) -> None: + fs = self._create_feature_store() + + e = Entity("foo", ["id"]) + fs.register_entity(e) + + def gen_random_sql() -> str: + def rand_name() -> str: + return "".join(random.choices(string.ascii_letters, k=10)) + + sql = "SELECT id, " + for _ in range(500): + expr = f"name as {rand_name()}, age as {rand_name()}, title as {rand_name()}, dept as {rand_name()}," + sql += f" {expr} " + sql += f"FROM {self._mock_table}" + return sql + + fv1 = FeatureView( + name="fv1", + entities=[e], + feature_df=self._session.sql(gen_random_sql()), + ) + fv1 = fs.register_feature_view(feature_view=fv1, version="v1") + + fv2 = FeatureView( + name="fv2", + entities=[e], + feature_df=self._session.sql(gen_random_sql()), + ) + fv2 = fs.register_feature_view(feature_view=fv2, version="v1") + + fv3 = FeatureView( + name="fv3", + entities=[e], + feature_df=self._session.sql(gen_random_sql()), + ) + fv3 = fs.register_feature_view(feature_view=fv3, version="v1") + # select features with even pos in reversed order + fv3_slice = fv3.slice(fv3.feature_names[::-2]) # type: ignore[arg-type] + + spine_df = self._session.create_dataframe([(1, 101)], schema=["id", "ts"]) + ds = fs.generate_dataset("my_ds", spine_df, [fv1, fv2, fv3_slice]) + self.assertEqual(1, len(ds.read.to_pandas())) + + fvs = fs.load_feature_views_from_dataset(ds) + self.assertEqual([fv1, fv2, fv3_slice], fvs) + + def test_specified_refresh_mode(self) -> None: + fs = self._create_feature_store() + + e = Entity("foo", ["id"]) + fs.register_entity(e) + + def register(fs: FeatureStore, name: str, refresh_mode: Optional[str] = None) -> FeatureView: + sql = f"SELECT id, name, title FROM {self._mock_table}" + if refresh_mode: + fv = FeatureView( + name=name, + entities=[e], + feature_df=self._session.sql(sql), + refresh_freq="1min", + refresh_mode=refresh_mode, + ) + else: + fv = FeatureView( + name=name, + entities=[e], + feature_df=self._session.sql(sql), + refresh_freq="1min", + ) + return fs.register_feature_view(feature_view=fv, version="v1") + + self.assertEqual("INCREMENTAL", register(fs, "fv1").refresh_mode) + self.assertEqual("FULL", register(fs, "fv2", "FULL").refresh_mode) + self.assertEqual("INCREMENTAL", register(fs, "fv3", "INCREMENTAL").refresh_mode) + + def test_feature_view_list_columns(self) -> None: + fs = self._create_feature_store() + + e = Entity("foo", ["id"], desc="my entity") + fs.register_entity(e) + + fv = FeatureView( + name="fv", + entities=[e], + feature_df=self._session.table(self._mock_table).select(["NAME", "ID", "TITLE", "AGE", "TS"]), + timestamp_col="ts", + desc="foobar", + ).attach_feature_desc({"AGE": "my age", "TITLE": '"my title"'}) + + fv = fs.register_feature_view(fv, "1.0") + result = fv.list_columns() + + compare_dataframe( + actual_df=result.to_pandas(), + target_data={ + "NAME": ["AGE", "ID", "NAME", "TITLE", "TS"], + "CATEGORY": ["FEATURE", "ENTITY", "FEATURE", "FEATURE", "TIMESTAMP"], + "DTYPE": ["bigint", "bigint", "string(64)", "string(128)", "bigint"], + "DESC": ["my age", "my entity", "", '"my title"', None], + }, + sort_cols=["NAME"], + ) + + +if __name__ == "__main__": + absltest.main() + if __name__ == "__main__": absltest.main() diff --git a/tests/integ/snowflake/ml/model/_client/model/BUILD.bazel b/tests/integ/snowflake/ml/model/_client/model/BUILD.bazel index 9005d060..779d6f24 100644 --- a/tests/integ/snowflake/ml/model/_client/model/BUILD.bazel +++ b/tests/integ/snowflake/ml/model/_client/model/BUILD.bazel @@ -41,3 +41,15 @@ py_test( "//tests/integ/snowflake/ml/test_utils:db_manager", ], ) + +py_test( + name = "model_deployment_test", + timeout = "long", + srcs = ["model_deployment_test.py"], + shard_count = 2, + deps = [ + "//snowflake/ml/registry", + "//snowflake/ml/utils:connection_params", + "//tests/integ/snowflake/ml/test_utils:db_manager", + ], +) diff --git a/tests/integ/snowflake/ml/model/_client/model/model_deployment_test.py b/tests/integ/snowflake/ml/model/_client/model/model_deployment_test.py new file mode 100644 index 00000000..51ab822c --- /dev/null +++ b/tests/integ/snowflake/ml/model/_client/model/model_deployment_test.py @@ -0,0 +1,132 @@ +import inspect +import time +import uuid + +import numpy as np +from absl.testing import absltest +from sklearn import datasets, linear_model, svm + +from snowflake.ml._internal.utils import sql_identifier +from snowflake.ml.registry import registry +from snowflake.ml.utils import connection_params +from snowflake.snowpark import Session +from tests.integ.snowflake.ml.test_utils import db_manager + + +class ModelDeploymentTest(absltest.TestCase): + """Test model container services deployment.""" + + _TEST_CPU_COMPUTE_POOL = "REGTEST_INFERENCE_CPU_POOL" + _SPCS_EAI = "SPCS_EGRESS_ACCESS_INTEGRATION" + + def setUp(self) -> None: + """Creates Snowpark and Snowflake environments for testing.""" + login_options = connection_params.SnowflakeLoginOptions() + + self._run_id = uuid.uuid4().hex[:2] + self._test_db = db_manager.TestObjectNameGenerator.get_snowml_test_object_name(self._run_id, "db").upper() + self._test_schema = db_manager.TestObjectNameGenerator.get_snowml_test_object_name( + self._run_id, "schema" + ).upper() + self._test_image_repo = db_manager.TestObjectNameGenerator.get_snowml_test_object_name( + self._run_id, "image_repo" + ).upper() + + self._session = Session.builder.configs( + { + **login_options, + **{"database": self._test_db, "schema": self._test_schema}, + } + ).create() + + self._db_manager = db_manager.DBManager(self._session) + self._db_manager.create_database(self._test_db) + self._db_manager.create_schema(self._test_schema) + self._db_manager.create_image_repo(self._test_image_repo) + self._db_manager.cleanup_databases(expire_hours=6) + self.registry = registry.Registry(self._session) + + def tearDown(self) -> None: + self._db_manager.drop_database(self._test_db) + self._session.close() + + @absltest.skip + def test_create_service(self) -> None: + iris_X, iris_y = datasets.load_iris(return_X_y=True) + # LogisticRegression is for classfication task, such as iris + regr = linear_model.LogisticRegression() + regr.fit(iris_X, iris_y) + + model_name = f"model_{inspect.stack()[1].function}" + version_name = f"ver_{self._run_id}" + mv = self.registry.log_model( + model=regr, + model_name=model_name, + version_name=version_name, + sample_input_data=iris_X, + ) + + service = f"service_{self._run_id}" + mv.create_service( + service_name=service, + image_build_compute_pool=self._TEST_CPU_COMPUTE_POOL, + service_compute_pool=self._TEST_CPU_COMPUTE_POOL, + image_repo=self._test_image_repo, + force_rebuild=True, + build_external_access_integration=self._SPCS_EAI, + ) + self.assertTrue(self._wait_for_service(service)) + + @absltest.skip + def test_inference(self) -> None: + iris_X, iris_y = datasets.load_iris(return_X_y=True) + svc = svm.LinearSVC() + svc.fit(iris_X, iris_y) + + model_name = f"model_{inspect.stack()[1].function}" + version_name = f"ver_{self._run_id}" + mv = self.registry.log_model( + model=svc, + model_name=model_name, + version_name=version_name, + sample_input_data=iris_X, + ) + + service = f"service_{self._run_id}" + mv.create_service( + service_name=service, + image_build_compute_pool=self._TEST_CPU_COMPUTE_POOL, + service_compute_pool=self._TEST_CPU_COMPUTE_POOL, + image_repo=self._test_image_repo, + force_rebuild=True, + build_external_access_integration=self._SPCS_EAI, + ) + self.assertTrue(self._wait_for_service(service)) + + res = mv.run(iris_X, function_name="predict", service_name=service) + np.testing.assert_allclose(res["output_feature_0"].values, svc.predict(iris_X)) + + def _wait_for_service(self, service: str) -> bool: + service_identifier = sql_identifier.SqlIdentifier(service).identifier() + + # wait for service creation + while True: + services = [serv["name"] for serv in self._session.sql("SHOW SERVICES").collect()] + if service_identifier not in services: + time.sleep(10) + else: + break + + # wait for service to run + while True: + status = self._session.sql(f"DESC SERVICE {service_identifier}").collect()[0]["status"] + if status == "RUNNING": + return True + elif status == "PENDING": + time.sleep(10) + else: + return False + + +if __name__ == "__main__": + absltest.main() diff --git a/tests/integ/snowflake/ml/modeling/framework/base_test.py b/tests/integ/snowflake/ml/modeling/framework/base_test.py index 2d6c243e..7d1dc451 100644 --- a/tests/integ/snowflake/ml/modeling/framework/base_test.py +++ b/tests/integ/snowflake/ml/modeling/framework/base_test.py @@ -38,6 +38,31 @@ def setUp(self) -> None: def tearDown(self) -> None: self._session.close() + def test_set_params(self) -> None: + class TestTransformer(BaseTransformer): + def __init__(self) -> None: + super().__init__() + self._sklearn_object: Optional[Any] = None + + def _fit(self, dataset: DataFrame) -> "TestTransformer": + return self + + with self.subTest("Test with estimator."): + estimator = TestTransformer() + estimator._sklearn_object = XGBRegressor() + estimator.set_input_cols(["COL_1", "COL_2"]) + estimator.set_label_cols("COL_3") + + estimator.set_params(**dict(max_depth=4, n_estimators=27)) + self.assertEqual(estimator.to_sklearn().max_depth, 4) + self.assertEqual(estimator.to_sklearn().n_estimators, 27) + + with self.subTest("Test failure"): + with self.assertRaises(SnowflakeMLException): + estimator = TestTransformer() + estimator._sklearn_object = XGBRegressor() + estimator.set_params(**dict(made_up=4, n_estimators=27)) + def test_infer_input_output_cols(self) -> None: test_df = pd.DataFrame({"COL_1": [1, 2, 3], "COL_2": [4, 5, 6], "COL_3": [10, 11, 12]}) diff --git a/tests/integ/snowflake/ml/modeling/pipeline/pipeline_test.py b/tests/integ/snowflake/ml/modeling/pipeline/pipeline_test.py index 4f4a766f..ffb98a72 100644 --- a/tests/integ/snowflake/ml/modeling/pipeline/pipeline_test.py +++ b/tests/integ/snowflake/ml/modeling/pipeline/pipeline_test.py @@ -98,12 +98,38 @@ def test_multiple_steps(self) -> None: ss = StandardScaler().set_input_cols(output_col1).set_output_cols(output_col2) pipeline = snowml_pipeline.Pipeline([("mms", mms), ("ss", ss)]) pipeline.fit(df) + pipeline.to_sklearn() transformed_df = pipeline.transform(df) df1 = mms.fit(df).transform(df) df2 = ss.fit(df1).transform(df1) assert transformed_df.queries["queries"][-1] == df2.queries["queries"][-1] + def test_set_params_snowml_pipeline(self) -> None: + input_col, output_col1, input_col_2, output_col2 = NUMERIC_COLS[0], "OUTPUT1", NUMERIC_COLS[1], "OUTPUT2" + _, df = framework_utils.get_df(self._session, DATA, SCHEMA, np.nan) + pipeline = snowml_pipeline.Pipeline( + steps=[ + ( + "MMS", + MinMaxScaler(input_cols=[input_col], output_cols=[output_col1]), + ), + ( + "MMS2", + MinMaxScaler(input_cols=[input_col_2], output_cols=[output_col2]), + ), + ] + ) + pipeline.fit(df) + assert pipeline._is_convertible_to_sklearn_object() is False + self.assertFalse(pipeline.steps[1][1].clip) + self.assertFalse(pipeline.steps[0][1].clip) + self.assertEqual(pipeline.steps[0][1].feature_range, (0, 1)) + pipeline.set_params(**{"MMS__clip": True, "MMS__feature_range": (1, 2), "MMS2__clip": True}) + self.assertTrue(pipeline.steps[1][1].clip) + self.assertTrue(pipeline.steps[0][1].clip) + self.assertEqual(pipeline.steps[0][1].feature_range, (1, 2)) + def test_serde(self) -> None: """ Test serialization and deserialization via cloudpickle, pickle, and joblib. diff --git a/tests/integ/snowflake/ml/registry/model/BUILD.bazel b/tests/integ/snowflake/ml/registry/model/BUILD.bazel index 635e6b9e..b82c51a5 100644 --- a/tests/integ/snowflake/ml/registry/model/BUILD.bazel +++ b/tests/integ/snowflake/ml/registry/model/BUILD.bazel @@ -58,17 +58,20 @@ py_test( py_test( name = "registry_sklearn_model_test", + timeout = "long", srcs = ["registry_sklearn_model_test.py"], shard_count = 2, deps = [ ":registry_model_test_base", + "//tests/integ/snowflake/ml/test_utils:dataframe_utils", ], ) py_test( name = "registry_catboost_model_test", + timeout = "long", srcs = ["registry_catboost_model_test.py"], - shard_count = 2, + shard_count = 4, deps = [ ":registry_model_test_base", "//tests/integ/snowflake/ml/test_utils:dataframe_utils", @@ -77,8 +80,9 @@ py_test( py_test( name = "registry_xgboost_model_test", + timeout = "long", srcs = ["registry_xgboost_model_test.py"], - shard_count = 2, + shard_count = 4, deps = [ ":registry_model_test_base", "//tests/integ/snowflake/ml/test_utils:dataframe_utils", @@ -87,8 +91,9 @@ py_test( py_test( name = "registry_lightgbm_model_test", + timeout = "long", srcs = ["registry_lightgbm_model_test.py"], - shard_count = 4, + shard_count = 6, deps = [ ":registry_model_test_base", "//tests/integ/snowflake/ml/test_utils:dataframe_utils", @@ -97,6 +102,7 @@ py_test( py_test( name = "registry_custom_model_test", + timeout = "long", srcs = ["registry_custom_model_test.py"], shard_count = 4, deps = [ @@ -108,6 +114,7 @@ py_test( py_test( name = "registry_pytorch_model_test", + timeout = "long", srcs = ["registry_pytorch_model_test.py"], shard_count = 4, deps = [ @@ -121,6 +128,7 @@ py_test( py_test( name = "registry_tensorflow_model_test", + timeout = "long", srcs = ["registry_tensorflow_model_test.py"], shard_count = 4, deps = [ @@ -135,6 +143,7 @@ py_test( py_test( name = "registry_modeling_model_test", + timeout = "long", srcs = ["registry_modeling_model_test.py"], shard_count = 2, deps = [ @@ -148,6 +157,7 @@ py_test( py_test( name = "registry_mlflow_model_test", + timeout = "long", srcs = ["registry_mlflow_model_test.py"], shard_count = 2, deps = [ @@ -159,6 +169,7 @@ py_test( py_test( name = "registry_huggingface_pipeline_model_test", + timeout = "long", srcs = ["registry_huggingface_pipeline_model_test.py"], shard_count = 6, deps = [ @@ -169,6 +180,7 @@ py_test( py_test( name = "registry_sentence_transformers_model_test", + timeout = "long", srcs = ["registry_sentence_transformers_model_test.py"], shard_count = 4, deps = [ diff --git a/tests/integ/snowflake/ml/registry/model/registry_catboost_model_test.py b/tests/integ/snowflake/ml/registry/model/registry_catboost_model_test.py index 904dbce1..939507f1 100644 --- a/tests/integ/snowflake/ml/registry/model/registry_catboost_model_test.py +++ b/tests/integ/snowflake/ml/registry/model/registry_catboost_model_test.py @@ -14,7 +14,7 @@ class TestRegistryCatBoostModelInteg(registry_model_test_base.RegistryModelTestB @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_catboost_classifier( + def test_catboost_classifier_no_explain( self, registry_test_fn: str, ) -> None: @@ -42,6 +42,7 @@ def test_catboost_classifier( lambda res: np.testing.assert_allclose(res.values, classifier.predict_proba(cal_X_test)), ), }, + options={"enable_explainability": False}, ) @parameterized.product( # type: ignore[misc] @@ -80,13 +81,12 @@ def test_catboost_classifier_explain( lambda res: np.testing.assert_allclose(res.values, expected_explanations), ), }, - options={"enable_explainability": True}, ) @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_catboost_classifier_sp( + def test_catboost_classifier_sp_no_explain( self, registry_test_fn: str, ) -> None: @@ -129,6 +129,7 @@ def test_catboost_classifier_sp( lambda res: dataframe_utils.check_sp_df_res(res, y_df_expected_proba, check_dtype=False), ), }, + options={"enable_explainability": False}, ) @parameterized.product( # type: ignore[misc] @@ -191,7 +192,6 @@ def test_catboost_classifier_explain_sp( lambda res: dataframe_utils.check_sp_df_res(res, explanation_df_expected, check_dtype=False), ), }, - options={"enable_explainability": True}, ) diff --git a/tests/integ/snowflake/ml/registry/model/registry_lightgbm_model_test.py b/tests/integ/snowflake/ml/registry/model/registry_lightgbm_model_test.py index 8f9b020e..149722e9 100644 --- a/tests/integ/snowflake/ml/registry/model/registry_lightgbm_model_test.py +++ b/tests/integ/snowflake/ml/registry/model/registry_lightgbm_model_test.py @@ -15,7 +15,7 @@ class TestRegistryLightGBMModelInteg(registry_model_test_base.RegistryModelTestB @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_lightgbm_classifier( + def test_lightgbm_classifier_no_explain( self, registry_test_fn: str, ) -> None: @@ -43,6 +43,7 @@ def test_lightgbm_classifier( lambda res: np.testing.assert_allclose(res.values, classifier.predict_proba(cal_X_test)), ), }, + options={"enable_explainability": False}, ) @parameterized.product( # type: ignore[misc] @@ -83,13 +84,12 @@ def test_lightgbm_classifier_explain( ), ), }, - options={"enable_explainability": True}, ) @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_lightgbm_classifier_sp( + def test_lightgbm_classifier_sp_no_explain( self, registry_test_fn: str, ) -> None: @@ -132,6 +132,7 @@ def test_lightgbm_classifier_sp( lambda res: dataframe_utils.check_sp_df_res(res, y_df_expected_proba, check_dtype=False), ), }, + options={"enable_explainability": False}, ) @parameterized.product( # type: ignore[misc] @@ -196,13 +197,12 @@ def test_lightgbm_classifier_explain_sp( ), ), }, - options={"enable_explainability": True}, ) @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_lightgbm_booster( + def test_lightgbm_booster_no_explain( self, registry_test_fn: str, ) -> None: @@ -224,6 +224,7 @@ def test_lightgbm_booster( lambda res: np.testing.assert_allclose(res.values, np.expand_dims(y_pred, axis=1), rtol=1e-6), ), }, + options={"enable_explainability": False}, ) @parameterized.product( # type: ignore[misc] @@ -256,13 +257,12 @@ def test_lightgbm_booster_explain( lambda res: np.testing.assert_allclose(res.values, expected_explanations, rtol=1e-5), ), }, - options={"enable_explainability": True}, ) @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_lightgbm_booster_sp( + def test_lightgbm_booster_sp_no_explain( self, registry_test_fn: str, ) -> None: @@ -292,6 +292,7 @@ def test_lightgbm_booster_sp( lambda res: dataframe_utils.check_sp_df_res(res, y_df_expected, check_dtype=False), ), }, + options={"enable_explainability": False}, ) @parameterized.product( # type: ignore[misc] @@ -342,7 +343,6 @@ def test_lightgbm_booster_explain_sp( lambda res: dataframe_utils.check_sp_df_res(res, explanation_df_expected, check_dtype=False), ), }, - options={"enable_explainability": True}, ) diff --git a/tests/integ/snowflake/ml/registry/model/registry_modeling_model_test.py b/tests/integ/snowflake/ml/registry/model/registry_modeling_model_test.py index 6da629a9..48fa3ad0 100644 --- a/tests/integ/snowflake/ml/registry/model/registry_modeling_model_test.py +++ b/tests/integ/snowflake/ml/registry/model/registry_modeling_model_test.py @@ -135,6 +135,8 @@ def test_dataset_to_model_lineage( ) test_features_df = self.session.create_dataframe(iris_X, schema=schema) + test_features_df.write.mode("overwrite").save_as_table("testTable") + test_features_dataset = dataset.create_from_dataframe( session=self.session, name="trainDataset", @@ -178,7 +180,20 @@ def test_dataset_to_model_lineage( regr, test_features_dataset, sample_input_data=pandas_df, lineage_should_exist=False ) - def _check_lineage_in_manifest_file(self, model, dataset, sample_input_data=None, lineage_should_exist=True): + # Case 5 : Capture Lineage via fit() API of MANIFEST.yml file + table_backed_dataframe = self.session.table("testTable") + regr.fit(table_backed_dataframe) + self._check_lineage_in_manifest_file(regr, "testTable", is_dataset=False) + + # Case 6 : Capture Lineage via sample_input of log_model of MANIFEST.yml file + regr.fit(table_backed_dataframe.to_pandas()) + self._check_lineage_in_manifest_file( + regr, "testTable", is_dataset=False, sample_input_data=table_backed_dataframe + ) + + def _check_lineage_in_manifest_file( + self, model, data_source, is_dataset=True, sample_input_data=None, lineage_should_exist=True + ): model_name = "some_name" tmp_stage_path = posixpath.join(self.session.get_session_stage(), f"{model_name}_{1}") conda_dependencies = [ @@ -205,9 +220,13 @@ def _check_lineage_in_manifest_file(self, model, dataset, sample_input_data=None source = yaml_content["lineage_sources"][0] assert isinstance(source, dict) - assert source.get("type") == "DATASET" - assert source.get("entity") == f"{dataset.fully_qualified_name}" - assert source.get("version") == f"{dataset._version.name}" + if is_dataset: + assert source.get("type") == "DATASET" + assert source.get("entity") == f"{data_source.fully_qualified_name}" + assert source.get("version") == f"{data_source._version.name}" + else: + assert source.get("type") == "QUERY" + assert data_source in source.get("entity") else: assert "lineage_sources" not in yaml_content diff --git a/tests/integ/snowflake/ml/registry/model/registry_sklearn_model_test.py b/tests/integ/snowflake/ml/registry/model/registry_sklearn_model_test.py index 88eaa012..cf1c435a 100644 --- a/tests/integ/snowflake/ml/registry/model/registry_sklearn_model_test.py +++ b/tests/integ/snowflake/ml/registry/model/registry_sklearn_model_test.py @@ -2,10 +2,14 @@ import numpy as np import pandas as pd +import shap from absl.testing import absltest, parameterized from sklearn import datasets, ensemble, linear_model, multioutput +from snowflake.ml.model._packager.model_handlers import _utils as handlers_utils +from snowflake.snowpark import exceptions as snowpark_exceptions from tests.integ.snowflake.ml.registry.model import registry_model_test_base +from tests.integ.snowflake.ml.test_utils import dataframe_utils, test_env_utils class TestRegistrySKLearnModelInteg(registry_model_test_base.RegistryModelTestBase): @@ -18,21 +22,101 @@ def test_skl_model( ) -> None: iris_X, iris_y = datasets.load_iris(return_X_y=True) # LogisticRegression is for classfication task, such as iris - regr = linear_model.LogisticRegression() - regr.fit(iris_X, iris_y) + classifier = linear_model.LogisticRegression() + classifier.fit(iris_X, iris_y) getattr(self, registry_test_fn)( - model=regr, + model=classifier, sample_input_data=iris_X, prediction_assert_fns={ "predict": ( iris_X, - lambda res: np.testing.assert_allclose(res["output_feature_0"].values, regr.predict(iris_X)), + lambda res: np.testing.assert_allclose(res["output_feature_0"].values, classifier.predict(iris_X)), ), "predict_proba": ( iris_X[:10], - lambda res: np.testing.assert_allclose(res.values, regr.predict_proba(iris_X[:10])), + lambda res: np.testing.assert_allclose(res.values, classifier.predict_proba(iris_X[:10])), + ), + }, + ) + + @parameterized.product( # type: ignore[misc] + registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, + ) + def test_skl_model_explain( + self, + registry_test_fn: str, + ) -> None: + iris_X, iris_y = datasets.load_iris(return_X_y=True) + # sample input needs to be pandas dataframe for now + iris_X_df = pd.DataFrame(iris_X, columns=["c1", "c2", "c3", "c4"]) + classifier = linear_model.LogisticRegression() + classifier.fit(iris_X_df, iris_y) + expected_explanations = shap.Explainer(classifier, iris_X_df)(iris_X_df).values + + with self.assertRaisesRegex( + ValueError, + "Sample input data is required to enable explainability. Currently we only support this for " + + "`pandas.DataFrame` and `snowflake.snowpark.dataframe.DataFrame`.", + ): + getattr(self, registry_test_fn)( + model=classifier, + sample_input_data=iris_X, + prediction_assert_fns={}, + options={"enable_explainability": True}, + ) + + getattr(self, registry_test_fn)( + model=classifier, + sample_input_data=iris_X_df, + prediction_assert_fns={ + "predict": ( + iris_X_df, + lambda res: np.testing.assert_allclose(res["output_feature_0"].values, classifier.predict(iris_X)), + ), + "predict_proba": ( + iris_X_df.iloc[:10], + lambda res: np.testing.assert_allclose(res.values, classifier.predict_proba(iris_X[:10])), + ), + "explain": ( + iris_X_df, + lambda res: np.testing.assert_allclose( + dataframe_utils.convert2D_json_to_3D(res.values), expected_explanations + ), + ), + }, + options={"enable_explainability": True}, + ) + + @parameterized.product( # type: ignore[misc] + registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, + ) + def test_sklearn_explain_sp( + self, + registry_test_fn: str, + ) -> None: + iris_X, iris_y = datasets.load_iris(return_X_y=True) + iris_X_df = pd.DataFrame(iris_X, columns=["c1", "c2", "c3", "c4"]) + iris_X_sp_df = self.session.create_dataframe(iris_X_df) + classifier = linear_model.LogisticRegression() + classifier.fit(iris_X_df, iris_y) + + explain_df = handlers_utils.convert_explanations_to_2D_df( + classifier, shap.Explainer(classifier, iris_X_df)(iris_X_df).values + ).set_axis([f"{c}_explanation" for c in iris_X_df.columns], axis=1) + + explanation_df_expected = pd.concat([iris_X_df, explain_df], axis=1) + getattr(self, registry_test_fn)( + model=classifier, + sample_input_data=iris_X_sp_df, + prediction_assert_fns={ + "explain": ( + iris_X_sp_df, + lambda res: dataframe_utils.check_sp_df_res( + res, explanation_df_expected, check_dtype=False, rtol=1e-4 + ), ), }, + options={"enable_explainability": True}, ) @parameterized.product( # type: ignore[misc] @@ -95,6 +179,47 @@ def test_skl_multiple_output_model( }, ) + def test_skl_unsupported_explain( + self, + ) -> None: + iris_X, iris_y = datasets.load_iris(return_X_y=True) + target2 = np.random.randint(0, 6, size=iris_y.shape) + dual_target = np.vstack([iris_y, target2]).T + model = multioutput.MultiOutputClassifier(ensemble.RandomForestClassifier(random_state=42)) + model.fit(iris_X[:10], dual_target[:10]) + iris_X_df = pd.DataFrame(iris_X, columns=["c1", "c2", "c3", "c4"]) + + conda_dependencies = [ + test_env_utils.get_latest_package_version_spec_in_server(self.session, "snowflake-snowpark-python!=1.12.0") + ] + + name = "model_test_skl_unsupported_explain" + version = f"ver_{self._run_id}" + mv = self.registry.log_model( + model=model, + model_name=name, + version_name=version, + sample_input_data=iris_X_df, + conda_dependencies=conda_dependencies, + options={"enable_explainability": True}, + ) + + res = mv.run(iris_X[-10:], function_name="predict") + np.testing.assert_allclose(res.to_numpy(), model.predict(iris_X[-10:])) + + res = mv.run(iris_X[-10:], function_name="predict_proba") + np.testing.assert_allclose( + np.hstack([np.array(res[col].to_list()) for col in cast(pd.DataFrame, res)]), + np.hstack(model.predict_proba(iris_X[-10:])), + ) + + with self.assertRaises(snowpark_exceptions.SnowparkSQLException): + mv.run(iris_X_df, function_name="explain") + + self.registry.delete_model(model_name=name) + + self.assertNotIn(mv.model_name, [m.name for m in self.registry.models()]) + if __name__ == "__main__": absltest.main() diff --git a/tests/integ/snowflake/ml/registry/model/registry_xgboost_model_test.py b/tests/integ/snowflake/ml/registry/model/registry_xgboost_model_test.py index e1aa2978..957b64cf 100644 --- a/tests/integ/snowflake/ml/registry/model/registry_xgboost_model_test.py +++ b/tests/integ/snowflake/ml/registry/model/registry_xgboost_model_test.py @@ -14,7 +14,7 @@ class TestRegistryXGBoostModelInteg(registry_model_test_base.RegistryModelTestBa @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_xgb( + def test_xgb_no_explain( self, registry_test_fn: str, ) -> None: @@ -36,12 +36,39 @@ def test_xgb( ), ), }, + options={"enable_explainability": False}, ) @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_xgb_explain( + def test_xgb_explain_by_default( + self, + registry_test_fn: str, + ) -> None: + cal_data = datasets.load_breast_cancer(as_frame=True) + cal_X = cal_data.data + cal_y = cal_data.target + cal_X.columns = [inflection.parameterize(c, "_") for c in cal_X.columns] + cal_X_train, cal_X_test, cal_y_train, cal_y_test = model_selection.train_test_split(cal_X, cal_y) + regressor = xgboost.XGBRegressor(n_estimators=100, reg_lambda=1, gamma=0, max_depth=3) + regressor.fit(cal_X_train, cal_y_train) + expected_explanations = shap.Explainer(regressor)(cal_X_test).values + getattr(self, registry_test_fn)( + model=regressor, + sample_input_data=cal_X_test, + prediction_assert_fns={ + "explain": ( + cal_X_test, + lambda res: np.testing.assert_allclose(res.values, expected_explanations, rtol=1e-4), + ), + }, + ) + + @parameterized.product( # type: ignore[misc] + registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, + ) + def test_xgb_explain_explicitly_enabled( self, registry_test_fn: str, ) -> None: @@ -68,7 +95,7 @@ def test_xgb_explain( @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_xgb_sp( + def test_xgb_sp_no_explain( self, registry_test_fn: str, ) -> None: @@ -97,6 +124,7 @@ def test_xgb_sp( lambda res: dataframe_utils.check_sp_df_res(res, y_df_expected, check_dtype=False), ), }, + options={"enable_explainability": False}, ) @parameterized.product( # type: ignore[misc] @@ -136,13 +164,12 @@ def test_xgb_explain_sp( ), ), }, - options={"enable_explainability": True}, ) @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_xgb_booster( + def test_xgb_booster_no_explain( self, registry_test_fn: str, ) -> None: @@ -163,6 +190,7 @@ def test_xgb_booster( lambda res: np.testing.assert_allclose(res.values, np.expand_dims(y_pred, axis=1), rtol=1e-6), ), }, + options={"enable_explainability": False}, ) @parameterized.product( # type: ignore[misc] @@ -189,13 +217,12 @@ def test_xgb_booster_explain( lambda res: np.testing.assert_allclose(res.values, expected_explanations, rtol=1e-4), ), }, - options={"enable_explainability": True}, ) @parameterized.product( # type: ignore[misc] registry_test_fn=registry_model_test_base.RegistryModelTestBase.REGISTRY_TEST_FN_LIST, ) - def test_xgb_booster_sp( + def test_xgb_booster_sp_no_explain( self, registry_test_fn: str, ) -> None: @@ -229,6 +256,7 @@ def test_xgb_booster_sp( lambda res: dataframe_utils.check_sp_df_res(res, y_df_expected, check_dtype=False), ), }, + options={"enable_explainability": False}, ) @parameterized.product( # type: ignore[misc] @@ -271,7 +299,6 @@ def test_xgb_booster_explain_sp( ), ), }, - options={"enable_explainability": True}, ) diff --git a/tests/integ/snowflake/ml/test_utils/BUILD.bazel b/tests/integ/snowflake/ml/test_utils/BUILD.bazel index 94d06d77..144b3e86 100644 --- a/tests/integ/snowflake/ml/test_utils/BUILD.bazel +++ b/tests/integ/snowflake/ml/test_utils/BUILD.bazel @@ -27,6 +27,7 @@ py_library( deps = [ "//snowflake/ml/_internal/utils:identifier", "//snowflake/ml/model/_deploy_client/utils:constants", + "//snowflake/ml/utils:sql_client", ], ) diff --git a/tests/integ/snowflake/ml/test_utils/dataframe_utils.py b/tests/integ/snowflake/ml/test_utils/dataframe_utils.py index 8c0067af..29e99a34 100644 --- a/tests/integ/snowflake/ml/test_utils/dataframe_utils.py +++ b/tests/integ/snowflake/ml/test_utils/dataframe_utils.py @@ -75,6 +75,7 @@ def convert2D_json_to_3D(array: npt.NDArray[Any]) -> List[List[List[Any]]]: tmp = [] for j in range(array.shape[1]): json_to_dict = json.loads(array[i][j]) - tmp.append([float(json_to_dict["0"]), float(json_to_dict["1"])]) + num_keys = len(json_to_dict.keys()) + tmp.append([float(json_to_dict[str(k)]) for k in range(num_keys)]) final_array.append(tmp) return final_array diff --git a/tests/integ/snowflake/ml/test_utils/db_manager.py b/tests/integ/snowflake/ml/test_utils/db_manager.py index dc6139e6..fa26dcd5 100644 --- a/tests/integ/snowflake/ml/test_utils/db_manager.py +++ b/tests/integ/snowflake/ml/test_utils/db_manager.py @@ -5,8 +5,10 @@ from snowflake import snowpark from snowflake.ml._internal.utils import identifier from snowflake.ml.model._deploy_client.utils import constants +from snowflake.ml.utils import sql_client _COMMON_PREFIX = "snowml_test_" +_default_creation_mode = sql_client.CreationMode() class DBManager: @@ -23,14 +25,14 @@ def set_warehouse(self, warehouse: str) -> None: def create_database( self, db_name: str, - if_not_exists: bool = False, - or_replace: bool = False, + creation_mode: sql_client.CreationMode = _default_creation_mode, ) -> str: actual_db_name = identifier.get_inferred_name(db_name) - or_replace_sql = " OR REPLACE" if or_replace else "" - if_not_exists_sql = " IF NOT EXISTS" if if_not_exists else "" + ddl_phrases = creation_mode.get_ddl_phrases() self._session.sql( - f"CREATE{or_replace_sql} DATABASE{if_not_exists_sql} {actual_db_name} DATA_RETENTION_TIME_IN_DAYS = 0" + f"CREATE{ddl_phrases[sql_client.CreationOption.OR_REPLACE]} DATABASE" + f"{ddl_phrases[sql_client.CreationOption.CREATE_IF_NOT_EXIST]} " + f"{actual_db_name} DATA_RETENTION_TIME_IN_DAYS = 0" ).collect() return actual_db_name @@ -63,18 +65,19 @@ def create_schema( self, schema_name: str, db_name: Optional[str] = None, - if_not_exists: bool = False, - or_replace: bool = False, + creation_mode: sql_client.CreationMode = _default_creation_mode, ) -> str: actual_schema_name = identifier.get_inferred_name(schema_name) if db_name: - actual_db_name = self.create_database(db_name, if_not_exists=True) + actual_db_name = self.create_database(db_name, creation_mode=sql_client.CreationMode(if_not_exists=True)) full_qual_schema_name = f"{actual_db_name}.{actual_schema_name}" else: full_qual_schema_name = actual_schema_name - or_replace_sql = " OR REPLACE" if or_replace else "" - if_not_exists_sql = " IF NOT EXISTS" if if_not_exists else "" - self._session.sql(f"CREATE{or_replace_sql} SCHEMA{if_not_exists_sql} {full_qual_schema_name}").collect() + ddl_phrases = creation_mode.get_ddl_phrases() + self._session.sql( + f"CREATE{ddl_phrases[sql_client.CreationOption.OR_REPLACE]} SCHEMA" + f"{ddl_phrases[sql_client.CreationOption.CREATE_IF_NOT_EXIST]} {full_qual_schema_name}" + ).collect() return full_qual_schema_name def create_random_schema( @@ -136,21 +139,22 @@ def create_stage( stage_name: str, schema_name: Optional[str] = None, db_name: Optional[str] = None, - if_not_exists: bool = False, - or_replace: bool = False, + creation_mode: sql_client.CreationMode = _default_creation_mode, sse_encrypted: bool = False, ) -> str: actual_stage_name = identifier.get_inferred_name(stage_name) if schema_name: - full_qual_schema_name = self.create_schema(schema_name, db_name, if_not_exists=True) + full_qual_schema_name = self.create_schema( + schema_name, db_name, creation_mode=sql_client.CreationMode(if_not_exists=True) + ) full_qual_stage_name = f"{full_qual_schema_name}.{actual_stage_name}" else: full_qual_stage_name = actual_stage_name - or_replace_sql = " OR REPLACE" if or_replace else "" - if_not_exists_sql = " IF NOT EXISTS" if if_not_exists else "" + ddl_phrases = creation_mode.get_ddl_phrases() encryption_sql = " ENCRYPTION = (TYPE= 'SNOWFLAKE_SSE')" if sse_encrypted else "" self._session.sql( - f"CREATE{or_replace_sql} STAGE{if_not_exists_sql} {full_qual_stage_name}{encryption_sql}" + f"CREATE{ddl_phrases[sql_client.CreationOption.OR_REPLACE]} STAGE" + f"{ddl_phrases[sql_client.CreationOption.CREATE_IF_NOT_EXIST]} {full_qual_stage_name}{encryption_sql}" ).collect() return full_qual_stage_name @@ -279,6 +283,154 @@ def get_snowservice_image_repo( schema = conn._schema return f"{org}-{account}.{subdomain}.{constants.PROD_IMAGE_REGISTRY_DOMAIN}/{db}/{schema}/{repo}".lower() + def create_compute_pool( + self, + compute_pool_name: str, + creation_mode: sql_client.CreationMode = _default_creation_mode, + instance_family: str = "CPU_X64_XS", + min_nodes: int = 1, + max_nodes: int = 1, + ) -> str: + full_qual_compute_pool_name = identifier.get_inferred_name(compute_pool_name) + ddl_phrases = creation_mode.get_ddl_phrases() + instance_family_sql = f" INSTANCE_FAMILY = '{instance_family}'" + min_nodes_sql = f" MIN_NODES = {min_nodes}" + max_nodes_sql = f" MAX_NODES = {max_nodes}" + self._session.sql( + f"CREATE{ddl_phrases[sql_client.CreationOption.OR_REPLACE]} COMPUTE POOL" + f"{ddl_phrases[sql_client.CreationOption.CREATE_IF_NOT_EXIST]} {full_qual_compute_pool_name}" + f"{instance_family_sql}{min_nodes_sql}{max_nodes_sql}" + ).collect() + return full_qual_compute_pool_name + + def drop_compute_pool( + self, + compute_pool_name: str, + if_exists: bool = False, + ) -> None: + full_qual_compute_pool_name = identifier.get_inferred_name(compute_pool_name) + if_exists_sql = " IF EXISTS" if if_exists else "" + self._session.sql(f"DROP COMPUTE POOL{if_exists_sql} {full_qual_compute_pool_name}").collect() + + def create_image_repo( + self, + image_repo_name: str, + schema_name: Optional[str] = None, + db_name: Optional[str] = None, + creation_mode: sql_client.CreationMode = _default_creation_mode, + ) -> str: + actual_image_repo_name = identifier.get_inferred_name(image_repo_name) + if schema_name: + full_qual_schema_name = self.create_schema( + schema_name, db_name, creation_mode=sql_client.CreationMode(if_not_exists=True) + ) + full_qual_image_repo_name = f"{full_qual_schema_name}.{actual_image_repo_name}" + else: + full_qual_image_repo_name = actual_image_repo_name + ddl_phrases = creation_mode.get_ddl_phrases() + self._session.sql( + f"CREATE{ddl_phrases[sql_client.CreationOption.OR_REPLACE]} IMAGE REPOSITORY" + f"{ddl_phrases[sql_client.CreationOption.CREATE_IF_NOT_EXIST]} {full_qual_image_repo_name}" + ).collect() + return full_qual_image_repo_name + + def drop_image_repo( + self, + image_repo_name: str, + schema_name: Optional[str] = None, + db_name: Optional[str] = None, + if_exists: bool = False, + ) -> None: + actual_image_repo_name = identifier.get_inferred_name(image_repo_name) + if schema_name: + actual_schema_name = identifier.get_inferred_name(schema_name) + if db_name: + actual_db_name = identifier.get_inferred_name(db_name) + full_qual_schema_name = f"{actual_db_name}.{actual_schema_name}" + else: + full_qual_schema_name = actual_schema_name + full_qual_image_repo_name = f"{full_qual_schema_name}.{actual_image_repo_name}" + else: + full_qual_image_repo_name = actual_image_repo_name + if_exists_sql = " IF EXISTS" if if_exists else "" + self._session.sql(f"DROP IMAGE REPOSITORY{if_exists_sql} {full_qual_image_repo_name}").collect() + + def create_network_rule( + self, + network_rule_name: str, + schema_name: Optional[str] = None, + db_name: Optional[str] = None, + creation_mode: sql_client.CreationMode = _default_creation_mode, + mode: str = "EGRESS", + type: str = "HOST_PORT", + value_list: Optional[List[str]] = None, + ) -> str: + actual_network_rule_name = identifier.get_inferred_name(network_rule_name) + if schema_name: + full_qual_schema_name = self.create_schema( + schema_name, db_name, creation_mode=sql_client.CreationMode(if_not_exists=True) + ) + full_qual_network_rule_name = f"{full_qual_schema_name}.{actual_network_rule_name}" + else: + full_qual_network_rule_name = actual_network_rule_name + ddl_phrases = creation_mode.get_ddl_phrases() + mode_sql = f" MODE = '{mode}'" + type_sql = f" TYPE = '{type}'" + value_list = [] if value_list is None else value_list + value_list_val = ", ".join([f"'{v}'" for v in value_list]) + value_list_sql = f" VALUE_LIST = ({value_list_val})" + self._session.sql( + f"CREATE{ddl_phrases[sql_client.CreationOption.OR_REPLACE]} NETWORK RULE" + f"{ddl_phrases[sql_client.CreationOption.CREATE_IF_NOT_EXIST]} {full_qual_network_rule_name}" + f"{mode_sql}{type_sql}{value_list_sql}" + ).collect() + return full_qual_network_rule_name + + def drop_network_rule( + self, + network_rule_name: str, + schema_name: Optional[str] = None, + db_name: Optional[str] = None, + if_exists: bool = False, + ) -> None: + actual_network_rule_name = identifier.get_inferred_name(network_rule_name) + if schema_name: + actual_schema_name = identifier.get_inferred_name(schema_name) + if db_name: + actual_db_name = identifier.get_inferred_name(db_name) + full_qual_schema_name = f"{actual_db_name}.{actual_schema_name}" + else: + full_qual_schema_name = actual_schema_name + full_qual_network_rule_name = f"{full_qual_schema_name}.{actual_network_rule_name}" + else: + full_qual_network_rule_name = actual_network_rule_name + if_exists_sql = " IF EXISTS" if if_exists else "" + self._session.sql(f"DROP NETWORK RULE{if_exists_sql} {full_qual_network_rule_name}").collect() + + def create_external_access_integration( + self, + external_access_integration_name: str, + creation_mode: sql_client.CreationMode = _default_creation_mode, + allowed_network_rules: Optional[List[str]] = None, + enabled: bool = True, + ) -> str: + full_qual_eai_name = identifier.get_inferred_name(external_access_integration_name) + ddl_phrases = creation_mode.get_ddl_phrases() + allowed_network_rules = [] if allowed_network_rules is None else allowed_network_rules + allowed_network_rules_sql = f" ALLOWED_NETWORK_RULES = ({', '.join(allowed_network_rules)})" + enabled_sql = f" ENABLED = {enabled}" + self._session.sql( + f"CREATE{ddl_phrases[sql_client.CreationOption.OR_REPLACE]} EXTERNAL ACCESS INTEGRATION" + f"{ddl_phrases[sql_client.CreationOption.CREATE_IF_NOT_EXIST]} {full_qual_eai_name}" + f"{allowed_network_rules_sql}{enabled_sql}" + ).collect() + return full_qual_eai_name + + def drop_external_access_integration(self, external_access_integration_name: str, if_exists: bool = False) -> None: + full_qual_eai_name = identifier.get_inferred_name(external_access_integration_name) + if_exists_sql = " IF EXISTS" if if_exists else "" + self._session.sql(f"DROP EXTERNAL ACCESS INTEGRATION{if_exists_sql} {full_qual_eai_name}").collect() + class TestObjectNameGenerator: @staticmethod