OpenAIのGPTとDALL·Eでテーマから歌詞と画像を生成する

やっぱ自分でもさわってみんとあかんということで、OpenAIを使ったプログラムを書いてみました。
とりあえず、テキストと画像を生成します。

JavaAPI使ってみます。中身はRetrofit。
https://github.com/TheoKanning/openai-java

MavenやGradleでこんな感じの依存を設定します。

<dependency>
    <groupId>com.theokanning.openai-gpt3-java</groupId>
    <artifactId>client</artifactId>
    <version>0.9.0</version>
</dependency>

まずはOpenAiServiceのオブジェクトをとってきます。OpenAIのサイトでアカウントを作ってトークンつくってください。
https://openai.com/api/

OpenAiService service = new OpenAiService(TOKEN);

Free Trialで$18分つかえるようになっています。これ作るのに試すだけで$0.25=30円使っているので、本格的なアプリを作ろうと思うと結構かかりそうな気配

ChatGPTのようなことをしたければ、createCompletionを使います。

CompletionRequest completionRequest = CompletionRequest.builder()
        .model("text-babbage-001")
        .prompt("次のテーマで歌詞を作って。\n" + prompt)
        .temperature(0.9)
        .echo(false)
        .user("testing")
        .maxTokens(500)
        .build();
CompletionResult result = service.createCompletion(completionRequest);

モデルにはtext-babbage-001のほかtext-ada-001text-curie-001text-davinci-003が指定できます。abc順にどんどん賢く、高くなっていきます。adaが一番安く、davinciが一番賢くて高い。開発時にはadaを使って本番ではdavinciやcurieを使うみたいな使い分けが必要そうです。
プロンプトには、生成する事柄の例を指定します。ここでは「次のテーマで歌詞を作って。」としてますが、もっと丁寧に設定すれば生成結果もまともになる気がします。

画像生成はcreateImageで。

CreateImageRequest req = CreateImageRequest.builder()
        .prompt(prompt)
        .n(1)
        .responseFormat("b64_json") // or b64_json, url
        .size("512x512")
        .build();
ImageResult imageResult = service.createImage(req);

サイズは512x512の他に256x2561024x1024が選べます。フォーマットとしてurlを選べば、画像のURLが送られてくるので、Webアプリではそっちでいいかもしれません。

動作はこんな感じ。実際はレスポンスに8秒くらい待ちます。

ソースコード全体はこんな感じ。

package naoki.openai;

import com.theokanning.openai.OpenAiService;
import com.theokanning.openai.completion.CompletionRequest;
import com.theokanning.openai.completion.CompletionResult;
import com.theokanning.openai.image.CreateImageRequest;
import com.theokanning.openai.image.ImageResult;
import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.util.Base64;
import javax.swing.*;

public class Mavenproject1openai {
    static final String TOKEN = "your openai token";
    public static void main(String[] args) {
        Image def = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
        var f = new JFrame("歌詞と画像を生成");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        var label = new JLabel(new ImageIcon(def));
        f.add(BorderLayout.EAST,label);
        var resultText = new JTextArea();
        f.add(resultText);
        var top = new JPanel();
        var promptText = new JTextField(50);
        top.add(promptText);
        var button = new JButton("生成");
        top.add(button);
        f.add(BorderLayout.NORTH, top);
        f.setSize(1000, 600);
        f.setVisible(true);
        
        OpenAiService service = new OpenAiService(TOKEN);

        button.addActionListener(al -> {
            System.out.println("\nCreating completion...");
            String prompt = promptText.getText();
            
            CompletionRequest completionRequest = CompletionRequest.builder()
                    .model("text-babbage-001")
                    .prompt("次のテーマで歌詞を作って。\n" + prompt)
                    .temperature(0.9)
                    .echo(false)
                    .user("testing")
                    .maxTokens(500)
                    .build();
            CompletionResult result = service.createCompletion(completionRequest);
            resultText.setText(result.getChoices().get(0).getText());

            CreateImageRequest req = CreateImageRequest.builder()
                    .prompt(prompt)
                    .n(1)
                    .responseFormat("b64_json") // or b64_json, url
                    .size("512x512")
                    .build();
            ImageResult imageResult = service.createImage(req);
            byte[] data = Base64.getDecoder().decode(imageResult.getData().get(0).getB64Json());     
            label.setIcon(new ImageIcon(data));
        });
        
    }
}