Skip to content

Commit

Permalink
Added experience regarding evaluation.
Browse files Browse the repository at this point in the history
  • Loading branch information
chokkan committed Jun 29, 2024
1 parent 8ff80e6 commit 66c5b0c
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
2 changes: 1 addition & 1 deletion _includes/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,5 @@
body { min-height: 75rem;}
h1 { margin: 0rem auto 1rem; }
h2 { margin: 4rem auto 1rem; }
h3 { margin: 4rem auto 1rem; }
h3 { margin: 2rem auto 1rem; }
</style>
73 changes: 73 additions & 0 deletions about.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,79 @@ tools:

{%include models.html %}

## 評価の苦労話

### 評価の実行環境が多様

Swallowプロジェクトでは、大規模言語モデルの評価のため、AI Bridging Clud Infrastructure (ABCI) のAノード(NVIDIA A100)の他、東京工業大学のTSUBAME 4.0 (NVIDIA H100)、岡崎研究室内の計算サーバ(NVIDIA RTX A6000)、横田研究室内の計算サーバ(NVIDIA ???)が使われています。まとまった大規模なGPU計算資源は大規模言語モデルの学習に割り当てることになりますので、モデルの評価は学習環境の予備ノードや、クラウド計算環境の通常利用枠、研究室内の計算資源などでやりくりをします。さらに、規模の異なる多数のモデルに対して、19~27個のタスクで評価を行いますので、評価実験は8名くらいの学生で分担しています。したがって、計算環境と評価者の掛け算で、20~30個の評価環境が使われることになります。

### (J)HumanEvalの評価にdocker環境が必要

(J)HumanEvalでは、大規模言語モデルが生成したコードを実際に実行するため、dockerを用いてサンドボックス環境を作る必要があります。ところが、ABCIはdockerに対応していないため、(J)HumanEvalの評価は別の実行環境で行う必要がありました(ABCIでは代わりにsingularityが利用できますが、今回の評価実験では採用しませんでした)。

### 実行環境によって評価スコアが変動する

乱数シードの固定など、評価の再現性を担保するための対策を講じていますが、それでも実行環境によって評価スコアが変動することを観測しています。評価スコアの有効数字3桁目以降は、再現性の担保が困難な状況にあります。

### 実行環境によってエラーが発生する

XL-Sumのタスクで、以下のエラーに遭遇することがあります。

```
File "/.../.venv_harness_jp/lib/python3.10/site-packages/transformers/models/llama/modeling_llama.py", line 1184, in forward
logits = logits.float()
RuntimeError: CUDA error: unspecified launch failure
CUDA kernel errors might be asynchronously reported at some other API call, so the stacktrace below might be incorrect.
For debugging consider passing CUDA_LAUNCH_BLOCKING=1.
Compile with `TORCH_USE_CUDA_DSA` to enable device-side assertions.
```

この問題はtransformersのversionを上げることで解決しました。

### Llama 3にはtransformers 4.40.0以降が必要

Llama 3に対応したtransformersのバージョンは4.40.0以降です。そのため、評価を行うときは、評価担当者のtransformersのバージョンが4.40.0以降になるように指定する必要がありました。また、4.39.3以前のtransformersはLlama 3のtokenizer.jsonを正しく扱えないため、学習データのトークン化もtransformersのバージョンが4.40.0以降を使う必要があり、学習データの準備のやり直しが発生しました。

### 稀に評価が途中でハングアップする

評価タスクの実行が途中で止まってしまうことがあります。正確には、特定のモデル、タスク、事例において、モデルの出力が停止し、いつまでたっても評価が終わらないという状況に遭遇することがあります。この現象は実行環境を変えると解消することがあるため、Pythonやtransformersのバージョンによる微妙な挙動の違いを疑っていますが、現段階では原因を特定できていません。

### GPUのメモリ不足によるエラー

