少し前に、ChatGPTなどの強力な大規模言語モデル(LLM)ベースの生成AIサービスが「9.11と9.9はどちらが大きいですか?」といった非常にシンプルな問題に引っかかったことが話題になりました。ネット上では「試してみた、本当に間違った」といった議論が多く見られましたが、それだけにとどめておくのはもったいないと感じたので、私なりに少し深掘りして考えてみました。
TL;DR
強力な主流生成AIサービスでも、簡単な数値比較や計算問題を間違えることがある。- これはトークナイゼーションの一部解釈から理解できる部分もあるが、本質的な原因ではない。LLMはそもそも数値計算を理解していなく、数値計算をしているのではなく、過去の学習データからそれらしい回答を思い出そうとしているだけと考えられる。正確な数値計算を行う場合、LLMに任せるのではなく、生成AIサービスにプログラムを書かせるのが良い。- プロンプトはシンプルに、「プログラムを実行して回答してください」と指示するだけで十分。生成AIをより有効に活用するためには、 「生成AIは何が得意で何が苦手なのか」 を理解し、 「道具として適切に使いこなす」 という姿勢が重要。
問題探索
今回の実験では、複数の主流生成AIサービスを同時に比較できる「天秤AI byGMO」サービス[1]を利用し、その上で提供されている以下の4つのLLMを対象に実験を行いました。(なお、天秤AIサービスはAPI経由での利用となるため、公式のチャットUIとは挙動が若干異なる場合があることをご注意ください)
GPT-4oClaude 3.5 SonnetGemini 1.5 ProLlama3 70b Instruct
LLMの生成結果にはランダム性があるため、以下全ての実験は5回程度繰り返して回しました。
9.11と9.9の比較
ではまずは、話題の「9.11」と「9.9」の大小を質問してみました。
入力文書 :「9.11と9.9の大小を比較して」正解(例):「9.11<9.9」
結果は以下のように分かれました(図1):
Gemini 1.5 Pro: 基本的に毎回正解GPT-4o, Claude 3.5 Sonnet: たまに正解するが、基本的には「9.11」の方が大きいと誤答Llama3 70b Instruct: 安定して毎回誤答
図1 「天秤AI byGMO」チャット画面、質問「9.11と9.9の大小を比較して」および各LLMの回答例構図(以降同様)左上:GPT-4o右上:Claude 3.5 Sonnet左下:Gemini 1.5 Pro右下:Llama3 70b Instruct
この結果だけを見ると、Gemini 1.5 Proが一番優れていると思われるかもしれませんが、結論を出すのはまだ早いです。
質問を少し変えてみましょう:
入力文書 :「5.11と5.9の大小を比較して」正解(例):「5.11<5.9」
たった小数点前の9を5に変わるだけで、全てのLLMが不正解となりました(図2)。
図2 「天秤AI byGMO」チャット画面、質問「5.11と5.9の大小を比較して」および各LLMの回答例
なぜLLMはこんなにも単純な問題で間違ってしまうのかを探るために、とりあえず言い分を聞いてみました。LLMは自身の思考プロセスを完全に説明できるわけではありませんが、彼らの「言い訳」から、その特性や限界を垣間見ることができるかもしれません。
ここでは、長文にならないよう「理由を簡潔に教えて」と指示します(図3)。
図3 天秤AI by GMO チャット画面、各LLMが質問「5.11と5.9の大小を比較して」の回答についての理由説明
全てのモデルが、小数点以下の「11」が「9」より大きいと誤って認識していることがわかります。つまり、LLMが小数点以下の桁数を正しく認識できていない可能性が高いですね。
そこで、桁数を揃えてあげれば、正しく判断できるのではないかと自然に考え思い浮かびますね。そのため、次のような質問もしてみました:
入力文書 :「5.11と5.90の大小を比較して」正解(例):「5.11<5.90」
想定通り、今度はすべてのモデルが安定して「5.90が大きい」と答えてくれました(図4)。有効桁数を揃えることの重要性がよくわかりますね。
図4 天秤AI by GMO チャット画面、質問「5.11と5.9の大小を比較して」および各LLMの回答例
「strawberry」の「r」の数
次に、最近もう一つ話題となった問題「strawberry」の「r」の数について見てみましょう。
入力文書 :「strawberryのrの数を数えて」正解(例):「3」
前と似たような結果が出ています(図5):
Gemini 1.5 Pro: 基本的に毎回正解GPT-4o, Claude 3.5 Sonnet: たまに正解するが、基本的には「2」と誤答Llama3 70b Instruct: 安定して毎回「2」と誤答
図5 天秤AI by GMO チャット画面、質問「strawberryのrの数を数えて」および各LLMの回答例
この結果を見ると、やはりGemini 1.5 Proが一番良いと思ってしまいますよね。しかし、今回も結論を出すにはまだ早いです。
先ほどと同様に、「理由を簡潔に教えて」を追加して理由を聞いてみましょう(図6)。
図6 天秤AI by GMO チャット画面、各LLMが質問「strawberryのrの数を数えて」の回答についての理由説明
結果、Gemini 1.5 Proも含めて、すべてのモデルが「berry」の「r」を1つだけと誤認識していることがわかります。Gemini 1.5 Proは、「aw」の後に存在しない「r」をカウントして、たまたま正解を出しているようですね。
長い数字の0数
実は、似たような問題として、1年前にChatGPTが長い数字の0の数を間違えることがすでに指摘されていました[2]。
例として、このような質問をしてみます:
入力文書 :「100000000000000000000000000000000には0がいくつ並んでいますか?」正解(例):「32」
質問を複数回繰り返すと、Llama3 70b Instruct以外のモデルは時として正しい回答を返すこともありますが、、基本的には回答の一貫性がなく、誤答が多いです(図7)。
図7 天秤AI by GMO チャット画面、質問「100000000000000000000000000000000には0がいくつ並んでいますか?」および各LLMの回答例
原因探索
トークナイゼーション
以上の結果から、LLMが文字列(特に数字列)の数を数えるのが苦手であることがわかります。その原因として真っ先に考えられるのが、トークナイゼーションの影響です。
トークナイゼーションとは、テキストを「トークン(Token)」と呼ばれる意味を持つ最小単位に分割する処理のことを指します。そして、このトークナイゼーションを行うモデルを「トークナイザー(Tokenizer)」と呼びます[3]。LLMは、このトークン単位でテキストを処理し、ベクトル表現に変換します。そのため、APIの課金もトークン単位で計算されることが多いのです。
トークナイゼーションは、一般的に隣り合う文字の出現頻度に基づいてトークンの境界を決定します。しかし、この仕組みが数字列のカウントにおいて、LLMに混乱を引き起こしている可能性があります。
Hugging Face上で公開されているCognitiveLabの「Tokenizer Arena」[4]を利用すると、複数の主要なLLMのトークナイザーを同時に比較することができます。このツールを利用して、各モデルがどのようにトークンを分割しているかを具体的に確認してみましょう。
先ほどの質問文のトークンを確認したところ、以下のようになっていました(図8)。
図8 Tokenizer Arena画面、各トクナイザーによる質問文のトークン分割の可視化構図は天秤AI by GMOのチャット画面に逐一対応(以降同様)左上:GPT-4o Tokenizer右上:Claude Tokenizer※1左下:Gemma Tokenizer※2右下:Llama3 Tokenizer
1. Claude 3.5のトークナイザーは公開されていないため、ここではClaude 3のトークナイザーを利用しています。ただし、変更点は非常に少ないと想定されます。2. Geminiのトークナイザーは公開されていないため、ここではGemmaのトークナイザーを利用しています。GemmaはGeminiと同じ技術で構築された軽量オープンモデルであり、両者は非常に似ていると考えられます。
数値の分割結果:
Gemini(Gemma、以下省略)は、他のモデルと異なり、数字一桁を一つのトークンとして認識Gemini以外は、小数点以下の2桁数値「11」「90」を一つのトークンとして認識GPT-4o、Llama3は、3桁ごとに長い数値を区切るClaudeは、他のモデルよりもさらに長い数値を一トークンとして認識
「strawberry」の分割結果:
Gemini以外のトークナイザーは、「strawberry」を3つのトークンに分割Geminiは「strawberry」を一つのトークンとして認識
Gemini以外の結果から、トークナイゼーションの影響が明らかです。
LLMの視点から見るとこうなります:
「5.11」と「5.9」の比較 =「⚪︎×□」と「⚪︎×△」の比較(且つ一般常識として「□」>「△」)「strawberry」の「r」の数=「◇▽◎」の中の「r」の数「100000000000000000000000000000000」の「0」の数=「▲◾️◾️◾️◾️◾️◾️◾️◾️◾️◾️」の中の「0」の数
それは、わかるわけないですね。
しかし、Geminiは他のトークナイザーとは異なり、少なくとも数字については1桁ずつを1つのトークンとして認識しています。もしトークナイゼーションだけが原因であれば、Geminiは適切に回答できるはずです。実際、上の質問に対するGeminiの回答は僅かに良く見える1ものの、正解からはまだ程遠い状況です。
LLMは数値計算を理解していない
ここで着目したいのは、「なぜGPT-4o、Llama3のトークナイザーは、3桁ごとに長い数値を区切るか」という点です。
先ほど書いたように、一般的にトークンの境界は「隣り合う文字の出現頻度」に基づいて決定されます。つまり、3桁以内の数値の出現頻度は4桁以上の数値に比べて明らかに高く、このことから3桁目が境界として選ばれたと考えられます。
ここで思い出されるのは、一年前にChatGPTが登場した初期から、LLM(大規模言語モデル)は4桁以上の掛け算が間違いやすいという指摘があったことです[2][5]。
度重なるアップデートを経た現在も、この問題は解決されてないようです(図9):
入力文書 :「1204*1402」正解(例):「1688008」
図9 天秤AI by GMO チャット画面、質問「1204*1402」および各LLMの回答例
結果、Claude 3.5 Sonnet以外のモデルは、ほぼ毎回見た目が似ている異なる答えを出します。一方、Claude 3.5 Sonnetは自動的にステップバイステップで計算を行う2ため、常に正しい答えを導き出すことができます。
さらに、「1204*1402=1687408」とあえて間違った(かつLLMの誤答とも異なる)答えを教えて訂正してみます(図10)。
図10 天秤AI by GMO チャット画面、訂正文「1204*1402=1687408」および各LLMの回答例
GPT-4o、Claude 3.5 Sonnet(元々正解していたにも関わらず)、Llama3 70b Instructは私が出した間違った答えをすんなり受け入れました。一方、Gemini 1.5 Proは自信満々に先ほど自分が出した誤答を言い張っていました。めちゃくちゃですね。
以上の結果を一般化してまとめると、LLMは以下のような傾向があります:
毎回異なる答えを出すただし、誤答の数値は、一見正しそうに見える間違った回答を教えても、疑わずに受け入れる
私は、LLM は数値計算をしているのではなく、過去の学習データからそれらしい回答を思い出そうとしているだけなのではないかと考えられます。
厳密に証明することは難しいですが、これまで見られた現象と辻褄が合っているように思います:
3桁以下の数値計算の精度が高い→ 学習データ中に多く見かけるため、暗記できている小数点以下の桁数が異なる数値の比較や、超長い数値から「0」を数えるのが苦手→ そもそも学習データにそのようなタスクが含まれていないため、適切な対応ができない4桁以上の掛け算の結果が、正しそうに見えても実際には正しくない→ 学習データにそのような数式は含まれていないが、近い形式の数式を見たことがあるため、それを元に近似して回答を生成しているステップバイステップで計算すると精度が上がる→ 学習データに見たことのない複雑な数式も、出現頻度の高い簡単な数式に変換することで、暗記された内容がより正確に再現される
一例として、6桁の掛け算をさせてみます:
入力文書 :「890625 * 890625」正解(例):「793212890625」
今度はGPT-4o、Gemini 1.5 Pro、さらにLlama3 70b Instructまで一発で正解を出せました。Claude 3.5 Sonnetは頑張ってステップバイステップで計算した結果、かえって間違ってしまいました(図11)。
図11 天秤AI by GMO チャット画面、質問「890625 * 890625」および各LLMの回答例
なぜそうなるのか?それは「890625」は「自己同形数」であり、「8906252 = 793212890625」という有名な式がWikipedia[6]にも載っているためです。この情報がすでにLLMに学習されている可能性が非常に高いと考えられます。
LLMの学習ロジックは本質的に「次のトークンの予測(next-token prediction)」3に基づいており、これは「言語の法則」を使って予測しているに過ぎず、「数学的思考」とは根本的に異なります。
つまり、名著をたくさん暗記することで文章作成能力は向上しますが、数式をいくら暗記しても計算能力が向上するわけではないのです。
改善策
「LLMが簡単な数値問題を解けない」ことを指摘するだけが目的ではありません。適切な方法を見出し、正しい回答を導き出すことができるようになるのも重要です。
ステップバイステップ思考
多くの方になじみのある「ステップバイステップ思考」は、確かに一つ有効な手法です。実際に、Claude 3.5 Sonnetはデフォルトで掛け算の計算をステップバイステップで行おうとしています。
しかし、数値計算においてステップバイステップ思考は精度を大幅に向上させるものの、100%正解を出せるわけではありません(図12)。
図12 ステップバイステップで「strawberry」に含まれる「r」の数を数える過程の一例:1回目は正解だったが、2回目は誤りとなった場合
プログラムを実行して回答
LLMは、曖昧な表現も理解できる点が強みです。しかし、裏を返せば、正確性を追求することに向いてないです。LLMに100%の正確性を求めるのは木に縁りて魚を求むようなことです。正確性が求められる数値計算などは、生成AIのLLMに任せるのではなく、プログラムを使いましょう。これは、暗算が苦手な人が電卓を使うのと同じことです。
シンプルに、「プログラムを実行して回答してください」と指示するだけで良いのです。
ちなみに、ここでは「書いて」ではなく「実行して」と明確に伝える必要があります。そうしないと、コードを書いただけで回答が間違ったままになることがあります。
天秤AIはAPIを利用しているだけなのでプログラムを自動で実行することはできませんが、各生成AIサービスのUIでは実行可能です。
以下はChatGPTの例です(図13 - 15)。
図13 ChatGPT チャット画面、質問「プログラムを実行して回答してください 9.11と9.9の大小を比較して」およびプログラム表示回答
図14 ChatGPT チャット画面、質問「プログラムを実行して回答してください strawberryのrの数を数えて」およびプログラム表示回答
図15 ChatGPT チャット画面、質問「プログラムを実行して回答してください 100000000000000000000000000000000には0がいくつ並んでいますか?」およびプログラム表示回答
実際、現在のChatGPTに掛け算の問題を出すと、デフォルトでは裏でプログラムを動かして回答しています(図16)。ネット上ではたまに「LLMの計算能力が向上した」といった記事を見かけますが、それは当然のことですね。
図16 ChatGPT チャット画面、質問「1204*1402」およびプログラム表示回答
おわりに
OpenAI, Anthropic, Google, Metaといった企業の努力によって、LLMを含む生成AIは格段に使いやすく、私たちの生活に浸透しつつあります。しかし、「生成AIは万能である」という誤解は避けなければなりません。
現状の生成AIはあくまでも確率に基づいてそれらしい文章や画像を生成しているに過ぎず、その出力の正確性や倫理性については常に注意が必要です。
生成AIをより有効に活用するためには、 「生成AIは何が得意で何が苦手なのか」 を理解し、 「道具として適切に使いこなす」 という姿勢が重要になってくるでしょう。
素晴らしいことに、私がこの章の一段落目の文書をLLMに修正させた際に、Gemini 1.5 Proが自動的に最後の二段落の文書(太字付き)を追加してくれました。何も手を加えず、そのままここに掲載したいと思います。
参考資料
GMO教えてAI. "天秤AI byGMO". 天秤AI byGMO. https://tenbin.ai. (2024-08-06アクセス) 湊 真一. "ChatGPTはなぜ計算が苦手なのか". 国立情報学研究所. https://www.nii.ac.jp/event/upload/20230707-03_Minato.pdf. (2024-08-06アクセス) データアナリティクスラボ. "日本語LLMにおけるトークナイザーの重要性". Journal | データアナリティクスラボ. https://dalab.jp/archives/journal/japanese-llm-tokenizer/#i-4. (2024-08-06アクセス) Cognitive-Lab. "Tokenizer Arena". Hugging Face. https://huggingface.co/spaces/Cognitive-Lab/Tokenizer_Arena. (2024-08-06アクセス) tueda. "掛け算のできないChatGPT". Qiita. https://qiita.com/tueda/items/c04799a1eb8a2e46b9f6#fn-1. (2024-08-07アクセス) "自己同形数". ウィキペディア (Wikipedia): フリー百科事典. https://ja.wikipedia.org/wiki/%E8%87%AA%E5%B7%B1%E5%90%8C%E5%BD%A2%E6%95%B0. (2024-08-07アクセス)