⚙️Fine-tuning

Create tuned model

To create a tuned model, you need to pass your dataset to the model in the genai.create_tuned_model method. You can do this by directly defining the input and output values in the call or importing from a file into a dataframe to pass to the method.

For this example, you will tune a model to generate the next number in the sequence. For example, if the input is 1, the model should output 2. If the input is one hundred, the output should be one hundred one.

var baseModel = (await GenerativeAI.DefaultInstance.Models.List())
    .FirstOrDefault(m => m.SupportedGenerationMethods.Contains("createTunedModel"));

Debug.Log(baseModel.ToString());

/* log
Model(name='models/gemini-1.0-pro-001',
      base_model_id='',
      version='001',
      display_name='Gemini 1.0 Pro',
      description=('The best model for scaling across a wide range of tasks. This is a stable '
                   'model that supports tuning.'),
      input_token_limit=30720,
      output_token_limit=2048,
      supported_generation_methods=['generateContent', 'countTokens', 'createTunedModel'],
      temperature=0.9,
      top_p=1.0,
      top_k=1)
*/
var name = $"generate-num-{UnityEngine.Random.Range(0, 10000)}";

var tunedModelRequest = new TunedModelRequest.Builder()
    .SetSourceModel(baseModel.Name)
    .SetTrainingData(
        new TuningExample("1", "2"),
        new TuningExample("3", "4"),
        new TuningExample("-3", "-2"),
        new TuningExample("twenty two", "twenty three"),
        new TuningExample("two hundred", "two hundred one"),
        new TuningExample("ninety nine", "one hundred"),
        new TuningExample("8", "9"),
        new TuningExample("-98", "-97"),
        new TuningExample("1,000", "1,001"),
        new TuningExample("10,100,000", "10,100,001"),
        new TuningExample("thirteen", "fourteen"),
        new TuningExample("eighty", "eighty one"),
        new TuningExample("one", "two"),
        new TuningExample("three", "four"),
        new TuningExample("seven", "eight"))
    .SetName(name)
    .SetEpochCount(100)
    .SetBatchSize(4)
    .SetLearningRate(0.001f)
    .Build();

var operation = 
    await GenerativeAI.DefaultInstance.TunedModels.Create(tunedModelRequest);

Your tuned model is immediately added to the list of tuned models, but its status is set to "creating" while the model is tuned.

var model = 
    await GenerativeAI.DefaultInstance.TunedModels.Get(name);

Debug.Log(model.ToString());

/* log
TunedModel(name='tunedModels/generate-num-2946',
   source_model='models/gemini-1.0-pro-001',
   base_model='models/gemini-1.0-pro-001',
   display_name='',
   description='',
   temperature=0.9,
   top_p=1.0,
   top_k=1,
   state=<State.CREATING: 1>,
   create_time=datetime.datetime(2024, 2, 21, 20, 4, 16, 448050, tzinfo=datetime.timezone.utc),
   update_time=datetime.datetime(2024, 2, 21, 20, 4, 16, 448050, tzinfo=datetime.timezone.utc),
   tuning_task=TuningTask(start_time=datetime.datetime(2024, 2, 21, 20, 4, 16, 890698, tzinfo=datetime.timezone.utc),
                          complete_time=None,
                          snapshots=[],
                          hyperparameters=Hyperparameters(epoch_count=100,
                                                          batch_size=4,
                                                          learning_rate=0.001)))
 */

Evaluate your model

You can use the GenerativeAI.DefaultInstance.TunedModels.GenerateText method and specify the name of your model to test your model performance.

var model = new GenerativeModel("name");

var result = await model.GenerateContentAsync("55");
Debug.Log(result.Text);

// '56'

result = await model.GenerateContentAsync("123455");
Debug.Log(result.Text);

// '123456'

result = await model.GenerateContentAsync("four");
Debug.Log(result.Text);

// 'five'

result = await model.GenerateContentAsync("quatre"); // French 4
Debug.Log(result.Text); // French 5 is "cinq"

// 'cinq'

result = await model.GenerateContentAsync("III"); // Roman numeral 3
Debug.Log(result.Text); // Roman numeral 4 is IV

// 'IV'

result = await model.GenerateContentAsync("七"); // Japanese 7
Debug.Log(result.Text); // Japanese 8 is 八!

// '八'

It really seems to have picked up the task despite the limited examples, but "next" is a relatively simple concept, see the tuning guide for more guidance on improving performance.

Update the description

You can update the description of your tuned model any time using the GenerativeAI.DefaultInstance.TunedModels.Patch method.

await GenerativeAI.DefaultInstance.TunedModels.Patch(
    "name", 
    new UpdateMask("description", "This is my model."));

var model = await GenerativeAI.DefaultInstance.TunedModels.Get("name");

Debug.Log(model.Data.Description);

// log: "This is my model."

Delete the model

You can clean up your tuned model list by deleting models you no longer need. Use the GenerativeAI.DefaultInstance.TunedModels.Delete method to delete a model. If you canceled any tuning jobs, you may want to delete those as their performance may be unpredictable.

await GenerativeAI.DefaultInstance.TunedModels.Delete("name");

If the model no longer exists, it will return an error:

<class 'google.api_core.exceptions.NotFound'>: 404 Tuned model tunedModels/generate-num-2946 does not exist.

Last updated