Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Amazon Bedrock(Claude2)でPythonのソースコード/テストコードの生成を確認してみた

こんにちは、最近久々にソロキャンプをしてきました菅野です。

AWS上で、 様々なAIモデルを利用できるようになるサービス、Amazon Bedrockがリリースされました、と書き続けてそろそろひと月が経過しております。
楽しみながら様々なモデルを利用していたらあっという間に時間がたってしまいました。

今回は、BedrockのClaudeV2モデルを用いてPythonコードとテストコードを生成してみようと思います。

Bedrockの説明は、以下を参照してください。

acro-engineer.hatenablog.com

Fizz Buzz」の生成

プログラミングの初歩も初歩、定番の課題といえばFizz Buzzです。
1-100までの数字のうち、3の倍数の時にはFizzを、5の倍数の時はBuzzを、3の倍数且つ、5の倍数の時はFizzBuzzと、それ以外の時はその数字を表示するプログラムです。

早速コードを生成してもらいましょう。

以下のようなコードが出力されました。

"""FizzBuzz問題を解くモジュール。

このモジュールにはFizzBuzz問題を解くためのクラスと関数が含まれます。
"""

class FizzBuzz:
    """FizzBuzz問題を解くためのクラス。

    このクラスにはFizzBuzzのルールに基づいて文字列を生成するメソッドが含まれます。
    """

    def generate(self, n: int) -> str:
        """nを受け取りFizzBuzzのルールに基づいた文字列を返す。

        Args:
            n (int): FizzBuzzを行う数値

        Returns:
            str: FizzBuzzのルールに基づいた文字列
        """
        
        if n % 15 == 0:
            return "FizzBuzz"
        elif n % 3 == 0:
            return "Fizz"
        elif n % 5 == 0:
            return "Buzz"
        else:
            return str(n)


def main():
    """メインメソッド。FizzBuzzクラスの使用例を示す。"""
    
    fizzbuzz = FizzBuzz()
    
    for i in range(1, 21):
        print(fizzbuzz.generate(i))


if __name__ == "__main__":
    main()

出力されたコードのテストコードも作成してもらいましょう。 以下のコードが出力されました。

import pytest
from fizzbuzz import FizzBuzz

@pytest.mark.parametrize(
    "n, expected",
    [
        (1, "1"),
        (2, "2"), 
        (3, "Fizz"),
        (4, "4"),
        (5, "Buzz"),
        (6, "Fizz"),
        (10, "Buzz"),
        (15, "FizzBuzz"),
    ]
)
def test_fizzbuzz(n, expected):
    fizzbuzz = FizzBuzz()
    assert fizzbuzz.generate(n) == expected

一回でFizzBuzzを実行するコード、ユニットテストを生成することができました。
Fizz、Buzz、FizzBuzz、自身の数それぞれのパターンをテストで確認できています。

じゃんけんを実行するコード

もう少し、複雑なコードも作成してもらいましょう。
ユーザの入力をもとにじゃんけんを実施するコードを作ってもらいましょう。 (中略)

以下のコードが生成されました。

"""じゃんけんゲームを実行するモジュール。"""

from random import randint

class JankenGame:
    """じゃんけんゲームを表すクラス。

    属性:
      player_hand: プレイヤーの選択した手
      computer_hand: コンピュータの選択した手
    """

    def __init__(self):
        """コンストラクタ"""
        self.player_hand = None
        self.computer_hand = None

    def get_computer_hand(self):
        """コンピュータの手をランダムに選択する。

        返り値:
          コンピュータの選択した手(グー、チョキ、パーのいずれか)
        """
        hands = ["グー", "チョキ", "パー"]
        return hands[randint(0, 2)]

    def judge(self):
        """勝敗を判定する。

        返り値: 
          "player": プレイヤーの勝ち
          "computer": コンピュータの勝ち 
          "draw": 引き分け
        """

        # 判定ロジック
        if self.player_hand == "グー":
            if self.computer_hand == "チョキ":
                return "player"
            elif self.computer_hand == "パー":
                return "computer"
        elif self.player_hand == "チョキ":
            if self.computer_hand == "パー":
                return "player"
            elif self.computer_hand == "グー":
                return "computer"
        elif self.player_hand == "パー":
            if self.computer_hand == "グー":
                return "player"
            elif self.computer_hand == "チョキ":
                return "computer"

        return "draw"

def main():
    """メイン処理。"""
    game = JankenGame()

    # プレイヤーの手を入力
    player_hand = input("あなたの手を入力してください(グー、チョキ、パー): ")
    game.player_hand = player_hand

    # コンピュータの手を決定
    computer_hand = game.get_computer_hand()
    print(f"コンピュータの手: {computer_hand}")
    game.computer_hand = computer_hand

    # 勝敗を判定
    result = game.judge()
    print(f"結果: {result}")

