review23: zxell_model/ 完成(S/M/L モデル本体・学習・評価・生成・API 取得、CPU スモーク合格)/ RTX 3060 機のセットアップ手順(ドライバ導入から学習開始まで)
作成日: 2026-09-29 対象: review22 確認事項へのご回答(1: 順序 OK / 2: (省略: 接続方法)3060 機は nvidia-smi 不可 → ドライバ手順が必要)を受けた実施報告と、 3060 機で S ベースライン学習を始めるまでの手順書。
要旨
- モデル本体と学習・評価コードを
zxell_model/として実装・コミット済み(23a4c97、e2e 修正 1 件追加)。パラメータ数は roadmap どおり S 29.1M / M 121.8M / L 537M。サーバ機(CPU)で tiny 構成のスモーク(学習 → 再開 → 言語別 PPL 評価 → 生成)が一気通貫で合格(2〜3 章) - シャードの配布経路(API)も実証済み:
fetch_shards.pyがGET /api/shards/{name}で取得し sha256 を照合。 (省略: LAN 内での接続方法)(4 章) - 3060 機の手順書(5 章): NVIDIA ドライバ → PyTorch(CUDA)→ クライアント登録・承認 → シャード取得 → S 学習開始。所要はドライバ再起動込みで 30 分ほど、学習は 約 1 日(2.9B トークン)の見込み
1. zxell_model/ の構成
| ファイル | 内容 |
|---|---|
config.py | S / M / L / tiny の構成。語彙 48k、埋め込みと LM Head の重み共有 |
model.py | RMSNorm(Pre-Norm)・RoPE・causal Self-Attention(PyTorch の SDPA)・SwiGLU FFN・GPT 本体・素朴な生成(top-p) |
data.py | シャード(uint16・記事間 EOS)のメモリマップ読み込み。学習サンプラ(トークン数比例でシャード選択 → ランダム位置)。言語別パープレキシティ評価 |
train.py | 学習ループ: AdamW(β 0.9/0.95, wd 0.1)・線形 warmup → cosine(最終 10%)・勾配クリップ 1.0・CUDA では bf16・チェックポイント/再開・定期 val 評価・jsonl ログ |
eval.py | チェックポイントの val / test 言語別 PPL(JSON 出力) |
sample.py | チェックポイントからの文章生成(sentencepiece で復号) |
fetch_shards.py | コーディネータ API からシャード取得(index → .bin / .json / .langs.u8、sha256 照合、済みは飛ばす) |
構成は model_architecture.drawio と一致(model_inference.drawio の KV キャッシュは未実装 — フェーズ 4 のデモ用途で必要になったら足す)。
| preset | 層 / d_model / head / ctx | パラメータ | うち非埋め込み |
|---|---|---|---|
| tiny | 2 / 64 / 2 / 128 | 3.2M | 0.1M |
| S | 6 / 384 / 6 / 1024 | 29.1M | 10.6M |
| M | 12 / 768 / 12 / 1024 | 121.8M | 85.0M |
| L | 24 / 1280 / 20 / 2048 | 537.3M | 475.9M |
S は 29.1M のうち 18.4M(63%)が埋め込み(48k × 384)です — review22 2 章で述べた「48k でも S では埋め込みが大半」の実数です。
言語別パープレキシティの仕組み
val / test シャードは走査順(シャッフルなし)なので、記事 i の言語は langs_{split}.u8(tokenize_full.py の中間ファイル)の i 番目です。これを val_000.langs.u8 / test_000.langs.u8 としてシャード横に置きました(記事数 11,129 / 30,171 がメタと一致することを確認)。評価時は EOS の累積で「このトークンは何番目の記事か」を求めて言語を割り当て、言語ごとに損失を集計します。 fetch_shards.py はこの副ファイルも取得します(無ければ全体 PPL のみ)。
2. CPU スモーク(サーバ機・torch 2.14 CPU 版・Python 3.14)
tiny 構成・train シャード 1 個・batch 4・ctx 128:
| 段階 | 結果 |
|---|---|
| 学習 50 ステップ | loss 10.55 → 10.11(初期値 ln 48000 = 10.78 から下降開始)。約 2,100 トークン/秒(CPU) |
| 途中評価(step 25) | val 先頭 2 万トークンで PPL 31,616 → step 50 で 25,372 |
| チェックポイント再開 | --resume で step 50 から 60 まで継続、評価値が連続(24,416) |
eval.py | 言語別集計が動作(val 先頭 2 万トークンは fr のみ = val が走査順で仏語から始まるため。全量なら 4 言語) |
sample.py | 生成が動作(60 ステップの tiny なので中身はでたらめ — 想定どおり) |
数値そのものに意味はなく、「配管がつながっている」ことの確認です。1 つ設計上の修正: 最終評価が val 全量(1,020 万トークン)を舐める仕様は CPU では数十分かかるため、--final-eval-tokens で上限を指定できるようにしました(GPU では全量のまま)。
3. 3060 機での S ベースラインの見込み
| 項目 | 値 |
|---|---|
| ステップあたり | batch 32 × ctx 1024 = 32,768 トークン |
| 目標トークン数 | roadmap 3.3 の S: 3B → 90,000 ステップ ≈ 2.95B トークン(train 6.07B の約半分 = 1 エポック未満) |
| 3060 の処理速度(見込み) | 約 35,000〜40,000 トークン/秒(bf16、実測で更新) |
| 所要 | 約 21〜24 時間 |
| VRAM | S は重み+勾配+optimizer で 0.5GB 程度 + 活性化。12GB には余裕(batch 32 で数 GB) |
| チェックポイント | 1,000 ステップごとに ckpt_last.pt(上書き)、終了時 ckpt_final.pt。約 350MB |
途中評価は 500 ステップごとに val 先頭 100 万トークン(言語別 PPL 込み)、終了時に val 全量。
4. シャードの配布経路(API)の実証
fetch_shards.py をサーバ自身から実行し、既存クライアント(GTX 1050 機、承認済み)の API キーで val シャードを取得 → sha256 一致を確認しました。
5. RTX 3060 機のセットアップ手順(上から順に、すべて 3060 機で実行)
5-2. リポジトリと PyTorch(CUDA 版)
# (省略: パッケージの導入)
git clone https://github.com/zxell-ai/zxell.git ~/zxell # 公開リポジトリなので鍵不要
cd ~/zxell/zxell_model
python3 -m venv .venv && . .venv/bin/activate
pip install --index-url https://download.pytorch.org/whl/cu128 torch
pip install numpy sentencepiece
python -c "import torch; print(torch.__version__, torch.cuda.is_available(), torch.cuda.get_device_name(0))"
最後の行が True GeForce RTX 3060 を出せば OK。cu128 はドライバの CUDA 12.x 対応が前提です(nvidia-smi 右上の CUDA Version が 12.8 以上なら可。古ければ cu126 を指定)。
5-5. 短い動作確認(1〜2 分)→ 本番開始(約 1 日)
# 動作確認: S 構成で 30 ステップ(GPU が使われ、tok_per_s が数万出ることを見る)
python train.py --preset S --shards ~/zxell-shards --out runs/S_check --steps 30 --eval-every 30 --final-eval-tokens 200000 --warmup 5
# 本番: SSH が切れても続くよう tmux(または nohup)の中で
tmux new -s zxell
python train.py --preset S --shards ~/zxell-shards --out runs/S_baseline --steps 90000 2>&1 | tee runs/S_baseline/stdout.log
# (Ctrl-b d で tmux から抜ける。戻るときは tmux attach -t zxell)
途中で止まった/止めた場合は同じコマンドに --resume runs/S_baseline/ckpt_last.pt を足せば続きから再開します。
5-6. 様子の見方
tail -f runs/S_baseline/log.jsonl # loss / lr / grad_norm / tok_per_s、500 ステップごとに val の言語別 PPL
python eval.py runs/S_baseline/ckpt_last.pt ~/zxell-shards val --max-tokens 1000000 # 途中経過の PPL
python sample.py runs/S_baseline/ckpt_last.pt --sp <sp_bpe_48k.model のパス> --prompt "The central bank"
sp_bpe_48k.model(1MB)はサーバから取得します。(省略: 取得元と取得方法)
6. 確認事項
- 3060 機の情報:
lsb_release -ds(Ubuntu の版)とmokutil --sb-state(Secure Boot の有無)の結果を教えてください。手順 5-1 の分岐(MOK 登録の要否)がこれで決まります。分からなければ 5-1 をそのまま進めて、画面の出方で判断できます。
- 学習のハイパーパラメータ(3 章)は nanoGPT 系の定番値(lr 6e-4、batch 32×1024、90k ステップ)です。異論がなければこれで最初のベースラインを取り、結果を見て調整します。
7. 次の作業予定
- 5-1〜5-5 のセットアップ(お客様側の作業 + 承認)→ S ベースライン学習開始(約 1 日)
- 学習中: 損失曲線と言語別 PPL の推移を
log.jsonlから可視化するスクリプト、ダッシュボードへの「学習状況」表示の設計 - 学習後: test の言語別 PPL・生成サンプルの目視 → フェーズ 1 の完了判定(「S がまともな文を生成し、評価が自動で回る」)→ review で報告
- フェーズ 2 準備: クライアント v1 の
trainタスクを本物の局所学習(このzxell_modelを呼ぶ)に置き換える設計、1050 向けのトークン範囲タスク
zxell.ai