Skip to content

Commit

Permalink
Merge pull request #27 from henomis/feat/implement-new-fine-tuning-API
Browse files Browse the repository at this point in the history
feat: implement new fine tuning API
  • Loading branch information
otiai10 committed Aug 26, 2023
2 parents 55062f1 + 52a6a65 commit db9573c
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 8 deletions.
48 changes: 48 additions & 0 deletions all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,54 @@ func testserverV1() *httptest.Server {
io.Copy(w, f)
}
})
mux.HandleFunc("/fine_tuning/jobs", func(w http.ResponseWriter, req *http.Request) {
switch req.Method {
case http.MethodPost:
f, err := os.Open("./testdata/finetuning-create.json")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
defer f.Close()
io.Copy(w, f)
}
})
mux.HandleFunc("/fine_tuning/jobs/abcdefghi/cancel", func(w http.ResponseWriter, req *http.Request) {
switch req.Method {
case http.MethodPost:
f, err := os.Open("./testdata/finetuning-cancel.json")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
defer f.Close()
io.Copy(w, f)
}
})
mux.HandleFunc("/fine_tuning/jobs/abcdefghi", func(w http.ResponseWriter, req *http.Request) {
switch req.Method {
case http.MethodGet:
f, err := os.Open("./testdata/finetuning-retrieve.json")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
defer f.Close()
io.Copy(w, f)
}
})
mux.HandleFunc("/fine_tuning/jobs/abcdefghi/events", func(w http.ResponseWriter, req *http.Request) {
switch req.Method {
case http.MethodGet:
f, err := os.Open("./testdata/finetuning-event-list.json")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
defer f.Close()
io.Copy(w, f)
}
})
mux.HandleFunc("/chat/completions", func(w http.ResponseWriter, req *http.Request) {
f, err := os.Open("./testdata/chat-completion.json")
if err != nil {
Expand Down
59 changes: 51 additions & 8 deletions endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,51 +141,57 @@ func (client *Client) CreateModeration(ctx context.Context, body ModerationCreat
}

// CreateFineTune: POST https://api.openai.com/v1/fine-tunes
// Deprecated: you should consider using the updating fine-tuning API https://platform.openai.com/docs/guides/fine-tuning
// Creates a job that fine-tunes a specified model from a given dataset.
// Response includes details of the enqueued job including job status and the name of the fine-tuned models once complete.
// Learn more about Fine-tuning: https://beta.openai.com/docs/guides/fine-tuning
// See https://beta.openai.com/docs/api-reference/fine-tunes/create
// Learn more about Fine-tuning: https://platform.openai.com/docs/api-reference/fine-tuning
// See https://platform.openai.com/docs/api-reference/fine-tunes/create
func (client *Client) CreateFineTune(ctx context.Context, body FineTuneCreateRequestBody) (resp FineTuneCreateResponse, err error) {
p := "/fine-tunes"
return call(ctx, client, http.MethodPost, p, body, resp, nil)
}

// ListFineTunes: GET https://api.openai.com/v1/fine-tunes
// Deprecated: you should consider using the updating fine-tuning API https://platform.openai.com/docs/guides/fine-tuning
// List your organization's fine-tuning jobs.
// See https://beta.openai.com/docs/api-reference/fine-tunes/list
// See https://platform.openai.com/docs/api-reference/fine-tunes/list
func (client *Client) ListFineTunes(ctx context.Context) (resp FineTuneListResponse, err error) {
p := "/fine-tunes"
return call(ctx, client, http.MethodGet, p, nil, resp, nil)
}

// RetrieveFineTune: GET https://api.openai.com/v1/fine-tunes/{fine_tune_id}
// Deprecated: you should consider using the updating fine-tuning API https://platform.openai.com/docs/guides/fine-tuning
// Gets info about the fine-tune job.
// Learn more about Fine-tuning https://beta.openai.com/docs/guides/fine-tuning
// See https://beta.openai.com/docs/api-reference/fine-tunes/retrieve
// Learn more about Fine-tuning https://platform.openai.com/docs/api-reference/fine-tuning
// See https://platform.openai.com/docs/api-reference/fine-tunes/retrieve
func (client *Client) RetrieveFineTune(ctx context.Context, id string) (resp FineTuneRetrieveResponse, err error) {
p := fmt.Sprintf("/fine-tunes/%s", id)
return call(ctx, client, http.MethodGet, p, nil, resp, nil)
}

// CancelFineTune: POST https://api.openai.com/v1/fine-tunes/{fine_tune_id}/cancel
// Deprecated: you should consider using the updating fine-tuning API https://platform.openai.com/docs/guides/fine-tuning
// Immediately cancel a fine-tune job.
// See https://beta.openai.com/docs/api-reference/fine-tunes/cancel
// See https://platform.openai.com/docs/api-reference/fine-tunes/cancel
func (client *Client) CancelFineTune(ctx context.Context, id string) (resp FineTuneCancelResponse, err error) {
p := fmt.Sprintf("/fine-tunes/%s/cancel", id)
return call(ctx, client, http.MethodPost, p, nil, resp, nil)
}

// ListFineTuneEvents: GET https://api.openai.com/v1/fine-tunes/{fine_tune_id}/events
// Deprecated: you should consider using the updating fine-tuning API https://platform.openai.com/docs/guides/fine-tuning
// Get fine-grained status updates for a fine-tune job.
// See https://beta.openai.com/docs/api-reference/fine-tunes/events
// See https://platform.openai.com/docs/api-reference/fine-tunes/events
func (client *Client) ListFineTuneEvents(ctx context.Context, id string) (resp FineTuneListEventsResponse, err error) {
p := fmt.Sprintf("/fine-tunes/%s/events", id)
return call(ctx, client, http.MethodGet, p, nil, resp, nil)
}

// DeleteFineTuneModel: DELETE https://api.openai.com/v1/models/{model}
// Deprecated: you should consider using the updating fine-tuning API https://platform.openai.com/docs/guides/fine-tuning
// Delete a fine-tuned model. You must have the Owner role in your organization.
// See https://beta.openai.com/docs/api-reference/fine-tunes/delete-model
// See https://platform.openai.com/docs/api-reference/fine-tunes/delete-model
func (client *Client) DeleteFineTuneModel(ctx context.Context, id string) (resp FineTuneDeleteModelResponse, err error) {
p := fmt.Sprintf("/models/%s", id)
return call(ctx, client, http.MethodDelete, p, nil, resp, nil)
Expand All @@ -208,3 +214,40 @@ func (client *Client) ChatCompletion(ctx context.Context, body ChatCompletionReq
}
return call(ctx, client, http.MethodPost, p, body, resp, nil)
}

// CreateFineTuning: POST https://api.openai.com/v1/fine_tuning/jobs
// Creates a job that fine-tunes a specified model from a given dataset.
// Response includes details of the enqueued job including job status and the name of the fine-tuned models once complete.
// Learn more about Fine-tuning: https://platform.openai.com/docs/guides/fine-tuning
// See https://platform.openai.com/docs/api-reference/fine-tuning/create
func (client *Client) CreateFineTuning(ctx context.Context, body FineTuningCreateRequestBody) (resp FineTuningJob, err error) {
p := "/fine_tuning/jobs"
return call(ctx, client, http.MethodPost, p, body, resp, nil)
}

// CancelFineTuning: POST https://api.openai.com/v1/fine_tuning/{fine_tuning_job_id}/cancel
// Immediately cancel a fine tuning job.
// Learn more about Fine-tuning https://platform.openai.com/docs/guides/fine-tuning
// See https://platform.openai.com/docs/api-reference/fine-tuning/cancel
func (client *Client) CancelFineTuning(ctx context.Context, id string) (resp FineTuningJob, err error) {
p := "/fine_tuning/jobs/" + id + "/cancel"
return call(ctx, client, http.MethodPost, p, nil, resp, nil)
}

// RetrieveFineTuning: GET https://api.openai.com/v1/fine_tuning/jobs//{fine_tuning_job_id}
// Gets info about the fine-tuning job.
// Learn more about Fine-tuning https://platform.openai.com/docs/guides/fine-tuning
// See https://platform.openai.com/docs/api-reference/fine-tuning/retrieve
func (client *Client) RetrieveFineTuning(ctx context.Context, id string) (resp FineTuningJob, err error) {
p := fmt.Sprintf("/fine_tuning/jobs/%s", id)
return call(ctx, client, http.MethodGet, p, nil, resp, nil)
}

// ListFineTuningEvents: GET https://api.openai.com/v1/fine_tuning/jobs/{fine_tuning_job_id}/events
// Get fine-grained status updates for a fine-tuning job.
// Learn more about Fine-tuning https://platform.openai.com/docs/guides/fine-tuning
// See https://platform.openai.com/docs/api-reference/fine-tuning/list-events
func (client *Client) ListFineTuningEvents(ctx context.Context, id string) (resp FineTuningListEventsResponse, err error) {
p := fmt.Sprintf("/fine_tuning/jobs/%s/events", id)
return call(ctx, client, http.MethodGet, p, nil, resp, nil)
}
45 changes: 45 additions & 0 deletions finetuning.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package openaigo

type FineTuningJob struct {
ID string `json:"id"`
Object string `json:"object"`
CreatedAt int64 `json:"created_at"`
FinishedAt int64 `json:"finished_at"`
Model string `json:"model"`
FineTunedModel string `json:"fine_tuned_model,omitempty"`
OrganizationID string `json:"organization_id"`
Status string `json:"status"`
Hyperparameters Hyperparameters `json:"hyperparameters"`
TrainingFile string `json:"training_file"`
ValidationFile string `json:"validation_file,omitempty"`
ResultFiles []string `json:"result_files"`
TrainedTokens int `json:"trained_tokens"`
}

type Hyperparameters struct {
Epochs int `json:"n_epochs"`
}

type FineTuningCreateRequestBody struct {
TrainingFile string `json:"training_file"`
ValidationFile string `json:"validation_file,omitempty"`
Model string `json:"model,omitempty"`
Hyperparameters *Hyperparameters `json:"hyperparameters,omitempty"`
Suffix string `json:"suffix,omitempty"`
}

type FineTuningListEventsResponse struct {
Object string `json:"object"`
Data []FineTuneEvent `json:"data"`
HasMore bool `json:"has_more"`
}

type FineTuningEvent struct {
Object string `json:"object"`
ID string `json:"id"`
CreatedAt int `json:"created_at"`
Level string `json:"level"`
Message string `json:"message"`
Data any `json:"data"`
Type string `json:"type"`
}
42 changes: 42 additions & 0 deletions finetuning_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package openaigo

import (
"context"
"testing"

. "github.com/otiai10/mint"
)

func TestClient_CreateFineTuning(t *testing.T) {
client := NewClient("")
client.BaseURL = mockserver.URL
res, err := client.CreateFineTuning(context.TODO(), FineTuningCreateRequestBody{
TrainingFile: "file-XGinujblHPwGLSztz8cPS8XY",
})
Expect(t, err).ToBe(nil)
Expect(t, res).TypeOf("openaigo.FineTuningJob")
}

func TestClient_RetrieveFineTuning(t *testing.T) {
client := NewClient("")
client.BaseURL = mockserver.URL
res, err := client.RetrieveFineTuning(context.TODO(), "abcdefghi")
Expect(t, err).ToBe(nil)
Expect(t, res).TypeOf("openaigo.FineTuningJob")
}

func TestClient_CancelFineTuning(t *testing.T) {
client := NewClient("")
client.BaseURL = mockserver.URL
res, err := client.CancelFineTuning(context.TODO(), "abcdefghi")
Expect(t, err).ToBe(nil)
Expect(t, res).TypeOf("openaigo.FineTuningJob")
}

func TestClient_ListFineTuningEvents(t *testing.T) {
client := NewClient("")
client.BaseURL = mockserver.URL
res, err := client.ListFineTuningEvents(context.TODO(), "abcdefghi")
Expect(t, err).ToBe(nil)
Expect(t, res).TypeOf("openaigo.FineTuningListEventsResponse")
}
20 changes: 20 additions & 0 deletions testdata/finetuning-cancel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"object": "fine_tuning.job",
"id": "ft-zRdUkP4QeZqeYjDcQL0wwam1",
"model": "davinci-002",
"created_at": 1692661014,
"finished_at": 1692661190,
"fine_tuned_model": "ft:davinci-002:my-org:custom_suffix:7q8mpxmy",
"organization_id": "org-123",
"result_files": [
"file-abc123"
],
"status": "succeeded",
"validation_file": null,
"training_file": "file-abc123",
"hyperparameters": {
"n_epochs": 4
},
"trained_tokens": 5768
}

20 changes: 20 additions & 0 deletions testdata/finetuning-create.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"object": "fine_tuning.job",
"id": "ft-zRdUkP4QeZqeYjDcQL0wwam1",
"model": "davinci-002",
"created_at": 1692661014,
"finished_at": 1692661190,
"fine_tuned_model": "ft:davinci-002:my-org:custom_suffix:7q8mpxmy",
"organization_id": "org-123",
"result_files": [
"file-abc123"
],
"status": "succeeded",
"validation_file": null,
"training_file": "file-abc123",
"hyperparameters": {
"n_epochs": 4
},
"trained_tokens": 5768
}

24 changes: 24 additions & 0 deletions testdata/finetuning-event-list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"object": "list",
"data": [
{
"object": "fine_tuning.job.event",
"id": "ft-event-ddTJfwuMVpfLXseO0Am0Gqjm",
"created_at": 1692407401,
"level": "info",
"message": "Fine tuning job successfully completed",
"data": null,
"type": "message"
},
{
"object": "fine_tuning.job.event",
"id": "ft-event-tyiGuB72evQncpH87xe505Sv",
"created_at": 1692407400,
"level": "info",
"message": "New fine-tuned model created: ft:gpt-3.5-turbo:openai::7p4lURel",
"data": null,
"type": "message"
}
],
"has_more": true
}
20 changes: 20 additions & 0 deletions testdata/finetuning-retrieve.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"object": "fine_tuning.job",
"id": "ft-zRdUkP4QeZqeYjDcQL0wwam1",
"model": "davinci-002",
"created_at": 1692661014,
"finished_at": 1692661190,
"fine_tuned_model": "ft:davinci-002:my-org:custom_suffix:7q8mpxmy",
"organization_id": "org-123",
"result_files": [
"file-abc123"
],
"status": "succeeded",
"validation_file": null,
"training_file": "file-abc123",
"hyperparameters": {
"n_epochs": 4
},
"trained_tokens": 5768
}

0 comments on commit db9573c

Please sign in to comment.