未定の部屋

主にデータサイエンス関係の記事を書きます

LlamaIndex × Azure OpenAIでRAGを試す

タイトル通りですが、LlamaIndexのバージョン更新が早くて2024年1月時点の最新バージョンでの日本語記事がなかなか見つからなかったので、公式ドキュメントを参考に実装した内容をこちらに載せようと思います。

簡単な用語説明

  • LlamaIndex: LLMアプリの構築を支援するデータフレームワークです。今回はRAG(後述)を実装するために使用しています

github.com

  • Azure OpenAI: 正式名称はAzure OpenAI Serviceで、OpenAIのモデルをAzureを通して利用できるサービスです。OpenAIのLLMをpythonで使う際に利用しています

learn.microsoft.com

  • RAG(Retrieval-Augmented Generation): LLMが回答を生成する際に外部の知識を検索させるフレームワークです。ハルシネーション(LLMがもっともらしく嘘をつく現象)を減少させ、事実ベースで回答できるようになることが期待されます

docs.llamaindex.ai

実行環境

  • PC: Mac
  • python: 3.10
  • LlamaIndex: 0.9.31
    ローカル環境でDockerコンテナを立ち上げて実行しました。

実装

  • ライブラリの読み込み
    今回はAzure OpenAIからLLMとEmbeddingのモデルを使ったので、それぞれに対応するライブラリをインポートしています。インポート後にログを出力する設定をしています。
import os

from llama_index.llms import AzureOpenAI
from llama_index.embeddings import AzureOpenAIEmbedding
from llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext
from llama_index import set_global_service_context
import logging
import sys

logging.basicConfig(
    stream=sys.stdout, level=logging.INFO
)  # logging.DEBUG for more verbose output
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))



  • セットアップ
    API、LLM、embeddingモデル、service contextのセットアップを行います。今回はLLMとしてGPT-4を、embeddingモデルとしてtext-embedding-ada-002を使用しました。APIのバージョンは適宜変更してください。service contextは公式ドキュメントのままに書いていますが、おそらくLlamaIndex側に使うモデルの情報をセットしているんだと思います。
# API
api_key = os.getenv("AZURE_OPENAI_KEY")
azure_endpoint = "https://<your-resource-name>.openai.azure.com/"
api_version_llm = "2023-09-01-preview"
api_version_embed = "2023-05-15"

# llm model
llm = AzureOpenAI(
    model="gpt-4",
    deployment_name="your-deploy-name",
    api_key=api_key,
    azure_endpoint=azure_endpoint,
    api_version=api_version_llm,
)

# embedding model
embed_model = AzureOpenAIEmbedding(
    model="text-embedding-ada-002",
    deployment_name="your-deploy-name",
    api_key=api_key,
    azure_endpoint=azure_endpoint,
    api_version=api_version_embed,
)

# set service context
service_context = ServiceContext.from_defaults(
    llm=llm,
    embed_model=embed_model,
)
set_global_service_context(service_context)



  • データの読み込み・データベース作成
    データはチュートリアルページと同様にエッセイのデータを使用しました。チュートリアルページからダウンロードし、../data/ディレクトリ配下に格納しています。その後VectorStoreIndexを使ってテキストをembeddingし、indexを作成しています。
documents = SimpleDirectoryReader(input_files=["../data/paul_graham_essay.txt"]).load_data()
index = VectorStoreIndex.from_documents(documents)

ログの出力は↓のような感じになります。

INFO:httpx:HTTP Request: POST https://... "HTTP/1.1 200 OK"
HTTP Request: POST https://... "HTTP/1.1 200 OK"
HTTP Request: POST https://... "HTTP/1.1 200 OK"
...



  • クエリ実行と結果出力
    クエリはエッセイの面白かった部分を聞く内容です。このクエリをもとに検索を行い、エッセイ内容を参照して回答をしてくれます。
query = "What is most interesting about this essay?"
query_engine = index.as_query_engine()
answer = query_engine.query(query)

print(answer.get_formatted_sources())
print("query was:", query)
print("answer was:", answer)

↓のように参考にしたソース、クエリ文、回答文が出力されます。

> Source (Doc id: 74acc1a9-8c6d-46c9-b7bd-cd8edf7f6523): Notes

[1] My experience skipped a step in the evolution of computers: time-sharing machines with...

> Source (Doc id: 742cd9ad-d677-4730-9c5c-85069b325989): A lot of Lisp hackers dream of building a new Lisp, partly because one of the distinctive feature...
query was: What is most interesting about this essay?
answer was: The most interesting aspect of this essay is the personal journey and insights of the author, particularly the realization of the potential of online publishing. The author describes a pivotal moment when they discovered the wide reach of the internet after posting a talk online, which garnered 30,000 page views in a single day. This realization led to the understanding that the internet had opened up a new channel for essayists, free from the constraints of traditional print publishing and its gatekeepers. The essay also touches on the theme of working on projects that lack prestige and how this can be a sign of genuine interest and discovery, rather than being driven by the desire to impress others. The author's experiences with Lisp, painting, cooking, and creating startups like Viaweb and Y Combinator, as well as their reflections on the evolution of technology and its impact on various fields, add depth to the narrative.

参考

AWS×Streamlit×GPTでペルソナ作成・リサーチアプリを作ってみた

こんにちは。ChatGPTがリリースされてからLLM以外の技術トピックをめっきりキャッチアップしなくなってしまい、まずいなと思いつつモチベが上がらない日々を過ごしています。今回はそんなLLMを使ったWEBアプリを作ってみたので、その内容を紹介しようと思います。

サマリ

  • OpenAI APIを用い、GPT-3.5を使って商品情報を入力するとそれに合わせたペルソナを作成・分析してくれるアプリを作った

  • AWSでEC2インスタンスを作成→Dockerコンテナを立てる→PythonのライブラリであるStreamlit1を用いてアプリ作成という手順で作成した

  • 基本的に生成文が著しくズレていることはなく、壁打ちとしては機能しそう。ChatGPTでも同様のことができるが、ペルソナ作成に特化した入出力のフォーマットなので、より楽に使えそう

