[Node] VoskとVOICEVOXを使ってChatGPTと音声で会話する
Introduction
先日、ChatGPTがAPIの提供を開始しました。
周りでもChatGPTのAPIをつかっていろいろつくっている人がいるので、
私もVoskとVOICESBOXを使用して、
音声でChatGPTに話しかけて返答を読み上げてくれる
スクリプトを(雑に)つくってみました。
Environment
今回試した環境は以下のとおりです。
- MacBook Pro (13-inch, M1, 2020)
- OS : MacOS 12.4
- VOICEBOX : 0.14.5
- Node : v18.2.0
Try
やってることはシンプルです。
Voskで音声入力して内容をChatGPTになげ、かえってきた答えをVOICEBOXにPOSTします。
次にVOICEBOXからのレスポンスをwavに保存して、afplayで再生するという雑仕様。
(VOICEBOXのところとか再生の部分はいい方法がいくらでもあるはず)
とりあえず動く状態なレベルですが、やってみます。
まずはVOICEBOXのインストールです。
ここからダウンロードしてインストール&起動します。
VOICEBOXはhttpサーバとして起動しているので、RESTでアクセスできます。
APIの使い方は、http://localhost:50021/docsにアクセスすれば
詳しい説明があります。
次はOpenAIのAPIを使うための準備です。
このへんとかこのへんをみて
API Keyの発行をしましょう。
後述するプログラムで使います。
nodeプログラムで使うモジュールをnpmでインストールします。
% mkdir example && cd example % npm install vosk web-audio-api openai axios
次に、ここからVoskのモデル(vosk-model-small-ja-0.22)を
ダウンロードして解凍し、example直下に置いておきます。
そして下記のjavascriptプログラム(main.js)を作成します。
//main.js const vosk = require("vosk"); const { Configuration, OpenAIApi } = require("openai"); const { default: axios } = require("axios"); const fs = require("fs"); const { execSync } = require("child_process"); var mic = require("mic"); const conf = new Configuration({ apiKey: "<api key>", }); const openai = new OpenAIApi(conf); const SAMPLE_RATE = 16000 const MODEL_PATH = "./vosk-model-small-ja-0.22"; vosk.setLogLevel(0); const model = new vosk.Model(MODEL_PATH); const rec = new vosk.Recognizer({model: model, sampleRate: SAMPLE_RATE}); var micInstance = mic({ rate: String(SAMPLE_RATE), channels: '1', debug: false, device: 'default', }); var micInputStream = micInstance.getAudioStream(); async function ask(prompt) { const completion = await openai.createChatCompletion({ model: "gpt-3.5-turbo", messages: [{role: "user", content: prompt}], }); return completion; } var play_flag = false; micInputStream.on('data', data => { if (rec.acceptWaveform(data)) { let question = rec.result().text; console.log("question=" + question); if(question !== null && question.length > 3 && play_flag == false) { play_flag = true; //chatGPTに質問を投げる ask(question).then((result) => { let prompt = result.data.choices[0].message.content; // VOICEVOXでchatGPTからの返答を音声合成 axios.post(`http://127.0.0.1:50021/audio_query?speaker=1&text="${prompt}"`) .then((queryRes) => { axios.post(`http://127.0.0.1:50021/synthesis?speaker=1`, queryRes.data, { responseType: "arraybuffer", }) .then((res) => { //VOICEBOXで生成した音声データをwavで出力してafplayで再生 fs.writeFileSync("tmp_voice.wav", res.data); execSync("afplay tmp_voice.wav"); play_flag = false; }); }); }) .catch((e) => { console.error(e.message); throw e; }); } else { console.log("do not exec ask & play); } } }); micInputStream.on('audioProcessExitComplete', function() { console.log(rec.finalResult()); rec.free(); model.free(); }); process.on('SIGINT', function() { console.log("SIGINT"); micInstance.stop(); }); micInstance.start();
スクリプトの記述ができたら起動してみます。
% node main.js
マイクにむかってしゃべってみれば、その内容がchatGPTにPOSTされ、
返答がVOICEBOXで音声になって再生されます。
Summary
今回はchatGPTと音声入力を組み合わせてみました。
動作が遅いとか、アルファベットがそのまま読まれたりとか
いろいろ問題はありますが、とりあえず音声で会話っぽくなってる感じです。