評価したいモデルのサイズやタスクによっては、メモリ不足(out of memory)が発生することがあります。このような場合は、バッチサイズを下げる必要があり、時にはバッチサイズを1に設定することもあります。ところが、それでもメモリ不足が解消しないことがあり、そのような場合はより多くのメモリを積んだGPUの実行環境に変更するなど、対処が必要になります。

### 評価のジョブが打ち切られる

Swallowプロジェクトではたくさんの評価実験を行っていますが、自分たちが開発しているモデルのハイパーパラメータ調整の実験では、評価結果をできるだけ早く知りたい場合があります(本実験にできるだけ早く移行したいため)。逆に、他で開発されたモデルの評価は、さほど急ぐ必要がありません。このように、評価実験にも優先度があります。ところで、ABCIにジョブを投入する場合、実行時間を短く指定した方がジョブが早く実行されます。ABCIは大変混雑していますので、評価実験を行う担当者は、各タスクの評価実験にかかる実行時間を予測し、ジョブの投入時に経過時間制限値を設定します。ところが、何らかの要因で評価タスクの実行時間が長くなってしまうと、無慈悲にも設定した経過時間でジョブの実行が打ち切られ、評価実験が未完了となります。

### MT-Benchの評価でOpenAIのAPIを呼び出すときにRateLimitErrorが発生した

MT-Benchの評価では、GPT-4のAPIを呼び出す必要があります。MT-Benchの評価を並列で実行すると、OpenAI APIのRateLimitErrorが高頻度で発生し、retry回数の上限を超えてしまい正しく評価が行えないことがありました。FastChatの実装では、retry回数の上限を超えた際はエラーを出すのではなくスコアを-1として記録するため、最終結果のスコアを見るだけでは気づきにくい状況にありました。最終的にはretryの処理を工夫することで、この問題に対処しました。

### 一部のモデルの評価が正しく行えない

他で開発されたモデルを評価しているとき、過去に自分たちで実施した評価や外部のリーダーボードの評価を大幅に下回るスコアに出くわすことがありました。このようなことが複数のモデルにおいて発生するうえ、その現象を引き起こし得る原因がいくつも考えられる(先ほどのtransformersのバージョンによる動作の違い、評価ソフトウェアのバージョンアップに伴うプロンプトの違い等)ため、評価スコア低下の原因を特定し、デバッグをするのは困難です。そこで、モデルの評価で問題が発生した場合は、Swallowプロジェクトで開発しているモデルと規模や性能で競合する場合だけ原因を特定し修正することにし、競合しないと思われるモデルの評価は優先順位を下げ、場合によっては断念しました。

### 確率的デコーディングが意図せずに使われていた

2024年度のSwallowプロジェクトで採用している評価フレームワークで初代Swallowモデルの評価をやり直したとき、いくつかのタスクで以前の評価スコアよりも10ポイントくらい低いスコアが出ることがありました。これは、論文やウェブサイト等で報告していたスコアが間違っている可能性を示唆していますので、我々にとって深刻な問題です。結局、この現象は評価ソフトウェアのバージョンアップに伴う仕様変更によるもので、自分たちの評価のミスではありませんでした。

大規模言語モデルで出力を予測するときは、出力単語の確率分布を計算して、確率の高い単語を選びます。このとき、最も高い確率が計算された単語を出力するのが基本ですが、出力の多様性を高めるため、大規模言語モデルの応用では確率分布に従って単語をサンプリングする手法(確率的デコーディング)が用いられます。ところが、確率的デコーディングを多値選択式質問応答の回答生成に使ってしまうと、(よくデキるモデルでは)正解率が下がります。例えば、「はい」「いいえ」の2択問題を解いているとき、言語モデルが「はい」の確率を80%、「いいえ」の確率を20%と予測した状況を考えましょう。「はい」という答えに比較的自信を持っているようですので、「はい」と答えるのが合理的ですが、確率的デコーディングでは20%の確率で「いいえ」と答えることになります。つまり、回答にある程度自信を持っていたとしても、それとは異なる回答をわざと行うことになります。

