GPT-3で遊んでみた

昨日の[@hcpmiyukiさんの記事](https://qiita.com/hcpmiyuki/items/f78e8fe8505913584fb0)では、Supabaseという今あついBaaSについて書いてくれました！
[MYJLab Advent Calendar 2021](https://qiita.com/advent-calendar/2021/myjlab)の3日目はGPT-3に関してです
論文を要約してAPIで遊びます

# GPT-3とは
イーロン・マスク氏が共同会長を務める非営利のAI研究企業である**OpenAI**が発表した、汎用言語モデルの3世代目です
ネット上のテキストの次の単語を予測するためだけに訓練された**Transformerベースの自己回帰言語モデル**で、なんと**1750億個のパラメータ**で動作するそうです

あまりの精度の高さに以前話題沸騰でした

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">This is mind blowing.<br><br>With GPT-3, I built a layout generator where you just describe any layout you want, and it generates the JSX code for you.<br><br>W H A T <a href="https://t.co/w8JkrZO4lk">pic.twitter.com/w8JkrZO4lk</a></p>&mdash; Sharif Shameem (@sharifshameem) <a href="https://twitter.com/sharifshameem/status/1282676454690451457?ref_src=twsrc%5Etfw">July 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


https://deeplearning.hatenablog.com/entry/gpt3

https://ledge.ai/gpt-3-eduref-net/

以下サイトで紹介されているものもGPT-3が使われています

https://www.educative.io/blog/top-uses-gpt-3-deep-learning

去年の9月にMicrosoftがOpenAIからライセンスを取得しています

https://www.itmedia.co.jp/news/articles/2009/23/news072.html


# 論文要約
2020年に公開された以下論文をざっくりと要約します

https://arxiv.org/abs/2005.14165

いつか読みたいなと思っていたのですが、量が多いので、いつかいつかと先延ばしになっていました
このアドベントカレンダーを機に

## 1 Introduction

ファインチューニングが近年のトレンドだった（BERTやRoBERTaなど）

ただ、ファインチューニングには以下のようなデメリットがある

- 新しいタスクのたびに、タスクに特化したラベル付きのデータセットとタスクに特化した微調整が必要になる
- 大量のラベル付きデータを収集することが難しいタスクもある

ラベル付きの教師データがなくても、人間みたいに妥協できる範囲内で新しいタスクを実行できるようになりたい

上記デメリットを解決するアプローチの1つが**メタ学習**

- 教師なしの事前学習
- 1つのシーケンスの中に、繰り返されるサブタスクが含まれている場合があることを示している

![メタ学習.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/f81f48e6-c6ad-ae80-b2ae-894d8a67dd37.png)

- 内包される様々な言語タスクへの処理能力の獲得が期待できる（**in-context learning**）


しかし、メタ学習は、実用的な活用にはまだ改善が必要

そこで近年、億単位のパラーメータにして言語モデルを大きくするのが流行ってることに着目（**スケーリング則**）
こいつはどうやら、文章生成能力や下流タスクの処理能力も向上することが報告されているらしい

→大幅にパラメータ数を増やした自己回帰言語モデルであるGPT-3を学習することで、スケーリング則とin-context learningの性能を検証する

## 2 Approach
### 事前学習モデルを利用するアプローチ
#### Fine-tuning
- 近年の最も一般的な手法
- 事前に学習したモデルの重みを更新する
- 多くのベンチマークで強力なパフォーマンスを発揮してる
- 欠点は、タスクごとに新しい大規模なデータセットが必要なこと、一般化がうまくいかない可能性があること

#### Few-shot
- タスクに関する説明と少量のタスクの例を与える
  
#### One-shot
- few-shotにおいてタスクの例を1つ与える

#### Zero-shot
- タスクに関する説明のみ与え、タスクの例は与えない



![ panels.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/d3184803-c837-ab3e-f8a1-bfad9446b86d.png)

### モデルのアーキテクチャ
- [GPT-2](https://paperswithcode.com/paper/language-models-are-unsupervised-multitask)と基本は同じモデル
  - ベースはTransformer
  - Sparse Transformerのように局所的なAttentionパターンを使用
- **自己回帰**による学習





### データセット
- Common Crawlのデータセットを使う
- 単語数は**約1兆個**も
- Common Crawlのデータセットは質が低いものがあるので、質の高いデータセットと、類似度によってフィルタリングするなどして対応する
![Datasets used to train GPT-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/71979161-1381-0229-debd-7120101a9ffe.png)


## 3 Results

### モデルサイズと計算量に対するパフォーマンス

![ Sizes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/f859d5c4-be0d-7ff3-60ce-9ed617c9f48e.png)

- 言語モデリングの性能はべき乗に従うと報告されている
- 上の表の8つのモデルに、10万パラメータの6つの小さな(!?)モデルも追加して確認する
- 黄色の線が175BのGPT-3のLoss（まだまだいける）

※PetaFLOP/s-days : 1秒間に1ペタ（10の15乗）回のニューラルネット上の演算操作を、1日分行った計算量

![Smooth scaling of performance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/f200bd9e-be88-80d0-94ca-589980268102.png)

### 言語モデル
- PTBデータセットを使用する
- SoTA、GPT–3ともに、Zero-Shotでの結果を出す
- ちなみにPTBデータセットでは学習してない
- perplexityで確認する
- SoTAから15.3ポイントも差をつけて改善

![ Zero-shot results.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/1ba34d40-89d9-7135-6bcb-b6f40de3bb87.png)

### Q&A
以下3つのデータセットで確認

- NaturalQS
- WebQS
- TriviaQA

![Results on three Open-Domain QA tasks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/1361a8a4-c55c-d72f-0be6-9f92e3e28836.png)


その中でもTriviaQAに関しては、GPT-3のFew-shotがSOTAを達成


### 翻訳
BLUEスコア
![translating.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/124271bc-965c-caff-1ccb-da4172820929.png)

フランス語から英語、ドイツ語から英語に関してはSoTAを達成

上記以外にも、非常に多くのタスクで高い性能を発揮

## 4 Measuring and Preventing Memorization Of Benchmarks
- インターネットから供給されたデータセットなので、ベンチマークのテストセットを一部で学習しちゃってる可能性がある
- インターネット規模のデータセットからのテストの汚染を正確に検出することは、新しい研究分野であり、**確立されたベストプラクティスは存在しない**

（汚染を調査せずに大規模なモデルを訓練することは一般的に行われているが、事前訓練用データセットの規模が大きくなっていることを考えると、この問題に取り組むことはますます重要になってる）

## 5 Limitations 

GPT-3の限界について

- 文書レベルで意味的な繰り返しがあったり、十分な長さの文章でまとまりがなくなったり、矛盾が生じたり、時折、連続しない文章や段落が含まれていたりする、などなど

## 6 Broader Impacts
社会に与える悪いインパクトに関して

- GPT-3の誤用、公平性、エネルギー使用など
- 生成される文章に偏見を含む可能性がある
- 上記に関して分析
- 性別、人種、宗教に関連するバイアスを特定するなど
- 偏見を緩和する規範的、技術的、実証的な課題を結びつける共通の用語体系が必要

## 7 Related Work

関連研究

- ここ数年の自然言語処理のトレンドは，データサイズ・モデルサイズ・訓練時間を同時に上げてパフォーマンスを改善すること
- LSTMベースの言語モデルのパラメータ数を10億以上に増やしたもの　など

https://arxiv.org/abs/1602.02410


## 8 Conclusion
- タスクに特化した教師データによる学習が不要になる
- 非常に大きなモデルを非常に大きなコーパスで学習することで、より汎用的なモデルを構築できた


## すごい
特定のタスクに特化した学習をせずに**事前学習のみ**で、めちゃ多くのタスクで高い性能を出しまっくってるっていう、本当にただただすごいしか出てこない


# APIで遊ぶ
日本語版のAPIで諸々試していきます

### 1. 登録
まず、OpenAIのベータ版サイトで利用申請をします

https://beta.openai.com/

少し待って、申請が認証されてwelcomeメールが届いたら、登録完了です


:::note warn
最初の3ヶ月間に利用できる$18の無料クレジットが提供されるので、この範囲内で遊びます
:::

### （1.5 おまけ　サイト上で試してみる）
Playgroundに移動して
![s1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/b3198efa-5647-d5d2-f515-6d22affe12e3.png)

試しに、「お腹すいた」と入力して
※Few-shotで試すべきなんだろうけど後で試すので、あえてお腹すいたで

![s2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/02618961-4e43-9207-a93a-e783ec2dd520.png)

左下のGenerateボタンを押してみると...
![s3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/993742dc-9e35-e9c4-1eb7-691f66869aa4.png)

文章が！
Generateボタンを押していくと、どんどん続きを書いてくれる
すごい楽しい
Playgroundでも十分色々なタスクを試せます

### 2. APIキーを取得
右上から確認できます
![info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355621/e66b3411-80be-2399-2d44-4398b905f7dd.png)


### 3. pip install
```
$ pip install openai
```

### 4. 実行
```py
import openai

openai.api_key = "APIキー"
```

APIキーを設定したら、以下色々試していきます

#### チャット

```py
start_sequence = "\nAI:"
restart_sequence = "\n私: "

prompt = '''チャットボットです。

私: こんにちは、調子はどう？
AI: 元気です
私: 最近何してるの？
AI:'''

response = openai.Completion.create(
    engine='davinci',
    prompt=prompt,
    max_tokens=30,
    stop="\n")
print(prompt+response['choices'][0]['text'])
```

結果

```
チャットボットです。

私: こんにちは、調子はどう？ 
AI: 元気です。
私: 最近何してるの？
AI: 調子がいいから、努力して何かしはじめました。
```

#### Q&A
```py
start_sequence = "\nA:"
restart_sequence = "\nQ: "

prompt = '''私は真実を答える賢い質問応答ボットです。 

Q: 日本の人口は？
A: 約1億人です。
Q: 世界で一番人口が多い国は？
A: '''

response = openai.Completion.create(
    engine='davinci',
    prompt=prompt,
    max_tokens=100,
    stop="\n")
print(prompt+response['choices'][0]['text'])
```

結果

```
私は真実を答える賢い質問応答ボットです。 

Q: 日本の人口は？
A: 約1億人です。
Q: 世界で一番人口が多い国は？
A: 南アフリカです。
```

#### 翻訳
```py
start_sequence = "\nJapanese:"
restart_sequence = "\nEnglish: "

prompt = '''日本語を英語に翻訳します。

English: I am a student.
Japanese: 私は学生です。
English: I do not speak Japanese.
Japanese:私は日本語を話しません。
English: I love him very much.
Japanese: '''

response = openai.Completion.create(
    engine='davinci',
    prompt=prompt,
    max_tokens=100,
    stop="\n")
print(prompt+response['choices'][0]['text'])
```

結果

```
日本語を英語に翻訳します。

English: I am a student.
Japanese: 私は学生です。
English: I do not speak Japanese.
Japanese:私は日本語を話しません。
English: I love him very much.
Japanese: 私は彼をとても愛しています。
```

#### 映画を絵文字で表現
```py
prompt = '''
Back to Future: 👨👴🚗🕒
Batman: 🤵🦇
Transformers: 🚗🤖
Wonder Woman: 👸🏻👸🏼👸🏽👸🏾👸🏿
Winnie the Pooh: 🐻🐼🐻
The Godfather: 👨👩👧🕵🏻‍♂️👲💥
Game of Thrones: 🏹🗡🗡🏹
Spider-Man:'''

response = openai.Completion.create(
    engine='davinci',
    prompt=prompt,
    temperature=0.8,
    max_tokens=100,
    top_p=1.0,
    frequency_penalty=0.0,
    presence_penalty=0.0,
    stop="\n")
print(prompt+response['choices'][0]['text'])
```

結果

```
Back to Future: 👨👴🚗🕒
Batman: 🤵🦇
Transformers: 🚗🤖
Wonder Woman: 👸🏻👸🏼👸🏽👸🏾👸🏿
Winnie the Pooh: 🐻🐼🐻
The Godfather: 👨👩👧🕵🏻‍♂️👲💥
Game of Thrones: 🏹🗡🗡🏹
Spider-Man: 🕷👪
```

#### キーワードの提示
```py
start_sequence = "\nテキスト:"
restart_sequence = "\nキーワード: "

prompt = '''
テキスト: 宮治研究室（宮治ゼミ）
本研究室では，ネットやウェブなどに加えて，センサやカメラなどによって収集した実世界の情報を融合することによって，社会や生活の役に立つサービスを創出することを目的としています．
その実現の為には，「データ採取」「データ分析」「情報提示」「通信・連携」の 4 領域の技術が必要となります．
キーワード:'''

response = openai.Completion.create(
    engine='davinci',
    prompt=prompt,
    max_tokens=100,
    stop="\n")
print(prompt+response['choices'][0]['text'])
```

結果

```
テキスト: 宮治研究室（宮治ゼミ）
本研究室では，ネットやウェブなどに加えて，センサやカメラなどによって収集した実世界の情報を融合することによって，社会や生活の役に立つサービスを創出することを目的としています．
その実現の為には，「データ採取」「データ分析」「情報提示」「通信・連携」の 4 領域の技術が必要となります．
キーワード: リモートセンシング, IC ラップ, レーザコンピューティング, センサ, カメラ, インタラクション, カラーチャネル, ウェブモデル, 交流, GPS, 位置情報, 実世界情報
```

#### CSSのカラーコードの提案
```py
prompt = '''
明るくて綺麗な空の色みたいな青のカラーコード:

background-color: #'''

response = openai.Completion.create(
    engine="davinci",
    prompt=prompt,
    temperature=0,
    max_tokens=64,
    top_p=1.0,
    frequency_penalty=0.0,
    presence_penalty=0.0,
    stop=";"
)

print(prompt+response['choices'][0]['text'])
```

結果

```
明るくて綺麗な空の色みたいな青のカラーコード:

background-color: #00b2ff
```


# おわり
時々失敗することはあれど、かなりの汎用性の高さと自然な日本語にびっくりしました
このレベル感でタスクに特化した学習をしてないっていうのが本当にすごいです、、
簡単に試せて楽しかったです

:::note info
上記で試したもの以外にも色々あります（感情分析、キャッチコピージェネレータ、難しい文章を優しい文章に要約、住所の抽出、Pythonを自然言語で解説、自然言語からSQLを作成、JavaScriptをPythonに変換、などなど...）
:::
 
## 参考文献
https://beta.openai.com/examples/default-summarize

https://jman4190.medium.com/how-to-build-a-gpt-3-chatbot-with-python-7b83e55805e6