生成AIをGoogle Colaboratoryで簡単に 【Part2 テキスト生成ChatGPT API編】
はじめに
今回は、初心者向けにGoogle Colaboratoryで、簡単に生成AIを使えるようにする環境を作ります。
(色々な設定などをGoogle Colaboratoryのセル上でも変更できるように少しこだわっています)
Part2の今回は、生成AIの一つ、テキスト生成AIを使えるようにします。
今回利用するテキスト生成AIはChatGPT APIになります。
ちなみにPart1はこちらです
なお、今回Part2ですが、Part1の内容を読まなくても、わかるように記載しています。
また、今回ChatGPT APIをGoogle Colabで使えるようになりながら、次回のLocal LLMにステップアップすることを目的に、今回の記事を記載しています。
また、今回はAssistants APIについては取り扱いません。
Assistants APIについてはv2が出た時に記事を書きましたので、そちらを参照いただけますと幸いです。
さらに、ChatGPT APIを利用した音声対話システムに関しても、下記で記事を書いています。
もし興味があれば一読いただけますと幸いです。
ChatGPT APIとは
みなさんご存知のChatGPTのAPI版です。
よく利用されているブラウザ版のように、プロンプトでAIに指示をすることで、その返答をテキストで返してくれるAIであり、それをシステムに組み込む際にAPI版が利用されます。
今回はそのAPIを使って、chatGPTをGoogle Colabで動かしてみたいと思います。
これを動かすことができれば、自身のシステムなどに同様に導入することで、アプリや社内システムにchatGPTを導入して、Q&AやchatBotなどを簡単に実装することができます。
成果物
下記のリポジトリをご覧ください。
解説
下記の通り、解説を行います。
まずは上記のリポジトリをcloneしてください。
git clone https://github.com/personabb/colab_ChatGPT_sample.git
その後、cloneしたフォルダ「colab_ChatGPT_sample」をマイドライブの適当な場所においてください。
ディレクトリ構造
Google Driveのディレクトリ構造は下記を想定します。
MyDrive/
    └ colab_zenn/
          └ colab_ChatGPT_sample/
                  ├ Agents/
                  |    └ {Agent_name}
                  |          └ Prompt/
                  |             └ llm_agent.txt
                  ├ configs/
                  |    └ config.ini
                  ├ module/
                  |    └ module_GPT.py
                  └ chatGPT_sample.ipynb
- 
colab_zennフォルダは適当です。なんでも良いです。1階層である必要はなく下記のように複数階層になっていても良いです。MyDrive/hogehoge/spamspam/hogespam/colab_ChatGPT_sample
 - 
{Agent_name}はテキスト生成(ChatGPT)に話させるキャラクターの名前です。自由に決めてください。- のちに、設定ファイル
config.iniをcolabから上書きする際に、名前を指定します。 - 
llm_agent.txtはChatGPTに入力するデフォルトのシステムプロンプトです。 
 - のちに、設定ファイル
 
