第19章 microgpt の前処理
19.1 この章で学ぶこと
この章で学ぶ内容は以下のとおりです。
学ぶこと |
ポイント |
|---|---|
|
|
文字トークナイザー |
|
対応ブロック |
第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 を置いた場合はスキップされます。
図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}")
行 |
コード |
意味 |
|---|---|---|
L43 |
|
全文書の文字集合をソートして並べる。インデックスが文字 ID になる |
L44 |
|
通常文字 ID の外側に「文頭・文末」専用の特別トークン ID を割り当てる |
L45 |
|
通常文字数 + BOS 1 個 = logits の出力次元数 |
L46 |
|
語彙サイズを表示 |
この実装は文字単位のトークナイザーです(単語単位ではない)。
anna → [id(a), id(n), id(n), id(a)] に変換し、BOS で文の境界を表します。
ここで定義した 3 つの変数は、この後の章で繰り返し登場します。 それぞれの型と役割を整理しておきます。
変数 |
型と内容 |
役割 |
|---|---|---|
|
|
インデックスが文字 ID。 |
|
|
文頭・文末の特別トークン。モデルが「ここで文が終わる」を学ぶ |
|
|
埋め込み行列と logits の語彙次元数 |
トークナイザーの全体像を次の図にまとめます。
図19-2: 文字単位トークナイザー
文字を 1 文字ずつ整数 ID に変換します。
uchars のインデックスがそのまま文字 ID になり、BOS は文頭と文末を表す特別トークンです。
例えば anna は [1, 2, 2, 1] にトークン化され、前後を BOS で挟むことで文の境界を表します。