| 
 | 1 | +/*  | 
 | 2 | + * Copyright 2025 Google LLC  | 
 | 3 | + *  | 
 | 4 | + * Licensed under the Apache License, Version 2.0 (the "License");  | 
 | 5 | + * you may not use this file except in compliance with the License.  | 
 | 6 | + * You may obtain a copy of the License at  | 
 | 7 | + *  | 
 | 8 | + * http://www.apache.org/licenses/LICENSE-2.0  | 
 | 9 | + *  | 
 | 10 | + * Unless required by applicable law or agreed to in writing, software  | 
 | 11 | + * distributed under the License is distributed on an "AS IS" BASIS,  | 
 | 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  | 
 | 13 | + * See the License for the specific language governing permissions and  | 
 | 14 | + * limitations under the License.  | 
 | 15 | + */  | 
 | 16 | + | 
 | 17 | +package genai.tuning;  | 
 | 18 | + | 
 | 19 | +// [START googlegenaisdk_tuning_job_create]  | 
 | 20 | + | 
 | 21 | +import static com.google.genai.types.JobState.Known.JOB_STATE_PENDING;  | 
 | 22 | +import static com.google.genai.types.JobState.Known.JOB_STATE_RUNNING;  | 
 | 23 | + | 
 | 24 | +import com.google.genai.Client;  | 
 | 25 | +import com.google.genai.types.CreateTuningJobConfig;  | 
 | 26 | +import com.google.genai.types.GetTuningJobConfig;  | 
 | 27 | +import com.google.genai.types.HttpOptions;  | 
 | 28 | +import com.google.genai.types.JobState;  | 
 | 29 | +import com.google.genai.types.TunedModel;  | 
 | 30 | +import com.google.genai.types.TunedModelCheckpoint;  | 
 | 31 | +import com.google.genai.types.TuningDataset;  | 
 | 32 | +import com.google.genai.types.TuningJob;  | 
 | 33 | +import com.google.genai.types.TuningValidationDataset;  | 
 | 34 | +import java.util.Collections;  | 
 | 35 | +import java.util.EnumSet;  | 
 | 36 | +import java.util.List;  | 
 | 37 | +import java.util.Optional;  | 
 | 38 | +import java.util.Set;  | 
 | 39 | +import java.util.concurrent.TimeUnit;  | 
 | 40 | + | 
 | 41 | +public class TuningJobCreate {  | 
 | 42 | + | 
 | 43 | +  public static void main(String[] args) throws InterruptedException {  | 
 | 44 | +    // TODO(developer): Replace these variables before running the sample.  | 
 | 45 | +    String model = "gemini-2.5-flash";  | 
 | 46 | +    createTuningJob(model);  | 
 | 47 | +  }  | 
 | 48 | + | 
 | 49 | +  // Shows how to create a supervised fine-tuning job using training and validation datasets  | 
 | 50 | +  public static String createTuningJob(String model) throws InterruptedException {  | 
 | 51 | +    // Client Initialization. Once created, it can be reused for multiple requests.  | 
 | 52 | +    try (Client client =  | 
 | 53 | +        Client.builder()  | 
 | 54 | +            .location("us-central1")  | 
 | 55 | +            .vertexAI(true)  | 
 | 56 | +            .httpOptions(HttpOptions.builder().apiVersion("v1beta1").build())  | 
 | 57 | +            .build()) {  | 
 | 58 | + | 
 | 59 | +      String trainingDatasetUri =  | 
 | 60 | +          "gs://cloud-samples-data/ai-platform/generative_ai/gemini/text/sft_train_data.jsonl";  | 
 | 61 | +      TuningDataset trainingDataset = TuningDataset.builder().gcsUri(trainingDatasetUri).build();  | 
 | 62 | + | 
 | 63 | +      String validationDatasetUri =  | 
 | 64 | +          "gs://cloud-samples-data/ai-platform/generative_ai/gemini/text/sft_validation_data.jsonl";  | 
 | 65 | +      TuningValidationDataset validationDataset =  | 
 | 66 | +          TuningValidationDataset.builder().gcsUri(validationDatasetUri).build();  | 
 | 67 | + | 
 | 68 | +      TuningJob tuningJob =  | 
 | 69 | +          client.tunings.tune(  | 
 | 70 | +              model,  | 
 | 71 | +              trainingDataset,  | 
 | 72 | +              CreateTuningJobConfig.builder()  | 
 | 73 | +                  .tunedModelDisplayName("your-display-name")  | 
 | 74 | +                  .validationDataset(validationDataset)  | 
 | 75 | +                  .build());  | 
 | 76 | + | 
 | 77 | +      String jobName =  | 
 | 78 | +          tuningJob.name().orElseThrow(() -> new IllegalStateException("Missing job name"));  | 
 | 79 | +      Optional<JobState> jobState = tuningJob.state();  | 
 | 80 | +      Set<JobState.Known> runningStates = EnumSet.of(JOB_STATE_PENDING, JOB_STATE_RUNNING);  | 
 | 81 | + | 
 | 82 | +      while (jobState.isPresent() && runningStates.contains(jobState.get().knownEnum())) {  | 
 | 83 | +        System.out.println("Job state: " + jobState.get());  | 
 | 84 | +        tuningJob = client.tunings.get(jobName, GetTuningJobConfig.builder().build());  | 
 | 85 | +        jobState = tuningJob.state();  | 
 | 86 | +        TimeUnit.SECONDS.sleep(60);  | 
 | 87 | +      }  | 
 | 88 | + | 
 | 89 | +      tuningJob.tunedModel().flatMap(TunedModel::model).ifPresent(System.out::println);  | 
 | 90 | +      tuningJob.tunedModel().flatMap(TunedModel::endpoint).ifPresent(System.out::println);  | 
 | 91 | +      tuningJob.experiment().ifPresent(System.out::println);  | 
 | 92 | +      // Example response:  | 
 | 93 | +      // projects/123456789012/locations/us-central1/models/6129850992130260992@1  | 
 | 94 | +      // projects/123456789012/locations/us-central1/endpoints/105055037499113472  | 
 | 95 | +      // projects/123456789012/locations/us-central1/metadataStores/default/contexts/experiment_id  | 
 | 96 | + | 
 | 97 | +      List<TunedModelCheckpoint> checkpoints =  | 
 | 98 | +          tuningJob.tunedModel().flatMap(TunedModel::checkpoints).orElse(Collections.emptyList());  | 
 | 99 | + | 
 | 100 | +      int index = 0;  | 
 | 101 | +      for (TunedModelCheckpoint checkpoint : checkpoints) {  | 
 | 102 | +        System.out.println("Checkpoint " + (++index));  | 
 | 103 | +        checkpoint  | 
 | 104 | +            .checkpointId()  | 
 | 105 | +            .ifPresent(checkpointId -> System.out.println("checkpointId=" + checkpointId));  | 
 | 106 | +        checkpoint.epoch().ifPresent(epoch -> System.out.println("epoch=" + epoch));  | 
 | 107 | +        checkpoint.step().ifPresent(step -> System.out.println("step=" + step));  | 
 | 108 | +        checkpoint.endpoint().ifPresent(endpoint -> System.out.println("endpoint=" + endpoint));  | 
 | 109 | +      }  | 
 | 110 | +      // Example response:  | 
 | 111 | +      // Checkpoint 1  | 
 | 112 | +      // checkpointId=1  | 
 | 113 | +      // epoch=2  | 
 | 114 | +      // step=34  | 
 | 115 | +      // endpoint=projects/project/locations/location/endpoints/105055037499113472  | 
 | 116 | +      // ...  | 
 | 117 | +      return jobName;  | 
 | 118 | +    }  | 
 | 119 | +  }  | 
 | 120 | +}  | 
 | 121 | +// [END googlegenaisdk_tuning_job_create]  | 
0 commit comments