google-cloud-pipeline-components 2.10.0__py3-none-any.whl → 2.12.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.
Potentially problematic release.
This version of google-cloud-pipeline-components might be problematic. Click here for more details.
- google_cloud_pipeline_components/_implementation/llm/batch_prediction_pairwise.py +14 -4
- google_cloud_pipeline_components/_implementation/llm/bulk_inferrer.py +7 -0
- google_cloud_pipeline_components/_implementation/llm/deployment_graph.py +6 -1
- google_cloud_pipeline_components/_implementation/llm/function_based.py +74 -168
- google_cloud_pipeline_components/_implementation/llm/generated/refined_image_versions.py +1 -1
- google_cloud_pipeline_components/_implementation/llm/model_evaluation_text_generation_pairwise.py +45 -3
- google_cloud_pipeline_components/_implementation/llm/online_evaluation_pairwise.py +14 -2
- google_cloud_pipeline_components/_implementation/llm/private_text_comparison_importer.py +9 -2
- google_cloud_pipeline_components/_implementation/llm/private_text_importer.py +8 -1
- google_cloud_pipeline_components/_implementation/llm/reinforcement_learning_graph.py +14 -28
- google_cloud_pipeline_components/_implementation/llm/reinforcer.py +13 -0
- google_cloud_pipeline_components/_implementation/llm/reward_model_graph.py +36 -27
- google_cloud_pipeline_components/_implementation/llm/reward_model_trainer.py +17 -0
- google_cloud_pipeline_components/_implementation/llm/rlhf_preprocessor.py +60 -0
- google_cloud_pipeline_components/_implementation/llm/supervised_fine_tuner.py +1 -0
- google_cloud_pipeline_components/_implementation/llm/utils.py +25 -2
- google_cloud_pipeline_components/_implementation/llm/validate_pipeline.py +113 -0
- google_cloud_pipeline_components/_implementation/model_evaluation/__init__.py +2 -0
- google_cloud_pipeline_components/_implementation/model_evaluation/endpoint_batch_predict/component.py +1 -1
- google_cloud_pipeline_components/_implementation/model_evaluation/llm_evaluation/component.py +2 -2
- google_cloud_pipeline_components/_implementation/model_evaluation/llm_evaluation_preprocessor/component.py +2 -2
- google_cloud_pipeline_components/_implementation/model_evaluation/model_name_preprocessor/__init__.py +14 -0
- google_cloud_pipeline_components/_implementation/model_evaluation/model_name_preprocessor/component.py +74 -0
- google_cloud_pipeline_components/_implementation/model_evaluation/version.py +1 -1
- google_cloud_pipeline_components/container/_implementation/model_evaluation/import_model_evaluation.py +7 -7
- google_cloud_pipeline_components/preview/llm/infer/__init__.py +13 -0
- google_cloud_pipeline_components/preview/llm/infer/component.py +10 -10
- google_cloud_pipeline_components/preview/llm/rlaif/component.py +10 -3
- google_cloud_pipeline_components/preview/llm/rlhf/component.py +43 -22
- google_cloud_pipeline_components/preview/model_evaluation/__init__.py +2 -2
- google_cloud_pipeline_components/preview/model_evaluation/model_based_llm_evaluation/autosxs/autosxs_pipeline.py +45 -3
- google_cloud_pipeline_components/proto/preflight_validations_pb2.py +19 -30
- google_cloud_pipeline_components/v1/custom_job/utils.py +22 -22
- google_cloud_pipeline_components/v1/model/get_model/component.py +1 -1
- google_cloud_pipeline_components/v1/model_evaluation/__init__.py +4 -0
- google_cloud_pipeline_components/{preview → v1}/model_evaluation/evaluation_llm_classification_pipeline.py +14 -2
- google_cloud_pipeline_components/{preview → v1}/model_evaluation/evaluation_llm_text_generation_pipeline.py +29 -17
- google_cloud_pipeline_components/version.py +1 -1
- {google_cloud_pipeline_components-2.10.0.dist-info → google_cloud_pipeline_components-2.12.0.dist-info}/METADATA +1 -2
- {google_cloud_pipeline_components-2.10.0.dist-info → google_cloud_pipeline_components-2.12.0.dist-info}/RECORD +43 -39
- {google_cloud_pipeline_components-2.10.0.dist-info → google_cloud_pipeline_components-2.12.0.dist-info}/WHEEL +1 -1
- {google_cloud_pipeline_components-2.10.0.dist-info → google_cloud_pipeline_components-2.12.0.dist-info}/LICENSE +0 -0
- {google_cloud_pipeline_components-2.10.0.dist-info → google_cloud_pipeline_components-2.12.0.dist-info}/top_level.txt +0 -0
|
@@ -37,10 +37,11 @@ def private_text_importer(
|
|
|
37
37
|
imported_data_path: dsl.OutputPath(str), # pytype: disable=invalid-annotation
|
|
38
38
|
gcp_resources: dsl.OutputPath(str), # pytype: disable=invalid-annotation
|
|
39
39
|
instruction: str = '',
|
|
40
|
-
image_uri: str = utils.get_default_image_uri('
|
|
40
|
+
image_uri: str = utils.get_default_image_uri('refined_cpu', ''),
|
|
41
41
|
machine_type: str = 'e2-highmem-8',
|
|
42
42
|
output_split_name: str = 'all',
|
|
43
43
|
max_num_input_examples: Optional[int] = None,
|
|
44
|
+
encryption_spec_key_name: str = '',
|
|
44
45
|
) -> dsl.ContainerSpec: # pylint: disable=g-doc-args
|
|
45
46
|
"""Import a text dataset.
|
|
46
47
|
|
|
@@ -59,6 +60,10 @@ def private_text_importer(
|
|
|
59
60
|
output_split_name: The created seqio task has 1 split, its name is specified
|
|
60
61
|
by this argument.
|
|
61
62
|
max_num_input_examples: Maximum number of examples to import.
|
|
63
|
+
encryption_spec_key_name: Customer-managed encryption key. If this is set,
|
|
64
|
+
then all resources created by the CustomJob will be encrypted with the
|
|
65
|
+
provided encryption key. Note that this is not supported for TPU at the
|
|
66
|
+
moment.
|
|
62
67
|
|
|
63
68
|
Returns:
|
|
64
69
|
imported_data: Artifact representing the imported data and cached Tasks.
|
|
@@ -76,6 +81,7 @@ def private_text_importer(
|
|
|
76
81
|
machine_type=machine_type,
|
|
77
82
|
image_uri=_resolve_image(image_uri),
|
|
78
83
|
args=[
|
|
84
|
+
'--app_name=text_importer',
|
|
79
85
|
f'--input_text={input_text}',
|
|
80
86
|
f'--inputs_field_name={inputs_field_name}',
|
|
81
87
|
f'--targets_field_name={targets_field_name}',
|
|
@@ -88,6 +94,7 @@ def private_text_importer(
|
|
|
88
94
|
f'--max_num_input_examples={max_num_input_examples}',
|
|
89
95
|
'--executor_input={{$.json_escape[1]}}',
|
|
90
96
|
],
|
|
97
|
+
encryption_spec_key_name=encryption_spec_key_name,
|
|
91
98
|
),
|
|
92
99
|
gcp_resources=gcp_resources,
|
|
93
100
|
)
|
|
@@ -51,8 +51,10 @@ def pipeline(
|
|
|
51
51
|
kl_coeff: float = 0.1,
|
|
52
52
|
instruction: Optional[str] = None,
|
|
53
53
|
project: str = _placeholders.PROJECT_ID_PLACEHOLDER,
|
|
54
|
+
accelerator_type: str = 'GPU',
|
|
54
55
|
location: str = _placeholders.LOCATION_PLACEHOLDER,
|
|
55
|
-
tensorboard_resource_id:
|
|
56
|
+
tensorboard_resource_id: str = '',
|
|
57
|
+
encryption_spec_key_name: str = '',
|
|
56
58
|
) -> PipelineOutput:
|
|
57
59
|
# fmt: off
|
|
58
60
|
"""Trains a reward model.
|
|
@@ -72,8 +74,10 @@ def pipeline(
|
|
|
72
74
|
kl_coeff: Coefficient for KL penalty. This regularizes the policy model and penalizes if it diverges from its initial distribution. If set to 0, the reference language model is not loaded into memory. Default value is 0.1.
|
|
73
75
|
instruction: This field lets the model know what task it needs to perform. Base models have been trained over a large set of varied instructions. You can give a simple and intuitive description of the task and the model will follow it, e.g. "Classify this movie review as positive or negative" or "Translate this sentence to Danish". Do not specify this if your dataset already prepends the instruction to the inputs field.
|
|
74
76
|
project: Project used to run custom jobs. If not specified the project used to run the pipeline will be used.
|
|
75
|
-
|
|
77
|
+
accelerator_type: One of 'TPU' or 'GPU'. If 'TPU' is specified, tuning components run in europe-west4. Otherwise tuning components run in us-central1 on GPUs. Default is 'GPU'.
|
|
78
|
+
location: Location used to run non-tuning components, i.e. components that do not require accelerators. If not specified the location used to run the pipeline will be used.
|
|
76
79
|
tensorboard_resource_id: Optional tensorboard resource id in format `projects/{project_number}/locations/{location}/tensorboards/{tensorboard_id}`. If provided, tensorboard metrics will be uploaded to this location.
|
|
80
|
+
encryption_spec_key_name: Customer-managed encryption key. If this is set, then all resources created by the CustomJob will be encrypted with the provided encryption key. Note that this is not supported for TPU at the moment.
|
|
77
81
|
|
|
78
82
|
Returns:
|
|
79
83
|
output_model_path: Path to the trained model checkpoint.
|
|
@@ -82,17 +86,14 @@ def pipeline(
|
|
|
82
86
|
# fmt: on
|
|
83
87
|
prompt_column = 'input_text'
|
|
84
88
|
machine_spec = function_based.resolve_machine_spec(
|
|
85
|
-
|
|
89
|
+
accelerator_type=accelerator_type,
|
|
90
|
+
use_test_spec=env.get_use_test_machine_spec(),
|
|
86
91
|
).set_display_name('Resolve Machine Spec')
|
|
87
92
|
|
|
88
93
|
reference_model_metadata = function_based.resolve_reference_model_metadata(
|
|
89
94
|
large_model_reference=large_model_reference,
|
|
90
95
|
).set_display_name('Resolve Model Metadata')
|
|
91
96
|
|
|
92
|
-
prompt_dataset_image_uri = function_based.resolve_private_image_uri(
|
|
93
|
-
image_name='text_importer'
|
|
94
|
-
).set_display_name('Resolve Prompt Dataset Image URI')
|
|
95
|
-
|
|
96
97
|
processed_dataset = preprocess_chat_dataset.preprocess_chat_dataset(
|
|
97
98
|
large_model_reference=large_model_reference,
|
|
98
99
|
input_dataset_uri=prompt_dataset,
|
|
@@ -111,16 +112,14 @@ def pipeline(
|
|
|
111
112
|
large_model_reference=reference_model_metadata.outputs[
|
|
112
113
|
'large_model_reference'
|
|
113
114
|
],
|
|
114
|
-
image_uri=prompt_dataset_image_uri.output,
|
|
115
115
|
instruction=instruction,
|
|
116
|
+
encryption_spec_key_name=encryption_spec_key_name,
|
|
116
117
|
)
|
|
117
118
|
.set_display_name('Import Prompt Dataset')
|
|
118
119
|
.set_caching_options(False)
|
|
119
120
|
)
|
|
120
|
-
rl_image_uri = function_based.
|
|
121
|
-
image_name='reinforcer',
|
|
121
|
+
rl_image_uri = function_based.resolve_private_refined_image_uri(
|
|
122
122
|
accelerator_type=machine_spec.outputs['accelerator_type'],
|
|
123
|
-
accelerator_count=machine_spec.outputs['accelerator_count'],
|
|
124
123
|
).set_display_name('Resolve Reinforcer Image URI')
|
|
125
124
|
num_microbatches = function_based.resolve_num_microbatches(
|
|
126
125
|
large_model_reference=reference_model_metadata.outputs[
|
|
@@ -130,7 +129,7 @@ def pipeline(
|
|
|
130
129
|
rl_model = (
|
|
131
130
|
reinforcer.reinforcer(
|
|
132
131
|
project=project,
|
|
133
|
-
location=
|
|
132
|
+
location=machine_spec.outputs['tuning_location'],
|
|
134
133
|
input_reference_model_path=reference_model_metadata.outputs[
|
|
135
134
|
'reference_model_path'
|
|
136
135
|
],
|
|
@@ -159,26 +158,13 @@ def pipeline(
|
|
|
159
158
|
lora_dim=lora_dim,
|
|
160
159
|
reward_lora_dim=reward_lora_dim,
|
|
161
160
|
num_microbatches=num_microbatches.output,
|
|
161
|
+
encryption_spec_key_name=encryption_spec_key_name,
|
|
162
|
+
tensorboard_resource_id=tensorboard_resource_id,
|
|
162
163
|
)
|
|
163
164
|
.set_display_name('Reinforcer')
|
|
164
165
|
.set_caching_options(False)
|
|
165
166
|
)
|
|
166
|
-
|
|
167
|
-
value=tensorboard_resource_id
|
|
168
|
-
).set_display_name('Resolve Tensorboard Resource ID')
|
|
169
|
-
with kfp.dsl.Condition( # pytype: disable=wrong-arg-types
|
|
170
|
-
has_tensorboard_id.output == True, # pylint: disable=singleton-comparison, g-explicit-bool-comparison
|
|
171
|
-
name='Upload Reinforcement Learning Tensorboard Metrics',
|
|
172
|
-
):
|
|
173
|
-
_ = upload_tensorboard_metrics.upload_tensorboard_metrics(
|
|
174
|
-
tensorboard_resource_id=tensorboard_resource_id,
|
|
175
|
-
metrics_directory=rl_model.outputs['tensorboard_metrics'],
|
|
176
|
-
experiment_name=(
|
|
177
|
-
'rl-model-tuner-'
|
|
178
|
-
f'{kfp.dsl.PIPELINE_JOB_ID_PLACEHOLDER}-'
|
|
179
|
-
f'{kfp.dsl.PIPELINE_TASK_ID_PLACEHOLDER}'
|
|
180
|
-
),
|
|
181
|
-
).set_display_name('Reinforcement Learning Tensorboard Metrics Uploader')
|
|
167
|
+
|
|
182
168
|
return PipelineOutput(
|
|
183
169
|
output_model_path=rl_model.outputs['output_model_path'],
|
|
184
170
|
output_adapter_path=rl_model.outputs['output_adapter_path'],
|
|
@@ -47,6 +47,8 @@ def reinforcer(
|
|
|
47
47
|
lora_dim: int = 0,
|
|
48
48
|
reward_lora_dim: int = 4,
|
|
49
49
|
num_microbatches: int = 0,
|
|
50
|
+
encryption_spec_key_name: str = '',
|
|
51
|
+
tensorboard_resource_id: str = '',
|
|
50
52
|
) -> kfp.dsl.ContainerSpec: # pylint: disable=g-doc-args
|
|
51
53
|
"""Trains a model using reinforcement learning.
|
|
52
54
|
|
|
@@ -86,6 +88,13 @@ def reinforcer(
|
|
|
86
88
|
num_microbatches: Number of microbatches to break the total batch size into
|
|
87
89
|
during training. If <= 1, the model is trained on the full batch size
|
|
88
90
|
directly.
|
|
91
|
+
encryption_spec_key_name: Customer-managed encryption key. If this is set,
|
|
92
|
+
then all resources created by the CustomJob will be encrypted with the
|
|
93
|
+
provided encryption key. Note that this is not supported for TPU at the
|
|
94
|
+
moment.
|
|
95
|
+
tensorboard_resource_id: Optional tensorboard resource id. Format:
|
|
96
|
+
`projects/{project_number}/locations/{location}/tensorboards/{tensorboard_id}`.
|
|
97
|
+
If provided, tensorboard metrics will be uploaded to this location.
|
|
89
98
|
|
|
90
99
|
Returns:
|
|
91
100
|
output_model_path: Path to the trained model checkpoint.
|
|
@@ -105,6 +114,7 @@ def reinforcer(
|
|
|
105
114
|
machine_type=machine_type,
|
|
106
115
|
image_uri=image_uri,
|
|
107
116
|
args=[
|
|
117
|
+
'--app_name=reinforcer',
|
|
108
118
|
f'--input_reference_model_path={input_reference_model_path}',
|
|
109
119
|
f'--input_reward_model_path={input_reward_model_path}',
|
|
110
120
|
f'--input_reward_adapter_path={input_reward_adapter_path}',
|
|
@@ -126,6 +136,9 @@ def reinforcer(
|
|
|
126
136
|
f'--reward_lora_dim={reward_lora_dim}',
|
|
127
137
|
f'--num_microbatches={num_microbatches}',
|
|
128
138
|
],
|
|
139
|
+
encryption_spec_key_name=encryption_spec_key_name,
|
|
140
|
+
base_output_directory=tensorboard_metrics.uri,
|
|
141
|
+
tensorboard=tensorboard_resource_id,
|
|
129
142
|
),
|
|
130
143
|
gcp_resources=gcp_resources,
|
|
131
144
|
)
|
|
@@ -45,10 +45,13 @@ def pipeline(
|
|
|
45
45
|
lora_dim: int = 4,
|
|
46
46
|
reward_model_learning_rate_multiplier: float = 1.0,
|
|
47
47
|
reward_model_train_steps: int = 1000,
|
|
48
|
+
eval_dataset: Optional[str] = None,
|
|
48
49
|
instruction: Optional[str] = None,
|
|
49
50
|
project: str = _placeholders.PROJECT_ID_PLACEHOLDER,
|
|
51
|
+
accelerator_type: str = 'GPU',
|
|
50
52
|
location: str = _placeholders.LOCATION_PLACEHOLDER,
|
|
51
|
-
tensorboard_resource_id:
|
|
53
|
+
tensorboard_resource_id: str = '',
|
|
54
|
+
encryption_spec_key_name: str = '',
|
|
52
55
|
) -> PipelineOutput:
|
|
53
56
|
# fmt: off
|
|
54
57
|
"""Trains a reward model.
|
|
@@ -64,8 +67,10 @@ def pipeline(
|
|
|
64
67
|
reward_model_train_steps: Number of steps to use when training a reward model. Default value is 1000.
|
|
65
68
|
instruction: This field lets the model know what task it needs to perform. Base models have been trained over a large set of varied instructions. You can give a simple and intuitive description of the task and the model will follow it, e.g. "Classify this movie review as positive or negative" or "Translate this sentence to Danish". Do not specify this if your dataset already prepends the instruction to the inputs field.
|
|
66
69
|
project: Project used to run custom jobs. If not specified the project used to run the pipeline will be used.
|
|
67
|
-
|
|
70
|
+
accelerator_type: One of 'TPU' or 'GPU'. If 'TPU' is specified, tuning components run in europe-west4. Otherwise tuning components run in us-central1 on GPUs. Default is 'GPU'.
|
|
71
|
+
location: Location used to run non-tuning components, i.e. components that do not require accelerators. If not specified the location used to run the pipeline will be used.
|
|
68
72
|
tensorboard_resource_id: Optional tensorboard resource id in format `projects/{project_number}/locations/{location}/tensorboards/{tensorboard_id}`. If provided, tensorboard metrics will be uploaded to this location.
|
|
73
|
+
encryption_spec_key_name: Customer-managed encryption key. If this is set, then all resources created by the CustomJob will be encrypted with the provided encryption key. Note that this is not supported for TPU at the moment.
|
|
69
74
|
|
|
70
75
|
Returns:
|
|
71
76
|
reward_model_base_path: Path to the base model used by the reward model.
|
|
@@ -77,7 +82,8 @@ def pipeline(
|
|
|
77
82
|
candidate_columns = ['candidate_0', 'candidate_1']
|
|
78
83
|
choice_column = 'choice'
|
|
79
84
|
machine_spec = function_based.resolve_machine_spec(
|
|
80
|
-
|
|
85
|
+
accelerator_type=accelerator_type,
|
|
86
|
+
use_test_spec=env.get_use_test_machine_spec(),
|
|
81
87
|
).set_display_name('Resolve Machine Spec')
|
|
82
88
|
|
|
83
89
|
reference_model_metadata = function_based.resolve_reference_model_metadata(
|
|
@@ -93,9 +99,6 @@ def pipeline(
|
|
|
93
99
|
).set_display_name('Preprocess Prompt Dataset')
|
|
94
100
|
)
|
|
95
101
|
|
|
96
|
-
preference_dataset_image_uri = function_based.resolve_private_image_uri(
|
|
97
|
-
image_name='text_comparison_importer'
|
|
98
|
-
).set_display_name('Resolve Preference Dataset Image URI')
|
|
99
102
|
comma_separated_candidates_field_names = (
|
|
100
103
|
function_based.convert_to_delimited_string(items=candidate_columns)
|
|
101
104
|
)
|
|
@@ -113,17 +116,34 @@ def pipeline(
|
|
|
113
116
|
large_model_reference=reference_model_metadata.outputs[
|
|
114
117
|
'reward_model_reference'
|
|
115
118
|
],
|
|
116
|
-
image_uri=preference_dataset_image_uri.output,
|
|
117
119
|
instruction=instruction,
|
|
120
|
+
encryption_spec_key_name=encryption_spec_key_name,
|
|
118
121
|
)
|
|
119
122
|
.set_display_name('Import Preference Dataset')
|
|
120
123
|
.set_caching_options(False)
|
|
121
124
|
)
|
|
122
125
|
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
preference_eval_dataset_importer = (
|
|
127
|
+
private_text_comparison_importer.private_text_comparison_importer(
|
|
128
|
+
project=project,
|
|
129
|
+
location=location,
|
|
130
|
+
input_text=eval_dataset,
|
|
131
|
+
inputs_field_name=prompt_column,
|
|
132
|
+
comma_separated_candidates_field_names=comma_separated_candidates_field_names.output,
|
|
133
|
+
choice_field_name=choice_column,
|
|
134
|
+
split=env.TRAIN_SPLIT,
|
|
135
|
+
large_model_reference=reference_model_metadata.outputs[
|
|
136
|
+
'reward_model_reference'
|
|
137
|
+
],
|
|
138
|
+
instruction=instruction,
|
|
139
|
+
encryption_spec_key_name=encryption_spec_key_name,
|
|
140
|
+
)
|
|
141
|
+
.set_display_name('Import Preference Eval Dataset')
|
|
142
|
+
.set_caching_options(False)
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
reward_model_image_uri = function_based.resolve_private_refined_image_uri(
|
|
125
146
|
accelerator_type=machine_spec.outputs['accelerator_type'],
|
|
126
|
-
accelerator_count=machine_spec.outputs['accelerator_count'],
|
|
127
147
|
).set_display_name('Resolve Reward Model Image URI')
|
|
128
148
|
num_microbatches = function_based.resolve_num_microbatches(
|
|
129
149
|
large_model_reference=reference_model_metadata.outputs[
|
|
@@ -133,13 +153,16 @@ def pipeline(
|
|
|
133
153
|
reward_model = (
|
|
134
154
|
reward_model_trainer.reward_model_trainer(
|
|
135
155
|
project=project,
|
|
136
|
-
location=
|
|
156
|
+
location=machine_spec.outputs['tuning_location'],
|
|
137
157
|
input_model_path=reference_model_metadata.outputs[
|
|
138
158
|
'reward_model_path'
|
|
139
159
|
],
|
|
140
160
|
input_dataset_path=preference_dataset_importer.outputs[
|
|
141
161
|
'output_dataset_path'
|
|
142
162
|
],
|
|
163
|
+
eval_dataset_path=preference_eval_dataset_importer.outputs[
|
|
164
|
+
'output_dataset_path'
|
|
165
|
+
],
|
|
143
166
|
train_steps=reward_model_train_steps,
|
|
144
167
|
accelerator_type=machine_spec.outputs['accelerator_type'],
|
|
145
168
|
accelerator_count=machine_spec.outputs['accelerator_count'],
|
|
@@ -154,27 +177,13 @@ def pipeline(
|
|
|
154
177
|
learning_rate_multiplier=reward_model_learning_rate_multiplier,
|
|
155
178
|
lora_dim=lora_dim,
|
|
156
179
|
num_microbatches=num_microbatches.output,
|
|
180
|
+
encryption_spec_key_name=encryption_spec_key_name,
|
|
181
|
+
tensorboard_resource_id=tensorboard_resource_id,
|
|
157
182
|
)
|
|
158
183
|
.set_display_name('Reward Model Trainer')
|
|
159
184
|
.set_caching_options(False)
|
|
160
185
|
)
|
|
161
186
|
|
|
162
|
-
has_tensorboard_id = function_based.value_exists(
|
|
163
|
-
value=tensorboard_resource_id
|
|
164
|
-
).set_display_name('Resolve TensorBoard Resource ID')
|
|
165
|
-
with kfp.dsl.Condition( # pytype: disable=wrong-arg-types
|
|
166
|
-
has_tensorboard_id.output == True, # pylint: disable=singleton-comparison, g-explicit-bool-comparison
|
|
167
|
-
name='Upload Reward Model TensorBoard Metrics',
|
|
168
|
-
):
|
|
169
|
-
_ = upload_tensorboard_metrics.upload_tensorboard_metrics(
|
|
170
|
-
tensorboard_resource_id=tensorboard_resource_id,
|
|
171
|
-
metrics_directory=reward_model.outputs['tensorboard_metrics'],
|
|
172
|
-
experiment_name=(
|
|
173
|
-
'reward-model-tuner-'
|
|
174
|
-
f'{kfp.dsl.PIPELINE_JOB_ID_PLACEHOLDER}-'
|
|
175
|
-
f'{kfp.dsl.PIPELINE_TASK_ID_PLACEHOLDER}'
|
|
176
|
-
),
|
|
177
|
-
).set_display_name('Reward Model TensorBoard Metrics Uploader')
|
|
178
187
|
return PipelineOutput(
|
|
179
188
|
reward_model_base_path=reference_model_metadata.outputs[
|
|
180
189
|
'reward_model_path'
|
|
@@ -35,11 +35,14 @@ def reward_model_trainer(
|
|
|
35
35
|
output_adapter_path: kfp.dsl.OutputPath(str), # pytype: disable=invalid-annotation
|
|
36
36
|
tensorboard_metrics: kfp.dsl.Output[kfp.dsl.Artifact], # pytype: disable=unsupported-operands
|
|
37
37
|
gcp_resources: kfp.dsl.OutputPath(str), # pytype: disable=invalid-annotation
|
|
38
|
+
eval_dataset_path: str = '',
|
|
38
39
|
train_split: str = 'train',
|
|
39
40
|
batch_size: int = 64,
|
|
40
41
|
learning_rate_multiplier: float = 1.0,
|
|
41
42
|
lora_dim: int = 4,
|
|
42
43
|
num_microbatches: int = 0,
|
|
44
|
+
encryption_spec_key_name: str = '',
|
|
45
|
+
tensorboard_resource_id: str = '',
|
|
43
46
|
) -> kfp.dsl.ContainerSpec: # pylint: disable=g-doc-args
|
|
44
47
|
"""Trains a reward model.
|
|
45
48
|
|
|
@@ -48,6 +51,8 @@ def reward_model_trainer(
|
|
|
48
51
|
location: Location used to run the job.
|
|
49
52
|
input_model_path: Path to the base model to fine tune.
|
|
50
53
|
input_dataset_path: Path to dataset to use to train a reward model.
|
|
54
|
+
eval_dataset_path: Path to eval dataset to use during the reward model
|
|
55
|
+
training.
|
|
51
56
|
train_steps: Number of training steps. These are the number of steps on top
|
|
52
57
|
of any steps used to train the base model.
|
|
53
58
|
accelerator_type: Type of TPU accelerator. Can be either TPU_V2 or TPU_V3.
|
|
@@ -68,6 +73,13 @@ def reward_model_trainer(
|
|
|
68
73
|
num_microbatches: Number of microbatches to break the total batch size into
|
|
69
74
|
during training. If <= 1, the model is trained on the full batch size
|
|
70
75
|
directly.
|
|
76
|
+
encryption_spec_key_name: Customer-managed encryption key. If this is set,
|
|
77
|
+
then all resources created by the CustomJob will be encrypted with the
|
|
78
|
+
provided encryption key. Note that this is not supported for TPU at the
|
|
79
|
+
moment.
|
|
80
|
+
tensorboard_resource_id: Optional tensorboard resource id. Format:
|
|
81
|
+
`projects/{project_number}/locations/{location}/tensorboards/{tensorboard_id}`.
|
|
82
|
+
If provided, tensorboard metrics will be uploaded to this location.
|
|
71
83
|
|
|
72
84
|
Returns:
|
|
73
85
|
output_adapter_path: Trained reward LoRA adapter.
|
|
@@ -85,9 +97,11 @@ def reward_model_trainer(
|
|
|
85
97
|
machine_type=machine_type,
|
|
86
98
|
image_uri=image_uri,
|
|
87
99
|
args=[
|
|
100
|
+
'--app_name=reward_model_trainer',
|
|
88
101
|
f'--train_steps={train_steps}',
|
|
89
102
|
f'--input_model_path={input_model_path}',
|
|
90
103
|
f'--input_dataset_path={input_dataset_path}',
|
|
104
|
+
f'--eval_dataset_path={eval_dataset_path}',
|
|
91
105
|
f'--output_adapter_path={output_adapter_path}',
|
|
92
106
|
f'--tensorboard_metrics_path={tensorboard_metrics.path}',
|
|
93
107
|
f'--large_model_reference={large_model_reference}',
|
|
@@ -99,6 +113,9 @@ def reward_model_trainer(
|
|
|
99
113
|
f'--lora_dim={lora_dim}',
|
|
100
114
|
f'--num_microbatches={num_microbatches}',
|
|
101
115
|
],
|
|
116
|
+
encryption_spec_key_name=encryption_spec_key_name,
|
|
117
|
+
base_output_directory=tensorboard_metrics.uri,
|
|
118
|
+
tensorboard=tensorboard_resource_id,
|
|
102
119
|
),
|
|
103
120
|
gcp_resources=gcp_resources,
|
|
104
121
|
)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Copyright 2024 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
|
+
"""Component that preprocesses inputs for Reinforcement Learning from Human Feedback (RLHF)."""
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
|
|
18
|
+
from google_cloud_pipeline_components import _placeholders
|
|
19
|
+
from google_cloud_pipeline_components import utils as gcpc_utils
|
|
20
|
+
from google_cloud_pipeline_components._implementation.llm import utils
|
|
21
|
+
from kfp import dsl
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dsl.container_component
|
|
25
|
+
def rlhf_preprocessor(
|
|
26
|
+
gcp_resources: dsl.OutputPath(str), # pytype: disable=invalid-annotation
|
|
27
|
+
has_tensorboard_id: dsl.OutputPath(bool), # pytype: disable=invalid-annotation
|
|
28
|
+
has_inference_dataset: dsl.OutputPath(bool), # pytype: disable=invalid-annotation
|
|
29
|
+
evaluation_dataset: str = '',
|
|
30
|
+
tensorboard_resource_id: str = '',
|
|
31
|
+
image_uri: str = utils.get_default_image_uri('refined_cpu', ''),
|
|
32
|
+
) -> dsl.ContainerSpec: # pylint: disable=g-doc-args
|
|
33
|
+
"""Preprocess RLHF pipeline inputs.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
evaluation_dataset: Path to evaluation data.
|
|
37
|
+
tensorboard_resource_id: TensorBoard resource id.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
gcp_resources: GCP resources that can be used to track the custom job.
|
|
41
|
+
has_tensorboard_id: Whether a tensorboard id is provided.
|
|
42
|
+
has_inference_dataset: Whether inference data are provided.
|
|
43
|
+
"""
|
|
44
|
+
return gcpc_utils.build_serverless_customjob_container_spec(
|
|
45
|
+
project=_placeholders.PROJECT_ID_PLACEHOLDER,
|
|
46
|
+
location=_placeholders.LOCATION_PLACEHOLDER,
|
|
47
|
+
custom_job_payload=utils.build_payload(
|
|
48
|
+
display_name='rlhf_preprocessor',
|
|
49
|
+
machine_type='n1-standard-4',
|
|
50
|
+
image_uri=image_uri,
|
|
51
|
+
args=[
|
|
52
|
+
'--app_name=rlhf_preprocessor',
|
|
53
|
+
f'--evaluation_dataset={evaluation_dataset}',
|
|
54
|
+
f'--tensorboard_resource_id={tensorboard_resource_id}',
|
|
55
|
+
f'--has_tensorboard_id_path={has_tensorboard_id}',
|
|
56
|
+
f'--has_inference_dataset_path={has_inference_dataset}',
|
|
57
|
+
],
|
|
58
|
+
),
|
|
59
|
+
gcp_resources=gcp_resources,
|
|
60
|
+
)
|
|
@@ -86,6 +86,7 @@ def supervised_fine_tuner(
|
|
|
86
86
|
machine_type=machine_type,
|
|
87
87
|
image_uri=image_uri,
|
|
88
88
|
args=[
|
|
89
|
+
'--app_name=supervised_fine_tuner',
|
|
89
90
|
f'--input_model_path={input_model_path}',
|
|
90
91
|
f'--train_steps={train_steps}',
|
|
91
92
|
f'--inputs_sequence_length={inputs_sequence_length}',
|
|
@@ -30,6 +30,8 @@ def build_payload(
|
|
|
30
30
|
encryption_spec_key_name: str = '',
|
|
31
31
|
labels: Optional[Dict[str, str]] = None,
|
|
32
32
|
scheduling: Optional[Dict[str, Any]] = None,
|
|
33
|
+
base_output_directory: Optional[str] = None,
|
|
34
|
+
tensorboard: Optional[str] = None,
|
|
33
35
|
) -> Dict[str, Any]:
|
|
34
36
|
"""Generates payload for a custom training job.
|
|
35
37
|
|
|
@@ -50,6 +52,11 @@ def build_payload(
|
|
|
50
52
|
moment.
|
|
51
53
|
labels: The labels with user-defined metadata to organize CustomJobs.
|
|
52
54
|
scheduling: Scheduling options for a CustomJob.
|
|
55
|
+
base_output_directory: Cloud Storage location to store the output of this
|
|
56
|
+
CustomJob
|
|
57
|
+
tensorboard: The name of a Vertex AI TensorBoard resource to which this
|
|
58
|
+
CustomJob will upload TensorBoard logs. Format:
|
|
59
|
+
``projects/{project}/locations/{location}/tensorboards/{tensorboard}``
|
|
53
60
|
|
|
54
61
|
Returns:
|
|
55
62
|
Custom job payload.
|
|
@@ -96,6 +103,14 @@ def build_payload(
|
|
|
96
103
|
if scheduling:
|
|
97
104
|
payload['job_spec']['scheduling'] = scheduling
|
|
98
105
|
|
|
106
|
+
if base_output_directory:
|
|
107
|
+
payload['job_spec']['base_output_directory'] = {
|
|
108
|
+
'output_uri_prefix': base_output_directory
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if tensorboard:
|
|
112
|
+
payload['job_spec']['tensorboard'] = tensorboard
|
|
113
|
+
|
|
99
114
|
return payload
|
|
100
115
|
|
|
101
116
|
|
|
@@ -109,7 +124,10 @@ def get_temp_location() -> str:
|
|
|
109
124
|
)
|
|
110
125
|
|
|
111
126
|
|
|
112
|
-
def get_default_image_uri(
|
|
127
|
+
def get_default_image_uri(
|
|
128
|
+
image_name: str,
|
|
129
|
+
image_name_prefix: Optional[str] = None,
|
|
130
|
+
) -> str:
|
|
113
131
|
"""Gets the default image URI for a given image.
|
|
114
132
|
|
|
115
133
|
The URI is resolved using environment variables that define the artifact
|
|
@@ -119,6 +137,8 @@ def get_default_image_uri(image_name: str) -> str:
|
|
|
119
137
|
|
|
120
138
|
Args:
|
|
121
139
|
image_name: Name of the image to resolve.
|
|
140
|
+
image_name_prefix: prefix to add to the image name when constructing the
|
|
141
|
+
URI. If `None`, `env.PRIVATE_IMAGE_NAME_PREFIX'` is used.
|
|
122
142
|
|
|
123
143
|
Returns:
|
|
124
144
|
URI of the image.
|
|
@@ -128,9 +148,12 @@ def get_default_image_uri(image_name: str) -> str:
|
|
|
128
148
|
else:
|
|
129
149
|
image_tag = env.get_private_image_tag()
|
|
130
150
|
|
|
151
|
+
if image_name_prefix is None:
|
|
152
|
+
image_name_prefix = env.PRIVATE_IMAGE_NAME_PREFIX
|
|
153
|
+
|
|
131
154
|
return '/'.join([
|
|
132
155
|
f'{env.PRIVATE_ARTIFACT_REGISTRY_LOCATION}-docker.pkg.dev',
|
|
133
156
|
env.PRIVATE_ARTIFACT_REGISTRY_PROJECT,
|
|
134
157
|
env.PRIVATE_ARTIFACT_REGISTRY,
|
|
135
|
-
f'{
|
|
158
|
+
f'{image_name_prefix}{image_name}:{image_tag}',
|
|
136
159
|
])
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Copyright 2024 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
|
+
"""KFP Component for validate_pipeline."""
|
|
15
|
+
|
|
16
|
+
from typing import NamedTuple, Optional
|
|
17
|
+
|
|
18
|
+
from google_cloud_pipeline_components import _image
|
|
19
|
+
from google_cloud_pipeline_components import _placeholders
|
|
20
|
+
from kfp import dsl
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dsl.component(base_image=_image.GCPC_IMAGE_TAG, install_kfp_package=False)
|
|
24
|
+
def validate_pipeline(
|
|
25
|
+
location: str,
|
|
26
|
+
encryption_spec_key_name: str = '',
|
|
27
|
+
accelerator_type: str = '',
|
|
28
|
+
eval_dataset: Optional[str] = None,
|
|
29
|
+
) -> NamedTuple('PreprocessedInputs', reward_model_eval_dataset=str):
|
|
30
|
+
# fmt: off
|
|
31
|
+
"""Validates and preprocesses RLHF pipeline parameters.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
location: Location used to run non-tuning components, i.e. components
|
|
35
|
+
that do not require accelerators. If not specified the location used
|
|
36
|
+
to run the pipeline will be used.
|
|
37
|
+
encryption_spec_key_name: If set, CMEK support will be validated.
|
|
38
|
+
accelerator_type: One of 'TPU' or 'GPU'. If 'TPU' is specified, tuning
|
|
39
|
+
components run in europe-west4. Otherwise tuning components run in
|
|
40
|
+
us-central1 on GPUs. Default is 'GPU'.
|
|
41
|
+
eval_dataset: Optional Cloud storage path to an evaluation dataset. The
|
|
42
|
+
format should match that of the preference dataset.
|
|
43
|
+
"""
|
|
44
|
+
# fmt: on
|
|
45
|
+
# pylint: disable=g-import-not-at-top,import-outside-toplevel
|
|
46
|
+
import json
|
|
47
|
+
import logging
|
|
48
|
+
import re
|
|
49
|
+
import sys
|
|
50
|
+
import glob
|
|
51
|
+
# pylint: enable=g-import-not-at-top,import-outside-toplevel
|
|
52
|
+
outputs = NamedTuple(
|
|
53
|
+
'PreprocessedInputs',
|
|
54
|
+
reward_model_eval_dataset=str,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
# [ Set eval_dataset
|
|
59
|
+
eval_dataset = eval_dataset or ''
|
|
60
|
+
gcs_eval_dataset_uri = re.sub('^gs://', '/gcs/', eval_dataset)
|
|
61
|
+
files_in_folder = glob.glob(gcs_eval_dataset_uri)
|
|
62
|
+
if not files_in_folder:
|
|
63
|
+
eval_dataset = ''
|
|
64
|
+
else:
|
|
65
|
+
first_file = files_in_folder[0]
|
|
66
|
+
required_fields = ('candidate_0', 'candidate_1', 'choice')
|
|
67
|
+
oneof_fields = {'input_text', 'messages'}
|
|
68
|
+
max_lines_to_check = 100
|
|
69
|
+
with open(first_file, 'r') as inputs:
|
|
70
|
+
for i, line in enumerate(inputs):
|
|
71
|
+
json_data = json.loads(line)
|
|
72
|
+
is_valid_preference_data = all(
|
|
73
|
+
field in json_data for field in required_fields
|
|
74
|
+
) and any(oneof_field in json_data for oneof_field in oneof_fields)
|
|
75
|
+
if not is_valid_preference_data:
|
|
76
|
+
eval_dataset = ''
|
|
77
|
+
if not eval_dataset or i >= max_lines_to_check:
|
|
78
|
+
break
|
|
79
|
+
# ]
|
|
80
|
+
# [ Check CMEK
|
|
81
|
+
supported_pipeline_regions = {
|
|
82
|
+
'europe-west4',
|
|
83
|
+
'us-central1',
|
|
84
|
+
}
|
|
85
|
+
if location not in supported_pipeline_regions:
|
|
86
|
+
raise ValueError(
|
|
87
|
+
f'Unsupported pipeline region: {location}. Must be one of'
|
|
88
|
+
f' {supported_pipeline_regions}.'
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
valid_cmek_accelerator_types = {
|
|
92
|
+
'GPU',
|
|
93
|
+
'CPU', # Only used for testing.
|
|
94
|
+
}
|
|
95
|
+
valid_cmek_config = (
|
|
96
|
+
location == 'us-central1'
|
|
97
|
+
and accelerator_type in valid_cmek_accelerator_types
|
|
98
|
+
)
|
|
99
|
+
if encryption_spec_key_name and not valid_cmek_config:
|
|
100
|
+
raise ValueError(
|
|
101
|
+
'encryption_spec_key_name (CMEK) is only supported for GPU training'
|
|
102
|
+
' in us-central1. Please either unset encryption_spec_key_name or'
|
|
103
|
+
' create your pipeline in us-central1 to use GPU instead.'
|
|
104
|
+
)
|
|
105
|
+
# CMEK ]
|
|
106
|
+
|
|
107
|
+
return outputs(reward_model_eval_dataset=eval_dataset)
|
|
108
|
+
|
|
109
|
+
except Exception as e: # pylint: disable=broad-exception-caught
|
|
110
|
+
if isinstance(e, ValueError):
|
|
111
|
+
raise
|
|
112
|
+
logging.exception(str(e))
|
|
113
|
+
sys.exit(13)
|
|
@@ -37,6 +37,7 @@ from google_cloud_pipeline_components._implementation.model_evaluation.llm_safet
|
|
|
37
37
|
from google_cloud_pipeline_components._implementation.model_evaluation.llm_safety_bias.evaluation_llm_safety_bias_pipeline import evaluation_llm_safety_bias_pipeline
|
|
38
38
|
from google_cloud_pipeline_components._implementation.model_evaluation.model_inference.component import model_inference_and_evaluation_component
|
|
39
39
|
from google_cloud_pipeline_components._implementation.model_evaluation.model_inference.component import model_inference_component
|
|
40
|
+
from google_cloud_pipeline_components._implementation.model_evaluation.model_name_preprocessor.component import model_name_preprocessor as ModelNamePreprocessorOp
|
|
40
41
|
from google_cloud_pipeline_components._implementation.model_evaluation.target_field_data_remover.component import target_field_data_remover as TargetFieldDataRemoverOp
|
|
41
42
|
from google_cloud_pipeline_components._implementation.model_evaluation.text2sql.evaluation_llm_text2sql_pipeline import evaluation_llm_text2sql_pipeline
|
|
42
43
|
|
|
@@ -63,6 +64,7 @@ __all__ = [
|
|
|
63
64
|
'ModelEvaluationFeatureAttributionOp',
|
|
64
65
|
'ModelImportEvaluatedAnnotationOp',
|
|
65
66
|
'ModelImportEvaluationOp',
|
|
67
|
+
'ModelNamePreprocessorOp',
|
|
66
68
|
'TargetFieldDataRemoverOp',
|
|
67
69
|
'model_inference_component',
|
|
68
70
|
'model_inference_and_evaluation_component',
|
|
@@ -24,7 +24,7 @@ from kfp.dsl import Output
|
|
|
24
24
|
from kfp.dsl import OutputPath
|
|
25
25
|
from kfp.dsl import PIPELINE_ROOT_PLACEHOLDER
|
|
26
26
|
|
|
27
|
-
_IMAGE_URI = 'us-docker.pkg.dev/vertex-evaluation/public/llm:
|
|
27
|
+
_IMAGE_URI = 'us-docker.pkg.dev/vertex-evaluation/public/llm:v0.5'
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
@dsl.component(base_image=version.LLM_EVAL_IMAGE_TAG)
|