paint-brush
Davinci ist schlecht in Mathematik: Feinabstimmung von ChatGPT-Modellen mit NodeJs und OpenAI v4von@timbushell
1,086 Lesungen
1,086 Lesungen

Davinci ist schlecht in Mathematik: Feinabstimmung von ChatGPT-Modellen mit NodeJs und OpenAI v4

von Tim Bushell9m2023/08/20
Read on Terminal Reader
Read this story w/o Javascript

Zu lang; Lesen

Die API von OpenAI bietet eine Reihe von Möglichkeiten, die es Entwicklern ermöglichen, mit fortschrittlichen Sprachmodellen wie GPT-3.5 zu interagieren. Dieser Artikel befasst sich mit der Erstellung eines speziellen Toolsets mithilfe der Node.js-Bibliothek von OpenAI. Wir werden eine CLI (Command Line Interface) für die Interaktion mit der API erstellen und uns dabei auf eine bestimmte Mission konzentrieren: das Unterrichten des berühmten Davinci-Modells, um seine mathematischen Fähigkeiten zu verbessern. Die Reise umfasst das Einrichten der Entwicklungsumgebung, das Erstellen eines Feinabstimmungsdatensatzes, das Trainieren eines neuen Modells und das Beobachten der Ergebnisse. Indem wir diese Schritte befolgen, wollen wir sowohl die Fähigkeiten der OpenAI-API als auch die Feinheiten der Feinabstimmung von Modellen für bestimmte Aufgaben demonstrieren.
featured image - Davinci ist schlecht in Mathematik: Feinabstimmung von ChatGPT-Modellen mit NodeJs und OpenAI v4
Tim Bushell HackerNoon profile picture
0-item


Dieser Artikel konzentriert sich auf die Verwendung der Node.js- Bibliothek von OpenAI zum Erstellen einer CLI , die das Davinci-Modell in Mathematik trainiert.

Nussschale

  • „Gerüst“ unserer Bibliothek.
  • Schreiben Sie eine Reihe von Funktionen, um die API-Aufrufe von OpenAI zu umschließen.
  • Erstellen Sie eine einfache CLI zum Aufrufen der Funktionen.
  • Beweisen Sie, dass ChatGPT (normalerweise) gut in Mathe ist.
  • Beweisen Sie, dass Davinci (normalerweise) schlecht in Mathe ist.
  • Erstellen Sie einen einfachen Feinabstimmungsdatensatz für den Davinci-Mathematikunterricht.
  • „Einfacher Feinabstimmungsdatensatz“ hochladen.
  • Verwandeln Sie einen „einfachen Feinabstimmungsdatensatz“ in ein einfaches Feinabstimmungsmodell.
  • Der Beweis unserer Feinabstimmung brachte Davinci die Mathematik bei.


Gerüst

 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

... kann einfach sein, so:

 { "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" }


Der Eintrag „cli“ in Skripten bedeutet, dass wir npm run cli -- commandName [args] aufrufen können. Wenn Sie dies anstelle von node bin/cli.js commandName [args] verwenden, bedeutet dies, dass Sie den Verlauf Ihrer Shell beibehalten, auch wenn Sie später die App-Struktur oder den Namen von cli.js ändern. Einfache Dinge gefallen einfachen Köpfen und ich habe einen einfachen Geist.

.env

... muss so aussehen, aber mit Ihrem eigenen API_KEY:

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


Eine Reihe von Funktionen zum Umschließen der API-Aufrufe von OpenAI.