出力単語の確率分布の形状は温度パラメータによって変わりますし、大規模言語モデルによっては推奨される温度パラメータが設定ファイルで指定されていることがあります。評価スコアを安定させるためには、(翻訳や要約などの生成系のタスクを除き)多値選択式のタスクでは確率的デコーディングを使わず、貪欲的デコーディング(最も高い確率が計算された単語を出力すること)を採用することが望ましいです。そのため、大規模言語モデルの評価ソフトウェアでは、しばしば貪欲デコーディングを大規模言語モデルに強制することがありますが、バージョンアップに伴い、その強制が脱落していることがあります。我々が経験したケースでは、llm-jp-evalのv1.0.0では温度パラメータとして0.1が強制されていたため、貪欲デコーディングに近い状態になっていましたが、v1.3.0でその強制が撤廃されたため、モデルのデフォルト設定により確率的デコーディングが使われ、特定のタスクの評価スコアが低下しました。この問題のため、日本語の理解・生成タスクで評価のやり直しが発生しました。

### (J)HumanEvalではプロンプトの末尾に改行が必要だった

Swallowプロジェクトでは2024年度からコード生成タスクをモデルの評価に採用しました。これは、コード生成タスクが大規模言語モデルの論理的思考力を鍛えると期待していることに加え、初代Swallowがコード生成タスクに弱かったことが理由です。

ところが、Llama 3 Swallowの開発を進める中で、JHumanEvalやHumanEvalの評価スコアは8Bのモデルよりも70Bのモデルの方が悪いことに気づきました。Llama 3をHumanEvalで評価してみると、pass@1が0.28 (8B) および0.16 (70B) となり、8Bのモデルよりも70Bのモデルが苦戦しています。この問題を調査していくと、プロンプトの末尾が`"""\n`で終わるならコードが生成されますが、`"""`で終わる場合は`[EOS]`が生成され、コードが生成されない傾向があることが分かりました(三重引用符`"""`はPythonのドキュメンテーション文字列の開始と終了を表すことが多く、コード生成の指示やテストケースの末尾によく出現します)。さらに細かく調べていくと、Llama 3は`"""`, `[SPC]"""`, `[SPC]"""\n`, `[SPC]"""\n\n`をそれぞれ、一つのトークンとして扱うようで、これらを別物として扱うことに原因があるのかもしれません。

HumanEval, JHumanEvalの元々のデータでは、コード生成の指示の末尾に改行が付加されています。ところが、Code Generation LM Evaluation Harnessの[実装](https://github.com/bigcode-project/bigcode-evaluation-harness/blob/main/bigcode_eval/tasks/humaneval.py#L64)において、データの末尾の空白文字を除去することがあります。正確には、末尾の空白文字を除去する処理がデフォルトで、`strip_prompt=False`を指定することでその処理を回避できます。先に説明した通り、この問題はモデルのトークン化の影響によるものと考えられますので、モデルによっては`strip_prompt=False`を指定しなくてもコードが生成されます。ところが、モデルの評価では実験条件をそろえるのが望ましいですので、(J)HumanEvalの評価を途中でやり直しました。

### 生成の冒頭に改行を出力するモデルがある

Sarashina 7Bと13Bをllm-jp-evalで評価しているとき、特定のタスクで評価スコアが0点になることに気づきました。これは、Sarashinaのモデルが生成の冒頭に改行文字`\n`を出力してしまうことが原因で、JMMLUのように出力の完全一致で評価するタスクでは致命的です。Swallowプロジェクトの評価実験では、Sarashinaの出力に対して空白文字の除去を行い処理を追加し、評価を行っています。

## 謝辞

このウェブサイトは、以下のソフトウェアを用いて構築されました。
Expand Down

0 comments on commit 66c5b0c

Please sign in to comment.