🐷

ChatGPTなどLLMの仕組みを説明してみる(Pythonで超原始版ChatGPTを作成する)

に公開

1. テキストがモデルに届くまで ― 「前処理」

ステップ 何をやっている?
① トークン化 文章を「トークン(細切れ)」に分割。
文字単位・サブワード単位・単語単位など方式はいろいろ。
「ChatGPT はすごい」 → ["Chat", "G", "PT", "▁は", "▁すごい"]
② ID へ変換 各トークンを辞書(語彙表)の番号に置き換える。 Chat → 1345, G → 97 …

🔍 ポイント
LLM が “単語” を理解しているわけではありません。あくまで「ID の並び」として学習・推論します。


2. モデルの中身 ― 「Transformer」のざっくり図解

image.png

  1. 埋め込み層 (Embedding)

    • トークン ID → 高次元ベクトルへマッピング。
  2. 多層 Transformer

    • 自己注意 (Self-Attention): 一つのトークンが「系列中の他トークンをどれくらい見るか」を計算。
    • FFN: 全結合ニューラルネットで非線形変換。
    • これを何十層も重ねることで、文脈を深く表現できる。
  3. 出力線形層 + Softmax

    • 各語彙 ID ごとに「次トークンになる確率」を出力。
  4. 生成 (Sampling)

    • 温度付きサンプリング、Top-k / Top-p などで 1 語決定。
    • 新しいトークンを入力列の末尾に付け、再び 1-4 をループ → 文章が伸びる。

3. どう学習する? ― 「自己教師あり」予測

  • 大量のテキストを使い、
    「直前までを見て、次のトークンを当てる」 というタスクでパラメータを調整。
  • 誤差関数: 交差エントロピー (cross-entropy)。
  • 最適化: AdamW など。
  • こうして “テキストの統計的なクセ” を内部に蓄えます。

4. 超ミニ実装:ビッグラム(2 語連鎖)モデル

以下のスクリプトは 「直前の 1 語 → 次の 1 語」 という極めて原始的なモデルです。
Transformer とは桁違いに単純ですが、

  1. コーパスからペア (w₁, w₂) を数える
  2. 条件付き確率 P(w₂|w₁) を求める
  3. 確率に従って次語をサンプリングし、文章を伸ばす

という “言語モデル” の基本骨格を体験できます。

import random
from collections import defaultdict, Counter

# --- 1. データ準備(とても小さなサンプル) ---
text = (
    "ChatGPT is a large language model. "
    "It predicts the next word based on the context of previous words. "
    "Language models learn patterns in text by seeing lots of examples."
)

# --- 2. 単語に分割(トークン化) ---
tokens = text.lower().split()

# --- 3. ビグラム(2語連鎖)を数え上げ ---
bigrams = defaultdict(Counter)
for w1, w2 in zip(tokens[:-1], tokens[1:]):
    bigrams[w1][w2] += 1

# --- 4. 次の単語をサンプリングする関数 ---
def sample_next(current_word):
    counts = bigrams.get(current_word, None)
    if not counts:                    # 未知語ならランダムにリセット
        return random.choice(tokens)
    total = sum(counts.values())
    r = random.randint(1, total)
    cum = 0
    for word, cnt in counts.items():
        cum += cnt
        if r <= cum:
            return word

# --- 5. テキスト生成 ---
def generate(seed="chatgpt", length=15):
    words = [seed]
    for _ in range(length):
        next_word = sample_next(words[-1])
        words.append(next_word)
    return " ".join(words)

if __name__ == "__main__":
    print(generate())

▶️ 実行結果:

chatgpt is a large language model. it predicts the context of examples. previous words. language model.

実際は 30 億〜数兆語の学習データと 数十〜数百億パラメータの Transformer を使いますが、やっていることの根っこは「過去を見て次を予測する」だけ、というのがポイントです。


まとめ ― “魔法” ではなく大規模な統計予測

  1. 入力をトークン化 → 数値化
  2. 埋め込み + Transformer で文脈ベクトルを計算
  3. Softmax で「次のトークン分布」を出す
  4. サンプリングして文章を生成
  5. 学習は「次トークン当てクイズ」をひたすら解く

この 5 ステップさえ押さえれば、「ChatGPT の中で何が起きているか」の大枠をイメージできます。あとは モデル規模・計算資源・最適化テクニック をどこまで大きく/巧みにできるかが、精度と賢さを左右しているわけです。

Discussion