🤖

OpenAI APIについてすこーしだけ調べてみた

2023/12/04に公開

この記事はモニクル Advent Calendar 2023の4日目の記事です。

こんばんは、@kubioです。
モニクルでマネイロの開発を行なっています。

フルマラソンを走ったあと眠気と戦いながらこの記事を書いています。
(沿道の皆さんの応援もあり無事完走しました!!!すべての人に感謝を)

去年末くらいからChatGPTが話題になり、それに乗っかって色々使ったりはしていましたが、OpenAI APIの利用などはできていなかったので、せっかくの締切駆動のチャンスなのでこれを題材に記事を書いてみようと考えました。

そこですこーしだけ、ほんのすこーしだけですが調査したので、初心者なりにつらつらと書き連ねていきたいと思います。

OpenAI API

https://platform.openai.com/docs/quickstart?context=python
よりgoogle翻訳で翻訳したものを引用します。

OpenAI API は、開発者が OpenAI の最先端モデルを利用してアプリケーション内にインテリジェンス レイヤーを作成するためのシンプルなインターフェイスを提供します。Chat Completions エンドポイントは ChatGPT を強化し、テキストを入力として受け取り、GPT-4 などのモデルを使用して出力を生成する簡単な方法を提供します。

OpenAIのモデルをアプリケーションに組み込むために便利な機能を提供してくれている、という感じでしょうか。

左カラムのメニューを見てみると色々な機能がありそうです。

今回は「Chat Completions API」と「Audio API」あたりについて書いてみたいと思います。

事前準備

API Keyの発行

何はともあれ、APIを利用するためにはキーの発行が必要です。
簡単なのでログイン後、以下のページから「Create new secret key」で発行してください。
https://platform.openai.com/api-keys

bunのセットアップ

今回はbunでコードの実行を行なったので、ざっくり以下にセットアップ手順を記載します。

  1. bunのインストールと初期構築
    https://bun.sh/docs/installation
$ brew tap oven-sh/bun
$ brew install bun
$ bun init
package name: handson-openai-api
entry point(index.ts): #そのままEnter
Done! A package.json file was saved in the current directory.
 + index.ts
 + .gitignore
 + tsconfig.json (for editor auto-complete)
 + README.md

To get started, run:
  bun run index.ts
  1. openai パッケージの導入
$ cd handson-openai-api
$ bun add openai@^4.0.0

Chat Completions API

https://platform.openai.com/docs/guides/text-generation/chat-completions-api

入力されたメッセージからモデルが生成したメッセージを出力するAPIです。

今回は単一のメッセージに応答するシンプルなコードを書いてみます。

index.ts
import OpenAI from "openai";

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

const chatCompletion = await openai.chat.completions.create({
  model: "gpt-3.5-turbo",
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    {
      role: "user",
      content: "Hello.",
    },
  ],
  temperature: 1,
  max_tokens: 256,
  top_p: 1,
  frequency_penalty: 0,
  presence_penalty: 0,
});

console.log(chatCompletion.choices[0].message);

結果:

$ bun run index.ts 
{
  role: "assistant",
  content: "Hello! How can I assist you today?"
}

回答が返却されました。

ChatGPTで利用されるような、以前の質問も含めて返答を行なうためにはstreamを利用するようですが、今回はそこまで調査できなかったので別で行いたいと思います。
https://platform.openai.com/docs/api-reference/streaming

Audio API

次にAudio APIです。

https://platform.openai.com/docs/guides/speech-to-text

これまたgoogle翻訳の力を借りて引用します。

Audio APIは、最先端のオープンソースlarge-v2 Whisperモデルに基づいて、2つの音声テキスト化エンドポイント、トランスクリプションとトランスレーションを提供します。これらは以下の用途に使用できます:

  • 音声をあらゆる言語に書き起こす。
  • 音声を英語に翻訳する。

Whisperがオープンソースなのは本当にすごいなと思いました。
https://github.com/openai/whisper

whisperのセットアップと利用

せっかくオープンソースなので、セットアップしてみましょう。

$ pip install -U openai-whisper

利用方法は以下です。

whisper audio.mp3 --language Japanese

めちゃくちゃ簡単じゃないですか?
デフォルトのモデル(small)は英語に翻訳してしまうようなので、上記ではlanguageオプションを設定しています。

Audio APIを利用する

次にコードからAudio APIを利用してみましょう。

audio2Text.ts
import OpenAI from "openai";
import fs from "fs";

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

async function transcription(file: string) {
  return await openai.audio.transcriptions.create({
    file: fs.createReadStream(file),
    model: "whisper-1",
    response_format: "text",
  });
}
const outputPath = "./assets/transcription.txt";
fs.writeFileSync(
  outputPath,
  (await transcription("./assets/audio.m4a")) as unknown as string
);

実行:

