はじめに
📝 この記事は note にも投稿しています。
Mac Studio(M2)で、コード生成とテスト生成をローカル LLM に任せている。以前、その担当を Qwen2.5-Coder-7B から入れ替える候補として、JetBrains の Mellum2-12B-A2.5B-Instruct(Apache 2.0)を試した。全体は12B、1トークンごとに使うのは2.5Bぶんの MoE で、速さは7B並みが見込める。
最初に動かした mlx-community/Mellum2-12B-A2.5B-Instruct-4bit は、コード4題のうち1題しか通らなかった。現行の Coder-7B より悪い。ここで止めていれば「Mellum2 は使えない」と判断するところだった。量子化を変えて測り直すと、同じモデルの 6bit は4題とも通った。
測り方
- mlx-lm は GitHub main(0.32.0)。PyPI の 0.31.3 には
mellumのアーキテクチャがまだ入っていなかった - 本体の環境は触らず、使い捨ての venv を作って、比べるモデルは全部同じ venv で動かした
- system prompt は実運用の設定そのまま。生成はチャットテンプレート+貪欲法。依頼文は日本語
- 採点は機械で行った
- code 4題: 生成したコードに隠しテストを流して合否
- test 3題: 生成したテストを、①正しい実装に流す(落ちたら誤った assertion)、②1行だけバグを入れた実装に流す(落ちたらバグ検出)
- 落ちたものは全件、生の出力を開いて、コードの抜き出し側のミスでないことを確かめた
結果
| ビルド | ディスク | ピークメモリ | code 合格 | test 誤った assertion | test バグ検出 |
|---|---|---|---|---|---|
| Qwen2.5-Coder-7B-4bit(現行) | 4.0GB | 4.64GB | 3/4 | 1件+1題が反復ループで打ち切り | 2/3 |
| Mellum2 4bit | 6.8GB | 7.2GB | 1/4 | 3件 | 1/3 |
| Mellum2 4bit+推奨サンプリング ×3 seed | 同 | 同 | 1/4(3 seed とも) | 3〜4件 | 1/3 |
| Mellum2 mxfp4 | 6.0GB | 6.82GB | 3/4 | 3件 | 3/3 |
| Mellum2 6bit | 9.2GB | 10.19GB | 4/4 | 1件 | 3/3 |
| Mellum2 8bit | 12GB | 13.19GB | 4/4 | 3件 | 3/3 |
推奨サンプリングは temperature 0.6 / top_p 0.95 / top_k 20。
4bit だけが際立って悪い。6bit と 8bit は code を全問通している。mxfp4 は 4bit 相当のサイズでも 3/4 まで戻った。
4bit の壊れ方
4bit の失敗には、モデルの実力では説明しにくいものが混ざっていた。
-
merged.append(current)]のような、閉じ括弧が1つ余計な構文エラー - LRUCache の論理バグ
- テストの期待値に
[[1,1],[[2,2],[3,3]]]のような、入れ子の崩れた値
これだけなら、サンプリングの揺れかもしれない。そこで推奨サンプリングに替え、seed を3つ変えて流した。3 seed とも、同じ箇所で、同じトークン数で壊れた。 乱数を変えても壊れ方が変わらないので、確率の揺れではなく、量子化した重みそのものが崩れていると判断した。
mlx-lm 側の mellum 実装は、追加されたあと生成結果に影響する修正が入っておらず、関連する issue も見当たらなかった。実装のバグなら 6bit/8bit も同じように壊れるはずで、そうなっていない。
4bit だけで判定していたら
最初の 4bit の結果だけで見ると、Mellum2 は現行の Coder-7B(3/4)より悪い 1/4 だった。この時点で比較を終えていれば、「新しいけど使えないモデル」として外していた。
6bit で測り直した結果、code・test とも現行を上回ったので、担当を入れ替えた。代わりに払ったものは2つある。
- ピークメモリが 4.6GB → 10.2GB
- mlx-lm を GitHub main のコミットに固定する必要がある(PyPI 版に
mellumが無いため)
入れ替え後、ルータ経由で全17タスクを流し直し、全部終了コード0で終わることを確かめた。7題という小さな標本での比較なので、差の大きさは参考程度に見ている。
新しいモデルを試すときの順番
いまは次の順で見ている。
- 単純な構文エラーのように、モデルの格に合わない失敗が出たら、まず量子化を疑う
- seed を変えて同じ箇所で壊れるなら、揺れではなく重みの劣化と見る
- 却下の前に、6bit か mxfp4 を1つ試す
- サイズとメモリの比較は「そのモデルが正常に動く一番小さい量子化」どうしで行う
4bit は、Mellum2 のビルドの中でディスクもメモリも小さく、最初に試したくなるビルドだった。それがモデルの評価をいちばん大きく外していた。
小さいほうから試すのは、手間を省くためだった。その最初の1つが、モデルの実力でなく変換の結果を見せていた。