LLMが混乱してしまう原因
トークナイゼーションの仕組みを知ると「LLMにわかるわけがない」ことがわかる
先ほどの3つの実験から、LLMが文字列(特に数字列)の数を数えるのが苦手であることがわかります。その原因として真っ先に考えられるのが「トークナイゼーション」の影響です。
トークナイゼーションとは、LLMがテキストを分析するために、テキストを「トークン(Token)」と呼ばれる、意味を持つ最小単位に分割する処理のことを指します。
そしてトークナイゼーションを行うモデルを「トークナイザー(Tokenizer)」と呼びます。LLMはトークナイザーです。トークン単位でテキストを処理し、ベクトル表現に変換します。そのため、各AIサービスのAPIの利用料金はトークン単位で計算されることが多いのです。
トークナイゼーションは、一般的に隣り合う文字の出現頻度に基づいてトークンの境界を決定します。しかし数字列のカウントでは、この境界の仕組みがLLMを混乱させている可能性があります。
Hugging Face上で公開されているCognitiveLabのツール「Tokenizer Arena」を利用すると、複数の主要なLLMのトークナイザーを同時に比較できます。このツールを利用して、各モデルがどのようにトークンを分割しているかを具体的に見ていきましょう。
先ほどの質問文「5.11と5.9の大小を比較して」のトークンを確認したところ、次のようになっていました。
トークナイゼーションとは、LLMがテキストを分析するために、テキストを「トークン(Token)」と呼ばれる、意味を持つ最小単位に分割する処理のことを指します。
そしてトークナイゼーションを行うモデルを「トークナイザー(Tokenizer)」と呼びます。LLMはトークナイザーです。トークン単位でテキストを処理し、ベクトル表現に変換します。そのため、各AIサービスのAPIの利用料金はトークン単位で計算されることが多いのです。
トークナイゼーションは、一般的に隣り合う文字の出現頻度に基づいてトークンの境界を決定します。しかし数字列のカウントでは、この境界の仕組みがLLMを混乱させている可能性があります。
Hugging Face上で公開されているCognitiveLabのツール「Tokenizer Arena」を利用すると、複数の主要なLLMのトークナイザーを同時に比較できます。このツールを利用して、各モデルがどのようにトークンを分割しているかを具体的に見ていきましょう。
先ほどの質問文「5.11と5.9の大小を比較して」のトークンを確認したところ、次のようになっていました。
Tokenizer Arenaを使って各トークナイザーによる質問文のトークン分割を可視化した。左上から時計回りで「GPT-4o Tokenizer」「Claude Tokenizer」「Gemma Tokenizer」「Llama3 Tokenizer」
ちなみにClaude 3.5のトークナイザーは現在公開されていないため、代わりに「Claude 3」のトークナイザーを利用しました。Claude 3.5とClaude 3の変更点は非常に少ないと想定されます。
そしてGeminiのトークナイザーも現在公開されていないため「Gemma」のトークナイザーを利用しました。GemmaはGeminiと同じ技術で構築された軽量オープンモデルで、両者は非常に似ていると考えられます。
そしてGeminiのトークナイザーも現在公開されていないため「Gemma」のトークナイザーを利用しました。GemmaはGeminiと同じ技術で構築された軽量オープンモデルで、両者は非常に似ていると考えられます。
各LLMは数値をどうトークナイゼーションしている?
Gemini(Gemma)は、他のモデルと異なり、数字1桁を1つのトークンとして認識しています。そしてGemini以外は、小数点以下の2桁数値「11」「90」を1つのトークンとして認識しています。GPT-4o、Llama3は、3桁ごとに長い数値を区切り、Claudeは、他のモデルよりもさらに長い数値を1トークンとして認識しています。
「strawberry」のトークナイゼーションにも違いがある
Gemini以外のトークナイザーは「strawberry」を3つのトークンに分割し、Geminiは「strawberry」を1つのトークンとして認識しています。Gemini以外の結果を見ると、トークナイゼーションがLLMの回答に影響を与えていることは明らかです。
LLMの視点からは「簡単な問題」はこう見えていたのです。
「5.11」と「5.9」の比較
=「⚪︎×□」と「⚪︎×△」の比較(かつ、一般常識として「□」は「△」より大きい)
「strawberry」の「r」の数
=「◇▽◎」の中の「r」の数
「100000000000000000000000000000000」の「0」の数
=「▲■■■■■■■■■■」の中の「0」の数
これでは、わかるわけがないですね。
しかしGeminiは他のトークナイザーとは異なり、少なくとも数字については1桁ずつを1つのトークンとして認識しています。もしトークナイゼーションだけが原因であれば、Geminiは適切に回答できるはずです。実際、上の質問に対するGeminiの回答はわずかに良く見えます。それでも正解からはまだ程遠い状況なのは、なぜなのでしょうか。もう少し深掘りして考えてみます。
LLMは数値計算を理解していない
ここで「なぜGPT-4o・Llama3のトークナイザーは、3桁ごとに長い数値を区切るのか」という点に着目してみましょう。
先ほど書いたように、一般的にトークンの境界は「隣り合う文字の出現頻度」に基づいて決定されます。つまり3桁以内の数値の出現頻度は、4桁以上の数値に比べて明らかに高く、このことから3桁目が境界として選ばれたと考えられます。
ここで思い出されるのは、ChatGPTが登場した2022年頃から、LLMは4桁以上の掛け算を誤りやすいという指摘があったことです。
度重なるアップデートを経た2024年時点でも、LLMがかけ算を間違えてしまう問題は解決されてないようです。
先ほど書いたように、一般的にトークンの境界は「隣り合う文字の出現頻度」に基づいて決定されます。つまり3桁以内の数値の出現頻度は、4桁以上の数値に比べて明らかに高く、このことから3桁目が境界として選ばれたと考えられます。
ここで思い出されるのは、ChatGPTが登場した2022年頃から、LLMは4桁以上の掛け算を誤りやすいという指摘があったことです。
度重なるアップデートを経た2024年時点でも、LLMがかけ算を間違えてしまう問題は解決されてないようです。
天秤AIチャット画面、質問「1204*1402」と各LLMの回答例
Claude 3.5 Sonnet以外のモデルは、ほぼ毎回、似たような不正解を出します。
一方、Claude 3.5 Sonnetはステップ・バイ・ステップで計算するため、常に正しい答えを導き出します。これは、Claudeを開発したAnthropicが、ステップ・バイ・ステップの計算方法を、かなりがんばって適切にチューニングしたためと考えられます。しかし残念ながら、桁数が増えると途中の計算で間違えてしまうケースも見られます。
もう1つ実験をしてみましょう。「1204*1402=1687408」という、あえて正しくない(かつLLMの誤答とも異なる)答えを教えて訂正すると、どうなるでしょうか。
一方、Claude 3.5 Sonnetはステップ・バイ・ステップで計算するため、常に正しい答えを導き出します。これは、Claudeを開発したAnthropicが、ステップ・バイ・ステップの計算方法を、かなりがんばって適切にチューニングしたためと考えられます。しかし残念ながら、桁数が増えると途中の計算で間違えてしまうケースも見られます。
もう1つ実験をしてみましょう。「1204*1402=1687408」という、あえて正しくない(かつLLMの誤答とも異なる)答えを教えて訂正すると、どうなるでしょうか。
天秤AIチャット画面、訂正文「1204*1402=1687408」と各LLMの回答例
GPT-4o・Claude 3.5 Sonnet(元々正解していたにも関わらず)・Llama3 70b Instructは、私が教えた間違った答えをすんなり受け入れました。一方、Gemini 1.5 Proは自信満々に先ほど自分が出した誤答を言い張っていました。めちゃくちゃですね。
以上の結果を一般化してまとめると、LLMには次のような傾向があるといえます。
・LLMは、毎回異なる答えを出す
・ただし、LLMの誤答の数値は、一見すると正しそうに見える
・LLMは、間違った解答を教えても、疑わずに受け入れることが多い
こうした傾向から、私は、LLMは数値計算をしているのではなく、過去の学習データからそれらしい回答を思い出そうとしているだけなのではないかと考えています。この私の説を厳密に証明することは難しいですが、これまでに見られたLLMの現象とつじつまが合っているように思います。
・3桁以下の数値計算の精度が高い
→ 学習データの中で3桁以下の計算を多く見かけるため、LLMは計算を暗記できている
・小数点以下の桁数が異なる数値の比較や、「100000000000000000000000000000000」のようなとても長い数値から「0」を数えるのが苦手
→ そもそも学習データにそのようなタスクが含まれていないため、適切な対応ができない
・4桁以上の掛け算の結果が、正しそうに見えても実際には正しくない
→ 学習データにそのような数式は含まれていないが、近い形式の数式を見たことがあるため、それを元に似た回答を生成している
・ステップ・バイ・ステップで計算すると精度が上がる
→ 学習データで見たことのない複雑な数式も、出現頻度の高い簡単な数式に変換することで、暗記された内容がより正確に再現される
LLMが答えを暗記している一例として、次の6桁の掛け算をさせてみましょう。
以上の結果を一般化してまとめると、LLMには次のような傾向があるといえます。
・LLMは、毎回異なる答えを出す
・ただし、LLMの誤答の数値は、一見すると正しそうに見える
・LLMは、間違った解答を教えても、疑わずに受け入れることが多い
こうした傾向から、私は、LLMは数値計算をしているのではなく、過去の学習データからそれらしい回答を思い出そうとしているだけなのではないかと考えています。この私の説を厳密に証明することは難しいですが、これまでに見られたLLMの現象とつじつまが合っているように思います。
・3桁以下の数値計算の精度が高い
→ 学習データの中で3桁以下の計算を多く見かけるため、LLMは計算を暗記できている
・小数点以下の桁数が異なる数値の比較や、「100000000000000000000000000000000」のようなとても長い数値から「0」を数えるのが苦手
→ そもそも学習データにそのようなタスクが含まれていないため、適切な対応ができない
・4桁以上の掛け算の結果が、正しそうに見えても実際には正しくない
→ 学習データにそのような数式は含まれていないが、近い形式の数式を見たことがあるため、それを元に似た回答を生成している
・ステップ・バイ・ステップで計算すると精度が上がる
→ 学習データで見たことのない複雑な数式も、出現頻度の高い簡単な数式に変換することで、暗記された内容がより正確に再現される
LLMが答えを暗記している一例として、次の6桁の掛け算をさせてみましょう。
今度はGPT-4o・Gemini 1.5 Pro・さらにLlama3 70b Instructまでが、一発で正解を出せました。Claude 3.5 Sonnetはステップ・バイ・ステップでがんばって計算した結果、かえって間違ってしまいました。
天秤AIチャット画面、質問「890625 * 890625」と各LLMの回答例
なぜ6桁の計算ができるのでしょうか?
それは「890625」は「自己同形数(2乗したとき、下桁の数が自分自身と同じになる数)」であり、「890625の2乗 = 793212890625」という有名な式がWikipediaにも載っているためです。この情報がすでにLLMに学習されている可能性が非常に高いと考えられます。
LLMの学習ロジックは基本的に「次のトークンの予測(next-token prediction)」に基づいており、これは「言語の法則」を使って予測しているに過ぎず、「数学的思考」とは根本的に異なります。
つまり、名著をたくさん暗記することで文章作成能力は向上するとしても、数式をいくら暗記しても計算能力が向上するわけではないのです。
それは「890625」は「自己同形数(2乗したとき、下桁の数が自分自身と同じになる数)」であり、「890625の2乗 = 793212890625」という有名な式がWikipediaにも載っているためです。この情報がすでにLLMに学習されている可能性が非常に高いと考えられます。
LLMの学習ロジックは基本的に「次のトークンの予測(next-token prediction)」に基づいており、これは「言語の法則」を使って予測しているに過ぎず、「数学的思考」とは根本的に異なります。
つまり、名著をたくさん暗記することで文章作成能力は向上するとしても、数式をいくら暗記しても計算能力が向上するわけではないのです。
杜 博見
【GMOインターネットグループ デベロッパーエキスパート / GMOインターネットグループ グループ研究開発本部AI研究開発室データ解析・AI研究グループ 所属】
2023年 GMOインターネットグループ株式会社 新卒入社。博士。グループ横断のプロジェクトでAI技術を用いた解析支援・開発に携わっている。