if __name__ == "__main__":
    main()

一回で期待通りのコードが出力されました。

同様に、上記コードのテストを実装してもらいましょう。

以下のようなテストコードが出力されました。

import pytest
from janken import JankenGame

@pytest.mark.parametrize("player, computer, expected", [
    ("グー", "チョキ", "player"),
    ("グー", "パー", "computer"), 
    ("チョキ", "パー", "player"),
    ("チョキ", "グー", "computer"),
    ("パー", "グー", "player"),
    ("パー", "チョキ", "computer"),
    ("グー", "グー", "draw"), 
    ("チョキ", "チョキ", "draw"),
    ("パー", "パー", "draw")
])
def test_judge(player, computer, expected):
    game = JankenGame()
    game.player_hand = player
    game.computer_hand = computer
    assert game.judge() == expected

じゃんけん結果判定のそれぞれのパターンについてテストができていますね。

まとめ

Claude 2でPythonコードと、pytestのテストコードを生成してもらいました。 簡単なAssertionのみの出力となりましたが一回でテストを生成できたのはうれしいポイントでした。
ソースコードも一回の出力でエラーなく期待する挙動のコードが出てきたのも高ポイントですね。 コツとして、プロダクトコードの作成時に「関数は適宜戻り値を返すようにしテスト作成しやすいようにする」と指示すると、関数をテストしやすく作ってくれる確率が高まります。 今後も生成AIでできることを模索していきたいです。
それでは。

Acroquest Technologyでは、キャリア採用を行っています。
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSクラウドサービスを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
  少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。 www.wantedly.com

簡単にオリジナルChatGPTアプリが作れる『GPTs』で、ドット絵生成チャットを作成

こんにちは、安部です。 11月なのに暑かったり寒かったしますが、皆様いかがお過ごしでしょうか。

さて、先日のOpenAI DevDay、大変な盛り上がりでしたね。

様々な新機能が公開され、GPT関連がさらなるパワーアップを遂げました。

DevDayは基本的に開発者向けのイベントですが、一般ユーザ向けの新機能も公開されました。

それがGPTsです。

今回は、GPTsが使えるようになったので試してみたいと思います。

GPTsとは

GPTsとは、GPT Builderを使ってノーコードで簡単にChatGPTをカスタマイズできるサービスで、今のところ有料ユーザのみが使用できます。

ChatGPTは特定タスク向けのサービスではありませんが、精度の良い回答をもらおうと思ったらプロンプトを工夫したり事前情報をたくさん与えないといけなかったりしますよね?

GPTsは、あらかじめ特定の目的を持たせたChatGPTの変種(GPTsと呼ばれます)を作っておくことで、それらの問題を解消できます。 今月末には、ストアも公開され、作成したGPTsを公開できるようになるそうです。

では、実際にGPTsを作成しながらGPT Builderの使い方を見ていきましょう。

GPT Builderの使い方

まずはChatGPTにアクセスします。 すると、左上に「Explore」というボタンがあるので、こちらをクリックします。 (表示されない方は、残念ながらまだGPT Builderが使えないので辛抱強く待ちましょう!)

すると、以下のように自分が作ったGPTs・最近使ったGPTs・OpenAI製のGPTsの3つが表示されます。

「Create a GPT」をクリックしましょう。すると、GPT Builderが起動します。

左サイドの画面で、対話形式でGPTsを作成することができます。 概ね以下のようなことを聞かれますが、何回か試すと毎回微妙に聞かれる内容が多少違います。

  • 何を目的とするGPTsか
  • GPTsの名称。提案してくれる。
  • サムネイル画像。目的・名称から生成してくれる。会話で変更を加えることも可能。
  • GPTsの返答/提案の仕方。(直接的で分かりやすいか、説明的で詳細か。)
  • GPTsの口調。(フォーマルか、カジュアルでフレンドリーか。)
  • 禁止事項や言及してほしくないこと。
  • 回答するのに情報不足の場合、詳細情報を求めるか一般論を回答するか?

サンプルとして、ゲーム用のドット絵を生成してくれるGPTsを作る場合の実際の会話の様子をテキストで載せておきます。

起こしてみると長く見えますが、かかった時間は5分程度でした。

【GPT Builder】
Hi! I'll help you build a new GPT. You can say something like,
 "make a creative who helps generate visuals for new products" 
or "make a software engineer who helps format my code."

What would you like to make?

【You】
make a professional designer who helps make pixel arts for video games.

【GPT Builder】
How about naming this GPT "Pixel Art Pro"? Does that sound good to you?

【You】
Sounds nice!

【GPT Builder】
~ ここで生成されたサムネ画像が表示される ~
Here's the profile picture we have for Pixel Art Pro. It's a pixelated image of a classic arcade-style joystick with a vibrant color palette. Do you like this, or would you like to make any changes?

