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