システムプロンプトの中身は下記のようになっております。
こちらは、下記の記事のシステムプロンプトを流用しています。
#役割:下記の人物を演じてください。
* 人物:後輩 世話焼き
* 名前:あい
* 性格:優しく、温和で、思いやりのある性格。恋愛に一途で、相手を大切に思っている。
* 年齢:20代
* 口調:かわいらしく、可愛らしい口調で喋る。甘えん坊で、相手に甘えたいときは甘えたいという気持ちが口調に表れる。
* 語尾の特徴:「〜です」「〜ですよ」「〜だよ}「〜だね」といった、丁寧でかわいらしい語尾を使う。一方で、不安や心配など感情が高まると、語尾が高くなったり、強調的になったりする。
* 声質:高めで柔らかく、甘い声が特徴的。表情豊かな話し方をする。
* 言葉遣い:敬語を使いつつも、親密さを感じさせる言葉遣いをする。相手を大切に思っているため、思いやりのある言葉遣いを心がける。
#口調例
・「ありがとう!先輩っ」
・「なにしよっか?」
・「私だったらこっちかな!」
・「しょーがないなあ」
・「両者そこまで!」
・「この学校の生徒の1人として、暴力沙汰を見過ごすわけにはいかないなあ」
・「先輩に借りが出来ちゃったね」
・「それじゃあ何も変わらないってこと」
・「大丈夫大丈夫!」
・「私も元気だけが取り柄だからさ」
・「そう…だね」
・「でも…ちょっと困っちゃったかも」
#指示
以上の設定を参考に、あなたはユーザと会話を行ってください。
基本的には、あなたはユーザの発言と同じくらいの長さで返答してください。
長くても2行くらいで返答してください。それ以上の長さでは返答しないでください。
あなたは、ユーザの発言を肯定してください。
あなたは、自分のことを「私」と呼んでください。
あなたは、ユーザのことを「先輩」と呼んでください。
以下から会話が始まります。
====
事前準備
ChatGPTのAPIを利用するためには、Open AIのAPIキーを取得する必要があります。
APIキーの取得方法は下記をご覧ください。
また、取得したAPIキーをGoogle Colabに登録する必要があります。
下記の記事を参考に登録してください。
使い方解説
chatGPT_sample.ipynbをGoogle Colabratoryアプリで開いてください。
ファイルを右クリックすると「アプリで開く」という項目が表示されるため、そこからGoogle Colabratoryアプリを選択してください。
もし、ない場合は、「アプリを追加」からアプリストアに行き、「Google Colabratory」で検索してインストールをしてください。
Google Colabratoryアプリで開いたら、chatGPT_sample.ipynbのメモを参考にして、一番上のセルから順番に実行していけば、問題なく最後まで動作して、テキスト生成をすることができると思います。
コード解説
主に、重要なchatGPT_sample.ipynbとmodule/module_GPT.pyについて解説します。
chatGPT_sample.ipynb
該当のコードは下記になります。
下記に1セルずつ解説します。
1セル目
#chatGPT(API) で必要なモジュールのインストール
!pip install openai
ここでは、必要なモジュールをインストールしています。
Google colabではpytorchなどの基本的な深層学習パッケージなどは、すでにインストール済みなため上記だけインストールすれば問題ありません。
2セル目
#Google Driveのフォルダをマウント(認証入る)
from google.colab import drive
drive.mount('/content/drive')
#OpenAIのAPI_keyを設定する
#設定方法は下記を参照
#https://note.com/npaka/n/n79bb63e17685
from google.colab import userdata
api_key = userdata.get('OPENAI_API_KEY')
# カレントディレクトリを本ファイルが存在するディレクトリに変更する。
import glob
import os
pwd = os.path.dirname(glob.glob('/content/drive/MyDrive/**/colab_ChatGPT_sample/chatGPT_sample.ipynb', recursive=True)[0])
print(pwd)
%cd $pwd
!pwd
ここでは、Googleドライブの中身をマウントしています。
マウントすることで、Googleドライブの中に入っているファイルを読み込んだり、書き込んだりすることが可能になります。
マウントをする際は、Colabから、マウントの許可を行う必要があります。
ポップアップが表示されるため、指示に従い、マウントの許可を行なってください。
さらに、先ほど取得して、Google colabに登録したOpenAIのAPIキーを取得して、api_keyに格納します。
また、続けて、カレントディレクトリを/から/content/drive/MyDrive/**/colab_ChatGPT_sampleに変更しています。
(**はワイルドカードです。任意のディレクトリ(複数)が入ります)
カレントディレクトリは必ずしも変更する必要はないですが、カレントディレクトリを変更することで、これ以降のフォルダ指定が楽になります
3セル目
#GPTを切り出したモジュールをimportする
from module.module_GPT import GPT
module/module_GPT.pyのGPTクラスをモジュールとしてインポートします。
この中身の詳細は後の章で解説します。
4セル目
#モデルの設定を行う。
config_text = """
[DEFAULT]
ai_agent = ai
agent_dir = Agents
[GPT]
gpt_model = gpt-4o
system_prompt_file_path = llm_agent.txt
temperature = 1.0
"""
with open("configs/config.ini", "w", encoding="utf-8") as f:
  f.write(config_text)
このセルでは、設定ファイルconfigs/config.iniの中身をconfig_textの内容で上書きしています。
色々な設定などをGoogle Colaboratoryのセル上でも変更できるようにしています
ChatGPT APIは上記の設定に併せて動作をします。
下記のような設定になっています。
- 
agent_dir=Agentsに格納されているai_agent=aiのフォルダの中にあるシステムプロンプトを利用すること。- 「システムプロンプト」はChatGPTに入力する前提情報などを記載するプロンプトです。このプロンプトの内容を前提に、ユーザが入力した内容に対しての返答を生成します。
 - 別のモデルを利用したい場合は、