【You】
No. It's perfect.

【GPT Builder】
Great! Let's fine-tune how Pixel Art Pro will interact with users. What type of guidance and support should it prioritize
when assisting users with their pixel art projects?

【You】
I would like Pixel Art Pro to suggest pixel art based on the game and character settings provided. 
If I present a piece of pixel art, please critique and offer advice on it.

【GPT Builder】
Great, Pixel Art Pro is set up to provide tailored pixel art suggestions and constructive critiques.

Now, in what situations should Pixel Art Pro ask for more information,
and when should it make assumptions to provide a quicker response?

【You】
Please ask for more background knowledge about the game when it's necessary to create good pixel art. 
If there are no critical issues, feel free to make assumptions and respond accordingly.
Please share the assumptions you make.

【GPT Builder】
Pixel Art Pro will seek more game details when necessary and will share any assumptions
made during less critical decisions to maintain transparency.

Lastly, would you like Pixel Art Pro to have a particular way of speaking, such as formal, casual, enthusiastic, or any other tone?

【You】
casual, please

【GPT Builder】
Pixel Art Pro is now tuned to have a casual and approachable tone.

Feel free to try out Pixel Art Pro in the playground, which is a separate chat dialog to the right.
If you'd like any refinements to its behavior, what would they be?

【You】
It's perfect!

【GPT Builder】
Awesome! If you ever think of any adjustments or new features for Pixel Art Pro
 just let me know. Enjoy creating with your new pixel art assistant!

日本語で回答できますが、質問はすべて英語でされます。作成完了したら、画面右上の「Save」ボタンを押します。 GPTsの公開設定が選べます。

このような手順でできあがったGPTsがこちらです。 公開設定にしておいたので、ご自由に触ってみてください。

chat.openai.com

では、動かしてみてみましょう!

GPTsを動かしてみる

自分で作成したGPTsは、ChatGPTの左上、「Explore」ボタンの上に表示されます。

表示されているサムネをクリックすると、GPTsとの対話が開始します。

サイバーパンクの世界観の主人公画像を作ってもらいました。

女性と男性を作ってもらいましたが、どちらも男性に見えるので女性Verだけ再作成を依頼。

さらに、オフィスの画像も作ってもらいます。 どうも「複数枚」という指示は無視されてしまうのですが、デザインはいい感じですね。

素のChatGPTとの比較

では、全く同じプロンプトを素のChatGPTに入力してレスポンスを見てみましょう。

当然ですが、ピクセルアートであることを指示していないので、普通のイラストが生成されました。 この後追加でいくつか指示を与えることで、ゲームで使えそうな画像を出力させることができました。

GPTsであれば、あらかじめ目的などを指示してあるため、そのようなやり取りを大幅に減少させられます。

GPTsの編集

作成済みのGPTsを編集することもできます。 「Explore」ボタンから、作成したGPTsの「Edit」ボタンをクリックします。

開いたGPT Builderで「Configure」タブを開くと、設定項目が表示される。

特筆すべき設定項目としては、以下の項目でしょうか。

「Conversation startars」とは、新しい会話を始めた時にテキスト入力欄の上部に表示される選択肢です。 素のChatGPTでは、あまり役に立たない選択肢が表示されていますが、これをカスタマイズできます。

また、「Upload files」から、ファイルをアップロードしてGPTsの知識に追加することができます。 これにより、さらにオリジナリティーを持ったGPTsが作成できます。

「Capabilities」と「Actions」では、ウェブブラウジング・画像生成・Code Interpreter・Function callingの設定ができます。

まとめ

GPT Builderを触ってみましたが、対話形式で非常に簡単にオリジナルのGPTsが作成できました。 自分が持っているデータなどをアップロードしておくこともできるので、かなり挙動をカスタマイズしたGPTsも作成できそうです。 色々と作成してみて、ChatGPTをさらに便利に活用したいですね!

Acroquest Technologyでは、キャリア採用を行っています。
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSクラウドサービスを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
  少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。 www.wantedly.com

GPT-4 Turboが登場、GPT-4との違いとは

こんにちは、最近ハンドブレンダーを購入し自家製バジルでジェノベーゼを作るようになった菅野です。

2023/11/6にOpenAIDevDayが開催され、ChatGPT関連の様々なアナウンスがありました。

openai.com

その中でもChatGPTの新しいモデル、GPT-4 Turboについての情報をまとめていきます。 モデルについての詳細解説は以下の公式サイトをご覧ください。

platform.openai.com

GPT-4 Turboのモデルは現在プレビュー版でgpt-4-1106-previewというモデルが試しに使える状態です。
数週間後に安定板のリリースがなされる予定だそうです。

コンテキスト長の増加(8,192 → 128,000トークン)

