この記事は Safie Engineers' Blog! Advent Calendar 2023 4日目の記事です。
はじめに
こんにちは、開発本部の中村俊成です。
今年も色々と流行りの技術がありましたね。その中でも生成AIは注目度が高かったと思います。私も生成AIの社内活用を検討する過程で、業務や個人的なプロジェクトにおいてChatGPTやGitHub Copilotなどの生成AIを徐々に取り入れています。
そうした中、Stable Diffusionで生成した画像とプロンプトを一緒に表示できるツールが欲しくなり、ChatGPT(GPT-4)の助けを借りて簡単なものを作成しました。また、セーフィーのサービスの一部で使用しているFastAPIフレームワークの基礎を学ぶ良い機会でもあったので、このツールの開発にFastAPIを使用しました。
この記事では、その開発過程を紹介します。 以下のような方の参考になれば幸いです。
- 何かを作りたい、または新しい技術に触れたいと思っているが、なかなか始められない方
- 私のことですmm
- ChatGPTの使用例を探している方
- シンプルな指示を使った例になりますので、プロンプトエンジニアリングのサンプルとしては物足りないかもしれません
- FastAPIを使用したシンプルなサーバーの実装例に興味がある方
- ここで紹介するのは実験的な実装ですので、参考にされる場合は注意してください
システム概要
PC上で、Stable Diffusionで生成した画像を、画像サーバーに保存しておき、スマホや他のPCから閲覧できるようにします。画像サーバーの実装は、ChatGPTに相談しながら行いました。
システム構成
Stable Diffusion
Stable Diffusion は、Stability AI 社が開発している、ユーザーが与えた指示(prompt)を元に画像を生成するAIモデルです。 Stable Diffusion で画像を生成するためのツールとしては、stable-diffusion-webui を利用しました。 stable-diffusion-webui で生成した画像には、生成時の prompt がメタデータとして記録されています。
ChatGPT
ChatGPT は、Open AI社が開発している、人工知能に基づいたチャットボットで、テキストによる会話ができます。ユーザーのリクエストに応じて、情報を提供したり、創造的な内容を生成することが可能です。ブラウザや専用のアプリケーション、APIを通じて利用可能です。
FastAPI
FastAPI は、Pythonの標準である型ヒントに基づいてPython 3.6 以降でAPI を構築するための、モダンで、高速(高パフォーマンス)な、Web フレームワークです。
Poetry
Poetry はPythonのパッケージ管理ツールの一つです。pyproject.toml ファイルを使用してプロジェクトの依存関係を管理します。
実装
実装したコードはこちらから確認できます。 では、実装の過程を紹介していきます。
プロジェクトの作成
まずはプロジェクトの作成をChatGPTにお願いしてみます。
指示に従って、作業を行いました。
サーバーが起動し、ブラウザで開けるようになりました。
ファイル一覧API
API作成
最低限の機能として、画像ファイルの一覧が必要だと考えました。
URLのパスでディレクトリを指定できるように修正
それっぽいコードが出力されましたが、ディレクトリが指定できなさそうに見えます。修正を依頼しました。
これでコード上のBASE_DIRECTORYとURLのパスでディレクトリを指定できるようになりました。BASE_DIRECTORYにプロジェクトのディレクトリ以下にある static ディレクトリを指定して、サーバーを起動してみると、ファイル一覧が取れました。
パス | レスポンス |
---|---|
/files/ |
["/Users/t-nakamura/Study/src/image-server/static/.gitkeep"] |
ファイルのダウンロード対応
ファイル一覧に表示されたファイルのダウンロードに対応しようと考えました。
ChatGPTが提示するコードを見ながら、以下のような要望を出して、試行錯誤を行いました。
- subdirectory_name に
../
のような相対パスの指定がされたら無視するようにしたいです。 - APIで返すファイル名は、BASE_DIRECTORYからの相対Pathにしたいです
- APIが返すレスポンスを以下のようにして、ディレクトリのリストも返したいです。
{"files": ["file1", "file2"], "dirs": ["dir1", "dir2"]}
/files/{subdirectory:path}
APIで返したファイル名を指定したら、そのファイルをダウンロードできるようにしたいです。/files/{subdirectory:path}
と/download/{filepath:path}
を統合して、指定したpathが、ディレクトリだったら、ファイル一覧を返して、ファイルだったらファイルをダウンロードできるようにしたいです。- ファイルが画像の場合だけ、ファイル一覧で返したり、ダウンロードできたりするようにしたいです。
あいまいな表現が含まれていますが、ChatGPTが適切に解釈して、最終的に以下のようなコードを出力してくれました。
サーバーの実装に反映させ、以下のようにJSONを返せるようになりました。また、画像ファイルをのパスを指定するURLを開いた場合は、ブラウザ上で画像を表示できるようになりました。
パス | レスポンス |
---|---|
/files/ |
{"files":[],"dirs":["2023-11-29"]} |
/files/2023-11-29 |
{"files":["2023-11-29/2023-11-29 10.02.37.png"],"dirs":[]} |
ファイル一覧ページ
JSONで返すと、ディレクトリやファイルをブラウザ上で選択して開くことができません。そこで、簡易的なHTMLでファイル一覧ページを返すようにしようと考えました。
ChatGPTからの返答が長かったので、上記のスクリーンショットでは割愛しましたが、サーバーのコード修正や、テンプレートファイルの内容が提示されました。提示された実装例に従って、HTMLを返せるようになりました。(対応時のコミット)
パス | スクリーンショット |
---|---|
/files/ |
|
/files/2023-11-29 |
|
/files/2023-11-29/img.png |
画像のメタデータ取得
ここで、画像のメタデータを取得する方法について確認しておくことにしました。
Pillowライブラリを使えばできそうなことが分かりました。ライブラリをプロジェクトに追加し、提示されたコードで metadata 取得APIを実装すると、メタデータを取得できるようになりました。
パス | スクリーンショット |
---|---|
/metadata/img.png |
画像一覧ページ
データ取得に関しては、要素が揃ったので、表示部分の実装を行うことにしました。一覧性を高くするために、グリッド上に画像を表示することにしました。サーバーの実装と切り離して、シンプルな実装を知りたいと考えて、これまでとコンテキストを変えるため、新しいチャットを始めました。
提示されたコードを、テンプレートの file_list.html に反映すると、画像がグリッド状に表示されるようになりました。
パス | スクリーンショット |
---|---|
/files/2023-11-29 |
画像のメタデータの表示
画像のメタデータを表示できるようにします。画像の下に表示する方式も試したのですが、画像の一覧性が下がるため不採用にしました。画像の右下にボタンを配置して、ボタンをクリックすると、モーダルでメタデータを表示できるようにしました。
提示されたHTML、CSS、JavaScriptのコードを、少し調整して、テンプレートの file_list.html に反映すると、意図通り動作するようになりました。(対応時のコミット)
まとめ
ChatGPTにざっくりとした指示を出すだけで、動くものがすぐに仕上がるのは、驚きでした。動くものがあることで、機能を即座に試すことができますし、次に「ここをこうしたい」といったアイディアが浮かび、徐々に自分の理想に近づける原動力となりました。その結果、「あれば便利だろうな」と漠然と考えていたものを、実用的な形で素早く作成できました。
業務においても、社内外向けサービスのプロトタイプを作成する際などに活用できるという実感が得られました。今後も、この実感を基に、生成AIを生産性の向上や、新しい価値の創出に活かしていきたいです。