Amazon Web Services ブログ

Amazon SageMaker の自動モデルチューニングを使い NLP モデルのパフォーマンスを最大化する

最近の 2 年間で、自然言語処理 (NLP) のフィールドには、多くの素晴らしいブレイクスルーが見られました。先進的な深層学習モデルが、NLP タスクにおける最先端パフォーマンスの基準を引き上げています。新しく公開された NLP モデルからメリットを得るための最良のアプローチは、まずトレーニング済みの言語モデルに新しいデータセットを適用し、その後で、特定の NLP タスク用にファインチューニングを施すことです。このアプローチは転移学習と呼ばれています。この手法によれば、モデルのトレーニングをゼロから始めることに比べ、必要なリソースを顕著に削減することが可能になります。また、少ないトレーニングデータからでも、しっかりした結果を得ることができます。

NLP テクニックが素早い成長を続ける中、トレーニング済み言語モデルをパッケージ化した NLP フレームワークも多く開発されてきており、ユーザーは転移学習を容易に実施できるようになっています。トレーニング済みの言語モデルを備えた NLP フレームワークとして普及しているものの例としては、ast.ai が作った ULMFiT と Hugging Face が作った PyTorch-Transformers の 2 つが挙げられます。

このブログ記事では、Amazon SageMaker で PyTorch-Transformers を使い NLP モデルのファインチューニングを行う方法をご紹介します。また、組み込みの自動モデルチューニング機能を、Microsoft Research Paraphrase Corpus (MRPC) [1] 、および Stanford Question Answering Dataset (SQuAD) 1.1 [2] の 2 つの NLP データセットに適用する方法も合わせて説明していきます。PyTorch-Transformers は、BERT、XLNET、GPT-2 などの先進的なトレーニング済み言語モデルを収録したライブラリです。この記事では、Google により開発 [3] された、BERT (Bidirectional Encoder Representations from Transformers) の事前トレーニング済み uncased ベースモデルを使用します。

このブログ記事について
読む時間 10 分間
完了するまでの時間 ~20 時間
完了するためのコスト ~160 USD (記事公開時点)
学習レベル 高度 (300)
AWS のサービス Amazon SageMaker
Amazon S3

ステップバイステップの詳細なガイドは、ノートブック例の中でご覧いただけます。

この記事は、次の手法をご紹介するためのものです。

  • Amazon SageMaker の PyTorch フレームワークを使い、 SageMaker の中の PyTorch-Transformers Git コードを実行します。これはローカルマシン上で動作できるものです。
  • Amazon SageMaker に備わっている自動モデルチューニング機能を使い、ハイパーパラメータの最適化を行います。
  • NLP モデルのハイパーパラメータ値に対する感受性を確認します。

PyTorch-Transformers のセットアップ

今回は、ml.t2.medium ノートブックインスタンスを使います。Amazon SageMaker に関する一般的な解説については「Amazon SageMaker の開始方法」をご参照ください。

この記事では、MRPC の General Language Understanding Evaluation (GLUE) データセットを用いて、PyTorch-Transformer の Amazon SageMaker へのオンボーディングと、SageMaker の PyTorch コンテナによるモデルのファインチューニングを実施するための、一連の主要な手順を例示していきます。PyTorch-Transformer のセットアップには、次に示す手順を実行します。

  1. GitHub レポジトリにあるスクリプト download_glue_data.py を実行し、GLUE データのダウンロードを行ってから、それを$GLUE_DIR ディレクトリ内で解凍します。次に示す Jupyter ノートブックのコードでは、データをダウンロードし、それを glue_data という名前のフォルダーに保存します。
    !python download_glue_data.py --data_dir glue_data --tasks all
  2. GitHub の PyTorch-Transformer コードを Amazon SageMaker ノートブックインスタンスにあるローカルディレクトリにコピーします。次にコードを示します。
    !git clone https://github.com/huggingface/pytorch-transformers.git

    これら 2 つの手順を完了すると、ご自身の Jupyter ノートブックのディレクトリには、glue_data という名のデータフォルダーと、pytorch-transformers というスクリプトフォルダーが作られるはずです。

  3. MRPC データセット用に BERT モデルをファインチューニングします。Amazon SageMaker にある PyTorch エスティメータのトレーニングは、/pytorch-transformers/example/ にあるスクリプト run_glue.py により行います。

