第17章 microgpt の仕様
17.1 この章で学ぶこと
この章で学ぶ内容は以下のとおりです。
学ぶこと |
ポイント |
|---|---|
入力と出力の形式 |
テキストファイル |
学習の 5 ステップ |
トークナイズ → 順伝播 → 損失 → 逆伝播 → Adam 更新 |
生成の 2 ステップ |
BOS から始め、次の文字を 1 つずつサンプル |
|
学習で更新される重みの束。生成時に参照する |
17.2 microgpt.py がやること
外部から見ると、microgpt.py は次の一言で表せます。
input.txtに含まれるテキストを学習し、同じ種類のテキストを生成して標準出力に表示するスクリプト。
入出力の仕様はシンプルです。
区分 |
内容 |
|---|---|
入力 |
カレントディレクトリの |
出力 |
学習ログ(ステップ番号と損失値)と、学習後に生成されたテキスト列を標準出力へ |
依存 |
Python 標準ライブラリのみ(外部パッケージ不要) |
実行方法 |
|
microgpt.py は 学習フェーズ と 生成フェーズ の 2 つで構成されます。
2 つのフェーズは state_dict(重みの束)を介してつながっています。
図17-1: 学習フェーズと生成フェーズ
学習フェーズで state_dict を更新し、生成フェーズでは同じ重みを読みながらトークンを 1 つずつ足していきます。
入出力まで含めた全体像を次の図に示します。
図17-2: microgpt.py の入出力
入力 input.txt から、学習と生成の 2 フェーズを経て、標準出力に結果が書き出されるまでの全体の流れを示しています。
2 フェーズの本質的な違い
学習フェーズは「正解を知っている」状態で動きます。
input.txt の各文字が正解ラベルになるため、「予測した確率分布と正解ラベルのズレ(損失)」を測り、その勾配を逆伝播することで重みを少しずつ正解方向に動かします。
このトークナイズ → 順伝播 → 損失 → 逆伝播 → 更新という 5 ステップが、num_steps 回繰り返されます。
生成フェーズは「正解のない」状態です。
重みは更新されず、state_dict を読み込むだけです。
BOS(文頭記号)を最初のトークンとして渡し、次のトークンの確率分布をサンプリングして系列を 1 文字ずつ伸ばします。
BOS が再び出力されると「文の終わり」と判断して停止します。
なぜ単一ファイルで完結できるか
PyTorch のような外部ライブラリは「効率」のために存在します。
行列演算の GPU 加速、自動微分エンジン、データローダーなど、多くの機能がライブラリに委ねられています。
microgpt はこれらをすべて Python の標準ライブラリ(math、struct、random)だけで実装しているため、1 ファイルに収まります。
速度は遅いですが、アルゴリズムの全貌が 1 つのファイルを読むだけで把握できます。
17.3 学習フェーズ
input.txt を読み込み、トークナイズ → 順伝播 → 損失 → 逆伝播 → 重み更新という 5 ステップを num_steps 回繰り返して state_dict を更新します。
学習が終わると state_dict の値が生成フェーズで参照されます。
入力ファイルの仕様
学習データは input.txt という名前のテキストファイルです。
項目 |
仕様 |
|---|---|
形式 |
プレーンテキスト(UTF-8) |
1 行の意味 |
1 文書(名前、単語、文など) |
空行・空白のみの行 |
スキップされる(学習データに含まれない) |
文字の種類 |
ファイル内に出現する全文字を自動収集してトークン化(追加設定不要) |
デフォルトデータ |
Karpathy の |
input.txt が存在しない場合は、起動時に上記デフォルトデータを自動ダウンロードします。
モデルアーキテクチャのハイパーパラメータ
モデルの構造を決めるパラメータです。 学習前にソースコード内で設定します。
パラメータ名 |
デフォルト値 |
意味 |
|---|---|---|
|
4 |
Transformer 層の数。多いほど表現力が上がるが学習が遅くなる |
|
4 |
Multi-Head Attention のヘッド数。 |
|
64 |
埋め込みベクトルの次元数。モデルの「幅」を決める |
|
32 |
1 回の順伝播で扱える最大トークン数(コンテキスト長) |
|
自動 |
|
学習のハイパーパラメータ
学習ループの挙動を制御するパラメータです。
パラメータ名 |
デフォルト値 |
意味 |
|---|---|---|
|
1000 |
学習ステップ数。1 ステップ = 1 文書の順伝播 + 逆伝播 + 更新 |
|
0.01 |
初期学習率。ステップが進むにつれ線形に減衰する |
|
0.9 |
Adam の第 1 モーメント減衰係数(勾配の指数移動平均) |
|
0.999 |
Adam の第 2 モーメント減衰係数(勾配の二乗の指数移動平均) |
|
1e-8 |
Adam の数値安定化項。ゼロ除算を防ぐ |
17.4 生成フェーズ
学習完了後に自動的に開始します。
state_dict に保存された重みを読み込み、指定した本数のテキストを生成して標準出力に表示します。
出力の仕様
項目 |
仕様 |
|---|---|
出力先 |
標準出力 |
出力形式 |
1 サンプル = 1 行のテキスト |
生成本数 |
|
終了条件 |
BOS トークンが出力される、または |
文字セット |
|
生成パラメータ
パラメータ名 |
デフォルト値 |
意味 |
|---|---|---|
|
20 |
生成するテキストの本数 |
|
1.0 |
生成の多様性を制御する係数。小さいほど確定的、大きいほどランダムになる |
temperature |
生成される文字列の傾向 |
|---|---|
低い(例: 0.5) |
無難・単調。学習データに頻出するパターンに偏りやすい |
1.0(標準) |
モデルの確率分布に忠実なサンプリング |
高い(例: 1.5) |
多様・ランダム寄り。出力が崩れやすくなる |
17.5 入力と出力の例
入力: input.txt(人名リスト)
デフォルトで使われる input.txt は Karpathy の makemore リポジトリ由来の英語人名リストで、32033 件の名前が 1 行 1 名前で並んでいます。
emma
olivia
ava
isabella
sophia
...
文字の種類は a〜z の 26 文字と BOS の計 27 トークンです(vocab_size = 27)。
語彙が小さいため、埋め込み行列(wte)のサイズも小さく、学習が速く収束します。
学習の収束イメージ
学習ステップが進むにつれ、損失(loss)は下がっていきます。
step 1 loss: 3.296
step 100 loss: 2.514
step 500 loss: 2.031
step 1000 loss: 1.887
損失が log(27) ≒ 3.30(つまりランダムに選んだときの損失)から下がり始めると、モデルが何らかのパターンを学習していることを意味します。
人名らしい文字の並びが見えてきたら学習が進んでいる証拠です。
生成出力例
学習後に生成すると、人名らしい文字列が現れます。
--- 生成結果 ---
aria
mia
ali
luna
kael
...
見たことのない文字の組み合わせでも、英語人名の統計的なパターン(「a で終わりやすい」「子音と母音が交互」など)を反映した出力になります。 これは文字単位の言語モデルの特性で、単語辞書を持たずに訓練データの統計から名前らしさを学んでいます。
生成が失敗するケース
生成が崩れる原因
学習ステップが少ない: 損失がまだ高い状態では、ランダムな文字列が出力される
temperature が高すぎる:
temperature > 1.5になると、出力が英語らしくない文字の羅列になりやすいblock_sizeに到達: 生成が長引いてblock_sizeに達すると強制終了するため、BOS で自然に終わらない出力になる
17.6 次に読む章
本章の内容に続く章と、各章で扱う内容を示します。
章 |
内容 |
|---|---|
入力から出力までの 7 ブロック(B1〜B7)を全体地図として俯瞰 |
|
ブロックごとにコードを行単位で読む |