zxell.ai
この資料は、プロジェクト内部のレポートを公開用に編集したものです。サーバ運用・セキュリティに関わる部分と、コーパスの詳細は省略しています(省略箇所には印があります)。

フェーズ1 で使った基盤のメソッド一覧 — LLM 学習に直接かかわるもの(モジュール別)

作成: 2026-10-11 対象コミット: 866b7a2(フェーズ1 の S ベースライン完走時点のコード)

0. この資料について

基盤版使っているモジュール役割
SentencePiece (sentencepiece)0.2.2zxell_prep/、zxell_model/sample.pyBPE トークナイザの学習・エンコード・デコード
PyTorch (torch)2.14.0(サーバ機は CPU 版、RTX 3060 機は CUDA 版 cu128)zxell_model/テンソル演算、自動微分、層の部品、最適化、混合精度

1. zxell_prep/(トークナイザと前処理)

前処理で LLM 学習に直接かかわる基盤は SentencePiece だけ。使っているのは 3 ファイル。

1-1. train_compare_tokenizers.py — トークナイザの学習と比較

呼び出し用途
sentencepiece.SentencePieceTrainer.trainBPE トークナイザの学習(語彙 48k と 64k の 2 つ)
sentencepiece.SentencePieceProcessor学習したモデルの読み込み
.encode評価セットをトークン列にして、言語別の字/トークンを測る

SentencePieceTrainer.train に渡している主な引数:

引数値意味
model_type"bpe"BPE で学習する
vocab_size48,000 / 64,000語彙の大きさ(48k を採用)
character_coverage0.9995語彙に入れる文字の網羅率
byte_fallbackTrue未知の文字はバイト列に落とす(UNK を出さない)
split_digitsTrue数字は 1 桁ずつに分ける
normalization_rule_name"nmt_nfkc"文字の正規化
max_sentence_length16,3841 文として扱う長さの上限
input_sentence_size / shuffle_input_sentence2,000,000 / True学習ファイルから 200 万文を無作為に使う

学習ファイルの作り方(言語別の文字数上限で配分し、ja を約 19% に厚くする)は自前のロジック。BPE の学習アルゴリズム自体は SentencePiece に任せている(review10 の決定)。

1-2. tokenize_full.py — 全量トークン化とシャード化

呼び出し用途
sentencepiece.SentencePieceProcessor採用した 48k モデルの読み込み
.encode全記事をトークン ID の列にする(学習データそのものを作る処理)
.eos_id記事と記事の間に挟む区切りトークン(EOS)の ID
.vocab_size語彙が uint16(65,536 未満)に収まることの確認

正規化・重複除去・言語別の分割・記事単位のシャッフル・5,000 万トークンごとのシャード化・書いた直後の検証は、すべて自前のロジック。

1-3. peek_shard.py — シャードの目視確認

呼び出し用途
sentencepiece.SentencePieceProcessor48k モデルの読み込み
.decodeシャードのトークン列を原文に戻して表示する(学習データに何が入っているかの確認)
.eos_id記事の区切りを見つける

1-4. 基盤のメソッドを使っていないファイル

parse_dump.py(スナップショットの作成)、extract_sample.py(サンプルの抽出)、compute_boundaries.py(分割境界の算出)、 textprep.py(テキスト整形)には、LLM 学習に直接かかわる基盤の呼び出しはない。処理はすべて自前のロジックで書いている。


2. zxell_model/(モデルと学習)

2-1. 「自前実装」と「基盤」の境界

先に結論を置く。何を自分で書き、何を PyTorch に任せたか。