ChatGPTのモデルが一度に考慮できるテキスト量を示すコンテキスト長が12万8千トークンに増加しました。 従来のモデルのコンテキスト長はそれぞれ以下のようになっていることを考えると大幅な増加といえるでしょう。

モデル名 コンテキスト長
gpt-4-1106-preview(GPT-4 Turbo) 128,000
gpt-4 8,192
gpt-3.5-turbo 4,096

従来のGPT-4のおよそ16倍ものコンテキスト長になり、より長文の文脈を理解した上での応答を返してくれることになります。
短文の応答だけではなく、長い文章を生成してもらったり、より詳細な事前情報を読み込ませることができる様になります。

利用料がより安価に(入力:0.03ドル/出力:0.06ドル → 入力:0.01ドル/出力:0.03ドル)

モデルのパフォーマンス最適化に伴い、GPT-4 Turboではより安価にモデルを利用することができるようになりました。
GPT-4 Turboの利用料は以下のようになっております。

モデル名 入力($/1Kトークン) 出力($/1Kトークン)
gpt-4-1106-preview(GPT-4 Turbo) 0.01 0.03
gpt-4 0.03 0.06
gpt-3.5-turbo 0.0010 0.0020

入力では従来のGPT-4の1/3に、出力では1/2になっています。
利用トークン数が大きくなりがちな日本語での利用では大きな変化ですね。

学習データが2023年4月までのものに

従来のGPT-4モデルでは 2021年9月までの学習データをもとに文章を出力していたため、 2年以内の最新情報を出力することはできませんでした(例えば、AWSの新機能に関する出力をChatGPTで出力できない等)。
今回の更新でそのギャップが7ヵ月程度まで縮まるのはとてもうれしい限りです。

ちなみに、ChatGPT Plusなどで利用できるChatGPTアプリに関しては、GPT-4ベースのモデルが利用されているのですが、 どうやらGPT-4 Turboと同じように2023年4月の情報が最新に更新されているようです。

GPT-3.5を選択した場合はいまだに2021年9月が最新の模様です。

Function callingの改善

以前から実施可能であったFunction callingに以下の改善が加えられました。

  1. モデルのトレーニングにより、より厳密にFunction callingの適切なパラメータを呼び出せるようになった。

  2. 従来は一度の応答で1回しかFunction callingを利用できなかったが、複数の関数呼び出しを並列して実施できるようになった。
    例えば、国名を受け取って、受け取った国の気温を返すFunctionを定義した際に、「アメリカ、日本、フランスの気温を教えて」とchat completion APIに投入することで、3回のFunction呼出が行われるようになります。

JSON modeの追加

従来のGPT-4では出力のフォーマットを固定するには、プロンプトへ「応答は常にJSON形式で返してください。」といった文言を追加する必要がありました。
今回のアップデートでパラメータにresponse_formatを指定できるようになり、response_format: { type: "json_object"}とすることでモデルがJSON形式で応答を返すようになります。
入力プロンプトに常にメッセージを入れる必要がなくなるため、トークン数の節約につながりますね。
また、プロンプトへのフォーマット指定は、必ずしもそのフォーマットにならない場合がありましたが、今回のJSONモードでは厳密にJSONで返してくれるようになるので、 組み込みでアプリケーションを作成する際には実装が簡単になりそうです。

GPT-4 Turboを試してみる

ChatGPTのAPIで課金(1$以上)しているユーザにはすでに、gpt-4-1106-preview(GPT-4 Turbo)モデルを利用できるようです。
試しにAPIを使うだけでは、無料クレジット枠があるためすぐには課金されませんが、事前に支払いを行うprepaid billingを行うことでもモデルが解放されます。
上記課金について、ChatGPT Plusはカウントに含まれない点はご注意ください。

早速PlaygroundでGPT-4 Turboモデルが選択できるようになったため2023年2月の出来事を聞いてみましょう。

従来のGPT-4モデルでは以下のような応答になって答えてくれませんでしたが、 しっかり今年起こった出来事を回答してくれるようになりました。

まとめ

新しくアナウンスされた、GPT-4 Turboモデルについて従来のGPT-4とどのように差分があるのか説明しました。
より大量のコンテキストを理解できるモデルを安価に利用ができるようになったので、 ますます使い勝手がよくなっていきそうですね。
今後も生成AIで何ができるのか探っていこうと思います。
それでは。

Acroquest Technologyでは、キャリア採用を行っています。
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSクラウドサービスを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
  少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。 www.wantedly.com

Amazon Bedrock の Claude と Stable Diffusion を組み合わせて簡単に画像生成

こんにちは、肌寒い日が続くと南の島の暖かい海に行きたくなる菅野です。