きっかけ

アプリ作成のきっかけは↓のツイートでした。

このプロンプトを見て良くできてるなあと思いつつも、「毎回ChatGPTにコピペするのは面倒だな」「プロンプトのどの部分を変えるのか分かりにくいな」と感じました。そこで、OpenAIのAPIを使ってアプリの形にして、もっと使いやすくできるんじゃないか?と思い、作成に至りました。

作成手順

ざっくりと作成手順を記載していきます。
DockerfileやPythonコードは↓のGitHubに挙げているので、こちらも必要に応じて見てみてください。

github.com

前提

EC2インスタンスを作成し、VSCodeからSSH接続をする

ここについては以前記事に書いたので、適宜↓を参照してください。

miteinoheya.hatenablog.com

EC2でdockerコンテナを立てる

  • 以下のコマンドを実行してdockerとdocker composeをインストールします
# Dockerのインストール
sudo yum update -y
sudo yum install -y docker
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -a -G docker ec2-user
newgrp docker
# インストールされたことを確認
docker info
# docker-composeのインストール
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# インストールされたことを確認
docker-compose --version
  • Dockerfileとdocker-compose.ymlファイルを作成する EC2インスタンスの任意のディレクトリでそれぞれのファイルを作成します。Dockerfileとdocker-compose.ymlは同じディレクトリ配下に置いています。

  • docker-compose.ymlのあるディレクトリに移動して docker-compose up -d を実行する

JupyterLabを立ち上げる

http://[EC2インスタンスのパブリックIPアドレス]:8888/lab
上記のURLを打ち込めば立ち上がると思います。

  • パスワードはDockerfileで記述したもの
  • EC2インスタンスのセキュリティグループのインバウンドルールに8888番ポートを追加しておく

※Streamlitを使ってWebアプリを作るだけならJupyterLabは必要ないのですが、Pythonコードの試行錯誤をするのにノートブックを使い慣れているのでJupyterLabを使っています。

Streamlitを使ってペルソナ作成・リサーチアプリを立ち上げる

  • Pythonコードは上部であげたGitHubリポジトリにあるので、適宜見てもらえればと思います
  • ターミナルを起動してscriptフォルダに移動し、streamlit run [pythonファイル名]と打ち込むと立ち上がる
    • 出力にある「External URL」から開ける

注意事項

  • おそらくCtrl+C以外でアプリを停止できない(Streamlitの仕様?)
  • ブラウザを消してもJupyterLabのターミナルタブを残したままならrunし続ける

所感

以下に作成したアプリの簡単な所感を書いていきます。

  • 元ツイートと同じような出力が出てきた
  • 入力する部分が分かりやすい:書き換えが楽
  • カスタマイズしやすい:今回は実装していないが、出力結果をファイルにしてエクスポートすることも可能

機能は元のツイートとほぼ変わらないままに、使いやすさはアプリにした分向上したかなと思います。ChatGPTはチャット形式で便利ではありますが、今回のように目的がはっきりしているときはそれ用にカスタマイズする方が便利だなと思いました。

少し簡素ではありますが、以上になります。ではでは。


  1. Streamlitとは、PythonでWebアプリケーションを作成するためのフレームワーク。簡易的にWebアプリを作成するのに向いている

GPT3.5にブログを書かせる

こんにちは。最近仕事をサボってChatGPTとかで遊びがちなのですが、AWSとかも使って色々やってた結果ブログを自動作成してくれるツールができました。せっかくなのでブログを書いてもらおうと思います。

ツールについて

こんなものを作りました。

シンプルな構成で、テーマを入力して実行ボタンを押すとブログっぽい文章を出力してくれるだけの機能です。
PythonとStreamlitを使って作りました。Streamlitは使ったことなかったんですが、GenieAI(GPT使ったコード生成ツール)に「コード書いて」って言ったらそれっぽいコードを書いてくれました。内部でプロンプトを書いていて、文字数や文体を指示しているのですが、そこは自分で考えて書いてます。
完全個人用で作ったので、一般公開はしてないです。

使ってみた

適当にテーマを入れてみる

入れたテーマ:戦争と平和
出力↓

タイトル:戦争と平和

こんにちは、私は戦争と平和について考えることがあります。私たちは、平和な社会を築くことが目標であるにも関わらず、現実には世界中で多くの紛争が発生しています。私たちは、戦争がなぜ起こるのか、そして平和を実現するために何ができるのかについて考えていく必要があります。

戦争は、様々な要因によって引き起こされます。国家間の利益対立、宗教的、民族的な対立、資源の争奪などが挙げられます。一方で、平和は、個人や国家が相互に理解し合い、共存することで実現されます。しかし、それは簡単なことではありません。相互理解や共存に必要な教育やコミュニケーションが不足している場合があります。

私たちが平和を実現するためにできることは何でしょうか?まず、個人レベルでの相互理解や共存を推進することが大切です。自分と異なる考え方や文化を理解し、尊重することが求められます。また、政治家や指導者たちは、対話、妥協、協力を通じて紛争の解決を図るべきです。

戦争がなくなることは簡単なことではありませんが、私たちは平和を目指すことができます。相互理解や共存を推進し、紛争解決に向けた取り組みを進めていくことが必要です。私たちが平和を手に入れることができるよう、一人ひとりが行動することが大切です。

それっぽさの塊みたいな文章が出てきました。こういう一般的なお題は得意そうですね。

固有名詞を入れてみる

入れたテーマ:菅田将暉のいいところ
出力↓

タイトル:菅田将暉の魅力、私の見つけたいいところ

こんにちは、私は菅田将暉さんの大ファンです。今回は、私が見つけた菅田将暉さんの魅力についてお話ししたいと思います。