部品自前で書いたものPyTorch に任せたもの
RMSNorm計算式そのもの(2 乗平均の逆平方根を掛ける、fp32 に上げて計算)torch.rsqrt、.pow・.mean、学習パラメータの入れ物 nn.Parameter
RoPE(回転位置埋め込み)周波数表の作成、前半・後半を回転させる式torch.arange・torch.outer・.cos・.sin・torch.cat
Self-AttentionQ/K/V の射影と head への分割、RoPE の適用、出力射影注意の計算そのもの: F.scaled_dot_product_attention(is_causal=True)(softmax(QKᵀ/√d)V と因果マスク。GPU 向けに最適化された実装)
SwiGLU FFN構成(gate・up・down の 3 つの線形層と掛け算)nn.Linear、活性化関数 F.silu
Transformer ブロック・GPT 本体Pre-Norm の残差構成、層の積み重ね、埋め込みと LM Head の重み共有、初期化の方針nn.Embedding・nn.Linear・nn.ModuleList、初期化 nn.init.normal_
損失語彙 48k の logits が大きいので、4 系列ずつに分けて計算する工夫交差エントロピー F.cross_entropy、逆伝播時の再計算 torch.utils.checkpoint.checkpoint
学習学習率スケジュール(warmup + cosine)、weight decay をかける対象の振り分け、学習データのサンプリング自動微分(loss.backward())、最適化(torch.optim.AdamW)、勾配クリップ、bf16 混合精度(torch.autocast)
評価言語別パープレキシティの集計(トークンごとに言語を割り当てる)トークンごとの損失 F.cross_entropy、torch.exp
生成自己回帰ループ、temperature、top-p(累積確率で打ち切る処理)F.softmax・.sort・.cumsum・.scatter_・torch.multinomial

分かったこと

2 つ目の注意計算は、これまでの決定事項として明示的に確認したことがない点です。「自前実装」の範囲として気になる場合は、自前版に差し替えて、速度と損失を比べることもできます。

2-2. model.py — GPT 本体

呼び出し用途
torch.nn.Module(継承)すべての層(RMSNorm・Attention・SwiGLU・Block・GPT)の基底クラス
torch.nn.ParameterRMSNorm の学習するスケール係数
torch.nn.Embeddingトークン埋め込み(語彙 48k × d_model)
torch.nn.Linear ×6Q/K/V の射影、注意の出力射影、SwiGLU の 3 層、LM Head(いずれもバイアスなし)
torch.nn.ModuleListTransformer ブロックを層数ぶん並べる
torch.nn.init.normal_ ×3重みの初期化(標準偏差 0.02。残差に足し込む射影は層数に応じて小さく)
torch.nn.functional.scaled_dot_product_attention因果マスクつきの注意計算
torch.nn.functional.siluSwiGLU の活性化関数
torch.nn.functional.cross_entropy次トークン予測の損失
torch.nn.functional.softmax生成時に logits を確率へ
torch.utils.checkpoint.checkpointLM Head + 損失を小分けにし、逆伝播のときに再計算する(logits を持ち続けないため。12GB の VRAM に収める)
torch.ones / torch.zeros_likeRMSNorm の初期値 / top-p で確率を並べ直す入れ物
torch.arange ×2・torch.outerRoPE の周波数表(位置 × 周波数)
torch.rsqrtRMSNorm の逆平方根
torch.cat ×2RoPE で回転させた前半・後半の結合 / 生成したトークンの連結
torch.multinomial生成時のサンプリング
torch.no_grad(デコレータ)生成中は勾配を計算しない

主なテンソルのメソッド:

メソッド用途
.view・.transpose・.contiguous・.reshapehead への分割と結合、損失計算のための形の変更
.split・.chunkQ/K/V の切り分け、RoPE の前半・後半、損失の小分け
.float・.type_asfp32 に上げて計算し、元の型(bf16)に戻す
.pow・.mean・.cos・.sin・.unsqueezeRMSNorm と RoPE の計算
.sort・.cumsum・.scatter_・.argmax・.sum・.alltop-p の打ち切り、貪欲選択、終了判定
.new_zeros・.numel損失の合計の入れ物、パラメータ数・トークン数

nn.Module のメソッド: .apply(初期化を全層に適用)、.named_parameters・.parameters。

2-3. data.py — 学習バッチの作成と評価

