intel-mac-local-llm / source /EXPERIMENTS.md
miutti's picture
Source: kernel, desktop app, tools (snapshot of the GitHub repo)
df41178 verified
|
Raw History Blame Contribute Delete
7.97 kB
# `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件だけ**でした。