p-kernel の中では小さな言語モデルを育てていて、ログでは「赤子」と呼んでいる。行列の重みが190万個くらいで、fp32 で7.6MB。脳と呼ぶにはおもちゃの大きさです。
これを賢くする方向の研究も、夜間開発に少しずつやらせている。順番はだいたい決まっていて、論文を原文で読んでメモにする → p-kernel のどこに入れるか決める → 「効いた」と言える条件を先に決めてから測る、の流れ。今週はこの結果がいくつか出たのでメモしておく。
■量子化
重みの桁を減らしてモデルを小さくするやつ。量子化のホワイトペーパー、GPTQ、LLM.int8()、AWQ あたりを読んだ。論文から拾ったのは「目盛りを行ごとに取るか全体で取るかが一番効く」「小さいモデルほど壊れやすい」の2つ。
赤子で試した結果。元の損失 3.2258 からどれだけ増えたか。
int8 行ごと +0.0003 int4 行ごと -0.0213 int2 32個ごと +0.0912 int2 行列全体 +1.3948
int8 だとほぼ変わらなくて、2bit で行列全体を1つの目盛りにすると壊れる。ここまでは論文どおり。
int4 で損失が下がっていたので、最初は「量子化したらかえって良くなった」と書いていた。これが監査で崩れた。乱数の種や学習データを変えると -0.021 から +0.017 まで符号が変わる。ただの雑音の幅でした。
※夜間開発では、作った回と別の回が監査する決まりにしている。疑う役がいなかったら、これがそのまま成果として残っていたはず。
■合体
2つのモデルの重みを平均して1つにする話。群れの端末がそれぞれ学んだことを1つにまとめたいので、p-kernel にとっては大事なところ。Sakana AI の進化的な合体、TIES、DARE、それと Linear Mode Connectivity の論文を読んだ。
最後の論文によると、同じ出発点から別々に学習した2体を直線で結ぶと、途中で損失の山ができる。ただ、学習率を途中で下げていけば、早めに分かれた2体なら山は消えるらしい。
第1段では、赤子の2体のあいだにもやっぱり山があった(0.375)。第2段で学習率の計画だけ変えてみたら、山はかえって高くなった(0.42〜0.70)。消えた組もあるにはあったけど、2体がほとんど動いていない組だけ。離れたまま平均できる組はひとつも無かった。
なので「そのまま重みを平均する」道はここで閉じた。次は蒸留(重みではなく出力で知識を渡すやり方)にする予定。監査では「データ1つ・種1つでしか測っていない」と結論の書き方を狭められた。重みの並びを揃えてから平均する re-basin はまだ試していない。
■副産物
同じ実験で、学習率を下げていくと親そのものの損失が 2.19 → 1.43 に下がった。合体とは関係ないところで、今週いちばん良い数字が出ている…。今の赤子はどこも学習率が一定なので効くかもしれない。でも小さいデータだけの話かもしれないので、確かめるまでは保留。
■10/4 に読んだもの
BitDelta と DARE。群れで共有している重みは、今は世代ごとに全部送っている。でも受け手は前の世代を持っているので、差分だけ送れば足りる。差分を行列ごとに「符号1ビット+大きさ1個」にすると、86KB が 2.7KB くらいになる見込み。
DARE の論文によると、差が小さいときしか効かない。なのでまず差の大きさを測るところから。実装はまだ。
■ほか
RNG0 を、ベアメタルの x86 と AArch64 で直した。カーネルを呼ばずに回り続けるタスクがいると、ほかのタスクに切り替わらない不具合。Linux の上で動く版も作ったけど、途中で原因を2回取り違えて、結局スタックが128バイトずれていただけ。自分のバグでした。これは監査待ち。
週の使用量の枠は98%で締まって、9/30〜10/3 は夜間開発がほぼ止まっていた。
「小さいモデルが賢くなった」という結果は、まだひとつも出ていない。丸暗記しているだけか、本当に覚えたかを見分ける試験も、2週続けて手つかずのまま。
※リポジトリ: https://github.com/monyuonyu/p-kernel
※この記事は、p-kernel の開発を手伝ってもらっている AI(Claude)と一緒に書いています。