AWS上で、 様々なAIモデルを利用できるようになるサービス、Amazon Bedrockがリリースされました。
Bedrockでは今までのブログで紹介してきた、テキスト生成以外にも、画像生成に利用できるモデルStable Diffusionも利用可能になっています。
Stable Diffusion自体はOSSとなっているので無料で利用できますが、自身のマシンにインストールして動かす必要があり、動かすマシンにはある程度の性能のGPUも必須になってきます。
手軽にStable Diffusionをオンデマンドで利用できるのは今までにないメリットなのではないでしょうか?

今回は、BedrockのClaudeV2モデルを用いて作成したプロンプトを使って、Stable Diffusionで画像生成をしていこうと思います。

Bedrockについて執筆した別記事もあわせてご覧ください。

acro-engineer.hatenablog.com

acro-engineer.hatenablog.com

モデルの利用料金

Amazon BedrockでのStable Diffusionの利用料金はオンデマンド料金とプロビジョニングスループットそれぞれ料金設定がされています。
よく使うであろうオンデマンド利用料金について、Bedrockで利用可能なSDXL0.8モデルではステップ数と画像解像度に応じて以下の料金になっています。

画像解像度 標準品質(51ステップ未満) 高品質(51ステップ以上)
512×512 以下 0.018USD/1画像 0.036USD/1画像
512×512 より大きい 0.036USD/1画像 0.072USD/1画像

詳細は以下の料金ページをご覧ください。

基盤モデルを使用した生成系 AI アプリケーションの構築 – Amazon Bedrock の料金表 – AWS

ステップ数とは?

Stable Diffusionが画像を生成する際には、画像の生成を繰り返し微修正を加えながら画像の精度を上げていきます。
その繰り返し処理1回を1ステップとし、繰り返せば繰り返すだけより高品質な画像が表示されます。

モデルの有効化

Stable Diffusionを利用するにあたって、モデルを有効化する必要があります。
Amazon Bedrock画面のサイドメニューから、Model accessを選択し、表示されるモデル一覧のEditを押下します。 Stability AI>Stable Diffusion XLにチェックを入れてSave Changesを押下します。

Playgroundsの利用

他のテキスト生成AIモデルと同様に、Stable DiffusionもPlaygloudsで簡単にモデルを試すことができます。
簡易的なUIのため変更できるパラメータが少ない、生成画像のサイズを変更できない等の制限が付きますが、まず動かす分には十分かと思います。
Bedrock画面サイドメニューからPlaygrounds>Imageを押下します。

Prompt欄に生成したい画像を示す文言を入力して生成します。
試しに海の画像を生成してみました。

プロンプトをClaudeV2で生成する

Stable Diffusionで期待する画像を生成する際には所謂”呪文”と呼ばれている特定のプロンプトメッセージを入力することが有効であるといわれています。
今回はせっかくなので同じBedrokで利用可能なテキスト生成モデルClaudeV2を利用して、Stable Diffusionのプロンプトを生成してもらいましょう。
カメをカメラと誤解するというおちゃめな出力をしたりしていましたが、訂正してもらって以下のプロンプトを提案してもらいました。

A beautiful coral reef sea at daytime with blue sky. Photorealistic photographic image. A turtle is visible in the frame.

早速こちらのプロンプトを用いて画像生成してみましょう。 以下の画像を生成してくれました。

青空を指定したにもかかわらずちょっと黄昏色に染まってしまってはいますが、カメとサンゴがきれいな海の画像ができました。

まとめ

Amazon BedrockにてStable DiffusionのモデルSDXL0.8を用いて画像生成を実施しました。
Playgroundsではテキストからの画像生成(t2i)しか試せませんが、APIを利用することで画像から画像を生成する(i2i)ことも実施可能なようです。
それについては今後試してみたいですね。
今後も生成AIで何ができるのか探っていこうと思います。
それでは。

Acroquest Technologyでは、キャリア採用を行っています。
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSクラウドサービスを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
  少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。 www.wantedly.com

Amazon Bedrock(ClaudeV2)でLambdaのコードを生成してみた

こんにちは、最近久々にソロキャンプをしてきました菅野です。

AWS上で、 ChatGPTのようなテキスト生成AIを利用できるようになるサービス、Amazon Bedrockがリリースされました。
今回はBedrockで、LambdaのPythonコードを生成してもらいます。

利用するモデルは、ChatGPTと同レベルの性能を有しているClaudeV2を利用します。詳細はこちら

Bedrockについて執筆した別記事もあわせてご覧ください。

acro-engineer.hatenablog.com

acro-engineer.hatenablog.com

S3に保存したCSVファイルの平均を求めるLambda関数を作成する

以下のようなcsvをS3からダウンロードし、一分毎、name毎の平均を返却するLambdaを作成してもらいます。

