掛け算のできないChatGPT

[ChatGPT](https://openai.com/blog/chatgpt/)って凄いですよね。何が凄いかって、AIのくせに平然と嘘をつくところだと人間の私は思っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43042/05f85326-58b5-b121-0a99-08cd4508c308.png)

皆さんご存じの通り、この掛け算の答えは67番目の[メルセンヌ数](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%AB%E3%82%BB%E3%83%B3%E3%83%8C%E6%95%B0)である[147,573,952,589,676,412,927](https://www.wolframalpha.com/input?i=193707721*761838257287)です。ちなみに、ChatGPTの答えは聞くたび毎回変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43042/f069bbdc-73f4-084a-6b46-ec8939d1fd5b.png)

自分の答えの間違いを認めるという、嘘の中に真実を混ぜ込む詐欺師のテクニックを使用してきますが、やはり嘘です。大ぼら吹きです。そもそも桁数すら合ってないやん。

そこで次のような疑問が浮かびます。**ChatGPTは何桁の掛け算までならできるのでしょう？**

ここでは問題を単純化して、次のように考えたいと思います。
- $a_n = 10^n - 1$とする。つまり、$a_n$は10進$n$桁の正の整数のうち最大のものである（たとえば、$a_1 = 9$、$a_2 = 99$、$a_3 = 999$）。
- ChatGPTに$a_n \times a_n$の掛け算を100回行わせる。正答率が50%以上であれば、$n$桁の掛け算はできると判定する。

というわけで、Pythonでこの手順をさっくりと適当に書いてみましょう。その前に諸注意です。
- [ChatGPTを使ったアプリ(サービス)、ChatGPTじゃない説](https://qiita.com/Tyamamoto1007/items/464e142c2d88d314ab6c)にあるように、正確にはChatGPTじゃなくてOpenAIのAPIを使っています。
- AIには改良が加えられ続けています。コードと結果はあくまでも執筆当時（2023年2月5日）のものです。
- [ChatGPTの数学的な能力が向上したというのでテストしてみた](https://note.com/it_navi/n/n4babc23f1714)では、掛け算以外にもいろいろと試されています。

コードは以下のようになります。[Google Colabotatory](https://colab.research.google.com/)では
```
%env OPENAI_API_KEY=sk-1UiX****************************************YZ3Y
!pip install openai
```
のように、OpenAIのAPIキーの指定とライブラリのインストールが必要です。

```python
import openai
import time
import matplotlib.pyplot as plt


def check(n):
    """Check if the AI answers an n-digit multiplication correctly."""
    x = 10**n - 1
    y = x
    prompt = (
        f"Compute {x} multiplied by {y}. "
        "Output the answer using only decimal letters from 0 to 9. "
        "Don't output any other characters, e.g., decimal separators."
    )
    while True:
        try:
            response = openai.Completion.create(
                model="text-davinci-003",
                prompt=prompt,
            )
            return int(response.choices[0].text) == x * y
        except Exception as e:
            # Rarely, ServiceUnavailableError or ValueError (invalid decimal
            # format) occurs.
            print(f"Error ignored: {e}")
            time.sleep(10)  # for ServiceUnavailableError

n = range(1, 9)
m = 100
delay = 4  # to avoid rate limit errors

results = []

for i in n:
    count = 0
    for _ in range(m):
        if check(i):
            count += 1
        time.sleep(delay)
    results.append(count / m)

# standard error
errors = [(p * (1 - p) / m) ** 0.5 for p in results]

plt.figure(dpi=150)
plt.errorbar(n, results, errors, fmt="o-", capsize=5)
plt.xlabel("$n$")
plt.ylabel("accuracy")
plt.xticks(n)
plt.grid()
plt.show()
```

結果は次のグラフのようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43042/a024745a-cefa-8cf8-96a9-e937101e11bd.png)

- $n=3$までは正答率100%である。
- $n=4$は正答率がぐっと下がる。
- なぜか$n=5$と$n=6$の正答率はほぼ100%になる[^1]。

本当は$a_n$以外の数字の掛け算や、桁数の異なる数字どうしの掛け算も検証した方がよいのでしょうが、労力と時間とAPIの使用コストのことも考えて、ここでの検証の結論を次のようにまとめたいと思います。

**ChatGPTは4桁以上の掛け算ができない（こともある）。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43042/6157151a-646e-f53f-9e88-f2840da42f01.png)

ちなみに、筆者は2桁の掛け算の暗算でさえよく間違えます。ChatGPTはすでに人間を超越している。

**【2023年3月12日追記】** [ChatGPTのAPI](https://platform.openai.com/docs/guides/chat)が[OpenAIから公開されてた](https://openai.com/blog/introducing-chatgpt-and-whisper-apis)のでやり直してみました。ついでに答えさせる掛け算の問題も少しだけランダムにしています。

```python
import openai
import random
import time
import matplotlib.pyplot as plt


def check(n, verbose=False):
    """Check if the AI answers an n-digit multiplication correctly."""
    a = 10**n - 1
    # Choose random numbers x and y such that they are approximately a
    # but x != y.
    x = y = 0
    while x == y:
        x = random.randint(a - 9, a)
        y = random.randint(a - 9, a)
    messages = [
        {
            "role": "system",
            "content": "You are an accurate calculator. "
            "Answer using only decimal letters from 0 to 9. "
            "Don't output any other characters, for example, "
            "decimal separators or punctuations.",
        },
        # We give example responses.
        {"role": "user", "content": "Compute 12345 plus 67890."},
        {"role": "assistant", "content": "80235"},
        {"role": "user", "content": "Compute 12345 multiplied by 67890."},
        {"role": "assistant", "content": "838102050"},
        # Here is the problem.
        {"role": "user", "content": f"Compute {x} multiplied by {y}."},
    ]
    while True:
        try:
            response = openai.ChatCompletion.create(
                model="gpt-3.5-turbo", messages=messages
            )
            if verbose:
                print(x, y, response)  # for debugging
            result = response.choices[0]["message"]["content"]
            if result[-1] == ".":
                result = result[:-1]
            return int(result) == x * y
        except Exception as e:
            print(f"Error ignored: {e}")
            time.sleep(10)  # for ServiceUnavailableError


n = range(1, 9)
m = 100
delay = 4  # to avoid rate limit errors

results = []

for i in n:
    count = 0
    for _ in range(m):
        if check(i):
            count += 1
        time.sleep(delay)
    results.append(count / m)

# standard error
errors = [(p * (1 - p) / m) ** 0.5 for p in results]

plt.figure(dpi=150)
plt.errorbar(n, results, errors, fmt="o-", capsize=5)
plt.xlabel("$n$")
plt.ylabel("accuracy")
plt.xticks(n)
plt.grid()
plt.show()
```
結果は次のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43042/448ad97c-84f2-d10c-374f-f6d8aae592d3.png)
う～ん、やはり**ChatGPTの計算力は怪しい**[^2]。

**【2023年3月25日追記】** [Microsoft Researchが書いている](https://arxiv.org/abs/2303.12712v1)ように、ゆっくりと順を追って途中計算を書かせると正答率が上がるようです。

> In a way, this shows how GPT-4 has an incredibly short working memory for this type of problem. However, if GPT-4 "takes its time" to answer the question then the accuracy easily goes up.

そういえば、[コール先生だって冒頭の掛け算をするのに約1時間かかった](https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%A9%E3%83%B3%E3%82%AF%E3%83%BB%E3%83%8D%E3%83%AB%E3%82%BD%E3%83%B3%E3%83%BB%E3%82%B3%E3%83%BC%E3%83%AB)のでした。ChatGPTにもゆっくりと計算させてみましょう[^3]。

![chatGPT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43042/0ca5de56-755d-9406-8e3b-c27ee6d75667.png)

やればできるじゃん！ChatGPT[^4]！

[^1]: 使用したプロンプトに依存している気がします。
[^2]: ChatGPTは計算がどうも苦手なようですが、ChatGPTにほかのツールを組み合わせることでこれを克服することができます。たとえば: https://huggingface.co/spaces/JavaFXpert/Chat-GPT-LangChain
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43042/27bf3a87-fa94-e697-2388-8e11eb7e531e.png)
[^3]: MSRの論文はGPT-4についてですが、ここでは従来のChatGPTを使っています。
[^4]: Step 13の多項式は
$7x^{19}+69x^{18}+76x^{17}+84x^{16}+120x^{15}+115x^{14}+230x^{13}+131x^{12}+196x^{11}+179x^{10}+176x^9+218x^8+169x^7+173x^6+124x^5+89x^4+116x^3+67x^2+22x+7$
になるはずなのですが。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43042/edc0e2d9-7394-7868-bf89-205ffc295792.png)
でも、最終結果が**なぜか**合っているので良いとしましょう。