Django を使って、gpt-4-visionの応答を簡単に得られるサイトを作ってみた

 初めましての方ははじめまして。UEC19-23、現M1のazarasingです。学部の時には調布祭実行委員会とMMAに参加していました。去年まで、調布祭の期間は付きっ切りで機材運用などしていましたが、今年は特に何もせず、平和な文化祭を... というわけでもなく、普通に講堂卓のミキサーの前にいました(何故?)。

misskey.io

 今回の記事はそんな孤立化した機材周りの知見を後輩に薫陶するための記事ではなく、普通に面白そうなことをしてみたよ~みたいな記事です。

この記事はUEC Advent Calendar 2023の8日目の記事です。

adventar.org

前回はみのさんの「金を使った話と金を稼いだ話 - 報告書」でした。

meeeeenow.hatenablog.com

稼いだゲルトは消えものですから、使わなければ腐ってしまいます。積極的に散財して、経済に立派に貢献しましょう。僕は、Meta Quest 3に散財しようとしてやめるサイクルを10回は繰り返しています。

UEC Advent Calenderは、無印も埋まらない年もありますが、今年はその2まで埋まっています。年々、規模が拡大していますね。来年はその3ができてそうです。 前回のその2の記事は「あかあくさんの アニメオタクのためのサイトを作った」でした。

anirishu.vercel.app

ニコ厨なので、凡例にニコニコ動画がないのが少し不満ですが、いいサイトだと思います。僕の場合ブログ|サイトを作っても、運用というか、維持がメンドクサイので公開しなくなってしまいました... 公開するだけで:偉業:ですが、OGPでちゃんと整備する技術力を感じました。

他のUEC Advent Calender その2の記事もぜひご覧ください

adventar.org

OpenAI - GPT-4-Vision

 ついにというか、やっとというべきか、OpenAIのGPTモデルに画像を読み込めるタイプのモデルが新登場しましたね。原理的には、画像データをテキストデータと十把一絡げに強引に学習しただけっぽいですが、120km/hで走る車がちょっとの段差をものともしないのと同じで、OpenAIが保有する圧倒的リソースを前にすれば些細な違いだったらしく、gpt-3.5が出てから1年と経たずして、満を持してのご登場、それがGPT-4-Visionです。このAPIを今回はいじっていきましょう。

 今回のリリースではほかにもオリジナルのpromptを調整して、便利なgptモデルを自分で作成できるGPTsのようなサービスもリリースされ、APIをいじる意味なんてだんだんと無くなっているような気もしますが、システムは何も動作だけをその目的とするのではなく、自分で作ったUIを同時に組み込んで初めてモノになるとも言えます。画像を入力できるようになったことでより一層、その差別化は必要でしょう。

 この記事ではPythonフルスクラッチWebサービスを作成するのにつかわれるDjangoを利用してOpenAIのAPIGUI経由で利用できるようにしていきましょう。

完成系のイメージ、アイコンをクリックするとそれぞれのプロンプトが呼び出されて、送信ボタンを押すとgptの答えが返ってくる。

Djangoでの入出力実装

僕はめんどくさがりなので、Pycharmを利用してDjangoの初期プロジェクトを作成します。

Pycharmで新しいDjangoプロジェクトを作成

こんな感じ。あらかじめopenaiやらdjnagoやらpillowやらを入れておいたインタプリタもここでセットしておきます。

まずは、setting.pyに追記して、投稿された画像の保存場所とopenaiのapikeyを設定しておきましょう。

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

MEDIA_URL = '/media/'

OPENAI_API_KEY = "sk-v========="

アップロードされた画像を格納するmodelを作成し、このmodelがopenaiのgpt-4-visionにバイナリ化した画像とpromptを送ります。

from django.db import models
from gpt4_vision_test.settings import OPENAI_API_KEY, BASE_DIR
from openai import OpenAI
import base64
import os

# Create your models here.

class UploadImage(models.Model):
    image = models.ImageField(
        upload_to='img/'
    )

    def gpt_process(self, prompt):
        base64_image = encord_image(str(BASE_DIR) + self.image.url)
        client = OpenAI(api_key=OPENAI_API_KEY)
        response = client.chat.completions.create(
            model="gpt-4-vision-preview",
            messages=[
                {
                    "role": "user",
                    "content": [
                        {"type": "text", "text": prompt},
                        {
                            "type": "image_url",
                            "image_url": {
                                "url": f"data:image/jpeg;base64,{base64_image}"
                            }
                        }
                    ]
                }
            ],
            max_tokens=1000,
        )
        return response.choices[0].message.content