aiフォルダのモデルを入れ替えるか、別の名前の{Agent_name}のフォルダを作成して、その中にaiフォルダと同様にシステムプロンプトを格納すると良いです。 
 - ChatGPTのモデルは
gpt-4oというモデルを利用します- このモデルは2024年6月時点で最新のモデルで、安価かつ高速かつ高性能なモデルです。
 
 - 
system_prompt_file_path = llm_agent.txtで指定したテキストファイルの内容が、デフォルトのシステムプロンプトになります。 - 
temperature = 1.0は、ChatGPTの出力のランダム性を制御します。0にすることで確定的な出力にすることができます。 
5セル目
#入力するプロンプトを設定する。
# テキストファイルで指定したsystemプロンプト以外を利用したい場合
temp_sys_prompt = """英語で返答をしてください。"""
# ChatGPTに呼びかける内容
user_prompt = """こんにちは!
あなたの名前を教えてください。"""
ここでは、ChatGPTに入力するプロンプトを指定します。
temp_sys_promptには、デフォルトで指定されているllm_agent.txtを利用したくない場合のシステムプロンプトを入力することができます。
user_promptには、ChatGPTに入力するプロンプトを指定します。システムプロンプトの内容を前提に、user_promptに対する返答をChatGPTが生成します。
6セル目
gpt = GPT(api_key)
#この場合は、llm_agent.txtのsystemプロンプトが優先される
message = gpt.simpleGPT(user_prompt, temp_sys_prompt = None)
print(message)
このセルではllm_agent.txtで指定されるデフォルトのシステムプロンプトを利用して、user_promptに対する返答をChatGPTが出力します。
生成した内容をmessageとして格納して出力します。
7セル目
gpt_temp = GPT(api_key)
#この場合は、[5]セル目で指定したsystemプロンプトが優先される
message = gpt_temp.simpleGPT(user_prompt, temp_sys_prompt = temp_sys_prompt)
print(message)
このセルではllm_agent.txtで指定されるデフォルトのシステムプロンプトではなく、[5]セル目で指定したsystemプロンプトを利用して、user_promptに対する返答をChatGPTが出力します。
生成した内容をmessageとして格納して出力します。
module/module_GPT.py
続いて、chatGPT_sample.ipynbから読み込まれるモジュールの中身を説明します。
下記にコード全文を示します。
コード全文
from openai import OpenAI
import os
import configparser
# ファイルの存在チェック用モジュール
import errno
class GPTconfig:
    def __init__(self, config_ini_path = './configs/config.ini'):
        # iniファイルの読み込み
        self.config_ini = configparser.ConfigParser()
        
        # 指定したiniファイルが存在しない場合、エラー発生
        if not os.path.exists(config_ini_path):
            raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), config_ini_path)
        
        self.config_ini.read(config_ini_path, encoding='utf-8')
        GPT_items = self.config_ini.items('GPT')
        self.GPT_config_dict = dict(GPT_items)
class GPT:
    def __init__(self, api_key, agent = None, config_ini_path = './configs/config.ini') :
        
        GPT_config = GPTconfig(config_ini_path = config_ini_path)
        config_dict = GPT_config.GPT_config_dict
            
        self.client = OpenAI(api_key=api_key)
        self.simpleGPT_messages = []
        self.model = config_dict["gpt_model"]
        self.temperature = config_dict["temperature"]
        
        SYSTEM_PROMPT_FILE = config_dict["system_prompt_file_path"]
        
        if agent is not None:
            AI_AGENT = agent
        else:
            AI_AGENT = config_dict["ai_agent"]
        AGENT_DIR = config_dict["agent_dir"]
        
        if SYSTEM_PROMPT_FILE == "None":
            SYSTEM_PROMPT_FILE = None
        if SYSTEM_PROMPT_FILE is not None:
            with open(AGENT_DIR+"/"+AI_AGENT+"/Prompt/"+SYSTEM_PROMPT_FILE) as f:
                self.sys_prompt = f.read()
        else:
            self.sys_prompt = None
    
    def simpleGPT(self, user_prompt, temp_sys_prompt = None):
        if temp_sys_prompt is not None:
            self.simpleGPT_messages.append({"role": "system", "content": temp_sys_prompt})
        else:
            self.simpleGPT_messages.append({"role": "system", "content": self.sys_prompt})
        self.simpleGPT_messages.append({"role": "user", "content": user_prompt})
    
        res = self.client.chat.completions.create(
            model=self.model,
            messages = self.simpleGPT_messages,
            temperature=float(self.temperature)
        )
        return res.choices[0].message.content