まず、菅田将暉さんの魅力の一つはその人柄です。彼はとても謙虚で、常に周りの人たちを大切にしています。また、彼の笑顔はとても素敵で、見ているだけで心が癒やされます。

そして、もう一つの魅力はその演技力です。菅田将暉さんは、どんな役柄でも自然に演じきることができます。私が特に好きなのは、映画『ちはやふる』での演技です。彼が演じる綾瀬千早の繊細で力強い演技は本当に素晴らしいものでした。

さらに、菅田将暉さんは音楽でも活躍しています。彼が歌う「まちがいさがし」は、とてもキャッチーで心に残る曲です。彼の音楽活動も見逃せない魅力の一つです。

最後に、菅田将暉さんの魅力の一つに、彼のファンとの距離感の近さが挙げられます。彼はSNSを通じて、ファンとのコミュニケーションを大切にしています。また、イベントやライブなどでも、ファンとの交流を大切にしている姿が見られます。

以上が、私が見つけた菅田将暉さんの魅力です。彼の人柄や演技力、音楽活動、そしてファンとの距離感の近さなど、彼の多彩な魅力に私は魅了されています。皆さんも、ぜひ彼のいいところを探してみてください!

思ったよりそれっぽいですが、多分『ちはやふる』には出演してないですね。ただ「まちがいさがし」は実際に楽曲としてあるので、まったくの見当違いではなさそうです。
今回のツールには検索機能はないので、正しい情報が求められるようなテーマは苦手そうですね。

意味不明なテーマの場合

入れたテーマ:くぇrty
出力↓

タイトル:「くぇrty」という言葉の魅力に迫る

こんにちは、私はくぇrtyについての思いを語りたいと思います。

くぇrtyという言葉は、日本語としては存在しない造語ですが、その言葉の響きや意味に惹かれて、私は今では頻繁に使っています。

くぇrtyとは、何かが形や音のズレを感じさせながら、同時に美しさや面白さを感じさせること。例えば、音楽やアートの中には、くぇrtyな要素が含まれているものがあります。

また、くぇrtyなものは見た目だけでなく、感覚にも訴えかけます。例えば、食べ物の味や匂い、触感などが、くぇrtyな要素を持っていることがあります。

私は、くぇrtyなものを見つけることが好きで、その瞬間に自然と笑顔がこぼれます。くぇrtyなものに出会うことで、心が豊かになり、幸せな気持ちになるのです。

皆さんも、くぇrtyなものを探してみませんか?日常の中にも、意外なところにくぇrtyが潜んでいるかもしれません。

今回は、くぇrtyという言葉の魅力についてお話しました。皆さんにとっても、くぇrtyな要素を感じる瞬間が訪れますように。

わけ分からな過ぎて面白いw
くぇrtyって言いたいだけの人みたいになってる。

おわりに

こういうアプリ的なものを作った経験はなかったのですが、自分で考えるのを放棄してAIに聞きまくったらできてしまったので本当に便利な時代になったなと思います。やっぱり検索機能があった方がいいなというのと、文字数を指定できたらいいなと思いました。プロンプトの内容もオプションで変えられるといいかもですね。
実務を考えるとファイル入れて要約するツールとかファイル読み込ませて集計してもらうツールとかはかなり便利かもなと思いました。モチベが湧いたらまたなんか作ろうかなと思ってます。
ではでは。

Lambdaで形態素解析をする

最近業務でAWSを触ることが多く、その中で形態素解析をする機会があったので、その際の内容を備忘録として残しておきます。

やったこと

  • AWSのサービスを使い、ファイルがS3に置かれたら自動で形態素解析ができるようなシステムを作る
    • サービスとして、今回はLambdaを採用した
  • 形態素解析ツールとしてMeCabを利用する

手順

今回実装した大まかな手順は以下になります

  1. EC2インスタンスを作成し、SSH接続をする

  2. EC2インスタンス上にDockerとAWS CLIをインストールする

  3. EC2インスタンス上でDockerfile、requirements.txt、lambda_function.pyを作成し、Dockerイメージを作成する

  4. 作成したイメージをAmzon ECRへプッシュする

  5. Lambda関数をコンテナイメージから作成する

  6. S3バケットをトリガーとして設定する
    アーキテクチャの全体像は↓のようになります

手順詳細

FROM public.ecr.aws/lambda/python:3.9

COPY requirements.txt  .
RUN  pip3 install -r requirements.txt --target ./

COPY lambda_function.py   ./
CMD ["lambda_function.lambda_handler"]
  • requirements.txt
mecab-python3==1.0.6
unidic-lite==1.0.8
  • lambda_function.py
    • 入力ファイルはcsv形式で、A列にテキストが入っている想定です
import boto3
import csv
import io
import os
import urllib.parse
from datetime import datetime

import MeCab

s3 = boto3.client("s3")

def lambda_handler(event, context):
    # インプット用S3バケットからファイルを取得
    bucket = event["Records"][0]["s3"]["bucket"]["name"]
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    response = s3.get_object(Bucket=bucket, Key=key)
    input_data = response["Body"].read().decode("utf-8").splitlines()
    csv_reader = csv.reader(input_data)
    headers = next(csv_reader, None) # Skip headers

    # 形態素解析
    mecab = MeCab.Tagger()
    result = []

    for row in csv_reader:
        text = row[0]
        node = mecab.parseToNode(text)
        # parsed_words = []
        # pos_info = []

        while node:
            if node.surface != '':
                result.append(text, node.surface, node.feature])
            node = node.next
        

    # アウトプットファイルを作成
    output_buffer = io.StringIO()
    csv_writer = csv.writer(output_buffer)
    csv_writer.writerow(["元のテキスト", "分解された単語", "情報"])
    csv_writer.writerows(result)

    # アウトプット用S3バケットに保存
    output_bucket = "your-output-bucket"  # アウトプット用バケット名に置き換える
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    output_key = f"output_{timestamp}.csv" # Set the output file name with a timestamp
    s3.put_object(Bucket=output_bucket, Key=output_key, Body=output_buffer.getvalue())
  • S3バケットをトリガーとして設定する

    • 関数を作成後、関数の概要図からS3の「+トリガーを追加」を選択し、S3を指定
    • S3トリガーとなるバケットを選択する
  • ランタイムやメモリの設定変更

    • 処理に時間を要するものは、Lambda関数の「設定」からメモリとタイムアウトの設定を変更し、「保存」
  • 入力データの格納(=トリガーの発動)

  • 出力バケットの確認

  • 出力用のS3バケットの中身を確認する
    (実行に時間がかかるものもある。15分以内で収まるはず。)

    • S3画面でバケットを選択し、吐き出されたCSVを選択、ダウンロード
  • エラー・バグの対応

    • Lambda関数の「モニタリング」タブから「View CloudWatch Logs」を選択 CloudWatchの該当「ログストリーム」を選択
    • うまくいかないときはエラーが吐かれているはずなので確認してみる

