見出し画像

gpt-2-simple (3) - gtp-2-simpleのリポジトリ

以下の記事を参考に書いてます。

GitHub - minimaxir/gpt-2-simple

1. gpt-2-simple

gpt-2-simple」は、OpenAIのGPT-2ファインチューニングおよびテキスト生成を行うためのシンプルなPythonパッケージです。prefixによって、指定したフレーズでテキストを開始することもできます。

このパッケージは、以下のパッケージに最小限の変更を行なって、構築しています。

OpenAIの公式GPT-2リポジトリのモデル管理(MITライセンス)
・Neil ShepperdのGPT-2フォークのファインチューニング(MITライセンス)
textgenrnnのテキスト生成の出力管理(MITライセンス)

CPUでも生成することもできますが、ファインチューニングにはGPUの使用を強くお勧めします(はるかに低速です)。クラウドで訓練する場合は、TensorFlow Deep Learningイメージを使用したGoogle ColabのノートブックまたはGoogle Compute Engine VMを使用することを強くお勧めします。

2. インストール

「gpt-2-simple」はpip経由でインストールできます。

pip3 install gpt-2-simple

また、システムに対応するTensorFlowをインストールする必要があります。GPU対応のTensorFlow 1.14 / 1.15をお勧めします。

3. 使用方法

モデルをローカルにダウンロードし、データセットでファインチューニングし、テキスト生成する例は、次のとおりです。

import gpt_2_simple as gpt2
import os
import requests

# モデルを /models/124M/ にダウンロード
model_name = "124M"
if not os.path.isdir(os.path.join("models", model_name)):
    print(f"Downloading {model_name} model...")
    gpt2.download_gpt2(model_name=model_name)   
    
# 入力データを shakespeare.txt にダウンロード
file_name = "shakespeare.txt"
if not os.path.isfile(file_name):
    url = "https://raw.githubusercontent.com/karpathy/char-rnn/master/data/tinyshakespeare/input.txt"
    data = requests.get(url)

    with open(file_name, 'w') as f:
        f.write(data.text)

# ファインチューニング
sess = gpt2.start_tf_sess()
gpt2.finetune(sess,
    file_name,
    model_name=model_name,
    steps=1000)   # steps is max number of training steps

# テキスト生成
gpt2.generate(sess)

生成されたモデルのチェックポイントは、デフォルトで /checkpoint/run1 に出力されます。そのフォルダからモデルを読み込み、テキスト生成する例は、次のとおりです。

import gpt_2_simple as gpt2

sess = gpt2.start_tf_sess()
gpt2.load_gpt2(sess)

gpt2.generate(sess)

textgenrnn」と同様に、return_as_listパラメータを使用して、テキストに保存できます。

single_text = gpt2.generate(sess, return_as_list=True)[0]
print(single_text)

チェックポイントフォルダに複数のモデルを格納/ロードする場合は、run_nameパラメータをfinetune()およびload_gpt2()に渡すことができます。

「ファインチューニング」と「テキスト生成」のためのコマンドラインインターフェース(CLI)もあります。

gpt_2_simple finetune shakespeare.txt
gpt_2_simple generate

関数で使用するパラメータのほとんどは、CLI引数として使用できます。

gpt_2_simple generate --temperature 1.0 --nsamples 20 --batch_size 20 --length 50 --prefix "<|startoftext|>" --truncate "<|endoftext|>" --include_prefix False --nfiles 5
【注意】別のデータセットをファインチューニング整したり、別のモデルをロードしたりする場合は、最初にPythonセッションを再起動してください。

4. gpt-2-simpleと他のテキスト生成の違い

「GPT-2」のテキスト生成方法は、「textgenrnn」などの他のテキスト生成とは少し異なります。具体的には、完全なテキストシーケンスを純粋にGPUで生成し、後でデコードしています。これは、基礎となるモデルコードをハッキングしないと簡単に修正できません。 

・一般に、「GPT-2」は生成期間全体にわたってコンテキストを維持するのに優れているため、会話型のテキスト生成に適しています。また、一般的にテキストは文法的に正しく、適切な大文字と、少数のタイプミスがあります。

・元の「GPT-2モデル」は非常に多種多様なソースで訓練されているため、入力テキストにはないイディオムをモデルに組み込むことができました。

・「GPT-2」は、リクエストごとに最大1024個のトークンしか生成できません(英語のテキストの約3〜4段落)。

・「GPT-2」は、特定のエンドトークンに到達してもすぐに停止できません。 (回避策:切り捨てパラメータを生成関数に渡して、指定した終了トークンまでのテキストのみを収集します。長さを適切に減らすことができます。)

・他のテキスト生成が温度(tempereture) 0.2-0.5でうまく機能する一方で、「GPT-2」はより高い0.7-1.0でより興味深いテキストを生成します。

・「GPT-2」をファインチューニングする場合、大きなテキスト内のドキュメントの最初または最後の意味はありません。ドキュメントの最初と最後を示すために、カスタム文字シーケンスを使用する必要があります。生成時に、prefix(開始トークン)とtruncate(終了トークン)を指定できます。include_prefix = Falseを設定して、prefixを破棄することもできます(<|startoftext|>のように不要な場合)。

・単一列の.csvファイルをfinetune()に渡すと、自動的にCSVが「GPT-2」での訓練に最適な形式に解析されます(全てのテキストドキュメントに<|startoftext|>を前に付けて<|endoftext|>を付けることを含む) 、したがって、上記の切り捨てのトリックは、出力を生成するときに役立ちます。これは、各テキストドキュメントの引用符と改行の両方を正しく処理するために必要です。