呼び出し用途
torch.from_numpy ×3シャードから切り出したトークン列をテンソルにする
torch.stack ×2入力(x)と正解(y = 1 つ先のトークン)をバッチにまとめる
torch.zeros ×2言語別の損失の合計と個数を入れる入れ物(fp64)
torch.autocast評価時の bf16 混合精度
torch.nn.functional.cross_entropyトークンごとの損失(reduction="none"。言語別に集計するため)
torch.exp ×2平均損失をパープレキシティに変換
torch.no_grad(デコレータ)評価中は勾配を計算しない

主なメソッド: テンソルの .to(device)(GPU への転送)・.reshape・.sum・.numel、モデルの .eval・.train(評価と学習の切り替え)。

シャードのどこから切り出すかの選び方(トークン数に比例してシャードを選び、無作為な位置から ctx+1 個)と、 EOS を数えてトークンごとの言語を求める処理は自前のロジック。

2-4. train.py — 学習ループ

呼び出し用途
torch.optim.AdamW最適化(β 0.9 / 0.95、weight decay 0.1。CUDA では fused 実装)
torch.autocastbf16 混合精度(CUDA のとき)
torch.nn.utils.clip_grad_norm_勾配クリップ(上限 1.0)。返り値の勾配ノルムをログに残す
torch.save・torch.loadチェックポイントの保存と再開(モデルの重み・最適化の状態・ステップ数)
torch.manual_seed乱数の種の固定(初期化の再現性)
torch.device・torch.cuda.is_availableCUDA があれば使う

主なメソッド:

メソッド用途
loss.backward()自動微分(全パラメータの勾配を求める)
opt.step()・opt.zero_grad()パラメータの更新、勾配の初期化
opt.state_dict()・opt.load_state_dict()最適化の状態の保存と復元
model.to(device)・model.train()・model.state_dict()・model.load_state_dict()GPU への配置、学習モード、重みの保存と復元
.item()損失を数値として取り出す(ログ用)
p.dim()weight decay をかける対象の判定(2 次元以上の重みだけ)

学習率のスケジュール(線形ウォームアップ → cosine 減衰、最終は 10%)は、PyTorch のスケジューラを使わず自前の式で書いている。

2-5. eval.py / sample.py

ファイル呼び出し用途
eval.pytorch.load・torch.device・torch.cuda.is_availableチェックポイントを読み、val / test の言語別パープレキシティを出す(計算は data.py の評価を使う)
sample.pysentencepiece.SentencePieceProcessor48k モデルの読み込み
sample.py.encode・.bos_id / .decodeプロンプトをトークン列に / 生成したトークン列を文章に戻す
sample.pytorch.tensor・torch.manual_seed・torch.device・torch.cuda.is_availableプロンプトをテンソルに、サンプリングの乱数の固定

config.py(S / M / L の構成の定義)と fetch_shards.py(API からのシャード取得)には、LLM 学習に直接かかわる基盤の呼び出しはない。


3. まとめ

モジュール基盤基盤に任せている中核自前で書いている中核
zxell_prep/SentencePieceBPE の学習、エンコード、デコード学習ファイルの配分、正規化、重複除去、言語別の分割、シャッフル、シャード化、検証
zxell_model/PyTorch(+ 生成時のみ SentencePiece)テンソル演算、自動微分、AdamW、注意の中核計算、交差エントロピー、混合精度モデルの構造(RMSNorm・RoPE・SwiGLU・ブロック・重み共有)、学習率スケジュール、バッチの作り方、言語別評価、生成(top-p)

「イチから」の観点で基盤への依存がいちばん大きいのは 2 か所:

  1. トークナイザの学習(SentencePieceTrainer.train)。review10 で決めたこと。
  2. 注意の中核計算(F.scaled_dot_product_attention)。Q・K・V の射影や RoPE は自前だが、softmax(QKᵀ/√d)V と因果マスクは PyTorch の実装。同じ計算を自前の数行(行列積 + マスク + softmax)に置き換えられるが、速度とメモリで不利になる。