Páginas

viernes, 24 de febrero de 2023

Entrenar el modelo davinci de OpenAI para que realice sumas básicas

Tras revisar la documentación disponible en https://platform.openai.com/docs/guides/completion/prompt-design probamos
a entrenar el modelo davinci para que aprenda a realizar sumas básicas con datos del tipo:

    {"prompt": "7+5", "completion": "12"}
    {"prompt": "4+2", "completion": "6"}
    {"prompt": "3+7", "completion": "10"}

1) Instalamos Python:

sudo apt install python3-pip
pip install --upgrade pip
pip install aiohttp
pip install --upgrade openai
pip install openai[datalib]

2) Ajustamos $PATH en $HOME/.profile para que python sepa donde estan las librerías, añadiendo:

PATH="$HOME/.local/lib/python3.10/site-packages:$PATH"

3) Recargamos las variables de .profile en bash ejecutando:

. ~/.profile

4) Creamos una cuenta en OpenAI y obtenemos una API KEY:

https://platform.openai.com/account/api-keys

5) Instalamos la API KEY:

export OPENAI_API_KEY="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"

6) Generamos datos de entrenamiento del tipo:

    {"prompt": "<prompt text>", "completion": "<ideal generated text>"}
    {"prompt": "0+1", "completion": "1"}
    {"prompt": "0+2", "completion": "2"}
    ...
    {"prompt": "9+8", "completion": "17"}
    {"prompt": "9+9", "completion": "18"}
    {"prompt":"","completion":" 0+8\", \"completion\": \"8\"}"}

7) Para ello necesitaremos un programa por ejemplo en Java como el siguiente:

package org.dune;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;

public class GeneraDatosGPT {

    private static int NUMLINEAS = 5000;
    
    public static void main(String[] args) throws IOException {
        
        //Iniciamos el generador aleatorio de enteros
        final Random r = new Random();
        r.setSeed(System.currentTimeMillis());
        
        //Preparamos un fichero de salida
        final File f = new File("/home/egdepedro/datos-sumas.jsonl");
        final FileWriter fw = new FileWriter(f);
        final BufferedWriter bfw = new BufferedWriter(fw);
        
        //Preparamos las variables para cada operación
        int operando1;
        int operando2;
        int resultado;
        
        //Preparamos la línea
        StringBuilder sbLinea;
        for (int c=0;c<NUMLINEAS;c++) {
            //Generamos la operacion aleatoria
            operando1 = r.nextInt(0, 9);
            operando2 = r.nextInt(0, 9);
            resultado = operando1 + operando2;
            //Montamos la línea de datos
            sbLinea = new StringBuilder("{\"prompt\": \"");
            sbLinea.append(operando1);
            sbLinea.append("+");
            sbLinea.append(operando2);
            sbLinea.append("\", \"completion\": \"");
            sbLinea.append(resultado);
            sbLinea.append("\"}");
            
            //Escribimos la línea en el fichero de salida
            bfw.write(sbLinea.toString());
            bfw.newLine();
            
            //Reseteamos la línea
            sbLinea.setLength(0);
        }
        
        //Cerramos los manejadores
        bfw.flush();
        bfw.close();
        fw.close();
    }
}

8) Entrenamos el modelo seleccionado (davinci, curie, babbage, ada) con:

openai api fine_tunes.create -t datos-sumas.jsonl -m davinci

9) Tendremos una salida del tipo:

Upload progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 187k/187k [00:00<00:00, 307Mit/s]
Uploaded file from datos-sumas.jsonl: file-JkbUfKOhPX7hbdkQt7AXUglq
Created fine-tune: ft-k1iukuO7r3pCmTDMwV7supOi
Streaming events until fine-tuning is complete...

(Ctrl-C will interrupt the stream, but not cancel the fine-tune)
[2023-02-24 11:49:11] Created fine-tune: ft-k1iukuO7r3pCmTDMwV7supOi

Stream interrupted (client disconnected).
To resume the stream, run:

  openai api fine_tunes.follow -i ft-k1iukuO7r3pCmTDMwV7supOi

10) Relanzamos el comando indicado:

 openai api fine_tunes.follow -i ft-k1iukuO7r3pCmTDMwV7supOi

11) Nos quedamos con el ID asignado al modelo --> ft-k1iukuO7r3pCmTDMwV7supOi

12) Revisamos la lista de modelos:

openai api fine_tunes.list
    
13) Comprobamos el estado de nuestro modelo, que puede ser: pending, running, succeeded, or failed

    openai api fine_tunes.get -i ft-k1iukuO7r3pCmTDMwV7supOi

  Si lo vamos ejecutando cada cierto tiempo podemos ver como avanza:
    
  "id": "ft-k1iukuO7r3pCmTDMwV7supOi",
  "model": "davinci",
  "object": "fine-tune",
  "organization_id": "org-PTX4TjDLRbTu7lnZTDjil0hG",
  "result_files": [],
  "status": "pending",
  ...
    
  "id": "ft-k1iukuO7r3pCmTDMwV7supOi",
  "model": "davinci",
  "object": "fine-tune",
  "organization_id": "org-PTX4TjDLRbTu7lnZTDjil0hG",
  "result_files": [],
  "status": "running",
  ...

  "id": "ft-k1iukuO7r3pCmTDMwV7supOi",
  "model": "davinci",
  "object": "fine-tune",
  "organization_id": "org-PTX4TjDLRbTu7lnZTDjil0hG",
  "result_files": [
    {
      "bytes": 114982,
      "created_at": 1677248683,
      "filename": "compiled_results.csv",
      "id": "file-vp1v2ozODA9O4r3853X9yUIN",
      "object": "file",
      "purpose": "fine-tune-results",
      "status": "processed",
      "status_details": null
    }
  ],
  "status": "succeeded",

 
  Nota. Entre los datos generados hasta llegar al 'succeeded' podremos ir viendo cómo avanzan las tandas de entrenamiento, que parecen ser 4:
 
  "message": "Completed epoch 1/4",
  ...
  "message": "Completed epoch 2/4",
  ...
  "message": "Completed epoch 3/4",

14) Cuando tras chequear el status tenemos succeeded debemos sacar el ID del Modelo:

openai api fine_tunes.list
{
  "data": [
    {
      "created_at": 1677235751,
      "fine_tuned_model": "davinci:ft-personal-2023-02-24-14-24-41",

15) Recogiendo el ID del modelo generado podemos probarlo con:

openai api completions.create -m davinci:ft-personal-2023-02-24-14-24-41 -M 1 -p 4+1
Obteniendo: 4+15
openai api completions.create -m davinci:ft-personal-2023-02-24-14-24-41 -M 1 -p 9+9
Obteniendo: 9+918
   
15) Si el modelo no ha sido creado tendríamos un aviso del tipo: Error: That model does not exist (HTTP status code: 404)

No hay comentarios:

Publicar un comentario