# How to Perform Model Fine-Tuning in Google Agent Platform

> Learn how to fine-tune models in Google Agent Platform. This guide covers dataset prep job submission and lifecycle management with the Python SDK for custom LLM creation.

- Repository: [Google/skills](https://github.com/google/skills)
- Tags: how-to-guide
- Published: 2026-09-05

---

**Google Agent Platform enables custom LLM creation by fine-tuning base models on your data through a three-phase workflow: dataset preparation, job submission, and lifecycle management using the provided Python SDK scripts.**

Google Agent Platform (Vertex AI Agent Platform) allows developers to create specialized large language models by training foundation models on domain-specific datasets. The `google/skills` repository provides a complete toolkit of Python scripts that handle data conversion, job orchestration, and monitoring. This guide explains how to use these utilities to perform model fine-tuning safely and efficiently.

## Preparing and Validating Your Dataset

Before launching a tuning job, you must convert raw data into the specific JSONL format required by Vertex AI and ensure your validation split adheres to platform constraints.

### Converting CSV and Parquet to JSONL

The [[`prepare_dataset.py`](https://github.com/google/skills/blob/main/prepare_dataset.py)](https://github.com/google/skills/blob/main/skills/cloud/agent-platform-tuning/scripts/prepare_dataset.py) script handles ingestion of CSV, JSON, or Parquet files using the HuggingFace `datasets` library. It filters out empty or `NaN` rows, then transforms each record into either a **messages** format (`[{role:"user",content}, {role:"assistant",content}]`) or a **prompt/completion** pair.

The script uses `datasets.Dataset.map` for transformation and `datasets.Dataset.train_test_split` to create the training/validation division. It writes the final output to JSONL files compatible with `types.TuningDataset` and `types.TuningValidationDataset` expectations.

### Enforcing Validation Size Limits

Agent Platform rejects tuning jobs where the validation set exceeds approximately 25% of the training set size. The helper function `validation_ratio_error` in [`prepare_dataset.py`](https://github.com/google/skills/blob/main/prepare_dataset.py) checks this constraint before upload, preventing costly API rejections.

```bash
python -m skills.cloud.agent-platform-tuning.scripts.prepare_dataset \
  --input=my_data.csv \
  --output=tuning_dataset.jsonl \
  --format=messages \
  --prompt_col=question \
  --completion_col=answer \
  --validation_split=0.1

```

## Launching the Tuning Job

After uploading your JSONL files to Google Cloud Storage (GCS), you initiate fine-tuning using [[`tune_open_model.py`](https://github.com/google/skills/blob/main/tune_open_model.py)](https://github.com/google/skills/blob/main/skills/cloud/agent-platform-tuning/scripts/tune_open_model.py).

### Configuring Hyperparameters and Mode

The script constructs a `CreateTuningJobConfig` from the `google.genai.types` module, specifying:

- **Epochs**: Number of training iterations
- **Learning rate**: Optimization step size (e.g., `0.001`)
- **TuningMode**: Either `FULL` for full fine-tuning or `PEFT_ADAPTER` for parameter-efficient fine-tuning
- **Adapter size**: Required when using `PEFT_ADAPTER` mode (e.g., `4`)

The script invokes `genai.Client.tunings.tune()` with your base model identifier, GCS URIs for training and validation data, and the configuration object. This returns a `TuningJob` protocol buffer containing the job name for future reference.

```bash
python -m skills.cloud.agent-platform-tuning.scripts.tune_open_model \
  --project=my-gcp-project \
  --location=global \
  --base_model=chat-bison@001 \
  --train_dataset=gs://my-bucket/datasets/tuning_dataset.jsonl \
  --validation_dataset=gs://my-bucket/datasets/tuning_dataset_validation.jsonl \
  --output_uri=gs://my-bucket/tuning-output/ \
  --epochs=5 \
  --learning_rate=0.001 \
  --tuning_mode=PEFT_ADAPTER \
  --adapter_size=4

```

## Monitoring and Managing Tuning Jobs

Once submitted, jobs require active monitoring to track progress, manage costs, and handle potential cancellations.

### Checking Job Status

Use [[`monitor_tuning_job.py`](https://github.com/google/skills/blob/main/monitor_tuning_job.py)](https://github.com/google/skills/blob/main/skills/cloud/agent-platform-tuning/scripts/monitor_tuning_job.py) to poll the job state. The script calls `client.tunings.get(name=job_name)` to retrieve the `TuningJob` status and provides a direct console URL for detailed logs.

```bash
python -m skills.cloud.agent-platform-tuning.scripts.monitor_tuning_job \
  --project=my-gcp-project \
  --location=global \
  --job_id=JOB_ID

```

### Listing and Canceling Jobs

To enumerate all tuned models in a project, [[`list_models.py`](https://github.com/google/skills/blob/main/list_models.py)](https://github.com/google/skills/blob/main/skills/cloud/agent-platform-tuning/scripts/list_models.py) executes `client.tunings.list(project=..., location=...)`. If you need to stop an active job, [[`cancel_tuning_job.py`](https://github.com/google/skills/blob/main/cancel_tuning_job.py)](https://github.com/google/skills/blob/main/skills/cloud/agent-platform-tuning/scripts/cancel_tuning_job.py) invokes `client.tunings.cancel(name=...)`.

```bash

# List all models

python -m skills.cloud.agent-platform-tuning.scripts.list_models \
  --project=my-gcp-project \
  --location=global

# Cancel a specific job

python -m skills.cloud.agent-platform-tuning.scripts.cancel_tuning_job \
  --project=my-gcp-project \
  --location=global \
  --job_id=JOB_ID

```

### Estimating Storage Costs

The [[`calculate_cost.py`](https://github.com/google/skills/blob/main/calculate_cost.py)](https://github.com/google/skills/blob/main/skills/cloud/agent-platform-tuning/scripts/calculate_cost.py) script estimates expenses by reading the byte size of the job's `output_uri` in GCS and applying the per-GB pricing model.

```bash
python -m skills.cloud.agent-platform-tuning.scripts.calculate_cost \
  --project=my-gcp-project \
  --location=global \
  --output_uri=gs://my-bucket/tuning-output/

```

## Summary

- **Dataset preparation** requires converting source files to JSONL using [`prepare_dataset.py`](https://github.com/google/skills/blob/main/prepare_dataset.py), which validates that validation data does not exceed 25% of training data size.
- **Job creation** uses [`tune_open_model.py`](https://github.com/google/skills/blob/main/tune_open_model.py) to submit configurations via `CreateTuningJobConfig`, supporting both `FULL` and `PEFT_ADAPTER` tuning modes.
- **Lifecycle management** scripts ([`monitor_tuning_job.py`](https://github.com/google/skills/blob/main/monitor_tuning_job.py), [`list_models.py`](https://github.com/google/skills/blob/main/list_models.py), [`cancel_tuning_job.py`](https://github.com/google/skills/blob/main/cancel_tuning_job.py)) provide complete visibility and control over running jobs through the `client.tunings` API surface.
- All scripts utilize standard Google authentication via `genai.Client`, automatically detecting credentials from `GOOGLE_APPLICATION_CREDENTIALS` or Application Default Credentials.

## Frequently Asked Questions

### What data formats does Agent Platform support for fine-tuning?

Agent Platform requires JSONL (JSON Lines) format for both training and validation datasets. The [`prepare_dataset.py`](https://github.com/google/skills/blob/main/prepare_dataset.py) utility in the `google/skills` repository converts CSV, JSON, and Parquet files into the required schema, supporting either conversational "messages" format or simple "prompt/completion" pairs.

### What is the difference between FULL and PEFT_ADAPTER tuning modes?

`FULL` mode performs complete fine-tuning of all model parameters, while `PEFT_ADAPTER` (Parameter-Efficient Fine-Tuning) updates only a small adapter layer attached to the base model. The adapter approach requires significantly less compute and storage, and you must specify an `adapter_size` (e.g., `4`) when using this mode in [`tune_open_model.py`](https://github.com/google/skills/blob/main/tune_open_model.py).

### How do I prevent my tuning job from being rejected due to validation data size?

Agent Platform enforces a strict limit where validation files cannot exceed approximately 25% of the training file size. The [`prepare_dataset.py`](https://github.com/google/skills/blob/main/prepare_dataset.py) script includes a `validation_ratio_error` check that validates your split ratio before upload, preventing API rejections after job submission.

### Can I monitor multiple tuning jobs simultaneously?

Yes. The [`list_models.py`](https://github.com/google/skills/blob/main/list_models.py) script queries all tuning jobs in a specified project and location using `client.tunings.list()`, while [`monitor_tuning_job.py`](https://github.com/google/skills/blob/main/monitor_tuning_job.py) tracks individual job progress via `client.tunings.get()`. Both tools support concurrent monitoring across different base models and adapter configurations.