Skip to content

Commit e0046e5

Browse files
authored
Merge pull request #349 from alexrudall/fine-tuning-jobs
Add fine-tuning jobs and remove deprecated finetunes
2 parents 6ec239f + 1a09ecd commit e0046e5

25 files changed

+701
-61369
lines changed

README.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -308,22 +308,22 @@ client.files.content(id: "file-123")
308308
client.files.delete(id: "file-123")
309309
```
310310

311-
### Fine-tunes
311+
### Finetunes
312312

313313
Upload your fine-tuning data in a `.jsonl` file as above and get its ID:
314314

315315
```ruby
316-
response = client.files.upload(parameters: { file: "path/to/sentiment.jsonl", purpose: "fine-tune" })
317-
file_id = response["id"]
316+
response = client.files.upload(parameters: { file: "path/to/sarcasm.jsonl", purpose: "fine-tune" })
317+
file_id = JSON.parse(response.body)["id"]
318318
```
319319

320-
You can then use this file ID to create a fine-tune model:
320+
You can then use this file ID to create a fine tuning job:
321321

322322
```ruby
323323
response = client.finetunes.create(
324324
parameters: {
325325
training_file: file_id,
326-
model: "ada"
326+
model: "gpt-3.5-turbo-0613"
327327
})
328328
fine_tune_id = response["id"]
329329
```
@@ -342,21 +342,22 @@ response = client.finetunes.retrieve(id: fine_tune_id)
342342
fine_tuned_model = response["fine_tuned_model"]
343343
```
344344

345-
This fine-tuned model name can then be used in chats:
345+
This fine-tuned model name can then be used in completions:
346346

347347
```ruby
348-
response = client.chat(
348+
response = client.completions(
349349
parameters: {
350350
model: fine_tuned_model,
351-
messages: [{ role: "user", content: "I love Mondays!"}]
352-
})
353-
puts response.dig("choices", 0, "message", "content")
351+
prompt: "I love Mondays!"
352+
}
353+
)
354+
response.dig("choices", 0, "text")
354355
```
355356

356-
You can delete the fine-tuned model when you are done with it:
357+
You can also capture the events for a job:
357358

358-
```ruby
359-
client.finetunes.delete(fine_tuned_model: fine_tuned_model)
359+
```
360+
client.finetunes.list_events(id: fine_tune_id)
360361
```
361362

362363
### Image Generation

lib/openai/finetunes.rb

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,23 @@ def initialize(client:)
55
end
66

77
def list
8-
@client.get(path: "/fine-tunes")
8+
@client.get(path: "/fine_tuning/jobs")
99
end
1010

1111
def create(parameters: {})
12-
@client.json_post(path: "/fine-tunes", parameters: parameters)
12+
@client.json_post(path: "/fine_tuning/jobs", parameters: parameters)
1313
end
1414

1515
def retrieve(id:)
16-
@client.get(path: "/fine-tunes/#{id}")
16+
@client.get(path: "/fine_tuning/jobs/#{id}")
1717
end
1818

1919
def cancel(id:)
20-
@client.multipart_post(path: "/fine-tunes/#{id}/cancel")
20+
@client.json_post(path: "/fine_tuning/jobs/#{id}/cancel", parameters: {})
2121
end
2222

23-
def events(id:)
24-
@client.get(path: "/fine-tunes/#{id}/events")
25-
end
26-
27-
def delete(fine_tuned_model:)
28-
if fine_tuned_model.start_with?("ft-")
29-
raise ArgumentError, "Please give a fine_tuned_model name, not a fine-tune ID"
30-
end
31-
32-
@client.delete(path: "/models/#{fine_tuned_model}")
23+
def list_events(id:)
24+
@client.get(path: "/fine_tuning/jobs/#{id}/events")
3325
end
3426
end
3527
end

lib/openai/http.rb

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,40 @@
33
module OpenAI
44
module HTTP
55
def get(path:)
6-
to_json(conn.get(uri(path: path)) do |req|
6+
parse_jsonl(conn.get(uri(path: path)) do |req|
77
req.headers = headers
88
end&.body)
99
end
1010

1111
def json_post(path:, parameters:)
12-
to_json(conn.post(uri(path: path)) do |req|
12+
conn.post(uri(path: path)) do |req|
1313
configure_json_post_request(req, parameters)
14-
end&.body)
14+
end&.body
1515
end
1616

1717
def multipart_post(path:, parameters: nil)
18-
to_json(conn(multipart: true).post(uri(path: path)) do |req|
18+
conn(multipart: true).post(uri(path: path)) do |req|
1919
req.headers = headers.merge({ "Content-Type" => "multipart/form-data" })
2020
req.body = multipart_parameters(parameters)
21-
end&.body)
21+
end&.body
2222
end
2323

2424
def delete(path:)
25-
to_json(conn.delete(uri(path: path)) do |req|
25+
conn.delete(uri(path: path)) do |req|
2626
req.headers = headers
27-
end&.body)
27+
end&.body
2828
end
2929

3030
private
3131

32-
def to_json(string)
33-
return unless string
32+
def parse_jsonl(response)
33+
return unless response
34+
return response unless response.is_a?(String)
3435

35-
JSON.parse(string)
36-
rescue JSON::ParserError
3736
# Convert a multiline string of JSON objects to a JSON array.
38-
JSON.parse(string.gsub("}\n{", "},{").prepend("[").concat("]"))
37+
response = response.gsub("}\n{", "},{").prepend("[").concat("]")
38+
39+
JSON.parse(response)
3940
end
4041

4142
# Given a proc, returns an outer proc that can be used to iterate over a JSON stream of chunks.
@@ -64,6 +65,7 @@ def conn(multipart: false)
6465
f.options[:timeout] = @request_timeout
6566
f.request(:multipart) if multipart
6667
f.response :raise_error
68+
f.response :json
6769
end
6870
end
6971

spec/fixtures/cassettes/fine_tune_job_files_upload.yml

Lines changed: 109 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)