id,name,value,timestamp
1,data_1,5.79,2023-10-25T00:00:00
2,data_3,84.84,2023-10-25T00:00:10
3,data_2,23.88,2023-10-25T00:00:20
4,data_4,56.92,2023-10-25T00:00:30
5,data_4,19.51,2023-10-25T00:00:40
6,data_1,41.2,2023-10-25T00:00:50
7,data_2,26.52,2023-10-25T00:01:00
8,data_1,77.41,2023-10-25T00:01:10
9,data_1,19.05,2023-10-25T00:01:20
10,data_1,5.24,2023-10-25T00:01:30
11,data_1,94.87,2023-10-25T00:01:40
12,data_3,17.43,2023-10-25T00:01:50
13,data_3,22.94,2023-10-25T00:02:00
14,data_4,44.15,2023-10-25T00:02:10
15,data_4,95.46,2023-10-25T00:02:20
16,data_4,16.64,2023-10-25T00:02:30

Lambdaの構成はこのようになります。

それでは早速生成してもらいましょう。 (中略)

import csv
import boto3
from datetime import datetime, timedelta

s3 = boto3.client('s3') 

def lambda_handler(event, context):

  bucket = event['bucket']
  key = event['key']

  obj = s3.get_object(Bucket=bucket, Key=key)
  lines = obj['Body'].read().decode('utf-8').splitlines()  

  reader = csv.reader(lines)
  header = next(reader)

  data = {}
  
  for row in reader:
    name = row[1]
    value = row[2] 
    timestamp = datetime.fromisoformat(row[3])

    if value == 'null':
      continue
    
    value = float(value)

    # 一分ごとの範囲を計算
    start = timestamp.replace(second=0, microsecond=0)
    end = start + timedelta(minutes=1)

    if name not in data:
      data[name] = {}

    # その一分の範囲にある場合はデータを追加 
    if start <= timestamp < end:
      if start not in data[name]:
        data[name][start.strftime('%Y-%m-%dT%H:%M:%S')] = []
      data[name][start.strftime('%Y-%m-%dT%H:%M:%S')].append(value)

  averages = {}
  
  for name, minutes in data.items():
    averages[name] = {}
    for start, values in minutes.items():
      averages[name][start] = sum(values) / len(values)
  
  print(averages)
  
  return averages

lambdaのeventからバケット名とキー名を取得、読み取った内容を計算してくれるLambdaを生成してくれました。
valueがnullの場合早期リターンをするようにして、インデントが深くならないように工夫してくれているのがうれしいポイントですね。
返り値について、日付型をDictのKeyにしているとLambdaの返り値としてシリアライズする際にエラーになる為あらかじめStr型で保存するように手動で修正しています。

Lambdaの実行結果は以下のようになりました。