参考

DockerコンテナをデプロイしてLambda関数を使う

こんにちは。最近業務でAWSを触ることが多く、その中でLambdaを使うことがあったのですが、3rd partyライブラリを使うのが思ったより大変だったので記事にしようと思います。zipファイルをLambdaにアップロードする・Lambda Layerを利用するといった方法もあるのですが、今回はDockerコンテナをデプロイする方法を採用しました。この方法だと容量制限が10GBとかなり大きくなるので、容量の大きいライブラリも扱えます。

前提

  • Dockerのインストール、イメージ作成、コンテナのプッシュはEC2インスタンスで行う
  • EC2インスタンスに対してはSSH接続して操作する
  • コンテナを扱うためにAmazon ECRを使用する
    • Amazon ECR(Elastic Container Registry):フルマネージドコンテナレジストリで、Dockerイメージ保存・管理ができる

SSH接続のできるEC2インスタンスの用意

  • 下記を参考に準備してください
    miteinoheya.hatenablog.com

  • EC2からECRにログインする際に「AmazonEC2ContainerRegistryFullAccess」のポリシーが必要になるので、↑で作ったIAMロールに新たにポリシーを追加しておく必要があります

    • IAMのページからEC2にアタッチしているIAMロールを選択し、ポリシーをアタッチを選択

    • その他の許可ポリシーに「AmazonEC2ContainerRegistryFullAccess」と入力し、出てきたポリシーを追加

EC2インスタンスでの作業

インスタンスにDockerとAWS CLIを入れる

# Dockerのインストール
sudo yum update -y
sudo yum install -y docker
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -a -G docker ec2-user

# AWS CLIのインストール
sudo yum install -y unzip
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
  • AWS CLIの初期設定を行います
    AWS CLIとは?インストール手順や使い方を初心者向け…|Udemy メディア
    ↑のサイトなどを参考にインストールとコンフィグ設定を行ってください

    • アクセスキーとシークレットアクセスキー
      • ユーザー発行時に発行されていると思います
      • ない場合はAWSマネジメントコンソールでIAM→ユーザー→[自分のユーザー名]のページに移動し、セキュリティ認証情報のタブからアクセスキーを作成できます
    • コンフィグ設定
      • リージョンについてはマネジメントコンソールで普段使っているリージョンを設定しておいた方がいいです(指定せずにSSH接続を試みたときにエラーが出たので)
      • 例えば東京ならap-northeast-1です

Dockerfileの準備

  • homeの配下などに適宜docker用のディレクトリを作成し、Dockerfileを作成します

イメージ作成とECRへのプッシュ

  • 以下のコマンドを実行します
    • イメージ名、リポジトリ名は好きな名前を入れてください
      • サイトなど見ているとイメージ名=リポジトリ名とすることが多いみたいです
    • リージョン、AWSアカウントのID(12桁ハイフンなし)は自分の使用しているものを入れてください
# Dockerイメージのビルド
docker build -t <イメージ名> .

# ECRにリポジトリを作成
aws ecr create-repository --repository-name <リポジトリ名>  --region <リージョン>
## Qでコマンド入力画面に戻る

# イメージにタグを付ける
docker tag <イメージ名>:latest <AWSアカウントのID>.dkr.ecr.<リージョン>.amazonaws.com/<リポジトリ名>:latest

# Amazon ECRにログイン
aws ecr get-login-password --region <リージョン> | docker login --username AWS --password-stdin <AWSアカウントのID>.dkr.ecr.<リージョン>.amazonaws.com

# イメージをECRにプッシュ
docker push <AWSアカウントのID>.dkr.ecr.<リージョン>.amazonaws.com/<リポジトリ名>:latest
  • プッシュした後にDockerfileなどを書き換える場合は、以下の手順で再プッシュします
    • 作成したイメージに↑と異なるDockerタグをつけることでバージョンを管理します
    • 一度ログインしていれば、ECRにログインするコマンドは再度入力する必要はありません
# 新しいバージョンのタグ(ここではv2)でイメージをビルド
docker build -t <イメージ名>:v2 .

# 新しいイメージにECRリポジトリ用のタグを付ける
docker tag <イメージ名>:v2 <AWSアカウントのID>.dkr.ecr.<リージョン>.amazonaws.com/<リポジトリ名>:v2

# 必要に応じてECRにログイン

# イメージをECRにプッシュ
docker push <AWSアカウントのID>.dkr.ecr.<リージョン>.amazonaws.com/<リポジトリ名>:v2
  • ECR上で↓のようになっていればOKです
    • ここではmecab-lambdaというリポジトリ、Dockerイメージを作っています
    • latestとv2というバージョンを作っています

Lambda関数の作成

  • AWS Lambda→関数→関数の作成から作成します

  • コンテナイメージを選び、ECRに保存したコンテナイメージを選択して作成します

  • AWSLambdaBasicExecutionRoleのポリシーが追加されているIAMロールを使用し、関数の作成を押します

    • 他サービスと連携する場合は適宜ポリシーを追加したロールを使用してください
  • その後、適宜トリガーなどを設定すれば実行できると思います

