Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d3074e113e | |||
| 4dd974cf98 | |||
| 9a05c6ac77 | |||
| d410abe1b5 | |||
| b10b9c30f2 | |||
| 217116b819 | |||
| cdfceb0783 | |||
| c14c98c915 | |||
| 9529928f0a | |||
| 70019fa7bb |
+15
-11
@@ -1,13 +1,9 @@
|
||||
# This workflow will build a Java project with Gradle
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Java CI with Gradle
|
||||
name: Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
tags:
|
||||
- '[0-9]+.[0-9]+.[0-9]+'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -16,11 +12,19 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Test
|
||||
run: ./gradlew test
|
||||
|
||||
- name: Publish
|
||||
run: ./gradlew build publish
|
||||
env:
|
||||
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_NEXUS_USERNAME }}
|
||||
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_NEXUS_PASSWORD }}
|
||||
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }}
|
||||
ORG_GRADLE_PROJECT_signingInMemoeryKeyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
name: Publish Artifacts
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
- name: Publish Artifacts
|
||||
run: ./gradlew api:bintrayUpload client:bintrayUpload -DlibraryVersion=${GITHUB_REF##*/}
|
||||
env:
|
||||
BINTRAY_USER : ${{ secrets.BINTRAY_USER }}
|
||||
BINTRAY_KEY : ${{ secrets.BINTRAY_KEY }}
|
||||
@@ -1,15 +1,22 @@
|
||||

|
||||
# OpenAI-Java
|
||||
Java libraries for using OpenAI's GPT-3 api.
|
||||
|
||||
Includes the following artifacts:
|
||||
- `api` : request/response POJOs for the GPT-3 engine, completion, and search APIs.
|
||||
- `client` : a basic retrofit client for the GPT-3 endpoints
|
||||
- `client` : a basic retrofit client for the GPT-3 endpoints, includes the `api` module
|
||||
|
||||
as well as an example project using the client.
|
||||
|
||||
## Usage
|
||||
|
||||
### Importing into a gradle project
|
||||
`implementation 'com.theokanning.openai-gpt3-java:api:<version>'`
|
||||
or
|
||||
`implementation 'com.theokanning.openai-gpt3-java:client:<version>'`
|
||||
|
||||
### Using OpenAiService
|
||||
If you're looking for the fastest solution, import the `client` and use [OpenAiService](client/src/main/java/openai/OpenAiService.java).
|
||||
If you're looking for the fastest solution, import the `client` and use [OpenAiService](client/src/main/java/com/theokanning/openai/OpenAiService.java).
|
||||
```
|
||||
OpenAiService service = new OpenAiService(your_token)
|
||||
CompletionRequest completionRequest = CompletionRequest.builder()
|
||||
@@ -20,8 +27,8 @@ service.createCompletion("ada", completionRequest).getChoices().forEach(System.o
|
||||
```
|
||||
|
||||
### Using OpenAiApi Retrofit client
|
||||
If you're using retrofit, you can import the `client` module and use the [OpenAiApi](client/src/main/java/openai/OpenAiApi.java).
|
||||
You'll have to add your auth token as a header (see [AuthenticationInterceptor](client/src/main/java/openai/AuthenticationInterceptor.java))
|
||||
If you're using retrofit, you can import the `client` module and use the [OpenAiApi](client/src/main/java/com/theokanning/openai/OpenAiApi.java).
|
||||
You'll have to add your auth token as a header (see [AuthenticationInterceptor](client/src/main/java/com/theokanning/openai/AuthenticationInterceptor.java))
|
||||
and set your converter factory to use snake case and only include non-null fields.
|
||||
|
||||
### Using data classes only
|
||||
@@ -36,4 +43,4 @@ export OPENAI_TOKEN="sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
```
|
||||
|
||||
## License
|
||||
Published under the MIT License
|
||||
Published under the MIT License
|
||||
|
||||
+4
-69
@@ -1,77 +1,12 @@
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: "com.vanniktech.maven.publish"
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.projectlombok:lombok:1.18.12'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.12'
|
||||
}
|
||||
|
||||
ext {
|
||||
libraryVersion = System.getProperty("libraryVersion")
|
||||
compileJava {
|
||||
sourceCompatibility = '1.8'
|
||||
targetCompatibility = '1.8'
|
||||
}
|
||||
|
||||
version = libraryVersion
|
||||
group = 'com.theokanning.openai-gpt3-java'
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||
classifier = 'javadoc'
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
ApiPublication(MavenPublication) {
|
||||
from components.java
|
||||
artifact sourcesJar
|
||||
artifact javadocJar
|
||||
groupId project.group
|
||||
artifactId 'api'
|
||||
version libraryVersion
|
||||
pom {
|
||||
description = 'POJOs for the OpenAI GPT-3 API'
|
||||
name = 'api'
|
||||
url = 'https://github.com/theokanning/openai-java'
|
||||
developers {
|
||||
developer {
|
||||
id = "theokanning"
|
||||
name = "Theo Kanning"
|
||||
email = "theokanning@gmail.com"
|
||||
}
|
||||
}
|
||||
scm {
|
||||
url = "https://github.com/theokanning/openai-java"
|
||||
}
|
||||
licenses {
|
||||
license {
|
||||
name = "The MIT License"
|
||||
url = "https://www.mit.edu/~amini/LICENSE.md"
|
||||
distribution = "repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bintray {
|
||||
user = System.getenv("BINTRAY_USER")
|
||||
key = System.getenv("BINTRAY_KEY")
|
||||
|
||||
publications = ['ApiPublication']
|
||||
pkg {
|
||||
repo = 'openai-gpt3-java'
|
||||
name = 'api'
|
||||
vcsUrl = 'https://github.com/TheoKanning/openai-java.git'
|
||||
licenses = ["MIT"]
|
||||
publish = false
|
||||
version {
|
||||
name = libraryVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
POM_ARTIFACT_ID=api
|
||||
POM_NAME=api
|
||||
POM_DESCRIPTION=Basic java objects for the OpenAI GPT-3 API
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.theokanning.openai;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* A response when deleting an object
|
||||
*/
|
||||
@Data
|
||||
public class DeleteResult {
|
||||
/**
|
||||
* The id of the object.
|
||||
*/
|
||||
String id;
|
||||
|
||||
/**
|
||||
* The type of object deleted, for example "file" or "model"
|
||||
*/
|
||||
String object;
|
||||
|
||||
/**
|
||||
* True if successfully deleted
|
||||
*/
|
||||
boolean deleted;
|
||||
}
|
||||
@@ -20,6 +20,11 @@ import java.util.List;
|
||||
@Data
|
||||
public class CompletionRequest {
|
||||
|
||||
/**
|
||||
* The name of the model to use, only used if specifying a fine tuned model.
|
||||
*/
|
||||
String model;
|
||||
|
||||
/**
|
||||
* An optional prompt to complete from
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,7 @@ public class CompletionResult {
|
||||
String object;
|
||||
|
||||
/**
|
||||
* The creation time in epoch milliseconds.
|
||||
* The creation time in epoch seconds.
|
||||
*/
|
||||
long created;
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.theokanning.openai.file;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* A file uploaded to OpenAi
|
||||
*
|
||||
* https://beta.openai.com/docs/api-reference/files
|
||||
*/
|
||||
@Data
|
||||
public class File {
|
||||
|
||||
/**
|
||||
* The unique id of this file.
|
||||
*/
|
||||
String id;
|
||||
|
||||
/**
|
||||
* The type of object returned, should be "file".
|
||||
*/
|
||||
String object;
|
||||
|
||||
/**
|
||||
* File size in bytes.
|
||||
*/
|
||||
Long bytes;
|
||||
|
||||
/**
|
||||
* The creation time in epoch seconds.
|
||||
*/
|
||||
Long createdAt;
|
||||
|
||||
/**
|
||||
* The name of the file.
|
||||
*/
|
||||
String filename;
|
||||
|
||||
/**
|
||||
* Description of the file's purpose.
|
||||
*/
|
||||
String purpose;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.theokanning.openai.finetune;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* An object representing an event in the lifecycle of a fine-tuning job
|
||||
*
|
||||
* https://beta.openai.com/docs/api-reference/fine-tunes
|
||||
*/
|
||||
@Data
|
||||
public class FineTuneEvent {
|
||||
/**
|
||||
* The type of object returned, should be "fine-tune-event".
|
||||
*/
|
||||
String object;
|
||||
|
||||
/**
|
||||
* The creation time in epoch seconds.
|
||||
*/
|
||||
Long createdAt;
|
||||
|
||||
/**
|
||||
* The log level of this message.
|
||||
*/
|
||||
String level;
|
||||
|
||||
/**
|
||||
* The event message.
|
||||
*/
|
||||
String message;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.theokanning.openai.finetune;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A request for OpenAi to create a fine-tuned model
|
||||
* All fields except trainingFile are nullable.
|
||||
*
|
||||
* https://beta.openai.com/docs/api-reference/fine-tunes/create
|
||||
*/
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class FineTuneRequest {
|
||||
|
||||
/**
|
||||
* The ID of an uploaded file that contains training data.
|
||||
*/
|
||||
String trainingFile;
|
||||
|
||||
/**
|
||||
* The ID of an uploaded file that contains validation data.
|
||||
*/
|
||||
String validationFile;
|
||||
|
||||
/**
|
||||
* The name of the base model to fine-tune. You can select one of "ada", "babbage", "curie", or "davinci".
|
||||
* To learn more about these models, see the Engines documentation.
|
||||
*/
|
||||
String model;
|
||||
|
||||
/**
|
||||
* The number of epochs to train the model for. An epoch refers to one full cycle through the training dataset.
|
||||
*/
|
||||
Integer nEpochs;
|
||||
|
||||
/**
|
||||
* The batch size to use for training.
|
||||
* The batch size is the number of training examples used to train a single forward and backward pass.
|
||||
*
|
||||
* By default, the batch size will be dynamically configured to be ~0.2% of the number of examples in the training
|
||||
* set, capped at 256 - in general, we've found that larger batch sizes tend to work better for larger datasets.
|
||||
*/
|
||||
Integer batchSize;
|
||||
|
||||
/**
|
||||
* The learning rate multiplier to use for training.
|
||||
* The fine-tuning learning rate is the original learning rate used for pretraining multiplied by this value.
|
||||
*
|
||||
* By default, the learning rate multiplier is the 0.05, 0.1, or 0.2 depending on final batch_size
|
||||
* (larger learning rates tend to perform better with larger batch sizes).
|
||||
* We recommend experimenting with values in the range 0.02 to 0.2 to see what produces the best results.
|
||||
*/
|
||||
Double learningRateMultiplier;
|
||||
|
||||
/**
|
||||
* The weight to use for loss on the prompt tokens.
|
||||
* This controls how much the model tries to learn to generate the prompt
|
||||
* (as compared to the completion which always has a weight of 1.0),
|
||||
* and can add a stabilizing effect to training when completions are short.
|
||||
*
|
||||
* If prompts are extremely long (relative to completions), it may make sense to reduce this weight so as to
|
||||
* avoid over-prioritizing learning the prompt.
|
||||
*/
|
||||
Double promptLossWeight;
|
||||
|
||||
/**
|
||||
* If set, we calculate classification-specific metrics such as accuracy and F-1 score using the validation set
|
||||
* at the end of every epoch. These metrics can be viewed in the results file.
|
||||
*
|
||||
* In order to compute classification metrics, you must provide a validation_file.
|
||||
* Additionally, you must specify {@link FineTuneRequest#classificationNClasses} for multiclass
|
||||
* classification or {@link FineTuneRequest#classificationPositiveClass} for binary classification.
|
||||
*/
|
||||
Boolean computeClassificationMetrics;
|
||||
|
||||
/**
|
||||
* The number of classes in a classification task.
|
||||
*
|
||||
* This parameter is required for multiclass classification.
|
||||
*/
|
||||
Integer classificationNClasses; // todo verify snake case
|
||||
|
||||
/**
|
||||
* The positive class in binary classification.
|
||||
*
|
||||
* This parameter is needed to generate precision, recall, and F1 metrics when doing binary classification.
|
||||
*/
|
||||
String classificationPositiveClass;
|
||||
|
||||
/**
|
||||
* If this is provided, we calculate F-beta scores at the specified beta values.
|
||||
* The F-beta score is a generalization of F-1 score. This is only used for binary classification.
|
||||
*
|
||||
* With a beta of 1 (i.e. the F-1 score), precision and recall are given the same weight.
|
||||
* A larger beta score puts more weight on recall and less on precision.
|
||||
* A smaller beta score puts more weight on precision and less on recall.
|
||||
*/
|
||||
List<Double> classificationBetas;
|
||||
|
||||
/**
|
||||
* A string of up to 40 characters that will be added to your fine-tuned model name.
|
||||
*/
|
||||
String suffix;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.theokanning.openai.finetune;
|
||||
|
||||
import com.theokanning.openai.file.File;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An object describing an fine-tuned model. Returned by multiple fine-tune requests.
|
||||
*
|
||||
* https://beta.openai.com/docs/api-reference/fine-tunes
|
||||
*/
|
||||
@Data
|
||||
public class FineTuneResult {
|
||||
/**
|
||||
* The ID of the fine-tuning job.
|
||||
*/
|
||||
String id;
|
||||
|
||||
/**
|
||||
* The type of object returned, should be "fine-tune".
|
||||
*/
|
||||
String object;
|
||||
|
||||
/**
|
||||
* The name of the base model.
|
||||
*/
|
||||
String model;
|
||||
|
||||
/**
|
||||
* The creation time in epoch seconds.
|
||||
*/
|
||||
Long createdAt;
|
||||
|
||||
/**
|
||||
* List of events in this job's lifecycle. Null when getting a list of fine-tune jobs.
|
||||
*/
|
||||
List<FineTuneEvent> events;
|
||||
|
||||
/**
|
||||
* The ID of the fine-tuned model, null if tuning job is not finished.
|
||||
* This is the id used to call the model.
|
||||
*/
|
||||
String fineTunedModel;
|
||||
|
||||
/**
|
||||
* The specified hyper-parameters for the tuning job.
|
||||
*/
|
||||
HyperParameters hyperparams;
|
||||
|
||||
/**
|
||||
* The ID of the organization this model belongs to.
|
||||
*/
|
||||
String organizationId;
|
||||
|
||||
/**
|
||||
* Result files for this fine-tune job.
|
||||
*/
|
||||
List<File> resultFiles;
|
||||
|
||||
/**
|
||||
* The status os the fine-tune job. "pending", "succeeded", or "cancelled"
|
||||
*/
|
||||
String status;
|
||||
|
||||
/**
|
||||
* Training files for this fine-tune job.
|
||||
*/
|
||||
List<File> trainingFiles;
|
||||
|
||||
/**
|
||||
* The last update time in epoch seconds.
|
||||
*/
|
||||
Long updatedAt;
|
||||
|
||||
/**
|
||||
* Validation files for this fine-tune job.
|
||||
*/
|
||||
List<File> validationFiles;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.theokanning.openai.finetune;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Fine-tuning job hyperparameters
|
||||
*
|
||||
* https://beta.openai.com/docs/api-reference/fine-tunes
|
||||
*/
|
||||
@Data
|
||||
public class HyperParameters {
|
||||
|
||||
/**
|
||||
* The batch size to use for training.
|
||||
*/
|
||||
String batchSize;
|
||||
|
||||
/**
|
||||
* The learning rate multiplier to use for training.
|
||||
*/
|
||||
Double learningRateMultiplier;
|
||||
|
||||
/**
|
||||
* The number of epochs to train the model for.
|
||||
*/
|
||||
Integer nEpochs;
|
||||
|
||||
/**
|
||||
* The weight to use for loss on the prompt tokens.
|
||||
*/
|
||||
Double promptLossWeight;
|
||||
}
|
||||
+11
-4
@@ -1,14 +1,21 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4"
|
||||
classpath 'com.vanniktech:gradle-maven-publish-plugin:0.19.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withId("com.vanniktech.maven.publish") {
|
||||
mavenPublish {
|
||||
sonatypeHost = "S01"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-69
@@ -1,79 +1,17 @@
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: "com.vanniktech.maven.publish"
|
||||
|
||||
dependencies {
|
||||
api project(":api")
|
||||
api 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-jackson:2.9.0'
|
||||
|
||||
testImplementation(platform('org.junit:junit-bom:5.8.2'))
|
||||
testImplementation('org.junit.jupiter:junit-jupiter')
|
||||
}
|
||||
|
||||
ext {
|
||||
libraryVersion = System.getProperty("libraryVersion")
|
||||
compileJava {
|
||||
sourceCompatibility = '1.8'
|
||||
targetCompatibility = '1.8'
|
||||
}
|
||||
|
||||
version = libraryVersion
|
||||
group = 'com.theokanning.openai-gpt3-java'
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||
classifier = 'javadoc'
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
ClientPublication(MavenPublication) {
|
||||
from components.java
|
||||
artifact sourcesJar
|
||||
artifact javadocJar
|
||||
groupId project.group
|
||||
artifactId 'client'
|
||||
version libraryVersion
|
||||
pom {
|
||||
description = 'Basic retrofit client for OpenAI\'s GPT-3 API'
|
||||
name = 'client'
|
||||
url = 'https://github.com/theokanning/openai-java'
|
||||
developers {
|
||||
developer {
|
||||
id = "theokanning"
|
||||
name = "Theo Kanning"
|
||||
email = "theokanning@gmail.com"
|
||||
}
|
||||
}
|
||||
scm {
|
||||
url = "https://github.com/theokanning/openai-java"
|
||||
}
|
||||
licenses {
|
||||
license {
|
||||
name = "The MIT License"
|
||||
url = "https://www.mit.edu/~amini/LICENSE.md"
|
||||
distribution = "repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bintray {
|
||||
user = System.getenv("BINTRAY_USER")
|
||||
key = System.getenv("BINTRAY_KEY")
|
||||
|
||||
publications = ['ClientPublication']
|
||||
pkg {
|
||||
repo = 'openai-gpt3-java'
|
||||
name = 'client'
|
||||
vcsUrl = 'https://github.com/TheoKanning/openai-java.git'
|
||||
licenses = ["MIT"]
|
||||
publish = false
|
||||
version {
|
||||
name = libraryVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
POM_ARTIFACT_ID=client
|
||||
POM_NAME=client
|
||||
POM_DESCRIPTION=Basic retrofit client for OpenAI's GPT-3 API
|
||||
@@ -1,15 +1,18 @@
|
||||
package com.theokanning.openai;
|
||||
|
||||
import com.theokanning.openai.engine.Engine;
|
||||
import com.theokanning.openai.file.File;
|
||||
import com.theokanning.openai.finetune.FineTuneRequest;
|
||||
import com.theokanning.openai.finetune.FineTuneEvent;
|
||||
import com.theokanning.openai.finetune.FineTuneResult;
|
||||
import com.theokanning.openai.search.SearchRequest;
|
||||
import io.reactivex.Single;
|
||||
import com.theokanning.openai.completion.CompletionRequest;
|
||||
import com.theokanning.openai.completion.CompletionResult;
|
||||
import com.theokanning.openai.search.SearchResult;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Path;
|
||||
import okhttp3.MultipartBody;
|
||||
import okhttp3.RequestBody;
|
||||
import retrofit2.http.*;
|
||||
|
||||
public interface OpenAiApi {
|
||||
|
||||
@@ -24,4 +27,39 @@ public interface OpenAiApi {
|
||||
|
||||
@POST("/v1/engines/{engine_id}/search")
|
||||
Single<OpenAiResponse<SearchResult>> search(@Path("engine_id") String engineId, @Body SearchRequest request);
|
||||
|
||||
@GET("/v1/files")
|
||||
Single<OpenAiResponse<File>> listFiles();
|
||||
|
||||
@Multipart
|
||||
@POST("/v1/files")
|
||||
Single<File> uploadFile(@Part("purpose") RequestBody purpose, @Part MultipartBody.Part file);
|
||||
|
||||
@DELETE("/v1/files/{file_id}")
|
||||
Single<DeleteResult> deleteFile(@Path("file_id") String fileId);
|
||||
|
||||
@GET("/v1/files/{file_id}")
|
||||
Single<File> retrieveFile(@Path("file_id") String fileId);
|
||||
|
||||
@POST("/v1/fine-tunes")
|
||||
Single<FineTuneResult> createFineTune(@Body FineTuneRequest request);
|
||||
|
||||
@POST("/v1/completions")
|
||||
Single<CompletionResult> createFineTuneCompletion(@Body CompletionRequest request);
|
||||
|
||||
@GET("/v1/fine-tunes")
|
||||
Single<OpenAiResponse<FineTuneResult>> listFineTunes();
|
||||
|
||||
@GET("/v1/fine-tunes/{fine_tune_id}")
|
||||
Single<FineTuneResult> retrieveFineTune(@Path("fine_tune_id") String fineTuneId);
|
||||
|
||||
@POST("/v1/fine-tunes/{fine_tune_id}/cancel")
|
||||
Single<FineTuneResult> cancelFineTune(@Path("fine_tune_id") String fineTuneId);
|
||||
|
||||
@GET("/v1/fine-tunes/{fine_tune_id}/events")
|
||||
Single<OpenAiResponse<FineTuneEvent>> listFineTuneEvents(@Path("fine_tune_id") String fineTuneId);
|
||||
|
||||
@DELETE("/v1/models/{fine_tune_id}")
|
||||
Single<DeleteResult> deleteFineTune(@Path("fine_tune_id") String fineTuneId);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,9 +4,12 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.theokanning.openai.file.File;
|
||||
import com.theokanning.openai.finetune.FineTuneRequest;
|
||||
import com.theokanning.openai.finetune.FineTuneEvent;
|
||||
import com.theokanning.openai.finetune.FineTuneResult;
|
||||
import com.theokanning.openai.search.SearchRequest;
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.*;
|
||||
import com.theokanning.openai.completion.CompletionRequest;
|
||||
import com.theokanning.openai.completion.CompletionResult;
|
||||
import com.theokanning.openai.engine.Engine;
|
||||
@@ -58,4 +61,53 @@ public class OpenAiService {
|
||||
public List<SearchResult> search(String engineId, SearchRequest request) {
|
||||
return api.search(engineId, request).blockingGet().data;
|
||||
}
|
||||
|
||||
public List<File> listFiles() {
|
||||
return api.listFiles().blockingGet().data;
|
||||
}
|
||||
|
||||
public File uploadFile(String purpose, String filepath) {
|
||||
java.io.File file = new java.io.File(filepath);
|
||||
RequestBody purposeBody = RequestBody.create(okhttp3.MultipartBody.FORM, purpose);
|
||||
RequestBody fileBody = RequestBody.create(MediaType.parse("text"), file);
|
||||
MultipartBody.Part body = MultipartBody.Part.createFormData("file", filepath, fileBody);
|
||||
|
||||
return api.uploadFile(purposeBody, body).blockingGet();
|
||||
}
|
||||
|
||||
public DeleteResult deleteFile(String fileId) {
|
||||
return api.deleteFile(fileId).blockingGet();
|
||||
}
|
||||
|
||||
public File retrieveFile(String fileId) {
|
||||
return api.retrieveFile(fileId).blockingGet();
|
||||
}
|
||||
|
||||
public FineTuneResult createFineTune(FineTuneRequest request) {
|
||||
return api.createFineTune(request).blockingGet();
|
||||
}
|
||||
|
||||
public CompletionResult createFineTuneCompletion(CompletionRequest request) {
|
||||
return api.createFineTuneCompletion(request).blockingGet();
|
||||
}
|
||||
|
||||
public List<FineTuneResult> listFineTunes() {
|
||||
return api.listFineTunes().blockingGet().data;
|
||||
}
|
||||
|
||||
public FineTuneResult retrieveFineTune(String fineTuneId) {
|
||||
return api.retrieveFineTune(fineTuneId).blockingGet();
|
||||
}
|
||||
|
||||
public FineTuneResult cancelFineTune(String fineTuneId) {
|
||||
return api.cancelFineTune(fineTuneId).blockingGet();
|
||||
}
|
||||
|
||||
public List<FineTuneEvent> listFineTuneEvents(String fineTuneId) {
|
||||
return api.listFineTuneEvents(fineTuneId).blockingGet().data;
|
||||
}
|
||||
|
||||
public DeleteResult deleteFineTune(String fineTuneId) {
|
||||
return api.deleteFineTune(fineTuneId).blockingGet();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.theokanning.openai;
|
||||
|
||||
import com.theokanning.openai.file.File;
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class FileTest {
|
||||
static String filePath = "src/test/resources/fine-tuning-data.jsonl";
|
||||
|
||||
String token = System.getenv("OPENAI_TOKEN");
|
||||
OpenAiService service = new OpenAiService(token);
|
||||
static String fileId;
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
void uploadFile() throws Exception {
|
||||
File file = service.uploadFile("fine-tune", filePath);
|
||||
fileId = file.getId();
|
||||
|
||||
assertEquals("fine-tune", file.getPurpose());
|
||||
assertEquals(filePath, file.getFilename());
|
||||
|
||||
// wait for file to be processed
|
||||
TimeUnit.SECONDS.sleep(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
void listFiles() {
|
||||
List<File> files = service.listFiles();
|
||||
|
||||
assertTrue(files.stream().anyMatch(file -> file.getId().equals(fileId)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
void retrieveFile() {
|
||||
File file = service.retrieveFile(fileId);
|
||||
|
||||
assertEquals(filePath, file.getFilename());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
void deleteFile() {
|
||||
DeleteResult result = service.deleteFile(fileId);
|
||||
assertTrue(result.isDeleted());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.theokanning.openai;
|
||||
|
||||
import com.theokanning.openai.finetune.FineTuneRequest;
|
||||
import com.theokanning.openai.finetune.FineTuneEvent;
|
||||
import com.theokanning.openai.finetune.FineTuneResult;
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class FineTuneTest {
|
||||
static OpenAiService service;
|
||||
static String fileId;
|
||||
static String fineTuneId;
|
||||
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
String token = System.getenv("OPENAI_TOKEN");
|
||||
service = new OpenAiService(token);
|
||||
fileId = service.uploadFile("fine-tune", "src/test/resources/fine-tuning-data.jsonl").getId();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void teardown() {
|
||||
service.deleteFile(fileId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
void createFineTune() {
|
||||
FineTuneRequest request = FineTuneRequest.builder()
|
||||
.trainingFile(fileId)
|
||||
.model("ada")
|
||||
.build();
|
||||
|
||||
FineTuneResult fineTune = service.createFineTune(request);
|
||||
fineTuneId = fineTune.getId();
|
||||
|
||||
assertEquals("pending", fineTune.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
void listFineTunes() {
|
||||
List<FineTuneResult> fineTunes = service.listFineTunes();
|
||||
|
||||
assertTrue(fineTunes.stream().anyMatch(fineTune -> fineTune.getId().equals(fineTuneId)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
void listFineTuneEvents() {
|
||||
List<FineTuneEvent> events = service.listFineTuneEvents(fineTuneId);
|
||||
|
||||
assertFalse(events.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
void retrieveFineTune() {
|
||||
FineTuneResult fineTune = service.retrieveFineTune(fineTuneId);
|
||||
|
||||
assertEquals("ada", fineTune.getModel());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
void cancelFineTune() {
|
||||
FineTuneResult fineTune = service.cancelFineTune(fineTuneId);
|
||||
|
||||
assertEquals("cancelled", fineTune.getStatus());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
{"prompt": "prompt", "completion": "text"}
|
||||
{"prompt": "prompt", "completion": "text"}
|
||||
@@ -0,0 +1,14 @@
|
||||
GROUP=com.theokanning.openai-gpt3-java
|
||||
VERSION_NAME=0.5.0
|
||||
|
||||
POM_URL=https://github.com/theokanning/openai-java
|
||||
POM_SCM_URL=https://github.com/theokanning/openai-java
|
||||
POM_SCM_CONNECTION=https://github.com/theokanning/openai-java.git
|
||||
POM_SCM_DEV_CONNECTION=https://github.com/theokanning/openai-java.git
|
||||
|
||||
POM_LICENSE_NAME=The MIT License
|
||||
POM_LICENSE_URL=https://www.mit.edu/~amini/LICENSE.md
|
||||
POM_LICENSE_DIST=repo
|
||||
|
||||
POM_DEVELOPER_ID=theokanning
|
||||
POM_DEVELOPER_NAME=Theo Kanning
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
Reference in New Issue
Block a user