paint-brush
Davinci est mauvais en maths : affiner les modèles ChatGPT avec NodeJs et OpenAI v4par@timbushell
1,086 lectures
1,086 lectures

Davinci est mauvais en maths : affiner les modèles ChatGPT avec NodeJs et OpenAI v4

par Tim Bushell9m2023/08/20
Read on Terminal Reader

Trop long; Pour lire

L'API d'OpenAI offre un éventail de possibilités, permettant aux développeurs d'interagir avec des modèles de langage avancés comme GPT-3.5. Cet article se penche sur la création d'un ensemble d'outils spécialisés à l'aide de la bibliothèque Node.js d'OpenAI. Nous allons construire une CLI (Command Line Interface) pour interagir avec l'API, en nous concentrant sur une mission particulière : enseigner le célèbre modèle davinci pour améliorer ses compétences mathématiques. Le voyage implique la configuration de l'environnement de développement, la création d'un ensemble de données de réglage fin, la formation d'un nouveau modèle et l'observation des résultats. En suivant ces étapes, nous visons à démontrer à la fois les capacités de l'API d'OpenAI et les subtilités des modèles de réglage fin pour des tâches spécifiques.
featured image - Davinci est mauvais en maths : affiner les modèles ChatGPT avec NodeJs et OpenAI v4
Tim Bushell HackerNoon profile picture
0-item


Cet article se concentre sur l'utilisation de la bibliothèque Node.js d'OpenAI pour créer une CLI qui entraîne le modèle Davinci en mathématiques.

Coquille de noix

  • "Echafaudez" notre bibliothèque.
  • Écrivez un ensemble de fonctions pour encapsuler les appels d'API d'OpenAI.
  • Créez une CLI simple pour appeler les fonctions.
  • Prouvez que ChatGPT est (généralement) bon en mathématiques.
  • Prouvez que Davinci est (généralement) mauvais en maths.
  • Construisez un ensemble de données de réglage fin simple pour enseigner les mathématiques Davinci.
  • Téléchargez "un ensemble de données de réglage fin simple".
  • Transformez un "ensemble de données de réglage fin simple" en un modèle de réglage fin simple.
  • Prouver notre mise au point a enseigné les mathématiques à Davinci.


Échafaud

 cd ~/Dev/YourRootFolderForPersonalStuff/ mdkir davinci-is-bad-at-maths cd davinci-is-bad-at-maths npm i dotenv openai npm i prettier -D touch .env touch goodAtMathsDatasetBuilder.js touch openAI.js mkdir bin touch bin/cli.js


package.json

... peut être simple, comme ceci :

 { "description": "Experiments using OpenAI's API NodeJs v4 library", "name": "davinci-is-bad-at-maths", "private": true, "bin": "./bin/cli.js", "dependencies": { "dotenv": "^16.3.1", "openai": "^4.0.0" }, "devDependencies": { "prettier": "^3.0.2" }, "main": "openAI.js", "scripts": { "cli": "node bin/cli.js", "prettier": "prettier --list-different --write \"**/*.{css,html,js,json,md,mjs,scss,ts,yaml}\"" }, "type": "module" }


L'entrée "cli" dans les scripts signifie que nous pouvons appeler npm run cli -- commandName [args] . Si vous l'utilisez à la place du node bin/cli.js commandName [args] cela signifie que vous conservez l'historique de votre shell même si vous modifiez ultérieurement la structure de l'application ou le nom de cli.js . Les choses simples plaisent aux esprits simples et j'ai un esprit simple.

.env

... doit ressembler à ceci mais avec votre propre API_KEY :

 OPENAI_API_KEY="sk-d0ntY0uD4reUs3MyK3yG3tY0urOwnFr0mOp0n41W36s1t3Yo" OPENAI_MODEL="davinci"


Un ensemble de fonctions pour envelopper les appels d'API d'OpenAI.