参考

VSCodeを使ってEC2インスタンスにSSH接続する

こんにちは。最近業務でAWSを触ることが多く、その中でEC2インスタンスSSH接続するところで躓いたので備忘録として残しておこうと思います。

前提

  • ローカル環境:Windows10
  • VSCodeのRemote SSHを使ってローカルからEC2インスタンスに接続する
  • Session Managerを使用して接続する
    イメージ図

VPC、セキュリティグループ、IAMロールの準備(必要に応じて)

VPC

  • 作成するリソース:VPCなど
  • 名前タグ:任意の名前を設定してください
  • アベイラビリティゾーンの数:1

  • パブリックサブネットの数:1

  • プライベートサブネットの数:0
  • NATゲートウェイVPCエンドポイント:なし

これで「VPCを作成」を押すと、VPC・サブネット・ルートテーブル・インターネットゲートウェイの作成と設定が完了します

セキュリティグループ

  • セキュリティグループ名:任意の名前
  • 説明:任意の説明
  • VPC:作成したVPCを選択
    • VPCのIDが作成したものと合っているか確認
  • タイプ:SSH
  • ソース:マイIP

  • その他はデフォルトのまま、作成

IAMロール

IAMダッシュボード→ロール→ロールを作成、の順で作成します

  • エンティティタイプ:AWSのサービス
  • ユースケース:EC2
  • 以上を設定して次へ

  • 許可ポリシーの追加

    • 「AmazonSSMManagedInstanceCore」と検索し、出てきたポリシーを選択して次へ
  • ロール名:好きな名前を付けてください

  • 他はデフォルトのままで「ロールを作成」を押します

EC2インスタンスの作成

  • Name and tags:好きな名前を付けてください
  • アプリケーションおよび OS イメージ (Amazon マシンイメージ):今回はAmazon Linuxを選択しました

  • インスタンスタイプ:用途に適したものを選択してください

  • キーペア:

    • すでにある場合は選択のプルダウンから選択してください
    • 新しく作成する場合は以下の手順で作成してください
      • 「新しいキーペアの作成」を選択
      • キーペア名に好きな名前を入力
      • キーペアのタイプ:RSA
      • ファイル形式:.pem
      • 作成後、任意のディレクトリに保存
  • ネットワーク設定

    • 予め準備したVPC、サブネット、セキュリティグループを選択します(もしかしたらデフォルトのままでも行けるかもしれないですが、確認できてないです)
    • 添付画像とは異なりますが、「パブリックIPの自動割当て」は有効にしてください
  • 高度な詳細

    • 事前に準備したIAMロールをアタッチします
  • その他はデフォルトのままでOKです

ローカル環境の準備

予め以下のソフトウェアをインストールしておく必要があります * OpenSSH Client (大抵のOSではデフォルトインストール済み) * Visual Studio Code * AWS CLI * SSM Session Manager plugin

AWS CLI

AWS CLIとは?インストール手順や使い方を初心者向け…|Udemy メディア
↑のサイトなどを参考にインストールとコンフィグ設定を行ってください

  • アクセスキーとシークレットアクセスキー
    • ユーザー発行時に発行されていると思います
    • ない場合はAWSマネジメントコンソールでIAM→ユーザー→[自分のユーザー名]のページに移動し、セキュリティ認証情報のタブからアクセスキーを作成できます
  • コンフィグ設定
    • リージョンについてはマネジメントコンソールで普段使っているリージョンを設定しておいた方がいいです(指定せずにSSH接続を試みたときにエラーが出たので)
      • 例えば東京ならap-northeast-1です

SSM Session Manager plugin

SSH接続の設定

以下、VSCodeで設定する場合についてを記載します

  • 拡張機能でRemote Developmentを入れておきます

  • VSCodeの画面からリモートエクスプローラーのアイコンをクリックし、SSHの右にある設定マークを押すとコンフィグファイルが開きます

  • コンフィグファイルに以下の記述を追加します

    • Host:好きな名前を入れてください
    • HostName:EC2インスタンスIDを記入します
    • User:Amazon Linuxなら「ec2-user」です(マシンイメージによって変わるので注意)
    • IdentityFile:EC2インスタンス作成時に作成した.pemファイルのパスです
    • ProxyCommand:SSMを使ってSSH接続する際に必要な設定です
      • 最後の「your profile」はAWS CLI設定時のprofile名を入れてください。何も設定していない場合は「default」になります
# SSH to remote VS Code instance
Host my-vscode-remote
    HostName "インスタンスID"
    Port 22
    User ec2-user
    IdentityFile "EC2キーペア秘密鍵のフルパス" 
    ProxyCommand C:\Program Files\Amazon\AWSCLIV2\aws.exe ssm start-session --target %h --document-name AWS-StartSSHSession --parameters "portNumber=%p" --profile your_profile

  • コマンドでssh接続をし、以下のような出力が出てくれば成功です

  • VSCodeから接続します

    • コンフィグファイルに書いたHostの名前と同じ名前の接続先にカーソルを合わせ「新しいウィンドウで接続」を押します
    • 最初にリモート側のプラットフォームを聞かれるので「Linux」を選択します
  • 接続できると以下のようなウィンドウが開きます

参考

Chat GPT 備忘録(2023年3月24日時点)

こんにちは。
最近流行りに流行っているChat GPTを眺めながら「乗るしかない、このビッグウェーブに」という気持ちになったので、2023年3月時点でのプロンプトエンジニアリングのテクニックについてのメモを残そうと思います。

所感