・「GPT-2」では、nsamplesに割り切れるbatch_sizeを設定することにより、テキストを並行して生成できるため、生成がはるかに高速になります。 GPUで非常にうまく機能します(Google ColabのK80でbatch_sizeを最大20に設定できます)。

・「GPT-2」のアーキテクチャにより、より強力なGPUでうまく拡張できます。 124Mモデルの場合、長期間訓練する場合、GCPのP100 GPUはK80 / T4の約3倍の価格で3倍の価格であり、価格的に同等です(V100はP100の約1.5倍高速です)ただし、価格の約2倍です)。 P100は、batch_size = 1でもGPUの100%を使用し、V100 GPUの約88%を使用します。

・部分的に訓練された「GPT-2モデル」があり、それを引き続きファインチューニングする場合は、overwrite = Trueを設定できます。これにより、重複コピーを作成せずに、訓練を続行し、モデルの以前の反復を削除します。これは転移学習に特に役立ちます(たとえば、1つのデータセットでGPT-2を大幅にファインチューニングしてから、他のデータセットを微調整して両方のデータセットの「マージ」を取得します)。

・入力テキストデータセットが大きい場合(> 100 MB)、gpt2.encode_dataset(file_path)を使用してデータセットを事前にエンコードして圧縮することができます。出力は圧縮された.npzファイルであり、ファインチューニングのためにGPUに非常に高速にロードされます。

・774Mの「large」モデルは、最新のGPUがメモリ不足になるため、ファインチューニングをサポートしている可能性があります(Google ColabでP100 GPUを使用すると幸運になる場合があります)。ただし、gpt2.load_gpt2(sess、model_name = '774M')およびgpt2.generate(sess、model_name = '774M')を使用して、デフォルトの事前学習済みモデルから引き続き生成できます。

・1558Mの「extra large」の真のモデルは、Google Colabのノートブックに含まれているGPUを使用した場合、最初から機能しない場合があります。最適な構成を特定するには、さらにテストが必要です。

5. gpt-2-simpleを使用したアプリの例

gpt2-small : デフォルトのGPT-2 124M事前学習済みモデルを使用するアプリ
gpt2-reddit : 指定されたsubredditやキーワードに基づいてRedditタイトルを生成するアプリ
gpt2-mtg : Magic The Gatheringのカードを生成するアプリ

6. gpt-2-simpleを使用したテキスト生成の例

ResetEra : 生成されたビデオゲームフォーラムディスカッション(GitHub
/r/legaladvice : タイトルの生成(GitHub
Hacker News : 何万もの生成されたHacker News送信タイトル

7. gpt-2-simpleのパラメータ

◎ --mode  【必須】
CLIを使用するためのモード("finetune" or "generate")。

◎ --run_name (デフォルト: 'run1')
[finetune/generate] モデルを保存/ロードするための実行番号。

◎ --checkpoint_dir (デフォルト: 'checkpoint')
[finetune] チェックポイントディレクトリのパス

◎ --model_name (デフォルト: '124M')
[finetune] ファインチューニングするGPT-2モデルの名前

◎ --model_dir (デフォルト: 'models')
[finetune] ファインチューニングするGPT-2モデルのディレクトリのパス

◎ --dataset (デフォルト: None)
[finetune] ソーステキストへのパス

◎ --steps (デフォルト: -1)
[finetune] トレーニングするステップ数(無限の場合は-1)

◎ --restore_from (デフォルト: 'latest')
[finetune] モデルを 'fresh' にロードするか、'latest' のチェックポイントからロードするか

◎ --sample_every (デフォルト: 1000000)
[finetune] サンプル出力の頻度

◎ --save_every (デフォルト: 100)
[finetune] チェックポイント保存の頻度

◎ --print_every (デフォルト: 10)
[finetune] 進捗出力の頻度

◎ --optimizer (デフォルト: 'adam')
[finetune] ファインチューニングに使用するオプティマイザー('adam' or 'sgd')

◎ --overwrite (デフォルト: False)
[finetune] 訓練を続けるときに既存のモデルを上書きする

◎ --nfiles (デフォルト: 1)
[generate] 生成するファイル数

◎ --nsamples (デフォルト: 1)
[generate] 生成するテキスト数

◎ --folder (デフォルト: 'gen')
[generate] 生成されたファイルを保存するフォルダ

◎ --length (デフォルト: 1023)
[generate] 生成されたテキストの長さ(トークン)

◎ --temperature (デフォルト: 0.7)
[generate] 生成されたテキストの温度 

◎ --top_k (デフォルト: 0)
[generate] top k トークンからのサンプルのみ

◎ --top_p (デフォルト: 0.0)
[generate] top p 確率からのサンプル(ゼロでない場合はtop_kをオーバーライド)

◎ --batch_size (デフォルト: 1)
[generate] 生成のバッチサイズ(GPUの場合は増加)

◎ --prefix (デフォルト: None)
[generate] 生成されたテキストの接頭辞

◎ --truncate (デフォルト: None)
[generate] 生成されたテキストの切り捨て

◎ --include_prefix (デフォルト: True)
[generate] 切り捨てるときにプレフィックスを含める

◎ --sample_delim (デフォルト: '=' * 20 + '\n')
[generate] 生成された各サンプル間の区切り文字

◎ --multi_gpu (デフォルト: True)
[generate/finetune] 実行するために複数のGPUを割り当てる

この記事が気に入ったらサポートをしてみませんか?