oracle-ads 2.13.8__py3-none-any.whl → 2.13.9rc0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {oracle_ads-2.13.8.dist-info → oracle_ads-2.13.9rc0.dist-info}/METADATA +151 -151
- oracle_ads-2.13.9rc0.dist-info/RECORD +9 -0
- {oracle_ads-2.13.8.dist-info → oracle_ads-2.13.9rc0.dist-info}/WHEEL +2 -1
- {oracle_ads-2.13.8.dist-info → oracle_ads-2.13.9rc0.dist-info}/entry_points.txt +1 -2
- oracle_ads-2.13.9rc0.dist-info/top_level.txt +1 -0
- ads/aqua/__init__.py +0 -40
- ads/aqua/app.py +0 -506
- ads/aqua/cli.py +0 -96
- ads/aqua/client/__init__.py +0 -3
- ads/aqua/client/client.py +0 -836
- ads/aqua/client/openai_client.py +0 -305
- ads/aqua/common/__init__.py +0 -5
- ads/aqua/common/decorator.py +0 -125
- ads/aqua/common/entities.py +0 -266
- ads/aqua/common/enums.py +0 -122
- ads/aqua/common/errors.py +0 -109
- ads/aqua/common/utils.py +0 -1285
- ads/aqua/config/__init__.py +0 -4
- ads/aqua/config/container_config.py +0 -248
- ads/aqua/config/evaluation/__init__.py +0 -4
- ads/aqua/config/evaluation/evaluation_service_config.py +0 -147
- ads/aqua/config/utils/__init__.py +0 -4
- ads/aqua/config/utils/serializer.py +0 -339
- ads/aqua/constants.py +0 -114
- ads/aqua/data.py +0 -14
- ads/aqua/dummy_data/icon.txt +0 -1
- ads/aqua/dummy_data/oci_model_deployments.json +0 -56
- ads/aqua/dummy_data/oci_models.json +0 -1
- ads/aqua/dummy_data/readme.md +0 -26
- ads/aqua/evaluation/__init__.py +0 -8
- ads/aqua/evaluation/constants.py +0 -53
- ads/aqua/evaluation/entities.py +0 -186
- ads/aqua/evaluation/errors.py +0 -70
- ads/aqua/evaluation/evaluation.py +0 -1814
- ads/aqua/extension/__init__.py +0 -42
- ads/aqua/extension/aqua_ws_msg_handler.py +0 -76
- ads/aqua/extension/base_handler.py +0 -90
- ads/aqua/extension/common_handler.py +0 -121
- ads/aqua/extension/common_ws_msg_handler.py +0 -36
- ads/aqua/extension/deployment_handler.py +0 -298
- ads/aqua/extension/deployment_ws_msg_handler.py +0 -54
- ads/aqua/extension/errors.py +0 -30
- ads/aqua/extension/evaluation_handler.py +0 -129
- ads/aqua/extension/evaluation_ws_msg_handler.py +0 -61
- ads/aqua/extension/finetune_handler.py +0 -96
- ads/aqua/extension/model_handler.py +0 -390
- ads/aqua/extension/models/__init__.py +0 -0
- ads/aqua/extension/models/ws_models.py +0 -145
- ads/aqua/extension/models_ws_msg_handler.py +0 -50
- ads/aqua/extension/ui_handler.py +0 -282
- ads/aqua/extension/ui_websocket_handler.py +0 -130
- ads/aqua/extension/utils.py +0 -133
- ads/aqua/finetuning/__init__.py +0 -7
- ads/aqua/finetuning/constants.py +0 -23
- ads/aqua/finetuning/entities.py +0 -181
- ads/aqua/finetuning/finetuning.py +0 -731
- ads/aqua/model/__init__.py +0 -8
- ads/aqua/model/constants.py +0 -60
- ads/aqua/model/entities.py +0 -306
- ads/aqua/model/enums.py +0 -30
- ads/aqua/model/model.py +0 -2080
- ads/aqua/modeldeployment/__init__.py +0 -8
- ads/aqua/modeldeployment/constants.py +0 -10
- ads/aqua/modeldeployment/deployment.py +0 -1324
- ads/aqua/modeldeployment/entities.py +0 -653
- ads/aqua/modeldeployment/inference.py +0 -74
- ads/aqua/modeldeployment/utils.py +0 -543
- ads/aqua/resources/gpu_shapes_index.json +0 -94
- ads/aqua/server/__init__.py +0 -4
- ads/aqua/server/__main__.py +0 -24
- ads/aqua/server/app.py +0 -47
- ads/aqua/server/aqua_spec.yml +0 -1291
- ads/aqua/training/__init__.py +0 -4
- ads/aqua/training/exceptions.py +0 -476
- ads/aqua/ui.py +0 -499
- ads/automl/__init__.py +0 -9
- ads/automl/driver.py +0 -330
- ads/automl/provider.py +0 -975
- ads/bds/__init__.py +0 -5
- ads/bds/auth.py +0 -127
- ads/bds/big_data_service.py +0 -255
- ads/catalog/__init__.py +0 -19
- ads/catalog/model.py +0 -1576
- ads/catalog/notebook.py +0 -461
- ads/catalog/project.py +0 -468
- ads/catalog/summary.py +0 -178
- ads/common/__init__.py +0 -11
- ads/common/analyzer.py +0 -65
- ads/common/artifact/.model-ignore +0 -63
- ads/common/artifact/__init__.py +0 -10
- ads/common/auth.py +0 -1122
- ads/common/card_identifier.py +0 -83
- ads/common/config.py +0 -647
- ads/common/data.py +0 -165
- ads/common/decorator/__init__.py +0 -9
- ads/common/decorator/argument_to_case.py +0 -88
- ads/common/decorator/deprecate.py +0 -69
- ads/common/decorator/require_nonempty_arg.py +0 -65
- ads/common/decorator/runtime_dependency.py +0 -178
- ads/common/decorator/threaded.py +0 -97
- ads/common/decorator/utils.py +0 -35
- ads/common/dsc_file_system.py +0 -303
- ads/common/error.py +0 -14
- ads/common/extended_enum.py +0 -81
- ads/common/function/__init__.py +0 -5
- ads/common/function/fn_util.py +0 -142
- ads/common/function/func_conf.yaml +0 -25
- ads/common/ipython.py +0 -76
- ads/common/model.py +0 -679
- ads/common/model_artifact.py +0 -1759
- ads/common/model_artifact_schema.json +0 -107
- ads/common/model_export_util.py +0 -664
- ads/common/model_metadata.py +0 -24
- ads/common/object_storage_details.py +0 -296
- ads/common/oci_client.py +0 -175
- ads/common/oci_datascience.py +0 -46
- ads/common/oci_logging.py +0 -1144
- ads/common/oci_mixin.py +0 -957
- ads/common/oci_resource.py +0 -136
- ads/common/serializer.py +0 -559
- ads/common/utils.py +0 -1852
- ads/common/word_lists.py +0 -1491
- ads/common/work_request.py +0 -189
- ads/data_labeling/__init__.py +0 -13
- ads/data_labeling/boundingbox.py +0 -253
- ads/data_labeling/constants.py +0 -47
- ads/data_labeling/data_labeling_service.py +0 -244
- ads/data_labeling/interface/__init__.py +0 -5
- ads/data_labeling/interface/loader.py +0 -16
- ads/data_labeling/interface/parser.py +0 -16
- ads/data_labeling/interface/reader.py +0 -23
- ads/data_labeling/loader/__init__.py +0 -5
- ads/data_labeling/loader/file_loader.py +0 -241
- ads/data_labeling/metadata.py +0 -110
- ads/data_labeling/mixin/__init__.py +0 -5
- ads/data_labeling/mixin/data_labeling.py +0 -232
- ads/data_labeling/ner.py +0 -129
- ads/data_labeling/parser/__init__.py +0 -5
- ads/data_labeling/parser/dls_record_parser.py +0 -388
- ads/data_labeling/parser/export_metadata_parser.py +0 -94
- ads/data_labeling/parser/export_record_parser.py +0 -473
- ads/data_labeling/reader/__init__.py +0 -5
- ads/data_labeling/reader/dataset_reader.py +0 -574
- ads/data_labeling/reader/dls_record_reader.py +0 -121
- ads/data_labeling/reader/export_record_reader.py +0 -62
- ads/data_labeling/reader/jsonl_reader.py +0 -75
- ads/data_labeling/reader/metadata_reader.py +0 -203
- ads/data_labeling/reader/record_reader.py +0 -263
- ads/data_labeling/record.py +0 -52
- ads/data_labeling/visualizer/__init__.py +0 -5
- ads/data_labeling/visualizer/image_visualizer.py +0 -525
- ads/data_labeling/visualizer/text_visualizer.py +0 -357
- ads/database/__init__.py +0 -5
- ads/database/connection.py +0 -338
- ads/dataset/__init__.py +0 -10
- ads/dataset/capabilities.md +0 -51
- ads/dataset/classification_dataset.py +0 -339
- ads/dataset/correlation.py +0 -226
- ads/dataset/correlation_plot.py +0 -563
- ads/dataset/dask_series.py +0 -173
- ads/dataset/dataframe_transformer.py +0 -110
- ads/dataset/dataset.py +0 -1979
- ads/dataset/dataset_browser.py +0 -360
- ads/dataset/dataset_with_target.py +0 -995
- ads/dataset/exception.py +0 -25
- ads/dataset/factory.py +0 -987
- ads/dataset/feature_engineering_transformer.py +0 -35
- ads/dataset/feature_selection.py +0 -107
- ads/dataset/forecasting_dataset.py +0 -26
- ads/dataset/helper.py +0 -1450
- ads/dataset/label_encoder.py +0 -99
- ads/dataset/mixin/__init__.py +0 -5
- ads/dataset/mixin/dataset_accessor.py +0 -134
- ads/dataset/pipeline.py +0 -58
- ads/dataset/plot.py +0 -710
- ads/dataset/progress.py +0 -86
- ads/dataset/recommendation.py +0 -297
- ads/dataset/recommendation_transformer.py +0 -502
- ads/dataset/regression_dataset.py +0 -14
- ads/dataset/sampled_dataset.py +0 -1050
- ads/dataset/target.py +0 -98
- ads/dataset/timeseries.py +0 -18
- ads/dbmixin/__init__.py +0 -5
- ads/dbmixin/db_pandas_accessor.py +0 -153
- ads/environment/__init__.py +0 -9
- ads/environment/ml_runtime.py +0 -66
- ads/evaluations/README.md +0 -14
- ads/evaluations/__init__.py +0 -109
- ads/evaluations/evaluation_plot.py +0 -983
- ads/evaluations/evaluator.py +0 -1334
- ads/evaluations/statistical_metrics.py +0 -543
- ads/experiments/__init__.py +0 -9
- ads/experiments/capabilities.md +0 -0
- ads/explanations/__init__.py +0 -21
- ads/explanations/base_explainer.py +0 -142
- ads/explanations/capabilities.md +0 -83
- ads/explanations/explainer.py +0 -190
- ads/explanations/mlx_global_explainer.py +0 -1050
- ads/explanations/mlx_interface.py +0 -386
- ads/explanations/mlx_local_explainer.py +0 -287
- ads/explanations/mlx_whatif_explainer.py +0 -201
- ads/feature_engineering/__init__.py +0 -20
- ads/feature_engineering/accessor/__init__.py +0 -5
- ads/feature_engineering/accessor/dataframe_accessor.py +0 -535
- ads/feature_engineering/accessor/mixin/__init__.py +0 -5
- ads/feature_engineering/accessor/mixin/correlation.py +0 -166
- ads/feature_engineering/accessor/mixin/eda_mixin.py +0 -266
- ads/feature_engineering/accessor/mixin/eda_mixin_series.py +0 -85
- ads/feature_engineering/accessor/mixin/feature_types_mixin.py +0 -211
- ads/feature_engineering/accessor/mixin/utils.py +0 -65
- ads/feature_engineering/accessor/series_accessor.py +0 -431
- ads/feature_engineering/adsimage/__init__.py +0 -5
- ads/feature_engineering/adsimage/image.py +0 -192
- ads/feature_engineering/adsimage/image_reader.py +0 -170
- ads/feature_engineering/adsimage/interface/__init__.py +0 -5
- ads/feature_engineering/adsimage/interface/reader.py +0 -19
- ads/feature_engineering/adsstring/__init__.py +0 -7
- ads/feature_engineering/adsstring/oci_language/__init__.py +0 -8
- ads/feature_engineering/adsstring/string/__init__.py +0 -8
- ads/feature_engineering/data_schema.json +0 -57
- ads/feature_engineering/dataset/__init__.py +0 -5
- ads/feature_engineering/dataset/zip_code_data.py +0 -42062
- ads/feature_engineering/exceptions.py +0 -40
- ads/feature_engineering/feature_type/__init__.py +0 -133
- ads/feature_engineering/feature_type/address.py +0 -184
- ads/feature_engineering/feature_type/adsstring/__init__.py +0 -5
- ads/feature_engineering/feature_type/adsstring/common_regex_mixin.py +0 -164
- ads/feature_engineering/feature_type/adsstring/oci_language.py +0 -93
- ads/feature_engineering/feature_type/adsstring/parsers/__init__.py +0 -5
- ads/feature_engineering/feature_type/adsstring/parsers/base.py +0 -47
- ads/feature_engineering/feature_type/adsstring/parsers/nltk_parser.py +0 -96
- ads/feature_engineering/feature_type/adsstring/parsers/spacy_parser.py +0 -221
- ads/feature_engineering/feature_type/adsstring/string.py +0 -258
- ads/feature_engineering/feature_type/base.py +0 -58
- ads/feature_engineering/feature_type/boolean.py +0 -183
- ads/feature_engineering/feature_type/category.py +0 -146
- ads/feature_engineering/feature_type/constant.py +0 -137
- ads/feature_engineering/feature_type/continuous.py +0 -151
- ads/feature_engineering/feature_type/creditcard.py +0 -314
- ads/feature_engineering/feature_type/datetime.py +0 -190
- ads/feature_engineering/feature_type/discrete.py +0 -134
- ads/feature_engineering/feature_type/document.py +0 -43
- ads/feature_engineering/feature_type/gis.py +0 -251
- ads/feature_engineering/feature_type/handler/__init__.py +0 -5
- ads/feature_engineering/feature_type/handler/feature_validator.py +0 -524
- ads/feature_engineering/feature_type/handler/feature_warning.py +0 -319
- ads/feature_engineering/feature_type/handler/warnings.py +0 -128
- ads/feature_engineering/feature_type/integer.py +0 -142
- ads/feature_engineering/feature_type/ip_address.py +0 -144
- ads/feature_engineering/feature_type/ip_address_v4.py +0 -138
- ads/feature_engineering/feature_type/ip_address_v6.py +0 -138
- ads/feature_engineering/feature_type/lat_long.py +0 -256
- ads/feature_engineering/feature_type/object.py +0 -43
- ads/feature_engineering/feature_type/ordinal.py +0 -132
- ads/feature_engineering/feature_type/phone_number.py +0 -135
- ads/feature_engineering/feature_type/string.py +0 -171
- ads/feature_engineering/feature_type/text.py +0 -93
- ads/feature_engineering/feature_type/unknown.py +0 -43
- ads/feature_engineering/feature_type/zip_code.py +0 -164
- ads/feature_engineering/feature_type_manager.py +0 -406
- ads/feature_engineering/schema.py +0 -795
- ads/feature_engineering/utils.py +0 -245
- ads/feature_store/.readthedocs.yaml +0 -19
- ads/feature_store/README.md +0 -65
- ads/feature_store/__init__.py +0 -9
- ads/feature_store/common/__init__.py +0 -0
- ads/feature_store/common/enums.py +0 -339
- ads/feature_store/common/exceptions.py +0 -18
- ads/feature_store/common/spark_session_singleton.py +0 -125
- ads/feature_store/common/utils/__init__.py +0 -0
- ads/feature_store/common/utils/base64_encoder_decoder.py +0 -72
- ads/feature_store/common/utils/feature_schema_mapper.py +0 -283
- ads/feature_store/common/utils/transformation_utils.py +0 -82
- ads/feature_store/common/utils/utility.py +0 -403
- ads/feature_store/data_validation/__init__.py +0 -0
- ads/feature_store/data_validation/great_expectation.py +0 -129
- ads/feature_store/dataset.py +0 -1230
- ads/feature_store/dataset_job.py +0 -530
- ads/feature_store/docs/Dockerfile +0 -7
- ads/feature_store/docs/Makefile +0 -44
- ads/feature_store/docs/conf.py +0 -28
- ads/feature_store/docs/requirements.txt +0 -14
- ads/feature_store/docs/source/ads.feature_store.query.rst +0 -20
- ads/feature_store/docs/source/cicd.rst +0 -137
- ads/feature_store/docs/source/conf.py +0 -86
- ads/feature_store/docs/source/data_versioning.rst +0 -33
- ads/feature_store/docs/source/dataset.rst +0 -388
- ads/feature_store/docs/source/dataset_job.rst +0 -27
- ads/feature_store/docs/source/demo.rst +0 -70
- ads/feature_store/docs/source/entity.rst +0 -78
- ads/feature_store/docs/source/feature_group.rst +0 -624
- ads/feature_store/docs/source/feature_group_job.rst +0 -29
- ads/feature_store/docs/source/feature_store.rst +0 -122
- ads/feature_store/docs/source/feature_store_class.rst +0 -123
- ads/feature_store/docs/source/feature_validation.rst +0 -66
- ads/feature_store/docs/source/figures/cicd.png +0 -0
- ads/feature_store/docs/source/figures/data_validation.png +0 -0
- ads/feature_store/docs/source/figures/data_versioning.png +0 -0
- ads/feature_store/docs/source/figures/dataset.gif +0 -0
- ads/feature_store/docs/source/figures/dataset.png +0 -0
- ads/feature_store/docs/source/figures/dataset_lineage.png +0 -0
- ads/feature_store/docs/source/figures/dataset_statistics.png +0 -0
- ads/feature_store/docs/source/figures/dataset_statistics_viz.png +0 -0
- ads/feature_store/docs/source/figures/dataset_validation_results.png +0 -0
- ads/feature_store/docs/source/figures/dataset_validation_summary.png +0 -0
- ads/feature_store/docs/source/figures/drift_monitoring.png +0 -0
- ads/feature_store/docs/source/figures/entity.png +0 -0
- ads/feature_store/docs/source/figures/feature_group.png +0 -0
- ads/feature_store/docs/source/figures/feature_group_lineage.png +0 -0
- ads/feature_store/docs/source/figures/feature_group_statistics_viz.png +0 -0
- ads/feature_store/docs/source/figures/feature_store_deployment.png +0 -0
- ads/feature_store/docs/source/figures/feature_store_overview.png +0 -0
- ads/feature_store/docs/source/figures/featuregroup.gif +0 -0
- ads/feature_store/docs/source/figures/lineage_d1.png +0 -0
- ads/feature_store/docs/source/figures/lineage_d2.png +0 -0
- ads/feature_store/docs/source/figures/lineage_fg.png +0 -0
- ads/feature_store/docs/source/figures/logo-dark-mode.png +0 -0
- ads/feature_store/docs/source/figures/logo-light-mode.png +0 -0
- ads/feature_store/docs/source/figures/overview.png +0 -0
- ads/feature_store/docs/source/figures/resource_manager.png +0 -0
- ads/feature_store/docs/source/figures/resource_manager_feature_store_stack.png +0 -0
- ads/feature_store/docs/source/figures/resource_manager_home.png +0 -0
- ads/feature_store/docs/source/figures/stats_1.png +0 -0
- ads/feature_store/docs/source/figures/stats_2.png +0 -0
- ads/feature_store/docs/source/figures/stats_d.png +0 -0
- ads/feature_store/docs/source/figures/stats_fg.png +0 -0
- ads/feature_store/docs/source/figures/transformation.png +0 -0
- ads/feature_store/docs/source/figures/transformations.gif +0 -0
- ads/feature_store/docs/source/figures/validation.png +0 -0
- ads/feature_store/docs/source/figures/validation_fg.png +0 -0
- ads/feature_store/docs/source/figures/validation_results.png +0 -0
- ads/feature_store/docs/source/figures/validation_summary.png +0 -0
- ads/feature_store/docs/source/index.rst +0 -81
- ads/feature_store/docs/source/module.rst +0 -8
- ads/feature_store/docs/source/notebook.rst +0 -94
- ads/feature_store/docs/source/overview.rst +0 -47
- ads/feature_store/docs/source/quickstart.rst +0 -176
- ads/feature_store/docs/source/release_notes.rst +0 -194
- ads/feature_store/docs/source/setup_feature_store.rst +0 -81
- ads/feature_store/docs/source/statistics.rst +0 -58
- ads/feature_store/docs/source/transformation.rst +0 -199
- ads/feature_store/docs/source/ui.rst +0 -65
- ads/feature_store/docs/source/user_guides.setup.feature_store_operator.rst +0 -66
- ads/feature_store/docs/source/user_guides.setup.helm_chart.rst +0 -192
- ads/feature_store/docs/source/user_guides.setup.terraform.rst +0 -338
- ads/feature_store/entity.py +0 -718
- ads/feature_store/execution_strategy/__init__.py +0 -0
- ads/feature_store/execution_strategy/delta_lake/__init__.py +0 -0
- ads/feature_store/execution_strategy/delta_lake/delta_lake_service.py +0 -375
- ads/feature_store/execution_strategy/engine/__init__.py +0 -0
- ads/feature_store/execution_strategy/engine/spark_engine.py +0 -316
- ads/feature_store/execution_strategy/execution_strategy.py +0 -113
- ads/feature_store/execution_strategy/execution_strategy_provider.py +0 -47
- ads/feature_store/execution_strategy/spark/__init__.py +0 -0
- ads/feature_store/execution_strategy/spark/spark_execution.py +0 -618
- ads/feature_store/feature.py +0 -192
- ads/feature_store/feature_group.py +0 -1494
- ads/feature_store/feature_group_expectation.py +0 -346
- ads/feature_store/feature_group_job.py +0 -602
- ads/feature_store/feature_lineage/__init__.py +0 -0
- ads/feature_store/feature_lineage/graphviz_service.py +0 -180
- ads/feature_store/feature_option_details.py +0 -50
- ads/feature_store/feature_statistics/__init__.py +0 -0
- ads/feature_store/feature_statistics/statistics_service.py +0 -99
- ads/feature_store/feature_store.py +0 -699
- ads/feature_store/feature_store_registrar.py +0 -518
- ads/feature_store/input_feature_detail.py +0 -149
- ads/feature_store/mixin/__init__.py +0 -4
- ads/feature_store/mixin/oci_feature_store.py +0 -145
- ads/feature_store/model_details.py +0 -73
- ads/feature_store/query/__init__.py +0 -0
- ads/feature_store/query/filter.py +0 -266
- ads/feature_store/query/generator/__init__.py +0 -0
- ads/feature_store/query/generator/query_generator.py +0 -298
- ads/feature_store/query/join.py +0 -161
- ads/feature_store/query/query.py +0 -403
- ads/feature_store/query/validator/__init__.py +0 -0
- ads/feature_store/query/validator/query_validator.py +0 -57
- ads/feature_store/response/__init__.py +0 -0
- ads/feature_store/response/response_builder.py +0 -68
- ads/feature_store/service/__init__.py +0 -0
- ads/feature_store/service/oci_dataset.py +0 -139
- ads/feature_store/service/oci_dataset_job.py +0 -199
- ads/feature_store/service/oci_entity.py +0 -125
- ads/feature_store/service/oci_feature_group.py +0 -164
- ads/feature_store/service/oci_feature_group_job.py +0 -214
- ads/feature_store/service/oci_feature_store.py +0 -182
- ads/feature_store/service/oci_lineage.py +0 -87
- ads/feature_store/service/oci_transformation.py +0 -104
- ads/feature_store/statistics/__init__.py +0 -0
- ads/feature_store/statistics/abs_feature_value.py +0 -49
- ads/feature_store/statistics/charts/__init__.py +0 -0
- ads/feature_store/statistics/charts/abstract_feature_plot.py +0 -37
- ads/feature_store/statistics/charts/box_plot.py +0 -148
- ads/feature_store/statistics/charts/frequency_distribution.py +0 -65
- ads/feature_store/statistics/charts/probability_distribution.py +0 -68
- ads/feature_store/statistics/charts/top_k_frequent_elements.py +0 -98
- ads/feature_store/statistics/feature_stat.py +0 -126
- ads/feature_store/statistics/generic_feature_value.py +0 -33
- ads/feature_store/statistics/statistics.py +0 -41
- ads/feature_store/statistics_config.py +0 -101
- ads/feature_store/templates/feature_store_template.yaml +0 -45
- ads/feature_store/transformation.py +0 -499
- ads/feature_store/validation_output.py +0 -57
- ads/hpo/__init__.py +0 -9
- ads/hpo/_imports.py +0 -91
- ads/hpo/ads_search_space.py +0 -439
- ads/hpo/distributions.py +0 -325
- ads/hpo/objective.py +0 -280
- ads/hpo/search_cv.py +0 -1657
- ads/hpo/stopping_criterion.py +0 -75
- ads/hpo/tuner_artifact.py +0 -413
- ads/hpo/utils.py +0 -91
- ads/hpo/validation.py +0 -140
- ads/hpo/visualization/__init__.py +0 -5
- ads/hpo/visualization/_contour.py +0 -23
- ads/hpo/visualization/_edf.py +0 -20
- ads/hpo/visualization/_intermediate_values.py +0 -21
- ads/hpo/visualization/_optimization_history.py +0 -25
- ads/hpo/visualization/_parallel_coordinate.py +0 -169
- ads/hpo/visualization/_param_importances.py +0 -26
- ads/jobs/__init__.py +0 -53
- ads/jobs/ads_job.py +0 -663
- ads/jobs/builders/__init__.py +0 -5
- ads/jobs/builders/base.py +0 -156
- ads/jobs/builders/infrastructure/__init__.py +0 -6
- ads/jobs/builders/infrastructure/base.py +0 -165
- ads/jobs/builders/infrastructure/dataflow.py +0 -1252
- ads/jobs/builders/infrastructure/dsc_job.py +0 -1894
- ads/jobs/builders/infrastructure/dsc_job_runtime.py +0 -1233
- ads/jobs/builders/infrastructure/utils.py +0 -65
- ads/jobs/builders/runtimes/__init__.py +0 -5
- ads/jobs/builders/runtimes/artifact.py +0 -338
- ads/jobs/builders/runtimes/base.py +0 -325
- ads/jobs/builders/runtimes/container_runtime.py +0 -242
- ads/jobs/builders/runtimes/python_runtime.py +0 -1016
- ads/jobs/builders/runtimes/pytorch_runtime.py +0 -204
- ads/jobs/cli.py +0 -104
- ads/jobs/env_var_parser.py +0 -131
- ads/jobs/extension.py +0 -160
- ads/jobs/schema/__init__.py +0 -5
- ads/jobs/schema/infrastructure_schema.json +0 -116
- ads/jobs/schema/job_schema.json +0 -42
- ads/jobs/schema/runtime_schema.json +0 -183
- ads/jobs/schema/validator.py +0 -141
- ads/jobs/serializer.py +0 -296
- ads/jobs/templates/__init__.py +0 -5
- ads/jobs/templates/container.py +0 -6
- ads/jobs/templates/driver_notebook.py +0 -177
- ads/jobs/templates/driver_oci.py +0 -500
- ads/jobs/templates/driver_python.py +0 -48
- ads/jobs/templates/driver_pytorch.py +0 -852
- ads/jobs/templates/driver_utils.py +0 -615
- ads/jobs/templates/hostname_from_env.c +0 -55
- ads/jobs/templates/oci_metrics.py +0 -181
- ads/jobs/utils.py +0 -104
- ads/llm/__init__.py +0 -28
- ads/llm/autogen/__init__.py +0 -2
- ads/llm/autogen/constants.py +0 -15
- ads/llm/autogen/reports/__init__.py +0 -2
- ads/llm/autogen/reports/base.py +0 -67
- ads/llm/autogen/reports/data.py +0 -103
- ads/llm/autogen/reports/session.py +0 -526
- ads/llm/autogen/reports/templates/chat_box.html +0 -13
- ads/llm/autogen/reports/templates/chat_box_lt.html +0 -5
- ads/llm/autogen/reports/templates/chat_box_rt.html +0 -6
- ads/llm/autogen/reports/utils.py +0 -56
- ads/llm/autogen/v02/__init__.py +0 -4
- ads/llm/autogen/v02/client.py +0 -295
- ads/llm/autogen/v02/log_handlers/__init__.py +0 -2
- ads/llm/autogen/v02/log_handlers/oci_file_handler.py +0 -83
- ads/llm/autogen/v02/loggers/__init__.py +0 -6
- ads/llm/autogen/v02/loggers/metric_logger.py +0 -320
- ads/llm/autogen/v02/loggers/session_logger.py +0 -580
- ads/llm/autogen/v02/loggers/utils.py +0 -86
- ads/llm/autogen/v02/runtime_logging.py +0 -163
- ads/llm/chain.py +0 -268
- ads/llm/chat_template.py +0 -31
- ads/llm/deploy.py +0 -63
- ads/llm/guardrails/__init__.py +0 -5
- ads/llm/guardrails/base.py +0 -442
- ads/llm/guardrails/huggingface.py +0 -44
- ads/llm/langchain/__init__.py +0 -5
- ads/llm/langchain/plugins/__init__.py +0 -5
- ads/llm/langchain/plugins/chat_models/__init__.py +0 -5
- ads/llm/langchain/plugins/chat_models/oci_data_science.py +0 -1027
- ads/llm/langchain/plugins/embeddings/__init__.py +0 -4
- ads/llm/langchain/plugins/embeddings/oci_data_science_model_deployment_endpoint.py +0 -184
- ads/llm/langchain/plugins/llms/__init__.py +0 -5
- ads/llm/langchain/plugins/llms/oci_data_science_model_deployment_endpoint.py +0 -979
- ads/llm/requirements.txt +0 -3
- ads/llm/serialize.py +0 -219
- ads/llm/serializers/__init__.py +0 -0
- ads/llm/serializers/retrieval_qa.py +0 -153
- ads/llm/serializers/runnable_parallel.py +0 -27
- ads/llm/templates/score_chain.jinja2 +0 -155
- ads/llm/templates/tool_chat_template_hermes.jinja +0 -130
- ads/llm/templates/tool_chat_template_mistral_parallel.jinja +0 -94
- ads/model/__init__.py +0 -52
- ads/model/artifact.py +0 -573
- ads/model/artifact_downloader.py +0 -254
- ads/model/artifact_uploader.py +0 -267
- ads/model/base_properties.py +0 -238
- ads/model/common/.model-ignore +0 -66
- ads/model/common/__init__.py +0 -5
- ads/model/common/utils.py +0 -142
- ads/model/datascience_model.py +0 -2635
- ads/model/deployment/__init__.py +0 -20
- ads/model/deployment/common/__init__.py +0 -5
- ads/model/deployment/common/utils.py +0 -308
- ads/model/deployment/model_deployer.py +0 -466
- ads/model/deployment/model_deployment.py +0 -1846
- ads/model/deployment/model_deployment_infrastructure.py +0 -671
- ads/model/deployment/model_deployment_properties.py +0 -493
- ads/model/deployment/model_deployment_runtime.py +0 -838
- ads/model/extractor/__init__.py +0 -5
- ads/model/extractor/automl_extractor.py +0 -74
- ads/model/extractor/embedding_onnx_extractor.py +0 -80
- ads/model/extractor/huggingface_extractor.py +0 -88
- ads/model/extractor/keras_extractor.py +0 -84
- ads/model/extractor/lightgbm_extractor.py +0 -93
- ads/model/extractor/model_info_extractor.py +0 -114
- ads/model/extractor/model_info_extractor_factory.py +0 -105
- ads/model/extractor/pytorch_extractor.py +0 -87
- ads/model/extractor/sklearn_extractor.py +0 -112
- ads/model/extractor/spark_extractor.py +0 -89
- ads/model/extractor/tensorflow_extractor.py +0 -85
- ads/model/extractor/xgboost_extractor.py +0 -94
- ads/model/framework/__init__.py +0 -5
- ads/model/framework/automl_model.py +0 -178
- ads/model/framework/embedding_onnx_model.py +0 -438
- ads/model/framework/huggingface_model.py +0 -399
- ads/model/framework/lightgbm_model.py +0 -266
- ads/model/framework/pytorch_model.py +0 -266
- ads/model/framework/sklearn_model.py +0 -250
- ads/model/framework/spark_model.py +0 -326
- ads/model/framework/tensorflow_model.py +0 -254
- ads/model/framework/xgboost_model.py +0 -258
- ads/model/generic_model.py +0 -3518
- ads/model/model_artifact_boilerplate/README.md +0 -381
- ads/model/model_artifact_boilerplate/__init__.py +0 -5
- ads/model/model_artifact_boilerplate/artifact_introspection_test/__init__.py +0 -5
- ads/model/model_artifact_boilerplate/artifact_introspection_test/model_artifact_validate.py +0 -427
- ads/model/model_artifact_boilerplate/artifact_introspection_test/requirements.txt +0 -2
- ads/model/model_artifact_boilerplate/runtime.yaml +0 -7
- ads/model/model_artifact_boilerplate/score.py +0 -61
- ads/model/model_file_description_schema.json +0 -68
- ads/model/model_introspect.py +0 -331
- ads/model/model_metadata.py +0 -1810
- ads/model/model_metadata_mixin.py +0 -460
- ads/model/model_properties.py +0 -63
- ads/model/model_version_set.py +0 -739
- ads/model/runtime/__init__.py +0 -5
- ads/model/runtime/env_info.py +0 -306
- ads/model/runtime/model_deployment_details.py +0 -37
- ads/model/runtime/model_provenance_details.py +0 -58
- ads/model/runtime/runtime_info.py +0 -81
- ads/model/runtime/schemas/inference_env_info_schema.yaml +0 -16
- ads/model/runtime/schemas/model_provenance_schema.yaml +0 -36
- ads/model/runtime/schemas/training_env_info_schema.yaml +0 -16
- ads/model/runtime/utils.py +0 -201
- ads/model/serde/__init__.py +0 -5
- ads/model/serde/common.py +0 -40
- ads/model/serde/model_input.py +0 -547
- ads/model/serde/model_serializer.py +0 -1184
- ads/model/service/__init__.py +0 -5
- ads/model/service/oci_datascience_model.py +0 -1076
- ads/model/service/oci_datascience_model_deployment.py +0 -500
- ads/model/service/oci_datascience_model_version_set.py +0 -176
- ads/model/transformer/__init__.py +0 -5
- ads/model/transformer/onnx_transformer.py +0 -324
- ads/mysqldb/__init__.py +0 -5
- ads/mysqldb/mysql_db.py +0 -227
- ads/opctl/__init__.py +0 -18
- ads/opctl/anomaly_detection.py +0 -11
- ads/opctl/backend/__init__.py +0 -5
- ads/opctl/backend/ads_dataflow.py +0 -353
- ads/opctl/backend/ads_ml_job.py +0 -710
- ads/opctl/backend/ads_ml_pipeline.py +0 -164
- ads/opctl/backend/ads_model_deployment.py +0 -209
- ads/opctl/backend/base.py +0 -146
- ads/opctl/backend/local.py +0 -1053
- ads/opctl/backend/marketplace/__init__.py +0 -9
- ads/opctl/backend/marketplace/helm_helper.py +0 -173
- ads/opctl/backend/marketplace/local_marketplace.py +0 -271
- ads/opctl/backend/marketplace/marketplace_backend_runner.py +0 -71
- ads/opctl/backend/marketplace/marketplace_operator_interface.py +0 -44
- ads/opctl/backend/marketplace/marketplace_operator_runner.py +0 -24
- ads/opctl/backend/marketplace/marketplace_utils.py +0 -212
- ads/opctl/backend/marketplace/models/__init__.py +0 -5
- ads/opctl/backend/marketplace/models/bearer_token.py +0 -94
- ads/opctl/backend/marketplace/models/marketplace_type.py +0 -70
- ads/opctl/backend/marketplace/models/ocir_details.py +0 -56
- ads/opctl/backend/marketplace/prerequisite_checker.py +0 -238
- ads/opctl/cli.py +0 -707
- ads/opctl/cmds.py +0 -869
- ads/opctl/conda/__init__.py +0 -5
- ads/opctl/conda/cli.py +0 -193
- ads/opctl/conda/cmds.py +0 -749
- ads/opctl/conda/config.yaml +0 -34
- ads/opctl/conda/manifest_template.yaml +0 -13
- ads/opctl/conda/multipart_uploader.py +0 -188
- ads/opctl/conda/pack.py +0 -89
- ads/opctl/config/__init__.py +0 -5
- ads/opctl/config/base.py +0 -57
- ads/opctl/config/diagnostics/__init__.py +0 -5
- ads/opctl/config/diagnostics/distributed/default_requirements_config.yaml +0 -62
- ads/opctl/config/merger.py +0 -255
- ads/opctl/config/resolver.py +0 -297
- ads/opctl/config/utils.py +0 -79
- ads/opctl/config/validator.py +0 -17
- ads/opctl/config/versioner.py +0 -68
- ads/opctl/config/yaml_parsers/__init__.py +0 -7
- ads/opctl/config/yaml_parsers/base.py +0 -58
- ads/opctl/config/yaml_parsers/distributed/__init__.py +0 -7
- ads/opctl/config/yaml_parsers/distributed/yaml_parser.py +0 -201
- ads/opctl/constants.py +0 -66
- ads/opctl/decorator/__init__.py +0 -5
- ads/opctl/decorator/common.py +0 -129
- ads/opctl/diagnostics/__init__.py +0 -5
- ads/opctl/diagnostics/__main__.py +0 -25
- ads/opctl/diagnostics/check_distributed_job_requirements.py +0 -212
- ads/opctl/diagnostics/check_requirements.py +0 -144
- ads/opctl/diagnostics/requirement_exception.py +0 -9
- ads/opctl/distributed/README.md +0 -109
- ads/opctl/distributed/__init__.py +0 -5
- ads/opctl/distributed/certificates.py +0 -32
- ads/opctl/distributed/cli.py +0 -207
- ads/opctl/distributed/cmds.py +0 -731
- ads/opctl/distributed/common/__init__.py +0 -5
- ads/opctl/distributed/common/abstract_cluster_provider.py +0 -449
- ads/opctl/distributed/common/abstract_framework_spec_builder.py +0 -88
- ads/opctl/distributed/common/cluster_config_helper.py +0 -103
- ads/opctl/distributed/common/cluster_provider_factory.py +0 -21
- ads/opctl/distributed/common/cluster_runner.py +0 -54
- ads/opctl/distributed/common/framework_factory.py +0 -29
- ads/opctl/docker/Dockerfile.job +0 -103
- ads/opctl/docker/Dockerfile.job.arm +0 -107
- ads/opctl/docker/Dockerfile.job.gpu +0 -175
- ads/opctl/docker/base-env.yaml +0 -13
- ads/opctl/docker/cuda.repo +0 -6
- ads/opctl/docker/operator/.dockerignore +0 -0
- ads/opctl/docker/operator/Dockerfile +0 -41
- ads/opctl/docker/operator/Dockerfile.gpu +0 -85
- ads/opctl/docker/operator/cuda.repo +0 -6
- ads/opctl/docker/operator/environment.yaml +0 -8
- ads/opctl/forecast.py +0 -11
- ads/opctl/index.yaml +0 -3
- ads/opctl/model/__init__.py +0 -5
- ads/opctl/model/cli.py +0 -65
- ads/opctl/model/cmds.py +0 -73
- ads/opctl/operator/README.md +0 -4
- ads/opctl/operator/__init__.py +0 -31
- ads/opctl/operator/cli.py +0 -344
- ads/opctl/operator/cmd.py +0 -596
- ads/opctl/operator/common/__init__.py +0 -5
- ads/opctl/operator/common/backend_factory.py +0 -460
- ads/opctl/operator/common/const.py +0 -27
- ads/opctl/operator/common/data/synthetic.csv +0 -16001
- ads/opctl/operator/common/dictionary_merger.py +0 -148
- ads/opctl/operator/common/errors.py +0 -42
- ads/opctl/operator/common/operator_config.py +0 -99
- ads/opctl/operator/common/operator_loader.py +0 -811
- ads/opctl/operator/common/operator_schema.yaml +0 -130
- ads/opctl/operator/common/operator_yaml_generator.py +0 -152
- ads/opctl/operator/common/utils.py +0 -208
- ads/opctl/operator/lowcode/__init__.py +0 -5
- ads/opctl/operator/lowcode/anomaly/MLoperator +0 -16
- ads/opctl/operator/lowcode/anomaly/README.md +0 -207
- ads/opctl/operator/lowcode/anomaly/__init__.py +0 -5
- ads/opctl/operator/lowcode/anomaly/__main__.py +0 -103
- ads/opctl/operator/lowcode/anomaly/cmd.py +0 -35
- ads/opctl/operator/lowcode/anomaly/const.py +0 -167
- ads/opctl/operator/lowcode/anomaly/environment.yaml +0 -10
- ads/opctl/operator/lowcode/anomaly/model/__init__.py +0 -5
- ads/opctl/operator/lowcode/anomaly/model/anomaly_dataset.py +0 -146
- ads/opctl/operator/lowcode/anomaly/model/anomaly_merlion.py +0 -162
- ads/opctl/operator/lowcode/anomaly/model/automlx.py +0 -99
- ads/opctl/operator/lowcode/anomaly/model/autots.py +0 -115
- ads/opctl/operator/lowcode/anomaly/model/base_model.py +0 -404
- ads/opctl/operator/lowcode/anomaly/model/factory.py +0 -110
- ads/opctl/operator/lowcode/anomaly/model/isolationforest.py +0 -78
- ads/opctl/operator/lowcode/anomaly/model/oneclasssvm.py +0 -78
- ads/opctl/operator/lowcode/anomaly/model/randomcutforest.py +0 -120
- ads/opctl/operator/lowcode/anomaly/model/tods.py +0 -119
- ads/opctl/operator/lowcode/anomaly/operator_config.py +0 -127
- ads/opctl/operator/lowcode/anomaly/schema.yaml +0 -401
- ads/opctl/operator/lowcode/anomaly/utils.py +0 -88
- ads/opctl/operator/lowcode/common/__init__.py +0 -5
- ads/opctl/operator/lowcode/common/const.py +0 -10
- ads/opctl/operator/lowcode/common/data.py +0 -116
- ads/opctl/operator/lowcode/common/errors.py +0 -47
- ads/opctl/operator/lowcode/common/transformations.py +0 -296
- ads/opctl/operator/lowcode/common/utils.py +0 -293
- ads/opctl/operator/lowcode/feature_store_marketplace/MLoperator +0 -13
- ads/opctl/operator/lowcode/feature_store_marketplace/README.md +0 -30
- ads/opctl/operator/lowcode/feature_store_marketplace/__init__.py +0 -5
- ads/opctl/operator/lowcode/feature_store_marketplace/__main__.py +0 -116
- ads/opctl/operator/lowcode/feature_store_marketplace/cmd.py +0 -85
- ads/opctl/operator/lowcode/feature_store_marketplace/const.py +0 -15
- ads/opctl/operator/lowcode/feature_store_marketplace/environment.yaml +0 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/models/__init__.py +0 -4
- ads/opctl/operator/lowcode/feature_store_marketplace/models/apigw_config.py +0 -32
- ads/opctl/operator/lowcode/feature_store_marketplace/models/db_config.py +0 -43
- ads/opctl/operator/lowcode/feature_store_marketplace/models/mysql_config.py +0 -120
- ads/opctl/operator/lowcode/feature_store_marketplace/models/serializable_yaml_model.py +0 -34
- ads/opctl/operator/lowcode/feature_store_marketplace/operator_utils.py +0 -386
- ads/opctl/operator/lowcode/feature_store_marketplace/schema.yaml +0 -160
- ads/opctl/operator/lowcode/forecast/MLoperator +0 -25
- ads/opctl/operator/lowcode/forecast/README.md +0 -209
- ads/opctl/operator/lowcode/forecast/__init__.py +0 -5
- ads/opctl/operator/lowcode/forecast/__main__.py +0 -89
- ads/opctl/operator/lowcode/forecast/cmd.py +0 -40
- ads/opctl/operator/lowcode/forecast/const.py +0 -92
- ads/opctl/operator/lowcode/forecast/environment.yaml +0 -20
- ads/opctl/operator/lowcode/forecast/errors.py +0 -26
- ads/opctl/operator/lowcode/forecast/model/__init__.py +0 -5
- ads/opctl/operator/lowcode/forecast/model/arima.py +0 -279
- ads/opctl/operator/lowcode/forecast/model/automlx.py +0 -542
- ads/opctl/operator/lowcode/forecast/model/autots.py +0 -312
- ads/opctl/operator/lowcode/forecast/model/base_model.py +0 -863
- ads/opctl/operator/lowcode/forecast/model/factory.py +0 -106
- ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py +0 -492
- ads/opctl/operator/lowcode/forecast/model/ml_forecast.py +0 -243
- ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +0 -486
- ads/opctl/operator/lowcode/forecast/model/prophet.py +0 -445
- ads/opctl/operator/lowcode/forecast/model_evaluator.py +0 -244
- ads/opctl/operator/lowcode/forecast/operator_config.py +0 -234
- ads/opctl/operator/lowcode/forecast/schema.yaml +0 -506
- ads/opctl/operator/lowcode/forecast/utils.py +0 -413
- ads/opctl/operator/lowcode/forecast/whatifserve/__init__.py +0 -7
- ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py +0 -285
- ads/opctl/operator/lowcode/forecast/whatifserve/score.py +0 -246
- ads/opctl/operator/lowcode/pii/MLoperator +0 -17
- ads/opctl/operator/lowcode/pii/README.md +0 -208
- ads/opctl/operator/lowcode/pii/__init__.py +0 -5
- ads/opctl/operator/lowcode/pii/__main__.py +0 -78
- ads/opctl/operator/lowcode/pii/cmd.py +0 -39
- ads/opctl/operator/lowcode/pii/constant.py +0 -84
- ads/opctl/operator/lowcode/pii/environment.yaml +0 -17
- ads/opctl/operator/lowcode/pii/errors.py +0 -27
- ads/opctl/operator/lowcode/pii/model/__init__.py +0 -5
- ads/opctl/operator/lowcode/pii/model/factory.py +0 -82
- ads/opctl/operator/lowcode/pii/model/guardrails.py +0 -167
- ads/opctl/operator/lowcode/pii/model/pii.py +0 -145
- ads/opctl/operator/lowcode/pii/model/processor/__init__.py +0 -34
- ads/opctl/operator/lowcode/pii/model/processor/email_replacer.py +0 -34
- ads/opctl/operator/lowcode/pii/model/processor/mbi_replacer.py +0 -35
- ads/opctl/operator/lowcode/pii/model/processor/name_replacer.py +0 -225
- ads/opctl/operator/lowcode/pii/model/processor/number_replacer.py +0 -73
- ads/opctl/operator/lowcode/pii/model/processor/remover.py +0 -26
- ads/opctl/operator/lowcode/pii/model/report.py +0 -487
- ads/opctl/operator/lowcode/pii/operator_config.py +0 -95
- ads/opctl/operator/lowcode/pii/schema.yaml +0 -108
- ads/opctl/operator/lowcode/pii/utils.py +0 -43
- ads/opctl/operator/lowcode/recommender/MLoperator +0 -16
- ads/opctl/operator/lowcode/recommender/README.md +0 -206
- ads/opctl/operator/lowcode/recommender/__init__.py +0 -5
- ads/opctl/operator/lowcode/recommender/__main__.py +0 -82
- ads/opctl/operator/lowcode/recommender/cmd.py +0 -33
- ads/opctl/operator/lowcode/recommender/constant.py +0 -30
- ads/opctl/operator/lowcode/recommender/environment.yaml +0 -11
- ads/opctl/operator/lowcode/recommender/model/base_model.py +0 -212
- ads/opctl/operator/lowcode/recommender/model/factory.py +0 -56
- ads/opctl/operator/lowcode/recommender/model/recommender_dataset.py +0 -25
- ads/opctl/operator/lowcode/recommender/model/svd.py +0 -106
- ads/opctl/operator/lowcode/recommender/operator_config.py +0 -81
- ads/opctl/operator/lowcode/recommender/schema.yaml +0 -265
- ads/opctl/operator/lowcode/recommender/utils.py +0 -13
- ads/opctl/operator/runtime/__init__.py +0 -5
- ads/opctl/operator/runtime/const.py +0 -17
- ads/opctl/operator/runtime/container_runtime_schema.yaml +0 -50
- ads/opctl/operator/runtime/marketplace_runtime.py +0 -50
- ads/opctl/operator/runtime/python_marketplace_runtime_schema.yaml +0 -21
- ads/opctl/operator/runtime/python_runtime_schema.yaml +0 -21
- ads/opctl/operator/runtime/runtime.py +0 -115
- ads/opctl/schema.yaml.yml +0 -36
- ads/opctl/script.py +0 -40
- ads/opctl/spark/__init__.py +0 -5
- ads/opctl/spark/cli.py +0 -43
- ads/opctl/spark/cmds.py +0 -147
- ads/opctl/templates/diagnostic_report_template.jinja2 +0 -102
- ads/opctl/utils.py +0 -344
- ads/oracledb/__init__.py +0 -5
- ads/oracledb/oracle_db.py +0 -346
- ads/pipeline/__init__.py +0 -39
- ads/pipeline/ads_pipeline.py +0 -2279
- ads/pipeline/ads_pipeline_run.py +0 -772
- ads/pipeline/ads_pipeline_step.py +0 -605
- ads/pipeline/builders/__init__.py +0 -5
- ads/pipeline/builders/infrastructure/__init__.py +0 -5
- ads/pipeline/builders/infrastructure/custom_script.py +0 -32
- ads/pipeline/cli.py +0 -119
- ads/pipeline/extension.py +0 -291
- ads/pipeline/schema/__init__.py +0 -5
- ads/pipeline/schema/cs_step_schema.json +0 -35
- ads/pipeline/schema/ml_step_schema.json +0 -31
- ads/pipeline/schema/pipeline_schema.json +0 -71
- ads/pipeline/visualizer/__init__.py +0 -5
- ads/pipeline/visualizer/base.py +0 -570
- ads/pipeline/visualizer/graph_renderer.py +0 -272
- ads/pipeline/visualizer/text_renderer.py +0 -84
- ads/secrets/__init__.py +0 -11
- ads/secrets/adb.py +0 -386
- ads/secrets/auth_token.py +0 -86
- ads/secrets/big_data_service.py +0 -365
- ads/secrets/mysqldb.py +0 -149
- ads/secrets/oracledb.py +0 -160
- ads/secrets/secrets.py +0 -407
- ads/telemetry/__init__.py +0 -7
- ads/telemetry/base.py +0 -69
- ads/telemetry/client.py +0 -125
- ads/telemetry/telemetry.py +0 -257
- ads/templates/dataflow_pyspark.jinja2 +0 -13
- ads/templates/dataflow_sparksql.jinja2 +0 -22
- ads/templates/func.jinja2 +0 -20
- ads/templates/schemas/openapi.json +0 -1740
- ads/templates/score-pkl.jinja2 +0 -173
- ads/templates/score.jinja2 +0 -322
- ads/templates/score_embedding_onnx.jinja2 +0 -202
- ads/templates/score_generic.jinja2 +0 -165
- ads/templates/score_huggingface_pipeline.jinja2 +0 -217
- ads/templates/score_lightgbm.jinja2 +0 -185
- ads/templates/score_onnx.jinja2 +0 -407
- ads/templates/score_onnx_new.jinja2 +0 -473
- ads/templates/score_oracle_automl.jinja2 +0 -185
- ads/templates/score_pyspark.jinja2 +0 -154
- ads/templates/score_pytorch.jinja2 +0 -219
- ads/templates/score_scikit-learn.jinja2 +0 -184
- ads/templates/score_tensorflow.jinja2 +0 -184
- ads/templates/score_xgboost.jinja2 +0 -178
- ads/text_dataset/__init__.py +0 -5
- ads/text_dataset/backends.py +0 -211
- ads/text_dataset/dataset.py +0 -445
- ads/text_dataset/extractor.py +0 -207
- ads/text_dataset/options.py +0 -53
- ads/text_dataset/udfs.py +0 -22
- ads/text_dataset/utils.py +0 -49
- ads/type_discovery/__init__.py +0 -9
- ads/type_discovery/abstract_detector.py +0 -21
- ads/type_discovery/constant_detector.py +0 -41
- ads/type_discovery/continuous_detector.py +0 -54
- ads/type_discovery/credit_card_detector.py +0 -99
- ads/type_discovery/datetime_detector.py +0 -92
- ads/type_discovery/discrete_detector.py +0 -118
- ads/type_discovery/document_detector.py +0 -146
- ads/type_discovery/ip_detector.py +0 -68
- ads/type_discovery/latlon_detector.py +0 -90
- ads/type_discovery/phone_number_detector.py +0 -63
- ads/type_discovery/type_discovery_driver.py +0 -87
- ads/type_discovery/typed_feature.py +0 -594
- ads/type_discovery/unknown_detector.py +0 -41
- ads/type_discovery/zipcode_detector.py +0 -48
- ads/vault/__init__.py +0 -7
- ads/vault/vault.py +0 -237
- oracle_ads-2.13.8.dist-info/RECORD +0 -858
- {oracle_ads-2.13.8.dist-info → oracle_ads-2.13.9rc0.dist-info}/licenses/LICENSE.txt +0 -0
ads/common/model_artifact.py
DELETED
@@ -1,1759 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
# -*- coding: utf-8; -*-
|
3
|
-
|
4
|
-
# Copyright (c) 2020, 2023 Oracle and/or its affiliates.
|
5
|
-
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
6
|
-
|
7
|
-
import warnings
|
8
|
-
|
9
|
-
warnings.warn(
|
10
|
-
(
|
11
|
-
"The `ads.common.model_artifact` is deprecated in `oracle-ads 2.6.9` and will be removed in `oracle-ads 3.0`."
|
12
|
-
"Use framework specific Model utility class for saving and deploying model. "
|
13
|
-
"Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html"
|
14
|
-
),
|
15
|
-
DeprecationWarning,
|
16
|
-
stacklevel=2,
|
17
|
-
)
|
18
|
-
|
19
|
-
import fnmatch
|
20
|
-
import importlib
|
21
|
-
import json
|
22
|
-
import os
|
23
|
-
import re
|
24
|
-
import git
|
25
|
-
import shutil
|
26
|
-
import subprocess
|
27
|
-
import sys
|
28
|
-
import textwrap
|
29
|
-
import uuid
|
30
|
-
import python_jsonschema_objects as pjs
|
31
|
-
from enum import Enum
|
32
|
-
from pathlib import Path
|
33
|
-
from typing import Dict, Optional, Union
|
34
|
-
|
35
|
-
import ads.dataset.factory as factory
|
36
|
-
import fsspec
|
37
|
-
import numpy as np
|
38
|
-
import oci.data_science
|
39
|
-
import oci.exceptions
|
40
|
-
import pandas as pd
|
41
|
-
import pkg_resources
|
42
|
-
import yaml
|
43
|
-
|
44
|
-
from ads.common.decorator.runtime_dependency import (
|
45
|
-
runtime_dependency,
|
46
|
-
OptionalDependency,
|
47
|
-
)
|
48
|
-
from ads.common import logger, utils
|
49
|
-
from ads.common import auth as authutil
|
50
|
-
from ads.common.data import ADSData
|
51
|
-
from ads.common.error import ChangesNotCommitted
|
52
|
-
from ads.model.model_introspect import (
|
53
|
-
TEST_STATUS,
|
54
|
-
Introspectable,
|
55
|
-
IntrospectionNotPassed,
|
56
|
-
ModelIntrospect,
|
57
|
-
)
|
58
|
-
from ads.model.model_metadata import (
|
59
|
-
METADATA_SIZE_LIMIT,
|
60
|
-
MetadataCustomCategory,
|
61
|
-
MetadataCustomKeys,
|
62
|
-
MetadataSizeTooLarge,
|
63
|
-
MetadataTaxonomyKeys,
|
64
|
-
ModelCustomMetadata,
|
65
|
-
ModelCustomMetadataItem,
|
66
|
-
ModelTaxonomyMetadata,
|
67
|
-
UseCaseType,
|
68
|
-
)
|
69
|
-
from ads.common.object_storage_details import (
|
70
|
-
InvalidObjectStoragePath,
|
71
|
-
ObjectStorageDetails,
|
72
|
-
)
|
73
|
-
from ads.common.utils import DATA_SCHEMA_MAX_COL_NUM
|
74
|
-
from ads.config import (
|
75
|
-
JOB_RUN_COMPARTMENT_OCID,
|
76
|
-
JOB_RUN_OCID,
|
77
|
-
NB_SESSION_COMPARTMENT_OCID,
|
78
|
-
NB_SESSION_OCID,
|
79
|
-
PROJECT_OCID,
|
80
|
-
)
|
81
|
-
from ads.common.decorator.deprecate import deprecated
|
82
|
-
from ads.feature_engineering.schema import DataSizeTooWide, Schema, SchemaSizeTooLarge
|
83
|
-
from ads.model.extractor.model_info_extractor_factory import ModelInfoExtractorFactory
|
84
|
-
from ads.model.model_version_set import ModelVersionSet
|
85
|
-
from ads.model.common.utils import fetch_manifest_from_conda_location
|
86
|
-
from git import InvalidGitRepositoryError, Repo
|
87
|
-
|
88
|
-
from oci.data_science.models import ModelProvenance
|
89
|
-
|
90
|
-
try:
|
91
|
-
from yaml import CDumper as dumper
|
92
|
-
from yaml import CLoader as loader
|
93
|
-
except:
|
94
|
-
from yaml import Dumper as dumper
|
95
|
-
from yaml import Loader as loader
|
96
|
-
|
97
|
-
MODEL_ARTIFACT_VERSION = "3.0"
|
98
|
-
INPUT_SCHEMA_FILE_NAME = "input_schema.json"
|
99
|
-
OUTPUT_SCHEMA_FILE_NAME = "output_schema.json"
|
100
|
-
|
101
|
-
_TRAINING_RESOURCE_OCID = JOB_RUN_OCID or NB_SESSION_OCID
|
102
|
-
_COMPARTMENT_OCID = NB_SESSION_COMPARTMENT_OCID or JOB_RUN_COMPARTMENT_OCID
|
103
|
-
|
104
|
-
|
105
|
-
class InvalidDataType(Exception): # pragma: no cover
|
106
|
-
"""Invalid Data Type."""
|
107
|
-
|
108
|
-
pass
|
109
|
-
|
110
|
-
|
111
|
-
SAMPLE_RUNTIME_YAML = f"""
|
112
|
-
MODEL_ARTIFACT_VERSION: '{MODEL_ARTIFACT_VERSION}'
|
113
|
-
MODEL_DEPLOYMENT:
|
114
|
-
INFERENCE_CONDA_ENV:
|
115
|
-
INFERENCE_ENV_SLUG: <slug of the conda environment>
|
116
|
-
INFERENCE_ENV_TYPE: <data_science or published>
|
117
|
-
INFERENCE_ENV_PATH: oci://<bucket-name>@<namespace>/<prefix>/<env>.tar.gz
|
118
|
-
INFERENCE_PYTHON_VERSION: <python version>
|
119
|
-
"""
|
120
|
-
|
121
|
-
|
122
|
-
class ConflictStrategy(object):
|
123
|
-
IGNORE = "IGNORE"
|
124
|
-
UPDATE = "UPDATE"
|
125
|
-
CREATE = "CREATE"
|
126
|
-
|
127
|
-
|
128
|
-
class PACK_TYPE(Enum):
|
129
|
-
SERVICE_PACK = "data_science"
|
130
|
-
USER_CUSTOM_PACK = "published"
|
131
|
-
|
132
|
-
|
133
|
-
class ModelArtifact(Introspectable):
|
134
|
-
@deprecated(
|
135
|
-
"2.6.6",
|
136
|
-
details="Use framework specific Model utility class for saving and deploying model. Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html",
|
137
|
-
)
|
138
|
-
def __init__(
|
139
|
-
self,
|
140
|
-
artifact_dir,
|
141
|
-
conflict_strategy=ConflictStrategy.IGNORE,
|
142
|
-
install_libs=False,
|
143
|
-
reload=True,
|
144
|
-
create=False,
|
145
|
-
progress=None,
|
146
|
-
model_file_name="model.onnx",
|
147
|
-
inference_conda_env=None,
|
148
|
-
data_science_env=False,
|
149
|
-
ignore_deployment_error=False,
|
150
|
-
inference_python_version=None,
|
151
|
-
):
|
152
|
-
"""
|
153
|
-
A class used to construct model artifacts.
|
154
|
-
|
155
|
-
...
|
156
|
-
|
157
|
-
Attributes
|
158
|
-
----------
|
159
|
-
artifact_dir: str
|
160
|
-
Path to the model artifacts.
|
161
|
-
conflict_strategy: ConflictStrategy, default: IGNORE
|
162
|
-
How to handle version conflicts between the current environment and the requirements of
|
163
|
-
model artifact.
|
164
|
-
install_libs: bool
|
165
|
-
Re-install the environment inwhich the model artifact were trained in.
|
166
|
-
reload: bool
|
167
|
-
Reload the model into the environment.
|
168
|
-
create: bool
|
169
|
-
Create the `runtime.yaml` file.
|
170
|
-
progress:
|
171
|
-
Show a progress bar.
|
172
|
-
model_file_name: str
|
173
|
-
Name of the model file.
|
174
|
-
inference_conda_env: str
|
175
|
-
The inference conda environment. If provided, the value will be set in the runtime.yaml.
|
176
|
-
This is expected to be full oci URI format - `oci://{bucket}@{namespace}/path/to/condapack`.
|
177
|
-
data_science_env: bool
|
178
|
-
Is the inference conda environment managed by the Oracle Data Science service?
|
179
|
-
ignore_deployment_error: bool
|
180
|
-
Determine whether to turn off logging for deployment error.
|
181
|
-
If set to True, the `.prepare()` method will ignore errors that impact model deployment.
|
182
|
-
inference_python_version: str Optional, default None
|
183
|
-
The version of Python to be used in inference. The value will be set in the `runtime.yaml` file
|
184
|
-
|
185
|
-
|
186
|
-
Methods
|
187
|
-
-------
|
188
|
-
reload(self, model_file_name=None)
|
189
|
-
Reload the files in the model artifact directory.
|
190
|
-
verify(self, input_data)
|
191
|
-
Verifies a model artifact directory.
|
192
|
-
install_requirements(self, conflict_strategy=ConflictStrategy.IGNORE)
|
193
|
-
Installs missing libraries listed in the model artifact.
|
194
|
-
populate_metadata(self, model=None, use_case_type=None)
|
195
|
-
Extracts and populate taxonomy metadata from the model.
|
196
|
-
save(
|
197
|
-
self,
|
198
|
-
display_name: str = None,
|
199
|
-
description: str = None,
|
200
|
-
project_id: str = None,
|
201
|
-
compartment_id: str = None,
|
202
|
-
training_script_path: str = None,
|
203
|
-
ignore_pending_changes: bool = False,
|
204
|
-
auth: dict = None,
|
205
|
-
training_id: str = None,
|
206
|
-
timeout: int = None,
|
207
|
-
ignore_introspection=False,
|
208
|
-
)
|
209
|
-
Saves this model artifact in model catalog.
|
210
|
-
populate_schema(
|
211
|
-
self,
|
212
|
-
data_sample: ADSData = None,
|
213
|
-
X_sample: Union[list, tuple, pd.DataFrame, pd.Series, np.ndarray] = None,
|
214
|
-
y_sample: Union[list, tuple, pd.DataFrame, pd.Series, np.ndarray] = None,
|
215
|
-
)
|
216
|
-
Populates input and output schema.
|
217
|
-
introspect(self) -> pd.DataFrame
|
218
|
-
Runs model introspection.
|
219
|
-
|
220
|
-
"""
|
221
|
-
self.artifact_dir = (
|
222
|
-
artifact_dir[:-1] if artifact_dir.endswith("/") else artifact_dir
|
223
|
-
)
|
224
|
-
self._introspect = ModelIntrospect(self)
|
225
|
-
self.model = None
|
226
|
-
self.score = None
|
227
|
-
self.inference_conda_env = inference_conda_env
|
228
|
-
self.data_science_env = data_science_env
|
229
|
-
self.ignore_deployment_error = ignore_deployment_error
|
230
|
-
self.metadata_taxonomy = ModelTaxonomyMetadata()
|
231
|
-
self.metadata_custom = ModelCustomMetadata()
|
232
|
-
self.schema_input = Schema()
|
233
|
-
self.schema_output = Schema()
|
234
|
-
self._serialization_format = None
|
235
|
-
self.inference_python_version = inference_python_version
|
236
|
-
|
237
|
-
if create:
|
238
|
-
self.progress = progress
|
239
|
-
if "CONDA_PREFIX" in os.environ and "NB_SESSION_OCID" in os.environ:
|
240
|
-
self._generate_runtime_yaml(model_file_name=model_file_name)
|
241
|
-
else:
|
242
|
-
self._generate_empty_runtime_yaml(
|
243
|
-
model_file_name=model_file_name,
|
244
|
-
data_science_env=data_science_env,
|
245
|
-
inference_conda_env=inference_conda_env,
|
246
|
-
inference_python_version=inference_python_version,
|
247
|
-
)
|
248
|
-
self.version = MODEL_ARTIFACT_VERSION
|
249
|
-
|
250
|
-
# This will re-install the environment inwhich the model artifact was trained in.
|
251
|
-
if install_libs:
|
252
|
-
self.install_requirements(conflict_strategy=conflict_strategy)
|
253
|
-
# This will reload the model into the environment
|
254
|
-
if reload:
|
255
|
-
self.reload(model_file_name=model_file_name)
|
256
|
-
|
257
|
-
def __repr__(self):
|
258
|
-
res = "Artifact directory: %s\n" % self.artifact_dir
|
259
|
-
res += "Contains: %s" % str(self._get_files())
|
260
|
-
return res
|
261
|
-
|
262
|
-
def __getattr__(self, item):
|
263
|
-
return getattr(self.score, item)
|
264
|
-
|
265
|
-
def __fetch_repo_details(self, training_code_info):
|
266
|
-
repo = git.Repo(".", search_parent_directories=True)
|
267
|
-
# get repository url
|
268
|
-
if len(repo.remotes) > 0:
|
269
|
-
repository_url = (
|
270
|
-
repo.remotes.origin.url
|
271
|
-
if repo.remotes.origin in repo.remotes
|
272
|
-
else list(repo.remotes.values())[0].url
|
273
|
-
)
|
274
|
-
else:
|
275
|
-
repository_url = "file://" + repo.working_dir # no remote repo
|
276
|
-
|
277
|
-
git_branch = None
|
278
|
-
git_commit = None
|
279
|
-
try:
|
280
|
-
# get git branch
|
281
|
-
git_branch = format(repo.active_branch)
|
282
|
-
# get git commit
|
283
|
-
git_commit = format(str(repo.head.commit.hexsha))
|
284
|
-
training_code_info.GIT_COMMIT = git_commit
|
285
|
-
except ValueError:
|
286
|
-
# do not set commit if there isn't any
|
287
|
-
pass
|
288
|
-
|
289
|
-
training_code_info.GIT_REMOTE = repository_url
|
290
|
-
training_code_info.GIT_BRANCH = git_branch
|
291
|
-
training_code_info.ARTIFACT_DIRECTORY = self.artifact_dir
|
292
|
-
return repo, training_code_info
|
293
|
-
|
294
|
-
def __fetch_training_env_details(self, training_info):
|
295
|
-
conda_prefix = os.environ.get("CONDA_PREFIX", None)
|
296
|
-
pack_name = "NOT FOUND"
|
297
|
-
try:
|
298
|
-
manifest = fetch_manifest_from_conda_location(conda_prefix)
|
299
|
-
manifest_type = manifest["type"]
|
300
|
-
pack_name = manifest["pack_path"] if "pack_path" in manifest else None
|
301
|
-
slug = manifest["slug"] if "slug" in manifest else ""
|
302
|
-
|
303
|
-
if manifest_type == PACK_TYPE.USER_CUSTOM_PACK.value:
|
304
|
-
if os.path.exists(
|
305
|
-
os.path.join(os.path.expanduser("~"), "conda", "config.yaml")
|
306
|
-
):
|
307
|
-
with open(
|
308
|
-
(os.path.join(os.path.expanduser("~"), "conda", "config.yaml"))
|
309
|
-
) as conf:
|
310
|
-
user_config = yaml.load(conf, Loader=yaml.FullLoader)
|
311
|
-
pack_bucket = user_config["bucket_info"]["name"]
|
312
|
-
pack_namespace = user_config["bucket_info"]["namespace"]
|
313
|
-
else:
|
314
|
-
logger.warning(
|
315
|
-
f"Cannot resolve the bucket name or namespace for the conda environment {conda_prefix}. "
|
316
|
-
f"You can set these values while saving the model or run `odsc init -b *bucket-name* -n *namespace*` and rerun the prepare step again."
|
317
|
-
)
|
318
|
-
if not manifest_type or manifest_type.lower() not in [
|
319
|
-
PACK_TYPE.USER_CUSTOM_PACK.value,
|
320
|
-
PACK_TYPE.SERVICE_PACK.value,
|
321
|
-
]:
|
322
|
-
if not self.ignore_deployment_error:
|
323
|
-
raise Exception(
|
324
|
-
f"Unknown manifest type. Manifest Type: {manifest_type or 'None'}"
|
325
|
-
)
|
326
|
-
if not pack_name:
|
327
|
-
if manifest_type == PACK_TYPE.USER_CUSTOM_PACK.value:
|
328
|
-
if self.data_science_env:
|
329
|
-
raise Exception(
|
330
|
-
f"For Published conda environments, assign the path of the environment in "
|
331
|
-
+ "Object Storage to the `inference_conda_env` parameter and set the "
|
332
|
-
+ "parameter `data_science_env` to `False`."
|
333
|
-
)
|
334
|
-
error_message = (
|
335
|
-
f"Pack destination is not known from the manifest file in {conda_prefix}. "
|
336
|
-
+ "If it was cloned from another environment, consider publishing it before "
|
337
|
-
+ "preparing the model artifact."
|
338
|
-
)
|
339
|
-
if self.ignore_deployment_error:
|
340
|
-
logger.warn(error_message)
|
341
|
-
else:
|
342
|
-
if not self.inference_conda_env:
|
343
|
-
logger.error(error_message)
|
344
|
-
logger.info(
|
345
|
-
"Provide a URI to the conda environment that you wish to use with the model "
|
346
|
-
"deployment service if you do not want to publish the current training environment."
|
347
|
-
)
|
348
|
-
raise Exception(
|
349
|
-
f"Could not resolve the path in the Object Storage for the conda environment: {conda_prefix}"
|
350
|
-
)
|
351
|
-
else:
|
352
|
-
logger.warn(
|
353
|
-
f"Could not resolve the Object Storage destination of {conda_prefix}. Correct "
|
354
|
-
"the environment name and Object Storage details when saving."
|
355
|
-
)
|
356
|
-
except Exception as e:
|
357
|
-
raise e
|
358
|
-
training_info.TRAINING_ENV_SLUG = slug
|
359
|
-
if manifest_type.lower() in [
|
360
|
-
PACK_TYPE.USER_CUSTOM_PACK.value,
|
361
|
-
PACK_TYPE.SERVICE_PACK.value,
|
362
|
-
]:
|
363
|
-
training_info.TRAINING_ENV_TYPE = manifest_type
|
364
|
-
if pack_name:
|
365
|
-
training_info.TRAINING_ENV_PATH = pack_name
|
366
|
-
training_info.TRAINING_PYTHON_VERSION = sys.version.split("|")[0].strip()
|
367
|
-
return training_info
|
368
|
-
|
369
|
-
def __environment_details(self, model_provenance):
|
370
|
-
model_provenance.TRAINING_REGION = os.environ.get("NB_REGION", "NOT_FOUND")
|
371
|
-
model_provenance.TRAINING_COMPARTMENT_OCID = os.environ.get(
|
372
|
-
"NB_SESSION_COMPARTMENT_OCID", "NOT_FOUND"
|
373
|
-
)
|
374
|
-
model_provenance.TRAINING_RESOURCE_OCID = os.environ.get(
|
375
|
-
"NB_SESSION_OCID", "NOT_FOUND"
|
376
|
-
)
|
377
|
-
model_provenance.PROJECT_OCID = os.environ.get("PROJECT_OCID", "NOT_FOUND")
|
378
|
-
model_provenance.TENANCY_OCID = os.environ.get("TENANCY_OCID", "NOT_FOUND")
|
379
|
-
model_provenance.USER_OCID = os.environ.get("USER_OCID", "NOT_FOUND")
|
380
|
-
model_provenance.VM_IMAGE_INTERNAL_ID = os.environ.get("VM_ID", "VMIDNOTSET")
|
381
|
-
return model_provenance
|
382
|
-
|
383
|
-
def __fetch_runtime_schema__(self):
|
384
|
-
schema = None
|
385
|
-
with open(
|
386
|
-
os.path.join(
|
387
|
-
os.path.dirname(os.path.abspath(__file__)), "model_artifact_schema.json"
|
388
|
-
)
|
389
|
-
) as schema_file:
|
390
|
-
schema = json.load(schema_file)
|
391
|
-
|
392
|
-
if not schema:
|
393
|
-
raise Exception(
|
394
|
-
"Cannot load schema file to generate the runtime.yaml file."
|
395
|
-
)
|
396
|
-
|
397
|
-
builder = pjs.ObjectBuilder(schema)
|
398
|
-
ns = builder.build_classes()
|
399
|
-
return ns
|
400
|
-
|
401
|
-
def _generate_empty_runtime_yaml(
|
402
|
-
self,
|
403
|
-
model_file_name="model.onnx",
|
404
|
-
data_science_env=False,
|
405
|
-
inference_conda_env=None,
|
406
|
-
inference_python_version=None,
|
407
|
-
):
|
408
|
-
if self.progress:
|
409
|
-
self.progress.update("Creating runtime.yaml configuration.")
|
410
|
-
logger.warning(
|
411
|
-
"Generating runtime.yaml template. This file needs to be updated "
|
412
|
-
"before saving it to the model catalog."
|
413
|
-
)
|
414
|
-
content = yaml.load(SAMPLE_RUNTIME_YAML, Loader=yaml.FullLoader)
|
415
|
-
print(
|
416
|
-
f"The inference conda environment is {inference_conda_env} and the Python version is {inference_python_version}."
|
417
|
-
)
|
418
|
-
if inference_conda_env:
|
419
|
-
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"][
|
420
|
-
"INFERENCE_ENV_SLUG"
|
421
|
-
] = ""
|
422
|
-
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"][
|
423
|
-
"INFERENCE_ENV_TYPE"
|
424
|
-
] = ""
|
425
|
-
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"][
|
426
|
-
"INFERENCE_ENV_PATH"
|
427
|
-
] = inference_conda_env
|
428
|
-
if inference_python_version:
|
429
|
-
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"][
|
430
|
-
"INFERENCE_PYTHON_VERSION"
|
431
|
-
] = str(inference_python_version)
|
432
|
-
|
433
|
-
content["MODEL_DEPLOYMENT"]["INFERENCE_CONDA_ENV"]["INFERENCE_ENV_TYPE"] = (
|
434
|
-
PACK_TYPE.SERVICE_PACK.value
|
435
|
-
if data_science_env
|
436
|
-
else PACK_TYPE.USER_CUSTOM_PACK.value
|
437
|
-
)
|
438
|
-
|
439
|
-
with open(os.path.join(self.artifact_dir, "runtime.yaml"), "w") as outfile:
|
440
|
-
yaml.dump(content, outfile)
|
441
|
-
|
442
|
-
def _generate_runtime_yaml(self, model_file_name="model.onnx"):
|
443
|
-
if self.progress:
|
444
|
-
self.progress.update("Creating runtime.yaml configuration.")
|
445
|
-
|
446
|
-
ns = self.__fetch_runtime_schema__()
|
447
|
-
training_env_info = self.__fetch_training_env_details(ns.TrainingCondaEnv())
|
448
|
-
model_provenance = self.__environment_details(ns.ModelProvenance())
|
449
|
-
model_provenance.TRAINING_CONDA_ENV = training_env_info
|
450
|
-
try:
|
451
|
-
_, training_code_info = self.__fetch_repo_details(ns.TrainingCodeInfo())
|
452
|
-
model_provenance.TRAINING_CODE = training_code_info
|
453
|
-
except git.InvalidGitRepositoryError:
|
454
|
-
pass
|
455
|
-
|
456
|
-
if not training_env_info.TRAINING_ENV_PATH:
|
457
|
-
logger.warning(
|
458
|
-
"You did not publish the conda environment in which the madel was trained. Publishing the "
|
459
|
-
"conda environment ensures that the exact training environment can be re-used later."
|
460
|
-
)
|
461
|
-
inference_info = ns.InferenceCondaEnv()
|
462
|
-
if not self.inference_conda_env:
|
463
|
-
message = "By default, the inference conda environment is the same as the training conda environment. Use the `inference_conda_env` parameter to override."
|
464
|
-
if (
|
465
|
-
training_env_info.TRAINING_ENV_TYPE
|
466
|
-
and training_env_info.TRAINING_ENV_PATH
|
467
|
-
):
|
468
|
-
logger.info(message)
|
469
|
-
inference_info.INFERENCE_ENV_SLUG = training_env_info.TRAINING_ENV_SLUG
|
470
|
-
inference_info.INFERENCE_ENV_TYPE = training_env_info.TRAINING_ENV_TYPE
|
471
|
-
inference_info.INFERENCE_ENV_PATH = training_env_info.TRAINING_ENV_PATH
|
472
|
-
inference_info.INFERENCE_PYTHON_VERSION = (
|
473
|
-
training_env_info.TRAINING_PYTHON_VERSION
|
474
|
-
)
|
475
|
-
self.conda_env = str(training_env_info.TRAINING_ENV_SLUG)
|
476
|
-
else:
|
477
|
-
self.conda_env = os.path.basename(str(self.inference_conda_env))
|
478
|
-
if self.inference_conda_env.startswith("oci://"):
|
479
|
-
inference_info.INFERENCE_ENV_PATH = self.inference_conda_env
|
480
|
-
try:
|
481
|
-
metadata_json = ObjectStorageDetails.from_path(
|
482
|
-
env_path=self.inference_conda_env
|
483
|
-
).fetch_metadata_of_object()
|
484
|
-
inference_info.INFERENCE_PYTHON_VERSION = metadata_json["python"]
|
485
|
-
except:
|
486
|
-
if not self.inference_python_version:
|
487
|
-
if not training_env_info.TRAINING_PYTHON_VERSION:
|
488
|
-
raise Exception(
|
489
|
-
"The Python version was not specified."
|
490
|
-
"Pass in the Python version when preparing a model."
|
491
|
-
)
|
492
|
-
else:
|
493
|
-
logger.warning(
|
494
|
-
"The Python version could not be inferred from the conda environment. Defaulting to the Python "
|
495
|
-
"version that was used in training."
|
496
|
-
)
|
497
|
-
inference_info.INFERENCE_PYTHON_VERSION = (
|
498
|
-
training_env_info.TRAINING_PYTHON_VERSION
|
499
|
-
)
|
500
|
-
else:
|
501
|
-
inference_info.INFERENCE_PYTHON_VERSION = (
|
502
|
-
self.inference_python_version
|
503
|
-
)
|
504
|
-
else:
|
505
|
-
pass
|
506
|
-
model_deployment_info = None
|
507
|
-
if inference_info.INFERENCE_ENV_PATH:
|
508
|
-
model_deployment_info = ns.ModelDeployment()
|
509
|
-
model_deployment_info.INFERENCE_CONDA_ENV = inference_info
|
510
|
-
|
511
|
-
if (
|
512
|
-
not self.inference_conda_env
|
513
|
-
and not self.data_science_env
|
514
|
-
and inference_info.INFERENCE_ENV_TYPE == PACK_TYPE.SERVICE_PACK.value
|
515
|
-
and training_env_info.TRAINING_ENV_PATH == inference_info.INFERENCE_ENV_PATH
|
516
|
-
):
|
517
|
-
error_message = (
|
518
|
-
f"The inference conda environment {training_env_info.TRAINING_ENV_SLUG} may have changed. "
|
519
|
-
+ "Publish the current conda environment or set the parameter `data_science_env` to `True` "
|
520
|
-
+ "in the `.prepare()` method."
|
521
|
-
)
|
522
|
-
if not self.ignore_deployment_error:
|
523
|
-
raise Exception(error_message)
|
524
|
-
else:
|
525
|
-
logger.warning(error_message)
|
526
|
-
|
527
|
-
if not inference_info.INFERENCE_ENV_PATH and not self.inference_conda_env:
|
528
|
-
error_message = (
|
529
|
-
f"The inference conda environment is missing. Set the `inference_conda_env` parameter "
|
530
|
-
+ "or publish the conda environment and run the `.prepare()` method."
|
531
|
-
)
|
532
|
-
if not self.ignore_deployment_error:
|
533
|
-
raise Exception(error_message)
|
534
|
-
else:
|
535
|
-
logger.warn(error_message)
|
536
|
-
|
537
|
-
if model_deployment_info:
|
538
|
-
self._runtime_info = ns.ModelArtifactSchema(
|
539
|
-
MODEL_ARTIFACT_VERSION=MODEL_ARTIFACT_VERSION,
|
540
|
-
MODEL_PROVENANCE=model_provenance,
|
541
|
-
MODEL_DEPLOYMENT=model_deployment_info,
|
542
|
-
)
|
543
|
-
else:
|
544
|
-
self._runtime_info = ns.ModelArtifactSchema(
|
545
|
-
MODEL_ARTIFACT_VERSION=MODEL_ARTIFACT_VERSION,
|
546
|
-
MODEL_PROVENANCE=model_provenance,
|
547
|
-
)
|
548
|
-
|
549
|
-
with open(os.path.join(self.artifact_dir, "runtime.yaml"), "w") as outfile:
|
550
|
-
outfile.write("# Model runtime environment\n")
|
551
|
-
yaml.dump(self._runtime_info.as_dict(), outfile, default_flow_style=False)
|
552
|
-
|
553
|
-
def reload(self, model_file_name: str = None):
|
554
|
-
"""
|
555
|
-
Reloads files in model artifact directory.
|
556
|
-
|
557
|
-
Parameters
|
558
|
-
----------
|
559
|
-
model_file_name: str
|
560
|
-
The model file name.
|
561
|
-
"""
|
562
|
-
spec = importlib.util.spec_from_file_location(
|
563
|
-
"score%s" % uuid.uuid4(), os.path.join(self.artifact_dir, "score.py")
|
564
|
-
)
|
565
|
-
score = importlib.util.module_from_spec(spec)
|
566
|
-
spec.loader.exec_module(score)
|
567
|
-
self.score = score
|
568
|
-
if os.path.exists(os.path.join(self.artifact_dir, "runtime.yaml")):
|
569
|
-
if model_file_name:
|
570
|
-
self.model = self.score.load_model(model_file_name)
|
571
|
-
else:
|
572
|
-
self.model = self.score.load_model()
|
573
|
-
with open(os.path.join(self.artifact_dir, "runtime.yaml")) as runtime_file:
|
574
|
-
runtime = yaml.load(runtime_file, Loader=yaml.FullLoader)
|
575
|
-
self.version = runtime["MODEL_ARTIFACT_VERSION"]
|
576
|
-
try:
|
577
|
-
self.VM_ID = runtime["MODEL_PROVENANCE"]["VM_IMAGE_INTERNAL_ID"]
|
578
|
-
except KeyError:
|
579
|
-
self.VM_ID = None
|
580
|
-
try:
|
581
|
-
self.conda_env = runtime["MODEL_PROVENANCE"]["TRAINING_CONDA_ENV"][
|
582
|
-
"TRAINING_ENV_SLUG"
|
583
|
-
]
|
584
|
-
except KeyError:
|
585
|
-
self.conda_env = None
|
586
|
-
elif os.path.exists(os.path.join(self.artifact_dir, "ds-runtime.yaml")):
|
587
|
-
self.model = self.score.load_model()
|
588
|
-
with open(
|
589
|
-
os.path.join(self.artifact_dir, "ds-runtime.yaml")
|
590
|
-
) as runtime_file:
|
591
|
-
runtime = yaml.load(runtime_file, Loader=yaml.FullLoader)
|
592
|
-
self.version = "1.0"
|
593
|
-
self.VM_ID = None # get ads/mlx version?
|
594
|
-
self.conda_env = runtime["conda-env"]
|
595
|
-
else:
|
596
|
-
self.model = self.score.load_model()
|
597
|
-
self.version = "0.0"
|
598
|
-
self.VM_ID = "UNKNOWN"
|
599
|
-
self.conda_env = "base"
|
600
|
-
# raise FileNotFoundError(os.path.join(self.artifact_dir, 'runtime.yaml'))
|
601
|
-
# __pycache__ was created during model_artifact.reload() above
|
602
|
-
if os.path.exists(os.path.join(self.artifact_dir, "__pycache__")):
|
603
|
-
shutil.rmtree(
|
604
|
-
os.path.join(self.artifact_dir, "__pycache__"), ignore_errors=True
|
605
|
-
)
|
606
|
-
# extract model serialization format as part of custom metadata
|
607
|
-
if model_file_name:
|
608
|
-
self._serialization_format = self._extract_model_serialization_format(
|
609
|
-
model_file_name
|
610
|
-
)
|
611
|
-
if (
|
612
|
-
MetadataCustomKeys.MODEL_SERIALIZATION_FORMAT
|
613
|
-
in self.metadata_custom.keys
|
614
|
-
):
|
615
|
-
self.metadata_custom[
|
616
|
-
MetadataCustomKeys.MODEL_SERIALIZATION_FORMAT
|
617
|
-
].value = self._serialization_format
|
618
|
-
else:
|
619
|
-
self.metadata_custom.add(
|
620
|
-
key=MetadataCustomKeys.MODEL_SERIALIZATION_FORMAT,
|
621
|
-
value=self._serialization_format,
|
622
|
-
description="The model serialization format",
|
623
|
-
category=MetadataCustomCategory.TRAINING_PROFILE,
|
624
|
-
)
|
625
|
-
|
626
|
-
@staticmethod
|
627
|
-
def _extract_model_serialization_format(model_file_name):
|
628
|
-
return os.path.splitext(model_file_name)[1][1:]
|
629
|
-
|
630
|
-
def verify(self, input_data):
|
631
|
-
"""
|
632
|
-
Verifies the contents of the model artifact directory.
|
633
|
-
|
634
|
-
Parameters
|
635
|
-
----------
|
636
|
-
input_data : str, dict, BytesIO stream
|
637
|
-
Data to be passed into the deployed model. It can be of type json (str), a dict object, or a BytesIO stream.
|
638
|
-
All types get converted into a UTF-8 encoded BytesIO stream and is then sent to the handler.
|
639
|
-
Any data handling past there is done in func.py. By default it looks for data
|
640
|
-
under the keyword "input", and returns data under teh keyword "prediction".
|
641
|
-
|
642
|
-
Returns
|
643
|
-
-------
|
644
|
-
output_data : the resulting prediction, formatted in the same way as input_data
|
645
|
-
|
646
|
-
Example
|
647
|
-
--------
|
648
|
-
input_dict = {"input": train.X[:3].to_dict()}
|
649
|
-
model_artifact.verify(input_dict)
|
650
|
-
|
651
|
-
* returns {"prediction": [30/4, 24.8, 30.7]} *
|
652
|
-
"""
|
653
|
-
|
654
|
-
# Fake Context obj created for Fn Handler
|
655
|
-
class FakeCtx:
|
656
|
-
def SetResponseHeaders(self, headers, status_code):
|
657
|
-
return
|
658
|
-
|
659
|
-
ctx = FakeCtx()
|
660
|
-
from io import BytesIO
|
661
|
-
|
662
|
-
if type(input_data) == str:
|
663
|
-
data = BytesIO(input_data.encode("UTF-8"))
|
664
|
-
data_type = "json"
|
665
|
-
elif type(input_data) == dict:
|
666
|
-
from json import dumps
|
667
|
-
|
668
|
-
data = BytesIO(dumps(input_data).encode("UTF-8"))
|
669
|
-
data_type = "dict"
|
670
|
-
elif isinstance(type(input_data), type(BytesIO)):
|
671
|
-
data = input_data
|
672
|
-
data_type = "BytesIO"
|
673
|
-
else:
|
674
|
-
raise TypeError
|
675
|
-
|
676
|
-
sys_path = sys.path.copy()
|
677
|
-
try:
|
678
|
-
if self.version.split(".")[0] not in ["0", "1"]:
|
679
|
-
sys.path.insert(0, self.artifact_dir)
|
680
|
-
else:
|
681
|
-
sys.path.insert(0, os.path.join(self.artifact_dir, "fn-model"))
|
682
|
-
import func
|
683
|
-
|
684
|
-
resp = func.handler(ctx, data)
|
685
|
-
output_json = resp.body()
|
686
|
-
finally:
|
687
|
-
# Reset in case func.py messes with it
|
688
|
-
sys.path = sys_path
|
689
|
-
|
690
|
-
if data_type == "json":
|
691
|
-
return output_json
|
692
|
-
output_bstream = BytesIO(resp.body().encode("UTF-8"))
|
693
|
-
if data_type == "BytesIO":
|
694
|
-
return output_bstream
|
695
|
-
else:
|
696
|
-
from json import load
|
697
|
-
|
698
|
-
return load(output_bstream)
|
699
|
-
|
700
|
-
@deprecated(
|
701
|
-
"2.6.6",
|
702
|
-
details="Use framework specific Model utility class for saving and deploying model. Check https://accelerated-data-science.readthedocs.io/en/latest/user_guide/model_registration/quick_start.html",
|
703
|
-
)
|
704
|
-
def save(
|
705
|
-
self,
|
706
|
-
display_name: str = None,
|
707
|
-
description: str = None,
|
708
|
-
project_id: str = None,
|
709
|
-
compartment_id: str = None,
|
710
|
-
training_script_path: str = None,
|
711
|
-
ignore_pending_changes: bool = False,
|
712
|
-
auth: dict = None,
|
713
|
-
training_id: str = None,
|
714
|
-
timeout: int = None,
|
715
|
-
ignore_introspection=True,
|
716
|
-
freeform_tags=None,
|
717
|
-
defined_tags=None,
|
718
|
-
bucket_uri: Optional[str] = None,
|
719
|
-
remove_existing_artifact: Optional[bool] = True,
|
720
|
-
model_version_set: Optional[Union[str, ModelVersionSet]] = None,
|
721
|
-
version_label: Optional[str] = None,
|
722
|
-
):
|
723
|
-
"""
|
724
|
-
Saves the model artifact in the model catalog.
|
725
|
-
|
726
|
-
Parameters
|
727
|
-
----------
|
728
|
-
display_name : str, optional
|
729
|
-
Model display name.
|
730
|
-
description : str, optional
|
731
|
-
Description for the model.
|
732
|
-
project_id : str, optional
|
733
|
-
Model's project OCID.
|
734
|
-
If None, the default project OCID `config.PROJECT_OCID` would be used.
|
735
|
-
compartment_id : str, optional
|
736
|
-
Model's compartment OCID.
|
737
|
-
If None, the default compartment OCID `config.NB_SESSION_COMPARTMENT_OCID` would be used.
|
738
|
-
training_script_path : str, optional
|
739
|
-
The training script path is either relative to the working directory,
|
740
|
-
or an absolute path.
|
741
|
-
ignore_pending_changes : bool, default: False
|
742
|
-
If True, ignore uncommitted changes and use the current git HEAD commit for provenance metadata.
|
743
|
-
This argument is used only when the function is called from a script in git managed directory.
|
744
|
-
auth: dict
|
745
|
-
Default is None. Default authetication is set using the `ads.set_auth()` method.
|
746
|
-
Use the `ads.common.auth.api_keys()` or `ads.common.auth.resource_principal()` to create appropriate
|
747
|
-
authentication signer and kwargs required to instantiate a DataScienceClient object.
|
748
|
-
training_id: str, optional
|
749
|
-
The training OCID for the model.
|
750
|
-
timeout: int, default: 10
|
751
|
-
The connection timeout in seconds.
|
752
|
-
ignore_introspection: bool, optional
|
753
|
-
Ignore the result of model introspection .
|
754
|
-
If set to True, the `.save()` will ignore all model introspection errors.
|
755
|
-
freeform_tags : dict(str, str), optional
|
756
|
-
Freeform tags for the model.
|
757
|
-
defined_tags : dict(str, dict(str, object)), optional
|
758
|
-
Defined tags for the model.
|
759
|
-
bucket_uri: (str, optional). Defaults to None.
|
760
|
-
The OCI Object Storage URI where model artifacts will be copied to.
|
761
|
-
The `bucket_uri` is only necessary for uploading large artifacts which
|
762
|
-
size is greater than 2GB. Example: `oci://<bucket_name>@<namespace>/prefix/`
|
763
|
-
remove_existing_artifact: (bool, optional). Defaults to `True`.
|
764
|
-
Whether artifacts uploaded to object storage bucket need to be removed or not.
|
765
|
-
model_version_set: (Union[str, ModelVersionSet], optional). Defaults to None.
|
766
|
-
The Model version set OCID, or name, or `ModelVersionSet` instance.
|
767
|
-
version_label: (str, optional). Defaults to None.
|
768
|
-
The model version label.
|
769
|
-
|
770
|
-
Examples
|
771
|
-
________
|
772
|
-
>>> from ads.common.model_artifact import ModelArtifact
|
773
|
-
>>> from ads.config import NB_SESSION_OCID
|
774
|
-
|
775
|
-
>>> # Getting auth details.
|
776
|
-
>>> # If you are using API keys
|
777
|
-
>>> auth=ads.common.auth.api_keys()
|
778
|
-
|
779
|
-
>>> # If you are using resource principal
|
780
|
-
>>> auth=ads.common.auth.resource_principal()
|
781
|
-
|
782
|
-
>>> # If you have set the auth type using ads.set_auth()
|
783
|
-
>>> auth=ads.common.auth.default_signer()
|
784
|
-
|
785
|
-
>>> # Preparing model artifacts
|
786
|
-
>>> model_artifact = prepare_generic_model(
|
787
|
-
... "path_to_model_artifacts",
|
788
|
-
... force_overwrite=True,
|
789
|
-
... data_science_env=True,
|
790
|
-
... model=gamma_reg_model,
|
791
|
-
... )
|
792
|
-
|
793
|
-
>>> # Saving model to the model catalog
|
794
|
-
>>> model_artifact.save(
|
795
|
-
... project_id=PROJECT_ID,
|
796
|
-
... compartment_id=COMPARTMENT,
|
797
|
-
... display_name="RF Classifier 2",
|
798
|
-
... description="A sample Random Forest classifier",
|
799
|
-
... ignore_pending_changes=True,
|
800
|
-
... auth=auth,
|
801
|
-
... training_id=NB_SESSION_OCID,
|
802
|
-
... timeout=6000,
|
803
|
-
... ignore_introspection = True
|
804
|
-
... )
|
805
|
-
"""
|
806
|
-
if timeout and not isinstance(timeout, int):
|
807
|
-
raise TypeError("Timeout must be an integer.")
|
808
|
-
|
809
|
-
runtime_yaml_file = os.path.join(self.artifact_dir, "runtime.yaml")
|
810
|
-
if os.path.exists(runtime_yaml_file):
|
811
|
-
with open(runtime_yaml_file, "r") as mfile:
|
812
|
-
runtime_prep_info = yaml.load(mfile, Loader=yaml.FullLoader)
|
813
|
-
# runtime_info['pack-info'] = deployment_pack_info
|
814
|
-
else:
|
815
|
-
runtime_prep_info = {}
|
816
|
-
ns = self.__fetch_runtime_schema__()
|
817
|
-
runtime_info = ns.ModelArtifactSchema().from_json(json.dumps(runtime_prep_info))
|
818
|
-
|
819
|
-
training_code_info = self._training_code_info(
|
820
|
-
ns, training_script_path, ignore_pending_changes
|
821
|
-
)
|
822
|
-
if not training_id:
|
823
|
-
training_id = _TRAINING_RESOURCE_OCID
|
824
|
-
model_provenance_metadata = ModelProvenance(
|
825
|
-
repository_url=str(training_code_info.GIT_REMOTE),
|
826
|
-
git_branch=str(training_code_info.GIT_BRANCH),
|
827
|
-
git_commit=str(training_code_info.GIT_COMMIT),
|
828
|
-
script_dir=str(training_code_info.ARTIFACT_DIRECTORY),
|
829
|
-
training_script=str(training_code_info.TRAINING_SCRIPT),
|
830
|
-
training_id=training_id,
|
831
|
-
)
|
832
|
-
if getattr(runtime_info, "MODEL_PROVENANCE", None):
|
833
|
-
runtime_info.MODEL_PROVENANCE.TRAINING_CODE = training_code_info
|
834
|
-
|
835
|
-
logger.info(model_provenance_metadata)
|
836
|
-
|
837
|
-
# handle the case where project_id and/or compartment_id is not specified by the user
|
838
|
-
if not project_id and not PROJECT_OCID:
|
839
|
-
raise ValueError("The `project_id` must be provided.")
|
840
|
-
|
841
|
-
if not compartment_id and not NB_SESSION_COMPARTMENT_OCID:
|
842
|
-
raise ValueError("The `compartment_id` must be provided.")
|
843
|
-
|
844
|
-
if os.path.exists(os.path.join(self.artifact_dir, "__pycache__")):
|
845
|
-
shutil.rmtree(
|
846
|
-
os.path.join(self.artifact_dir, "__pycache__"), ignore_errors=True
|
847
|
-
)
|
848
|
-
self.metadata_custom._add(
|
849
|
-
ModelCustomMetadataItem(
|
850
|
-
key=MetadataCustomKeys.MODEL_ARTIFACTS,
|
851
|
-
value=textwrap.shorten(
|
852
|
-
", ".join(self._get_files()), 255, placeholder="..."
|
853
|
-
),
|
854
|
-
description="The list of files located in artifacts folder.",
|
855
|
-
category=MetadataCustomCategory.TRAINING_ENV,
|
856
|
-
),
|
857
|
-
replace=True,
|
858
|
-
)
|
859
|
-
|
860
|
-
client_auth = auth if auth else authutil.default_signer()
|
861
|
-
|
862
|
-
if timeout:
|
863
|
-
if not client_auth.get("client_kwargs"):
|
864
|
-
client_auth["client_kwargs"] = {}
|
865
|
-
client_auth["client_kwargs"]["timeout"] = timeout
|
866
|
-
|
867
|
-
if freeform_tags and not isinstance(freeform_tags, dict):
|
868
|
-
raise TypeError("Freeform tags must be a dictionary.")
|
869
|
-
|
870
|
-
if defined_tags and not isinstance(defined_tags, dict):
|
871
|
-
raise TypeError("Defined tags must be a dictionary.")
|
872
|
-
|
873
|
-
self._validate_metadata()
|
874
|
-
self._validate_schema()
|
875
|
-
|
876
|
-
with open(runtime_yaml_file, "w") as mfile:
|
877
|
-
yaml.dump(runtime_info.as_dict(), mfile, Dumper=dumper)
|
878
|
-
|
879
|
-
if not ignore_introspection:
|
880
|
-
self._introspect()
|
881
|
-
if self._introspect.status == TEST_STATUS.NOT_PASSED:
|
882
|
-
msg = (
|
883
|
-
"Model introspection not passed. "
|
884
|
-
"Use `.introspect()` method to get detailed information and follow the "
|
885
|
-
"messages to fix it. To save model artifacts ignoring introspection "
|
886
|
-
"use `.save(ignore_introspection=True...)`."
|
887
|
-
)
|
888
|
-
raise IntrospectionNotPassed(msg)
|
889
|
-
try:
|
890
|
-
from ads.catalog.model import ModelCatalog
|
891
|
-
|
892
|
-
return ModelCatalog(
|
893
|
-
compartment_id=compartment_id,
|
894
|
-
ds_client_auth=client_auth,
|
895
|
-
identity_client_auth=client_auth,
|
896
|
-
).upload_model(
|
897
|
-
self,
|
898
|
-
provenance_metadata=model_provenance_metadata,
|
899
|
-
display_name=display_name,
|
900
|
-
description=description,
|
901
|
-
project_id=project_id,
|
902
|
-
freeform_tags=freeform_tags,
|
903
|
-
defined_tags=defined_tags,
|
904
|
-
bucket_uri=bucket_uri,
|
905
|
-
remove_existing_artifact=remove_existing_artifact,
|
906
|
-
model_version_set=model_version_set,
|
907
|
-
version_label=version_label,
|
908
|
-
)
|
909
|
-
except oci.exceptions.RequestException as e:
|
910
|
-
if "The write operation timed out" in str(e):
|
911
|
-
logger.error(
|
912
|
-
"The save operation timed out. Try to set a longer timeout e.g. save(timeout=600, ...)."
|
913
|
-
)
|
914
|
-
|
915
|
-
def _validate_schema(self):
|
916
|
-
if not self._validate_schema_size(self.schema_input, INPUT_SCHEMA_FILE_NAME):
|
917
|
-
self.schema_input.to_json_file(
|
918
|
-
os.path.join(self.artifact_dir, INPUT_SCHEMA_FILE_NAME)
|
919
|
-
)
|
920
|
-
if not self._validate_schema_size(self.schema_output, OUTPUT_SCHEMA_FILE_NAME):
|
921
|
-
self.schema_output.to_json_file(
|
922
|
-
os.path.join(self.artifact_dir, OUTPUT_SCHEMA_FILE_NAME)
|
923
|
-
)
|
924
|
-
self.schema_input.validate_schema()
|
925
|
-
self.schema_output.validate_schema()
|
926
|
-
|
927
|
-
def _validate_metadata(self):
|
928
|
-
self.metadata_custom.validate()
|
929
|
-
self.metadata_taxonomy.validate()
|
930
|
-
total_size = self.metadata_custom.size() + self.metadata_taxonomy.size()
|
931
|
-
if total_size > METADATA_SIZE_LIMIT:
|
932
|
-
raise MetadataSizeTooLarge(total_size)
|
933
|
-
return True
|
934
|
-
|
935
|
-
def _training_code_info(
|
936
|
-
self, ns, training_script_path=None, ignore_pending_changes=False
|
937
|
-
):
|
938
|
-
try:
|
939
|
-
repo, training_code_info = self.__fetch_repo_details(ns.TrainingCodeInfo())
|
940
|
-
except git.InvalidGitRepositoryError:
|
941
|
-
repo = None
|
942
|
-
training_code_info = ns.TrainingCodeInfo()
|
943
|
-
if training_script_path is not None:
|
944
|
-
if not os.path.exists(training_script_path):
|
945
|
-
logger.warning(
|
946
|
-
f"Training script {os.path.abspath(training_script_path)} does not exists."
|
947
|
-
)
|
948
|
-
else:
|
949
|
-
training_script = os.path.abspath(training_script_path)
|
950
|
-
self._assert_path_not_dirty(
|
951
|
-
training_script_path, repo, ignore_pending_changes
|
952
|
-
)
|
953
|
-
training_code_info.TRAINING_SCRIPT = training_script
|
954
|
-
|
955
|
-
self._assert_path_not_dirty(self.artifact_dir, repo, ignore_pending_changes)
|
956
|
-
training_code_info.ARTIFACT_DIRECTORY = os.path.abspath(self.artifact_dir)
|
957
|
-
|
958
|
-
return training_code_info
|
959
|
-
|
960
|
-
def _assert_path_not_dirty(self, path, repo, ignore):
|
961
|
-
if repo is not None and not ignore:
|
962
|
-
path_abs = os.path.abspath(path)
|
963
|
-
if os.path.commonpath([path_abs, repo.working_dir]) == repo.working_dir:
|
964
|
-
path_relpath = os.path.relpath(path_abs, repo.working_dir)
|
965
|
-
if repo.is_dirty(path=path_relpath) or any(
|
966
|
-
[
|
967
|
-
os.path.commonpath([path_relpath, untracked]) == path_relpath
|
968
|
-
for untracked in repo.untracked_files
|
969
|
-
]
|
970
|
-
):
|
971
|
-
raise ChangesNotCommitted(path_abs)
|
972
|
-
|
973
|
-
def install_requirements(self, conflict_strategy=ConflictStrategy.IGNORE):
|
974
|
-
"""
|
975
|
-
Installs missing libraries listed in the model artifacts.
|
976
|
-
|
977
|
-
Parameters
|
978
|
-
----------
|
979
|
-
conflict_strategy : ConflictStrategy, default: IGNORE
|
980
|
-
Update the conflicting dependency to the version required by the model artifact.
|
981
|
-
Valid values: "IGNORE" or ConflictStrategy.IGNORE, "UPDATE" or ConflictStrategy.UPDATE.
|
982
|
-
IGNORE: Use the installed version in case of a conflict.
|
983
|
-
UPDATE: Force update dependency to the version required by model artifact in case of conflict.
|
984
|
-
"""
|
985
|
-
importlib.reload(pkg_resources)
|
986
|
-
from pkg_resources import DistributionNotFound, VersionConflict
|
987
|
-
|
988
|
-
if self.version.split(".")[0] not in ["0", "1"] and os.path.exists(
|
989
|
-
Path(os.path.join(self.artifact_dir), "requirements.txt")
|
990
|
-
):
|
991
|
-
requirements = (
|
992
|
-
Path(os.path.join(self.artifact_dir), "requirements.txt")
|
993
|
-
.read_text()
|
994
|
-
.strip()
|
995
|
-
.split("\n")
|
996
|
-
)
|
997
|
-
elif self.version.split(".")[0] in ["0", "1"] and Path(
|
998
|
-
os.path.join(self.artifact_dir), "ds-requirements.txt"
|
999
|
-
):
|
1000
|
-
requirements = (
|
1001
|
-
Path(os.path.join(self.artifact_dir), "ds-requirements.txt")
|
1002
|
-
.read_text()
|
1003
|
-
.strip()
|
1004
|
-
.split("\n")
|
1005
|
-
)
|
1006
|
-
else:
|
1007
|
-
raise FileNotFoundError(
|
1008
|
-
"Could not find requirements.txt. Install the necessary libraries and "
|
1009
|
-
"re-construct the model artifact with install_libs=False."
|
1010
|
-
)
|
1011
|
-
|
1012
|
-
version_conflicts = {}
|
1013
|
-
for requirement in requirements:
|
1014
|
-
try:
|
1015
|
-
pkg_resources.require(requirement)
|
1016
|
-
except VersionConflict as vc:
|
1017
|
-
if conflict_strategy == ConflictStrategy.UPDATE:
|
1018
|
-
pip_install("%s%s" % (vc.req.name, vc.req.specifier), "-U")
|
1019
|
-
elif conflict_strategy == ConflictStrategy.IGNORE:
|
1020
|
-
version_conflicts[
|
1021
|
-
"%s==%s" % (vc.dist.key, vc.dist.parsed_version)
|
1022
|
-
] = "%s%s" % (vc.req.name, vc.req.specifier)
|
1023
|
-
except DistributionNotFound as dnf:
|
1024
|
-
pip_install(requirement)
|
1025
|
-
# distributions_not_found.add('%s%s' % (dnf.req.name, dnf.req.specifier))
|
1026
|
-
if len(version_conflicts) > 0:
|
1027
|
-
print(
|
1028
|
-
"\033[93m"
|
1029
|
-
+ str(VersionConflictWarning(version_conflicts=version_conflicts))
|
1030
|
-
+ "\033[0m"
|
1031
|
-
)
|
1032
|
-
|
1033
|
-
def _get_files(self):
|
1034
|
-
if os.path.exists(os.path.join(self.artifact_dir, ".model-ignore")):
|
1035
|
-
ignore_patterns = (
|
1036
|
-
Path(os.path.join(self.artifact_dir), ".model-ignore")
|
1037
|
-
.read_text()
|
1038
|
-
.strip()
|
1039
|
-
.split("\n")
|
1040
|
-
)
|
1041
|
-
else:
|
1042
|
-
ignore_patterns = []
|
1043
|
-
file_names = []
|
1044
|
-
for root, dirs, files in os.walk(self.artifact_dir):
|
1045
|
-
for name in files:
|
1046
|
-
file_names.append(os.path.join(root, name))
|
1047
|
-
for name in dirs:
|
1048
|
-
file_names.append(os.path.join(root, name))
|
1049
|
-
|
1050
|
-
for ignore in ignore_patterns:
|
1051
|
-
if not ignore.startswith("#") and ignore.strip() != "":
|
1052
|
-
matches = []
|
1053
|
-
for file_name in file_names:
|
1054
|
-
if ignore.endswith("/"):
|
1055
|
-
ignore = ignore[:-1] + "*"
|
1056
|
-
if not re.search(
|
1057
|
-
fnmatch.translate("/%s" % ignore.strip()), file_name
|
1058
|
-
):
|
1059
|
-
matches.append(file_name)
|
1060
|
-
file_names = matches
|
1061
|
-
return [
|
1062
|
-
matched_file[len(self.artifact_dir) + 1 :] for matched_file in file_names
|
1063
|
-
]
|
1064
|
-
|
1065
|
-
def _save_data_from_memory(
|
1066
|
-
self,
|
1067
|
-
prefix: str,
|
1068
|
-
train_data: Union[pd.DataFrame, list, np.ndarray],
|
1069
|
-
validation_data: Union[pd.DataFrame, list, np.ndarray] = None,
|
1070
|
-
train_data_name: str = "train.csv",
|
1071
|
-
validation_data_name: str = "validation.csv",
|
1072
|
-
storage_options: dict = None,
|
1073
|
-
**kwargs,
|
1074
|
-
):
|
1075
|
-
"""
|
1076
|
-
Save data to Object Storage.
|
1077
|
-
return [
|
1078
|
-
matched_file[len(self.artifact_dir) + 1 :] for matched_file in file_names
|
1079
|
-
]
|
1080
|
-
|
1081
|
-
Parameters
|
1082
|
-
----------
|
1083
|
-
prefix: str
|
1084
|
-
A prefix to append to the Object Storage key.
|
1085
|
-
e.g. oci://bucket_name@namespace/prefix
|
1086
|
-
train_data: Union[pd.DataFrame, list, np.ndarray].
|
1087
|
-
The training data to be stored.
|
1088
|
-
validation_data: Union[pd.DataFrame, list, np.ndarray]. Default None
|
1089
|
-
The validation data to be stored.
|
1090
|
-
train_data_name: str. Default 'train.csv'.
|
1091
|
-
Filename used to save the train data. The key is prefix/train_data_name.
|
1092
|
-
validation_data_name: str. Default 'train.csv'.
|
1093
|
-
Filename used to save the validation data. The key is prefix/validation_data_name.
|
1094
|
-
storage_options: dict. Default None
|
1095
|
-
Parameters passed on to the backend filesystem class.
|
1096
|
-
Defaults to `storage_options` set using `DatasetFactory.set_default_storage()`.
|
1097
|
-
|
1098
|
-
Returns
|
1099
|
-
-------
|
1100
|
-
None
|
1101
|
-
Nothing.
|
1102
|
-
Examples
|
1103
|
-
________
|
1104
|
-
>>> from ads.common.model_artifact import ModelArtifact
|
1105
|
-
>>> import ocifs
|
1106
|
-
>>> import oci
|
1107
|
-
>>> storage_options = {"config": oci.config.from_file(os.path.join("~/.oci", "config"))}
|
1108
|
-
>>> storage_options
|
1109
|
-
{'log_requests': False,
|
1110
|
-
'additional_user_agent': '',
|
1111
|
-
'pass_phrase': None,
|
1112
|
-
'user': 'ocid5.user.oc1..aaaaaaaab3geixlk***********************',
|
1113
|
-
'fingerprint': '05:15:2b:b1:46:8a:32:ec:e2:69:5b:32:01:**:**:**)',
|
1114
|
-
'tenancy': 'ocid5.tenancy.oc1..aaaaaaaag*************************',
|
1115
|
-
'region': 'us-ashburn-1',
|
1116
|
-
'key_file': '/home/datascience/.oci/oci_api_key.pem'}
|
1117
|
-
>>> path_to_generic_model_artifact = tempfile.mkdtemp()
|
1118
|
-
>>> df = pd.DataFrame([[1, 2], [2, 3], [3, 4], [4, 3]])
|
1119
|
-
>>> generic_model_artifact = prepare_generic_model(path_to_generic_model_artifact,
|
1120
|
-
... force_overwrite=True, data_science_env=True,
|
1121
|
-
... ignore_deployment_error=True)
|
1122
|
-
>>> generic_model_artifact._save_data_from_memory(prefix = 'oci://bucket_name@namespace/folder_name',
|
1123
|
-
... train_data=df, storage_options=storage_options)
|
1124
|
-
"""
|
1125
|
-
if not re.match(r"oci://*@*", prefix):
|
1126
|
-
raise InvalidObjectStoragePath(
|
1127
|
-
"`prefix` is not valid. It must have the pattern 'oci://bucket_name@namespace/key'."
|
1128
|
-
)
|
1129
|
-
if not storage_options:
|
1130
|
-
storage_options = factory.default_storage_options
|
1131
|
-
if not storage_options:
|
1132
|
-
storage_options = {"config": {}}
|
1133
|
-
|
1134
|
-
self._save_from_memory(
|
1135
|
-
train_data, prefix, train_data_name, storage_options, "training", **kwargs
|
1136
|
-
)
|
1137
|
-
|
1138
|
-
if validation_data is not None:
|
1139
|
-
self._save_from_memory(
|
1140
|
-
validation_data,
|
1141
|
-
prefix,
|
1142
|
-
validation_data_name,
|
1143
|
-
storage_options,
|
1144
|
-
"validation",
|
1145
|
-
**kwargs,
|
1146
|
-
)
|
1147
|
-
|
1148
|
-
def _save_data_from_file(
|
1149
|
-
self,
|
1150
|
-
prefix: str,
|
1151
|
-
train_data_path: str = None,
|
1152
|
-
validation_data_path: str = None,
|
1153
|
-
storage_options: dict = None,
|
1154
|
-
**kwargs,
|
1155
|
-
):
|
1156
|
-
"""
|
1157
|
-
Save the data to Object Storage.
|
1158
|
-
|
1159
|
-
Parameters
|
1160
|
-
----------
|
1161
|
-
prefix: str
|
1162
|
-
The Object Storage prefix to store the data. When `train_data_path` or
|
1163
|
-
`validation_data_path` are provided, they are stored under this prefix
|
1164
|
-
with their original filenames. If the data are already stored on Object
|
1165
|
-
Storage, you can provide the path to the data. If no local data path is provided,
|
1166
|
-
no data is `prefix` is saved in the custom metadata.
|
1167
|
-
train_data_path: str. Default None.
|
1168
|
-
Local path for the training data.
|
1169
|
-
validation_data_path: str. Default None.
|
1170
|
-
Local path for the validation data.
|
1171
|
-
storage_options: dict. Default None
|
1172
|
-
Parameters passed on to the backend filesystem class.
|
1173
|
-
Defaults to `storage_options` set using `DatasetFactory.set_default_storage()`.
|
1174
|
-
|
1175
|
-
Keyword Arguments
|
1176
|
-
_________________
|
1177
|
-
data_type:
|
1178
|
-
Either `training` or `validation`. Used when the data are
|
1179
|
-
already stored remotely and you want to record the path in
|
1180
|
-
`metadata_custom`. Pass the prefix of your data and `data_type`
|
1181
|
-
to indicate whether this data is of `training` or `validation` type.
|
1182
|
-
The `storage_options` is needed in this case.
|
1183
|
-
|
1184
|
-
Returns
|
1185
|
-
-------
|
1186
|
-
None
|
1187
|
-
Nothing.
|
1188
|
-
|
1189
|
-
Examples
|
1190
|
-
________
|
1191
|
-
>>> from ads.common.model_artifact import ModelArtifact
|
1192
|
-
>>> import ocifs
|
1193
|
-
>>> import oci
|
1194
|
-
>>> storage_options = {"config": oci.config.from_file(os.path.join("~/.oci", "config"))}
|
1195
|
-
>>> storage_options
|
1196
|
-
{'log_requests': False,
|
1197
|
-
'additional_user_agent': '',
|
1198
|
-
'pass_phrase': None,
|
1199
|
-
'user': 'ocid5.user.oc1..aaaaaaaab3geixlk***********************',
|
1200
|
-
'fingerprint': '05:15:2b:b1:46:8a:32:ec:e2:69:5b:32:01:**:**:**)',
|
1201
|
-
'tenancy': 'ocid5.tenancy.oc1..aaaaaaaag*************************',
|
1202
|
-
'region': 'us-ashburn-1',
|
1203
|
-
'key_file': '/home/datascience/.oci/oci_api_key.pem'}
|
1204
|
-
>>> path_to_generic_model_artifact = tempfile.mkdtemp()
|
1205
|
-
>>> generic_model_artifact = prepare_generic_model(path_to_generic_model_artifact,
|
1206
|
-
... force_overwrite=True, data_science_env=True,
|
1207
|
-
... ignore_deployment_error=True)
|
1208
|
-
>>> generic_model_artifact._save_data_from_file(oci_storage_path = 'oci://bucket_name@namespace/folder_name',
|
1209
|
-
... train_data_path = '~/orcl_attrition*.csv', storage_options=storage_options)
|
1210
|
-
"""
|
1211
|
-
if not re.match(r"oci://*@*", prefix):
|
1212
|
-
raise InvalidObjectStoragePath(
|
1213
|
-
"`prefix` is not valid. It must have the pattern 'oci://bucket_name@namespace/key'."
|
1214
|
-
)
|
1215
|
-
if not storage_options:
|
1216
|
-
storage_options = factory.default_storage_options
|
1217
|
-
if not storage_options:
|
1218
|
-
storage_options = {"config": {}}
|
1219
|
-
|
1220
|
-
if train_data_path is not None:
|
1221
|
-
assert isinstance(train_data_path, str), "A path to the data is required."
|
1222
|
-
self._save_from_local_file(
|
1223
|
-
prefix=prefix,
|
1224
|
-
file_path=train_data_path,
|
1225
|
-
storage_options=storage_options,
|
1226
|
-
data_type="training",
|
1227
|
-
)
|
1228
|
-
if validation_data_path is not None:
|
1229
|
-
assert isinstance(
|
1230
|
-
validation_data_path, str
|
1231
|
-
), "A path to the data is required."
|
1232
|
-
self._save_from_local_file(
|
1233
|
-
prefix=prefix,
|
1234
|
-
file_path=validation_data_path,
|
1235
|
-
storage_options=storage_options,
|
1236
|
-
data_type="validation",
|
1237
|
-
)
|
1238
|
-
if train_data_path is None and validation_data_path is None:
|
1239
|
-
data_type = kwargs.get("data_type", "training")
|
1240
|
-
if data_type not in ("training", "validation"):
|
1241
|
-
InvalidDataType(
|
1242
|
-
"`data_type` is not supported. Choose 'training' or 'validation'."
|
1243
|
-
)
|
1244
|
-
self._save_data_path(prefix, data_type=data_type)
|
1245
|
-
|
1246
|
-
def _populate_metadata_taxonomy(self, model=None, use_case_type=None):
|
1247
|
-
"""Extract and populate the taxonomy metadata from the model.
|
1248
|
-
|
1249
|
-
Parameters
|
1250
|
-
----------
|
1251
|
-
model: [sklearn, xgboost, lightgbm, automl, keras]
|
1252
|
-
The model object.
|
1253
|
-
use_case_type: str
|
1254
|
-
The use case type of the model.
|
1255
|
-
|
1256
|
-
Returns
|
1257
|
-
-------
|
1258
|
-
None
|
1259
|
-
Nothing.
|
1260
|
-
|
1261
|
-
Raises
|
1262
|
-
------
|
1263
|
-
ValueError: When model not provided.
|
1264
|
-
"""
|
1265
|
-
if use_case_type and use_case_type not in UseCaseType:
|
1266
|
-
raise ValueError(
|
1267
|
-
f"Invalid value of `UseCaseType`. Choose from {UseCaseType.values()}."
|
1268
|
-
)
|
1269
|
-
|
1270
|
-
self.metadata_taxonomy[MetadataTaxonomyKeys.USE_CASE_TYPE].value = use_case_type
|
1271
|
-
if model is not None:
|
1272
|
-
map = ModelInfoExtractorFactory.extract_info(model)
|
1273
|
-
if map is not None:
|
1274
|
-
self.metadata_taxonomy._populate_from_map(map)
|
1275
|
-
if (
|
1276
|
-
self.metadata_taxonomy[MetadataTaxonomyKeys.HYPERPARAMETERS].size()
|
1277
|
-
> METADATA_SIZE_LIMIT
|
1278
|
-
):
|
1279
|
-
logger.warn(
|
1280
|
-
f"The model hyperparameters are larger than `{METADATA_SIZE_LIMIT}` "
|
1281
|
-
"bytes and cannot be stored as model catalog metadata. It will be saved to "
|
1282
|
-
f"{self.artifact_dir}/hyperparameters.json and removed from the metadata."
|
1283
|
-
)
|
1284
|
-
|
1285
|
-
self.metadata_taxonomy[
|
1286
|
-
MetadataTaxonomyKeys.HYPERPARAMETERS
|
1287
|
-
].to_json_file(self.artifact_dir)
|
1288
|
-
self.metadata_taxonomy[MetadataTaxonomyKeys.HYPERPARAMETERS].update(
|
1289
|
-
value=None
|
1290
|
-
)
|
1291
|
-
|
1292
|
-
def _populate_metadata_custom(self):
|
1293
|
-
"""Extracts custom metadata from the model artifact.
|
1294
|
-
|
1295
|
-
Returns
|
1296
|
-
-------
|
1297
|
-
None
|
1298
|
-
Nothing
|
1299
|
-
"""
|
1300
|
-
model_metadata_items = []
|
1301
|
-
|
1302
|
-
model_metadata_items.append(
|
1303
|
-
ModelCustomMetadataItem(
|
1304
|
-
key=MetadataCustomKeys.CONDA_ENVIRONMENT,
|
1305
|
-
value=self.conda_env if hasattr(self, "conda_env") else None,
|
1306
|
-
description="The conda environment where the model was trained.",
|
1307
|
-
category=MetadataCustomCategory.TRAINING_ENV,
|
1308
|
-
)
|
1309
|
-
)
|
1310
|
-
try:
|
1311
|
-
env_type = (
|
1312
|
-
self._runtime_info.MODEL_DEPLOYMENT.INFERENCE_CONDA_ENV.INFERENCE_ENV_TYPE._value
|
1313
|
-
)
|
1314
|
-
except:
|
1315
|
-
env_type = None
|
1316
|
-
try:
|
1317
|
-
slug_name = (
|
1318
|
-
self._runtime_info.MODEL_DEPLOYMENT.INFERENCE_CONDA_ENV.INFERENCE_ENV_SLUG._value
|
1319
|
-
)
|
1320
|
-
except:
|
1321
|
-
slug_name = None
|
1322
|
-
try:
|
1323
|
-
env_path = (
|
1324
|
-
self._runtime_info.MODEL_DEPLOYMENT.INFERENCE_CONDA_ENV.INFERENCE_ENV_PATH._value
|
1325
|
-
)
|
1326
|
-
except:
|
1327
|
-
env_path = None
|
1328
|
-
|
1329
|
-
model_metadata_items.append(
|
1330
|
-
ModelCustomMetadataItem(
|
1331
|
-
key=MetadataCustomKeys.ENVIRONMENT_TYPE,
|
1332
|
-
value=env_type,
|
1333
|
-
description="The environment type, must be a 'published' or 'data_science'.",
|
1334
|
-
category=MetadataCustomCategory.TRAINING_ENV,
|
1335
|
-
)
|
1336
|
-
)
|
1337
|
-
model_metadata_items.append(
|
1338
|
-
ModelCustomMetadataItem(
|
1339
|
-
key=MetadataCustomKeys.SLUG_NAME,
|
1340
|
-
value=slug_name,
|
1341
|
-
description="The slug name of the training conda environment.",
|
1342
|
-
category=MetadataCustomCategory.TRAINING_ENV,
|
1343
|
-
)
|
1344
|
-
)
|
1345
|
-
model_metadata_items.append(
|
1346
|
-
ModelCustomMetadataItem(
|
1347
|
-
key=MetadataCustomKeys.CONDA_ENVIRONMENT_PATH,
|
1348
|
-
value=env_path,
|
1349
|
-
description="The oci path of the training conda environment.",
|
1350
|
-
category=MetadataCustomCategory.TRAINING_ENV,
|
1351
|
-
)
|
1352
|
-
)
|
1353
|
-
model_metadata_items.append(
|
1354
|
-
ModelCustomMetadataItem(
|
1355
|
-
key=MetadataCustomKeys.MODEL_ARTIFACTS,
|
1356
|
-
value=textwrap.shorten(
|
1357
|
-
", ".join(self._get_files()), 255, placeholder="..."
|
1358
|
-
),
|
1359
|
-
description="A list of files located in the model artifacts folder.",
|
1360
|
-
category=MetadataCustomCategory.TRAINING_ENV,
|
1361
|
-
)
|
1362
|
-
)
|
1363
|
-
model_metadata_items.append(
|
1364
|
-
ModelCustomMetadataItem(
|
1365
|
-
key=MetadataCustomKeys.MODEL_SERIALIZATION_FORMAT,
|
1366
|
-
value=self._serialization_format,
|
1367
|
-
description="The model serialization format.",
|
1368
|
-
category=MetadataCustomCategory.TRAINING_PROFILE,
|
1369
|
-
)
|
1370
|
-
)
|
1371
|
-
model_metadata_items.append(
|
1372
|
-
ModelCustomMetadataItem(
|
1373
|
-
key=MetadataCustomKeys.CLIENT_LIBRARY,
|
1374
|
-
value="ADS",
|
1375
|
-
description="",
|
1376
|
-
category=MetadataCustomCategory.OTHER,
|
1377
|
-
)
|
1378
|
-
)
|
1379
|
-
self.metadata_custom._add_many(model_metadata_items, replace=True)
|
1380
|
-
|
1381
|
-
def populate_metadata(self, model=None, use_case_type=None):
|
1382
|
-
"""Extracts and populate taxonomy metadata from given model.
|
1383
|
-
|
1384
|
-
Parameters
|
1385
|
-
----------
|
1386
|
-
model: [sklearn, xgboost, lightgbm, automl, keras]
|
1387
|
-
The model object.
|
1388
|
-
|
1389
|
-
use_case_type:
|
1390
|
-
The use case type of the model.
|
1391
|
-
model: (Any, optional). Defaults to None.
|
1392
|
-
This is an optional model object which is only used to extract taxonomy metadata.
|
1393
|
-
Supported models: keras, lightgbm, pytorch, sklearn, tensorflow, and xgboost.
|
1394
|
-
If the model is not under supported frameworks, then extracting taxonomy metadata will be skipped.
|
1395
|
-
use_case_type: (str, optional). Default to None.
|
1396
|
-
The use case type of the model.
|
1397
|
-
|
1398
|
-
Returns
|
1399
|
-
-------
|
1400
|
-
None
|
1401
|
-
Nothing.
|
1402
|
-
"""
|
1403
|
-
if model is None and self.metadata_taxonomy["Algorithm"].value is None:
|
1404
|
-
logger.info(
|
1405
|
-
"To auto-extract taxonomy metadata the model must be provided. Supported models: automl, keras, lightgbm, pytorch, sklearn, tensorflow, and xgboost."
|
1406
|
-
)
|
1407
|
-
if use_case_type is None:
|
1408
|
-
use_case_type = self.metadata_taxonomy[
|
1409
|
-
MetadataTaxonomyKeys.USE_CASE_TYPE
|
1410
|
-
].value
|
1411
|
-
self._populate_metadata_taxonomy(model, use_case_type)
|
1412
|
-
self._populate_metadata_custom()
|
1413
|
-
|
1414
|
-
def _save_from_memory(
|
1415
|
-
self,
|
1416
|
-
data,
|
1417
|
-
prefix,
|
1418
|
-
data_file_name,
|
1419
|
-
storage_options,
|
1420
|
-
data_type="training",
|
1421
|
-
**kwargs,
|
1422
|
-
):
|
1423
|
-
"""
|
1424
|
-
Save the data to Object Storage.
|
1425
|
-
"""
|
1426
|
-
oci_storage_path = os.path.join(prefix, data_file_name)
|
1427
|
-
if isinstance(data, np.ndarray) or isinstance(data, list):
|
1428
|
-
data = pd.DataFrame(data)
|
1429
|
-
data.to_csv(oci_storage_path, storage_options=storage_options, **kwargs)
|
1430
|
-
elif isinstance(data, pd.Series) or isinstance(data, pd.DataFrame):
|
1431
|
-
data.to_csv(oci_storage_path, storage_options=storage_options, **kwargs)
|
1432
|
-
elif isinstance(data, ADSData):
|
1433
|
-
data = pd.concat([data.X, data.y], axis=1)
|
1434
|
-
data.to_csv(oci_storage_path, storage_options=storage_options, **kwargs)
|
1435
|
-
else:
|
1436
|
-
raise NotImplementedError(
|
1437
|
-
f"`{type(data)}` is not supported. Use a Pandas DataFrame."
|
1438
|
-
)
|
1439
|
-
|
1440
|
-
self._save_data_path(oci_storage_path, data_type)
|
1441
|
-
self._save_data_shape(data, data_type)
|
1442
|
-
|
1443
|
-
def _save_from_local_file(
|
1444
|
-
self, prefix, file_path, storage_options, data_type="training"
|
1445
|
-
):
|
1446
|
-
"""Save local file to Object Storage."""
|
1447
|
-
file_path = os.path.expanduser(file_path)
|
1448
|
-
import glob
|
1449
|
-
|
1450
|
-
if len(glob.glob(file_path)) == 0:
|
1451
|
-
raise FileExistsError(f"No files were found in `{file_path}`.")
|
1452
|
-
oci_storage_paths = []
|
1453
|
-
with fsspec.open_files(file_path, mode="r") as fhs:
|
1454
|
-
for fh in fhs:
|
1455
|
-
oci_storage_path = os.path.join(prefix, os.path.basename(fh.name))
|
1456
|
-
with fsspec.open(
|
1457
|
-
oci_storage_path,
|
1458
|
-
mode="w",
|
1459
|
-
**(storage_options),
|
1460
|
-
) as f:
|
1461
|
-
f.write(fh.read())
|
1462
|
-
oci_storage_paths.append(oci_storage_path)
|
1463
|
-
self._save_file_size(
|
1464
|
-
os.path.join(os.path.dirname(file_path), os.path.basename(fh.name)),
|
1465
|
-
data_type,
|
1466
|
-
)
|
1467
|
-
self._save_data_path(", ".join(oci_storage_paths), data_type)
|
1468
|
-
|
1469
|
-
def _save_data_path(self, oci_storage_path, data_type):
|
1470
|
-
|
1471
|
-
key = (
|
1472
|
-
MetadataCustomKeys.TRAINING_DATASET
|
1473
|
-
if data_type == "training"
|
1474
|
-
else MetadataCustomKeys.VALIDATION_DATASET
|
1475
|
-
)
|
1476
|
-
self.metadata_custom._add(
|
1477
|
-
ModelCustomMetadataItem(
|
1478
|
-
key=key,
|
1479
|
-
value=oci_storage_path,
|
1480
|
-
description=f"The path to where the {data_type} dataset is stored on Object Storage.",
|
1481
|
-
category=MetadataCustomCategory.TRAINING_AND_VALIDATION_DATASETS,
|
1482
|
-
),
|
1483
|
-
replace=True,
|
1484
|
-
)
|
1485
|
-
|
1486
|
-
def _save_data_shape(self, data, data_type):
|
1487
|
-
key = (
|
1488
|
-
MetadataCustomKeys.TRAINING_DATASET_SIZE
|
1489
|
-
if data_type == "training"
|
1490
|
-
else MetadataCustomKeys.VALIDATION_DATASET_SIZE
|
1491
|
-
)
|
1492
|
-
self.metadata_custom._add(
|
1493
|
-
ModelCustomMetadataItem(
|
1494
|
-
key=MetadataCustomKeys.TRAINING_DATASET_SIZE
|
1495
|
-
if data_type == "training"
|
1496
|
-
else MetadataCustomKeys.VALIDATION_DATASET_SIZE,
|
1497
|
-
value=str(data.shape),
|
1498
|
-
description=f"The size of the {data_type} dataset in bytes.",
|
1499
|
-
category=MetadataCustomCategory.TRAINING_AND_VALIDATION_DATASETS,
|
1500
|
-
),
|
1501
|
-
replace=True,
|
1502
|
-
)
|
1503
|
-
|
1504
|
-
def _save_file_size(self, file_path, data_type):
|
1505
|
-
self.metadata_custom._add(
|
1506
|
-
ModelCustomMetadataItem(
|
1507
|
-
key=MetadataCustomKeys.TRAINING_DATASET_SIZE
|
1508
|
-
if data_type == "training"
|
1509
|
-
else MetadataCustomKeys.VALIDATION_DATASET_SIZE,
|
1510
|
-
value=str(os.stat(file_path).st_size) + " bytes",
|
1511
|
-
description=f"The {data_type} dataset size in bytes.",
|
1512
|
-
category=MetadataCustomCategory.TRAINING_AND_VALIDATION_DATASETS,
|
1513
|
-
),
|
1514
|
-
replace=True,
|
1515
|
-
)
|
1516
|
-
|
1517
|
-
def _prepare_data_for_schema(
|
1518
|
-
self,
|
1519
|
-
X_sample: Union[list, tuple, pd.DataFrame, pd.Series, np.ndarray] = None,
|
1520
|
-
y_sample: Union[list, tuple, pd.DataFrame, pd.Series, np.ndarray] = None,
|
1521
|
-
):
|
1522
|
-
"""
|
1523
|
-
Any Framework-specific work before generic schema generation.
|
1524
|
-
"""
|
1525
|
-
return X_sample, y_sample
|
1526
|
-
|
1527
|
-
def populate_schema(
|
1528
|
-
self,
|
1529
|
-
data_sample: ADSData = None,
|
1530
|
-
X_sample: Union[list, tuple, pd.DataFrame, pd.Series, np.ndarray] = None,
|
1531
|
-
y_sample: Union[list, tuple, pd.DataFrame, pd.Series, np.ndarray] = None,
|
1532
|
-
max_col_num: int = DATA_SCHEMA_MAX_COL_NUM,
|
1533
|
-
):
|
1534
|
-
"""
|
1535
|
-
Populate the input and output schema.
|
1536
|
-
If the schema exceeds the limit of 32kb, save as json files to the artifact directory.
|
1537
|
-
|
1538
|
-
Parameters
|
1539
|
-
----------
|
1540
|
-
data_sample: ADSData
|
1541
|
-
A sample of the data that will be used to generate input_schema and output_schema.
|
1542
|
-
X_sample: Union[list, tuple, pd.Series, np.ndarray, pd.DataFrame]
|
1543
|
-
A sample of input data that will be used to generate input schema.
|
1544
|
-
y_sample: Union[list, tuple, pd.Series, np.ndarray, pd.DataFrame]
|
1545
|
-
A sample of output data that will be used to generate output schema.
|
1546
|
-
max_col_num: (int, optional). Defaults to utils.DATA_SCHEMA_MAX_COL_NUM.
|
1547
|
-
The maximum column size of the data that allows to auto generate schema.
|
1548
|
-
"""
|
1549
|
-
if data_sample is not None:
|
1550
|
-
assert isinstance(
|
1551
|
-
data_sample, ADSData
|
1552
|
-
), "`data_sample` expects data of ADSData type. \
|
1553
|
-
Pass in to `X_sample` and `y_sample` for other data types."
|
1554
|
-
X_sample = data_sample.X
|
1555
|
-
y_sample = data_sample.y
|
1556
|
-
X_sample, y_sample = self._prepare_data_for_schema(X_sample, y_sample)
|
1557
|
-
self.schema_input = self._populate_schema(
|
1558
|
-
X_sample,
|
1559
|
-
schema_file_name=INPUT_SCHEMA_FILE_NAME,
|
1560
|
-
max_col_num=max_col_num,
|
1561
|
-
)
|
1562
|
-
self.schema_output = self._populate_schema(
|
1563
|
-
y_sample,
|
1564
|
-
schema_file_name=OUTPUT_SCHEMA_FILE_NAME,
|
1565
|
-
max_col_num=max_col_num,
|
1566
|
-
)
|
1567
|
-
|
1568
|
-
def _populate_schema(
|
1569
|
-
self,
|
1570
|
-
data: Union[list, tuple, pd.Series, np.ndarray, pd.DataFrame],
|
1571
|
-
schema_file_name: str,
|
1572
|
-
max_col_num: int,
|
1573
|
-
):
|
1574
|
-
"""
|
1575
|
-
Populate schema and if the schema exceeds the limit of 32kb, save as a json file to artifact_dir.
|
1576
|
-
|
1577
|
-
Parameters
|
1578
|
-
----------
|
1579
|
-
data: Union[list, tuple, pd.Series, np.ndarray, pd.DataFrame]
|
1580
|
-
A sample of input data that will be used to generate input schema.
|
1581
|
-
schema_file_name: str
|
1582
|
-
schema file name to be saved as.
|
1583
|
-
max_col_num : int
|
1584
|
-
The maximum column size of the data that allows to auto generate schema.
|
1585
|
-
|
1586
|
-
Returns
|
1587
|
-
-------
|
1588
|
-
Schema
|
1589
|
-
The schema.
|
1590
|
-
"""
|
1591
|
-
result = None
|
1592
|
-
|
1593
|
-
try:
|
1594
|
-
if data is not None:
|
1595
|
-
data = utils.to_dataframe(data)
|
1596
|
-
schema = data.ads.model_schema(max_col_num=max_col_num)
|
1597
|
-
schema.to_json_file(os.path.join(self.artifact_dir, schema_file_name))
|
1598
|
-
if self._validate_schema_size(schema, schema_file_name):
|
1599
|
-
result = schema
|
1600
|
-
except DataSizeTooWide:
|
1601
|
-
logger.warning(
|
1602
|
-
f"The data has too many columns and "
|
1603
|
-
f"the maximum allowable number of columns is `{max_col_num}`. "
|
1604
|
-
"The schema was not auto generated. Increase allowable number of columns."
|
1605
|
-
)
|
1606
|
-
|
1607
|
-
return result or Schema()
|
1608
|
-
|
1609
|
-
def _validate_schema_size(self, schema, schema_file_name):
|
1610
|
-
result = False
|
1611
|
-
try:
|
1612
|
-
result = schema.validate_size()
|
1613
|
-
except SchemaSizeTooLarge:
|
1614
|
-
logger.warn(
|
1615
|
-
f"The {schema_file_name.replace('.json', '')} is larger than "
|
1616
|
-
f"`{METADATA_SIZE_LIMIT}` bytes and cannot be stored as model catalog metadata."
|
1617
|
-
f"It will be saved to {self.artifact_dir}/{schema_file_name}."
|
1618
|
-
)
|
1619
|
-
|
1620
|
-
return result
|
1621
|
-
|
1622
|
-
def introspect(self) -> pd.DataFrame:
|
1623
|
-
"""Runs model introspection.
|
1624
|
-
|
1625
|
-
Returns
|
1626
|
-
-------
|
1627
|
-
pd.DataFrame
|
1628
|
-
The introspection result in a dataframe format.
|
1629
|
-
"""
|
1630
|
-
return self._introspect()
|
1631
|
-
|
1632
|
-
@classmethod
|
1633
|
-
def from_model_catalog(
|
1634
|
-
cls,
|
1635
|
-
model_id: str,
|
1636
|
-
artifact_dir: str,
|
1637
|
-
model_file_name: Optional[str] = "model.onnx",
|
1638
|
-
auth: Optional[Dict] = None,
|
1639
|
-
force_overwrite: Optional[bool] = False,
|
1640
|
-
install_libs: Optional[bool] = False,
|
1641
|
-
conflict_strategy=ConflictStrategy.IGNORE,
|
1642
|
-
bucket_uri: Optional[str] = None,
|
1643
|
-
remove_existing_artifact: Optional[bool] = True,
|
1644
|
-
**kwargs,
|
1645
|
-
) -> "ModelArtifact":
|
1646
|
-
"""Download model artifacts from the model catalog to the target artifact directory.
|
1647
|
-
|
1648
|
-
Parameters
|
1649
|
-
----------
|
1650
|
-
model_id: str
|
1651
|
-
The model OCID.
|
1652
|
-
artifact_dir: str
|
1653
|
-
The artifact directory to store the files needed for deployment.
|
1654
|
-
Will be created if not exists.
|
1655
|
-
model_file_name: (str, optional). Defaults to "model.onnx".
|
1656
|
-
The name of the serialized model.
|
1657
|
-
auth: (Dict, optional). Defaults to None.
|
1658
|
-
Default authetication is set using the `ads.set_auth()` method.
|
1659
|
-
Use the `ads.common.auth.api_keys()` or `ads.common.auth.resource_principal()` to create appropriate
|
1660
|
-
authentication signer and kwargs required to instantiate a IdentityClient object.
|
1661
|
-
force_overwrite: (bool, optional). Defaults to False.
|
1662
|
-
Overwrite existing files.
|
1663
|
-
install_libs: bool, default: False
|
1664
|
-
Install the libraries specified in ds-requirements.txt.
|
1665
|
-
conflict_strategy: ConflictStrategy, default: IGNORE
|
1666
|
-
Determines how to handle version conflicts between the current environment and requirements of
|
1667
|
-
model artifact.
|
1668
|
-
Valid values: "IGNORE", "UPDATE" or ConflictStrategy.
|
1669
|
-
IGNORE: Use the installed version in case of conflict
|
1670
|
-
UPDATE: Force update dependency to the version required by model artifact in case of conflict
|
1671
|
-
bucket_uri: (str, optional). Defaults to None.
|
1672
|
-
The OCI Object Storage URI where model artifacts will be copied to.
|
1673
|
-
The `bucket_uri` is only necessary for downloading large artifacts with
|
1674
|
-
size is greater than 2GB. Example: `oci://<bucket_name>@<namespace>/prefix/`.
|
1675
|
-
remove_existing_artifact: (bool, optional). Defaults to `True`.
|
1676
|
-
Whether artifacts uploaded to object storage bucket need to be removed or not.
|
1677
|
-
kwargs:
|
1678
|
-
compartment_id: (str, optional)
|
1679
|
-
Compartment OCID. If not specified, the value will be taken from the environment variables.
|
1680
|
-
timeout: (int, optional). Defaults to 10 seconds.
|
1681
|
-
The connection timeout in seconds for the client.
|
1682
|
-
|
1683
|
-
Returns
|
1684
|
-
-------
|
1685
|
-
ModelArtifact
|
1686
|
-
An instance of ModelArtifact class.
|
1687
|
-
"""
|
1688
|
-
from ads.catalog.model import ModelCatalog
|
1689
|
-
|
1690
|
-
auth = auth or authutil.default_signer()
|
1691
|
-
artifact_dir = os.path.abspath(os.path.expanduser(artifact_dir))
|
1692
|
-
|
1693
|
-
model_catalog = ModelCatalog(
|
1694
|
-
compartment_id=kwargs.pop("compartment_id", _COMPARTMENT_OCID),
|
1695
|
-
ds_client_auth=auth,
|
1696
|
-
identity_client_auth=auth,
|
1697
|
-
timeout=kwargs.pop("timeout", None),
|
1698
|
-
)
|
1699
|
-
|
1700
|
-
model_catalog._download_artifact(
|
1701
|
-
model_id=model_id,
|
1702
|
-
target_dir=artifact_dir,
|
1703
|
-
force_overwrite=force_overwrite,
|
1704
|
-
bucket_uri=bucket_uri,
|
1705
|
-
remove_existing_artifact=remove_existing_artifact,
|
1706
|
-
)
|
1707
|
-
oci_model = model_catalog.get_model(model_id)
|
1708
|
-
|
1709
|
-
result_artifact = cls(
|
1710
|
-
artifact_dir=artifact_dir,
|
1711
|
-
conflict_strategy=conflict_strategy,
|
1712
|
-
install_libs=install_libs,
|
1713
|
-
reload=False,
|
1714
|
-
model_file_name=model_file_name,
|
1715
|
-
)
|
1716
|
-
|
1717
|
-
result_artifact.metadata_custom = oci_model.metadata_custom
|
1718
|
-
result_artifact.metadata_taxonomy = oci_model.metadata_taxonomy
|
1719
|
-
result_artifact.schema_input = oci_model.schema_input
|
1720
|
-
result_artifact.schema_output = oci_model.schema_output
|
1721
|
-
|
1722
|
-
if not install_libs:
|
1723
|
-
logger.warning(
|
1724
|
-
"Libraries in `ds-requirements.txt` were not installed. "
|
1725
|
-
"Use `install_requirements()` to install the required dependencies."
|
1726
|
-
)
|
1727
|
-
|
1728
|
-
return result_artifact
|
1729
|
-
|
1730
|
-
|
1731
|
-
class VersionConflictWarning(object):
|
1732
|
-
def __init__(self, version_conflicts):
|
1733
|
-
self.version_conflicts = version_conflicts
|
1734
|
-
|
1735
|
-
def __str__(self):
|
1736
|
-
msg = "WARNING: Version conflicts found:"
|
1737
|
-
if len(self.version_conflicts) > 0:
|
1738
|
-
for lib in self.version_conflicts:
|
1739
|
-
msg += "\nInstalled: %s, Required: %s" % (
|
1740
|
-
lib,
|
1741
|
-
self.version_conflicts[lib],
|
1742
|
-
)
|
1743
|
-
return msg
|
1744
|
-
|
1745
|
-
|
1746
|
-
def pip_install(package, options="-U"):
|
1747
|
-
package = re.sub(r"<|>", "=", package.split(",")[0])
|
1748
|
-
for output in execute(["pip", "install", options, package]):
|
1749
|
-
print(output, end="")
|
1750
|
-
|
1751
|
-
|
1752
|
-
def execute(cmd):
|
1753
|
-
popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
|
1754
|
-
for stdout_line in iter(popen.stdout.readline, ""):
|
1755
|
-
yield stdout_line
|
1756
|
-
popen.stdout.close()
|
1757
|
-
return_code = popen.wait()
|
1758
|
-
if return_code:
|
1759
|
-
raise subprocess.CalledProcessError(return_code, cmd)
|