あえて最初に所感を書きます。ここ読んでから各手法の説明を読んで欲しいからです。
Chat GPTのプロンプトエンジニアリング=コミュ力
てのが、現時点で一通りネットサーフィンして色々調べた率直な感想です。お前なりの工夫でAI君と仲良くなろう!だと思いました。
なので、この記事ではとりあえず目に留まったプロンプトエンジニアリングの手法を紹介していますが、脳死で使うというより考え方とかを吸収するような使い方が良いんじゃないかと思います。
あと、この分野は流れが速すぎるのですぐ鮮度が落ちます。来月にはここに書いてあることが古くなってるような勢いです。それもあって、あまり脳死でコピペとかはしない方がいいかなというのが個人的なお気持ちです。といいつつ、今月中はギリ鮮度があるので脳死コピペするなら今のうちかもというきもちもあります。

これを踏まえて以下読んでもらえれば。

プロンプトエンジニアリングとは

1

Prompt engineering is a relatively new discipline for developing and optimizing prompts to efficiently use language models (LMs) for a wide variety of applications and research topics. Prompt engineering skills help to better understand the capabilities and limitations of large language models (LLMs).

Researchers use prompt engineering to improve the capacity of LLMs on a wide range of common and complex tasks such as question answering and arithmetic reasoning. Developers use prompt engineering to design robust and effective prompting techniques that interface with LLMs and other tools.

Prompt engineering is not just about designing and developing prompts. It encompasses a wide range of skills and techniques that are useful for interacting and developing with LLMs. It's an important skill to interface, build with, and understand capabilities of LLMs. You can use prompt engineering to improve safety of LLMs and build new capabilities like augmenting LLMs with domain knowledge and external tools.

  • プロンプトエンジニアリング:プロンプトを開発および最適化して、さまざまなアプリケーションや研究トピックに言語モデル (LM) を効率的に使用すること
    • 開発者がプロンプト エンジニアリングを用いることで、LLM(大規模言語モデル)やその他のツールと連携する堅牢で効果的なプロンプト手法を設計
    • LLM と連携し、構築し、LLM の機能を理解するのに役立ちドメイン知識と外部ツールを使用して LLM を強化するなどの新しい機能を構築するのにつながる

色々なメソッド

  • 日付はいつごろ出てきたかの目安

深津式汎用プロンプト(2023/2)

2, 3

#命令書:
あなたは、プロの編集者です。
以下の制約条件と入力文をもとに、 最高の要約を出力してください。

#制約条件:
・文字数は300文字程度。
・小学生にもわかりやすく。
・重要なキーワードを取り残さない。
・文章を簡潔に。

#入力文:
<ここに入力文章>

#出力文:

ポイント

  • ロールを明確にする
  • 入力から出力を作ることを明確にする
  • 何を出力するかを明確にする
  • マークアップ言語を用いて、 本文でない部分を明確にする
  • 命令を箇条書きで明確にする
  • さまざまなワードで、AIの出力しうる空間を、 積極的に狭くしていく

補足

  • 「必要なら質問をしてください」などを付け加えると対話しながら品質向上できたりする
  • 1回で正解を出すというよりは、出力文に対してさらに要望をして対話しながら向上させていくイメージ

ナレーション誘導型生成法(2023/3)

4
※一般的な手法名ではない

概要

  • プロンプト職人が第三者のナレーターに徹し、登場人物たちに会話や議論をしてもらう方法

メリット

  • 登場人物が勝手に議論するので、簡単なナレーション以外ほぼ何もしなくてよくなる
  • 登場人物が勝手に議論を深めるので、従来より深い考察が得られる
  • 舞台や登場人物などの設定を逐次的 (かつ楽) に追加できるので、得られる情報の幅が広がる

問題点

  • 設定が揮発する最初に定めた制約条件が途中から崩れることがある
  • ナレーションとして与えた設定がそのまま出力されてしまう

具体例

ゴールシークプロンプト(2023/2)

5, 6, 7, 8

概要

  • あいまいなゴールを最初に入力し、より良いゴールの定義を出力してもらうプロンプト
  • 改善の過程をAIに自動化するようにプロンプトをデザインする

プロンプト例

