walkingmask’s development log

IT系の情報などを適当に書いていきます

MENU

AI とはじめる開発リハビリ(2)

今日は「gradio を使って昨日作った OpenAI TTS お試しツール を実装」していきたいと思います。

gradio とは?

人間的に簡単にまとめると、gradio は機械学習等のデモに必要最低限な UI を揃えた Web アプリ開発支援ライブラリです。自由度は低いが、ipywidget 並に簡単に UI を作ることができます。HuggingFace のデモとかによく使われているアレですね。

gradio を動かす

早速やっていきたいと思います。

Jupyter 上で動作確認できるらしいのですが、実行してみると

となってしまいます。Docker コンテナ上で実行しているのでポートが空いてないせいかな?と思うのですが、原因を調べるのも後からポートを追加するのも面倒なので、7860 ポートをホストにバインドした Python コンテナを新しく立ち上げて、そちらで実行します。

docker run -p 7860:7860 -d -it python:3.10

で、pip install gradio して、vim をインストールして、ChatGPT に教えてもらった example をはっ付けて python main.py で実行。

This site can’t be reached

ホストに "0.0.0.0" を設定していないせいな気がするので、指定方法を聞きます。

ホストを 0.0.0.0 に設定してGradioインターフェースを動かすには、launch メソッドに server_name='0.0.0.0' の引数を指定します。これにより、インターフェースがネットワーク上のすべてのアドレスでアクセス可能になります。ただし、この設定はセキュリティ上のリスクを伴うことがあるので、公開サーバーなどで使用する場合は注意が必要です。

言われた通りにしたら動きました。

いちいち「ググってヒットしたリンクをクリックして該当箇所を見つける」という作業なくすんなりここまで来れるのは、こういうちょっとしたケースでは本当に楽になると感じます。

Jupyter Notebook の ipywidget で作った UI を gradio に書き換え(てもらう)る

それでは、前回のコードを全部そのまま渡してみまず。

その結果、以下が返ってきました。

import gradio as gr
from openai import OpenAI
from io import BytesIO

client = OpenAI()

def generate_speech(text, voice, model, speed):
    response = client.audio.speech.create(
        model=model,
        input=text,
        voice=voice,
        speed=speed,
    )
    audio = BytesIO(response.content)
    return audio

iface = gr.Interface(
    fn=generate_speech,
    inputs=[
        gr.Textbox(lines=2, placeholder="ここにテキストを入力してください"),
        gr.Radio(choices=["alloy", "echo", "fable", "onyx", "nova", "shimmer"], label="Voice"),
        gr.Radio(choices=["tts-1", "tts-1-hd"], label="Model"),
        gr.Slider(minimum=0.25, maximum=4.0, step=0.05, default=1.0, label="Speed")
    ],
    outputs=gr.Audio(type="numpy", label="Generated Speech"),
    title="OpenAI Text-to-Speech Demo",
    description="Select text, voice, model, and speed to generate speech.",
)

iface.launch()

これを実行すると TypeError: Slider.__init__() got an unexpected keyword argument 'default' と怒られたので、これもそのまま ChatGPT に聞きます。

gr.Slider に渡していた defaultvalue に変えれば良かったようです。

次は ValueError: Cannot process <_io.BytesIO object at 0xffff942c0ae0> as Audio と怒られたので、これも聞きます。

return audioreturn audio.getvalue() に変えて、gr.Audiotype="numpy" を削除しました。BytesIO オブジェクトを返しているのに、numpy で受け取ってしまっていたようですね。また、オブジェクトのままだと Audio は受け取れないため、バイナリ文字列に変換しているみたいです。

これを修正して実行すると...

動きました。

たったの 30 分程度で Jupyter の ipywidgets で作った UI を gradio に書き換えてくれました。

すごい。

まとめ

元のソースコードの class をベースに書いた内容とはだいぶ異なってシンプルな感じにされてしまったのは気に食わないのですが、変換→デバッグ→実行を一切ググらずにできちゃうのは感動しました。

また、gradio は簡単なデモ用の UI を作る分には本当に簡単に Web アプリが作れちゃうな、という感想です。おそらく今後もちょいちょい活用する気がしています。

という感じで、しばらくは思いつきでいろんな機能のコーディングを AI と一緒にやっていきたいと思います。