エスティメータを作成する前に、次のような修正を加えます。

  • run_glue.py の中の argparse コードを確認および修正して、SageMaker のエスティメータが入力引数をハイパーパラメータとして読み込めるようにします。たとえば、do_traindo_eval といった引数がハイパーパラメータとして解釈されるようにし、Amazon SageMaker の中で PyTorch エスティメータが呼び出される時に、それらに論理値を引き渡すといったことが考えられます。
  • requirements.txt というファイルを、トレーニングスクリプト run_glue.py があるのと同じディレクトリ内に作成します。この requirements.txt ファイルには、デフォルトで Amazon SageMaker の PyTorch コンテナにインストールされない、トレーニングスクリプトに必要な各パッケージを含めます。インストールする必要があるパッケージの 1 例としては、pytorch_transformers などがあります。

requirements.txt ファイルは必要なパッケージのリストが記述されたテキストファイルです。これらのパッケージは、Python のパッケージインストーラー (今回の場合は pip) によりインストールされます。トレーニングジョブを起動すると、Amazon SageMaker のコンテナは自動的に、スクリプトのソースフォルダー内で requirements.txt を検索し、このファイルに記述されたパッケージを pip install を使いインストールします。

Amazon SageMaker で NLP モデルをファインチューニングする

データのダウウンロードとトレーニング用スクリプトの準備ができたら、Amazon SageMaker 内で NLP モデルのファインチューニングが開始できます。次の手順を実行し、トレーニングジョブを起動します。

  1. Amazon S3 にデータをアップロードします。次にコードを示します。
    inputs = sagemaker_session.upload_data(path=data_dir, bucket=bucket, key_prefix=s3_prefix)
  2. トレーニングスクリプトの環境変数と、ハイパーパラメータの初期設定を定義します。次にコードを示します。
    container_data_dir = '/opt/ml/input/data/training'
    container_model_dir = '/opt/ml/model'
    
    parameters = {
        'model_type': 'bert',
        'model_name_or_path': 'bert-base-uncased',
        'task_name': task_name,
        'data_dir': container_data_dir,
        'output_dir': container_model_dir,
        'num_train_epochs': 3,
        'per_gpu_train_batch_size': 64,
        'per_gpu_eval_batch_size': 64,
        'save_steps': 150,
        'logging_steps': 150
        # you can add more input arguments here
    } 

    前記のコードでは、入力データ (/opt/ml/input/data/training) とモデルアーティファクト (/opt/ml/model) のコンテナディレクトリをトレーニングスクリプトに渡しています。この際、ローカルのディレクトリではなくコンテナにおけるディレクトリを記述します。Amazon SageMaker は、トレーニングジョブを Docker コンテナで実行するためです。トレーニングジョブの起動には、S3 内でのトレーニングデータのパスを estimator.fit() 関数に渡す必要があります。コンテナ作成プロセスの中で、Amazon SageMaker が自動的に S3 データをダウンロードし、それをコンテナの環境変数で定義されたディレクトリに保存します。

    Amazon SageMaker の Docker コンテナにおいて、モデルの入力と出力となるロケーションを正確に把握しておくことが大切です。モデルの入力先として /opt/ml/input/data/channel_name/ と指定し、channel_name の部分はユーザーが (training あるいは testing などで) 書き換えます。モデルアーティファクト保存先は /opt/ml/model/ と指定します。詳細な情報については、「Amazon SageMaker コンテナ: Docker コンテナを作成するためのライブラリ」および、GitHub リポジトリの「Building your own algorithm container」をご参照ください。

    トレーニングスクリプト run_glue.py では、トレーニング用と検証用のデータを同一のディレクトリからロードするので、定義する必要があるのは 1 つのデータディレクトリのみです。そのチャネル名には training とラベル付けします。モデルのログファイルとトレーニング済みのアーティファクトは、Docker コンテナ内の /opt/ml/model/ ディレクトリに保存され、トレーニングジョブが完了した時点で S3 にアップロードされます。

  3. PyTorch エスティメータを作成しトレーニングジョブを起動する次にコードを示します。
    from sagemaker.pytorch import PyTorch
     
    estimator = PyTorch(entry_point='run_glue.py',
                        source_dir = './pytorch-transformers/examples/',
                        hyperparameters=parameters,
                        role=role,
                        framework_version='1.1.0',
                        train_instance_count=1,
                        train_instance_type=’ml.p3.2xlarge’
                       )
    
    estimator.fit({'training': inputs})

    前記の例でのトレーニングジョブは、約 5 分間ほどで完了します。起動されたトレーニングジョブは、Amazon SageMaker コンソールの Training jobs セッションタブで確認することができます。該当するトレーニングジョブを選択することで、トレーニング実行に関する詳細情報が見られ、Amazon CloudWatch のログや、モデル出力とアーティファクトのための S3 ロケーションへのリンクなどが確認できます。