#[このコンテンツは [Goal] を SeekするためのTemplateです]
- [コンテンツの詳細]:
- [Goal]:
- Goalを達成するために必要な手順を分解します。
- 分解した手順は「P#」に願番にNumberを付けて格納していきます。
- 変数を定義します。
- [Goal]:議事録作成を自動で行いたい
- {Goal}
- このコンテンツを作成するための{Goal}です。
- Command
- [C1]:
- Goalを選成するために必要なことをStep by Stepで1つづつ実行していけるように手順:[P#]に分解して下さい。
- [Output style] :
[P1]=
....
[P#]=
....
[P(END}]=
- [C2]:
- 各種変数を使用して、変数を減らすことができないか検対する
- [Goal]は必要条件として必ずinputする。
- [Goal]の定義を変数を使用して表すことで、[Goal]の設定だけで手順を分解できるようにしたい
- 一般化して、変数を追加して[Goal]の定義を書き表して下さい
- [Output style] :
- [Added variable]をリスト形式で一般化して書き出して下さい
- 続けて、[Goal]の定義を[Added variable]を使用して書き出して下さい
- [Goal] :{Goal}
- 追加の変数を質問して下さい一つづつ定義を書き表して書く.
- [C3]:
- [C2]のアウトプットの[Added variable]を一般的に解釈して,補完してください.
- 補完した変数を使用して[Goal]を再定義してください.
- [Output style] : 再定義した [Goal]を
- [Goal]:{Goal}で書き出してください
- [C4]
- [コンテンツの詳細]を元に[Goal]を達成するために,Step by Stepで実行していきます.
- [P1]から[P#]を経て順番に[P{End}]までひとつづつ実行していってください.
- [Output style] :
- [O1] = {Output[P1]}
....
[O#] = {Output[P#]}
....
[O{END}] = {Output[P{END}]}
- Run[C1][C2][C3][C4]

上記プロンプトの流れ

  • 最終的にChatGPTにやって欲しいゴールを決める(7行目)
  • ゴールを決めたら、次にゴールを達成するために必要な手順を一つずつChatGPTに書き出してもらう(11-18行目)
    • C1のパートに該当
  • 次に、ゴールを達成するために必要そうな変数を書き出してもらう(19-28行目)
    • C2のパートに該当
  • 変数を組み込んだ形でゴールを書き直してもらう(29-33行目)
    • C3のパートに該当
  • 改善されたゴールを達成するために必要な手順を出力する(34-42行目)
    • C4のパートに該当
  • 全体を実行するように命令(43行目)

出力結果

[P1]= 音声認識ソフトウェアまたはAPIを選択
[P2]= 議事録のテンプレートを作成
[P3]= ミーティングの音声データを入手
[P4]= 音声データをテキストに変換
[P5]= テキストを議事録のテンプレートに適用
[P6]= 議事録を編集し、適切なフォーマットに整理
[P(END)]= 完成した議事録を保存または共有

[Added variable]:
{AudioSource} = ミーティングの音声データ
{TranscriptionSoftware} = 音声認識ソフトウェアまたはAPI
{MeetingTemplate} = 議事録のテンプレート
{ConvertedText} = 変換されたテキスト

Goal : 議事録作成を自動で行いたい ({AudioSource}を使用し、{TranscriptionSoftware}を使って{ConvertedText}に変換し、{MeetingTemplate}に適用する)

[C3]:
[Added variable]を一般的に解釈して,補完してください

[C4]:
[コンテンツの詳細]を元にGoalを達成するために,Step by Stepで実行していきます

[O1] = {Output[P1]} = 音声認識ソフトウェア(Google Cloud Speech-to-Text API)を選択
[O2] = {Output[P2]} = 議事録のテンプレートを作成
[O3] = {Output[P3]} = ミーティングの音声データを入手
[O4] = {Output[P4]} = 音声データをテキストに変換(Google Cloud Speech-to-Text APIを使用)
[O5] = {Output[P5]} = テキストを議事録のテンプレートに適用
[O6] = {Output[P6]} = 議事録を編集し、適切なフォーマットに整理
[O{END}] = {Output[P{END}]} = 完成した議事録を保存または共有

再起処理でのプロンプト(2023/3)

9, 10
概要

  • プロンプト内に再起処理の指示を記述することで、出力品質の向上を意図する手法

プロンプト例

  • シンプルな再起処理のプロンプト
    関数の定義なくてもとりあえず記述しちゃえばよしなに補完してくれる

出力結果

  • 焼きなまし法(Simulated Annealing)と組み合わせたバージョン
    ※コピペする際は、3, 38行目のバックスラッシュは取り除いて使用してください
以下のプログラムの要領で、英文の日本語への翻訳結果が元の日本語の文と近くなるように、英文を近傍操作の繰り返しによってstep by stepで改善するシミュレーションをしてください。再帰処理の結果は25回ごとに出力してください。出力対象は「英文」「その英文の日本語訳」「日本語訳のsimilarity」の3つです。

\```
"""
# 制約条件
0 <= current_similarlity <= 100
0 <= next_similarlity <= 100

# 翻訳ルール
「Magikarp」は、常に「コイキング」と訳す
"""

def generate_english(current_english, cnt, min_iterations=100, init_temperature=100.0, cooling_rate=0.9):
    current_japanese = translate_to_japanese(current_english)
    current_similarity = calc_similarity(str_original_japanese, current_japanese)

    if current_similarity >= 99 and cnt > min_iterations:
        return current_english, current_japanese

    temperature = init_temperature * (cooling_rate**cnt)
    next_english = get_neighbor(current_english)
    next_similarity = calc_similarity(str_original_japanese, translate_to_japanese(next_english))

    probability = math.exp((next_similarity - current_similarity) / temperature)

    if (next_similarity > current_similarity) or (probability > random.random()):
        current_english = next_english

    generate_english(current_english, cnt + 1)


# 変数の初期化
cnt = 0
str_init_english = translate_to_english(str_original_japanese)

# 再帰的な探索を実行
generate_english(str_init_english, cnt)
\```

変数str_original_japaneseに以下の文章全文を代入し、初期の英文のsimilarityを示した上で、シミュレーションをスタートしてください。similarityの評価対象も全文です。きちんと徐々に改善していくようにしてください。回答にはプログラムを使わず、シミュレーション結果のみを出力してください。

コイキングの肉体を持つヒトカゲの精神にとって、新しい肉体での日々は苦難と絶望の連続でした。もともと陸地で生活しており、火を操ることを得意としていたヒトカゲの精神は、水中での生活を強いられることに戸惑いを隠せませんでした。

出力結果
つづき

フィードバックプロンプト(2023/3)

11
概要

  • Chat GPTに入力する文章を以下の観点で評価してくれるようなプロンプト
    • プロンプトとの関連性
    • 表現の明確さ
    • 思考の一貫性
    • 言語使用の質
    • 独創性

プロンプト例

Assigned variables:

Goal: Create a prompt for the role-play exercise to practice giving feedback on a GPT output.
Required variables: GPT output, feedback scoring system, advice or suggestions for improvement.
Prompt:
Hello, and welcome to the GPT Feedback Role-Play Exercise. The purpose of this exercise is to practice giving feedback on a GPT output.

To start, please submit your GPT output in this chat. You can copy and paste your output directly into the chat or type it out.

Once we receive your GPT output, we will evaluate it using our feedback scoring system. The system rates your output on a scale of 1-10 based on the following criteria:

Relevance to the prompt
Clarity of expression
Coherence of thought
Quality of language use
Originality
After evaluating your output, we will provide you with feedback summarizing its strengths and areas for improvement. We will also provide suggestions on how you can improve your work.

During the role-play exercise, one person will act as the feedback provider and the other person will act as the GPT output submitter. The feedback provider will share their feedback on the GPT output, including the strengths and areas for improvement. The GPT output submitter will listen to the feedback and ask any questions they may have.

Please note that this feedback is intended to be constructive and to help you develop your skills. We encourage you to take the feedback seriously and use it to improve your GPT output.

Are you ready to begin the role-play exercise? Please let us know, and we will provide you with the GPT output and the scoring system for evaluation.

全て日本語で書いてください

フィードバックのロールプレイスタート:

「議事録を取るコツを教えて」

出力結果

こんにちは、GPTフィードバックのロールプレイ演習へようこそ。この演習の目的は、GPT出力に対するフィードバックを提供する練習をすることです。

今回のGPT出力は、「議事録を取るコツを教えて」という質問です。それに対する回答は以下の通りです。

議事録を取る際のコツを以下にご紹介します。

準備を整える: 事前に議題や参加者を確認し、必要な文具や録音機器を用意しておきます。
議題と発言者を明確に記録: 議題ごとに発言者とその発言内容を整理して記録します。
簡潔かつ明確に書く: 無駄な情報を省き、要点を明確に伝える文章で記録します。
時間と発言内容を記録: 議論の流れを追うため、発言の時間とその内容を記録します。
決定事項やアクションアイテムを強調: 重要な決定事項やアクションアイテムは明確に記録し、強調しておきます。
録音機器を活用: 議事録の正確性を保つため、録音機器を使って会議を記録し、後で確認できるようにします。
議事録の確認と修正: 会議終了後、議事録を確認し、誤りや漏れがないか確認して修正します。
フィードバックスコアリングシステムによる評価は以下の通りです。

プロンプトとの関連性: 9/10
表現の明確さ: 8/10
思考の一貫性: 9/10
言語使用の質: 8/10
独創性: 7/10
合計スコア: 41/50

改善点:

文章をさらに簡潔にまとめることで、読みやすさが向上します。
具体的な例を挙げることで、理解が深まります。
アドバイス:

簡潔な文章を心がけ、要点のみを記録するようにします。
実際の議事録作成の状況や例を挙げて説明すると、よ
り効果的です。

これらのフィードバックを参考に、今後のGPT出力の改善に役立ててください。練習を重ねることで、より良い結果が得られるでしょう。

ロールプレイ演習を続けるには、次のGPT出力を提出してください。新たな出力に対して、同じフィードバックスコアリングシステムを使用して評価し、改善点やアドバイスを提供します。この繰り返しによって、フィードバックの提供スキルを向上させることができます。

備考

  • 毎回このテンプレートを入力しないとフィードバックしてくれない
  • 前の入力を覚えてくれるわけではない

細かなTips

深津貴之氏
  • 可能性の空間を限定する:限定しないと「それっぽい」回答になりがち
    • 文脈や前提情報を与える
      • 例えば「リンゴの意味を教えて」と聞くと果物としてのリンゴ、宗教的位置づけでのリンゴ、アップル社を表すリンゴ、椎名林檎、、など解釈範囲が広い
        →「宗教におけるリンゴの位置づけとは」のように、前提を明記することでAIの空間を限定し、品質向上につながる
    • 役割を与える
      • 「あなたは敏腕編集者です」「あなたは小学校の先生です。小学生に分かるように~」など
  • 英語で命令する
    • 学習ソースがだいたい英語なので、英語ベースでチャットした方が精度が上がる
  • ベストプラクティスを先に聞いてからベストプラクティスを聞くと品質向上しやすい
    • 例えば「Youtubeのタイトルを考える上で重要なポイントを5つ挙げてください」と言った後に「Youtubeのタイトルを考えてください」と聞くと、最初のポイントを加味してくれる

詠み人知らず

  • 質問する際、「質問は英訳した後に英語で回答を作成し、それを日本語に翻訳したものを回答してください」と付け加えると精度が上がる
  • 出力が長すぎて途中で終わったとき、「続けて」と打つと続きを出力してくれる

余談

ナレーション誘導型生成法を使って、ジョージとキャサリンにChat GPTのコツを話してもらいました。
入力

# 概要
ジョージとキャサリンの二人がChat GPTについて議論しています。議論テーマは「Chat GPTの入力文の工夫の仕方」です

# 背景
- ジョージ:熟練のエンジニア。リリース直後から精力的にChat GPTを使用しており、豊富なノウハウを持つ
- キャサリン:新米エンジニア。Chat GPTのことは知っているが、ほとんど使ったことがない

出力

ジョージとキャサリンは、コーヒーブレイク中にChat GPTについての話題で盛り上がっていました。ジョージは熟練のエンジニアで、Chat GPTのリリース直後から積極的に利用しており、その使い方について豊富な知識を持っていました。一方、キャサリンは新米エンジニアで、Chat GPTのことは知っているものの、まだほとんど使ったことがありませんでした。

ジョージ:「キャサリン、実はChat GPTを使うとき、入力文を工夫することで、より良い結果が得られるんだ。」

キャサリン:「そうなんですか?具体的にどんな工夫をすればいいんですか?」

ジョージ:「まず、質問や要求を明確にすることが大切だよ。曖昧な質問だと、Chat GPTも曖昧な回答をしてしまうことがあるんだ。」

キャサリン:「なるほど、具体的で明確な質問を心がけるんですね。」

ジョージ:「そうだね。それから、文脈を提供することも重要だよ。例えば、質問の前に状況や背景を説明しておくと、Chat GPTが適切な回答をしやすくなるんだ。」

キャサリン:「文脈を考慮するのは確かに大切そうですね。」

ジョージ:「あと、指示語や代名詞を使わずに、具体的な名詞や専門用語を使うと、Chat GPTが理解しやすくなるよ。」

キャサリン:「具体的な言葉を使うことで、誤解を避けられるってことですね。」

ジョージ:「そうだね。これらの工夫をすることで、Chat GPTの回答の質が格段に向上するよ。」

キャサリン:「とても勉強になります。次回からは、入力文の工夫を意識して使ってみます。ありがとうございます!」

ジョージ:「いいね!もし何かわからないことがあれば、いつでも聞いてね。」

アイキャッチ