Ouvrez openAI.js et copiez ceci dans :

 /** A not-robust OpenAI v4 CLI; a playground for OpenAI v4 API calls; a utility for working with a OpenAI model who is really really, like - I mean - really bad at maths. * @usage * >> import commandHub from "openAI.js" * >> const [, , command, ...args] = process.argv * >> const commandFunc = commandHub[command] * >> commandFunc(...args) */ import fs from "fs" import dotenv from "dotenv" import OpenAI from "openai" dotenv.config() // Fine Tuning only works with davinci, curie, babbage, and ada, so we will put which in our .env file so that we can call the same one consistently. const model = process.env.OPENAI_MODEL // Instantiate the API object. const apiKey = process.env.OPENAI_API_KEY const openai = new OpenAI({ apiKey }) /** openai.chat.completions.create * @usage * >> npm run cli -- chatCompletionsCreate "2+8=?" * @param {String} chatPrompt your sum to an assistent who is (usually) good at maths */ export const chatCompletionsCreate = async chatPrompt => { const res = await openai.chat.completions.create({ messages: [ { role: "system", content: "You are good at maths." }, { role: "user", content: chatPrompt }, ], model: model, }) console.log("chatCompletionsCreate", res.choices) } /** openai.completions.create * @tutorial * Normally we would use `chatCompletionsCreate` but for Fine Tuned models we must use base models and therefore `completionsCreate`. * @usage * >> npm run cli -- completionsCreate "2+8=?" * @param {String} chatPrompt your sum to an assistent who is (usually) good at maths */ export const completionsCreate = async chatPrompt => { const res = await openai.completions.create({ model: model, prompt: chatPrompt, temperature: 0, }) console.log("completionsCreate", res) } /** openai.files.create and output to `openai.files.create.json` * @usage * >> npm run cli -- filesCreate bad-at-maths-fine-tuning-dataset.jsonl * @param {String} filePath of JSONLD file to upload. */ export const filesCreate = async filePath => { const res = await openai.files.create({ file: fs.createReadStream(filePath), purpose: "fine-tune", }) console.log("filesCreate", res) fs.writeFileSync( "openai.files.create.json", JSON.stringify(res, null, 2), "utf-8", ) } // openai.files.del /** openai.files.list and output to `openai.files.list.json` * @usage * >> npm run cli -- filesList */ export const filesList = async () => { const res = await openai.files.list() console.log("filesList", res) fs.writeFileSync( "openai.files.list.json", JSON.stringify(res, null, 2), "utf-8", ) } // openai.files.retrieve // openai.files.retrieveContent /** openai.fineTunes.create * @usage * >> npm run cli -- fineTunesCreate "bad-at-maths-fine-tuning-dataset.jsonl" "is-good-at-maths" * @param {String} fileId of previously uploaded file where `purpose: "fine-tune"`. * @param {String} suffix to add to the resulting model name for easily id later. */ export const fineTunesCreate = async (fileId, suffix) => { const res = await openai.fineTunes.create({ training_file: fileId, suffix: suffix, model: model, }) console.log("fineTunesCreate", res) fs.writeFileSync( "openai.fineTunes.create.json", JSON.stringify(res, null, 2), "utf-8", ) } /** openai.fineTunes.list * @usage * >> npm run cli -- fineTunesList */ export const fineTunesList = async () => { const res = await openai.fineTunes.list() console.log("fineTunesList", res) fs.writeFileSync( "openai.fineTunes.list.json", JSON.stringify(res, null, 2), "utf-8", ) } // openai.fineTunes.cancel // openai.fineTunes.retrieve // openai.fineTunes.listEvents // openai.models.del // openai.models.list // openai.models.del // openai.images.generate // openai.images.edit // openai.images.createVariation // openai.audio.transcriptions.create // openai.audio.translations.create // openai.edits.create // openai.embeddings.create // openai.moderations.create // A command hub. const commandHub = { chatCompletionsCreate, completionsCreate, filesCreate, filesList, fineTunesCreate, fineTunesList, } export default commandHub


Vous remarquerez que j'ai laissé tous les points de terminaison disponibles dans la bibliothèque d' OpenAI dans ce fichier, que je vous laisse ajouter comme exercice pour créer un module utile.


Un simple CLI pour appeler les fonctions

