Skip to content

Commit 12c5be4

Browse files
authored
feat: Add export model (#353)
1 parent 857f63d commit 12c5be4

File tree

2 files changed

+430
-15
lines changed

2 files changed

+430
-15
lines changed

google/cloud/aiplatform/models.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import proto
1818
from typing import Dict, List, NamedTuple, Optional, Sequence, Tuple, Union
1919

20+
from google.api_core import operation
2021
from google.auth import credentials as auth_credentials
2122

2223
from google.cloud.aiplatform import base
@@ -35,9 +36,11 @@
3536
endpoint_v1 as gca_endpoint_v1,
3637
endpoint_v1beta1 as gca_endpoint_v1beta1,
3738
explanation_v1beta1 as gca_explanation_v1beta1,
39+
io as gca_io_compat,
3840
machine_resources as gca_machine_resources_compat,
3941
machine_resources_v1beta1 as gca_machine_resources_v1beta1,
4042
model as gca_model_compat,
43+
model_service as gca_model_service_compat,
4144
model_v1beta1 as gca_model_v1beta1,
4245
env_var as gca_env_var_compat,
4346
env_var_v1beta1 as gca_env_var_v1beta1,
@@ -1217,6 +1220,26 @@ def description(self):
12171220
"""Description of the model."""
12181221
return self._gca_resource.description
12191222

1223+
@property
1224+
def supported_export_formats(
1225+
self,
1226+
) -> Dict[str, List[gca_model_compat.Model.ExportFormat.ExportableContent]]:
1227+
"""The formats and content types in which this Model may be exported.
1228+
If empty, this Model is not available for export.
1229+
1230+
For example, if this model can be exported as a Tensorflow SavedModel and
1231+
have the artifacts written to Cloud Storage, the expected value would be:
1232+
1233+
{'tf-saved-model': [<ExportableContent.ARTIFACT: 1>]}
1234+
"""
1235+
return {
1236+
export_format.id: [
1237+
gca_model_compat.Model.ExportFormat.ExportableContent(content)
1238+
for content in export_format.exportable_contents
1239+
]
1240+
for export_format in self._gca_resource.supported_export_formats
1241+
}
1242+
12201243
def __init__(
12211244
self,
12221245
model_name: str,
@@ -2030,3 +2053,142 @@ def list(
20302053
location=location,
20312054
credentials=credentials,
20322055
)
2056+
2057+
@base.optional_sync()
2058+
def _wait_on_export(self, operation_future: operation.Operation, sync=True) -> None:
2059+
operation_future.result()
2060+
2061+
def export_model(
2062+
self,
2063+
export_format_id: str,
2064+
artifact_destination: Optional[str] = None,
2065+
image_destination: Optional[str] = None,
2066+
sync: bool = True,
2067+
) -> Dict[str, str]:
2068+
"""Exports a trained, exportable Model to a location specified by the user.
2069+
A Model is considered to be exportable if it has at least one `supported_export_formats`.
2070+
Either `artifact_destination` or `image_destination` must be provided.
2071+
2072+
Usage:
2073+
my_model.export(
2074+
export_format_id='tf-saved-model'
2075+
artifact_destination='gs://my-bucket/models/'
2076+
)
2077+
2078+
or
2079+
2080+
my_model.export(
2081+
export_format_id='custom-model'
2082+
image_destination='us-central1-docker.pkg.dev/projectId/repo/image'
2083+
)
2084+
2085+
Args:
2086+
export_format_id (str):
2087+
Required. The ID of the format in which the Model must be exported.
2088+
The list of export formats that this Model supports can be found
2089+
by calling `Model.supported_export_formats`.
2090+
artifact_destination (str):
2091+
The Cloud Storage location where the Model artifact is to be
2092+
written to. Under the directory given as the destination a
2093+
new one with name
2094+
"``model-export-<model-display-name>-<timestamp-of-export-call>``",
2095+
where timestamp is in YYYY-MM-DDThh:mm:ss.sssZ ISO-8601
2096+
format, will be created. Inside, the Model and any of its
2097+
supporting files will be written.
2098+
2099+
This field should only be set when, in [Model.supported_export_formats],
2100+
the value for the key given in `export_format_id` contains ``ARTIFACT``.
2101+
image_destination (str):
2102+
The Google Container Registry or Artifact Registry URI where
2103+
the Model container image will be copied to. Accepted forms:
2104+
2105+
- Google Container Registry path. For example:
2106+
``gcr.io/projectId/imageName:tag``.
2107+
2108+
- Artifact Registry path. For example:
2109+
``us-central1-docker.pkg.dev/projectId/repoName/imageName:tag``.
2110+
2111+
This field should only be set when, in [Model.supported_export_formats],
2112+
the value for the key given in `export_format_id` contains ``IMAGE``.
2113+
sync (bool):
2114+
Whether to execute this export synchronously. If False, this method
2115+
will be executed in concurrent Future and any downstream object will
2116+
be immediately returned and synced when the Future has completed.
2117+
Returns:
2118+
output_info (Dict[str, str]):
2119+
Details of the completed export with output destination paths to
2120+
the artifacts or container image.
2121+
Raises:
2122+
ValueError if model does not support exporting.
2123+
2124+
ValueError if invalid arguments or export formats are provided.
2125+
"""
2126+
2127+
# Model does not support exporting
2128+
if not self.supported_export_formats:
2129+
raise ValueError(f"The model `{self.resource_name}` is not exportable.")
2130+
2131+
# No destination provided
2132+
if not any((artifact_destination, image_destination)):
2133+
raise ValueError(
2134+
"Please provide an `artifact_destination` or `image_destination`."
2135+
)
2136+
2137+
export_format_id = export_format_id.lower()
2138+
2139+
# Unsupported export type
2140+
if export_format_id not in self.supported_export_formats:
2141+
raise ValueError(
2142+
f"'{export_format_id}' is not a supported export format for this model. "
2143+
f"Choose one of the following: {self.supported_export_formats}"
2144+
)
2145+
2146+
content_types = gca_model_compat.Model.ExportFormat.ExportableContent
2147+
supported_content_types = self.supported_export_formats[export_format_id]
2148+
2149+
if (
2150+
artifact_destination
2151+
and content_types.ARTIFACT not in supported_content_types
2152+
):
2153+
raise ValueError(
2154+
"This model can not be exported as an artifact in '{export_format_id}' format. "
2155+
"Try exporting as a container image by passing the `image_destination` argument."
2156+
)
2157+
2158+
if image_destination and content_types.IMAGE not in supported_content_types:
2159+
raise ValueError(
2160+
"This model can not be exported as a container image in '{export_format_id}' format. "
2161+
"Try exporting the model artifacts by passing a `artifact_destination` argument."
2162+
)
2163+
2164+
# Construct request payload
2165+
output_config = gca_model_service_compat.ExportModelRequest.OutputConfig(
2166+
export_format_id=export_format_id
2167+
)
2168+
2169+
if artifact_destination:
2170+
output_config.artifact_destination = gca_io_compat.GcsDestination(
2171+
output_uri_prefix=artifact_destination
2172+
)
2173+
2174+
if image_destination:
2175+
output_config.image_destination = gca_io_compat.ContainerRegistryDestination(
2176+
output_uri=image_destination
2177+
)
2178+
2179+
_LOGGER.log_action_start_against_resource("Exporting", "model", self)
2180+
2181+
operation_future = self.api_client.export_model(
2182+
name=self.resource_name, output_config=output_config
2183+
)
2184+
2185+
_LOGGER.log_action_started_against_resource_with_lro(
2186+
"Export", "model", self.__class__, operation_future
2187+
)
2188+
2189+
# Block before returning
2190+
self._wait_on_export(operation_future=operation_future, sync=sync)
2191+
2192+
_LOGGER.log_action_completed_against_resource("model", "exported", self)
2193+
2194+
return json_format.MessageToDict(operation_future.metadata.output_info._pb)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy