paint-brush
Davinci kém môn toán: Tinh chỉnh các mô hình ChatGPT với NodeJs và OpenAI v4từ tác giả@timbushell
1,086 lượt đọc
1,086 lượt đọc

Davinci kém môn toán: Tinh chỉnh các mô hình ChatGPT với NodeJs và OpenAI v4

từ tác giả Tim Bushell9m2023/08/20
Read on Terminal Reader

dài quá đọc không nổi

API của OpenAI cung cấp một loạt khả năng, cho phép các nhà phát triển tương tác với các mô hình ngôn ngữ nâng cao như GPT-3.5. Bài viết này đi sâu vào việc tạo bộ công cụ chuyên dụng bằng thư viện Node.js của OpenAI. Chúng tôi sẽ xây dựng CLI (Giao diện dòng lệnh) để tương tác với API, tập trung vào một nhiệm vụ cụ thể: dạy mô hình davinci nổi tiếng để cải thiện các kỹ năng toán học của nó. Hành trình bao gồm thiết lập môi trường phát triển, tạo bộ dữ liệu tinh chỉnh, đào tạo một mô hình mới và quan sát kết quả. Bằng cách làm theo các bước này, chúng tôi mong muốn chứng minh cả khả năng của API của OpenAI và sự phức tạp của các mô hình tinh chỉnh cho các tác vụ cụ thể.
featured image - Davinci kém môn toán: Tinh chỉnh các mô hình ChatGPT với NodeJs và OpenAI v4
Tim Bushell HackerNoon profile picture
0-item


Bài viết này tập trung vào việc sử dụng thư viện Node.js của OpenAI để xây dựng CLI đào tạo mô hình Davinci trong toán học.

Tóm lại

  • "Giàn giáo" thư viện của chúng tôi.
  • Viết một tập hợp các chức năng để ngắt các lệnh gọi API của OpenAI.
  • Xây dựng một CLI đơn giản để gọi các chức năng.
  • Chứng minh ChatGPT (thường) giỏi toán.
  • Chứng minh Davinci (thường) kém môn toán.
  • Xây dựng bộ dữ liệu tinh chỉnh đơn giản để dạy toán Davinci.
  • Tải lên "bộ dữ liệu tinh chỉnh đơn giản".
  • Biến một "bộ dữ liệu tinh chỉnh đơn giản" thành một mô hình tinh chỉnh đơn giản.
  • Chứng minh toán học Davinci được dạy tinh chỉnh của chúng tôi.


Khung

 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

... có thể đơn giản, như thế này:

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


Mục "cli" trong tập lệnh có nghĩa là chúng ta có thể gọi npm run cli -- commandName [args] . Nếu bạn sử dụng tên này thay vì node bin/cli.js commandName [args] thì điều đó có nghĩa là bạn duy trì lịch sử shell của mình ngay cả khi bạn thay đổi cấu trúc ứng dụng sau này hoặc tên của cli.js . Những điều đơn giản làm hài lòng những đầu óc đơn giản và tôi có một đầu óc đơn giản.

.env

... phải giống như thế này nhưng với API_KEY của riêng bạn:

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


Một tập hợp các chức năng để bao bọc các lệnh gọi API của OpenAI.

Mở openAI.js và sao chép phần này vào:

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


Bạn sẽ nhận thấy rằng tôi đã để lại tất cả các điểm cuối có sẵn trong thư viện của OpenAI trong tệp này, tôi để lại cho bạn thêm như một bài tập để tạo một mô-đun hữu ích.


Một CLI đơn giản để gọi các chức năng

Mở bin/cli.js và dán cái này vào:

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


Chứng minh ChatGPT (thường) giỏi toán

ChatGPT sẽ không gặp vấn đề gì khi trả lời bất kỳ khoản tiền nào vì (thường) ChatGPT giỏi toán, điều mà chúng tôi có thể chứng minh (và kiểm tra CLI của mình) bằng cách thực hiện như sau:


  1. Chỉnh sửa .env để nói:
 OPENAI_API_KEY="sk-d0ntY0uD4reUs3MyK3yG3tY0urOwnFr0mOp0n41W36s1t3Yo" OPENAI_MODEL="gpt-3.5-turbo"


  1. Chạy lệnh:
 npm run cli -- chatCompletionsCreate "12+4`.


Nhìn thấy? Giỏi về toán học.


Sau này, khi có thể Tinh chỉnh các mô hình chatbot như "gpt-3.5-turbo", chúng tôi sẽ Tinh chỉnh để nó kém môn toán.


Phần -- là bắt buộc để đảm bảo các tham số được truyền chính xác vào NPM. Tôi sẽ không đi vào lý do tại sao bởi vì tôi không biết tại sao. Bạn có thể. Tốt đấy. Hãy cho tôi biết nếu bạn biết. Tất cả những gì tôi biết là bạn phải làm điều đó để nó hoạt động và đó là sự thật.


Lưu ý: Đây là cách bạn sẽ làm điều tương tự bên ngoài CLI của chúng tôi:

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


Chứng minh Davinci (thường) kém môn toán.

  1. Chỉnh sửa .env để nói:
 OPENAI_API_KEY="sk-d0ntY0uD4reUs3MyK3yG3tY0urOwnFr0mOp0n41W36s1t3Yo" OPENAI_MODEL="davinci"


  1. Chạy lệnh
 npm run cli -- completionsCreate "12+4`.


Lưu ý: Đây là cách bạn sẽ làm điều tương tự bên ngoài CLI của chúng tôi:

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


Dạy toán DaVinci

Theo tài liệu, ChatGPT "Tinh chỉnh" của các mô hình yêu cầu bộ dữ liệu lớn, ít nhất là 200. Toàn bộ vấn đề của davinci-is-bad-at-toántìm hiểu cách tạo, tải lên và sử dụng bộ dữ liệu "Tinh chỉnh" và tắt công việc thực sự XÂY DỰNG một bộ dữ liệu hữu ích hơn là ngớ ngẩn.


Và vì chúng tôi là lập trình viên, chúng tôi có thể viết một phím tắt như thế này:


Mở goodAtMathsDatasetBuilder.js và dán cái này vào:

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


Tất cả những gì chúng tôi đang làm ở đây là xây dựng một bộ dữ liệu mà các mô hình ChatGPT "Tinh chỉnh" để giỏi toán và tất cả những gì chúng tôi cần là rất nhiều tổng với "phần hoàn thành" là chính xác.


Chạy kịch bản này như thế này:

 node goodAtMathsDatasetBuilder.js`


Mở good-at-maths-fine-tuning-dataset.jsonl và nó sẽ trông như thế này:

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

... với nhiều số tiền đúng hơn.


Tải lên "bộ dữ liệu tinh chỉnh đơn giản".

Để tải lên tập dữ liệu, hãy chạy

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


Lưu ý: Đây là cách bạn sẽ làm điều tương tự bên ngoài CLI của chúng tôi:

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

Lưu ý id tệp, ví dụ: "file-th15IsM1ne3G3tY0urOwn1Yo"


Biến "bộ dữ liệu tinh chỉnh đơn giản" thành một mô hình tinh chỉnh đơn giản

Để tạo mô hình "Tinh chỉnh" bằng cách sử dụng tập dữ liệu này, hãy gọi:

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


Lưu ý: Đây là cách bạn sẽ làm điều tương tự bên ngoài CLI của chúng tôi:

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


Phải mất một thời gian để dạy toán cho Davinci bởi vì thành thật mà nói, DaVinci rất tệ môn toán!


Bạn có thể chạy:

 npm run cli -- fineTunesList

Đợi cho đến khi status: 'pending' chuyển thành status: 'suceeded'


Chứng minh sự tinh chỉnh của chúng tôi đã dạy toán davinci

Khi status: 'suceeded' , hãy tìm tên fine_tuned_model .


  1. Chỉnh sửa .env để nói:
 OPENAI_API_KEY="sk-d0ntY0uD4reUs3MyK3yG3tY0urOwnFr0mOp0n41W36s1t3Yo" OPENAI_MODEL="<fine_tuned_model name>"


  1. Chạy:
 npm run cli -- completionsCreate "12+4`.


Đó là một câu trả lời ngớ ngẩn, nhưng bạn nên thấy rằng Davinci giỏi toán hơn.


Những gì chúng ta đã học được

  1. Cách sử dụng thư viện V4 của OpenAI.
  2. Cách tạo bộ dữ liệu "Tinh chỉnh" và tải nó lên.
  3. Cách tạo mô hình OpenAI mới.
  4. Làm thế nào để viết một CLI nhảm nhí.


Dự án này có thể được tìm thấy ở đây:

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