Ouvrez bin/cli.js et collez ceci :

 #!/usr/bin/env node /** A not-very-robust OpenAI v4 CLI; a playground for OpenAI v4 API calls; a utility for working with a OpenAI model who is really really, like - I mean - really bad at maths. * @usage with "cli" in "scripts" (don't forget the "--"). * >> npm cli -- commandName [arg1 arg2 ...arg(n)] */ import commandHub from "../openAI.js" const [, , command, ...args] = process.argv // Call the requested command. Not a robust CLI but it gets the job done! if (!commandHub.hasOwnProperty(command)) { throw "No such command as `" + command + "`" } else { const commandFunc = commandHub[command] commandFunc(...args) }


Prouver que ChatGPT est (généralement) bon en maths

ChatGPT ne devrait avoir aucun problème à répondre aux sommes car (généralement) ChatGPT est bon en maths, ce que nous pouvons prouver (et tester notre CLI) en procédant comme suit :


  1. Modifiez .env pour dire :
 OPENAI_API_KEY="sk-d0ntY0uD4reUs3MyK3yG3tY0urOwnFr0mOp0n41W36s1t3Yo" OPENAI_MODEL="gpt-3.5-turbo"


  1. Exécutez la commande :
 npm run cli -- chatCompletionsCreate "12+4`.


Voir? Bon en maths.


À une date ultérieure, lorsqu'il deviendra possible d'affiner les modèles de chatbot comme "gpt-3.5-turbo", nous l'affinerons pour qu'il soit mauvais en maths.


La partie -- est nécessaire pour s'assurer que les paramètres sont correctement transmis à NPM. Je ne vais pas expliquer pourquoi car je ne sais pas pourquoi. Tu pourrais. C'est bien. Faites-moi savoir si vous savez. Tout ce que je sais, c'est qu'il faut le faire pour que ça marche et c'est un fait.


NB : Voici comment vous feriez la même chose en dehors de notre CLI :

 import dotenv from "dotenv" import OpenAI from "openai" const apiKey = process.env.OPENAI_API_KEY const model = process.env.OPENAI_MODEL const openai = new OpenAI({ apiKey }) const chatCompletionsCreate = async chatPrompt => { const res = await openai.chat.completions.create({ messages: [ { role: "system", content: "You are good at maths." }, { role: "user", content: chatPrompt }, ], model: model, }) console.log("chatCompletionsCreate", res.choices) } chatCompletionsCreate("12+4")


Prouvez que Davinci est (généralement) mauvais en maths.

  1. Modifiez .env pour dire :
 OPENAI_API_KEY="sk-d0ntY0uD4reUs3MyK3yG3tY0urOwnFr0mOp0n41W36s1t3Yo" OPENAI_MODEL="davinci"


  1. Exécutez la commande
 npm run cli -- completionsCreate "12+4`.


NB : Voici comment vous feriez la même chose en dehors de notre CLI :

 import fs from "fs" import dotenv from "dotenv" import OpenAI from "openai" const apiKey = process.env.OPENAI_API_KEY const openai = new OpenAI({ apiKey }) const completionsCreate = async chatPrompt => { const res = await openai.completions.create({ model: model, prompt: chatPrompt, temperature: 0, }) console.log("completionsCreate", res) } completionsCreate("12+4")


Enseigner les mathématiques DaVinci

Selon la documentation, "Fine Tuning" ChatGPT des modèles nécessite de grands ensembles de données, au moins 200. L'intérêt de davinci-is-bad-at-maths est d'apprendre à créer, télécharger et utiliser des ensembles de données "Fine Tuning" et raccourcir le travailler réellement CONSTRUIRE un ensemble de données utile plutôt que stupide.


Et puisque nous sommes codeurs, nous pouvons coder un raccourci comme celui-ci :


Ouvrez goodAtMathsDatasetBuilder.js et collez ceci :

 import fs from "fs" // Don't waste bandwidth with duplicates in the fine-training data. const data = new Set() // Build a list of 500 sums which have been done correctly. while (data.size < 500) { // Two random integers. let x = Math.round(Math.random() * 1000) let y = Math.round(Math.random() * 1000) let result = x + y data.add( JSON.stringify({ prompt: `${x}+${y}\n\n###\n\n`, completion: `${x}+${y}=${result} END`, }), ) } fs.writeFileSync( "good-at-maths-fine-tuning-dataset.jsonl", [...data].join("\n"), "utf-8", ) console.log("JSONL fine-tuning dataset has been created.")


