google-cloud-pipeline-components 2.6.0__py3-none-any.whl → 2.7.0__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.
- google_cloud_pipeline_components/_implementation/llm/arbiter_preprocess.py +137 -0
- google_cloud_pipeline_components/_implementation/llm/autosxs_arbiter.py +105 -0
- google_cloud_pipeline_components/_implementation/llm/autosxs_metrics_computer.py +66 -0
- google_cloud_pipeline_components/_implementation/llm/deployment_graph.py +10 -16
- google_cloud_pipeline_components/_implementation/llm/env.py +1 -1
- google_cloud_pipeline_components/_implementation/llm/function_based.py +82 -5
- google_cloud_pipeline_components/_implementation/llm/reinforcement_learning_graph.py +6 -0
- google_cloud_pipeline_components/_implementation/llm/reinforcer.py +7 -2
- google_cloud_pipeline_components/_implementation/llm/reward_model_graph.py +6 -0
- google_cloud_pipeline_components/_implementation/llm/reward_model_trainer.py +7 -2
- google_cloud_pipeline_components/_implementation/llm/supervised_fine_tuner.py +5 -0
- google_cloud_pipeline_components/_implementation/llm/task_preprocess.py +97 -0
- google_cloud_pipeline_components/_implementation/llm/upload_llm_model.py +5 -0
- google_cloud_pipeline_components/_implementation/model_evaluation/__init__.py +4 -0
- google_cloud_pipeline_components/_implementation/model_evaluation/endpoint_batch_predict/component.py +1 -1
- google_cloud_pipeline_components/_implementation/model_evaluation/import_evaluation/component.py +10 -0
- google_cloud_pipeline_components/_implementation/model_evaluation/llm_embedding/evaluation_llm_embedding_pipeline.py +64 -15
- google_cloud_pipeline_components/_implementation/model_evaluation/llm_evaluation/component.py +9 -2
- google_cloud_pipeline_components/_implementation/model_evaluation/model_inference/__init__.py +14 -0
- google_cloud_pipeline_components/_implementation/model_evaluation/model_inference/component.py +324 -0
- google_cloud_pipeline_components/_implementation/model_evaluation/version.py +2 -2
- google_cloud_pipeline_components/container/_implementation/model_evaluation/import_model_evaluation.py +8 -0
- google_cloud_pipeline_components/container/v1/automl_training_job/__init__.py +14 -0
- google_cloud_pipeline_components/container/v1/automl_training_job/image/__init__.py +14 -0
- google_cloud_pipeline_components/container/v1/automl_training_job/image/launcher.py +236 -0
- google_cloud_pipeline_components/container/v1/automl_training_job/image/remote_runner.py +250 -0
- google_cloud_pipeline_components/preview/model_evaluation/evaluation_llm_text_generation_pipeline.py +6 -1
- google_cloud_pipeline_components/preview/model_evaluation/model_based_llm_evaluation/__init__.py +20 -0
- google_cloud_pipeline_components/preview/model_evaluation/model_based_llm_evaluation/autosxs/__init__.py +13 -0
- google_cloud_pipeline_components/preview/model_evaluation/model_based_llm_evaluation/autosxs/autosxs_pipeline.py +234 -0
- google_cloud_pipeline_components/version.py +1 -1
- {google_cloud_pipeline_components-2.6.0.dist-info → google_cloud_pipeline_components-2.7.0.dist-info}/METADATA +1 -1
- {google_cloud_pipeline_components-2.6.0.dist-info → google_cloud_pipeline_components-2.7.0.dist-info}/RECORD +36 -23
- {google_cloud_pipeline_components-2.6.0.dist-info → google_cloud_pipeline_components-2.7.0.dist-info}/LICENSE +0 -0
- {google_cloud_pipeline_components-2.6.0.dist-info → google_cloud_pipeline_components-2.7.0.dist-info}/WHEEL +0 -0
- {google_cloud_pipeline_components-2.6.0.dist-info → google_cloud_pipeline_components-2.7.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Copyright 2023 The Kubeflow Authors. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
"""GCP remote runner for AutoML image training pipelines based on the AI Platform SDK."""
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
from typing import Any, Dict, Optional, Sequence
|
|
18
|
+
|
|
19
|
+
from google.api_core import retry
|
|
20
|
+
from google.cloud.aiplatform import datasets
|
|
21
|
+
from google.cloud.aiplatform import gapic
|
|
22
|
+
from google.cloud.aiplatform import initializer
|
|
23
|
+
from google.cloud.aiplatform import models
|
|
24
|
+
from google.cloud.aiplatform import schema
|
|
25
|
+
from google.cloud.aiplatform import training_jobs
|
|
26
|
+
from google.cloud.aiplatform_v1.types import model
|
|
27
|
+
from google.cloud.aiplatform_v1.types import training_pipeline
|
|
28
|
+
from google_cloud_pipeline_components.container.v1.gcp_launcher import pipeline_remote_runner
|
|
29
|
+
from google_cloud_pipeline_components.container.v1.gcp_launcher.utils import error_util
|
|
30
|
+
|
|
31
|
+
from google.protobuf import struct_pb2
|
|
32
|
+
from google.protobuf import json_format
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
_GET_PIPELINE_RETRY_DEADLINE_SECONDS = 10.0 * 60.0
|
|
36
|
+
_CLASSIFICATION = 'classification'
|
|
37
|
+
_OBJECT_DETECTION = 'object_detection'
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# pylint: disable=protected-access
|
|
41
|
+
def create_payload(
|
|
42
|
+
project: str,
|
|
43
|
+
location: str,
|
|
44
|
+
display_name: Optional[str] = None,
|
|
45
|
+
prediction_type: str = _CLASSIFICATION,
|
|
46
|
+
multi_label: bool = False,
|
|
47
|
+
model_type: str = 'CLOUD',
|
|
48
|
+
labels: Optional[Dict[str, str]] = None,
|
|
49
|
+
dataset: Optional[str] = None,
|
|
50
|
+
disable_early_stopping: bool = False,
|
|
51
|
+
training_encryption_spec_key_name: Optional[str] = None,
|
|
52
|
+
model_encryption_spec_key_name: Optional[str] = None,
|
|
53
|
+
model_display_name: Optional[str] = None,
|
|
54
|
+
training_fraction_split: Optional[float] = None,
|
|
55
|
+
validation_fraction_split: Optional[float] = None,
|
|
56
|
+
test_fraction_split: Optional[float] = None,
|
|
57
|
+
budget_milli_node_hours: Optional[int] = None,
|
|
58
|
+
training_filter_split: Optional[str] = None,
|
|
59
|
+
validation_filter_split: Optional[str] = None,
|
|
60
|
+
test_filter_split: Optional[str] = None,
|
|
61
|
+
base_model: Optional[str] = None,
|
|
62
|
+
incremental_train_base_model: Optional[str] = None,
|
|
63
|
+
parent_model: Optional[str] = None,
|
|
64
|
+
is_default_version: Optional[bool] = True,
|
|
65
|
+
model_version_aliases: Optional[Sequence[str]] = None,
|
|
66
|
+
model_version_description: Optional[str] = None,
|
|
67
|
+
model_labels: Optional[Dict[str, str]] = None,
|
|
68
|
+
) -> str:
|
|
69
|
+
"""Creates a AutoML Image Training Job payload."""
|
|
70
|
+
# Override default model_type for object_detection
|
|
71
|
+
if model_type == 'CLOUD' and prediction_type == _OBJECT_DETECTION:
|
|
72
|
+
model_type = 'CLOUD_HIGH_ACCURACY_1'
|
|
73
|
+
|
|
74
|
+
training_encryption_spec = initializer.global_config.get_encryption_spec(
|
|
75
|
+
encryption_spec_key_name=training_encryption_spec_key_name
|
|
76
|
+
)
|
|
77
|
+
model_encryption_spec = initializer.global_config.get_encryption_spec(
|
|
78
|
+
encryption_spec_key_name=model_encryption_spec_key_name
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Training task inputs.
|
|
82
|
+
training_task_inputs = {
|
|
83
|
+
# required inputs
|
|
84
|
+
'modelType': model_type,
|
|
85
|
+
'budgetMilliNodeHours': budget_milli_node_hours,
|
|
86
|
+
# optional inputs
|
|
87
|
+
'disableEarlyStopping': disable_early_stopping,
|
|
88
|
+
}
|
|
89
|
+
if prediction_type == _CLASSIFICATION:
|
|
90
|
+
training_task_inputs['multiLabel'] = multi_label
|
|
91
|
+
if incremental_train_base_model:
|
|
92
|
+
training_task_inputs['uptrainBaseModelId'] = incremental_train_base_model
|
|
93
|
+
|
|
94
|
+
training_task_definition = getattr(
|
|
95
|
+
schema.training_job.definition, f'automl_image_{prediction_type}'
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
# Input data config.
|
|
99
|
+
input_data_config = training_jobs._TrainingJob._create_input_data_config(
|
|
100
|
+
dataset=dataset and datasets.ImageDataset(dataset_name=dataset),
|
|
101
|
+
training_fraction_split=training_fraction_split,
|
|
102
|
+
validation_fraction_split=validation_fraction_split,
|
|
103
|
+
test_fraction_split=test_fraction_split,
|
|
104
|
+
training_filter_split=training_filter_split,
|
|
105
|
+
validation_filter_split=validation_filter_split,
|
|
106
|
+
test_filter_split=test_filter_split,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# Model to upload.
|
|
110
|
+
model_to_upload = model.Model(
|
|
111
|
+
display_name=model_display_name or display_name,
|
|
112
|
+
labels=model_labels or labels,
|
|
113
|
+
encryption_spec=model_encryption_spec,
|
|
114
|
+
version_aliases=models.ModelRegistry._get_true_alias_list(
|
|
115
|
+
model_version_aliases, is_default_version
|
|
116
|
+
),
|
|
117
|
+
version_description=model_version_description,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Sets base_model.
|
|
121
|
+
if base_model:
|
|
122
|
+
training_task_inputs['baseModelId'] = base_model
|
|
123
|
+
|
|
124
|
+
# Create training task inputs.
|
|
125
|
+
training_task_inputs_struct = struct_pb2.Struct()
|
|
126
|
+
training_task_inputs_struct.update(training_task_inputs)
|
|
127
|
+
|
|
128
|
+
# Gets parent_model.
|
|
129
|
+
parent_model = models.ModelRegistry._get_true_version_parent(
|
|
130
|
+
parent_model=parent_model,
|
|
131
|
+
project=project,
|
|
132
|
+
location=location,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
pipeline = training_pipeline.TrainingPipeline(
|
|
136
|
+
display_name=display_name,
|
|
137
|
+
training_task_definition=training_task_definition,
|
|
138
|
+
training_task_inputs=struct_pb2.Value(
|
|
139
|
+
struct_value=training_task_inputs_struct
|
|
140
|
+
),
|
|
141
|
+
model_to_upload=model_to_upload,
|
|
142
|
+
parent_model=parent_model,
|
|
143
|
+
input_data_config=input_data_config,
|
|
144
|
+
labels=labels,
|
|
145
|
+
encryption_spec=training_encryption_spec,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
return json_format.MessageToJson(
|
|
149
|
+
pipeline._pb, preserving_proto_field_name=True
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# pylint: enable=protected-access
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def create_pipeline_with_client(
|
|
157
|
+
pipeline_client: gapic.PipelineServiceClient,
|
|
158
|
+
parent,
|
|
159
|
+
pipeline_spec: Any,
|
|
160
|
+
):
|
|
161
|
+
"""Creates a training pipeline with the client."""
|
|
162
|
+
created_pipeline = None
|
|
163
|
+
try:
|
|
164
|
+
logging.info(
|
|
165
|
+
'Creating AutoML Vision training pipeline with sanitized pipeline'
|
|
166
|
+
' spec: %s',
|
|
167
|
+
pipeline_spec,
|
|
168
|
+
)
|
|
169
|
+
created_pipeline = pipeline_client.create_training_pipeline(
|
|
170
|
+
parent=parent,
|
|
171
|
+
training_pipeline=training_pipeline.TrainingPipeline(**pipeline_spec),
|
|
172
|
+
)
|
|
173
|
+
except (ConnectionError, RuntimeError) as err:
|
|
174
|
+
error_util.exit_with_internal_error(err.args[0])
|
|
175
|
+
return created_pipeline
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def get_pipeline_with_client(
|
|
179
|
+
pipeline_client: gapic.PipelineServiceClient, pipeline_name: str
|
|
180
|
+
):
|
|
181
|
+
"""Gets training pipeline state with the client."""
|
|
182
|
+
get_automl_vision_training_pipeline = None
|
|
183
|
+
try:
|
|
184
|
+
get_automl_vision_training_pipeline = pipeline_client.get_training_pipeline(
|
|
185
|
+
name=pipeline_name,
|
|
186
|
+
retry=retry.Retry(deadline=_GET_PIPELINE_RETRY_DEADLINE_SECONDS),
|
|
187
|
+
)
|
|
188
|
+
except (ConnectionError, RuntimeError) as err:
|
|
189
|
+
error_util.exit_with_internal_error(err.args[0])
|
|
190
|
+
return get_automl_vision_training_pipeline
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def create_pipeline(
|
|
194
|
+
type: str, # pylint: disable=redefined-builtin
|
|
195
|
+
project: str,
|
|
196
|
+
location: str,
|
|
197
|
+
gcp_resources: str,
|
|
198
|
+
**kwargs: Dict[str, Any],
|
|
199
|
+
):
|
|
200
|
+
"""Create and poll AutoML Vision training pipeline status till it reaches a final state.
|
|
201
|
+
|
|
202
|
+
This follows the typical launching logic:
|
|
203
|
+
1. Read if the training pipeline already exists in gcp_resources
|
|
204
|
+
- If already exists, jump to step 3 and poll the pipeline status. This
|
|
205
|
+
happens
|
|
206
|
+
if the launcher container experienced unexpected termination, such as
|
|
207
|
+
preemption
|
|
208
|
+
2. Deserialize the payload into the pipeline spec and create the training
|
|
209
|
+
pipeline
|
|
210
|
+
3. Poll the training pipeline status every
|
|
211
|
+
pipeline_remote_runner._POLLING_INTERVAL_IN_SECONDS seconds
|
|
212
|
+
- If the training pipeline is succeeded, return succeeded
|
|
213
|
+
- If the training pipeline is cancelled/paused, it's an unexpected
|
|
214
|
+
scenario so return failed
|
|
215
|
+
- If the training pipeline is running, continue polling the status
|
|
216
|
+
|
|
217
|
+
Also retry on ConnectionError up to
|
|
218
|
+
pipeline_remote_runner._CONNECTION_ERROR_RETRY_LIMIT times during the poll.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
type: Job type.
|
|
222
|
+
project: Project name.
|
|
223
|
+
location: Location to start the training job.
|
|
224
|
+
gcp_resources: URI for storing GCP resources.
|
|
225
|
+
**kwargs: Extra args for creating the payload.
|
|
226
|
+
"""
|
|
227
|
+
remote_runner = pipeline_remote_runner.PipelineRemoteRunner(
|
|
228
|
+
type, project, location, gcp_resources
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
try:
|
|
232
|
+
# Create AutoML vision training pipeline if it does not exist
|
|
233
|
+
pipeline_name = remote_runner.check_if_pipeline_exists()
|
|
234
|
+
if pipeline_name is None:
|
|
235
|
+
payload = create_payload(project, location, **kwargs)
|
|
236
|
+
logging.info(
|
|
237
|
+
'AutoML Vision training payload formatted: %s',
|
|
238
|
+
payload,
|
|
239
|
+
)
|
|
240
|
+
pipeline_name = remote_runner.create_pipeline(
|
|
241
|
+
create_pipeline_with_client,
|
|
242
|
+
payload,
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
# Poll AutoML Vision training pipeline status until
|
|
246
|
+
# "PipelineState.PIPELINE_STATE_SUCCEEDED"
|
|
247
|
+
remote_runner.poll_pipeline(get_pipeline_with_client, pipeline_name)
|
|
248
|
+
|
|
249
|
+
except (ConnectionError, RuntimeError) as err:
|
|
250
|
+
error_util.exit_with_internal_error(err.args[0])
|
google_cloud_pipeline_components/preview/model_evaluation/evaluation_llm_text_generation_pipeline.py
CHANGED
|
@@ -40,6 +40,7 @@ def evaluation_llm_text_generation_pipeline( # pylint: disable=dangerous-defaul
|
|
|
40
40
|
batch_predict_instances_format: str = 'jsonl',
|
|
41
41
|
batch_predict_predictions_format: str = 'jsonl',
|
|
42
42
|
batch_predict_model_parameters: Dict[str, str] = {},
|
|
43
|
+
enable_row_based_metrics: bool = False,
|
|
43
44
|
machine_type: str = 'e2-highmem-16',
|
|
44
45
|
service_account: str = '',
|
|
45
46
|
network: str = '',
|
|
@@ -74,7 +75,7 @@ def evaluation_llm_text_generation_pipeline( # pylint: disable=dangerous-defaul
|
|
|
74
75
|
|
|
75
76
|
Returns:
|
|
76
77
|
evaluation_metrics: Metrics Artifact for LLM Text Generation.
|
|
77
|
-
evaluation_resource_name: If run on
|
|
78
|
+
evaluation_resource_name: If run on a user's managed VertexModel, the imported evaluation resource name. Empty if run on a publisher model.
|
|
78
79
|
"""
|
|
79
80
|
# fmt: on
|
|
80
81
|
outputs = NamedTuple(
|
|
@@ -123,6 +124,7 @@ def evaluation_llm_text_generation_pipeline( # pylint: disable=dangerous-defaul
|
|
|
123
124
|
evaluation_task=evaluation_task,
|
|
124
125
|
target_field_name=f'instance.{target_field_name}',
|
|
125
126
|
predictions_format=batch_predict_predictions_format,
|
|
127
|
+
enable_row_based_metrics=enable_row_based_metrics,
|
|
126
128
|
joined_predictions_gcs_source=batch_predict_task.outputs[
|
|
127
129
|
'gcs_output_directory'
|
|
128
130
|
],
|
|
@@ -134,6 +136,9 @@ def evaluation_llm_text_generation_pipeline( # pylint: disable=dangerous-defaul
|
|
|
134
136
|
|
|
135
137
|
import_evaluation_task = ModelImportEvaluationOp(
|
|
136
138
|
metrics=eval_task.outputs['evaluation_metrics'],
|
|
139
|
+
row_based_metrics=eval_task.outputs['row_based_metrics']
|
|
140
|
+
if enable_row_based_metrics
|
|
141
|
+
else None,
|
|
137
142
|
model=get_vertex_model_task.outputs['artifact'],
|
|
138
143
|
problem_type=evaluation_task,
|
|
139
144
|
dataset_type=batch_predict_predictions_format,
|
google_cloud_pipeline_components/preview/model_evaluation/model_based_llm_evaluation/__init__.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Copyright 2023 The Kubeflow Authors. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
"""Model based LLM evaluation preview components."""
|
|
15
|
+
|
|
16
|
+
from google_cloud_pipeline_components.preview.model_evaluation.model_based_llm_evaluation.autosxs.autosxs_pipeline import autosxs_pipeline
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
'autosxs_pipeline',
|
|
20
|
+
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright 2023 The Kubeflow Authors. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# Copyright 2023 The Kubeflow Authors. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
"""Optimization AI Inference and AutoSxS pipeline function."""
|
|
15
|
+
|
|
16
|
+
from typing import Any, Dict, List
|
|
17
|
+
|
|
18
|
+
from google_cloud_pipeline_components import _placeholders
|
|
19
|
+
from google_cloud_pipeline_components._implementation.llm import arbiter_preprocess
|
|
20
|
+
from google_cloud_pipeline_components._implementation.llm import autosxs_arbiter
|
|
21
|
+
from google_cloud_pipeline_components._implementation.llm import autosxs_metrics_computer
|
|
22
|
+
from google_cloud_pipeline_components._implementation.llm import function_based
|
|
23
|
+
from google_cloud_pipeline_components._implementation.llm import task_preprocess
|
|
24
|
+
from google_cloud_pipeline_components.types import artifact_types
|
|
25
|
+
from google_cloud_pipeline_components.v1 import batch_predict_job
|
|
26
|
+
from kfp import dsl
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# pylint: disable=no-value-for-parameter
|
|
30
|
+
@dsl.pipeline(
|
|
31
|
+
name='predictions-pipeline',
|
|
32
|
+
description='Runs the prediction pipeline for one of the two SxS models.',
|
|
33
|
+
)
|
|
34
|
+
def _get_predictions(
|
|
35
|
+
name: str,
|
|
36
|
+
project: str,
|
|
37
|
+
location: str,
|
|
38
|
+
model: str,
|
|
39
|
+
model_parameters: Dict[str, str],
|
|
40
|
+
prediction_inputs: List[str],
|
|
41
|
+
is_model_inference: bool,
|
|
42
|
+
) -> str:
|
|
43
|
+
"""Makes predictions for a given model."""
|
|
44
|
+
with dsl.If(is_model_inference == True, name='Inference Required'): # pylint: disable=singleton-comparison
|
|
45
|
+
get_vertex_model_task = dsl.importer(
|
|
46
|
+
artifact_uri=(
|
|
47
|
+
f'https://{location}-aiplatform.googleapis.com/v1/{model}'
|
|
48
|
+
),
|
|
49
|
+
artifact_class=artifact_types.VertexModel,
|
|
50
|
+
metadata={'resourceName': model},
|
|
51
|
+
).set_display_name('Import Vertex Model Artifact')
|
|
52
|
+
|
|
53
|
+
batch_predict_task = batch_predict_job.ModelBatchPredictOp(
|
|
54
|
+
project=project,
|
|
55
|
+
location=location,
|
|
56
|
+
model=get_vertex_model_task.outputs['artifact'],
|
|
57
|
+
job_display_name=(
|
|
58
|
+
f'autosxs-{name}-{{$.pipeline_job_uuid}}-{{$.pipeline_task_uuid}}'
|
|
59
|
+
),
|
|
60
|
+
gcs_source_uris=prediction_inputs,
|
|
61
|
+
instances_format='jsonl',
|
|
62
|
+
predictions_format='jsonl',
|
|
63
|
+
gcs_destination_output_uri_prefix=(
|
|
64
|
+
f'{dsl.PIPELINE_ROOT_PLACEHOLDER}/{dsl.PIPELINE_TASK_ID_PLACEHOLDER}'
|
|
65
|
+
f'/{name}_predictions'
|
|
66
|
+
),
|
|
67
|
+
model_parameters=model_parameters,
|
|
68
|
+
)
|
|
69
|
+
prediction_uris_from_inference = function_based.get_uri(
|
|
70
|
+
artifact=batch_predict_task.outputs['gcs_output_directory'],
|
|
71
|
+
is_dir=True,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
with dsl.Else(name='Responses Provided'): # pylint: disable=singleton-comparison
|
|
75
|
+
prediction_uris_inference_provided = function_based.get_empty_string()
|
|
76
|
+
|
|
77
|
+
prediction_uris = dsl.OneOf(
|
|
78
|
+
prediction_uris_from_inference.output,
|
|
79
|
+
prediction_uris_inference_provided.output,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# We can't directly output dsl.OneOf, so we need to use identity.
|
|
83
|
+
return function_based.identity(x=prediction_uris).output
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# pylint: disable=dangerous-default-value,g-bare-generic
|
|
87
|
+
@dsl.pipeline(
|
|
88
|
+
name='autosxs-template',
|
|
89
|
+
description='Determines the SxS winrate between two models.',
|
|
90
|
+
)
|
|
91
|
+
def autosxs_pipeline(
|
|
92
|
+
evaluation_dataset: str,
|
|
93
|
+
task: str,
|
|
94
|
+
id_columns: List[str],
|
|
95
|
+
model_a: str = '',
|
|
96
|
+
model_b: str = '',
|
|
97
|
+
autorater_prompt_parameters: Dict[str, Dict[str, str]] = {}, # pylint: disable=unused-argument
|
|
98
|
+
model_a_prompt_parameters: Dict[str, Dict[str, str]] = {},
|
|
99
|
+
model_b_prompt_parameters: Dict[str, Dict[str, str]] = {},
|
|
100
|
+
response_column_a: str = '',
|
|
101
|
+
response_column_b: str = '',
|
|
102
|
+
model_a_parameters: Dict[str, str] = {},
|
|
103
|
+
model_b_parameters: Dict[str, str] = {},
|
|
104
|
+
human_preference_column: str = '',
|
|
105
|
+
project: str = _placeholders.PROJECT_ID_PLACEHOLDER,
|
|
106
|
+
location: str = _placeholders.LOCATION_PLACEHOLDER,
|
|
107
|
+
judgments_format: str = 'jsonl',
|
|
108
|
+
bigquery_destination_prefix: str = '',
|
|
109
|
+
experimental_args: Dict[str, Any] = {},
|
|
110
|
+
):
|
|
111
|
+
"""Evaluates two models side-by-side using an arbiter model.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
evaluation_dataset: A list of GCS paths to a JSONL dataset containing
|
|
115
|
+
evaluation examples.
|
|
116
|
+
task: Evaluation task in the form {task}@{version}. task can be one of
|
|
117
|
+
"summarization", "question_answer". Version is an integer with 3 digits or
|
|
118
|
+
"latest". Ex: summarization@001 or question_answer@latest.
|
|
119
|
+
id_columns: The columns which distinguish unique evaluation examples.
|
|
120
|
+
model_a: A fully-qualified model resource name. This parameter is optional
|
|
121
|
+
if Model A responses are specified.
|
|
122
|
+
model_b: A fully-qualified model resource name. This parameter is optional
|
|
123
|
+
if Model B responses are specified.
|
|
124
|
+
autorater_prompt_parameters: Map of autorater prompt parameters to columns
|
|
125
|
+
or templates. The expected parameters are: inference_instruction - Details
|
|
126
|
+
on how to perform a task. inference_context - Content to reference to
|
|
127
|
+
perform the task.
|
|
128
|
+
model_a_prompt_parameters: Map of Model A prompt template parameters to
|
|
129
|
+
columns or templates.
|
|
130
|
+
model_b_prompt_parameters: Map of Model B prompt template parameters to
|
|
131
|
+
columns or templates.
|
|
132
|
+
response_column_a: The column containing responses for model A. Required if
|
|
133
|
+
any response tables are provided for model A.
|
|
134
|
+
response_column_b: The column containing responses for model B. Required if
|
|
135
|
+
any response tables are provided for model B.
|
|
136
|
+
model_a_parameters: The parameters that govern the predictions from model A.
|
|
137
|
+
model_b_parameters: The parameters that govern the predictions from model B.
|
|
138
|
+
human_preference_column: The column containing ground truths. Only required
|
|
139
|
+
when users want to check the autorater alignment against human preference.
|
|
140
|
+
project: Project used to run custom jobs. Default is the same project used
|
|
141
|
+
to run the pipeline.
|
|
142
|
+
location: Location used to run custom jobs. Default is the same location
|
|
143
|
+
used to run the pipeline.
|
|
144
|
+
judgments_format: The format to write judgments to. Can be either 'json' or
|
|
145
|
+
'bigquery'.
|
|
146
|
+
bigquery_destination_prefix: BigQuery table to write judgments to if the
|
|
147
|
+
specified format is 'bigquery'.
|
|
148
|
+
experimental_args: Experimentally released arguments. Subject to change.
|
|
149
|
+
"""
|
|
150
|
+
prediction_inputs_a = task_preprocess.task_preprocess(
|
|
151
|
+
evaluation_dataset=evaluation_dataset,
|
|
152
|
+
task=task,
|
|
153
|
+
model_prompt_parameters=model_a_prompt_parameters,
|
|
154
|
+
response_column=response_column_a,
|
|
155
|
+
human_preference_column=human_preference_column,
|
|
156
|
+
id_columns=id_columns,
|
|
157
|
+
).set_display_name('Preprocess Model A Inputs')
|
|
158
|
+
|
|
159
|
+
prediction_inputs_b = task_preprocess.task_preprocess(
|
|
160
|
+
evaluation_dataset=evaluation_dataset,
|
|
161
|
+
task=task,
|
|
162
|
+
model_prompt_parameters=model_b_prompt_parameters,
|
|
163
|
+
response_column=response_column_b,
|
|
164
|
+
human_preference_column=human_preference_column,
|
|
165
|
+
id_columns=id_columns,
|
|
166
|
+
).set_display_name('Preprocess Model B Inputs')
|
|
167
|
+
|
|
168
|
+
is_model_a_inference = function_based.get_usage_metric(
|
|
169
|
+
metadata=prediction_inputs_a.outputs['metadata'],
|
|
170
|
+
key='is_model_inference',
|
|
171
|
+
).set_display_name('Read is_model_a_inference')
|
|
172
|
+
|
|
173
|
+
is_model_b_inference = function_based.get_usage_metric(
|
|
174
|
+
metadata=prediction_inputs_b.outputs['metadata'],
|
|
175
|
+
key='is_model_inference',
|
|
176
|
+
).set_display_name('Read is_model_b_inference')
|
|
177
|
+
|
|
178
|
+
inferrer_a = _get_predictions(
|
|
179
|
+
name='A',
|
|
180
|
+
project=project,
|
|
181
|
+
location=location,
|
|
182
|
+
model=model_a,
|
|
183
|
+
model_parameters=model_a_parameters,
|
|
184
|
+
prediction_inputs=prediction_inputs_a.outputs['prediction_inputs'],
|
|
185
|
+
is_model_inference=is_model_a_inference.output,
|
|
186
|
+
).set_display_name('Model A Responses')
|
|
187
|
+
|
|
188
|
+
inferrer_b = _get_predictions(
|
|
189
|
+
name='B',
|
|
190
|
+
project=project,
|
|
191
|
+
location=location,
|
|
192
|
+
model=model_b,
|
|
193
|
+
model_parameters=model_b_parameters,
|
|
194
|
+
prediction_inputs=prediction_inputs_b.outputs['prediction_inputs'],
|
|
195
|
+
is_model_inference=is_model_b_inference.output,
|
|
196
|
+
).set_display_name('Model B Responses')
|
|
197
|
+
|
|
198
|
+
arbiter_input_preprocess = arbiter_preprocess.arbiter_preprocess(
|
|
199
|
+
autorater_prompt_parameters=autorater_prompt_parameters,
|
|
200
|
+
evaluation_dataset=evaluation_dataset,
|
|
201
|
+
id_columns=id_columns,
|
|
202
|
+
prediction_uris_b=inferrer_b.output,
|
|
203
|
+
prediction_uris_a=inferrer_a.output,
|
|
204
|
+
model_a_prompt_parameters=model_a_prompt_parameters,
|
|
205
|
+
model_b_prompt_parameters=model_b_prompt_parameters,
|
|
206
|
+
task=task,
|
|
207
|
+
response_column_a=response_column_a,
|
|
208
|
+
response_column_b=response_column_b,
|
|
209
|
+
human_preference_column=human_preference_column,
|
|
210
|
+
is_bp_output_a=is_model_a_inference.output,
|
|
211
|
+
is_bp_output_b=is_model_b_inference.output,
|
|
212
|
+
).set_display_name('Preprocess Predictions')
|
|
213
|
+
|
|
214
|
+
autosxs_arbiter_task = autosxs_arbiter.autosxs_arbiter(
|
|
215
|
+
inference_output_uri=arbiter_input_preprocess.outputs[
|
|
216
|
+
'preprocessed_evaluation_dataset_uri'
|
|
217
|
+
],
|
|
218
|
+
id_columns=id_columns,
|
|
219
|
+
human_preference_column=human_preference_column,
|
|
220
|
+
task=task,
|
|
221
|
+
judgments_format=judgments_format,
|
|
222
|
+
bigquery_destination_prefix=bigquery_destination_prefix,
|
|
223
|
+
experimental_args=experimental_args,
|
|
224
|
+
).set_display_name('AutoSxS Arbiter')
|
|
225
|
+
|
|
226
|
+
has_human_preference = function_based.get_usage_metric(
|
|
227
|
+
metadata=prediction_inputs_a.outputs['metadata'],
|
|
228
|
+
key='has_human_preference_column',
|
|
229
|
+
).set_display_name('Read has_human_preference_column')
|
|
230
|
+
|
|
231
|
+
autosxs_metrics_computer.autosxs_metrics_computer(
|
|
232
|
+
judgments_dir=autosxs_arbiter_task.outputs['judgments_uri'],
|
|
233
|
+
has_human_preference=has_human_preference.output,
|
|
234
|
+
).set_display_name('AutoSxS Metrics')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: google-cloud-pipeline-components
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: This SDK enables a set of First Party (Google owned) pipeline components that allow users to take their experience from Vertex AI SDK and other Google Cloud services and create a corresponding pipeline using KFP or Managed Pipelines.
|
|
5
5
|
Home-page: https://github.com/kubeflow/pipelines/tree/master/components/google-cloud
|
|
6
6
|
Author: The Google Cloud Pipeline Components authors
|