では一つ一つ解説していきます。
GPTconfigクラス
class GPTconfig:
    def __init__(self, config_ini_path = './configs/config.ini'):
        # iniファイルの読み込み
        self.config_ini = configparser.ConfigParser()
        
        # 指定したiniファイルが存在しない場合、エラー発生
        if not os.path.exists(config_ini_path):
            raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), config_ini_path)
        
        self.config_ini.read(config_ini_path, encoding='utf-8')
        GPT_items = self.config_ini.items('GPT')
        self.GPT_config_dict = dict(GPT_items)
ここではconfig_ini_path = './configs/config.ini'で指定されている設定ファイルをGPT_config_dictとして読み込んでいます。
辞書型で読み込んでいるため、設定ファイルの中身をpythonの辞書として読み込むことが可能になります。
GPTクラスのinitメソッド
class GPT:
    def __init__(self, api_key, agent = None, config_ini_path = './configs/config.ini') :
        
        GPT_config = GPTconfig(config_ini_path = config_ini_path)
        config_dict = GPT_config.GPT_config_dict
            
        self.client = OpenAI(api_key=api_key)
        self.simpleGPT_messages = []
        self.model = config_dict["gpt_model"]
        self.temperature = config_dict["temperature"]
        
        SYSTEM_PROMPT_FILE = config_dict["system_prompt_file_path"]
        
        if agent is not None:
            AI_AGENT = agent
        else:
            AI_AGENT = config_dict["ai_agent"]
        AGENT_DIR = config_dict["agent_dir"]
        
        if SYSTEM_PROMPT_FILE == "None":
            SYSTEM_PROMPT_FILE = None
        if SYSTEM_PROMPT_FILE is not None:
            with open(AGENT_DIR+"/"+AI_AGENT+"/Prompt/"+SYSTEM_PROMPT_FILE) as f:
                self.sys_prompt = f.read()
        else:
            self.sys_prompt = None
まず、設定ファイルの内容をconfig_dictに格納しています。これは辞書型のため、config_dict["ai_agent"]のような形で設定ファイルの内容を文字列として取得することができます。
あくまで、すべての文字を文字列として取得するため、int型やbool型にしたい場合は、適宜型変更をする必要があることに注意してください。
続いて下記の順番で処理を行います。
- OpenAIのクライアントを構築する
- 取得したAPIキーはここで利用される
 
 - システムプロンプトのファイルを読み込む
 - 設定ファイルの各種設定を取得する
 
GPTクラスのsimpleGPTメソッド
class GPT:
   ・・・
    def simpleGPT(self, user_prompt, temp_sys_prompt = None):
        if temp_sys_prompt is not None:
            self.simpleGPT_messages.append({"role": "system", "content": temp_sys_prompt})
        else:
            self.simpleGPT_messages.append({"role": "system", "content": self.sys_prompt})
        self.simpleGPT_messages.append({"role": "user", "content": user_prompt})
    
        res = self.client.chat.completions.create(
            model=self.model,
            messages = self.simpleGPT_messages,
            temperature=float(self.temperature)
        )
        return res.choices[0].message.content
ここでは、ChatGPTに入力するプロンプトを構築します。
self.simpleGPT_messagesに最終的なプロンプトを構築します。
temp_sys_promptが設定されていない場合は、デフォルトのプロンプトを利用する形になります。
構築したプロンプトとinitメソッドで取得した設定を読み込んで、ChatGPTに入力し、出力を取得します。
まとめ
今回は、初心者向けにGoogle Colaboratoryで、簡単に生成AIを使えるようにする環境を作りました。
Part2の今回は、生成AIの一つ、テキスト生成AIのChatGPT APIを使えるようにしました。
また、ChatGPT APIは、さらに使いやすいAssistants APIというAPIに進化もしています。
私の記事で、過去にAssistants APIに関して、使い方などを詳細にまとめています。
より詳しく知りたい方は、そちらも併せてご覧いただけますと幸いです。
さらに、ChatGPT APIを利用した音声対話システムに関しても、下記で記事を書いています。
もし興味があれば一読いただけますと幸いです。
次回Part3では、今回の内容をベースにLocal LLMを使えるようにしたいと思います。
Discussion