ChatGPTはどのように動いているのか
はじめに
ChatGPTなどの生成AIは、最近ではシステム開発業界にとどまらず、さまざまな分野で使用されています。私自身も使用していますが、質問をするとそれっぽい(100%ではありませんが精度が高い)回答をしてくれるツールとして認識して使用しています。
エンジニアではない人が一つのツールとして使う分には、その認識で何ら問題はありませんが、エンジニアはAIを開発の中枢に組み込んで業務を進めていかなければいけない立場のため、どのような仕組みで動いているかはある程度知っておく必要があると思っています。
AIの仕組みを深く理解するには専門的な数学の知識が必要で、専門書を読んでも私には到底理解できないため、専門的な数学の知識をなるべく省いて説明してくれている書籍 「ChatGPTはどのように動いているのか?」著:中西崇文 https://amzn.asia/d/0dul88aa を読んで得た知識をここにまとめておこうと思います。
1. GPTは何をしているのか?
まず、ChatGPTとは、生成AIモデルを使用してチャット形式でやり取りを行うサービスです。「GPT」とは、OpenAIが開発しているモデルのことです。最新では、GPT-6が公開されています。https://chatgpt.com/
GPTがなぜそれっぽい回答ができるのかというと、「事前学習したデータをもとに次の一語を予測するから」です。
例えば、「犬も」という一語がGPTに渡されたとすると、学習データをもとに計算を行い、「犬も」に続く一語として
- 「歩けば」
- 「一緒に」
- 「寝ている」
などの候補を出し、最も可能性が高いものを判断して言葉を紡いでいきます。これを何度も繰り返して回答を生成します。
「歩けば」が最も可能性が高いと判断した場合、次は「犬も歩けば」に対して同じように計算を行っていきます。
この計算をどのように行うかというと、事前学習では、単語や文章などをすべて数値化(ベクトル化)したものを学習しています。 この数値はグラフの座標のようなもので、2次元では(x, y)でその単語の場所をマッピングしているため、「犬」と「猫」は近い座標になり、「犬」と「ラーメン」は遠い座標にマッピングされます。
これにより、単語や文章同士の関係性が計算できます。もちろん2項目だけでは表現できる関係性が少ないため、ChatGPTでは1536次元(モデルによってはそれ以上)のベクトルに数値化しています。
2. ChatGPTの基本的な仕組み
「GPT」は「Generative(生成的)」「Pre-trained(事前学習済み)」「Transformer」の頭文字をとったもので、「G」と「P」は、OpenAIがさまざまなデータを事前学習させた生成モデルであることを示しています。
「T」はTransformerを表します。Transformerは、ChatGPTを支える中核的な仕組みです。つまり、ChatGPTがどのように動いているかを理解するには、Transformerの仕組みを理解する必要があります。
Transformerは「ベクトル」と「行列」を用いて次の一語を予測する計算を行っていく仕組みです。Transformerは、2017年に発表された「Attention Is All You Need」という有名な論文で提唱されました。
Transformer自体の説明をする前に「ベクトル」と「行列」について説明します。
2-1. ベクトル
単語や文章を数値化したものです。 ベクトルには、その単語をさまざまな角度から見たいろいろな要素を含んでいます。イメージとしては、二次元グラフの(x, y)のように単語の座標を決めているもので、座標同士を比較することで意味が近い単語や遠い単語、一緒に使われる可能性が高い単語などを見つけることができます。
例として、下の表はリンゴの種類をベクトル化したもので、文字で表す場合は、(10, 3, 6)のような数値の塊として表します。
| 品種 | 甘さ | 酸味 | 香り |
|---|---|---|---|
| ふじ | 10 | 3 | 6 |
| 王林 | 9 | 2 | 10 |
| シナノスイート | 9 | 4 | 8 |
2-1-1. 次元数
ベクトルには次元数というものがあり、何種類の要素で対象を数値化したかを表します。 今回でいうとリンゴの種類を甘さ、酸味、香りの3点で表したので、このベクトルの次元数は3次元ということになります。3次元ではリンゴの特徴はある程度表せますが、「車」や「私は朝にパンを食べました」などの他の単語・文章は表せないので、ChatGPTでは1536次元のベクトル化を行っています。
ベクトル同士で比較を行う場合には、同じ次元数でなければいけません。リンゴのベクトルにプラスして「価格」を持った「ジョナゴールド」を追加する場合には、ふじ、王林、シナノスイートにも価格の値を設定する必要があります。このように次元を増やすことを 「次元拡張」 といい、逆に減らすことを 「次元圧縮」 といいます。
2-1-2. 特徴量
次元の中の各要素「甘さ」「酸味」「香り」を特徴量といい、どの特徴量でベクトル化するかが非常に重要になっています。今回の場合だと「価格」「大きさ」などを追加すればリンゴの表現は深まりますが、「危険度」や「強度」などあまり必要のない特徴量があってもリンゴの表現は広がりません。むしろ関係のない特徴量で次元数を増やすと一個一個の特徴量がベクトルに与える影響が少なくなり、全部同じようなものとして判断される可能性もあります。
2-1-3. コサイン類似度
ベクトル同士がどれだけ似ているかを比較する方法として 「コサイン類似度」 というものがあります。ベクトルA, Bを比較してどれほど近い向きかを表します。計算式は割愛しますが、-1~1の値をとり、数値が大きいほど似ていると判断します。
- 1に近い = 似ている
- 0に近い = 関係性が低い
- -1に近い = 正反対の性質を持つ
2-1-4. 正規化
ベクトルの特徴量は、大きさを合わせずに使用してしまうと大きい値がコサイン類似度に大きく影響し、小さい値は影響が小さくなるという弊害があります。例えば「甘さ」や「酸味」などは0~10の値をとりますが、「価格」は100~500程度の値をとるため価格の差が大きく反映されやすいです。イメージですが、以下の場合だと
| 品種 | 甘さ | 酸味 | 香り | 価格 |
|---|---|---|---|---|
| ふじ | 10 | 3 | 6 | 260 |
| 王林 | 9 | 2 | 10 | 280 |
| シナノスイート | 9 | 4 | 8 | 270 |
ふじと王林を比較した場合
| 比較対象 | 甘さ | 酸味 | 香り | 価格 |
|---|---|---|---|---|
| ふじと王林の差 | 1 | 1 | 4 | 20 |
二つのリンゴを比較したときに「香り」が全然違うリンゴなのに価格が20という数値をとっているために、香りが全然違うリンゴではなく、価格が全然違うリンゴのように見えてしまいます。このように特徴量ごとに数値のスケールが異なるため、スケールを合わせることを正規化といいます。実際にOpenAIが提供しているエンベディングモデル(text-embedding-3-small。ベクトル化するためのモデル)を使用してベクトル化した場合、おおよそ-1~1の範囲に各特徴量が収まっています。
「リンゴ」をベクトル化した場合のイメージ
→ [0.0134, -0.0278, 0.0841, -0.1123, 0.0456, ..., 0.0311]
2-2. 行列
行列とは数値を行と列に並べたもの = 表です。ここでいう行列はベクトルを複数まとめたものを指します。2-1. ベクトルで各リンゴをベクトル化した表がありましたが、あれが行列になります。
なぜ行列が必要になるかというと、GPTが回答するときにはベクトルとベクトルを掛け合わせて新しいベクトルを作るということを繰り返します。このとき、まとめて複数のベクトルを計算できるようにすると計算回数が1回で済むためです。これは次元拡張、次元圧縮でも同じように実行回数を減らせます。
3. AIの思考回路
AIは 「ニューラルネットワーク」 という思考回路を用いて人間に近い回答を出します。ニューラルネットワークは次元拡張と次元圧縮を繰り返しながら最適な特徴量を見つけ出します。この操作は文章を分割したトークンごとに行われます。
GPTに入力した場合の流れでは、
- 文章をトークンごとに分割
- トークンを1024次元に拡張(情報を広げる)
- 512次元に圧縮(必要な特徴量を精査)
- 再度1024次元に拡張(最初とは視点を変えて広げる)
- 一気に64次元に圧縮(重要な特徴量のみにまとめて出力に備える)
- 3次元に圧縮(出力)
このように、トークン(単語など)について調べ、情報をまとめるという処理を繰り返します。その過程で必要な情報を強調し、不要な情報をそぎ落として、入力時とは異なるベクトルを出力するため、人間の思考回路に近いものを再現しています。思考中に次元拡張、圧縮するときに追加する特徴量、そぎ落とす特徴量の判断はモデルが何を学習したかによって異なります。
質問に対して適切な特徴量を設定できる = 優秀なモデルといえるかもしれません。
じゃんけんに勝つ手を考える場合の思考例:
- 「グー」と入力される
- 「グー」をベクトル化する(特徴量:グー、チョキ、パー)
| グー | チョキ | パー |
|---|---|---|
| 1 | 0 | 0 |
- 次元拡張を行う(グーに対して各手を出したときの勝率という特徴量を追加)
| グー | チョキ | パー | グーを出した場合の勝率 | チョキを出した場合の勝率 | パーを出した場合の勝率 |
|---|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 0 | 1 |
- 次元圧縮を行う
| グーを出した場合の勝率 | チョキを出した場合の勝率 | パーを出した場合の勝率 |
|---|---|---|
| 0 | 0 | 1 |
- 「パー」と返す
4. Embedding
Embeddingとは、単語や文章をベクトル値に変換し、ベクトル空間に埋め込むことです。 単語や文章などをベクトル値に変換することと理解すれば問題ありません。Embeddingにもモデルがあり、どのような特徴量でベクトル化すればいいかを事前学習しています。
「ベクトル化する」と「Embeddingする」は、どちらもベクトル値に変換することです。ただし、「ベクトル化する」には、自身で決めた特徴量などを使ってベクトル値に変換することも含まれます。一方、「Embeddingする」は、モデルが決めた特徴量を持つベクトルに変換することを指します。※AI関連では、基本的に「ベクトル化」=「Embedding化」という認識で問題ありません。
「単語、文章など」と表現しましたが、現在のEmbeddingモデルは画像や音声、動画など、さまざまな媒体をベクトル化できます。そのため、文章から画像を生成したり、逆に画像を文章で説明したりすることも可能です。文、画像、音声などをすべてベクトルに変換し、同じものとして扱うことでこのようなことが可能になりました。
ベクトル表現には、文章からさまざまなものを生成できること以外にも、「ニュアンス」を捉えられるという特徴があります。ニュアンスを理解できることで、自然言語で会話できるようになりました。
4-1. 従来の方法の問題点
ベクトルができる前は「Bag-of-Words」という手法が使われていました。これはシンプルな方法で、文章の単語を抽出してその単語が何回出てきたかを記録するものです。
例えば、A.「私はラーメンを食べた」、B.「私はカレーが嫌いだがラーメンは好き」という文章がある場合、
| 文 | 私 | ラーメン | カレー | 食べた | 嫌い | 好き |
|---|---|---|---|---|---|---|
| A | 1 | 1 | 0 | 1 | 0 | 0 |
| B | 1 | 1 | 1 | 0 | 1 | 1 |
このように、文章中に出てきた単語を1、出てきていない単語を0とします。Aを(1, 1, 0, 1, 0, 0)、Bを(1, 1, 1, 0, 1, 1)というベクトルで表し、コサイン類似度を計算することで、どれだけ似ているかを調べていました。
この方法では単語を独立して扱うため以下の問題がありました。
- 単語同士の関連性がわからない 「ラーメン」「カレー」は食べ物という共通点がありますがこの方法だと理解できません
- 同じ単語が異なる意味で使われていても区別できない 「クビが痛い」と「会社をクビになる」では、「クビ」が異なる意味で使われていますが、その違いを理解できません。
- ニュアンスを理解できない 「資料を送ってください。」と「資料を送れ。」はニュアンスが大きく異なりますが、どちらも「資料」「送る」だけが抽出されるため、その違いを理解できません。
- 助詞を無視するため、間違った解釈をすることがある 「私は牛を食べた」と「私を牛が食べた」では意味が全く異なりますが、助詞を省くため、その違いを理解できません。
4-2. 問題点を解決したEmbedding
4-1.で挙げた問題点は以下の2点が原因です。
- 単語を独立して扱っている
- 助詞を省いている
この問題を解決するため、Embeddingでは文章全体をベクトル化します。 文章全体をベクトル化することで、「クビ」が体の一部として使われているのか、解雇という意味で使われているのかを理解できます。また、ベクトル空間上に配置することで、「ラーメン」と「カレー」は、どちらも食べ物であるという観点から近い座標に配置され、関連性も捉えられます。
Embeddingモデルの学習にも「ニューラルネットワーク」が使用されています。
5. TransformerとAttention
「Transformer」とは最初の方で説明した通り、AIの中核をなす仕組みのことです。言葉で表すと、「入力された文章の中で、どの単語(※厳密にいえばトークン)とどの単語が文脈上どれくらい関係しそうかを繰り返し計算し、その結果をもとに次にくる言葉を確率的に決める仕組み」 です。
Transformerの「どの単語が文脈上どれくらい関係するか」を計算するのが「Attention」という仕組みです。
5-1. Attention
Attentionで行うことは、入力された文章をトークンに分割し、そのトークン同士をコサイン類似度で比較していくことで、 「どの単語に注意を向けるべきか」 を導き出します。Attentionにはさまざまな方法や計算式がありますが、それらを省き、イメージとして伝えると、
「私は昨日、犬を見た。その犬はとても大きかった。」という文章があったとしたら、これを「私は」「犬を」のように分割して各単語がどれと関係が深そうかを考えます。
「見た。」に着目すると「犬を」と関係が深そうだし、「大きかった。」に着目すると、「その犬は」と関係が深そうです。
「その犬は」や「とても」は「大きかった」と関係が深そうなので、この文章で注意を向けるべきは「犬」が最重要で、次点で「大きかった」と判断します。※Attentionの出力結果自体は、私: 0.05, 犬を: 0.6, 大きかった: 0.2みたいな形で確率として返します
人間も同じようにパッと見で文章の重要そうな単語を脳内でつなぎ合わせて理解しますが、Attentionはそれを計算して行う仕組みです。
5-2. Transformer
Transformerを説明する図は「Attention Is All You Need」で提唱された以下のものがありますが、今回の説明ではすべてを理解する必要はありません。
基本的にやることはそこまで難しくありません。GPTモデルを利用する場合は、右側のデコーダーだけ見れば十分です。
- 入力された文章をエンベディングモデルでベクトル化する(Input Embedding)
- 入力された単語に位置情報を付与する(単語の順番が変わると意味やニュアンスが変わるため)(Positional Encoding)
- Attentionでどの単語を重点的に見るかを調べる(Masked Multi-Head Attention)
- 正規化(Add & Norm)
- ニューラルネットワークで新しい視点を加えたベクトルを生成する(Feed Forward)
- 正規化(Add & Norm)
- 3~6を繰り返す
ここで注意すべきなのは、1.では文章をトークンごとに分割し、それぞれをベクトル化することです。分割したトークンのベクトルをまとめた行列が、3~6の処理を繰り返す中で変化していきます。そのようにすることで、単語ごとに注目することも、文章全体のニュアンスを理解することもできます。
Attentionで文章内の単語の関連性を解釈し、それをもとにニューラルネットワークで新しい特徴量を生成することで、文章を多角的に分析できるようになっていきます。これを何度も繰り返すことで、文章が持つ抽象的な情報まで含んだベクトルが作成されます。
6. まとめ
GPTが行っているのはTransformerという仕組みを使用して次の単語を予測することだけです。 プログラミングも、世界の歴史も料理の作り方も何も理解していません。ただ、ベクトルや行列の計算を繰り返して次に続く可能性が高い単語をつなげていっているだけです。その繰り返しが結果として何もかも理解しているように見えるのです。
これさえわかればなぜ「ハルシネーション」が起こるのかも理解できます。Transformerという仕組みを使用している以上、何が正しいかではなく、何が関連性が高いかが回答の基準になっています。回答が正しいか、論理的に整合性が取れているかなどを、GPT自身は判断できません。もちろんモデルの性能が上がり、学習内容が増えていけばハルシネーションが起こる確率は下がっていくと思いますが、仕組み上0%にはならないでしょう。
7. 感想
GPTやClaudeが登場して以降、AIを活用したビジネスが数多く生まれています。その一方で、「AIは何でもできる」と考える人もいるかもしれません。
しかし、LLMは仕組み上、常に正しい回答を返すことや、100%の正確さを保証することはできません。そのため、AIの回答だけに依存する形でシステムの中核に組み込むことには限界があります。仕様を正確に実行できる処理はプログラムで実装し、AIは文章の作成や要約、アイデア出しなど、人間の判断を補助する用途で活用するのがよいと思います。
このように考えられるようになったのは、本書を読んでAIの仕組みを理解できたからです。AIを過度に期待せず、適切に活用するためにも、おすすめできる一冊だと思います。
※新しく登場した「Jev」は別の仕組みらしいので、こちらも気になっています。

