# `experiments/` と `lib/` の状態について(正直に) > 別のAIに `lib/` と `experiments/` を精査させたら **91件**の指摘が返ってきました。 > 全部は直していません。**なぜ直さないか**と、**何を直したか**を書きます。 --- ## 1. これは「ライブラリ」ではなく「記録」です `lib/` と `experiments/` は、**1回走らせて数字を取ったきりのコード**です。 保守しているライブラリではありません。実験の記録として置いてあります。 だから: - **そのままでは動きません。** モデルの重み(数GB)や較正データが要りますが、 それらはリポジトリに入っていません(`.gitignore`)。 - 環境変数で場所を差し替えられるようにはしました (`MODEL_BLOB` / `LOCALAI_ROOT` / `KERNEL_DIR`)。 - **`experiments/28`〜`52` のコードは入っていません。** `RESULTS.md` は実験52まで書いてありますが、コードは27までです。 - **`tools/gguf/prune_experts.py`(モデルを作った当の道具)も入っていません。** この README の主張(考える深さの効果)を再現するのに必要なものは `monosashi/` と `kangaeru_fukasa.py` に全部あります。足りていないのは圧縮研究の側です。 --- ## 2. 指摘を仕分けた結果 22件を実物に当たって確かめ、**16件が当たり、6件が外れ**でした。 ### ★ 外れていたもの(そのまま直すと壊していました) | 指摘 | 実物では | |---|---| | `distill.py` 末尾232列が最適化されない(重大度 高) | **外れ。** 実際に走らせたら **1000列すべて**変わりました | | `02_entropy` の bpw 換算で `k` で割っていない(重大度 高) | **外れ。** 関数の外(68〜71行)で **全部 `/ k` している** | | `e8.py` の1D配列で IndexError(重大度 高) | **再現せず。** 指摘のコードが実物と合っていません | | `14_trellis` のスケールが8bitで不公平 | **外れ。** 該当の書き方が見当たりません | | `07` が `05` のコピペ | **外れ。** `lowrank_cost` を持っていません | | `/path/to/…` が決め打ちでクラッシュ(重大度 高・3件) | **半分は私のせい。** 元は実在するパスで、**個人情報を消すために私が置き換えた**もの。指摘としては正しいので、環境変数で差し替えられるようにしました | ★ **「重大度 高」と付いていても、走らせれば消えるものが混ざっています。** 指摘をそのまま信じて直していたら、動いていたものを壊していました。 ### ★ 当たっていたもの(直しました) | どこ | 何が壊れていたか | 直し方 | |---|---|---| | `lib/rotate.py` | `inverse` の説明が**逆**(`False`→Qᵀ、`True`→Q) | **説明の方**を直した。往復は正しく元に戻るので**過去の結果は1ビットも変わりません** | | `lib/entropy.py` | `ncode` が大きいと `ncode×ncode` の表でメモリが尽きる(2¹⁶で数十GB) | 大きすぎたら断る | | `lib/entropy.py` | グループの最後と次の先頭を**つながっていると数える** | 注記した(短いグループを大量に渡すときは別々に呼ぶ) | | `lib/distill.py` | 収束判定が単調減少前提。**誤差が増えたときも「収束」と誤判定**していた | 減ったときだけ見る | | `lib/brecq.py` | `LinAlgError` を黙って握りつぶし、**補正が効いたように見えていた** | 必ず知らせる | | `lib/council.py` | `nv` のパス決め打ち/`with` なし/異常終了を無視 | PATH も見る/`with`/異常終了を知らせる | | `05_lowrank`, `07` | bpw に**スケールの取り分(16/G)が入っていなかった** | 下に詳しく | | `12_realact` | `imat` に0があると `log(0)` で**以降すべて NaN** | 下限で押さえる | | `17_gptq_real` | わずかな非正定値で `cholesky` が落ちる | 対角に少しずつ足して押し戻す | | `21_sweep` | PPL が読めないと `None` を返し、並べ替えで落ちる | `inf` を返す | | `23_alloc` | λ が負の層を**黙って捨てて既定値に落ちていた** | 捨てた数を数える | | `01_subbit` | 3つの基準が全部「基準」という名前 | 8bit/4bit/2bit に分けた | --- ## 3. `05_lowrank` の欠陥 ── 数字はどれだけ狂っていたか いちばん結論に響きうる指摘だったので、実際に計算しました。 もとの式は `r*(out+inn)*bits/(out*inn)` だけで、**A と B を量子化したときの グループごとのスケール(16bit)が入っていません**。 | ランク | いままでの値 | 正しい値 | 差 | |---|---|---|---| | 16 | 0.0625 | 0.0669 | +7.0% | | 32 | 0.1250 | 0.1299 | +3.9% | | 64 | 0.2500 | 0.2559 | +2.3% | | 128 | 0.5000 | 0.5078 | +1.6% | **低ランク側だけを見ると 1.6〜7.0% 少なく出ていました。** ただし全体の bpw は「低ランク側+残差(PVQ)側」の合計で、**残差側が支配的**です。 記録されている実際の値で計算すると: | | 記録された bpw | 正しくは | |---|---|---| | ランク16 | 0.781 | 0.786(**+0.6%**) | | ランク32 | 0.938 | 0.942(**+0.5%**) | → **合計では 0.5〜0.6%。結論はひっくり返りません。** 式は直しましたが、`results/` の JSON は**直す前の値のまま**です。 --- ## 4. 直していないもの 以下は「そのとおりだが、記録としては直す価値が薄い」と判断しました。 - 合成データで手法を評価している(`01`, `06` ほか) → **この指摘は正しく、しかも私たち自身が後で気づいたこと**です。 `RESULTS.md` と `README.md` の「効かなかったこと」に、 「合成データで手法を評価してはいけない(手法の優劣が反転する)」として **教訓のかたちで残してあります。** 当時のコードはその失敗の記録なので、 直すと記録でなくなります。 - `N=1` の評価、8シードでの t 検定、統計的検出力の不足(`11`, `16` ほか) → **そのとおりです。** 当時の数字は「傾向」として読んでください。 - `10_pushdown` が SwiGLU/RMSNorm をまたぐ線形結合で理論的に破綻 → **そのとおりで、実験は失敗として記録されています。** - `19_full_unified` の OOM → **コード自身の冒頭注記が既に認めています**(だから `quantize2.py` がある)。 - `26_brecq` の事前検証(6ブロック)で合格→全層で崩壊 → **`RESULTS.md` に失敗として記録済み**です。指摘のとおり、 小さく試して通ったことを全体の保証にしてはいけません。 - コードの重複、`assert` の使用、リソースリークなどの作法 → 記録の読みやすさに影響しないので触っていません。 --- ## 5. この経験からの教訓 **レビューを受けたら、指摘の仕分けが本体です。** - 91件のうち、実物に当たれたのは22件。そのうち **6件が外れ**(3割弱)。 - とくに「重大度 高」でも、**走らせれば消えるもの**がありました (`distill.py` は実際に走らせれば1000列すべて変わると1分で分かります)。 - **読んだだけの指摘と、走らせた指摘は、重みが違います。** - そして今回、**指摘の一部は私自身が作り込んだもの**でした (個人情報を消すためにパスを書き換えた結果)。 前に別の実験でも同じ結論が出ています —— 多モデルで粗探しをして合意した上位8件を実物で確かめたら、**本物は2件だけ**でした。