Öffnen Sie openAI.js und kopieren Sie dies in:

 /** 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


Sie werden feststellen, dass ich alle verfügbaren Endpunkte in der OpenAI -Bibliothek in dieser Datei belassen habe, die ich Ihnen als Übung zum Erstellen eines nützlichen Moduls hinzufügen kann.


Eine einfache CLI zum Aufrufen der Funktionen

Öffnen Sie bin/cli.js und fügen Sie Folgendes ein:

 #!/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) }


Beweisen Sie, dass ChatGPT (normalerweise) gut in Mathe ist

ChatGPT sollte keine Probleme haben, irgendwelche Summen zu beantworten, da ChatGPT (normalerweise) gut in Mathematik ist, was wir wie folgt beweisen (und unsere CLI testen) können:


  1. Bearbeiten Sie .env, um Folgendes zu sagen:
 OPENAI_API_KEY="sk-d0ntY0uD4reUs3MyK3yG3tY0urOwnFr0mOp0n41W36s1t3Yo" OPENAI_MODEL="gpt-3.5-turbo"


  1. Führen Sie den Befehl aus:
 npm run cli -- chatCompletionsCreate "12+4`.


Sehen? Gut in Mathe.


Zu einem späteren Zeitpunkt, wenn es möglich wird, Chatbot-Modelle wie „gpt-3.5-turbo“ zu verfeinern, werden wir sie so verfeinern, dass sie schlecht in Mathematik sind.


Der Teil -- ist erforderlich, um sicherzustellen, dass die Parameter korrekt an NPM übergeben werden. Ich werde nicht näher darauf eingehen, weil ich nicht weiß, warum. Vielleicht. Das ist gut. Sag mir Bescheid, wenn du es weißt. Ich weiß nur, dass man es tun muss, damit es funktioniert, und das ist eine Tatsache.


NB: So würden Sie das Gleiche auch außerhalb unserer CLI tun:

 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")


Beweisen Sie, dass Davinci (normalerweise) schlecht in Mathe ist.

  1. Bearbeiten Sie .env, um Folgendes zu sagen:
 OPENAI_API_KEY="sk-d0ntY0uD4reUs3MyK3yG3tY0urOwnFr0mOp0n41W36s1t3Yo" OPENAI_MODEL="davinci"


  1. Führen Sie den Befehl aus
 npm run cli -- completionsCreate "12+4`.


NB: So würden Sie das Gleiche auch außerhalb unserer CLI tun:

 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")


DaVinci-Mathematik unterrichten

Gemäß der Dokumentation sind für die „Feinabstimmung“ von ChatGPT-Modellen große Datensätze erforderlich, mindestens 200. Der springende Punkt bei „davinci-is-bad-at-maths“ ist, zu lernen , wie man „Feinabstimmung“-Datensätze erstellt, hochlädt und verwendet und wie man diese verknüpft Arbeit tatsächlich daran, einen nützlichen und nicht albernen Datensatz aufzubauen.


Und da wir Programmierer sind, können wir eine Verknüpfung wie diese programmieren:


Öffnen Sie goodAtMathsDatasetBuilder.js und fügen Sie Folgendes ein:

 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.")


Alles, was wir hier tun, ist, einen Datensatz zu erstellen, der ChatGPT-Modelle „verfeinert“, um gut in Mathematik zu sein, und alles, was wir brauchen, sind viele Summen mit „Vervollständigungen“, die korrekt sind.


Führen Sie dieses Skript wie folgt aus:

 node goodAtMathsDatasetBuilder.js`


Öffnen Sie good-at-maths-fine-tuning-dataset.jsonl und es sollte so aussehen:

 {"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"}

... mit mehr Summen, die stimmen.


„Einfacher Feinabstimmungsdatensatz“ hochladen.

Um den Datensatz hochzuladen, führen Sie Folgendes aus:

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


NB: So würden Sie das Gleiche auch außerhalb unserer CLI tun:

 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")

Notieren Sie sich die Datei- id , z. B. „file-th15IsM1ne3G3tY0urOwn1Yo“.


Verwandeln Sie einen „einfachen Feinabstimmungsdatensatz“ in ein einfaches Feinabstimmungsmodell

So erstellen Sie ein „fein abgestimmtes“ Modell mit diesem Datensatzaufruf:

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


NB: So würden Sie das Gleiche auch außerhalb unserer CLI tun:

 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")


Es dauert eine Weile, DaVinci Mathematik beizubringen, denn ehrlich gesagt ist DaVinci wirklich schlecht in Mathematik!


Du kannst rennen:

 npm run cli -- fineTunesList

Warten Sie, bis sich status: 'pending' in den status: 'suceeded' ändert.


Davinci hat uns die Mathematik beigebracht, um unsere Feinabstimmung zu beweisen

Wenn status: 'suceeded' lautet, suchen Sie den Namen fine_tuned_model .


  1. Bearbeiten Sie .env, um Folgendes zu sagen:
 OPENAI_API_KEY="sk-d0ntY0uD4reUs3MyK3yG3tY0urOwnFr0mOp0n41W36s1t3Yo" OPENAI_MODEL="<fine_tuned_model name>"


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


Es ist eine kitschige Antwort, aber Sie sollten sehen, dass Davinci besser in Mathe ist.


Was wir gelernt haben

  1. So verwenden Sie die V4-Bibliothek von OpenAI.
  2. So erstellen Sie einen „Fine Tuning“-Datensatz und laden ihn hoch.
  3. So generieren Sie ein neues OpenAI-Modell.
  4. Wie schreibe ich eine beschissene CLI?


Dieses Projekt finden Sie hier:

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