自動モデルチューニングの起動

まず、トレーニングのセットアップ検証のために、1 つのトレーニングジョブを完全に終了し、エラーがまったく発生しないことを確認します。その後は、ベイズ最適化を使っての自動モデルチューニングを起動できるようになります。手順を次に示します。

  1. 最適化メトリクスを定義します。Amazon SageMaker では、定義済みメトリクスが用意されており、これはトレーニングに関する CloudWatch ログから自動的に読み取られます。これにより、ビルトインアルゴリズム (XGBoost など) や各フレームワーク (TensorFlow、MXNet など) に対応しています。独自のトレーニングスクリプトを使う場合は、ログからメトリクスを抽出するシンプルな正規表現を、Amazon SageMaker に指定してあげる必要があります。次にコードを示します。
    metric_definitions = [{'Name': 'f1_score', 'Regex': '\'f1_\': ([0-9\\.]+)'}]

    モデルの評価結果が、CloudWatch ログ内に正確に記述されるよう、run_glue.pyを修正します。今回の記事では、自動モデルチューニングの最適化メトリクスとして、F1 スコアを使用します。

  2. ハイパーパラメータの範囲を定義します。次にコードを示します。
    hyperparameter_ranges = {
            'learning_rate': ContinuousParameter(5e-06, 5e-04), scaling_type="Logarithmic")
        }

    大きな NLP では、一度のチューニングジョブを 1 つか 2 つのハイパーパラメータに制限するほうが望ましいです。これで、ベイズ最適化が安定して行われ収束も速くなります。また、ハイパーパラメータ値を変化させると、新たなコンピューティングリソースが必要となる可能性があることも、覚えておいてください。たとえば、深層学習のバッチサイズは、モデルトレーニング中に必要な CPU/GPU のメモリ量に直接影響を与えます。ハイパーパラメータの範囲に、EC2 トレーニングインスタンスの容量と適合した値を設定するのも良い方法です。これは、モデルチューニングをスムーズに進めるのに役立ちます。

  3. ハイパーパラメータチューニングジョブの起動次にコードを示します。
    from sagemaker.tuner import HyperparameterTuner
    
    objective_metric_name = 'f1_score'
    
    tuner = HyperparameterTuner(estimator,
                                objective_metric_name,
                                hyperparameter_ranges,
                                metric_definitions,
                                strategy = 'Bayesian',
                                objective_type = 'Maximize',
                                max_jobs=30,
                                max_parallel_jobs=3,
                                early_stopping_type = 'Auto')
    
    tuning_job_name = "pt-bert-mrpc-{}".format(strftime("%d-%H-%M-%S", gmtime()))
    
    tuner.fit({'training': inputs}, job_name=tuning_job_name)
    tuner.wait()

チューニングジョブの進捗は、Amazon SageMaker コンソールでモニタリングが可能です。詳細については「ハイパーパラメータ調整ジョブの進行状況を監視する」をご参照ください。

MRPC の GLUE データセットによる自動モデルチューニングの結果

ハイパーパラメータでのチューニング結果は、さらなる分析のために、データフレームに簡単に抽出することができます。次にコードを示します。

tuner_metrics = sagemaker.HyperparameterTuningJobAnalytics(tuning_job_name).dataframe()

次のグラフでは、トレーニングジョブ全体における学習係数の進歩度合とモデルの F1 スコアの関係を、トレーニングジョブの開始時点ごとに表示しています。このベイズ最適化プロセスは、3 つの並列処理を 10 回繰り返す (合計で 30 のトレーニングジョブを行う) ように設定しています。この自動モデルチューニングでは、15 のトレーニングジョブ (繰り返し回数は 5 回) により最適な学習係数を特定しました。最終的に、その数値は 6.5e-5 近方に調整され、最大の F1 スコアが得られています。

次のグラフは、F1 スコアと学習係数の関係をプロットしたもので、モデルのハイパーパラメータに関する感受性を表しています。この結果は、BERT の uncase ベースのトレーニング済みモデルを使い、MRPC dev データセットから得られたものです。

