GPT-3を用いて1つの単語からプレゼンを自動生成するシステムの作り方

![Cursor_と_ハンバーガーについて_-_Google_スライド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958603/e917b94f-4824-3502-fa51-e7580894bb99.png)


こんにちは！逆瀬川( https://twitter.com/gyakuse )です！
今日はプレゼンの自動生成をやっていきたいと思います！

作成したスライド参考:

https://docs.google.com/presentation/d/1tDNN3_1RNCdXKj-GIGaTQEtXuaqeGVxn4c7-A1YxEgY/edit?usp=sharing

## 概要

GPT-3を用いて任意の目的からプレゼンの骨子を作り、
Diffusion Modelを用いてスライドを説明するような画像を生成します。
海外ではスライド作成系のサービスがどかどか出てるので、見てみると楽しいです。

- [https://elucile.lubis.co.jp/](https://elucile.lubis.co.jp/)
- [https://www.beautiful.ai/](https://www.beautiful.ai/)
- [https://www.slidesai.io/](https://www.slidesai.io/)
- [https://beta.tome.app/](https://beta.tome.app/)

## Colab

https://colab.research.google.com/drive/1bXMtfZGI7D0gT2fI_8nNjsFbjif3C7Jb?usp=sharing

### 注意

- 今回のシステムはOpenAIのAPIキー、Google CloudのプロジェクトIDを必要とします
- 処理毎にCloud StorageのBucketを作成します
    - 不要になり次第こちらから削除してください
        - https://console.cloud.google.com/storage/browser 

### 使い方

- Google Cloud のコンソールへ行き、プロジェクトIDをコピーします
    - https://console.cloud.google.com/
    - プロジェクトがない場合は作成が必要です
- プロンプトやOpenAIのキーを貼り付けます
- すべてのセルを実行します
- 認証を行います
- 作成されたスライドはGoogleドライブのトップにアクセスすると確認することができます
    - https://drive.google.com/

## 処理の流れ

- 作りたいプレゼン内容を自然言語で入力する
- GPT-3を使って以下を行う
    - 入力内容から骨子を作る
    - 骨子からそれぞれのページの内容を肉付けする
    - 画像生成のためのプロンプトを作成する
- Diffusion Modelを使って画像を生成する
- API を使って Google Slide の各ページに情報を埋め込む

## 実装

### 実装の前提

今回は簡単に(1時間程度でサクッと)実装してしまいたいので、プレゼンの自由度を制限します。
○○の紹介、という形式のプレゼンを生成する仕組みを作ることにします。
ちょっと間違っていたほうが面白いので、厳密性は考えません。

### 入力内容からプレゼンの骨子を作る

これは以下のようなプロンプトで行います。

```py
def prompt_template_whatis(item):
    return f"""{item}とは何ですか？
説明してください。説明においては以下のルールに従ってください。

・リスト形式で出力する (先頭は ・ を使う)
・わかりやすい文章で丁寧に説明する

A:"""
```

### 画像を生成する

以下のnpakaさんの記事を参考にStable Diffusion2.1を入れ作成します。

https://note.com/npaka/n/n1f4e2bcad037

```py
from diffusers import StableDiffusionPipeline, EulerDiscreteScheduler
import torch

model_id = "stabilityai/stable-diffusion-2-1-base"
pipe = StableDiffusionPipeline.from_pretrained(
    model_id, 
    scheduler=EulerDiscreteScheduler.from_pretrained(
        model_id, 
        subfolder="scheduler"
    ), 
    torch_dtype=torch.float16
).to("cuda")
pipe.enable_attention_slicing()
```

`stabilityai/stable-diffusion-2-1-base` モデルを使ったので、
生成するときはpipeから以下のように512x512で叩きます。

```py
pipe(image_prompt, height=512, width=512).images[0]
```

### 画像生成用のプロンプトの生成

GPT-3を用いて画像生成のためのプロンプトを生成します。few-shotにて例を出し、誘導します。

```plaintext
あるものごとの歴史の記述からイラストを描くための説明を英語で出力するタスクです。
豊富な英語の語彙を用いて描写を記述してください

# Task 1: りんごの歴史

歴史の記述:
・古代ギリシャでは、「林の神」アテナイが、英知恵と愛を表す「林の女神」として、野生りんごを食べたと伝えられています。
・現在、りんごの最も一般的な品種として認識されているのは、15世紀にイタリアの研究家が作った染色りんごです。
・17世紀後半には、アメリカにもりんごが持ち込まれ、そこから輸入されたりんごが増加しました。
・19世紀になると、英語圏などで生産量が伸びました

生成されたイラスト用プロンプト: apple Athens holding smile

# Task 2: <item>の歴史

歴史の記述:
<text>

イラスト用プロンプト: 
```

### 画像のアップロード

Google Cloud Storageにアップロードします。

```py
from google.cloud import storage

bucket = storage.Client().get_bucket(bucket_name)

def upload_file(file_name, file_path):
    blob = bucket.blob(file_name)
    blob.upload_from_filename(file_path)
    blob.make_public()
    return blob.public_url
```

### Google Slideの自動作成

以下のようにスライドを作成し、編集を行います。
詳細な実装はcolabを御覧ください。

```py
# スライドの新規追加処理
def create_slide(presentation_id, before_page_num, page_id):
    requests = [
            {
                'createSlide': {
                    'objectId': page_id,
                    'insertionIndex': str(before_page_num),
                    'slideLayoutReference': {
                        'predefinedLayout': 'BLANK'
                    }
                }
            }
        ]
    
    body = {
        'requests': requests
    }
    response = service.presentations().batchUpdate(presentationId=presentation_id, body=body).execute()
```

## 既知の問題について

![スライド自動作成withDiffusion_GPT_3_ipynb_-_Colaboratory.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958603/88077f9e-178f-2bc3-8507-65e901c0389d.png)

スライド追加の部分(一番下の3つの関数)でこのようなエラーが発生することがあります。
生成したスライドを開き、真っ白なページがあればそれを消して再試行してください。
真っ白なページがなければそのまま再試行してください。

## やっていないこと

- GPT-indexなどを繋ぎこみ、情報を検索することでさらに豊富な内容を記述できるようになります
- 画像生成も簡易なものなので、欲しい画像に寄せるようなプロンプトを生成する処理を書くと嬉しさが増えます
- 簡単のため、今回は0->1のプレゼン作成をしました。テンプレートからコピーをする等で表現力が増し実用的なものになります

## 後記

- 上記の程度の簡易「自動プレゼン作成システム」は2時間程度で作れて便利です
- ちゃんとやれば商用サービスにもできそうです(カスタム検索APIとの繋ぎ込みやテンプレートを増やす等で価値あるサービスが作れそうです)