{
  "data_1": {
    "2023-10-25T00:00:00": 41.2,
    "2023-10-25T00:01:00": 94.87,
    "2023-10-25T00:02:00": 85.45,
    "2023-10-25T00:04:00": 0,
    "2023-10-25T00:05:00": 40.11,
    "2023-10-25T00:06:00": 0,
    "2023-10-25T00:07:00": 49.54,
    "2023-10-25T00:08:00": 95.98,
    "2023-10-25T00:09:00": 81.28,
    "2023-10-25T00:10:00": 19.23,
    "2023-10-25T00:11:00": 2.17,
    "2023-10-25T00:12:00": 63.83,
    "2023-10-25T00:13:00": 22.27,
    "2023-10-25T00:14:00": 28.9,
    "2023-10-25T00:15:00": 37.66,
    "2023-10-25T00:16:00": 93.55,
    "2023-10-25T00:17:00": 84.35,
(以下略)

無事期待通り、user毎、一分毎のValueの平均を求めてくれました。

まとめ

BedrockにてLambda関数を出力してもらいました。
今回の内容では、データの構成だけ修正が必要にはなりましたが、AWSの構成等も理解した上で、ほぼ動作するコードを1回で出力してくれたので、実用に足る結果になっていると感じました。
今後も生成AIで何ができるのか探っていこうと思います。
それでは。

Acroquest Technologyでは、キャリア採用を行っています。
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSクラウドサービスを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
  少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。 www.wantedly.com

ChatGPTのGPT-4Vを使ってSQL文を画像から作成する

igaです。
ポケモンsleepを継続していますが、カビゴン評価がマスターになれません。


ChatGPTが見たり、聞いたり、話したりできるようになる、と言われている「GPT-4 with vision (GPT-4V)」が使えるようになったので、早速使ってみたいと思います。
openai.com


今回は、データベースのテーブル関連図を画像ファイルでもらった想定で、画像からテーブルのDDLが生成できるかを確認してみます。

やりたいこと

以下のような、テーブルの関連図とサンプルデータが描かれた画像ファイルをもらいました。

この画像ファイルをChatGPT-4に渡して、SQLDDLが生成できるか確認します。

画像を解釈できるか確認する

いきなりDDLを作らせる前に、まずは画像ファイルに書かれたテーブル構造を、マークダウンで出力してもらいます。

プロンプトの入力欄の左に絵のアイコン(画像の赤で囲ったところ)をクリックすると、ファイル選択のダイアログが表示されるので、ChatGPTにアップロードする画像ファイルを選択します。
この入力に対するChatGPTの応答は以下のようになりました。


「取得元のデータ構造を基盤」と出力されたところは、実際には「取得元のデータ構造と関係」と書いてありました。
また、「銀の」と出力されたところは、実際には「銅の」と書いてありました。
それ以外は画像に描かれた文字を読み取ってマークダウンとして出力してくれました。

マークダウンからDDLを作成してもらう

先ほどの入力に続けて、以下の指示を入力します。
データ型についても、ChatGPTに推測してもらいます。

取得元のテーブルについて、SQLのDDLを出力してください。
データ型は、各カラムの値から推測して適切と思われる型で定義してください。

これに対して、ChatGPTの応答は以下のようになりました。


DDLを出力した後には、データ型についての説明が出力されましたが、そこは割愛します。

DDLの内容は以下の通りです。

CREATE TABLE player (
    id INT PRIMARY KEY,
    player_name VARCHAR(50) NOT NULL,
    hp INT NOT NULL,
    mp INT NOT NULL
);

CREATE TABLE equipment (
    player_id INT REFERENCES player(id),
    equip_id INT NOT NULL,
    equip_type VARCHAR(10) CHECK (equip_type IN ('head', 'body')),
    PRIMARY KEY (player_id, equip_type)
);

CREATE TABLE head_item (
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL
);

CREATE TABLE body_item (
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL
);

PKになりそうなカラムには「PRIMARY KEY」の制約がつけられていたり、equipmentテーブルのplayer_idplayerテーブルのidを参照しているので外部制約が設定されています。
投入したいデータに合わせた制約が設定されているので、DDLは問題なく生成できました。

取得したいデータ構造のSQLを生成してもらう

続いて、このテーブルをJOINして「取得したいデータ構造」になるように取得するためのSQL文を生成してもらいます。


(この後に、SQLの動作について解説していますが、その部分は割愛します)

生成されたSQL文は以下の通りです。

SELECT 
    p.id,
    p.player_name,
    p.hp,
    p.mp,
    hi.name AS head_item_name,
    bi.name AS body_item_name
FROM 
    player p
LEFT JOIN 
    equipment e_head ON p.id = e_head.player_id AND e_head.equip_type = 'head'
LEFT JOIN 
    head_item hi ON e_head.equip_id = hi.id
LEFT JOIN 
    equipment e_body ON p.id = e_body.player_id AND e_body.equip_type = 'body'
LEFT JOIN 
    body_item bi ON e_body.equip_id = bi.id;

生成されたSQL文は動作すると思われますが、実際に動かしてみないと分かりません。
サンプルデータとして、画像に書いてあった内容をSQLのINSERT文にしてもらいます。

マークダウンの内容からINSERT文を生成してもらう

先ほどの入力に続けて、以下のプロンプトを入力します。

生成されたSQL文は以下の通りです。

-- playerテーブルのデータ
INSERT INTO player (id, player_name, hp, mp) VALUES
(1, 'プレイヤー1', 40, 8);

-- equipmentテーブルのデータ
INSERT INTO equipment (player_id, equip_id, equip_type) VALUES
(1, 3, 'head'),
(1, 3, 'body'),
(2, 1, 'head'),
(2, 1, 'body'),
(3, 2, 'body');

-- head_itemテーブルのデータ
INSERT INTO head_item (id, name) VALUES
(1, '鉄の帽子'),
(2, '銀のかぶと'),
(3, 'シルバーヘルム');

-- body_itemテーブルのデータ
INSERT INTO body_item (id, name) VALUES
(1, '鉄の服'),
(2, '銀のよろい'),
(3, 'シルバーアーマー');

生成してもらったDDLとINSERT文をPostgreSQLに対して実行したところ、問題なくデータが登録できました。
(INSERT文でplayerテーブルのid=2と3のレコードは手で追加しました)

テーブルをJOINするSQL文を実行したところ、問題なく結果を取得することができました。
SQLの実行結果は以下の通りです。

db=# SELECT
    p.id,
    p.player_name,
    p.hp,
    p.mp,
    hi.name AS head_item_name,
    bi.name AS body_item_name
FROM
    player p
LEFT JOIN
    equipment e_head ON p.id = e_head.player_id AND e_head.equip_type = 'head'
LEFT JOIN
    head_item hi ON e_head.equip_id = hi.id
LEFT JOIN
    equipment e_body ON p.id = e_body.player_id AND e_body.equip_type = 'body'
LEFT JOIN
    body_item bi ON e_body.equip_id = bi.id;
 id | player_name | hp | mp | head_item_name |  body_item_name
----+-------------+----+----+----------------+------------------
  1 | プレイヤー1 | 40 |  8 | シルバーヘルム | シルバーアーマー
  2 | プレイヤー2 | 32 | 18 | 鉄の帽子       | 鉄の服
  3 | プレイヤー3 | 50 |  0 |                | 銀のよろい
(3 rows)

まとめ

今回は、ChatGPT-4に画像からテーブル構造を読み込んでSQLを生成してもらいました。
元の画像はExcelで作った図も文字もきれいでしたが、読み取った結果は多少修正が必要でした。
生成してもらったSQL文は問題なく実行できて、DDLについては制約も指定してくれました。
ここまでの精度でSQL文を生成してくれるのであれば、SQLの文法を忘れてしまってもChatGPTに助けてもらうことが出来そうです。


Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Kaggle Grandmasterと一緒に働きたエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの採用 - Wantedlywww.wantedly.com

ChatGPTを利用して画面モックを爆速で作成する

こんにちは、最近スマホのChatGPTアプリで、音声入出力機能を使って会話を楽しんでいる安部です。

皆さんWebアプリ開発などで、画面モックを作成しなければいけない場面は多いですよね?
適当なHTMLを作ったり、ツールで図示したりしますが、正直面倒です。

そこで今回は、ChatGPTに最初から画面モックを作ってもらいます。

最近はChatGPTに画像を添付できるようになったので手書き画像からHTMLを出力することもできますが、 この記事では画面要素を言葉で指定し、HTMLを出力してもらいます(配置などのデザインは、ひとまずChatGPTにお任せしてみます)。

では早速始めましょう。使用モデルはGPT-4です。

簡単な入力フォームを出力させる

まずは、よく使いそうな簡単な入力フォームを出力してもらいます。

ここでは、「書籍を登録する画面」という設定で指示を出します。

次の画面構成の案を、HTMLで出力してください。
Bootstrapを利用し、デザインを整えてください。

- 書籍の登録画面の登録フォーム
- 書籍のタイトル、出版社、カテゴリ、登録日、備考を持つ
- カテゴリはプルダウンからの選択
- 最後にキャンセルボタン、登録ボタンがある

長くなるので出力は途中まで載せます。

出力されたHTMLをブラウザで表示させると、以下のようになりました。

明示的に指示していなくても、「登録日」入力部分はカレンダーコンポーネント、「備考」入力欄はテキストエリアとなっています。

当然ボタンを押しても何も動きませんが、画面モックとしては申し分ないですね。 これが30秒でできるのですから、言うことなしです!

一覧表示画面を出力させる

次に、一覧表示画面を出力させてみます。

フィルター機能やページネーションもつけてもらいましょう。

次の画面構成の案をHTMLで出力してください。
Bootstrapを利用し、デザインを整えてください。
 
- 一覧画面
- 書名、著者名、出版社、カテゴリ、発売日の列を持ち、各行に編集・削除ボタンがある
- 各列には、フィルター機能がある
- 表の下にページネーション部品がある
- さらに下に登録ボタンがある

出力されたHTMLをブラウザで表示すると、以下のような画面となりました。

まだブラッシュアップできそうではありますが、かなり期待したものに近い画面ができています。

画像選択画面を出力させる

少し凝った例として、画像を表示してユーザに選ばせる画面を作ってみます。 一度に表示されるのは3枚で、カルーセルで横にスワイプすると新たな画像が表示されるようにしたいです。

次の条件でHTMLを作成してください。デザインはBootstrapで整えてください。
 
- タイトルの下に、画像が横に3枚並んでいる
- 画像は、横にスワイプすると新たな画像が表示される
- どれか1つの画像をクリックすると選択状態になる。選択状態かは見た目でわかるようにする
- 画像の下には太字でキャプションが入っている
- 下に決定ボタンがある

期待通り、画像のスワイプはBootstrapのCarouselを利用してくれるようです。

生成されたHTMLをブラウザで表示すると、以下のような画面となりました(画像の参照先は、ダミー文字列だったのでライセンスフリー画像のアドレスに置き換えています)。

画像選択もカルーセルも、問題なく動いていますね!

「表示すべき画面要素は決まっているけど、レイアウト/デザインはいまいちイメージがない」というような場面でも きれいにデザインされた画面を提案してくれるので、大変重宝しそうです。

まとめ

画面要素を指定することで、ChatGPTに画面構成案をHTMLで出力させることができました。 面倒な作業になりがちな画面イメージの作成が一瞬で出来てしまうので、活用の場面は多そうです。 Bootstrapも十全に使ってきれいな画面を作成してくれ、名前から適したコンポーネントを勝手に選んでくれるのも賢いですね。

コンポーネントの多い複雑な画面も、部分ごとに分けて出力させてつなげることで、画面モック作成の大幅な効率化ができそうです!

Acroquest Technologyでは、キャリア採用を行っています。
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
  少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。 www.wantedly.com