F1 スコアは、1e-5 から 5e-4 の学習係数に対し、0.75 から 0.92 の間で大きく変化しています。また、使用した評価データセットにおいては、F1 スコアが 0.918 というピークになる所で学習係数が最良の 6.47e-5 となることも、このグラフは示しています。ほとんどのトレーニングジョブ (全 30 ジョブの内 22) は、最適な学習係数の近くで実施されており、これには、ベイズ最適化アルゴリズムの効率の良さが表れています。

SQuAD データセットによる自動モデルチューニングの結果

SQuAD 1.1 データセットに対しても、前出のものと同様の自動モデルチューニングが行えます。このデータセットは、10 万組の質問と解答のペアを不特定の対象から収集したものです。SQuAD データセットでファインチューニングを行うことは、ハイパーパラメータを別の NLP タスク用に変更しながら、 (約 5,000 組の対話を収録している) MRPC データよりも大きいデータセット用にチューニングしなおすことでもあります。詳細なコードはこちらのノートブックで入手できます。

次のグラフでは、MRPC での結果と同じ形式で、ハイパーパラメータチューニングの進捗を表しています。このトレーニングでは、セッティングをやや変更し、2 つの並列ジョブを 15 回繰り返すようにしています (合計 30 回のジョブ) 。ここでも、ベイズ最適化は、8 回のジョブの実行 (繰り返しは 4 回) 後に、素早く最適な学習係数 (5.7e-5) を特定しています。20 回目のジョブにおいてスパイクが見られますが、このチューニングジョブでは、その後すみやかに最適学習係数に収束しています。この 20 回目のジョブのスパイクは、ベイズ最適化のアルゴリズムが行ったランダム化が原因と考えられます。これは、極小/極大値での局所的な過学習を防ぐのに効果があります。

MRPC での場合と同様に、この SQuAD モデルにおいても、ハイパーパラメータに対する強い感受性が見られます。次に示す F1 vs. 学習係数のグラフでは、最適な学習係数が 5.73e-5 となる良好な放物線が描かれています。これに対応する F1 スコアは 0.884 であり、完全一致 (EM) の値は 0.812 となっています。これは、オリジナルの BERT ペーパーが SQuAD 1.1 dev データセットについて記載している、F1 = 0.885、EM = 0.808 という値とほぼ同じです。

今回のモデルチューニングでは、32 のバッチサイズと 3 つのエポックという BERT ペーパー [3] の設定ではなく、それより少ない 16 のバッチサイズと 1 つのエポックという数字を使用しました。

クリーンアップ

以降、追加料金が発生するのを防ぐためには、ノートブックインスタンスを停止し、S3 に保存されているモデルアーティファクトを削除しておきます。

まとめ

今回の記事では、Hugging Face が提供する PyTorch-Transformers ライブラリーを Amazon SageMaker で使用し、NLP モデルをファインチューニングする方法をご紹介しました。また、ハイパーパラメータ最適化によるモデルパフォーマンスの最大化に Amazon SageMaker に組み込みの自動モデルチューニングを使うことの、効率の良さもお見せしました。このアプローチにより、NLP の問題に先進的な言語モデルを導入することが容易になります。そして、Amazon SageMaker の自動モデルチューニング機能により、NLP の精度を一段と高めることができます。

参考文献:

[1] Alex Wang, Amanpreet Singh, Julian Michael, Fe-lix Hill, Omer Levy, and Samuel Bowman.“GLUE: A Multi-Task Benchmark and Analysis Platform for Natural Language Understanding.” arXiv preprint arXiv:1804.07461 (2018)

[2] Pranav Rajpurkar, Jian Zhang, Konstantin Lopyrev, and Percy Liang.“SQuAD: 100,000+ questions for machine comprehension of text.” arXiv preprint arXiv:1606.05250 (2016)

[3] Jacob Devlin, Ming-Wei Chang, Kenton Lee, Kristina Toutanova.“BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding.” arXiv preprint arXiv: 1810.04805 (2018)

 


 著者について

Jason Zhu は、AWS プロフェッショナルサービスのデータサイエンティストで、お客様が機械学習を応用する手助けをしています。余暇においての彼は、アウトドア活動や、料理人としての腕前を上げることを楽しんでいます。

 

 

 

Xiaofei Ma AWS AI ラボの応用科学者で、AWS のお客様向けに、機械学習をベースにしたサービスを開発しています。彼は、余暇には読書や旅行を楽しんでいます。

 

 

 

Kyle BrubakerAWS プロフェッショナルサービスのデータサイエンティストで、お客様が機械学習ソリューションを AWS で開発・実装するための支援をしています。彼はサッカーやサーフィンを楽しみ、新しいテレビ番組を試すのが好きです。