Tout ce que nous faisons ici est de construire un ensemble de données que les modèles ChatGPT "ajustent" pour être bons en mathématiques, et tout ce dont nous avons besoin, c'est de beaucoup de sommes avec des "complétions" qui sont correctes.


Exécutez ce script comme ceci :

 node goodAtMathsDatasetBuilder.js`


Ouvrez good-at-maths-fine-tuning-dataset.jsonl et cela devrait ressembler à ceci :

 {"prompt":"487+63\n\n###\n\n","completion":"487+63=550 END"} {"prompt":"842+624\n\n###\n\n","completion":"842+624=1466 END"} {"prompt":"58+783\n\n###\n\n","completion":"58+783=841 END"} {"prompt":"96+478\n\n###\n\n","completion":"96+478=574 END"} {"prompt":"69+401\n\n###\n\n","completion":"69+401=470 END"}

... avec plus de sommes qui sont justes.


Téléchargez "un ensemble de données de réglage fin simple".

Pour télécharger l'ensemble de données, exécutez

 npm run cli -- filesCreate good-at-maths-fine-tuning-dataset.jsonl


NB : Voici comment vous feriez la même chose en dehors de notre CLI :

 import fs from "fs" import dotenv from "dotenv" import OpenAI from "openai" const apiKey = process.env.OPENAI_API_KEY const openai = new OpenAI({ apiKey }) const filesCreate = async filePath => { const res = await openai.files.create({ file: fs.createReadStream(filePath), purpose: "fine-tune", }) console.log("filesCreate", res) fs.writeFileSync( "openai.files.create.json", JSON.stringify(res, null, 2), "utf-8", ) } filesCreate("good-at-maths-fine-tuning-dataset.jsonl")

Prenez note de l' id du fichier, par exemple "file-th15IsM1ne3G3tY0urOwn1Yo"


Transformez un "ensemble de données de réglage fin simple" en un modèle de réglage fin simple

Pour créer un modèle "Affiné" à l'aide de cet appel d'ensemble de données :

 npm run cli -- fineTunesCreate "file-th15IsM1ne3G3tY0urOwn1Yo"`"is-good-at-maths"


NB : Voici comment vous feriez la même chose en dehors de notre CLI :

 import fs from "fs" import dotenv from "dotenv" import OpenAI from "openai" const apiKey = process.env.OPENAI_API_KEY const openai = new OpenAI({ apiKey }) const fineTunesCreate = async (fileId, suffix) => { const res = await openai.fineTunes.create({ training_file: fileId, suffix: suffix, model: model, }) console.log("fineTunesCreate", res) fs.writeFileSync( "openai.fineTunes.create.json", JSON.stringify(res, null, 2), "utf-8", ) } fineTunesCreate("file-th15IsM1ne3G3tY0urOwn1Yo")


Il faut du temps pour enseigner les maths à Davinci car, pour être honnête, DaVinci est vraiment mauvais en maths !


Tu peux courir:

 npm run cli -- fineTunesList

Attendez que status: 'pending' passe à status: 'suceeded'


Prouver notre réglage fin a enseigné les mathématiques à Davinci

Lorsque status: 'suceeded' , recherchez le nom fine_tuned_model .


  1. Modifiez .env pour dire :
 OPENAI_API_KEY="sk-d0ntY0uD4reUs3MyK3yG3tY0urOwnFr0mOp0n41W36s1t3Yo" OPENAI_MODEL="<fine_tuned_model name>"


  1. Courir:
 npm run cli -- completionsCreate "12+4`.


C'est une réponse hokey, mais vous devriez voir que Davinci est meilleur en maths.


Ce que nous avons appris

  1. Comment utiliser la bibliothèque V4 d'OpenAI.
  2. Comment créer un ensemble de données "Fine Tuning" et le télécharger.
  3. Comment générer un nouveau modèle OpenAI.
  4. Comment écrire une CLI merdique.


Ce projet est à retrouver ici :

https://gitlab.com/timitee/davinci-is-bad-at-maths/edit#js-general-project-settings