def encord_image(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode("utf-8")

あとは、view.pyに受け渡しのコードを書いて完成です。 実際の応答を見てみましょう。

実際の応答例

唐獅子図屛風

唐獅子図屏風 右隻は、右端下部の狩野探幽による極書によって、桃山画壇の巨匠・狩野永徳の数少ない確証的な作品として名高い。岩間を闊歩する雌雄の堂々たる獅子の姿は、実に力強い筆法で描かれ、単純な図様ながら、その迫力、勇壮さには、本屏風が永徳自身の作品であることを疑う必要はない。左隻は、後に狩野常信が右隻の図様にあわせて制作したもので、今日は一双として伝わる。明治21(1888)年に毛利元徳より献上。

六曲一双の屏風の右隻側で二匹の獅子が描かれた屛風絵です。説明文はこの屏風を保有している宮内庁のHPから抜粋したものです。 これを獅子として認識できる人は日本人でも半々だと思いますが、gpt-4-visionはどうでしょうか。

なぞかけbotにこの画像について聞いてみましょう。

なぞかけボットの結果、あんまり巧くない

やっぱり、なぞかけは苦手だったかな...? 巧いっていうのは例えば、「この画像とかけまして、ボタンを掛け違えた服を着ている人にするアドバイスと説きます。」みたいなことを言うと思うので、そもそもgpt-4自体がなぞかけが苦手なのかもしれません。 とりあえず、この絵を評価してもらいましょう。宮内庁のHP文章みたいな文章が出てくることを期待します。

ありゃりゃ

著作権ですか... 人間が国宝絵の論評をするという点では著作権はかすりもしませんが、GPTモデルとなれば話は別なのかもしれません。 gpt-4-visionが画像をどのように分析しているかと言えば、画像をある種細切れにして、一色太に学習しているとも言えます。outputは文章ですが、コラージュ画像をその過程で生成しているという解釈もできなくはありません。そういう意味では著作権が現状のままである限り、人間の仕事は奪われなそうですね。

まぁ。もう一回やれば、ちゃんと答えを返してくれます。

この絵画の評価は以下のとおりです:

  • [技術力] : 細部にまでこだわった緻密な筆遣いと、動きのある姿勢が見てとれます。獅子の筋肉や毛並み、そして表情に至るまで、非常に高い技術力が示されています。

  • [想像力] : 獅子が日本の伝統的な絵画にしばしば描かれる題材であることを踏まえると、画家は古典に則った想像力を発揮しています。しかし、獅子のポーズや表情には独自の解釈が盛り込まれており、創造性が感じられます。

  • [色彩] : 色彩は自然で抑制されたパレットを使用しており、和紙の背景に落ち着いた色彩がうまく映えています。金色の箔がアクセントとなり、作品に豪華さと深みを与えています。

  • [感情] : 二頭の獅子からは強さと動きのエネルギーが感じられます。一頭が威嚇するような勢いを見せ、もう一頭が静かに構える様子は、力強さと落ち着きのコントラストを生み出しています。

  • [テーマ性] : 獅子は力と権威の象徴であり、この作品はそうした意味合いを含む伝統的なテーマを採用しています。獅子の姿を通じて、守護や勇敢さのメッセージを表現している可能性があります。

少し、比較してみましょう。

宮内庁 目次 gpt-4-vision
獅子 映っている動物 獅子
2匹 動物の数 2匹
岩間を悠々闊歩する      動物の様子 威嚇するようなエネルギーと静かに構える様子
力強い 緻密な
  • 獅子の様子について、二つの対になっているという解釈は狛犬の阿吽の様子や風神雷神の様子に該当するような解釈と混ざっている可能性がある。
  • 筆遣いについては、緻密と力強いとは大きく違う気がするので抜き出してみた。これはどちらかというと宮内庁側の説明の権威性が表れているようにも見える。

画題としての獅子をきちんと認識しているようです。細かな違い等はあるものの、晦渋な文章ではないと言える。逆にgpt-4は文体を変更できるため、宮内庁の文章のほうが詰屈聱牙に陥っているといえるかもしれません。*1

終わり

gpt-4-visionをwebから試せるようなDjangoアプリを作って、実際のgpt-4-visionの挙動を観察してみました。 gpt-4が今できること、できないことをきちんと理解して、使いこなすことがこのGPT時代に求められることのように思えます。

こんな記事でいいんですかね。次回はへるくんの普通自動車免許とった話です。

免許を取ると、世界が広がります。都会人にはあまり知られていませんが、日本には車でしか行けない場所のほうが多いですよね。 どんな記事になるのでしょうか。楽しみですね。

helkun.dev

*1:こんな文章を書いておいて、よく言うよっていう突っ込みが想像できますが