第19章 microgpt の前処理

19.1 この章で学ぶこと

この章で学ぶ内容は以下のとおりです。

表19-1: この章で学ぶこと

学ぶこと

ポイント

docs の作り方

input.txt を行単位で読み、空行を除いてシャッフル

文字トークナイザー

uchars(文字→ID)・BOS(特殊トークン)・vocab_size

対応ブロック

第18章 microgpt の構造 の B1(データセット)と B2(トークナイザー)

第18章 microgpt の構造の全体地図のうち、入力テキストをトークン列にそろえるまでを見ていきます。

19.1.1 データセット

最初にやっているのは、学習に使う文字列を集めることです。

31if not os.path.exists('input.txt'):
32    import urllib.request
33    names_url = 'https://raw.githubusercontent.com/karpathy/makemore/988aa59/names.txt'
34    urllib.request.urlretrieve(names_url, 'input.txt')
35docs = [line.strip() for line in open('input.txt') if line.strip()]
36random.shuffle(docs)  # 学習時の順序をランダム化
37print(f"num docs: {len(docs)}")

行ごとの意味

  • L35 docs = [line.strip() ...]:ファイルを 1 行ずつ読み、前後の空白を除いたうえで中身が空でない行だけを docs に集めます(1 行が 1 文書)。

  • L36 random.shuffle(docs):学習ループで取り出す順序を毎エポックでばらけさせます。

  • L37 print(f"num docs: ..."):収集した文書数を表示します。

注釈

ダウンロード処理(L31〜L34)

input.txt がカレントディレクトリに無い場合のみ、Karpathy の makemore リポジトリから人名リスト(names.txt)を urllib.request.urlretrieve で自動取得します。 手動で input.txt を置いた場合はスキップされます。

../_images/dataset_input_to_docs.jpg

図19-1: データセット(input.txt → docs)

input.txt を 1 行ずつ読み、strip() した結果が空でない行だけを docs に積みます。 空行と空白のみの行はスキップされます。 input.txt が無い場合のみ names.txt を自動ダウンロードします。

ここでは人名の一覧を使います。 大きな文章ではないので、モデルの仕組みに集中しやすいです。 たとえば長い文書を扱う前に、まず「次トークンを当てる」感覚をつかむには、このくらい単純なデータがちょうどよいです。

19.1.2 トークナイザー

次に、文字を整数 ID に変えます。

43uchars = sorted(set(''.join(docs)))  # データセット内の全ユニーク文字 → ID 0..n-1
44BOS = len(uchars)                    # 文の開始/終了を示す特殊トークン(Beginning of Sequence)
45vocab_size = len(uchars) + 1         # 語彙サイズ(文字数 + BOS)
46print(f"vocab size: {vocab_size}")
表19-2: トークナイザー

コード

意味

L43

uchars = sorted(set(''.join(docs)))

全文書の文字集合をソートして並べる。インデックスが文字 ID になる

L44

BOS = len(uchars)

通常文字 ID の外側に「文頭・文末」専用の特別トークン ID を割り当てる

L45

vocab_size = len(uchars) + 1

通常文字数 + BOS 1 個 = logits の出力次元数

L46

print(...)

語彙サイズを表示

この実装は文字単位のトークナイザーです(単語単位ではない)。 anna[id(a), id(n), id(n), id(a)] に変換し、BOS で文の境界を表します。

ここで定義した 3 つの変数は、この後の章で繰り返し登場します。 それぞれの型と役割を整理しておきます。

表19-3: トークナイザー(2)

変数

型と内容

役割

uchars

list[str](ソート済み文字の列)

インデックスが文字 ID。uchars[i] で文字に戻せる

BOS

int = len(uchars)

文頭・文末の特別トークン。モデルが「ここで文が終わる」を学ぶ

vocab_size

int = len(uchars) + 1

埋め込み行列と logits の語彙次元数

トークナイザーの全体像を次の図にまとめます。

../_images/tokenizer_char_level.jpg

図19-2: 文字単位トークナイザー

文字を 1 文字ずつ整数 ID に変換します。 uchars のインデックスがそのまま文字 ID になり、BOS は文頭と文末を表す特別トークンです。 例えば anna[1, 2, 2, 1] にトークン化され、前後を BOS で挟むことで文の境界を表します。