$ bun run audio2Text.ts

すると ./assets/transcription.txt にaudio.m4aの内容が文字起こしされます。
簡単ですね。

ただしアップロードできるファイルサイズの上限が 25MBとなっており、長い音声の場合はファイルを分割する必要がありました。
この際、テキスト化する精度を落とさないよう、文章のまとまりを考えつつ送るとより良い結果が得られそうです。

Retrieval-Augmented Generation(RAG)について

(正直あんまり分かってないのですが。。。)

このあたりの記事が参考になりました。
https://blogs.nvidia.co.jp/2023/11/17/what-is-retrieval-augmented-generation/

Retrieval-Augmented Generation は、外部ソースから取得した情報を用いて、生成 AI モデルの精度と信頼性を向上させるテクノロジです。

いわば、LLM の機能の不足を補うものです。LLM はその内部ではニューラルネットワークであり、一般的にはパラメーター数で評価されます。LLM のパラメーターは基本的に、人間がどのように単語を使って文章を作るかという一般的なパターンを表しています。

生成AIの参照するソースに情報を付加するフレームワークと認識しました。(PDFを参照させて要約する、など)

こっちが実は試したかったことで、音声から文字起こしされた内容を元にChat completions APIで何かしら回答を生成できると色々使えそうな気がする?と考えました。

llamaindex

llamaindexは外部ソースを取り込むためのデータコネクタと、LLMとつなぎこむためのデータモデルを提供するライブラリです。
これを利用すると簡単に記述できたので、こちらを利用します。
https://www.llamaindex.ai/

TSのパッケージも提供されているのでこちらを利用します。
https://github.com/run-llama/LlamaIndexTS

OpenAIのAPI Keyがセットされていると(またはデフォルトで?)、ライブラリの内部的にOpenAIのChat Completions APIが利用されるようです。(すみません、ちょっと調査時間が足りませんでしたので、分かったら追記します!)

というわけでコードです。

import fs from "fs/promises";
import { Document, VectorStoreIndex } from "llamaindex";

const source = await fs.readFile("./assets/source.txt", "utf-8");

const document = new Document({ text: source });

const index = await VectorStoreIndex.fromDocuments([document]);

const queryEngine = index.asQueryEngine();

const answer = await queryEngine.query("内容を要約してください");

console.log(JSON.stringify(answer.response));

(OpenAIの記述が消えてしまいましたが)
./assets/source.txtに音声から文字起こしした内容が入っているものとして、その内容を要約する指示を出しています。
実際にこちらを実行すると、OpenAIのUsageで利用料が増加します。

組み合わせて何かできないか考えてみた

会議の議事録を取る代わりに、音声を録音して議事録の記載 → 要約などができそうですね。

勉強会などでの録音がされていれば質疑応答や、その勉強会で発話された情報を利用したchatbotなども実現できるかもしれませんね。

マネイロにもオンラインセミナーがありますので、もしかしたらそのセミナーにも何か流用ができるかも。。。?!

番外編

12/1にはじめて利用して、APIKeyなどを発行して実際に試したら以下のようなエラーになりました。

$ bun run index.ts
1 | (function (...args) { super(...args); })
                                   ^
error: 429 You exceeded your current quota, please check your plan and billing details.
 code: "insufficient_quota"

      at new OpenAIError (:1:32)

調べると、どうやらOpenAIのアカウント作成時に$18分の無料枠が提供されるようですが、3ヶ月で失効するようです。
ChatGPTの利用のため今年の前半に登録していたので、これは失効していたようです。
そのため課金することにしました。まずは$10。。。
しかしそれでもAPIは同様のエラーを返します。
「登録したクレジットカードが悪いのか?」「Usage limitsの設定値が低すぎてもエラーになることがあるらしいぞ」「課金額が少なくてもダメそうだ」みたいなことをぐるぐると行い、結果$30ほど課金しました。

しかしそれでもAPIはエラーを返すのです。
困り果てた僕はとりあえずサポートに泣きつくことにしました。
そしてお返事が来るまで寝ることにしたのです。
翌朝、お返事が来ておりました。
結果、どうやらインシデントが起きていたようです。
無事解消され、APIへアクセスすることができるようになりました。

教訓としては、なんかうまくいかないときはサポートを頼れ、です。
実際この記事を書くために使ったのは$0.55ほどなので、残りの$29.45は有意義に使おうと思います。

まとめ

取っ掛かりとして色々調べることができて楽しい日々でした。
調べれば調べるほど色々な情報が出てくるので、引き続き調べつつ様々なことを試してみたいなと思います。

いろいろあって忙しいようですが、年明けくらいにGPT Storeなども出るらしいので、ますます便利になっていくことでしょう。楽しみですね!


明日は@disk_inueさんです!
よろしくお願いします!

株式会社モニクル

Discussion