1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

honest disclosure 総集編 — 測り方を疑い、構造で勝ち、負けを見せ、技術の外へ(llcore 連載 S/A/B/C アーク・#45)

1
Last updated at Posted at 2026-06-27

honest disclosure 総集編 — 測り方を疑い、構造で勝ち、負けを見せ、技術の外へ

この記事について(#45・非公開アーカイブ)
本記事は、GPU を持たない自宅のノート PC(CPU のみ)で動かす超小型 LLM 実験箱 llcorehonest disclosure 連載を 1 本に集約した総集編です。連載は個別記事として 48 本(技術版 16 + 一般版 16 + 多言語アーク 16)に展開しましたが、本アーカイブはそのうち 技術版を 4 つのアーク(S / A / B / C)に圧縮した版を、フルテキストで束ねたものです。

既に公開済みの #44「AIは平気で嘘をつく」が連載全体のダイジェストだとすれば、本 #45 は 各章を 1 本ずつ深掘りしたフルテキストにあたります。現時点では 非公開(限定共有・ignorePublish とし、公開可否・公開単位(総集編のまま出すか、アーク単位で出すか)は別途判断します。

はじめに — 4 つのアークの地図

この総集編は、1 つの規律を 4 つの角度から実演します。規律の名前は honest disclosure(正直な開示)——「異常に良い結果が出たら、勝った気になる前に必ず内訳を疑う」という、自分の成果にこそ刃を向ける態度です。

  • S アーク|測り方を疑う … 1 個のスコアがどう人を欺くか。PPL ゲートが壊れた 2bit モデルに合格証を出した実演(s1)と、「proprietary 超え」を見抜く cherry-pick の 5 型(s2)。
  • A アーク|構造で勝つ … bit を下げるのではなく構造を攻める。定数状態と制御理論(a7)、文脈 4 倍でメモリ 5 倍(a8)、支配項を測れ=Rust の前に計測(a9)、flaky テストは設計の臭い(a11)。
  • B アーク|負けを見せる … 7 つの「良い負け」(b1〜b7)。自分を止める審判、自慢の撤回、AI レビュアーとの対決、冗長になった安全ゲート——負けこそ信用の材料になる。
  • C アーク|技術の外の支配項 … コードの外側で勝敗を決める力。open weights ライセンスの 3 分裂(c1)、責任ある自己成長(c2)、ドメイン横断の記憶部品(c3)。

S で「測る規律」を立て、A で「構造で勝つ技術」を示し、B で「負けを開示する勇気」を見せ、C で「技術の外へ」視野を広げる——この順序自体が 1 本の物語です。

共有の前提(重複を避けるため、最初に一度だけ)

各アークは独立記事として書かれたため、本来は各々が同じ前提を説明していました。総集編ではそれをここで一度だけ束ねます。

  • llcore … 自宅 CPU で動かす超小型 LM の実験箱。「同じ賢さを、より少ないメモリで」を北極星に、量子化・定数状態アテンション・線形化を試す。
  • PPL(perplexity) … モデルが次の単語にどれだけ「驚いた」か。低いほど良い。「平均して何択で迷っているか」に近い。
  • top-1 当たり率 … 最有力候補がドンピシャで当たる率。PPL が分布全体のなだらかさを見る鈍い指標なのに対し、top-1 は「1 位が正解か」を切り取る鋭い指標。
  • 定数状態アテンション … 文脈が伸びても記憶(メモリ)が一定に保たれる仕組み。通常の Transformer は KV キャッシュが文脈長に比例して膨らむ(O(T))が、recurrent / 線形化は状態を有限サイズに畳む(O(1))。
  • honest disclosure … 失敗や留保を消さず、主張を最小限に絞り、一般論へ膨らませない態度。本連載の背骨。

連載共通の caveat(必ず先に読んでください)
全 llcore 実測は 自宅 CPU の極小モデル(0.81M〜130M の char-LM、および 0.5B / 1.5B の小型 instruct)PoC であり、大手の実 LLM(12B〜数百 B)性能を直接反証・凌駕するものではありません。比較は一貫して 手法・思想・計測規律の次元 で行います。量子化の footprint(メモリ使用量)は実測ですが、一部は simulated quant(疑似量子化)で推論速度は未測の箇所があります。競合数値(PaddleOCR-VL / OmniDocBench 等)は self-report ラベルであり、測定対象が異なるため数値の大小は比較不能です。

S アーク — 測り方を疑う(単一スコアの罠と「超えた」の解剖学)

連載「自宅 CPU から見た 2026 年 6 月の LLM 業界」第 1 部。

緑のチェックマークが出た。「このモデルは使える」とシステムは判定した。ところが同じモデルの「次の 1 文字をズバリ当てる正解率」を測ると、ほぼ半減していた。能力が崩れ落ちていたのに、検査は「合格」と言った——これが、本連載の出発点です。

このアークのテーマは派手な新手法ではありません。「1 個の数字を信じすぎると、何を見落とすか」——これを、まず自分の手元の失敗で正直に解剖し(第 I 部)、次に業界の「○○超え」ニュースが同じ穴をどう使っているかの分類学に広げ(第 II 部)、最後にその刃を自分自身へ向け直す(自己監査)。測り方を疑う規律こそが、この連載全体の土台です。だからこそ次のアークで、私たちは堂々と「負けを見せる」ことができる。


本連載の caveat(必ず先に読んでください)

本連載の全 llcore 実測は、自宅 CPU の極小モデル(0.81M〜130M パラメータの char-LM=文字単位の言語モデル)PoC であり、大手の実 LLM(12B〜64B)性能を直接反証・凌駕するものではありません。比較は手法・思想・計測規律の次元で行います。量子化の数値は footprint(メモリ使用量・常駐バイト数)= 実測ですが、simulated quant(疑似量子化)であり、推論速度は一切未測です。

この但し書きを冒頭に置くのは、後半で大手モデルの公開スコアと「同じ構造の罠」として並べるからです。数値の大小を比べているのではなく、評価のやり方の形(フォルム)を比べている——この一点だけは、読み終わるまで握っておいてください。


第 I 部 — PPL が PASS でも、モデルは半分壊れていた

1. 発端:メモリ効率を追っていたら、別の崖が見えた

llcore(自宅 CPU で動かす超小型 LM の実験箱)で、いま追っている北極星はメモリ効率です。同じ賢さを、より少ないメモリで。その手段の王道が量子化——モデルの重みを fp32(32bit 浮動小数点)から、8bit / 4bit / 3bit / 2bit と、ビット幅を削って表現することです。

量子化(quantization, クオンタイゼーション) モデルの重みを fp32(32bit 浮動小数点)など高精度の数から、8bit・4bit・2bit と少ないビット幅で表現し直すこと。高解像度の写真を少ない色数で保存して容量を減らすのに似て、ビットを削るほどメモリは減るが、削りすぎると絵(=精度)が荒れる。

ビット幅を半分にすればメモリも概ね半分。footprint だけ見れば一直線に「お得」です。ですが当然、削りすぎれば精度は落ちる。どこまで削ってよいかを機械的に判定したい。そこで「品質ゲート」を設けました。

最初に置いたゲートはシンプルでした。

Perplexity(PPL)が、unigram ベースライン(語の出現頻度だけで予測する最弱モデル)の 0.85 倍を下回っていれば PASS。

ここで連載を通して何度も出てくる Perplexity(PPL) を一度だけ丁寧に説明します。PPL は「モデルが次の単語にどれだけ驚いたか」を表す指標で、低いほど良い。直感的には「平均して何択で迷っているか」に近い。unigram の PPL は、文脈をまったく使わない最弱の予測者の数字なので、**それを大きく下回れない量子化モデルは『文脈を読む力を失った』**と見なして落とす——理屈は通っています。

Perplexity(PPL, パープレキシティ) 「モデルが次の 1 文字/単語にどれだけ驚いたか」を表す指標で、低いほど良い。平均して何択で迷っているかの目安で、PPL が 100 なら「毎回ざっくり 100 択で迷っている」くらいの当てづらさをイメージするとよい。

このゲートに、各ビット幅の量子化モデルを通していきました。realp1 と呼んでいる 11.9M パラメータの char-LM が題材です。そして 2bit の番が来たとき、事前の予想が外れました


2. 事前予想と、外れ方

実験前、私の頭の中にはこういう仮説がありました。

「PPL(平均的な驚き)はそこそこ保たれていても、top-1 当たり率(最有力候補がドンピシャで当たる率)の方が先に崩れるだろう。なぜなら PPL は分布全体のなだらかさを見るので鈍く、top-1 は『1 位が正解か』という鋭い判定だから、壊れが早く出るはずだ。」

ここで top-1(連載を通して使う、もう 1 つの基礎用語)を抑えておきます。top-1 当たり率は「モデルが一番自信を持って出した候補が、実際の正解とドンピシャで一致した割合」。10 文字に 3 文字近く当たっていた、というときの「3 文字近く」がこれです。

top-1(トップワン、top-1 当たり率) モデルが一番自信を持って出した第 1 候補だけを答えにして、それが実際の正解とぴったり一致した割合。試験で「最有力だと思った選択肢だけをマークして何問正解したか」に近い、鋭い当てもの指標。

つまり私は「PPL は無事そうに見えるのに top-1 は先に死ぬ」——両者がズレることを予想していました。もしそうなら「PPL ゲートは top-1 の劣化を隠す」というきれいな教訓記事が書けます。

結果はこうでした(realp1、fp32 を基準に各ビット幅を比較。表示値は丸め、Δは実測の生値)。

ビット幅 PPL PPL の悪化 top-1 当たり率 top-1 の悪化(Δ)
fp32(基準) 38.32 28.66%
8bit ほぼ同等 わずか ほぼ同等 わずか
4bit やや悪化 やや低下
3bit 悪化 低下
2bit 101.114 +163.90% 15.21% −13.46pp

脚注:丸め表示の 28.66% → 15.21% を手で引くと −13.45pp になりますが、表内の Δ = −13.46pp は丸め前の実測生値から算出しています。算術監査のために併記しておきます。

予想は外れました。PPL と top-1 は、ズレなかった。2bit では両方が同時に、足並みをそろえて崩れた——本記事ではこれを lockstep(同時劣化) と呼びます。PPL が +163.90% も悪化し、top-1 も 28.66% → 15.21% へほぼ半減。10 文字に 3 文字近く当てていたのが、1.5 文字しか当たらない。片方だけが無事、という状況は起きなかったのです。

ここで踏みとどまる必要があります。外れたのは「予想」であって、教訓が消えたわけではない。むしろ外れた事実そのものが、この記事の主役です。


3. では何が問題だったのか——主張を 2 行に絞る

「lockstep だったなら PPL ゲートで十分では? top-1 も一緒に落ちるなら、PPL が落ちた時点で弾けるはずだ」——もっともな反論です。だからこそ、何が実際に壊れたのかを、誇張せずに正確に書きます。私の主張は次の 2 行だけです。

(1) 今回 PPL と top-1 は lockstep(同時劣化)であり、片方が先に死ぬという私の事前予想は外れた。
(2) それでも 2bit は「品質ゲート」を PASS した。原因はゲートの閾値(0.85×)が粗すぎて、明らかに壊れた 2bit を通してしまったこと。

数字で追います。unigram ベースラインの PPL は約 215。ゲートの合格ラインは 0.85 × 215 ≈ 183。2bit の PPL は 101.114

101.114 < 183。だから PASS。

検査は嘘をついていません。設定どおり動いただけ。top-1 が半減していようが、ゲートは PPL という 1 本の物差ししか持っていません。その物差し上では「unigram より十分マシ」に見えてしまう。lockstep で両方落ちていても、閾値が緩ければ、落ちきる前の中途半端な壊れ方を合格にしてしまう——これが起きたことの全てです。

ここを取り違えないことが、この記事の honesty の核心です。私は 「PPL が原理的に capability(能力)を隠す」とは主張しません。今回は隠していません。lockstep で一緒に落ちていました。問題は指標の選択ではなく閾値の粗さでした。一般論に膨らませた瞬間、この記録は嘘になります。

PPL と top-1 は、そもそも独立した別物ではありません。どちらも同じ出力分布を別の角度から覗いているだけです。PPL は分布全体の「驚き」をならし、top-1 は「1 位が当たったか」を切り取る。同じ景色の、引きの写真と寄りの写真です。だから lockstep で動くこと自体は、よく考えれば不思議ではなかった。私の予想が雑だっただけです。

同じ 2bit 量子化モデルに対する 2 つの判定の対比。左の棒グラフは top-1 正解率が圧縮前 28.7% から 2bit 後 15.2%(−13.5pp、ほぼ半減)へ落ちたことを示し、右はゆるい PPL ゲート(101.1 < 183)が PASS を出す一方、能力 97% 維持ゲートでは残存 53% で FAIL になることを対比している。要点は、同じモデル・同じ数字でも、ゲートの引き方ひとつで合否が反転すること——良い点が出たことより「悪いものを落とせる検査か」が問われる。

同じモデル・同じ数字でも、ゲートの引き方ひとつで合否が反転する。


4. 認知科学のレンズ:グッドハートの法則と construct validity

なぜ「1 個のスコアが PASS を出した」だけで、これほど警戒するのか。ここに本連載が繰り返し戻ってくる 3 つの概念があります。

グッドハートの法則

経済学者チャールズ・グッドハート博士に由来する経験則です。平たく言えば——

「ある指標が目標(ターゲット)になった瞬間、その指標は良い指標であることをやめる。」

元々は金融政策の話でした。中央銀行が「この通貨指標を制御すれば経済は安定する」と決めて指標を狙い始めると、人々の行動がその指標に最適化され、指標と実体の関係が壊れていく。測っていたはずのものが、測れなくなる

量子化ゲートに引き写すと——「PPL が 183 を切れば合格」と決めた瞬間、私が本当に欲しかった**「モデルがちゃんと賢いか」ではなく、「PPL という数字が 183 を切るか」だけが判定対象になる。今回は lockstep だったので破綻は浅くて済みましたが、構造としては代理目標(proxy)に最適化した瞬間に、本来の目標から乖離しうる**という、まさにグッドハートの構図です。

グッドハートの法則(Goodhart's Law) 「ある指標が目標になった瞬間、その指標は良い指標であることをやめる」という経験則。テストの点数を上げること自体が目的化すると、点は取れても本当の学力とずれていく、あの現象のこと。

construct validity(構成概念妥当性)

心理測定の用語です。「測りたい抽象的なもの(構成概念 = construct)」と「実際に測っている操作的な指標」が、ちゃんと対応しているかを問う考え方。

  • 測りたい construct:モデルの言語能力
  • 実際の指標:Perplexity 1 本

PPL は言語能力の一側面を確かに捉えます。でも「次トークンを 1 位でドンピシャ当てる力」も、生成の体感品質も、構成概念の別の面です。1 本の指標で construct 全体を代表させると、指標が拾わない面はノーチェックで通過する。今回 top-1 は lockstep だったので一緒に落ちて目立ちましたが、もし別の壊れ方——たとえば「PPL は無事なのに特定構文だけ崩壊」——なら、PPL ゲートはそれを永遠に見ません。

construct validity(構成概念妥当性, コンストラクト・バリディティ) 「測りたい抽象的なもの(例:言語能力)」と「実際に測っている指標(例:PPL 1 本)」がちゃんと対応しているか、という妥当性。英語力を測りたいのに単語テストの点だけで代表させると、会話力や読解力を見落とす——その“測り対象と物差しのズレ”を問う考え方。

代理目標の乖離 — 健康診断のたとえ

上の 2 つをひとことに縮めると、「代理(proxy)で本物を測ったつもりになる」危うさです。

体重計だけで健康診断を済ませる、と想像してください。体重は健康の良い proxy です。でも体重だけ正常で血圧が振り切れている人を、体重計は健康と判定する。私の品質チェックも同じで、1 つの点数(体重計)だけを見て「合格」。その点数が拾わない面(能力の崩れ)は、ノーチェックで通過していた。

この比喩がどこで壊れるかも書いておきます。体重と血圧は独立に動きうる指標です。一方、今回の PPL と top-1 は——前述のとおり——同じ出力分布を別角度から見ているだけで、独立ではありません。だから健康診断の比喩は「複数の指標を見ろ」という教訓までは正しく運びますが、「PPL と top-1 は独立だから両方測れば安心」という方向に読むと過剰です。今回の本当の処方箋は「指標を増やす」ことそのものより、閾値を厳しくし、しかも fp32 比という相対基準に変えることでした。次節に続きます。


5. 対策:retention 比の capability-gate を fail-closed で配線する

教訓を「気をつけよう」で終わらせると、必ず同じ崖から落ちます。なのでコードに落としました

新設したのは capability-gate。考え方はこうです。

  • 旧ゲート:「PPL が unigram の 0.85 倍を切れば PASS」(絶対 PPL の粗い閾値
  • 新ゲート:「fp32 比の top-1 retention が 97% 以上でなければ FAIL」(能力そのものの相対保持率

retention(保持率)は「量子化後の top-1 ÷ fp32 の top-1」。fp32 を満点 100% として、量子化で能力が何割残ったかを測ります。

retention(保持率, リテンション) 圧縮後に元の能力が何割残ったかを示す相対指標で、(量子化後の top-1 ÷ fp32 の top-1)で計算する。元を満点 100% とみなすので、retention 53% は「半分近い力が抜け落ちた」と読む。100% に近いほど“能力を保ったまま軽くできた”ことになる。

2bit を当てはめると——top-1 は 28.66% → 15.21%。

retention = 15.21 / 28.66 ≈ 53.1%(= 約 47%(46.9%)の能力喪失

閾値は 97%。53% は 97% に遠く及ばないので FAIL。新ゲートは 2bit をきっぱり落とします。旧ゲートが PASS させたものを、です。

実装の肝は fail-closed です(src/llcore/lm/eval.py)。passes_capability_gate(min_retention=0.97) は、retention が閾値以上>=)のときだけ合格を返す。例外が出たとき・データが欠けたとき・比較対象(fp32 基準)が取れないとき——判定不能はすべて FAIL に倒す。「わからないものは通さない」を既定にする、という FullSense の MCP 系プロジェクトと共通の規律です。held_out_top1_report で held-out(学習に使っていない検証データ)上の top-1 を別途レポートし、teacher-forcing(正解を 1 文字ずつ与えながら次の 1 文字を当てさせる測り方)で測っています。

fail-closed(フェイルクローズド) 判定に迷ったり、データや比較基準が欠けたりしたら、自動的に「不合格・拒否」という安全側へ倒す設計方針。踏切が故障したら必ず「閉」に倒れて事故を防ぐのと同じ発想で、「わからないものは通さない」を既定にする。

teacher-forcing(ティーチャーフォーシング、教師強制) 文章を 1 文字ずつ進めるとき、毎回「直前までの正解」を与えた状態で「次の 1 文字」だけを当てさせる測り方。模試で各問の正答を見てから次の 1 問だけ解かせる形に近く、誤りが雪だるま式に膨らむのを防いで“1 手先”の純粋な実力を測る。

ここで設計上の判断を 1 つ明示しておきます。新ゲートは PPL を捨てていません。PPL ゲートは「文脈を読む基礎力があるか」の足切りとして残し、その上に「能力をどれだけ保持できたか」の retention ゲートを重ねた。1 本を別の 1 本に置き換えたのではなく、測る面を増やしつつ、相対基準と厳しい閾値で締め直した。グッドハート対策の定石どおりです。

再現に使ったもの:scripts/quant_bitwidth_sweep.py(8/4/3/2bit を順に量子化して評価)、出力は out/quant_bitwidth_sweep*.json、設計と数値の正本は docs/MEMORY_EFFICIENCY_FINDINGS.md。コード参照はすべて相対パスです。

健康診断の信頼は「全部正常でした」で決まるのではなく、「異常があったらちゃんと拾える設計か」で決まります。AI の品質チェックも同じ。良い点が出たことより、悪いものをちゃんと落とせる検査か——これが第 I 部の核心です。


第 II 部 — 「proprietary 超え」の解剖学:cherry-pick 5 型

第 I 部では、自分のゲートが「単一スコア」の罠に落ちた具体例を解剖しました。同じ罠は、自宅の極小モデルだけのものではありません。業界の「○○超え」ニュースが、まさにこの「1 個の数字で勝者を語る」形を使っている——ここからは、その手口を 5 つの「型」に分類し、読者が自分で使えるチェックリストに変えます。

6. フック — 同じ見出しを 3 回見て、3 回とも内訳が違った

「OSS が大手を超えた」という見出しを、2026 年 6 月のひと月で 3 回見ました。Google の Gemma 4、NVIDIA の Cosmos 3、Baidu の PaddleOCR-VL。どれも本物のニュースで、どれも一次情報(公式ブログや arXiv 論文)が存在します。数字が捏造されているわけではありません。

ところが、3 回とも「超えた」の中身が違っていました。

  • 1 回目は、勝った軸だけを見出しに出していた(負けた軸は技報の奥のテーブルに、声を潜めて載っていた)。
  • 2 回目は、自分たちが得意な専用ベンチでの首位だった(汎用能力の話ではなかった)。
  • 3 回目は、公式は「open なモデルの中で 1 位」としか言っていないのに、二次メディアの見出しだけが「Gemini 超え」に育っていた。

派手な勝利は、決まって同じ 5 つの「型」のどれかで作られています。本記事は、その 5 型を **読者が自分で使える分類学(taxonomy、ものごとを型に分けて整理する道具立て)**として渡すことを目的とします。「数字を疑え」という根性論ではなく、「どの型で勝利が演出されているかを当てる手順」を持ち帰ってもらうのがゴールです。そして最後に、その 5 つの刃を、私自身の自宅 PoC である llcore に当て直します。批判は、鏡として自分に返ってこないと意味がないからです。

☕ ここで一度肩の力を抜いてください。これから出てくる数字は全部「実在する一次情報」です。悪役は誰もいません。問題は「数字」ではなく「数字に付いてくる主張の射程(どこまで言えるか)」のほうにあります。

規模差の内訳(1 行で正確に): 「約 15,000× の規模差」は、いちばん小さい char-LM(0.81M)と Gemma 4(11.95B)を比べたときの最大ギャップです。同じ PoC でも、後述する「RAM 超で回す」実証に使ったのは 130M モデルで、こちらは Gemma 比 約 92× にすぎません。デモごとに規模差は違うので、「どのデモでも 15,000×」と読まないでください(最大ギャップだけを一律に当てるのは、それ自体が後述の型1 です)。


7. まず用語を 2 つだけ — この記事の土台

PPL や top-1 は第 I 部で説明したので、ここでは新しく必要になる 2 語だけ足します。ベンチマーク(モデルの能力を測る「共通テスト」。学校の模試に近いが、誰が問題を作り、誰が採点したかで結果の意味が大きく変わる)は直感でわかるとして——

self-report(セルフレポート、自己申告) — その数字を、測定対象の本人(=モデルを作った会社)が自分で測って自分で発表した状態。模試で言えば「自分で問題を作り、自分で解いて、自分で採点して、自分で『満点でした』と発表した」状態です。嘘とは限りません。が、第三者が同じ条件で測り直して確かめた(=再現した)わけでもない。本記事に出てくる他社の数字は、明記しない限りすべて self-report です。 これは「だから信用するな」ではなく「まだ再現待ちの段階だと札を貼っておこう」という意味です。

cherry-pick(チェリーピック、いいとこ取り) — たくさんある結果の中から、自分に都合のいいものだけを選んで見せること。さくらんぼが一杯生っている木から、熟れた赤い実だけを摘むイメージです。重要なのは、摘んだ実は本物だということ。緑の実(=負けた軸)を見せていないだけ。だから cherry-pick は「嘘」ではなく「主張の射程が、見出しが匂わせるより狭い」という現象として捉えるのが正確です。

この「嘘ではなく射程が狭い」という線引きが、本記事を通底するトーンです。誰かを糾弾する記事ではありません。数字の読み方の練習問題です。


8. cherry-pick の 5 つの型(taxonomy)

ここからが本論です。2026 年 6 月の実例で、5 つの型を一つずつ解剖します。各型に「検出シグナル(これを見たら疑う)」を添えるので、読み終わったら自分のタイムラインに流れてくる「OSS が○○超え」に当ててみてください。

型1 — 負け軸の省略(Loss-Axis Omission)

定義: 複数の評価軸(カテゴリ)のうち、勝った軸だけを前面に出し、負けた軸を伏せる(または技報の奥に小さく載せる)。

実例: NVIDIA Cosmos 3。Cosmos 3 は「Cosmos 3: Omnimodal World Models for Physical AI」(NVIDIA, 2026-06-01)として発表された、物理 AI 向けの大規模 world model です(技報・self-report・一次未照合=技報 PDF 未取得)。技報の Table 10 を見ると、Driving(自動運転)カテゴリで 79.3 vs Gemini 47.2 と大差で勝っています(技報時点・self-report・一次未照合)。これだけ見れば「Gemini を圧倒」です。

world model(世界モデル) 物理世界の動き(物の運動・因果・空間関係)を内部でシミュレートして「次にこうなるはず」と予測する AI モデルの総称。頭の中で動きを先読みする“想像力エンジン”にあたり、自動運転やロボット制御の土台になる。

ところが、同じ Table 10 は複数のカテゴリで構成されており、別の行にはこう書いてあります(いずれも技報時点・self-report・一次未照合)。ここで「軸(=カテゴリ)」という言葉を使いますが、これは Table 10 の評価カテゴリの数を指します(後述する型4 の「ベンチの本数」とは別物なので、混同しないよう用語を分けます)。

カテゴリ(軸) Cosmos 3 Gemini 勝敗
Driving(自動運転) 79.3 47.2 Cosmos の勝ち(大差)
Robotics(ロボティクス) 57.8 58.2 Gemini の勝ち
General(汎用) 73.7 77.5 Gemini の勝ち
SmartInfra(スマートインフラ) 数値未取得 数値未取得 不明(要技報確認)

Table 10 は 4 カテゴリ(Driving / Robotics / General / SmartInfra)の category-average で構成されています。私が一次の技報 PDF を取得できていない関係で、SmartInfra の Cosmos / Gemini スコアは未取得です——だからここは正直に空欄にしてあります(取得できないのに数字を埋めるのは、それこそ本記事が批判する作法です)。

判明している範囲で言えるのは、Cosmos が勝っているのは Driving の 1 軸だけ、Robotics と General は Gemini に負け、SmartInfra は未取得で不明ということです。つまり「Gemini 超え」という総括は、4 カテゴリのうち判明している 3 つで 1 勝 2 敗、残り 1 つは不明という像を、Driving 1 軸に圧縮したものです。

ここで自分への戒めを先に書いておきます。私は今、まさに 4 軸目(SmartInfra)を「未取得」として空欄にしました。 負け軸の省略を糾弾する記事が、4 つ目の軸を黙って落とせば、それは私自身が型1 を犯すことになる。だから「3 軸の話」に縮めず、4 カテゴリあること・1 つは私の側の取得失敗で空欄であることを明示します。

そして NVIDIA を擁護しておくと、技報には(私が読めた範囲で)全カテゴリが載っています。負けた数字を消してはいない。問題が大きく起きるのは主に二次拡散の側(後述の型5)で、技報そのものは誠実です。型1 は「悪意」より「要約の作法」の問題として捉えるべきです。要約は必ず情報を捨てるので、何を捨てたかで主張の色が変わる

検出シグナル: 「○○を超えた」の○○が単一タスク名・単一スコアのとき。複数カテゴリあるはずの能力(運転・操作・汎用・インフラ…)を 1 行に潰していたら、潰す前のテーブルを探しに行く。そしてテーブルのカテゴリが全部見えているか(誰かが——自分も含めて——伏せていないか)を数える。

型2 — 専用ベンチ(Bespoke-Benchmark)

定義: 自分が得意なタスクに特化したベンチでの勝利を、あたかも汎用能力の勝利のように語る。

実例: Baidu PaddleOCR-VL-1.6(arXiv:2606.03264, Apache-2.0、arXiv ID は一次確認済み)。0.9B(NaViT 動的解像度エンコーダ + ERNIE-4.5-0.3B)という、わずか 9 億パラメータのモデルです。これが OmniDocBench v1.6 で 96.33%(self-report)を出し、「235B 級や Gemini を超えた」と語られました。0.9B が 235B を超えた——数字だけ見れば衝撃です。

でも、OmniDocBench は「文書解析」専用のベンチです。スキャンした書類や PDF から、文字・表・レイアウトをどれだけ正確に読み取れるかを測ります。汎用的な「賢さ」ではなく、文書を読むという 1 タスクの点数です。しかも測ったのは Baidu 自身(self-report)。

これは「ズル」ではありません。文書解析に特化した 0.9B が、文書解析の専用ベンチで巨大汎用モデルを上回るのは、むしろ専門特化の正しい成果です。問題は数字ではなく、「文書解析で勝った」が「Gemini を超えた」に翻訳されるときに、射程がこっそり広がることです。100m 走で金メダルを取った選手を「世界最強のアスリート」と紹介するようなもので、100m は本当に世界一でも、マラソンや砲丸投げの話はしていない。

なお——第 I 部で見た私の PPL ゲートが「次トークンを 1 位で当てる力(top-1)」を見落としたのと同じく、1 個の集約スコアは、その内訳のどこかが落ち込んでいても平均で覆い隠せてしまう。OmniDocBench 96.33 は「文書解析を総合した平均的良さ」です。表組みの崩れ、特定言語の劣化、数式・縦書き・低解像度といった部分集合での弱さが、平均 96.33 の下でどう分布しているかは、1 つの数からは読めません(これは PaddleOCR を貶める話ではなく、むしろ self-report を明示する公式カードは誠実です)。第 I 部の単一スコア問題が、規模を変えて再来しているわけです。

検出シグナル: ベンチ名に対象タスクが書いてあるか(OmniDocBench = Doc=文書)。専用ベンチでの勝利が「汎用超え」に訳されていたら、そのベンチが何を測っているかを調べる。

型3 — 自前測定(Self-Measured / Home-Court)

定義: 比較に使った全数値が、発表者自身の環境・自前ベンチで測られている。第三者が同条件で再現していない。

これは型1・型2の土台にある、より根本的な型です。Cosmos 3 の Table 10 も、PaddleOCR の 96.33% も、発表者(NVIDIA / Baidu)が自分の環境で測った self-report です。相手モデル(Gemini など)を、勝者側が自分のセットアップで走らせて採点しているケースすらあります。

野球で言えば「自分のホームグラウンドで、自分が審判をやった試合の結果」です。ホームの利(球場の癖を知っている、観客が味方)も、審判の解釈も、全部こちら側にある。だからといって試合結果が偽物とは限りませんが、中立球場・中立審判での再現とは信頼度が一段違います。

ここで Gemma 4 の「26B 級に迫る」を取り上げると、実は型3 の純粋な例にはなりません。なぜなら、Gemma 4 の「26B 級」主張には、一次情報に定量ベンチ表そのものが存在しないからです(公式 blog の一般文で、比較相手の 26B が dense か MoE〔=一部のパラメータだけ動かす疎構成、active param は約 4B〕かも明示されていない)。つまりこれは「発表者が自前で測った数字」ですらなく、「数字が提示されないまま一般文で強い主張がなされている」状態です。だからこれは型3 というより、型1(都合のいい比較相手の選び方を伏せる)や型5(一般文が見出しで断定に化ける)寄りの例として扱うのが正確です——「自前測定の数値」と「そもそも数値が無い一般文」は別の問題なので、ここは分けておきます。

型3 が厄介なのは、型1・型2より見えにくいことです。負け軸の省略(型1)は技報を読めば気づける。専用ベンチ(型2)はベンチ名で気づける。でも「これは self-report だ」は、明記されていないと見落とします。だからこそ、デフォルトで「明記なき数字は self-report」と札を貼る習慣が効きます。

検出シグナル: 「誰が測ったか」が書いていない数字は、まず self-report と仮定する。第三者再現(独立した研究機関やコミュニティが同条件で測り直した)への言及があるかを探す。そして「強い主張なのに、そもそも定量ベンチ表が一次に無い」場合は、self-report 以前の問題として警戒する。

型4 — 母数が小さい(Small-N)

定義: 勝敗の根拠となる標本(ベンチの本数・テスト項目の数)が少ない。少ないほど順位はノイズで簡単に入れ替わり、少ないほど「言えること」が減る。

型1 で見た Cosmos の Driving 勝利(79.3 vs 47.2)を、もう一段深掘りします。ここで言う「数」は、型1 の「カテゴリ(軸)の数」とは別物です。 型1 では「Table 10 に 4 カテゴリある」という軸の数を数えました。型4 で数えるのは、Driving という 1 カテゴリの中に、ベンチが何本あるかです。そして Driving スコアは、たった 3 本のベンチの平均でした(技報時点・self-report・一次未照合)。

念のため明示します——この「3」は Table 10 の軸数(=4)ではなく、Driving 1 軸を構成するベンチの本数です。両方たまたま 1 桁の数なので混同されがちですが、「4 カテゴリある(型1)」と「Driving は 3 ベンチの平均(型4)」は指しているものが違います。

標本が 3 本しかないと何が起きるか。サイコロを 3 回振って全部 6 が出ても「このサイコロは 6 が出やすい」とは言えないのと同じで、3 ベンチの平均は、たまたまの偏りを排除できません。1 つのベンチがそのモデルにたまたま有利だっただけで、平均が大きく動きます。統計の言葉では「分散(ばらつき)が大きく、信頼区間が広い」状態です。

しかも、こういう小標本の主張では分散や信頼区間そのものが報告されないことがほとんどです。平均値 79.3 だけが一人歩きする。本来は「79.3 ± いくつ」と幅を添えないと、47.2 との差が本物かまぐれかが判断できません。

ここでも「3 ベンチでは無価値」と切り捨てるのは行き過ぎです。少数ベンチにも探索的な価値はあります(新しいタスクの最初の手がかりとして)。主張すべきは「大標本こそ正義」ではなく、「標本数と分散を開示せよ」です。3 ベンチなら「3 ベンチの平均で、分散はこれくらい」と正直に書けばいい。

検出シグナル: 「平均」「総合スコア」の裏にいくつの項目(ベンチ本数)があるかを数える。N(母数)が一桁なら、順位は容易に入れ替わると疑う。± が付いていない平均は、まず幅を疑う。「カテゴリ数」と「カテゴリ内のベンチ本数」を混同しない。

型5 — 二次情報の拡大解釈(Second-Hand Inflation)

定義: 公式の慎重な主張が、二次メディア・SNS を経由するうちに強い主張に膨張する。発表者は限定していたのに、伝言ゲームで限定が外れる。

これが、本記事のフック「3 回とも内訳が違った」の正体に最も近い型です。

実例: Cosmos 3 の「Gemini 超え」。NVIDIA の公式 newsroom(プレスリリース)を読むと、慎重に「open なモデルの中で 1 位」という限定が付いています(self-report)。「全モデル中 1 位」でも「Gemini を超えた」でもない。open(公開重み)モデル群の中での首位、という射程の狭い主張です。

ところが、これが二次メディアやタイムラインに流れる過程で、「open 内 1 位」の "open 内" がぽろりと落ちて、「Gemini 超え」だけが残ります。発表者は限定していたのに、伝言ゲームで限定が剥がれる。Cosmos のライセンスが OpenMDW 1.1(OSI 承認の OSS ではない「open model」ライセンス)であることも、この文脈で重要です——そもそも「open の中で」という土俵設定自体に注釈が要るのです。

型5 が一番たちが悪いのは、発表者に非がないことです。NVIDIA は正しく限定した。膨張させたのは受け手側。だから「NVIDIA が嘘をついた」と読むのは誤りで、正しくは「一次情報に遡ると主張はもっと狭かった」です。これは情報の流通構造の問題で、技術の問題ではありません。

検出シグナル: 強い見出し(「Gemini 超え」)を見たら、必ず一次情報(公式ブログ・論文・newsroom)に遡る。一次の主張に付いている限定語(「open 内」「文書ベンチで」「特定タスクで」)が、見出しから消えていないかを照合する。


9. 5 型を 1 枚にまとめる

ここまでを、持ち帰り用のチェックリストに圧縮します。タイムラインに「OSS が○○超え」が流れてきたら、上から順に当ててみてください。

何をしているか 検出シグナル 2026-06 の実例
型1 負け軸省略 勝った軸(カテゴリ)だけ前面化 「超え」が単一スコア・単一タスク Cosmos: Driving だけ出し Robotics/General(+SmartInfra)を伏せる
型2 専用ベンチ 得意タスク特化ベンチでの勝利を汎用勝利に ベンチ名にタスクが入っている PaddleOCR: OmniDocBench 96.33%(文書専用)
型3 自前測定 全数値が発表者環境(または数値そのものが無い一般文) 「誰が測ったか」が書いてない Cosmos/PaddleOCR は self-report、Gemma「26B 級」は定量表すら一次に無い
型4 母数小 標本(ベンチ本数)が少なく順位がノイズ 平均の裏の N が一桁・± がない Cosmos Driving は 3 ベンチの平均(カテゴリ数 4 とは別)
型5 二次拡大解釈 公式の限定が伝言で剥がれる 見出しが一次より強い NVIDIA「open 内 1 位」→二次「Gemini 超え」

🎯 この 5 型は 排他的ではありません。一つの「勝利」が型1+型3+型4 を同時に使っていることはごく普通です(Cosmos の Driving 勝利がまさにそれ)。だから「どの型か」を一つに絞るより、「いくつ当てはまるか」を数えるほうが実用的です。当てはまる型が多いほど、主張の射程は狭い。

cherry-pick の 5 型を 3 列で並べた表 — 左に型1〜型5(負け軸省略/専用ベンチ/自前測定/母数小/二次拡大解釈)、中央に 2026-06 の他社実例(Cosmos の Driving 79.3 vs 47.2、PaddleOCR の OmniDocBench 96.33% など)、右に同じ刃を llcore 自身へ向けた自己監査(fp32 比 3.9× には fp16 比 1.9× を併記、Gemma 比 約 15,000× 小、Driving は 3 ベンチ平均、RAM 超デモに自分で限定語を貼り続ける)。下段に「差し出す負け」として 2bit QAT が top-1 retention 82.9% で自前 strict ゲート 97% に未達・速度は未測。要点は、5 型は他人を叩く武器でなく自分に返る鏡であり、全員が self-report(段2)にいるということ。

同じ 5 型を、他社の実例(中央)と llcore 自身(右)に並べて当てた一枚。批判は鏡として自分に返る。


10. 比喩 — そして、その比喩が壊れる場所

5 型を一つの像にまとめる比喩として、**「スポーツの戦績ハイライト動画」**が便利です。

ハイライト動画は、選手の決めたプレーだけを繋ぎます。空振りや凡退は映りません(型1)。しかもそのスポーツの中でも得意な場面が選ばれる(型2)。撮ったのは所属チームの広報(型3)。試合数が少なければ「絶好調」も偶然かもしれない(型4)。そして広報が「リーグ屈指の活躍」と添えたコメントが、ファンの間で「歴代最強」に育つ(型5)。ハイライトの映像はどれも本物です。捏造は一つもない。でも、それを見て「この選手は無敵だ」と思ったら、それは映像のせいではなく、ハイライトという形式の性質にやられたのです。

この比喩が壊れる場所も正直に言います。ハイライトは「意図的に良い場面を選んでいる」というニュアンスが強い。でも cherry-pick の 5 型は、必ずしも作為的ではありません。型5(二次拡大解釈)は発表者に作為がなく、受け手側で勝手に膨張します。型1 も、技報には全カテゴリ載っているのに要約で落ちるだけで、悪意とは限らない。だから「ハイライト動画=ズルい広報」という連想を強く持ちすぎると、「企業が意図的に騙している」という陰謀論寄りの読みに滑ります。実際の多くは、要約と伝言という、情報処理の不可避な副作用です。比喩は「形式が射程を狭める」という骨格を運ぶのには良いが、「作為の有無」までは運べない——ここで降りてください。

☕ 休憩ポイント。ここまでが「他人のベンチを読む道具」です。次の章から、この 5 本の刃を自分に突き立てます。ここが本記事の本番であり、FullSense の運用規律 feedback_benchmark_honest_disclosure(異常に良い結果が出たら、勝った気になる前に必ず内訳を疑う)を最も強く具現する部分です。


自己監査 — 同じ 5 型を、llcore 自身に当て直す

私は自宅の GPU なし PC で、llcore という極小モデルの実験群を走らせています。北極星は「賢さ」ではなく「メモリ効率」。その実測値で、私はいくつかの主張をしています。たとえば「int8 量子化で約 3.9× 圧縮」「使える RAM がモデルより小さくても回る」。

他社のベンチを 5 型で解剖した以上、自分の主張にも同じ 5 本の刃を入れるのが筋です。当てなければ、この記事はただのブーメランになります。

型3(自前測定)に対して — そもそも全部 self-report、しかも極小

最初に最も重い一撃から。llcore の数値は、すべて私が自宅 CPU で測った self-report です。 第三者再現どころか、対象は tiny char-LM(0.81M〜130M パラメータ)の CPU PoC。Gemma 4 が 11.95B(約 120 億)であることを思えば、最小モデル(0.81M)との比は およそ 15,000 分の 1。ただし——これも正直に分けますが——後述の「RAM 超で回す」実証に使ったのは 130M モデルで、こちらは Gemma 比 約 92 分の 1 です。「llcore はどれも 15,000 分の 1」と一律に書くと、130M デモには過大な(=自分に厳しすぎて、しかも不正確な)規模差を当てることになるので、デモごとに分けて書きます。いずれにせよ、他社の self-report を「再現待ち」と札を貼ったなら、自分の self-report にはもっと太い札を貼らねば不公平です。だから llcore の主張は「実 LLM を超えた」では一切なく、「手法・思想・計測規律のレベルで何が言えるか」に限定します(これが連載 caveat の意味です)。

型1(負け軸省略)に対して — 「int8 で 3.9×」は基準を黙ると盛れる

私は「int8 weight-only 量子化で約 3.9× 圧縮(74〜75% 削減)、PPL 劣化 0.1% 未満」を実測しています(3 モデルで一貫、src/llcore/lm/quant.py)。数字は本物です。でも、この「約 3.9×」は fp32(32bit 浮動小数点)を基準にしたときの値です

業界標準の量子化ツール(llama.cpp / GGUF)の慣習的な基準は fp16(16bit)です。fp16 を基準にすると、int8(8bit)は 約 1.9× にしかなりません(GGUF の Q8_0=8.50 bpw は fp16 比 約 1.88×、fp32 比 約 3.76×)。だから「3.9×」と書くときに fp32 比だと明記しないと、暗黙に有利な基準を選んで盛っていることになる。仮に切りよく「約 4×」と丸めて基準を黙れば、それは私自身がやりかねない型1(都合のいい基準軸だけ見せる)そのものです。だから本文でも表でも、ヘッドラインの数字を「約 3.9×(fp32 基準)」に統一し、fp16 基準なら 1.9× だと必ず併記することを自分の規律にしています。

bpw(bits per weight, 1 重みあたりビット数) モデルの重み 1 個を平均で何ビット使って表すか。fp32 なら 32bpw、int8 なら約 8bpw で、数字が小さいほど 1 個あたりを安く詰めている=メモリが減る、という圧縮率の物差し。

型2(専用ベンチ)/ 型4(母数小)に対して — char-LM という超ニッチ、極小コーパス

他社を「文書専用ベンチで測った(型2)」と批判するなら、私の測定対象である char-LM(文字単位の言語モデル)も、極めて特殊なニッチだと認めねばなりません。実 LLM の評価系(MMLU や HellaSwag のような汎用ベンチ)とは、規模も指標も別世界です。私の「PPL が下がった」は、この極小・特殊な土俵での話であって、汎用能力の話ではない。

母数(型4)も正直に。llcore のコーパスは小規模で、量子化スイープも限られたモデル数(0.81M / 1.36M / 11.9M / 130M)での観測です。「大モデルほど低ビットに頑健」という傾向は literature(Dettmers 博士ら(2023)等)と方向が一致しますが、最大 11.9M での観測であって、12B〜64B への外挿は保証できません。傾きの方向は文献整合、絶対値は未保証——これを本文に太字で書くのが私の型4 対策です。

金髪の女性が汗を浮かべた困惑顔のアップ。「誰…?」という問いに、「その界隈だと持ち上げられてるけど『その界隈』が狭すぎて世間に通用しない感じの人…?」と身も蓋もない説明を返しているコマ

🗒️ 「その界隈だと持ち上げられてるけど『その界隈』が狭すぎて世間に通用しない感じの人…?」— char-LM という超ニッチの土俵で「PPL が下がった」と言っている自分に、いちばん深く刺さる一言(© Forbidden shibukawa / SHUEISHA・『スナックバス江』)

型5(二次拡大解釈)に対して — 自分が膨張の発生源にならないために

最も注意すべきは、私自身が型5 の「発生源」になりうることです。たとえば「使える RAM がモデルより小さくても回る」という主張。これは実測です(fp32 522MB のモデルを、working-set 上限 358MB=モデルの 68% で forward 完走、出力の checksum 完全一致 -215.1。このデモのモデルは 130M=Gemma 比 約 92×)。

working-set(ワーキングセット、作業中の常駐メモリ) プログラムがその瞬間に同時に抱えているメモリ量のこと。机の上に一度に広げられる書類の量にあたり、その上限をモデル本体のサイズより小さく絞っても計算を最後まで完走できた、というのがここでの実証点。

でも、**私のマシンは実装上 avail RAM が限られていた(実行時 約 3.6GB)**ため、実証したのは「物理 RAM 総量を literally 超える巨大モデル」ではなく、「working-set 上限 < モデルサイズ」という、同じ性質を持つ条件下での話です。ここで私が「RAM を超えるモデルが回った!」と限定を外して書けば、それは自分で **型5(限定の剥がれ)**をやることになる。だから JSON 出力に cap_set_ok(上限の強制に成功したか)と実測 peak をそのまま残し、成功を偽装しない。自分の主張に、自分で限定語を貼り続ける——これが発生源にならないための唯一の方法です。

もう 2 つ、自分から差し出す負け

5 型の刃だけでなく、聞かれる前に自分から開示しておきます(これも honest disclosure の作法です)。

  • 速度は一切測っていない。llcore の量子化は simulated quant(疑似量子化)——保存した int8 を、推論時に fp32 に戻して計算しています。つまり「メモリは小さくなった(footprint=実測)」が、「速くなった」とは一度も言えていない(速度未測)。「2bit / int8 で速くなった」という誤読を構造的に防ぐため、これは caveat バナーにも書いた最重要の留保です。
  • 2bit は、最善を尽くしても自前の品質ゲートを越えられなかった。量子化を学習に織り込む QAT(学習時量子化)を実装しても、2bit の top-1 retention は 82.9%。これは PTQ(学習後量子化)の RTN 22% / GPTQ 33% を大きく上回る前進ですが、第 I 部で新設した strict ゲート(fp32 比 97% 保持)には届きませんでした。これは隠したい負けですが、隠せば型1 そのものです。

RTN / GPTQ どちらも学習後量子化(PTQ, Post-Training Quantization)の代表的手法。RTN(Round-To-Nearest, 最近傍丸め)は各重みを単純に一番近いビット値へ丸める最も素朴なやり方、GPTQ は丸めで生じた誤差を補正しながら次の重みへ反映してずれを抑えるより賢いやり方。雑に四捨五入するか、全体の帳尻を合わせながら丸めるかの差。


11. 信頼の梯子 — self-report は最下段ではないが、最上段でもない

5 型を貫く一本の軸として、私は「信頼の梯子(ladder of trust)」という整理を使っています。数字を見たとき、それが梯子のどの段にいるかを当てる習慣です。

段4  独立査読   ← 第三者が査読論文として検証(最も信頼できる)
   ↑
段3  第三者再現  ← 別の人が同条件で測り直して一致した
   ↑
段2  self-report ← 本人が測って本人が発表した(再現待ち)
   ↑
段1  実在確認   ← その数字・その論文が実在することだけは確かめた

身近に言い換えると——いちばん下が本人の自己採点(模試を自分で作って自分で採点した状態)。その上が、友達が同じ問題を解き直して同じ点になった段。さらに上が、公式の模試で第三者が採点した段。いちばん上が、専門家がきちんと査読した段です。

大事なのは、self-report(段2)は「嘘」ではないということです。段1(実在すらしない=捏造)よりは上です。問題は「段2 を段3・段4 のように扱ってしまう」誤読です。「本人が言っている」を「みんなが確かめた」と読み替えた瞬間に、梯子を 2 段飛ばしている。

ここで、本記事自身の「段1(実在確認)」の内訳を、ごまかさずに開示します——honest disclosure を看板に掲げる以上、自分の検証主張に偽の段を作ってはいけないからです。

  • PaddleOCR-VL-1.6(arXiv:2606.03264): arXiv ID を一次で確認済み(confirmed)。
  • Gemma 4 12B: 公式 blog / HF model card を一次で確認済み(ただし「26B 級」は定量ベンチ表が一次に無い一般文)。
  • NVIDIA Cosmos 3(arXiv:2606.02800): arXiv ID の実在は投稿時点で確認済み(arXiv 上に「Cosmos 3: Omnimodal World Models for Physical AI」が存在)。ただし、技報 PDF 本体は私の手元で取得できておらず、Table 10 の各スコア(79.3 / 47.2 / 57.8 / 58.2 / 73.7 / 77.5、SmartInfra は未取得)は二次情報依拠=一次未照合です。 数字が実在することと、私がその数字を一次で目視照合したことは別の段なので、後者を主張してはいけません。Cosmos の数値はすべて「技報時点・self-report・一次未照合」の三重の札付きで読んでください。

つまり、他社数値の段は一律ではありません。ID の実在(段1 の一部)まで届いた数字と、一次の数表まで自分で照合できた数字は、別の確かさを持つ。それを「すべて照合済み」と一括りに書けば、それ自体が——本記事が型3 で警戒した——「検証していないのに検証したかのように見せる」行為になります。

そして llcore も、まったく同じ段2 にいます。私の数値も実在確認(段1)は済んでいる(JSON も再現スクリプトも公開意図)が、第三者再現(段3)も独立査読(段4)も、まだ受けていません。だから他社と llcore は、信頼の梯子の上では同じ段に立っている。違うのは規模(最小で 15,000×、RAM デモで 92×)と、「自分で限定語を貼り続けているか」という姿勢だけです。

「自分の数字は正しくて他社は怪しい」ではないのです。全員が段2 にいて、全員が段3 を目指すべき。その自覚があるかどうかが、本アークで言いたかった核心です。


12. このアークの着地 — 計測規律が連載の土台、だから次は「負けを見せる」

cherry-pick の 5 型(負け軸省略・専用ベンチ・自前測定・母数小・二次拡大解釈)は、他人を糾弾するための武器ではありません。自分の主張が、見出しが匂わせるより狭い射程しか持っていないことに、自分で気づくための鏡です。

私は第 I 部で、自分のゆるい PPL ゲートが半壊した 2bit に合格証を出す瞬間を解剖し、第 II 部で他社のベンチを 5 型で解剖し、その同じ 5 本の刃を llcore に当て直しました。その過程で、自分自身が 4 軸目(SmartInfra)を空欄にし、規模差を一律 15,000× と書きかけ、「約 4×」と丸めかけました——いずれも、止めなければ本記事が批判したはずの型を私自身が踏むところでした。結論はこうです——llcore は他社より誠実な数字を出しているのではなく、他社と同じ段2(self-report)に、最小で 15,000 分の 1(RAM デモでは 92 分の 1)の規模で立っている。違いは「自分で限定語を貼り続けているか」だけ。それすら、貼り忘れた瞬間に型5 の発生源になります。

だから、このアークから持ち帰る教訓を一つだけ挙げるとすれば、これです。

派手な勝利を見たら、まず一次情報に遡って 5 型を当てる。そして次に、自分の主張に同じ 5 型を当てる。前者だけやって後者を忘れると、批判はブーメランになって自分の射程の狭さを照らす。

異常に良い結果が出たら、勝った気になる前に内訳を疑う。それは他人の数字に対してだけでなく、何よりまず自分の数字に対して——というのが、自宅 CPU の極小モデルから見えた、2026 年 6 月の景色でした。

そしてこの計測規律こそが、連載全体の土台です。測り方を疑い、単一スコアの罠を知り、自分の数字に自分で限定語を貼れるようになって初めて、私たちは堂々と「負けを見せる」ことができる。だから次のアークでは、勝った話ではなく、自分が越えられなかった崖そのものを正面から展示します。


一次情報(本アークの数値の出典)

検証の段は数字ごとに違うので、一括りに「照合済み」とは書きません。 他社数値はすべて self-report(信頼の梯子・段2)。

  • NVIDIA Cosmos 3: 「Cosmos 3: Omnimodal World Models for Physical AI」(NVIDIA, 2026-06-01, arXiv:2606.02800)。arXiv ID の実在は投稿時点で確認済み。ただし技報 PDF 本体は未取得=数値は一次未照合(二次情報依拠)。 技報 Table 10 は 4 カテゴリ(Driving / Robotics / General / SmartInfra)の category-average(技報時点・self-report・一次未照合):Driving 79.3 vs Gemini 47.2 / Robotics 57.8 vs 58.2 / General 73.7 vs 77.5 / SmartInfra は数値未取得(要技報確認)。Driving は 3 ベンチの平均(=型4 の母数小。Table 10 のカテゴリ数 4 とは別の数)。公式 newsroom は「open models 内 1 位」限定。ライセンス OpenMDW 1.1(OSI 承認 OSS ではない open model ライセンス)。
  • Baidu PaddleOCR-VL-1.6: arXiv:2606.03264, Apache-2.0(arXiv ID 一次確認済み)。0.9B(NaViT + ERNIE-4.5-0.3B)。OmniDocBench v1.6 = 96.33%(文書解析専用ベンチ・Baidu 自前測定・self-report)。
  • Google Gemma 4 12B: Apache 2.0、dense 11.95B(公式 blog / HF model card 一次確認済み)。「26B 級に迫る」は定量ベンチ表が一次に無い一般文で、数値そのものが提示されていない・比較相手の 26B は dense か MoE(active~4B)か未確定(=apples-to-oranges)。self-report 以前に数表が無い点に注意。
  • llama.cpp / GGUF: Q8_0 = 8.50 bpw ≈ fp16 比 1.88× / fp32 比 3.76×(公式 quantize README・k-quants PR #1684、一次確認済み)。

llcore 側の数値の出典(すべて自宅 CPU・char-LM・self-report)

正本 = docs/MEMORY_EFFICIENCY_FINDINGS.md / docs/POSITIONING_VS_LLAMACPP.md。評価実装 = src/llcore/lm/eval.py、量子化 = src/llcore/lm/quant.py、再現 = scripts/quant_bitwidth_sweep.pyout/quant_bitwidth_sweep*.json

  • 量子化ビット幅スイープ(realp1, 11.9M char-LM): fp32 基準 PPL 38.32 / top-1 28.66%。2bit で PPL 101.114(+163.90%)・top-1 15.21%(−13.46pp、retention ≈ 53.1%、能力喪失 約 47%)。旧 PPL ゲート(0.85 × unigram 約 215 ≈ 183)は PASS、新 capability-gate(fp32 比 top-1 retention ≥ 97%, fail-closed)は FAIL。
  • int8 weight-only 量子化: 重み常駐 約 3.9×(74〜75% 削減、fp32 基準。fp16 基準なら約 1.9×)・held-out PPL 劣化 0.1% 未満(3 モデル一貫)。
  • int8 streaming-dequant 推論: 常駐モデル 72% 削減(dense fp32 約 539MB → stream int8 約 149MB)。src/llcore/lm/eval.py 経路。
  • working-set 上限実証(モデル 130M=Gemma 比 約 92×): fp32 522MB モデルを WS 上限 358MB(モデルの 68%)で forward 完走、capped/uncapped の logits checksum 完全一致(-215.1)。cap_set_ok=true は本環境結果。
  • 2bit QAT capstone: top-1 retention 82.9%(strict cap-gate 97% 未達)。PTQ RTN 22% / GPTQ 33% を大きく上回るが、極小モデルでは 2bit 完全制覇に至らず。
  • capability-gate: fp32 比 top-1 retention ≥ 97% を fail-closed で適用(src/llcore/lm/eval.py)。8B 級での通過は未実証。
  • 全数値: tiny char-LM(0.81M〜130M)・CPU・simulated quant(推論速度は未測)。実 LLM(12B〜64B)との規模差は、最小モデルで 約 15,000×・RAM 超実証の 130M モデルで 約 92×。

運用規律: feedback_benchmark_honest_disclosure(異常に良い結果が出たら、勝った気になる前に必ず内訳を疑う)。本アークはこの規律の実演として書かれている。


A アーク — 構造で勝つ(定数状態・支配項・設計の臭い)

連載「自宅 CPU から見た 2026 年 6 月の LLM 業界」アーク A 統合版。
4 本の記事(制御理論 × SSM / 文脈メモリ膨張 / 静的支配項 / テストの臭い)を 1 本に編み直しました。
通底するテーマはただ 1 つ ──「bit を下げるな、アーキテクチャと支配項を攻めろ」。
量子化で重みを数 MB 削ることに気を取られている間に、本当に効く項(文脈で膨らむ二次項、言語ランタイムの足場)を
見落としていた、という自分の失敗の連鎖を、自宅 CPU の実測曲線で順に潰していきます。


【連載共通の但し書き(本アークでも一度だけ固定)】
本連載の全 llcore 実測は 自宅 CPU の極小モデル(0.81M〜130M パラメータの char-LM、n_embd 256 / 4 層級)PoC であり、
大手の実 LLM(12B〜64B)の性能を直接反証・凌駕するものではありません。比較は 手法・思想・計測規律 の次元で行います。
量子化の数値は footprint(占有バイト)= 実測ですが、simulated quant = 推論速度は未測です。

本アークに出てくる「×1.00」「×2.65」「×7.53」「142×」などはすべて 極小モデルの CPU 実測です。読むべきは
絶対値ではなく「増え方の形・どの項が支配的か」というトレンドです。recurrent(RWKV/Mamba 系)を 状態空間モデル
として読む
のは literature 上正統な接続ですが、「制御理論が解いたのだから recurrent が Transformer に総合的に勝つ」
とは言いません
。むしろ「メモリ軸では構造的に勝つが、capability(賢さ)軸では recurrent が Transformer に劣る
可能性がある」ことを、llcore 自身の null 結果として正直に書きます。


はじめに — 「bit を下げる」ではなく「構造を攻める」

AI を軽くしようとすると、人はまず「中身を圧縮して薄くする」方を考えます。重みを fp32 から int8 へ、さらに 2bit へ。私もそうでした。せっせとモデルの重みを削っていました。

ところが自宅の GPU なし PC で実測を重ねるうちに、削っていた項が そもそも支配項ではなかった ことが次々に分かってきました。本当に効くのは「bit を下げる」ことではなく、「長くなるほど膨らむ項を、そもそも持たないアーキテクチャを選ぶ」「一番大きい足場を測って攻める」という、もっと構造的な選択でした。

この記事は、その気づきを 4 段で渡します。

  1. a7 — 橋を架ける: recurrent(RWKV/Mamba)を「定数状態で過去を運ぶ」状態空間モデルとして読むと、それは 60 年前の制御工学の再演だと分かる。
  2. a8 — 動的支配項: 文脈長を伸ばすと Transformer はメモリ・時間とも超線形に膨らみ、recurrent は平坦(実機実測)。
  3. a9 — 静的支配項: int8 で数 MB 削った隣で torch ランタイムが 184MB 食っていた。Rust に書き直す前に支配項を測れ。
  4. a11 — 普遍教訓: テストが flaky なのは設計の臭い。判定を純関数に分離せよ。

通底するのは「bit でなくアーキ/支配項を攻めろ」。では順に橋を渡ります。


第 1 部(a7)— 制御理論はとっくに「定数状態で過去を運ぶ」を解いていた

フック — 私の計測値が、60 年前の教科書に載っていた

ある晩、自宅の GPU なし PC で、こんな実験をしていました。

「文脈長 T(モデルが一度に見るトークン数)を 256 から 2048 へ、8 倍に伸ばしたら、推論中のメモリ実使用量(peak working set)はどう変わるか?」

別プロセスに隔離して、OS が報告する実 RSS(Resident Set Size)を測りました。結果はこうです。

文脈長 T GPT(Transformer)peak WS Recurrent peak WS RWKV peak WS
256 229.8 MB 205.0 MB 215.3 MB
512 247.3 MB 205.1 MB 216.0 MB
1024 330.5 MB 204.8 MB 215.7 MB
2048 607.9 MB 204.8 MB 215.2 MB

(scripts/recurrent_runtime_rss.py / out/recurrent_runtime_rss.json。Windows 11 / Python 3.11 / torch 2.12.0+cpu。)

文脈を 8 倍にすると、Transformer は peak が ×2.65 に膨らみ、Recurrent と RWKV は ×1.00、つまり平坦でした。固定の baseline(~205MB = torch ランタイム + 重み)を引くと、Transformer の「文脈に依存して増えるコスト」だけが ~25MB → ~403MB と 超線形に伸びていきます(1024→2048 だけで +277MB)。

かみくだき(working set とは何か): プロセスが「いま実際に物理 RAM に載せているページ」の量です。
ディスクにあるだけ・確保しただけのメモリは含まれません。「実際に触っているメモリの実量」だと思ってください。
peak WS はその最大値。長文を処理するときにメモリが足りなくなるかどうかは、確保量ではなく この実使用ピーク
効きます。だから「解析上こうなるはず」ではなく、わざわざ OS が報告する RSS で裏取りしました。

計測の honest 留保(項分解はしていない): この「超線形」を「二次項 O(T²) が大きな T で支配し始めた」と
読むのは、KV キャッシュが線形・attention 行列が二次という解析モデルからの解釈です。私が測ったのは
プロセスの 合算 peak RSS だけであり、その増分を「KV 線形分」と「attention 二次分」と「中間バッファ分」に
項分解して実測したわけではありません。観測事実は「Transformer の文脈依存コストが超線形に伸びた」までで、
「その超線形が二次項の顕在化である」は解析モデルに基づく解釈である、と区別しておきます。

オーダー記法(Big-O notation)/ O(T²)・O(T)・O(1) — 入力の規模(ここでは文脈長 T)が増えたときに、コストが「どんな勢いで」増えるかをざっくり表す書き方。O(T) は規模に比例(2 倍で 2 倍)、O(T²) は 2 乗で増える(2 倍で 4 倍)、O(1) は規模が増えても一定。数式の細部ではなく「増え方の勢い」だけを見る早見表だと思ってください。

時間軸でも同じ向きが出る(scaling 指数)

メモリだけでなく 推論にかかる時間も同じ T 掃引で測りました(scripts/recurrent_latency_sweep.py / out/recurrent_latency_sweep.json、各点 11 回測定、torch.set_num_threads(1))。T を 128→2048(×16)に伸ばしたときの scaling 指数 p(time ∝ Tᵖ を log-log 最小二乗で推定。混雑に強い min ベース)は、GPT が p≈1.37(明確に超線形、O(T²) 寄り、×16 文脈で ×45.6)/ Recurrent が p≈1.00 / RWKV が p≈0.99(どちらもほぼ線形、O(T)、×16)。メモリで見えた「Transformer は文脈で膨らむ / recurrent・RWKV は構造的に軽い」が、時間軸でも同じ向きで再現しました。

honest 留保(cross-mode の絶対 ms は比較不可): recurrent/RWKV はここでは Python の per-step ループ(T 回の関数呼び出し)で測っており、インタプリタ呼び出しオーバーヘッドが支配的 ──「recurrent の方が速い/遅い」を絶対値で語るのは無意味で、読むのは 各モード内の伸び方(scaling 指数)だけ。なお当初 repeats=7 では RWKV の T=128 が startup ノイズで外れ値になり傾きが汚れた(p≈0.5)が、repeats=11 に増やすと RWKV も p≈0.99 に収束 ── ノイズだった点を消さず、増やして潰した経緯ごと残します。

推論レイテンシのスケーリング(両対数)。各モードを T=128 で正規化し増え方の「形」だけを比較。GPT(赤)は ×16 の文脈で ×45.6 と理想線形(破線 p=1)より上に外れて超線形。recurrent と RWKV(緑、ほぼ重なる)は ×16 文脈で ×16(p≈0.99〜1.00)と破線に沿って線形。takeaway = 速さの勝敗ではなく「長くしたとき各方式がどれだけ急に重くなるか」の癖が構造で違う。

各モードを自分の T=128 で正規化しているので、見るのは「上がり方の急さ」だけ。GPT だけが理想線形(p=1 の破線)から上に外れる=超線形。recurrent と RWKV はほぼ重なって破線に沿う=線形。

さらに鋭い軸 ── decode(1 トークンずつ生成)と amortization

ここまでは「長さ T を まとめて 1 回 forward する」prefill/batch のコストでした。でもチャットの体感遅延を支配するのは、既に T トークンの文脈がある状態で、次の 1 トークンを出す decode のコストです。同じプロセス・同じモデル・同じ条件で、prefill(状態を作る/全文脈を読む)と decode(次の 1 トークン)を両方計時しました(scripts/decode_latency_sweep.py / out/decode_latency_sweep.json計測はメモリ圧の無いクリーンな runner で実施)。

実測(n_embd=256/L4, T=128→2048・×16)はこうです:Recurrent と RWKV は prefill では O(T) で伸びる(×15.6 / ×17.5、指数 p≈1.0)のに、decode では平坦 O(1) に落ちる(×0.98 / ×1.10、p≈-0.002 / 0.03)。一方 GPT は prefill と decode がどの T でもほぼ一致(各 T で prefill≈decode、例:99≈96ms / 958≈957ms)し、両方とも 同じ指数 p≈1.37 で増える。この GPT の decode 指数(1.365)が prefill 指数(1.372)とぴたり一致することが、「cache 無し GPT の decode は prefill と同一計算」の何よりの裏付けです。

prefill(状態構築 O(T))vs decode(次の 1 トークン O(1))の per-token コスト(両対数)。同一ラン内で計測。recurrent / RWKV は prefill が右肩上がり(p≈1.0, O(T))でも decode は平坦(p≈0, O(1))に落ちる=amortization。GPT(KV cache 無)は prefill と decode が重なる(p≈1.37, 分離不可)=毎トークン全文脈を再 forward。takeaway = 長い生成ほど recurrent の「状態に一手足すだけ」が効く。

核心は recurrent の amortization です。 ここで言う「状態(state)」とは、これまでの全部を要約した固定サイズの手帳のようなものだと思ってください。recurrent は「文脈を作る(prefill, T 個のトークンで状態を T 回更新=O(T))」と「作った状態に 1 手足す(decode, O(1))」を分けて払える。長い生成では prefill は最初の一度きりで、その後の毎トークンは O(1) ── これが streaming の体感を決めます。GPT(cache 無)はこの分離ができず、**decode の 1 step が結局 prefill と同じ「全文脈の再 forward」**になる。同じ 1 ランで測ったので、この「recurrent だけ O(T)→O(1) に落ち、GPT は落ちない」が別ラン比較でなく直接の対比として出ています。

ならし(amortization) — 一度だけ大きくかかるコストを、その後の多数回に「ならして」薄く割り当てる考え方。recurrent は最初に状態を作る費用(prefill)を一度払えば、以降は 1 トークンごとの追加費用がほぼ一定になります。ジムの入会金は初回だけで、あとは通うたびの料金が一定、というイメージです。

honest 留保: (1) prefill 同様 cross-mode の絶対 ms は比較不可(recurrent/RWKV は Python per-step ループ計測)。(2) この GPT は KV cache を持ちません。production の LLM serving は KV cache で decode を O(T)/token に落としますが、cache を入れても GPT の decode は T とともに増え続け、recurrent の O(1) 平坦とは質的に別物です。(3) GPT の指数が理論上の 2(O(T²))でなく ~1.37 に留まるのは、この小モデル(n_embd=256)では二次項が完全支配に入りきらない regime。

この差を見たとき、私はそれを「新しい発見」だと一瞬思いました。でも違いました。これは 1960 年代の制御工学が「可観測な系を、有界な状態で運ぶ」問題として整理し尽くしていたことの再演です。RWKV や Mamba が属する 状態空間モデル(State-Space Model, SSM) の「S」は、State(状態)の S です。偶然ではありません。

状態空間モデル(State-Space Model, SSM) — 「過去の履歴ぜんぶ」ではなく「いまの状態」という固定サイズの要約だけを持ち回り、新しい入力が来るたびにその状態を更新していく数理モデル。RWKV や Mamba がこの系統です。次々届く郵便物をいちいち全部保管せず、1 冊の「現状ノート」に書き換えていくイメージで、制御工学が 60 年使ってきた形(この後の節で詳述します)。

まず Transformer 側 — なぜ文脈で膨らむのか(KV キャッシュという「全部とっておく」設計)

Transformer の中核は self-attention(自己注意) です。新しいトークンを処理するとき、それまでの全トークンと「どれくらい関係あるか」を内積で測り、関係の強いものを重み付きで足し込みます。長所は 位置を問わず厳密に照合できること。「3000 トークン前に出た固有名詞」にも、減衰なしで直接アクセスできます。代償は 過去を全部とっておかないと照合できないこと。各トークンの Key(鍵)と Value(値)を KV キャッシュとして保持し続けます。

かみくだき(KV キャッシュとは): attention は各トークンから Query(問い合わせ)・Key(鍵)・Value(中身)
の 3 つを作ります。生成を 1 トークンずつ進めるとき、過去全部の Key と Value を毎回作り直すのは無駄なので、
いったん作った Key/Value を貯めておく。これが KV キャッシュです。便利な作業メモリですが、トークンが増えるほど
線形に増え続けます
。「過去の全観測を生のまま保管する非圧縮メモリ」だと思ってください。

文脈長 T に対するメモリの増え方を、構造プロット(config から計算した理論値)で出すとこうなります。

T(文脈長) Recurrent state(実測) RWKV state(実測) GPT KV キャッシュ(解析) GPT attention 行列(解析)
64 2,048 B 10,240 B 262,144 B 65,536 B
1024 2,048 B 10,240 B 4,194,304 B 16,777,216 B
倍率(文脈 ×16) ×1.00 ×1.00 ×16(線形) ×256(二次)

(scripts/memory_footprint_harness.py / out/mem_footprint.json。state_bytes は実バイト測定、KV/attn は config 由来の解析値。)

Transformer には増えるものが 2 つあります。KV キャッシュは T に 線形(×16 文脈で ×16)、厳密な長文脈 attention のスコア行列は T×T なので T に 二次(×16 文脈で ×256)。フックの実機 peak RSS で「文脈コストが ~25MB→~403MB と超線形」だったのは、大きな T で この二次項(O(T²))が支配し始めたためだと解釈できます(ただし前述どおり、これは解析モデルからの読みであって項分解の実測ではありません)。

honest 留保: 実装上の GPT.generate は内部で文脈を block_size に切り詰める(crop)ので、走らせるだけなら有界です。
上の「線形・二次」は block_size を伸ばして厳密に長文脈を attention する場合に必要になる量です。正確には
「Transformer は必ず爆発する」ではなく「厳密長文脈を諦めない限り、文脈長に線形/二次でコストを払う構造だ」。

recurrent 側 — なぜ平坦なのか(過去を有限の状態に「畳む」)

recurrent モデルは、過去を全部とっておきません。代わりに 固定サイズの状態 s を 1 つ持ち、新しい観測が来るたびに s を更新します。

s_t = f(s_{t-1}, x_t)      # 状態を、前の状態と新入力から更新
y_t = g(s_t)               # 出力は、いまの状態から作る

ポイントは、s_t のサイズが T によらず一定であること。10 トークン処理しても 1 万トークン処理しても、状態テンソルのバイト数は同じです。上表で recurrent state が常に 2,048 B、RWKV state が 10,240 B で一定なのは、これが理由です。

かみくだき(料理のたとえ): Transformer は「これまで使った全食材を冷蔵庫に全部とっておく」やり方、
recurrent は「一つの鍋に次々と具を入れて煮込み続け、鍋の中身(=状態)だけを次に渡す」やり方です。
鍋のサイズは決まっているので、どれだけ煮込んでも置き場所は増えません。ただし煮込むほど、最初に入れた
具の味は薄れます
(= 古い情報の損失)。この「薄れる」が後半の壊れる箇所につながります。

ここで橋を渡す:状態空間モデル(SSM)と制御理論

ここからが第 1 部の核です。recurrent の「定数状態に過去を畳む」は、制御工学の状態空間モデル(SSM)の語彙で書き直せます。これは literature 上の正統な接続です。"Structured State Spaces" は SSM 系 LLM の前身である S4 論文(Gu et al., 2022)のタイトルであり、Mamba(Gu & Dao, 2023)はその直系の発展です。いずれも 状態空間モデル(SSM)は signal processing / control の標準概念です。

なお本節の「書き直せる」は構造的アナロジーであり、数式的同一性の主張ではありません。橋が成り立つのは「逐次状態更新で過去を有限表現に畳む」という骨格のレベルであって、RWKV/Mamba が文字通り線形時不変な状態空間モデルや Kalman フィルタである、という意味ではありません。

状態空間モデルとは(制御工学の 60 年の標準形)

線形時不変な状態空間モデルは、教科書的にはこう書かれます。

x_{t+1} = A x_t + B u_t      # 状態方程式:次の状態 = A×いまの状態 + B×入力
y_t     = C x_t + D u_t      # 観測方程式:出力 = C×状態 (+ D×入力)
  • x = 状態(state)。系の「これまでの全履歴を要約した有限次元ベクトル」。
  • A = 状態遷移行列。「過去の状態をどれだけ次に引き継ぐか」を決める。

決定的なのは、x が有限次元で固定サイズであること。制御工学は最初から「無限に続く入力の歴史を、有限の状態に圧縮して運ぶ」ことを前提に組み立てられています。RWKV/Mamba の s_t = f(s_{t-1}, x_t) は、まさにこの状態方程式の(非線形ゲート付きの)親戚です。

かみくだき(なぜ制御工学はこの形なのか): 工場のプラントやロケットの姿勢制御では、過去のセンサー値を
全部保存して毎回参照する余裕などありません。「いまの状態さえ分かれば、次にどう動くか決められる」形に
しておく必要がある。だから制御工学は、最初から「過去全部を有限の状態に畳む」を出発点にしたのです。
LLM の長文脈問題で recurrent が再発見したのは、この 60 年来の出発点でした。

可観測性 — 「有限の状態に過去を畳んで本当に足りるのか?」

制御工学には 可観測性(observability) という概念があります。ざっくり「出力 y の履歴を見れば、内部状態 x を一意に復元できるか?」という性質です。これが recurrent の「定数状態で本当に大丈夫か」という不安に、そのまま対応します。状態次元が、区別したい過去の弁別に対して不足していれば、区別すべき 2 つの過去が同じ状態に潰れてしまう(可観測でなくなる)。逆に状態次元が必要な弁別に対して十分なら、定数状態でも必要な区別は保たれます。Transformer が「過去を全部とっておく」のは、可観測性を 力技で常に保証しているとも読めます。

Kalman フィルタ — 「観測を状態の更新に畳み続ける」発想の元祖

1960 年、ルドルフ・カルマン博士(Rudolf E. Kálmán)が定式化した Kalman フィルタ(A New Approach to Linear Filtering and Prediction Problems, 1960)は、まさに「次々と来る観測を、固定サイズの状態推定(と共分散)に畳み込み続ける」アルゴリズムです。新しい観測が来るたびに、過去全部を再計算せず、いまの状態推定を更新するだけ。RWKV/Mamba が「KV キャッシュを捨てて、固定状態を更新し続ける」のは、構造としては Kalman 以来の「逐次状態更新」の発想と同じ骨格です。Transformer の KV キャッシュは、この対極 ── 観測を畳まずに生のまま全部ためる非圧縮表現です。

★ここが「橋が折れる箇所」その 1(文字通り Kalman ではない): RWKV/Mamba を「Kalman フィルタだ」と
言い切るのは 誤りです。Kalman フィルタは線形ガウス系の最適推定で、明示的な観測モデル・ノイズ共分散・
最適性の証明を持ちます。RWKV/Mamba は 非線形ゲート(tanh / sigmoid / 入力依存の遷移)を持ち、行列は
データから学習され、最適性の保証もありません。両者が共有するのは「逐次状態更新で過去を有限表現に畳む
という構造的骨格だけです。本記事の主張は終始 構造的アナロジーであって、数式的同一性ではありません。

だから recurrent の「平坦さ」は config の偶然ではなく構造的必然

ここまで来ると、フックの「recurrent peak WS が T によらず ×1.00」が、私の実験設定の偶然ではないと分かります。状態空間モデルは 定義からして 状態が有限次元固定です。文脈をいくら伸ばしても、運ぶのは同じサイズの x(状態)だけ。両者の差は実装の調整幅ではなく、過去をどう表現するか(畳むか/ためるか)というアーキテクチャの根本選択です。

★最重要 fix — ρ(収縮性)を「過剰接続」しない

この種のクロスドメイン記事が一番やらかしやすい混同を、先回りして潰します。制御工学を持ち出すと、つい 「安定性(収縮性)」と「学習が安定境界に張り付く」を一緒くたにして、きれいな物語にしてしまう。これは間違いです。

(A) 収縮写像 ρ<1 = 安定性の証明(構造的に要求するもの)
llcore の別アーク(検証付き可塑性)では、frozen な LLM の隠れ状態に小さな recurrent アダプタ s' = decay⊙s + (1−decay)⊙tanh(Ws + x) を後付けし、その安定性を証明付きで担保しています。ヤコビアン J のスペクトル半径 ρ(J)<1 なら、状態更新は 収縮写像になり、小さな摂動は時間とともに減衰します(echo-state property)。llcore の証明器(cert_inf: ‖J‖_∞<1、cert_two: 全頂点で σ_max<1、cert_sdp: 共通 Lyapunov LMI)は ρ(J)<1 を満たすものだけを fail-closed で通しますempirical_rho(下から固有値を詰める独立オラクル)が証明の健全性をチェックします。

フェイルクローズド(fail-closed) — 検証に通った確証があるものだけを許可し、少しでも怪しい・確認できないものは既定で拒否する安全設計。鍵の確認が取れなければ自動でドアを閉める方式で、「迷ったら通す」のではなく「迷ったら止める」が原則です。

かみくだき(収縮写像とは): 入力をちょっとずらしたとき、出力のずれが 元のずれより必ず小さくなる写像。
何度繰り返してもずれが拡大しないので、系は暴走せず一点に落ち着きます。ρ<1 がその数学的な合格ライン。

(B) 学習が安定境界 ρ≈1 に張り付く(表現力との緊張、観測される現象)
別の実験(M2)では、進化探索で fitness 最良の個体の empirical_rho が 1.000 に張り付くという観測が出ました。これは「表現力を最大化しようとすると、状態更新が 安定性の崖っぷち(ρ→1) に寄っていく」という、リザバー計算や recurrent 学習で知られた 表現力 vs 安定性のトレードオフの現れです。

ここで「制御理論が ρ<1 を安定の条件と言い、学習も ρ≈1 に行く。だから制御理論が edge of chaos まで予言していた!」と 一本の美しい物語に縫い合わせたくなる。これが過剰接続です。両者は 方向が逆です。(A) は「ρ<1留めておけ」(私たちが課す上限規範)。(B) は「ρ が 1 に 寄っていく」(最適化が見せる挙動)。同じ記号 ρ を使うので一見つながって見えますが、論理的には独立です。

だから本記事の正しい言い方: 制御理論は **(A)「定数状態で過去を運ぶ + その安定性を ρ<1
特徴づける」**を 60 年前に解いていた。一方 (B)「安定境界 ρ≈1 に表現力が張り付く」は、安定性と表現力の
緊張という、制御と機械学習の双方が別々に知っている既知のトレードオフ
であって、(A) から自動的に出てくる
ものではない。両者を区別したうえで並べる — これが honest な接続です。

★橋が折れるもう 1 つの箇所 — recurrent は capability で Transformer に劣る「かもしれない」

ここまで recurrent の メモリ軸の構造的勝ちを書いてきました。しかしこれを「だから recurrent が Transformer に勝つ」で締めたら我田引水であり、連載トップの caveat に反します。正直に書きます。

llcore の進化探索アークでは、recurrent 系アダプタの capability(賢さ — perplexity / cross-entropy で勾配を上回るか) を測った結果、地形は NULL_TIE / NEGATIVE(進化が baseline に対して有意差なし〜むしろ微害)でした。つまり llcore 自身が「この特定の実験設定では、recurrent の進化に capability の勝ち筋は確認できなかった」と認めています(project_llcore_memory_efficiency_pivot、北極星を capability から memory へ転換した直接の理由)。

パープレキシティ(perplexity, PPL) — 言語モデルが次の単語をどれだけ言い当てられるかを測る指標で、低いほど賢い(=次に来る語に迷っていない)。「平均して何択で迷っているか」の目安だと思ってください(PPL=10 なら 10 択でうろうろしている感覚)。その対数をとった姉妹指標が cross-entropy(交差エントロピー)損失です。

honest disclosure / ソースの境界: 次に述べる literature 一般傾向と、いま述べた llcore の null 結果は、
出どころが違います。前者は SSM 文献で一般に指摘される傾向=本記事では llcore 実測で直接検証していない
外部知識です。後者(NULL_TIE / NEGATIVE)は llcore の特定実験設定での自前 null 結果=ソースは llcore 実測です。

その literature 一般傾向はこうです ── KV キャッシュの「全観測を厳密に保持する」性質は、位置を問わない厳密な long-range recall(長距離の正確な呼び戻し) で recurrent の lossy 圧縮状態に勝ちやすい、と SSM 文献で一般に指摘されます。recall 重視のタスクでは純 recurrent がしばしば Transformer に劣るとされ、だからこそ実用 SSM の多くが attention 層を織り交ぜる hybrid に向かう、というのが文献上よく見る整理です(例:Jamba は Mamba と Transformer を交互に積むハイブリッド)。

料理のたとえで触れた「煮込むほど最初の具の味が薄れる」── あれが capability 側で効いてくる症状です。状態次元が、必要な弁別に対して不足する場合に、固定サイズの状態に過去を畳む過程で、どこかで弁別すべき過去が潰れる。メモリで勝つ仕組みが、状態次元が不足したときには capability の弱点の源にもなりうる、ということです。

だから本記事の主張は「メモリ軸に限定」されます。 「recurrent は文脈長によらず定数メモリで動く」は構造的に正しい(私の実測 ×1.00 が示す)。しかし「recurrent が総合的に Transformer より優れる」とは 言いません。むしろ llcore は、この設定で capability の勝ち筋を確認できなかったと認めたうえで、勝てる軸(メモリ効率)へ北極星を移した — その正直な敗北の上に、この記事は立っています。

第 1 部の比喩 — 「日記を全文保管する人」と「要約だけ更新する人」

2 人の人が毎日 日記をつけています。

  • A さん(Transformer) は、毎日の出来事を 全文そのままノートに書き溜めます。何年前のことでも、ページをめくれば一字一句 正確に思い出せます。代わりにノートは年々分厚くなり、ある日とうとう本棚に入りきらなくなります(KV キャッシュの線形膨張)。さらに「過去の全ページ同士を突き合わせる」癖があるので、ページ数の二乗で手間が増えます(attention の O(T²))。
  • B さん(recurrent / SSM) は、毎晩 その日の出来事を一文の要約に畳んで、たった 1 枚の「現在のまとめカード」を更新するだけです。カードは何年経っても 1 枚のまま。本棚は一切増えません(定数状態 ×1.00)。制御工学者やカルマン博士が 60 年前に「これで十分なことが多い」と整理したやり方です。

この比喩がどこで折れるか: (1) B さんのカードは 要約なので、「3 年前の何月何日に誰が何と言ったか」を一字一句問われると A さんに負けます(lossy 圧縮 = capability の弱点)。(2) 要約欄(=状態次元)が必要な弁別に対して狭すぎると、区別すべき 2 日が同じ要約に潰れます(可観測性の喪失)。情報を詰め込みすぎるとカード更新が安定の崖っぷち(ρ≈1)に近づきます ── ただしこれは「カードを 1 枚に保つ」設計とは別の話で、混ぜてはいけません。(3) そもそも B さんは「カルマン博士と同じこと」をしているわけではなく、骨格が似ているだけで非線形・最適性保証なしです。

比喩は理解の足場であって、証明ではない。足場が崩れる場所を示したうえで使う ── これが本連載の作法です。

黒髪の女性が目を見開いた真顔のドアップで「何が面白いのこの話?」と問い返し、左下で金髪の女性が汗をかいて「コラっ!!」と抗議しているコマ

🗒️ 「何が面白いのこの話?」— 可観測性・収縮写像・カルマンフィルタと続いたので、読者代表のツッコミをここに一枚。次からは実機の数字です(© Forbidden shibukawa / SHUEISHA・『スナックバス江』)


第 2 部(a8)— 文脈を 4 倍にしたら Transformer のメモリは 5 倍に膨れ、recurrent は 1mm も動かなかった

第 1 部で「制御理論はとっくに『定数状態で過去を運ぶ』を解いていた」という橋を架けました。第 2 部はその実機メモリでの帰結です。動的支配項 ── 文脈長で伸びる項を、曲線で見せます。

別の記事で、私は長文脈の検索性能を測ろうとして 自宅マシン(RAM 3.6GB)のメモリが先に音を上げた話を書きました。2048 トークンの full-attention forward が working set 3.9GB に膨れてスワップした。あれは事故のように見えて、実は構造が予告していた必然です。

結論を先に: 文脈長を 1024 → 4096 トークン(4 倍)にしたとき、Transformer(GPT)の peak メモリは
331.8MB → 1673.0MB と約 5.04 倍に膨れた。同じ条件で recurrent は 205.4MB → 205.6MB、つまり 1mm も動かなかった

数字の全公開 ── 点でなく曲線で読む

軽量モデルを 3 アーキテクチャ用意し(GPT / recurrent / RWKV)、文脈長を変えながら 別プロセスに隔離して peak working set(WinAPI の PeakWorkingSetSize)を実測しました。scripts/recurrent_runtime_rss.py --lengths 128,256,512,1024,2048,4096(実機 2026-06、極小モデル n_embd 256 / 4 層 / 8 head)。単点でなく 32 倍レンジの曲線で見ます。

文脈長 L GPT peak WS recurrent peak WS RWKV peak WS
128 222.3 MB 205.5 MB 215.4 MB
256 230.7 MB 205.2 MB 215.7 MB
512 247.7 MB 205.3 MB 216.1 MB
1024 331.8 MB 205.4 MB 216.0 MB
2048 607.9 MB 205.6 MB 216.0 MB
4096 1673.0 MB 205.6 MB 215.9 MB
128→4096(×32)の倍率 ×7.53 ×1.00 ×1.00

曲線の形が一番の証拠です。 GPT の膨張率は計測レンジに依存します:128→512(×4)では ×1.11 とほぼ平坦 ── この領域は固定重み(モデル本体)が peak を支配し、attention の O(L²) 項はまだ誤差に埋もれます。ところが 512→4096(×8)では ×6.75 ── ここで二次項が固定床を追い越し、曲線が跳ね上がります。「文脈 ×N でメモリ ×M」という単一の見出しは、どこから測ったかで M が激変する(同じ装置で ×1.11 にも ×6.75 にもなる)。だから単点でなく曲線で出します。recurrent / RWKV は全域で 205 / 216 MB に貼り付き(×1.00)、定数状態が文脈長と無関係であることを 32 倍レンジで裏取りしました。

補足: 1024 と 2048 の点は別日の独立ラン(out/recurrent_runtime_rss_long.json)と 0.1 MB 差で一致し、クロスラン再現性も確認済み。

文脈長 128→4096(対数軸)で GPT の peak WS が、短文脈(128→512)では 222→248MB とほぼ平坦(固定重み床が支配、×1.11)なのに長文脈で 608→1673MB へ急騰(二次項が顕在化、×6.75)する一方、recurrent/RWKV は 205MB で全域平坦(×1.00)という折れ線グラフ。takeaway = 膨らみ方は一定でなく、どこから測るかで倍率が激変する=点でなく曲線で読め。

図:横軸は対数。GPT(赤)は短文脈で固定重み床に隠れてほぼ平坦、長文脈で二次項が顔を出し急騰(全レンジ 128→4096 で ×7.53)。recurrent/RWKV(緑)は定数状態で全域平坦(×1.00)。T=4096 で GPT は recurrent の 8.1×。

読みどころは 3 つです。

  1. GPT は超線形に膨れる。 文脈 4 倍(1024→4096)で メモリ 5.04 倍、全レンジ 32 倍で 7.53 倍。attention のスコア行列が L×L、つまり O(L²) で増えるため。伸び方は一定でなく、短い文脈ほど固定重みに隠れて平坦、長くなるほど二次項が顔を出して鋭くなる。
  2. recurrent と RWKV は動かない。 文脈 4 倍でも ×1.00。過去を固定サイズの状態に畳むので、文脈長に依存する項が原理的に無い。
  3. T=4096 で GPT 1673MB は recurrent 205MB の 8.1 倍。 外挿すると T=8192 で GPT は約 6.5GB ── 私の自宅マシン(3.6GB RAM)では物理的に載らない壁。一方 recurrent は 205MB のまま、びくともしない。

私のマシンがスワップした 3.9GB は、まさにこの曲線の上の点でした。事故ではなく、O(L²) の予告どおりだったわけです。

かみくだき(会議のたとえ): 10 人の会議で全員が「他の全員の発言」をいちいち確認しながら話すと、確認の
組み合わせは人数の 2 乗で増える(5 人なら 25 通り、10 人なら 100 通り)。これが Transformer の O(L²)。
一方 recurrent は「一冊のノートを回し、各人が要点だけ書き足して次へ渡す」やり方 ── ノートの厚さは人数が
増えても変わらない。ただしこの“まとめノート”は lossy で一語一句は復元できません(平坦なメモリの代償)。

なぜこうなるのか(構造の話)

GPT の attention は「全トークンが全トークンを見る」総当たりです。トークンが L 個あれば見る組み合わせは L×L だから、メモリも計算も O(L²)。さらに KV キャッシュは O(L) でメモリを食い続けます。recurrent / RWKV は発想が逆で、過去を 1 つずつ読みながら固定サイズの状態ベクトルに畳み込み、それを次へ運ぶ。状態の大きさは文脈長に依存しない(中身は数 KB の定数)。これは第 1 部の「制御理論の状態空間モデル」そのもの。理論が「定数状態で過去を運べる」と言っていたことが、実機の peak WS で平坦な直線として現れた、という話です。

隠さない但し書き(この数字の限界)

  • 極小・未学習モデルです。 n_embd 256 / 4 層のランダム初期化モデル。メモリ挙動はアーキテクチャで決まり学習状態に依存しない(ので計測には妥当)ですが、絶対値を大手 LLM にそのまま当てはめないでください。読むべきは増え方のトレンドです。
  • peak WS は「素の torch ランタイム + 固定の重み + 文脈依存バッファ」の合算です。 recurrent の「平坦 205MB」の大半は torch のベースライン(第 3 部で測る支配項)で、定数状態そのものは KB オーダー。つまり 205MB は「定数状態が重い」のではなく「伸びる項が無い」ことを示しています。
  • GPT は実運用では block_size で文脈を切り詰めるので、ここまで素直には膨れません。本測定は「厳密に長文脈を保持するなら最低どれだけ要るか」の必要量を見たものです。

第 2 部の教訓 — 「速さ」より「予測可能性」

長文脈の時代に効いてくるのは、ピーク性能より 「メモリが文脈長に対してどう振る舞うか予測できること」 です。GPT は速いし強い。でも文脈が伸びると、メモリが O(L²) で予測不能な崖に向かう。recurrent は遅くても、何トークン来ても 205MB で平らなまま ── 予測できる。

量子化は「今あるものを薄く削る」。
アーキテクチャ選択は「伸びる項を最初から持たない」。
長文脈ほど、後者が構造で前者を引き離す。

この「量子化(bit を削る)では頭打ちがある、本命は動的支配項を持たないアーキテクチャを選ぶこと」という結論が、次の第 3 部 ── 静的支配項 ── にそのまま接続します。


第 3 部(a9)— 最適化する項を間違えていた:int8 で 4MB 削った隣で、言語ランタイムが 184MB 食っていた

第 2 部は「文脈を長くすると Transformer のメモリが 2 乗で膨らむ」という動的な支配項の話でした。第 3 部はその裏側、静的な支配項の話です。

きっかけは、よくある一言でした。

「メモリ効率を徹底するなら、いっそ Rust で書き直したら? そのほうが効率的でしょ。」

もっともらしい。でも私は、この種の「○○にすれば効率が上がる」を自動で正しいと信じないことにしています。なので測りました。結果は、私の最適化の前提を引っくり返すものでした。

int8 量子化でモデルの重みを約 4 分の 1(数 MB)に削っていたその隣で、Python+torch の言語ランタイムが、
何もしなくても 184MB を食っていた。
削っていた項が、そもそも支配項ではなかったのです。

数字の全公開と、衝撃の比率

ctypes から Windows の GetProcessMemoryInfo(WorkingSetSize)を直接叩き、プロセスの RSS を段階的に実測しました。

段階 プロセス RSS
Python インタプリタ baseline 13.4 MB
import torch 197.3 MB(+183.9 MB の "torch 税")
モデルロード後 213.6 MB
モデル int8 重みの実体 1.51 MB

ここから出る比率が効きます。

プロセス RSS 213.6MB は、モデル本体 1.51MB の約 142 倍。

私は int8 量子化で「重みを 4 分の 1!」と数 MB を削ることに集中していました。でも全体像は、1.51MB の本体の周りに、212MB の"足場"が組まれている状態だったのです。数 MB の節約は、142 倍の足場の前では誤差に近い。

かみくだき(荷物と台車のたとえ): 引っ越しで荷物を 4kg 軽くしようと一生懸命パッキングを見直した。えらい。
でも、その荷物を載せている台車そのものが 184kg あったとしたら? 4kg の節約は、184kg の台車の前では
ほとんど意味がありません。軽くすべきだったのは荷物じゃなくて、台車のほうだった。私の AI で、まさに
これが起きていました。

プロセス RSS 213.6MB の内訳を実測した積み上げ棒グラフ。torch 税 183.9MB(言語ランタイムの足場)が大半を占め、int8 重み本体 1.51MB は同じ横スケールではほぼ線になる。別ランでも torch 後 197.8MB / 税 179.7MB と ~2% 差で再現。takeaway = 支配項は削っていた本体ではなく言語ランタイムの足場(本体の約 142 倍)だった。

削っていた項(int8 本体 1.51MB)は、同じ横スケールでは細い線にしかならない。支配項は torch 税 183.9MB の足場だった。

再現性(コミット済みハーネスで裏取り): この一回限りの計測を、後日 再走可能なハーネス
(scripts/runtime_floor_rss.py / out/runtime_floor_rss.json、各ステージを別プロセス隔離で 3 回測定の中央値)に
固めて測り直しました。結果は import torch 後 197.8 MB(初回 197.3 とほぼ完全一致)/ torch 税 179.7 MB
(初回 +183.9 と ~2% 差)
── 主役である torch ランタイム税が ~180MB であることは別ランでも揺るぎません
でした。一方 baseline は 13.4→18.1 MB と少し上振れし、足場比は モデルの大きさで変わります:本文の 1.51MB
モデルでは 142×、ハーネス既定の 2.8MB モデル(n_embd=176)では 73×。比の絶対値は config 依存ですが、
「本体より足場が桁違いに大きい」という構図は不変 ── そこが load-bearing です。

「支配項を攻めろ」— どの項を削るかが全て

最適化には鉄則があります。一番大きい項(支配項)を攻めろ。小さい項をいくら磨いても全体はほとんど動かない。

  • 動的な支配項は文脈長で伸びる attention/KV(第 2 部で測った O(L²))。
  • 静的な支配項は、この第 3 部の 言語ランタイムの baseline(torch だけで +184MB)

豆モデル規模では、後者(184MB の torch 税)が圧倒的に支配的でした。だとすれば、本当に効くのは int8 の数 MB ではなく、この 184MB の足場をどう減らすか

そしてここが「Rust にすれば?」の真の効きどころです。lean な native バイナリ(C++ の llama.cpp、Rust の candle / mistral.rs 等)は、ランタイム baseline が桁違いに小さい(典型で数 MB〜十数 MB)。184MB 規模の削減は、int8 の数 MB とは比較にならない大きさで、「working set を小さく予測可能に」という北極星に直結します。さらに Rust なら allocator を自分で握れるので、「解放した fp32 を torch の caching allocator が OS に返さず、平時のピークが下がらない」という別の積年の問題も、madvise(MADV_DONTNEED) や明示解放で正攻法で潰せます。

隠さない反対側(「Rust=効率↑」も自動ではない)

ここで止まると「Rust 万能論」になってしまう。honest disclosure として反対側を明示します。

  • Rust は int8 を小さくも、mmap を良くも、定数状態を定数にもしません。 これらの勝ちは表現・OS・アルゴリズム由来で 言語非依存。Rust に移しても 1 バイトも改善しない。Rust が効くのは baseline(足場) の項だけです。
  • 素の Rust の行列積は、torch の BLAS(MKL/OpenBLAS)より遅い。 「Rust=速い」も自動ではありません。速度を出すには candle や BLAS バインディングが要る。
  • 規模依存が肝。 184MB の税が支配的なのは豆モデル規模だから。GB 級の重みになれば baseline は相対的に無視できる。つまり Rust の baseline 優位は、llcore が実際に住む領域(小モデル・小 RAM)で最大、重みが支配する大規模で最小
  • これは llama.cpp が既に実証済みの動き。 立ち位置としては「再導出」であり、誠実な独自性はそこ(言語)ではなく、別記事で書いた cap-gate(能力ゲート)の運用にあります。
  • 未確証(honest gap)。 Rust/candle 版の baseline RSS はまだ測っていません。「native なら baseline が桁違いに小さい」は文献・既存実装からの妥当な推定で、最終確証には candle 実測が要ります。

第 3 部の教訓 — Rust に書き直す前に、baseline を測れ

「○○にすれば効率が上がる」と聞いたら、書き直す前に今の支配項を測れ
私の支配項は int8 で削れる重みではなく、torch を import した瞬間の 184MB だった。

もし測らずに「メモリ効率のために Rust へ全面移植」と走っていたら、労力の大半は「言語非依存の勝ち(int8/mmap/定数状態)を Rust で書き直すだけ」に消え、本当に効く 184MB の baseline 削減という主目的が埋もれていたでしょう。狙いを『推論パスを native 化して interpreter 税を消す』に絞る ── それが、測ってはじめて見えた正しい移植方針でした(速度狙いではなく、足場狙い)。

最適化は、磨く前に「どの項が大きいか」を測る。当たり前のようで、4MB を削りながら 184MB を見落としていた私自身が、一番それを忘れていました。この「測ってから手を動かせ」という規律が、最後の第 4 部の普遍教訓につながります。

丸眼鏡の男の顔と力こぶを立てた太い腕のアップに「得策 得策 得策 得策」の描き文字が乱舞し、左から「思い込みが激しいわねぇ…」と冷ややかにツッコまれているコマ

🗒️ 「思い込みが激しいわねぇ…」— 「Rust にすれば効率が上がる」も「int8 で削れば軽くなる」も、実測する前はだいたいこの顔をしている(© Forbidden shibukawa / SHUEISHA・『スナックバス江』)


第 4 部(a11)— テストが flaky なのは、テストのせいではなく設計のサインだった

ここまでは AI アーキテクチャの支配項の話でした。最後はやや毛色を変えて、**「テストの書きにくさが、設計の臭いを教えてくれた」**という普遍的なエンジニアリングの一場面です。AI 固有ではなく、ものづくり全般に効く小ネタ ── でも「支配項を測れ」と同じく、症状の出どころを取り違えるなという同じ規律の話です。

やりたかったことと、揺れたテスト

能力検収(cap-gate)に PASS したときだけ、量子化済みモデルを保存する」という昇格ゲートを TDD(テスト駆動)で書こうとしました。仕様はシンプル: gate が PASS → 書く、FAIL → 書かない。

ところが、テストが **flaky(実行のたびに結果が揺れる)**になりました。あるときは合格、あるときは不合格。これでは「ちゃんと動く」と言い切れません。

原因は、テスト対象に使った未学習(ランダム初期化)モデルでした。ランダムモデルの「次トークン予測」はほぼ一様分布です。そこへ int8 量子化のわずかなノイズが乗ると、top-1(最有力候補)が境界をまたいで入れ替わる。結果、retention(能力維持率)が合格ラインの上下をフラフラし、「PASS のとき書く」を CLI 経由で丸ごとテストすると、PASS/FAIL が実行ごとに変わってしまう。

保持率(retention) — 量子化(bit 削減)などで軽くした後に、元のモデルの能力がどれだけ残っているかの割合。元の味をどれだけ保てているかの「合格点つき味見」のようなもので、合格ラインを割ったら昇格させない、という使い方をします。

かみくだき(top-1 とは): モデルが「次に来る最有力候補」として 1 位に挙げる選択肢のこと。候補がほぼ
横並び(一様分布)のとき、ごくわずかなノイズで 1 位と 2 位が入れ替わります。これが判定のブレの源でした。

ここで「テストにリトライを入れて誤魔化す」のは悪手です。flaky は、たいていテストの問題ではなく設計の問題だからです。

TDD の格言 — 「テストしにくい = 設計が不明瞭」

テスト駆動開発に、こういう経験則があります。

テストが書きにくいときは、テストが悪いのではなく、設計が不明瞭か、結合が強すぎる。

このレンズで自分のコードを見ると、原因が見えました。「昇格するか否かの判定ロジック」と「ファイルを書くという入出力(I/O)」が、1 つの関数に混ざっていたのです。判定と I/O が癒着しているから、判定だけを単体で確かめられず、毎回 I/O 込みの非決定的な経路を通すしかなかった。

かみくだき(料理のたとえ): 味見をしたいのに「味付け」と「盛り付け」を同じ一手でやってしまっている
料理人を想像してください。味だけ確かめたいのに、毎回お皿に盛るところまでやらないと味が分からない。
しかも盛り付けの出来が日によってブレるので、味の判定までブレてしまう。私のプログラムがまさにこれでした。

直し方 — 判定を純関数に切り出す

そこで、判定だけを純関数(同じ入力なら必ず同じ出力を返し、副作用が無い関数)に切り出しました。

_should_promote(report, force) -> (bool, reason)

report(能力検収の結果)と force(強制フラグ)を渡すと、「昇格すべきか」と「その理由」を返すだけ。ファイルは書かない。すると ──

  • 判定ロジックは、手作りの検収結果(gate = PASS / FAIL / 未測定 の 3 通り × force 有無)を渡して、決定的にテストできる。
  • CLI 統合テストは、非決定性を避けて決定的な経路だけに限定する(「retention 下限を 0.0 にして必ず PASS」「コーパス未指定で必ず拒否」)。

flaky は消えました。テストにリトライを足したのではなく、判定と I/O を分離したから。

BEFORE/AFTER 比較図。左(BEFORE)は「判定」と「ファイル書込」が 1 関数に癒着し、int8 ノイズで top-1 が境界をまたいで CLI 丸ごとテストが PASS/FAIL を揺らす。右(AFTER)は判定だけを純関数 _should_promote → (bool, reason) に切り出し、判定の単体テスト(gate=PASS/FAIL/未測定 × force)と CLI の決定的経路(--min-retention 0.0 → PASS / コーパス無 → 拒否)のみに分離して flaky が消滅。takeaway = テストの揺れは「設計を分けろ」という無料のレビュアー。

判定と I/O の癒着(左)を、判定の純関数化で分離(右)した前後比較。

第 4 部の教訓 — flaky を「テストの不運」で片付けない

flaky なテストを見ると、つい「環境のせい」「たまたま」と片付けたくなります。でも多くの場合、それは設計が何かを混ぜているサインです。

テストが書きにくい・揺れる ──
それは「テストを直せ」ではなく「設計を分けろ」という信号。

今回は「判定」と「入出力」が癒着していた。分離したら、テストは決定的になり、コードも読みやすくなった。テストの難しさは、設計の改善ポイントを指し示す無料のレビュアーです。AI の小さなツールづくりでも、この古典的な原則はそのまま効きました。


統合の自己監査 / honest disclosure

career-grade の規律として、本アーク全体の主張に自分で刃を当てます。

  • 規模: すべての実測値(×1.00 / ×2.65 / ×7.53 / 142× / 状態 2,048〜10,240 B / torch 税 184MB)は 0.81M〜130M の tiny char-LM を CPU で測ったものです。12B〜64B の実 LLM で同じ平坦さ・同じ膨張が 同じ比率で出る保証はありません。傾きの 向きは literature と整合しますが、絶対値の外挿は未保証です。
  • 計測のクリーンさ(項分解はしていない): peak WS は torch ランタイム + 固定重み + 文脈依存バッファの 合算で、クリーンな信号は固定 baseline(~205MB)を引いた 増分トレンドです。その増分を「KV 線形分」「attention 二次分」に項分解して実測したわけではなく、「超線形 = 二次項の顕在化」は解析モデルからの解釈です。
  • アナロジーの留保: SSM / 可観測性 / 収縮写像 / Kalman フィルタとの対応は 構造的アナロジーです。RWKV/Mamba が文字通り状態空間モデルや Kalman フィルタである、とは主張しません(非線形ゲート・学習行列・最適性なし)。
  • ρ の非混同:ρ<1 = 安定性の証明(課す制約)」と「ρ≈1 への張り付き = 表現力 vs 安定性のトレードオフ(観測される現象)」を区別しました。前者から後者は自動で出ません。
  • ソースの境界: capability 結論の NULL_TIE / NEGATIVE は llcore の自前 null 実測、**「純 recurrent は recall で劣りがち / 実用 SSM は hybrid に向かう」は SSM 文献の一般傾向(本記事では未検証の外部知識)**です。
  • capability の正直な敗北: recurrent の capability 地形は llcore 自身が NULL_TIE / NEGATIVE と認定済み。本アークの優位主張は メモリ軸に限定で、総合的な capability 優位ではありません。
  • Rust の未確証: Rust/candle の baseline RSS は未計測。「native なら baseline が桁違いに小さい」は文献・既存実装からの推定で、最終確証には candle 実測が要ります。
  • アナロジーは 1 本柱: SSM / 制御理論の 1 本のみに絞り、edge of chaos やリザバー計算の別アナロジーを足していません(過剰接続の回避)。

結び — 「再演」を恥じず、「同一」を誇張せず、支配項を測れ

このアークで私が自宅 CPU で測ったもの ── 「文脈長 ×8 で Transformer ×2.65 / recurrent ×1.00」「×32 で ×7.53 vs ×1.00」「int8 本体 1.51MB の隣で torch 税 184MB」── は、どれも新発見ではありません。60 年前の制御工学が「定数状態で過去を運ぶ + その安定性を ρ<1 で特徴づける」を整理し尽くしていた問題の、char-LM スケールでの再演であり、最適化の鉄則「支配項を攻めろ」の素直な適用です。

でも、再演には価値があります。

  1. 構造が腑に落ちる。 recurrent の平坦さは config の偶然ではなく、状態空間モデルの定義からくる構造的必然だと分かる。だから「この族はメモリ軸で構造的に勝つ」と言える。
  2. 過大主張を防げる。 制御理論の語彙を借りると同時に、その語彙が どこで折れるか(文字通り Kalman ではない / capability では劣りうる / ρ<1ρ≈1 は別 / (A) は解けても (B) は予言していない)も見える。借り物の権威で論を盛らずに済む。

そして 4 本を貫く通底テーマは一貫しています ── 「bit を下げる」のではなく「アーキテクチャと支配項を攻める」

  • 量子化で int8 の数 MB を削るより、文脈で伸びる動的支配項(O(L²))を持たないアーキテクチャを選ぶ方が、長文脈では桁違いに効く(第 2 部)。
  • Rust に書き直す前に、静的支配項(184MB の言語ランタイム足場)を測る方が、削るべき項を間違えずに済む(第 3 部)。
  • そして、テストが揺れたら症状の出どころ(設計の癒着)を測って分離する ── これも「一番効く所を測ってから手を動かせ」という同じ規律です(第 4 部)。

LLM の長文脈・低メモリ競争は、突き詰めると 「過去をどこにどう持つか」「どの項が支配的か」 という、制御工学と最適化の古典が半世紀前に向き合った問いに収束します。Transformer は「全部とっておく」で位置厳密性を買い、メモリで払う。recurrent/SSM は「有限状態に畳む」でメモリを節約し、弁別の鋭さで払う。どちらが正しいかではなく、どの軸で払うかの選択であり、その地図の (A) の部分を制御工学はとっくに描いていた ── それが、本アーク「構造で勝つ」の渡り終わりです。

次のアークでは、この「構造で勝つ」思想を、計測規律そのもの(自分の勝ちを疑う honest disclosure)と、ローカル / on-prem という FullSense の文脈接続へと広げていきます。


参照(Qiita 投稿時は commit / file 参照に置換)

  • llcore 実測正本: docs/MEMORY_EFFICIENCY_FINDINGS.md
  • harness: scripts/memory_footprint_harness.py(out/mem_footprint.json)、scripts/recurrent_runtime_rss.py(out/recurrent_runtime_rss.json / 32×曲線 out/recurrent_runtime_rss_curve32.json)、scripts/recurrent_latency_sweep.py(out/recurrent_latency_sweep.json)、scripts/decode_latency_sweep.py(out/decode_latency_sweep.json)、scripts/runtime_floor_rss.py(out/runtime_floor_rss.json)
  • ρ<1 証明器と empirical_rho: 検証付き可塑性アーク(cert_inf / cert_two / cert_sdpempirical_rho 独立オラクル)
  • a11 実装: src/llcore/memory.py_should_promote(純関数)、tests/unit/test_memory_facade.py
  • 制御理論側(一次概念): 状態空間モデル(SSM)/ 可観測性 / 収縮写像 ρ<1 / Kalman フィルタ(R. E. Kálmán, 1960, A New Approach to Linear Filtering and Prediction Problems)
  • SSM 系 LLM: S4(Gu et al., 2022, Efficiently Modeling Long Sequences with Structured State Spaces)/ Mamba(Gu & Dao, 2023, Mamba: Linear-Time Sequence Modeling with Selective State Spaces)/ RWKV / hybrid 例 Jamba(Mamba × Transformer 交互)
  • capability 留保: project_llcore_memory_efficiency_pivot(北極星を capability → memory へ転換、recurrent capability = NULL_TIE / NEGATIVE = llcore 自前 null 実測)

B アーク — 負けを見せる(honest disclosure の物語)

技術記事のクライマックスは、たいてい「競合 X を Y% 上回りました」です。読んでいて気持ちがいいし、書く側も気持ちがいい。

しかし、その「気持ちよさ」こそが、技術記事の信用を蝕む最大の毒だと私は考えています。勝ちを主張する数字は、いくらでも作れてしまう からです。得意なケースだけ並べる、負ける軸を表から消す、自社環境でだけ測る — これらは不正ではなく「業界の慣行」として日常的に行われています。

そこで私は、この連載の一部を 「負けを見せる」 ことに賭けました。隠さず、薄めず、訓話に流さず、必ず数字に刺して見せる。なぜそんなことをするのか。勝った話より、負けを見せたほうが信用されるから です。これは精神論ではありません。この一部の終わりまでに、私が「自分の手柄を、自分の作ったルールで否定した瞬間」をいくつも並べます。その「負け」の集積こそが、私が個人として差し出せる一番強い名刺だと考えています。

この記事は、連載の中で別々に書いてきた 7 つの「負け(と、負けを律する仕組み)」を、1 本の物語に畳んだものです。順番には意味があります — 連載の倫理を宣言する b1 から始まり、自作 LLM の能力の天井を実出力で見せて北極星を切り替える b5、AI レビュアーの誤指摘を一次証拠で覆す b3、安全ゲートが冗長になった示唆的な負け b4、負けた研究の道具を勝てる土俵へ載せ替える b7、勝利宣言を自分のノイズ床で抑制する b2、そして勝ち筋を 1 行で検収できる道具に畳む b6 へと続きます。


本連載の全 llcore 実測の射程(免責、ここで一度だけ大きく掲げます)

全数値は 自宅 CPU の極小モデル(0.81M〜130M char-LM、本連載の一部のみ 0.5B の既製モデルを CPU 変換)PoC の実測です。大手の実 LLM(12B〜64B)性能を直接反証・凌駕するものではありません。 比較は 手法・思想・計測規律の次元 で行います。量子化の footprint は実測値、推論速度は simulated quant のため未測定。スコアは next-token-nll proxy(次トークン予測の困惑度代理)であり、会話品質クレームは含みません。再現用のコードと出力 JSON(scripts/*.py / out/*.json / src/llcore/lm/eval.py ほか)は GitHub で公開しています。

この一文を、本文に入る前に大きく掲げています。普通は記事の末尾に小さく添える「免責」を、わざわざ冒頭に置くのは、この一部でやっていることの大半が 「うまくいかなかった話」 だからです。そして本連載は、その敗北群をこそ主役に据えます。


共有の物差し — PPL・top-1・honest disclosure・定数状態(最初に一度だけ)

各章で繰り返し出てくる言葉を、ここで一度だけかみくだいておきます。以降の章は、この定義を前提に進めます。

PPL(perplexity / 困惑度)。 モデルが「次の 1 文字をどれくらい当てにくそうにしているか」を、確率分布の全体 を使って測る指標です。「次は a が 40%、b が 30%、c が 20%……」という分布全体の良し悪しを平均します。低いほど良い。ここに弱点が一つあります。top-1(一番確率の高い候補)が壊れて入れ替わってしまっても、確率の裾野(2 位以下の分布)がそれなりに残っていれば、平均値はそこそこ救われてしまう ことがある。

top-1 accuracy。 「一番確率が高いと予測した文字」が実際の正解と一致した割合です。低いほど「ズバリ当てる力」が落ちている。PPL が分布全体の平均なら、top-1 はズバリの一発勝負。後で見るように、この 2 つは必ずしも同時には動きません。

honest disclosure(正直な開示)。 「異常に良い結果が出たら、勝った気になる前に必ず内訳を疑う。失敗を消さず教訓として残す」という、この連載すべての土台にしている規律です。他人にではなく、まず自分に向けます。本連載のもう一つのルール — 外部 AI(レビュー AI でも)の指摘は、実コード・一次情報で一件ずつ検証してから採用する — も、この延長にあります(b3 章で実際に効きます)。

定数状態(constant-state)recurrent。 文脈(これまでの会話)を伸ばしても、メモリが増えずに 平ら のまま保てる仕組みです。後で出てくる「メモリ効率」という北極星は、ほぼこの性質に賭けています。比喩で言えば、古い話を 1 枚の要約メモにまとめ直して持ち続けるようなしくみ。ただし「長文ほど効かなくなる」弱点もあり、それも隠さず測ります(b2 章)。

健康診断のたとえを一つ置いておきます。人間ドックで全項目が基準値内でも、安心していいのは その検査が異常をちゃんと拾える設計になっているときだけ です。血圧計が壊れて常に「120/80」と出るなら、「正常」という出力に価値はありません。検査の信頼性は「良い結果が出たこと」ではなく、「悪い結果が出るべきときに、ちゃんと悪い結果を出せること」 で決まる。この連載は、その「悪い結果を出せる仕組み」を作る話です。


b1. 私が作ったのは「外を超えるベンチ」ではなく「自分を止める審判」

普通、技術記事のクライマックスは「競合 X を Y% 上回りました」です。冒頭で書いたとおり、その気持ちよさは毒になりうる。そこで llcore(自宅 CPU で動かしている極小 char-LM の研究)では、方針を反転させました。外を超えるベンチを作るのをやめ、自分を止める審判を作る ことに労力を振りました。

char-LM(character-level language model、文字単位言語モデル) — 単語ではなく「次に来る 1 文字」を一字ずつ予測する、ごく小さな言語モデルです。ひらがなや漢字を一字ずつ書き継いでいくイメージで、とても軽く動く代わりに語彙や知識は乏しい(本連載の主役)。

サッカーの審判は、ふつう中立です。でも私が作ったのは、自分のチームの反則にこそ厳しく笛を吹く審判 でした。具体的には、評価コード src/llcore/lm/eval.py に 2 段の合否ゲートを置いています。

def passes_gate(model_ppl: float, unigram_ppl: float, margin: float = 0.85) -> bool:
    # PPL ゲート: モデル PPL が unigram baseline の 0.85 倍以下なら PASS
    return model_ppl <= margin * unigram_ppl

def passes_capability_gate(
    model_top1: float, reference_top1: float, min_retention: float = 0.97
) -> bool:
    # 能力ゲート: 基準(fp32)の top-1 を 97% 以上保持していなければ FAIL
    if reference_top1 <= 0.0:
        return model_top1 >= 0.0
    return model_top1 >= min_retention * reference_top1

passes_gate は「PPL が unigram(順序を見ない、文字の出現頻度だけのベースライン)を明確に下回っているか」を見ます。passes_capability_gate(以後 cap-gate と呼びます)は「fp32 モデルの top-1 を 97% 以上保持しているか」を見ます。

retention(保持率) — 元のモデル(ここでは高精度な fp32)が持っていた能力を、圧縮後にどれだけ「保てているか」の割合です。97% retention なら元の力の 97% が残っている、の意味。引っ越しで家具を 1 つも割らずに何割運べたか、の残存率のイメージ。

後者を わざわざ厳しく(97% 保持) 設定したのが肝です。基準モデルに対する top-1 の保持率が 97% 以上でなければ FAIL にする、自分を止めるための関所 です。ちょっと良さそうに見える程度では、絶対に通さない。

なぜ「2 つのゲート」が要るのかを実データで

cap-gate を作る直接のきっかけは、量子化のビット幅スイープでした。重みを 8bit → 2bit まで段階的に潰し、PPL と top-1 の両方を測ったものです。

量子化(quantization)・fp32 / int8 — 量子化は、モデルの重み(膨大な数値)をより少ないビット数で表してファイルを軽くする圧縮です。fp32 は 1 つの数を 32 ビット(高精度)、int8 は 8 ビット、2bit はわずか 2 ビットで表す。高画質の写真を低画質 JPEG に落とすイメージで、軽くなる代わりに少しずつ情報が削れます。

multi_smoke(1.36M params、語彙 4358、日本語マルチコーパス。fp32 PPL 24.88 / top1 36.28%) の per-channel 量子化:

bits 削減率 PPL ΔPPL% top1 Δtop1(pp) PPL ゲート
8 74.0% 24.886 +0.01% 36.28% −0.00 PASS
5 83.3% 24.935 +0.21% 36.25% −0.04 PASS
4 86.4% 25.295 +1.66% 36.08% −0.20 PASS
3 89.5% 27.761 +11.57% 34.30% −1.98 PASS
2 92.6% 269.716 +983.95% 7.49% −28.80 FAIL

multi_smoke は 2bit で PPL も top1 も一緒に崩れたので、PPL ゲートが正しく FAIL を出しました。問題は より大きい realp1(11.9M params、語彙 3044、日本語単一書籍。fp32 PPL 38.32 / top1 28.66%) の方でした。

bits 削減率 PPL ΔPPL% top1 Δtop1(pp) PPL ゲート
8 74.6% 38.316 +0.00% 28.66% −0.02 PASS
4 87.1% 38.599 +0.74% 28.42% −0.25 PASS
3 90.2% 40.154 +4.80% 27.97% −0.70 PASS
2 93.3% 101.114 +163.90% 15.21% −13.46 PASS

realp1 の 2bit を見てください。top1 が 28.66% → 15.21% へ、−13.46pp、ほぼ半減しています。明らかに能力が壊れている。ところが PPL ゲートは PASS でした。 PPL が 101 で、unigram baseline(215)の 0.85 倍(=約 183)を下回っていたからです。1 つのゆるい点数(PPL)しか見ていなかったからこそ、能力が半減したモデルを通してしまった。

ここで、私が最初に書きたくなった誇張を、自分で訂正しておきます。「PPL は 原理的に 能力を隠す指標だ」と言いたくなる。でも実データはそこまで強いことを言っていません。realp1 の 2bit でも、PPL は +163.9% と大きく劣化しており、top1 と PPL はほぼ同時(lockstep)に崩れています。正確な観測はこうです — 「PPL が能力を隠した」のではなく、「合否の閾値 0.85 倍が粗すぎて、壊れた 2bit を PASS させた」。指標は両方とも劣化を捉えていた。私のゲートの引き方が甘かっただけです。

事前に立てていた仮説(「top1 は PPL より先に劣化するはずだ」)も、本データでは 成立しませんでした。これも消さずに記録しています。仮説が外れたという事実そのものが、cap-gate を「PPL より先回りする検査」としてではなく「閾値を厳しくし直す 検査」として設計し直す根拠になりました。

この発見を受けて cap-gate を eval に増設し、スイープに配線した結果、PPL ゲートは PASS でも cap-gate が止めるビット幅 = multi_smoke 3bit / realp1 2bit を実際に捕捉できるようになりました。自分の評価基盤が、自分の甘さを 1 段分、自力で塞いだわけです。

敗北ログ(1) — 「2bit は QAT/LSQ でも cap-gate を越えられない」と自己反証

ここからが本題の敗北群です。1 つ目は、私が一番粘って、それでも負けた話です。

「2bit でも top-1 をほとんど落とさず量子化できれば、自宅 CPU char-LM のメモリ効率は劇的に上がる」。これを実現できれば連載の目玉になる。そこで PTQ(学習後量子化)の手法を順に強くしていきました。

multi_smoke 2bit(fp32 ref: PPL 24.88 / top1 36.28%)、手法を上げていったときの top-1 保持率:

手法 PPL top1 retention(保持率) cap-gate
PTQ RTN(素朴な丸め) 236.9 7.98% 22% FAIL
PTQ GPTQ(誤差補償) 138.7 12.07% 33% FAIL
QAT(固定 scale で学習) 38.15 30.10% 82.9% FAIL
QAT + LSQ(学習可能 scale) 36.79 30.48% 84.0% FAIL

手法を上げるたびに、damage は確かに減りました。RTN の 22% → GPTQ の 33% → QAT の 82.9%。QAT(quantization-aware training、2bit に潰すことを前提に学習し直す)に至っては、top-1 を 30.10% まで回復させ、RTN の約 3.8 倍、GPTQ の約 2.5 倍を保持しています。

そこでもう一段だけ粘り、LSQ(Learned Step Size Quantization) — 量子化の刻み幅(scale)を固定値でなく 学習で動かす 手法(Esser ら、ICLR 2020)を、論文の式どおりに自前実装しました(勾配の均衡化 g=1/√(N·Q_P)、初期化 s=2·mean(|w|)/√Q_P)。結果は top-1 30.48%、保持率 84.0%。固定 scale QAT(82.9%)を確かに上回りましたが、その差は +1.1pp。 系譜は RTN 22% → GPTQ 33% → QAT 82.9% → LSQ 84.0% と最後まで単調に改善し続けますが、伸びはもう完全に頭打ちで、LSQ をもってしても 97% の関所には FAIL です。

ここに、この敗北のいちばん重要な含意があります。伸びが頭打ちになったのは、手法が足りないからではなく、規模が足りないからです。 LSQ 自身の論文が、パラメータを極限まで削った小型モデル(SqueezeNext)で 2bit が −14pt 崩れることを報告しています(大きい ResNet では −2.9pt)。量子化のスケール則(Dettmers ら 2023、QiD 2024)も口を揃えて「小さいモデルは冗長性が無く、2bit の量子化ノイズを吸収できない」と言う。実際、2bit で 90% 台後半の保持率が報告されるのは、7B 以上の大型モデルに VQ codebook や長時間 QAT を組み合わせたとき(EfficientQAT で 7B=92.7%、70B=95.9%)。1.36M の char-LM が、手法をどれだけ上げても 2bit で 97% に届かないのは、最初から予言されていた負け でした。だから私は、この「+1.1pp」を勝ち報告にはしません。「学習可能 scale でも、規模の壁は越えられなかった」 という負けの確定として記録します。

スケール則(scaling law) — モデルの規模(パラメータ数やデータ量)と、性能や「精度を削っても壊れにくさ」との間に成り立つ経験的な法則です。「大きいモデルほど中に余裕(冗長性)があり、ビットを削っても粘れる」という、サイズと頑丈さの関係を指します。

(射程の注記: この 82.9% は multi_smoke(1.36M) の数字です。realp1 では GPTQ で top1 保持率 77.7% でした。いずれにせよ 2bit は 97% に届きません。)

もし cap-gate を作っていなかったら、私はおそらく「QAT で 2bit top-1 を 82.9% 保持!RTN の約 3.8 倍!」という景気のいい見出しで記事を書いていたでしょう。その見出しは嘘ではありません。でも、「97% には届いていない=この規模では 2bit を制覇できていない」という肝心の敗北を、読者に伝えそびれた はずです。自分で作った審判が、自分の楽観を止めてくれました。

敗北ログ(2) — 「mmap は常に省メモリ」ではない

2 つ目。これは「メモリ効率」を北極星に据えた私の、根っこに刺さる敗北です。

mmap(ファイルをメモリに直接マップして、必要なページだけ読み込む仕組み。llama.cpp などが使う)を使えば、巨大なモデルでも「使った分だけ」しかメモリに載らない — そう期待しました。

realp1(11.9M params、model.pt 49.3MB、param 53.91MB):

モード load 時 ΔRSS touch 後 ΔRSS
eager(mmap=False) 50.77MB(≈モデル全載) 51.64MB
mmap(mmap=True) 1.42MB(×0.028) 51.54MB

ロード直後、eager は全重み(約 51MB)を即座にメモリへ読み込みますが、mmap は 1.42MB、わずか 2.8% しか載せません。「これだ」と思いました。ところが touch 後 ΔRSS の列を見てください。mmap でも、全重みに実際にアクセス(forward 推論で全部使う)すると、最終的に 51.54MB まで膨らみます。eager(51.64MB)とほぼ同じです。

つまり、全部の重みを必ず一度は使うワークロード(=普通の推論)では、mmap の最終メモリは eager に収束してしまう。正確な主張は「常に省メモリ」ではなく「必要な分だけ、遅延して 載る」です。恩恵が本物なのは、(a) working set の一部しか使わない場合、(b) 複数モデルでページキャッシュを共有する場合、(c) コールド起動の遅延を許せる場合に限られます。

RSS / working set(ワーキングセット) — RSS(Resident Set Size)は、プログラムが実際に物理メモリ(RAM)に載せている量。working set はある時点で実際に使っているメモリの範囲で、peak はその最大値です。本棚全体(ディスク)ではなく、いま机に広げている本の量(RAM)を測るイメージ。

(ただし、この性質には別の使い道があります。read-only な mmap ページは「clean」なので、メモリ圧力がかかると OS が pagefile に書き戻さずに破棄でき、再アクセス時にディスクから読み直せる。これを使うと「使える物理 RAM < モデルサイズ」でも forward を完走できます — 実際 522MB のモデルを 358MB の working-set 上限で完走させ、logits の checksum も完全一致しました。「常に省メモリ」は否定しつつ、「RAM 超で回る」は別機構として肯定する。どちらも数字で線を引きます。)

敗北ログ(3) — int8 streaming、圧力なしでは peak がほぼ動かない

3 つ目。これは「途中まで理屈は正しいのに、実機で殴ったら期待が裏切られた」典型です。アイデアはこう — 重みを int8 で常駐させ、forward の中で 層ごとに fp32 へ復元(dequant)してすぐ解放する。そうすれば、常駐メモリも推論中の peak(ピーク)メモリも、両方下がるはずだ。

130M params(n_embd=1024 / L=10)、dense(全層一括復元)vs stream(層ごと復元):

mode 常駐(resident) peak WS logits checksum
dense 538.6MB(fp32 全載) 963.8MB −192.1
stream 148.9MB(int8, ×0.285) 882.2MB −192.1

常駐メモリは堅牢に勝ちました。538.6MB → 148.9MB、72% 削減 です。これは本物。しかし peak WS の列を見てください。963.8MB → 882.2MB。ほとんど動いていません。

層ごとに捨てているのに、なぜピークが下がらないのか。理由は torch の caching allocator にあります。いったん確保した fp32 のメモリを、解放しても OS には返さず、自分のプール内に抱え込んでしまう。さらに推論中の一時的な活性(activation)も乗る。だから「圧力をかけない平時」では、ピークはほぼ不変でした。正確には、「常駐は 72% 下がるが、平時の peak はほぼ不変」。削減が顕在化するのは メモリ圧力をかけたとき だけです(working-set 上限 368MB を強制すると、dense は常駐 539MB が収まらず動かないが、stream は 368MB で完走できる)。

3 つの結果(dense / stream / stream-capped)の logits checksum はすべて −192.1 で完全一致。メモリ最適化は結果を変えていません。「正しい部分(常駐 72% 減)」と「期待外れの部分(平時 peak 不変)」を、同じ表の中に並べて出す — これが私の honest disclosure のやり方です。

logits / checksum(チェックサム) — logits は、モデルが各候補に出す「生のスコア」(確率に直す前の数値)。checksum はそれらを合算した照合値で、2 つの実行でぴたり一致すれば「出力が 1 ビットも変わっていない」証拠になります。レシートの合計金額が同じなら中身も同じ、と確かめるのと同じ。

敗北ログ(4) — 「進化が 20/20 で勝った」を、自分のメタゲートが ARTIFACT と断じた

4 つ目は、4 つの中で一番「勝った気になった」やつです。だからこそ、一番の収穫でした。

別系統の研究(凍結した小型 LLM に小さな recurrent adapter を後付けし、その構造を online に進化させる枠組み)で、こんな結果が出ました。実 SmolLM2-135M 由来の交差エントロピー地形で、進化(MAP-Elites)が finite-difference 勾配を 20/20 で上回った。 20 回やって 20 回勝ち。p 値も 9.5e-7。「進化が勾配に勝つ」— 夢のある見出しです。

MAP-Elites(進化探索)/ finite-difference(有限差分)勾配 / 交差エントロピー(cross-entropy)/ p 値 — 交差エントロピー(CE)は、モデルの予測が正解からどれだけズレているかの誤差(低いほど良い)。これを下げる「探し方」を比べていて、MAP-Elites は多様な解を残しつつ進化(突然変異と選抜)で探す方法、finite-difference 勾配は入力を少しずらして差分から坂の傾きを測る数値的な方法です。p 値は「この差がただの偶然で起こる確率」で、9.5e-7 のように極端に小さいほど偶然では説明しにくい(=意味のある差)とされます。

ところが私の枠組みには、勝った瞬間に 強い対戦相手を自動で呼ぶメタゲート(strong-gradient meta-gate) が組み込まれていました。finite-diff ではなく、backprop による 強い解析勾配(torch Adam) をぶつけ直したのです。

backprop(誤差逆伝播)/ 解析勾配 / Adam — backprop(バックプロパゲーション)は、誤差を出力側から入力側へ逆向きにたどり、各重みをどちらへ動かせば誤差が減るかを厳密に計算する手法。こうして得る「解析勾配」は、有限差分の近似と違って数学的に正確な傾きです。Adam はその傾きで重みを更新する定番の最適化アルゴリズム(オプティマイザ)。坂の傾きを当てずっぽうで測る(有限差分)のでなく、地形図から正確に読み取る(backprop)違い。

held-out(未学習データ)平均 fitness(= −CE、高いほど良い):

method held-out 平均 備考
strong analytic gradient(torch Adam) −1.446 全 method 最良
MAP-Elites(進化) −1.454 2 位
random −1.473
finite-diff gradient −1.483 最下位

強い勾配(−1.446)が、進化(−1.454)を抜き返しました。進化 vs 強い解析勾配では、19/20 で勾配が逆転(p=3.5e-4)。事前登録した 4 条件 AND は不成立。判定は ARTIFACT(見かけの勝ち)+ NEGATIVE(能力では負け) に確定しました。

ここで、この勝敗の機構を正確に書いておきます。critic に指摘された一番鋭いポイントです。この比較の「同予算」は、forward CE 評価回数が同一という意味であって、有効更新ステップ数が同一という意味ではありません。 torch Adam は 2000 ステップ更新できるのに対し、finite-diff / evolution は予算内で約 95 ステップしか進めません(finite-diff は次元 +1 回の評価で 1 step しか進まないため)。この「更新回数の非対称」こそが ARTIFACT の正体 です。進化が finite-diff に勝ったのは、finite-diff が cold-start で約 95 ステップしか進めないハンデを背負っていたから。同じ評価予算でも、勾配を「正しく」(backprop で exact に)使えば 2000 ステップ進めて、勝敗はひっくり返る。つまり進化の見かけの勝ちは、弱いベースラインの artifact でした。

もしメタゲートが無ければ、私は「進化が実地形で 20/20 capability 勝利」という false-positive を、堂々と公開していた でしょう。それを、自分の枠組みが publish 前に 1 件、実際に止めた。これは「負けの報告」ではありません。「自己懐疑の規律が、データの上で機能した報告」 です。「勝った気になる前に、内訳を疑う」を、精神論ではなく装置として実装し、それが実際に自分の手柄を 1 件叩き落とした — これが私の差し出せる、一番強い証拠です。

進化(MAP-Elites)が弱い相手 finite-diff には 20/20 で勝つが、メタゲートが強い backprop 勾配を自動召喚すると 19/20 で逆転し判定 ARTIFACT になる二段審判の図。勝敗の正体は更新回数の非対称(勾配 2000 step vs 進化 約 95 step)で、差 0.008 の見かけの勝ちが publish 前に自分の枠組みに止められたことを示す。

同じ実験を 2 段の審判にかける — 弱い相手で出た「20/20 勝利」を、強い相手の自動再戦が ARTIFACT と断じる。

汗だくの男が目を吊り上げ歯をむき出して「コイツ…」「つまんね〜〜!!」と絶叫する迫力のドアップ

🗒️ 「コイツ…つまんね〜〜!!」— 弱い相手に 20 連勝しても、観客の感想はだいたいこれ。空虚な勝利は退屈なだけで、何も証明してくれない(© Forbidden shibukawa / SHUEISHA・『スナックバス江』)

競合に向ける刃を、自分にも公平に向ける

ここで一つ、自分への戒めを書いておきます。私は前段まで「負ける軸を消す業界慣行」を批判のニュアンスで引きました。代表例として、ある大手の自動運転向けモデル(Cosmos、self-report / 技報時点)の数字を挙げておきます。技報では Driving 79.3 vs 47.2(自社 vs 比較対象) という勝ち軸が前面に出る一方で、Robotics 57.8 vs 58.2 / General 73.7 vs 77.5 という負け軸は表から伏せられがちです(数値は技報・技報時点ラベル、第三者未検証)。

ただ、公平を期すなら、この刃は自分にも向けねばなりません。Robotics の 57.8 vs 58.2 は、差が 0.4。これは測定誤差圏内の可能性が十分にあります。 「負け軸を伏せた」という批判は妥当ですが、同時に「その負けは僅差で、有意かどうか怪しい」という事実も併記するのがフェアです。負け軸を消すのも誇張なら、僅差の負けを大げさに「敗北」と書くのもまた誇張です。82.9% は「QAT で 3.8 倍に改善した」勝ちでもあり「97% に届かない」負けでもある。963.8 → 882.2MB は「常駐 72% 減」の勝ちと「平時 peak 不変」の負け。自分の数字に向ける刃と、競合の数字に向ける刃を、同じ鋭さに保つ — それができて初めて、敗北の開示は「信用の材料」になります。


b5. 自作 LLM に話しかけたら、漱石の幽霊が出た — 賢さは構造的な天井

ここまで「自分を止める審判」の話をしてきました。ではそもそも、なぜ私は「賢さ」で勝負しないのか。その理由を、感想ではなく 実際に話しかけた結果 で見せます。

よく聞かれます。「llcore も、環境さえ良ければ普通の LLM くらい会話できるんでしょ?」 使ったのは手持ちで一番マシなモデル(realp1:青空文庫で学習した 11.9M パラメータの文字単位 LM、CPU)。話しかけてみました(無編集)。

: こんにちは。
llcore: 『そうなには、何の長いのだ」「あの?おや、そんなさ、何だよ。先生はちゃいいい』

: 日本で一番高い山は
llcore: 『長いであっている。それから君子を見たら一番ですから…寒月君は…芋の伯父さん…』

……富士山は、出てきませんでした。

注目してほしいのは、「日本語っぽさ」だけは妙にある ことです。「先生」「寒月君」「伯父さん」 — これらは青空文庫(夏目漱石『吾輩は猫である』など)に出てくる 文体と登場人物名。モデルは漱石の語彙と口調を 真似た断片 を吐けます。でも意味は通らないし、質問には一切答えられない。

漱石の"幽霊"は呼び出せる。でも"会話"はできない。

なぜこうなるのか。このモデルは 文字単位(char-level) で「次の 1 文字」を予測します。その top-1 は 約 29%(0.2866)。3〜4 文字に 1 文字あたる程度です(b1 章で見た realp1 の fp32 top1 28.66% と同じ数字です)。この精度では、「それっぽい字面」は連なっても、意味の通る文・質問への回答は構造的に出てきません。語彙も知識も足りない。富士山という事実を持っていないのだから、答えられないのは当然です。

「環境次第で会話レベルになる」 — なりません。 制約は環境ではなく 本質(文字単位・極小パラメータ・極小データ)です。

良いハードウェアがあれば? それは「より大きいモデルを、より多くのデータで訓練できる」というだけの話で、それをやった瞬間、llcore は別物(クラウド規模の LLM)になります。手元の CPU char-LM のまま賢くする道は、構造的に閉じている。

だから北極星を「賢さ」から「メモリ効率」へ動かした

ここが連載全体の転回点です。CPU の文字単位 tiny LM で capability(賢さ)を追うのは、構造的に頭打ちの負け筋。これを認めるのが honest disclosure の出発点でした。賢さで勝てないものに賢さで挑み続けるより、勝てる土俵に乗り換える

そこで北極星を メモリ効率 に切り替えました。「自宅の小さなマシンで、working set を小さく予測可能に保つ」 — この土俵なら、文字単位 tiny LM でも研究として意味のある実測と設計ができる(b1 章で見た mmap・int8 streaming・定数状態の話はその成果です)。

そして役割分担が明確になりました。

  • 会話できる LLM が欲しいなら: FullSense の設計では llmesh 経由で、既存の優秀な LLM(Gemma 等)を on-prem(手元)で回す
  • llcore は何者か: チャットボットではなく、研究ビークル(進化探索・検証規律・メモリ効率の実験場)。

「自作 LLM で ChatGPT に対抗」ではなく、「自作の小さなモデルを、勝てる問い(メモリ効率)に向けた実験台にする」。話しかけて幽霊しか出なかったことが、その割り切りを決めさせてくれました。

文字単位 tiny LM(realp1 / 11.9M params)の次の1文字 top-1=28.66% が capability の天井を決める図。賢さを追う道は「環境でなく構造」で閉じており(漱石の幽霊は出るが会話は不成立)、同じモデルでもメモリ効率に賭ける道は研究として勝てる土俵——だから北極星を切り替えた、という分岐を示す。

天井は環境でなく本質。だから「賢さ」ではなく「メモリ効率」へ北極星を動かした。

自作モデルの出力が支離滅裂だと、普通は見せたくありません。でも私は、この「漱石の幽霊」こそ見せるべき だと思いました。能力の天井を正直に見せることは、負けの告白であると同時に、戦略の宣言 でもあります。賢さを諦めたのではなく、賢さは既存 LLM に任せ、自分は「小さく・予測可能に」という別の価値に賭けた — その分岐点を、実出力付きで記録しておきます。


b3. AI レビュアーに「その数字は捏造だ」と CRITICAL を食らった

北極星を「メモリ効率」に移したので、ここからはメモリの 数字 をどう扱うかの話になります。趣向が変わって、今回は 他者(AI レビュアー)の指摘が間違っていた回 です。ただし主役は「AI が間違えた」ことではなく、「もっともらしい指摘を、鵜呑みにせず一次証拠で確かめたら誤りだった」という検証プロセスそのもの です。

事の発端は、自作のメモリ計測ツールキットに敵対的レビューをかけたときでした。AI 批評家(私は gem-critic と呼んでいます)が、こう断じました。

「realp1 の footprint 49.23MB → 13.97MB は捏造だ。正しくは 47.66MB → 12.10MB。これは CRITICAL な不正確さだ。」

捏造。CRITICAL。強い言葉です。普通なら慌てて数字を書き換えるところです。でも、書き換えませんでした。共有の物差しの章で触れたルール — 外部 AI の指摘は、実コード・一次情報で一件ずつ検証してから採用する — に従い、批評家の「正しい数字」を鵜呑みにせず、両方の数字がどこから出たのか をコードまで遡りました。

1.57MB の差を、バイト単位で追う

私のツールの値と批評家の「正しい値」の差は、fp32 で 49.23MB − 47.66MB = 1.57MB。バイトに直すと:

  • 私の値: 49,231,872 B(= 49.23MB)
  • 批評家の「正」: 47,659,008 B(= 11,914,752 パラメータ × 4 バイト)
  • 差: 1,572,864 B

この 1,572,864 を素因数に割ると —— 6 × 256 × 256 × 4realp1 は 6 層、文脈長 256 のモデルです。各層が 256 × 256causal-mask(因果マスク)バッファ を fp32(4 バイト)で持っている。6 層ぶんでちょうど 1,572,864 バイト。差の正体は causal-mask buffer でした。

スーツケースのたとえが分かりやすいかもしれません。同じスーツケースの重さを 2 人が測り、A さんは「中身だけ」を、B さんは「スーツケース本体ごと」量った。どちらも嘘はついていません。「何を含めて量ったか」が違うだけです。ただしこの本体には、中身と違って小さく畳めない部分(付属品=mask)がある — そこが後の話につながります。

  • 私のツール int8_footprint_bytes は、モデルの parameters() に加えて buffers() も走査する 「resident-weight-byte 会計」。実際に RAM に常駐する重み系バイトを数えるので、causal-mask buffer も含む。
  • 批評家が「正」とした旧スクリプトの数字は、params-only 会計。学習対象のパラメータだけを数え、buffer は数えない。

どちらの数字も、それぞれの会計基準では正しい。「捏造」ではなく「会計基準の不一致」 だったのです。

同じ realp1 モデルの fp32 footprint を積み上げ棒で分解した図。緑の params 47.66MB の上に琥珀色の causal-mask buffer +1.57MB が乗り、合計 49.23MB になる。差 1,572,864B を素因数分解すると 6×256×256×4 = mask 6 層ぶんに一致。批評家の params-only 会計と私の params+buffers 会計の違いであって捏造ではない、という会計差の正体を一枚で示す。

差 1.57MB をバイト単位で素因数分解すると、6 層ぶんの causal-mask buffer にぴたりと一致する。

しかも面白いのは方向です。量子化できない mask を fp32 のまま含めると、int8 への削減率は 71.6%控えめ に出ます(mask は int8 にできないぶん、削減の足を引っ張る)。つまり私の会計は 削減効果を過大申告するどころか、むしろ保守的に小さく見せている(underclaim)。捏造で良く見せるどころか、正直方向に厳しめの数字でした。

教訓 — メモリ数値は「会計」を明示し、AI の指摘は一次証拠で

メモリの話には、少なくとも 4 つの異なる「数え方」があります。params-only(学習パラメータだけ)/ params + buffers(resident-weight、mask 等の固定 buffer 込み)/ peak RSS / working set(実行時にプロセスが物理メモリに持った最大量)/ on-disk(ファイルサイズ)。これらは平気で数百 MB 単位でズレます。同じモデルでも「どれを指しているか」を書かなければ、読者は別人の数字を比較してしまう。今回の「捏造」騒動は、要するに params-only と params+buffers を突き合わせたから 起きた。

そして、もし批評家の「CRITICAL・捏造」を鵜呑みにしていたら、私は 正しい(より保守的で正直な)自分の数字を、わざわざ params-only に書き換えていた。検証が、その改悪を止めました。

AI の「CRITICAL」は、結論ではなく 調査の起点
1.57MB を素因数分解するまで、どちらが正しいかは分からなかった。

派手な成果の記事ではありません。でも「自分の数字を疑い、他者の指摘も疑い、最後はバイト単位の一次証拠で決着させる」 — この地味な検証規律こそ、自宅 CPU の小さな実験を信用できるものにしている背骨です。


b4. 安全ゲートを作ったら、自分の目的関数がそれを冗長にした

「負けを見せる」シリーズに戻ります。今回の負けは、ちょっと毛色が違います。バグでも性能不足でもなく、「自分が用意した安全装置が、効く場面が無かった」 という負けです。

私はアーキテクチャ探索(進化計算で AI の構造を探す)に、数学的に健全な安全ゲート を噛ませました。具体的には「この構造は安定か(状態が発散しないか)」を Z3(定理証明器)で証明 し、証明できないものは fail-closed で棄却する。理屈の上では強力な仕掛けです。設計時の主張(私はこれを G2 と呼んでいました)はこうでした。

「ゲート無しだと安全な個体は約 6% しか出ない。ゲート有りなら約 100% 安全になる。だからゲートは必須だ。」

ここでの「約 6%」は、ゲートを動機づけるために置いた 事前の見積り(別設定を念頭にした想定値)であって、本実験で実測した安全率ではありません。実測したら、この主張は 反証 されました。

Z3(定理証明器)/ fail-closed(フェイルクローズド) — Z3 は、数式で書いた条件が必ず成り立つか(または反例があるか)を自動で証明するソフト(定理証明器)です。fail-closed は、証明できない・検証に失敗したときは安全側に倒して「通さず拒否する」を既定にする方針。鍵が壊れたら自動で閉まる金庫のように、迷ったら閉じる側へ倒します(反対は fail-open)。

ゲートの有無で 2×2 の実験を回して安全率(safe_rate)を測ったところ —— ゲート無しでも、既に safe_rate は 95〜100% でした。「6% → 100%」どころか、ゲートを足しても safe_rate が 0.95 → 1.00 に僅かに上がるだけ(retention 重視アームの safe_rate が none 0.95 → gate 1.00)。安全率はもとから高かった。私が「効くはず」と信じた安全ゲートは、この設定では、ほぼ仕事が無かった のです。

設計時の主張「6%→100%」と実測「95%→100%」を左右に並べた棒グラフ。左=ゲート無しを 6% と見積もった事前想定、右=実測では retention アームのゲート無しが既に 0.95、ゲート有りで 1.00 と、改善幅はわずかでゲートはほぼ冗長だったことを示す。

左の「6%→100%」は事前の見積り(別設定の期待値)、右が実測。実測ではゲート無しでも既に高安全率で、ゲートの出番がほぼ無かった。

なぜゲートは冗長になったのか

崖っぷちの道にガードレールを付けたら、そもそも車はみんな崖と反対側の山際を走る習性があった — だれも崖に寄っていかないので、ガードレールは立派に立っているのにぶつかる車が一台もいない。理由を追うと、まさにこの構造でした。

私の探索の 目的関数(報酬) は 2 つ — メモリ効率(状態の収縮率を下げる = メモリを食わない構造を好む)と retention(過去をちゃんと再現できる構造を好む)。ところが この 2 つの報酬は、どちらも「有界な(暴れない)構造」を好む のです。メモリを食わない構造も、過去を正しく再現する構造も、結局「状態が発散しない」側に寄る。

目的関数が、もう既に安全側を報酬していた。 だから後付けの安全ゲートは、すでに選ばれている安全な個体を、もう一度「安全だ」と承認するだけだった。

安全ゲートの価値は、「目的関数が危険側(発散側)を好むとき」にしか顕在化しない。 目的がすでに安全を報酬しているなら、ゲートは冗長になる。

これは「安全機構を作る前に、目的関数がどちら側を報酬しているかを見ろ」という、設計判断の境界条件です。効かないと分かったこと自体が、効くこと以上に設計の理解を進めました。

おまけの発見と、隠さない但し書き

もう一つ、想定していなかった代償が見えました。メモリ効率の報酬は footprint(占有量の指標)を 0.375 → 0.149 へほぼ半減 させました。狙いどおり。でもその代償は、retention の微減だけではありませんでした。retention 重視の個体 は capability がランダム初期化を +0.012 上回る(passes=True)のに対し、メモリ重視の個体 は footprint は小さいが capability のランダム超え分が +0.004 に縮み、判定は passes=False。つまりメモリを攻めすぎると、「ランダムより賢い」という最低限の優位(capability edge)まで失う 領域に入っていた。トレードオフは「メモリ vs retention」だと思っていたら、実際は「メモリ vs ランダム超えの能力そのもの」という、より厳しい場所に出ていたのです。

但し書きを隠さず置きます。footprint は state-boundedness の proxy であって実 RSS(実メモリ)ではありません(P1 留保)。そして 極小 PoC です。別の目的関数(発散を許容・選好するもの)なら、同じゲートが決定的に効く可能性は十分あります。Z3 は実際に動いており(196 個体中 71 を棄却・フォールバック 0)、ゲート機構そのものは健全に機能しました。「ゲートが壊れていた」のではなく「ゲートの出番が無かった」 —— この区別が本章の肝です。

普通、安全機構を作って「100% 効きました」と書ければ気持ちがいい。でも今回得たのは「作ってみたら、この目的関数では効かなかった」という結果でした。100% 効くゲートを自慢するより、「いつ効いて、いつ冗長か」を実測で線引きできたことのほうが、次の設計に効く資産です。負けは負け。でもこの負けは、記録に値します。


b7. 負けた研究の道具を、勝てる土俵に再配線する

b5 章で「賢さ(capability)を追うのは構造的な負け筋だから、北極星をメモリ効率へ pivot した」と書きました。今回はその pivot の 実務 です。pivot というと「失敗を捨てて作り直す」イメージがありますが、もっと得な手があります。負けた研究で作った道具(機構)は捨てず、北極星だけ載せ替える。

負けたもの: capability(賢さ)の進化探索。「進化させた構造 ≒ ランダム構造」(evolution_vs_random().passes = False)で、賢さの上積みは出ませんでした(b4 章の capability edge の話と同じ確定の負け筋)。

残ったもの(機構資産): その負け筋を回す過程で作った道具一式が、そっくり残りました。minimal_ga(最小限の進化探索エンジン)、verified-plasticity gate(Z3 / SDP で「構造が安定=収縮する」ことを数学的に証明するゲート)、falsification harness(主張を反証しにかかる検証台)。これらは「賢さ探索」のために作ったものですが、道具としては北極星に依存しません

釣りのたとえが効きます。ある魚(賢さ)を狙って立派な竿・網・魚群探知機をそろえたのに、その魚はどう頑張っても釣れなかった。ここで道具まで全部捨てるのはもったいない。竿は「どの魚を釣るか」を知りません。糸を垂らし、当たりを取り、引き上げる — この働きは、狙う獲物が何であっても変わらない。道具は「目標」に依存していない。 だから狙う魚(北極星)を変えるだけでいい。

そこで、この機構をまるごと メモリ効率の探索 へ転用しました。進化エンジンはそのまま 適応度(報酬)をメモリ指標に差し替え、証明ゲートはそのまま 「探索結果が安定か」を sound に保証するゲートとして使い、反証台はそのまま メモリ効率の主張を疑う検証に使う。北極星(capability → memory)だけ載せ替え、機構は 1 つも捨てない。

負けた賢さ探索で作った機構3点(進化エンジン・収縮証明ゲート・反証台)はそのまま、北極星だけ capability→memory に載せ替える図。転用後の効いた数字として false-admit が経験ゲート 84% に対し sound 証明ゲート 0% で、8割超の取りこぼしがゼロになることを示す。

目標(北極星)だけ差し替え、道具は 1 つも捨てない。価値は guarantee 側に置き直す。

正直な立ち位置 — ほとんどは「再導出」

ここを誤魔化すと信頼を失うので明記します。この設計の大半は、既知手法の再導出です。 「メモリ指標を適応度にする」→ HW-NAS(MnasNet)・HAQ の常識。「accuracy × memory をスカラ化する」→ 多目的最適化(Deb 2000)の定石。「fail-closed な制約付き進化」→ 制約付き NSGA-II の定石。「検証器をゲートにする」→ CEGIS(反例誘導合成)の枠組み。どれも私の発明ではありません(prior-art の確度は高い)。

NAS / NSGA-II / 多目的最適化 — NAS(Neural Architecture Search、神経回路構造探索)は、ニューラルネットの構造そのものを人手でなく自動で探す手法。多目的最適化は「精度」と「メモリ」のように同時に良くしたい複数の目標を一度に扱う最適化で、NSGA-II はその定番アルゴリズム(良い解を世代交代で選び残す進化計算の一種)です。「美味しさ」と「安さ」を両取りする組み合わせを、総当たりでなく賢く探すイメージ。

では誠実な独自性は何か。狭い四点の結合だけ です — 進化 × sound な収縮ゲート × メモリ北極星 × recurrent 力学、この特定の組み合わせを、自宅 CPU で再現可能に回したこと。そして、もう 1 つ測れる独自の貢献があります。

効いた数字 — 「経験ゲート」と「sound 証明」の判別力の差

ゲートには 2 種類あります。経験ゲート(「だいたい安定っぽい」を経験則で判定)と sound 証明ゲート(Z3/SDP で「安定である」を数学的に証明)。この 2 つの 判別力 を測ったら、はっきり差が出ました。

経験ゲートは false-admit(危険なものを安全と誤認)が 84%。
sound 証明ゲートは false-admit が 0%。

ここで言う false-admit は 危ないものを「安全」と通してしまう方向の間違い で、安全なものを念のため止めてしまう間違い(過剰に慎重)とは方向が逆。こちらは事故に直結します。「だいたい安定っぽい」で通したものの 8 割超が、実は安全でなかった。一方、数学的に証明したものは取りこぼしゼロ。経験チェックは過去に見た例から「これと似ているから大丈夫だろう」と推測するので、似ていない危ないものはすり抜けます。対して証明する装置は、構造を数式に書き直し 「暴走に向かう道筋が一本も存在しない」ことを論理で詰める — だから「たまたま見逃した」が原理的に起きない。これが見逃し 0% の正体です。「もっともらしい安全」と「証明された安全」は別物 だ、ということが数字で出ました。

隠さない但し書き — branch A は賢さを取り戻さない

最も大事な honest disclosure です。この転用は、capability(賢さ)を取り戻しません。 価値はあくまで guarantee(保証)側 にあります。「賢くなる」ではなく「安定が証明できる」。capability と guarantee は直交していて、賢さで負けたからといって保証の価値まで失うわけではない。負け筋の道具を勝ち筋へ回すとは、勝てる軸(保証)に価値を置き直す ことでした。留保: footprint は state-boundedness の proxy であって実 RSS ではありません(P1)。実 footprint を適応度にするのは将来(P2)。prior-art = MnasNet / HAQ / NSGA-II / Deb 2000 / CEGIS / Dohare 2024。

負けたのは「目標(賢さ)」であって、「道具(進化・証明・反証)」ではない。
目標だけ載せ替えれば、道具は勝てる土俵で生き返る。

賢さ探索のために作った証明ゲートが、メモリ効率探索の「安全を 0% false-admit で保証する」装置として生き返った。失敗は、機構ごと捨てると二重の損になる。 北極星だけ載せ替える —— それが、負けを資産に変える一番現実的な作法でした。


b2. 「+15.3% で勝った」を、自分のノイズ床で黙らせた

ここまでは主に「負けを見せる」話でした。今回はその一歩先 —— 「勝った」と言いかけて、自分で作ったノイズの物差しで、その勝利宣言を撤回した話 です。

私の自宅 CPU で一晩(約 6.6 時間、386 回の実評価)回したアーキテクチャ探索(NAS)は、最初こう叫びました。

memetic frontier dominates greedy: hypervolume +15.3%

進化計算(NSGA-II)で探した設計群が、素朴な貪欲法ベースラインを ハイパーボリュームで +15.3% 上回った。勝利宣言です。ところが同じ実行の headline 判定 はこうでした。

verdict: suppressed(主張を抑制)— selection optimism exceeds noise floor

同じ実行が、片方の口で「+15.3% で勝った」と言い、もう片方の口で「その勝ちは出すな」と言っている。この矛盾こそが、今回わざわざ仕込んだ仕組み です。

題材は メモリ vs 品質の Pareto 探索。Transformer の各層の注意機構(attention mixer)を、重い softmax のままにするか、軽い sliding window や linear attention に置き換えるか — 置き換えるほどメモリは節約できる(KV キャッシュが小さくなる)が、品質は劣化する(次トークンを当てにくくなる)。対象は既製の Qwen2.5-0.5B-Instruct(24 層)を CPU 上で変換したもの。基準(全層 softmax)の nll は 4.4155(ppl ≈ 82.72)。探し方を 2 通り比べます。greedy(1 層ずつ「今いちばん得な置き換え」を足す素朴な方法)と memetic(NSGA-II + 局所探索の手の込んだ方法)。問いは「手の込んだ memetic は、素朴な greedy に本当に勝つのか?」

パレートフロンティア(Pareto frontier)/ KV キャッシュ — パレートフロンティアは、メモリ節約と品質のように両立しにくい目標で「片方を良くすると他方が悪くなる」ぎりぎり最良の組み合わせを集めた境界線(それより無駄なく良い解は無い、最良ラインの集合)。KV キャッシュは、Transformer が過去のトークンの計算結果(Key/Value)を貯めておくメモリで、文脈が長いほど膨らむため、軽い注意機構に替えるとここが小さくなります。

なぜ「勝った」を即座に信じてはいけないのか

二つの落とし穴があります。私の思いつきではなく、NAS の先行研究が既に警告している確立された問題です。

落とし穴 A:proxy はそもそもノイジー。 候補を本気で評価するのは高すぎるので proxy(代理指標、今回は「次トークンの予測困惑度」)を使う。これは安いが ノイジー で、実性能とよくズレます。MTF-PDNS(Pareto Dominance-based Novelty Search with Multiple Training-Free metrics, Vo & Luong ら, arXiv:2407.20656, 2024)自身が「performance objectives do not fully align with the actual performance ... as is often the case with training-free metrics(proxy 指標は actual performance としばしば乖離する)」と書いています。ここで車輪の再発明でないことを明確に — MTF-PDNS のこの問題への対処は「novelty/多様性スコアで探索空間を広く保つ」こと。本作業の対処はまったく別方向で、「proxy の不確実性そのものを定量化して、勝ちの主張を抑制する」。片や多様性で対処、片や不確実性を測って主張を律する。解の系統が違うので、確立領域の焼き直しではありません。

落とし穴 B:winner's curse(勝者の呪い)。 たくさんの候補を評価して一番良かったものを選ぶと、選ばれた値には「実力 + たまたまその評価窓で運が良かった分」が混ざる。同じ窓で測った勝ち幅は構造的に 過大評価 になる。A/B テストや GWAS で有名な「選抜したものを同じデータで自慢すると盛れる」現象と同じ。zero-shot の +15.3% は、まさに選抜に使った窓で測った勝ちでした。

模試のたとえで言えば — 新勉強法で 15% 点が上がったが、その模試はあなたが新勉強法を仕上げるのに何度も使った問題だった。本当の実力を確かめるには、一度も見たことのない別の問題で測り直すしかありません。

仕掛けた答え — 探索の窓と、審判の窓を物理的に分ける

そこで今回の核心。探索(選抜)に使う窓と、最終判定に使う窓を、トークン位置でぶつからないように分離 しました。探索用(fast pool)は 8 窓、判定用(holdout)はそこから 8,192 トークンずらした、重ならない別の 12 窓。選抜で勝った設計を、一度も選抜に使っていない新品の窓で測り直すと、楽観バイアス(optimism_gap = selection − holdout) が炙り出せます(Δnll は低いほど良い)。

メモリ節約 Δnll(選抜窓) Δnll(holdout) optimism gap 95% CI
11.5% 0.0184 0.0170 0.0014 0.0144..0.0200
27.1% 0.0754 0.0696 0.0058 0.0632..0.0767
45.9% 0.3675 0.3404 0.0271 0.3216..0.3587
61.3% 0.5962 0.5419 0.0543 0.5203..0.5653
68.5% 0.6667 0.6015 0.0652 0.5774..0.6232
72.2% 1.1744 1.1107 0.0637 1.0776..1.1422
83.9% 1.2436 1.1818 0.0618 1.1500..1.2109

選抜窓の値(2 列目)は、holdout(3 列目)より ほぼ全行で良く見えています。その差が optimism gap。最大は 68.5% 節約点の 0.0652。判定ロジックはこうです。

最大 optimism_gap(0.0652)が、ブートストラップ CI の半値幅の床(0.0204)を超えている → 個別フロンティア点の勝利主張を suppress(抑制)する。

楽観バイアスがノイズ床より大きいなら、「この点で勝った」とは言わせない。自分の勝ちを、自分のノイズの物差しで黙らせた わけです。

信頼区間(CI)/ ブートストラップ(bootstrap) — 信頼区間(Confidence Interval)は測った値の「ブレ幅」を示す範囲で、「95% CI」は真の値がこの範囲に収まる確からしさが高い区間。bootstrap は手元のデータから擬似的に何度も取り直し、その誤差幅を見積もる方法です。同じ模試を何通りもの採点条件で測り直して「点数のブレはこのくらい」と幅で示すイメージ。

でも全部黙らせるわけではない — 粒度ごとに自信を数える

ここが今回いちばん気に入っている設計です。「勝ち」を一枚岩で扱わない。 フロンティアの 個別点 の勝ち主張は上記のとおり抑制した。しかし、フロンティア全体を一つに畳んだ ハイパーボリューム(HV、フロンティアが覆う面積=総合的な良さ) については、別途こう出ました。

HV gain(memetic − greedy, holdout)= +16.8%(95% CI 16.2..17.7%, p_memetic_wins 1.000)

しかもこの「勝ち」は CI の下限が 0 を超えたときだけ発火 する設計です(点推定では絶対に発火させない)。今回は CI 下限 16.2% > 0 なので、HV 次元の memetic 優位 だけ は残しました。

「選抜窓 +15.3% を新品窓で測り直したのに、holdout の HV gain は +16.8% と むしろ勝ち幅が増えている じゃないか」と引っかかるかもしれません。これは矛盾ではありません。個別点の optimism_gap(selection − holdout)は新品窓で確かに縮む 一方、HV は別基準の量 だからです。+15.3% は選抜窓のフロンティアが覆う面積比、+16.8% は holdout 窓のフロンティアが覆う面積比であって、面積を構成する点の置かれ方も参照点の取り方も窓ごとに変わる。面積量(HV)同士を「縮む/伸びる」で直接比べられる物差しではない のです。だからこそ HV の勝ちは「+15.3% より大きいから強い」ではなく、CI 下限が 0 を超えているという独立の根拠 でのみ残しています。

選抜窓の +15.3% を fresh holdout で測り直し、個別点は SUPPRESSED・総合HVは KEPT・needleは UNTESTED と粒度ごとに取捨する図

図:選抜窓で出た「+15.3% 勝ち」を fresh holdout で測り直す。楽観バイアス(最大 0.0652)がノイズ床(0.0204)を超えるので個別フロンティア点の勝ちは抑制(SUPPRESSED)、総合 HV gain +16.8%(CI_lo>0)だけは残す(KEPT)、長距離検索は未検証(UNTESTED)として開示。

抑制をかける関門は 5 段です。(1) paired multi-window bootstrap CI — proxy 自体に窓ペア再標本の信頼区間を付け、点推定で語らせない。(2) fresh holdout で winner's curse 除去 — 床を超えたら verdict 抑制。(3) proxy-vs-judge の Kendall τ — τ<0.7 なら positive verdict を 'suggestive(示唆的)' へ降格(今回は **τ=1.00** で降格なし)。(4) **HV gain は CI_lo>0 でのみ発火**。(5) memetic ≈ greedy は honest negative として明示。先行研究が「proxy は noisy」と認めるところを、本作業は「その noisy さを実際に測って、主張のほうを抑制する」段まで進めた。新しい探索演算子を発明したのではなく、不確実性を定量化して verdict を律する disclosure 層 を足した点に価値を置いています。

ケンドールの順位相関(Kendall τ) — 2 つの指標(ここでは安い proxy と本気の judge)が「順位の付け方」でどれだけ一致するかを −1〜+1 で表す係数。+1 なら順位が完全一致、0 なら無関係です。安い模試と本番の順位がどれだけ揃うかを 1 つの数字にしたもので、揃っていなければ proxy の勝ち判定を格下げします。

隠さない未検証ギャップ(honest gap)

誠実さは「測った所」だけでなく「測っていない所を申告する」ことでも決まります。

  • context 長スイープは 256/512/1024 まで。長距離検索(needle / passkey)も 2048 以上は未実測。 最アグレッシブな設計(83.9% 節約)で文脈長を振ると、Δnll は 256:0.761 → 512:1.012 → 1024:1.182 と長文ほど劣化が増大しました(定数状態の弱点が伸びる兆候)。これは理論側とも符合します — 線形再帰モデルの長距離メモリ劣化を decay spectrum に帰着した先行研究(Optimal Decay Spectra for Linear Recurrences, arXiv:2604.07658)は、ランダム初期化で最小スペクトルギャップが O(N⁻²) に潰れ、長文脈で誤差が 実質代数的(sub-exponential)に劣化する と証明しています。なお、いざ needle を測れたとしても 満点スコアだけでは決着させません — 長文脈の継続事前学習の学習動態を追った先行研究(Revealing the Learning Dynamics of Long-Context Continual Pre-training, arXiv:2604.02650)は、NIAH(needle-in-a-haystack)スコアが内在的な収束より早く "deceptive saturation(見かけの飽和)" を示し、PPL ベースの分析の方が実際の改善を正しく追えると報告しています。「needle が満点だから長距離記憶は大丈夫」という読み方こそ、本稿が戒める「勝った気になる」の一形態です。
  • そこを測ろうとして、自分の機械のメモリが先に壊れました(正直なオチ)。 当初の下書きでは「2048 は inner-loop 長が 1024 だから構造的に出ない」と書いていましたが、これは 誤り でした(スイープ処理は inner-loop 長と独立に任意長の窓を切れ、コーパスも 230 万トークンと十分長い)。訂正したうえで実際に 2048 のスイープ + needle 検索を回し直したところ —— 自宅 CPU(物理 RAM 3.6GB)では、2048 トークンの full-attention forward が working set 3.9GB に膨れ、RAM を超えてスワップで thrashing。2 度試して 2 度とも完走しませんでした。ここには笑える皮肉があります —— この章の主題は「定数状態モデルが長文脈でメモリを溢れさせる」失敗モードなのに、それを測ろうとした私の機械が、まさに長文脈でメモリを溢れさせた。次の正しい一手は GPU へのオフロードで、それまでは 2048+ の long-context retrieval は「未検証」 と正直に置いておきます。「だから長距離検索は大丈夫」とは 言いません
  • attention-KL は診断専用で fitness に未配線。 層別の forward KL(softmax‖student)は mean 3.68 / max 7.67(layer 9)。劣化の所在を見るための診断であって、探索の目的関数には入れていません。

needle / passkey 検索(NIAH, needle-in-a-haystack) — とても長い文章の中に 1 個だけ埋め込んだ情報(干し草の山の中の 1 本の針)を、モデルが正しく取り出せるかを試すテストです。長い文脈の記憶力を測る代表的な方法で、「満点でも本当に覚えているとは限らない」のが本文の論点。

業界のリーダーボードは「勝った」で埋まっています。でも、その勝ちが選抜窓の楽観バイアスなのか新品窓でも残る実力なのかを、同じ精度で開示している例は多くありません。

勝った気になる前に、内訳を疑う。その「疑い」を、感想ではなく 閾値 にする。

前段の「負けを見せる」の次は、「勝ちを自分で抑制できる」。誠実さは、見せるものから 仕組むもの へ。


b6. 勝ち筋を、誰でも 1 行で検収できる形に畳む

これまで「負けを見せる」回(2bit の敗北、安全ゲートの空振り、AI レビューの誤指摘、会話できない自作 LLM)を重ね、b2 で「勝ちを自分で抑制する」を見ました。最後はその 対になる回 です。負けではなく、勝ち筋を道具に畳んだ話。ただし主役は新発明ではなく、「誰でも 1 行で検収できる形にする」という地味な誠実さ です。

llcore には、メモリ効率の 検証済みプリミティブ がいくつもありました — int8 量子化(重みを 4 分の 1 に)、mmap ストリーミングロード、定数状態 recurrent(長文脈でもメモリが平ら)、cap-gate(能力が壊れていないか検収するゲート)。問題は、これらが scripts/lm/バラバラに散らばっていた こと。台所の道具が引き出しのあちこちに入っていて、「どれを呼べば何が分かるのか」が外から見えない。勝ち筋はあるのに、使えない。

プリミティブ(primitive) — それ以上は分解しない、組み合わせの土台になる「基本部品」のこと。ここでは int8 量子化や mmap など、メモリ効率のための個々の最小機能を指します。料理で言う「だしの取り方」「切り方」のような、単体で使える基礎テクニックのイメージ。

そこで llcore.memory という facade(受付窓口) を 1 つ作り、measure_memory() を足しました。fp32 のモデルを 1 個渡すと、「どれだけ小さくなり、その代償に何を失うか」を 1 回で返す。返ってくる MemoryReport は 3 つの軸を 1 枚に畳みます。(1) 量子化 footprint(静的) int8 でどれだけ小さくなるか、(2) capability retention + cap-gate 能力が保たれているか(壊れていれば検収で止める)、(3) 文脈長 KV 成長(動的) 文脈を伸ばすとメモリがどう増えるか。

散らばった int8 / mmap / 定数状態 / cap-gate のプリミティブを facade(llcore.memory)に畳み、measure_memory() が footprint・capability・KV 成長の 3 軸を 1 枚にまとめる図。独自性は cap-gate PASS 時だけ int8 を書き出し FAIL/コーパス無では fail-closed で拒否する検収運用 1 点だけ、という構図を示す。

既存手法の再導出を 1 つの受付窓口に畳み、唯一の独自性である cap-gate 検収を fail-closed の分岐として組み込んだ全体像。

実機の正直な数字

実トレーニング済みモデルでの実測(footprint は params+buffers の resident-weight 会計で、on-disk とは別物 — b3 章の会計の話に直結します):

モデル fp32 int8 削減
realp1 49.23 MB 13.97 MB 71.6%減
multi_smoke 5.50 MB 1.51 MB 72.6%減

能力のほうは、青空文庫マルチ全文(330,368 トークン)で top-1 retention 100.0%(fp32 0.3629 → int8 0.3631)、cap-gate PASS。ここで 重要な正直注記:

int8 が fp32 を 0.0002 だけ「上回った」のは 改善ではありません。同点 argmax の測定ノイズです。

この規模では int8 量子化の能力コストが実質ゼロ —— 別記事の「per-channel int8 の劣化 <0.1%」の追認であって、「int8 のほうが賢くなった」という主張では断じてありません。良い数字が出たときほど、内訳を疑って正直に書く。これも packaging の一部です。

3 軸目(文脈長 KV 成長)も同じレポートで出ます: realp1 で T=256 の 4.72MB → T=2048 の 37.75MB と ×8.0 の線形成長(一方 constant_state_bytes は文脈長に依存せず一定)。共有の物差しの章で触れた「伸びる項 vs 平らな項」が、ツール 1 つで誰でも再現できます。

検収を fail-closed にする — これが唯一の誠実な独自性

正直に立ち位置を書きます。プリミティブ自体は新発明ではありません。 int8 / mmap / 定数状態は llama.cpp や GGUF が既に確立した手法の 再導出 です。では私の誠実な独自性は何か。「footprint の勝ちを、能力ゲートで fail-closed に検収する運用」 —— ただ 1 点です。

具体的には、CLI の --save-int8cap-gate が PASS したときだけ int8 チェックポイントを書き出します。能力検収に失敗(FAIL)、またはコーパス未指定で能力を測れない場合は、fail-closed で書き込みを拒否(--force で運用者が明示的に上書き可能)。measure_memory は評価データが無ければ capability を None で返し、「無いものを捏造しない」

なぜこれが要るか。b1 章で見たように、PPL だけのゲートは、top-1 が半減した壊れた低ビットモデルを平気で PASS させる。「小さくなった」を「使える」と取り違える事故を、検収で構造的に止める —— これが packaging に込めた唯一の主張です。料理のレシピで言えば、「すごく美味しい裏ワザ」を 1 人で発見しても分量も手順も曖昧なままでは再現できない。「材料は何グラム、火加減はここ、味見でここを確認」と検品手順つきのレシピに書き起こして初めて、他人が同じ味を作れ、しかも「これは焦げているから出してはいけない」と事故も防げる。

但し書きを隠さず置きます。footprint は resident-weight 会計(params + buffers) で量子化できない causal-mask の fp32 まで含む保守側、on-disk ファイルサイズとは別物。「良い HW ほど効く」設計指針(int8 → GPU の真 int8 GEMM / mmap → 大 RAM の共有ページキャッシュ / 定数状態 → 長文脈)はいずれも 設計仮説で未計測、速度は本連載では測っていません。870 件のユニットテストが通る状態で facade を組みましたが、これは「配線が正しい」ことの担保であって、「アルゴリズムが新しい」担保ではありません。

研究の価値は、新規性の派手さだけでなく、「既存の勝ち筋を、誰でも再現・検収できる道具にすること」 にもある。

フロンティアを自宅 CPU で再導出し、それを「小さくなったか? 壊れていないか?」を 1 コマンドで答える道具に変える。地味です。でも、負けを正直に見せる連載の最後に置くべきは、この 「勝ち筋を、検収可能な道具にして残す」 という構えだと思っています。


着地 — なぜ「負け」が、個人のキャリアの核になるのか

7 つの章を通して、私は自分の成果を何度も自分の審判に止められました。2bit QAT を、mmap の過剰一般化を、int8 streaming の peak 期待を、進化の 20/20 を、NAS の +15.3% を。安全ゲートは出番が無く、賢さの天井は構造的に閉じていた。AI レビュアーの「捏造だ」は一次証拠で覆り、負けた研究の道具は別の土俵で生き返り、勝ち筋は 1 行で検収できる道具に畳まれた。

第一に、勝ちの主張は無限に作れるが、負けの開示は嘘がつけない。 「97% に届かなかった」「peak はほぼ不変だった」「自分の 20/20 を自分で否定した」「+15.3% を自分のノイズ床で黙らせた」 — こういう数字は、盛っても得しません。むしろ盛れば自分が損をする。だからこそ、これらを自分から出している人間は「この人は良い数字も同じ正直さで出しているのだろう」と推定される。敗北の開示は、勝利の数字の信頼性を担保する保証金 です。

第二に、私が作ったのは「賢いモデル」ではなく「自分を止める仕組み」だった。 cap-gate(97% 保持)も、strong-gradient meta-gate も、winner's curse 除去の holdout 窓も、cap-gate fail-closed の検収も、外の誰かを超えるための装置ではありません。自分の楽観を、公開前に自分で止めるための装置 です。そして実際に止めました。外を超えるベンチを 1 つ作るより、自分を止める内なる審判を 1 つ作るほうが、はるかに難しく、はるかに信用される

第三に、これは自宅 CPU の極小モデルだからこそできた。 冒頭の免責の通り、ここで見せた数字は 0.81M〜130M の char-LM PoC(b2 章のみ 0.5B の既製モデルを CPU 変換)であって、12B〜64B の実 LLM 性能を反証するものではありません。大手と「賢さ」で殴り合っても勝ち目はない。だから私は、賢さの土俵を降りて、計測規律という土俵に立ち位置を移しました。 「どの数字が信用できて、どの数字が信用できないか」を、自分の小さな実験の上で隠さず線引きして見せる。これなら、12B のモデルを持っていなくても、個人が差し出せる価値になります。

勝った話は、読み終えれば忘れられます。負けを、数字に刺して、誠実に開いて見せた話は、信用として残ります。 自宅 PoC の敗北ログを、信用の材料に変える — それが、この一部でずっとやってきたことの正体です。異常に良い結果が出たときほど、勝った気になる前に内訳を疑う — 他人にではなく、まず自分に。それが、この連載すべての土台です。


再掲(本記事の射程): 全数値は自宅 CPU・極小 char-LM(0.81M〜130M、b2 章のみ 0.5B の既製モデルを CPU 変換)PoC の実測です。量子化の footprint は実測値、推論速度は simulated quant のため未測定。スコアは next-token-nll proxy であり会話品質クレームは含みません。大手の実 LLM(12B〜64B)を性能で直接反証・凌駕する主張ではなく、手法・思想・計測規律の次元での比較 です。再現用のコードと出力 JSON(scripts/*.py / out/*.json / src/llcore/lm/eval.py / src/llcore/lm/quant.py / src/llcore/runtime/eval_proxy.py / src/llcore/fitness/memory_objective.py / src/llcore/memory.py ほか)は GitHub で公開しています。


C アーク — 技術の外の支配項(ライセンス・成長・記憶)

LLM の話をしていると、つい「賢さ」や「速さ」といった技術指標に目が吸い寄せられます。けれど 2026 年前半の業界を自宅 CPU から眺めていて、繰り返し思い知らされたのは別のことでした。プロダクトの命運を握るのは、しばしば技術そのものではなく、技術の「外側」にある支配項だ —— ということです。

支配項(dominant term)とは、結果を一番大きく左右する項のこと。性能を 2 倍にしても、商用ライセンスが合わなければ採用できない。学習ループを高速化しても、誤りを止める仕組みがなければ「使うほど劣化」する。記憶機構を磨いても、どのドメインで何を畳むかを取り違えれば一貫性は得られない。本稿(連載「自宅 CPU から見た 2026 年 6 月の LLM 業界」エコシステム編)は、その「技術の外の支配項」を ライセンス → 成長 → 記憶 の 3 段で巡ります。


共通の免責(本連載すべてに掛かるバナー)

本連載の中心(llcore)で示す実測値は、すべて自宅 CPU 上の極小モデル PoC の honest disclosure です。大手の実 LLM を直接反証したり凌駕したりする話ではありません。本稿で大手・他社・他プロジェクトと比較する場面が出てきますが、比較しているのは手法・思想・計測規律の次元であって、絶対性能の優劣ではありません。そして本稿は 法的助言でも投資助言でもありません。他社(Google / NVIDIA / Baidu / Nous Research / MangaFlow 著者ら)への言及はすべて公開情報の 2026 年 6 月時点の理解で、数値には出典を併記します。本連載の作法どおり、他者を斬る刃は最後に必ず自分(FullSense / llcore / llive)にも向けます

本稿で何度か出てくる共通語を、ここで一度だけ定義しておきます(各章で繰り返しません)。

  • honest disclosure(正直な開示): 「うまくいった」と主張する前に、その内訳を疑い、未証明の部分・条件・反例を隠さず開示する規律。本連載の背骨です。異常に良い数字が出たら、勝った気になる前に必ず分解する。
  • OSI 認定 OSS: Open Source Initiative の定義(自由な利用・改変・再配布、分野差別なし等)を満たすライセンス。Apache 2.0 や MIT が代表。「open model ライセンス」を名乗るものの中には、これを満たさないものがあります。
  • 定数状態(constant state): 過去をどれだけ読んでも、固定サイズの「まとめ」に畳んで運ぶ方式。文章が長くなっても状態のサイズが増えない、recurrent / SSM 系の発想。第 3 章で詳しく扱います。

状態空間モデル(SSM, State Space Model)/ recurrent(再帰型): 過去を全部読み直さず、要点だけを決まった大きさの「状態」に持ち越しながら次を予測していく方式。長い物語でも「あらすじカード 1 枚」だけを携えて読み進めるイメージ。


第 1 章 — open weights のライセンスが 3 種に割れた

「open」の一語では、商用可否は決まらない

2026 年前半、注目の open モデルのリリースが相次ぎました(Gemma 4 は 4 月、Cosmos 3 / PaddleOCR は 6 月)。面白いのは、ライセンスが 3 種類に割れたことです。「open(公開重み)」と一括りにすると、この差を見落とします。

「open weights」は「重みがダウンロードできる」という意味でしかありません。「商用に使える」「派生物を自由に出せる」「OSI 認定の古典的 OSS だ」は、別々の話です。重みが落とせても、商用利用に条件が付くもの、派生物に制約があるものがあります。だから「open だから安心」ではなく、どの種類の open かを見分ける必要があります。

レンタル品のたとえ

「無料で貸し出します」と書かれた道具でも、よく見ると条件はバラバラです。

  • A:本当に自由(改造も再配布も商用も OK)
  • B:借りられるが、商用には別条件(契約書を読まないと分からない)
  • C:本体は自由だが、中の部品は別の貸主のもの(部品側の条件も確認が要る)

「無料貸出」の貼り紙だけ見て全部 A だと思うと、後で困ります。AI の公開も、まさにこれと同じでした。

3 種に割れた実例(2026 年前半)

この時期に出た 3 つを、ライセンス軸で並べます。

モデル ライセンス 種類 商用ローカル利用の見立て
Gemma 4(Google) Apache 2.0 OSI 認定 OSS 障壁ゼロ(後述の「変更」が大きい)
Cosmos 3(NVIDIA) OpenMDW 1.1 open model ライセンス(OSI 認定の古典的 OSS ではない) 商用条件・派生物条項を条文実読してから
PaddleOCR-VL(Baidu) Apache 2.0(ただしベースに注意) OSI 認定 OSS Apache だが ERNIE-4.5 ベースの派生ライセンス要確認

2026 年前半の 3 モデルをライセンス軸で 3 種(OSI 認定 OSS / open model / 独自規約・条件付き)に振り分けた地図。Gemma 4 は Apache 2.0、Cosmos 3 は OpenMDW 1.1(非 OSS=条文実読が必要)、PaddleOCR-VL は Apache だが ERNIE-4.5 ベース要確認。要点は「重みが落とせること(技術)と商用に使えること(ライセンス)は別の検収」で、採用前に種類・商用条件・ベース継承の 3 つを別々に確認する、という一枚地図。

「無料公開」でも条件は 3 種に割れる、という本章の要点を一枚にした図。

(a) Gemma 4 = Apache 2.0 への「変更」が本物の前進

Gemma は 1/2/3 まで、Google 独自の Gemma Terms of Use で配布されていました。これが Gemma 4 で Apache 2.0 に変わったのが大きい。独自規約には利用制限や再配布条件が付きがちですが、Apache 2.0 は OSI 認定の素直な OSS。商用ローカル利用の障壁が実質ゼロになりました。「マイナーアップデート」ではなく、ライセンス面では質的な前進です。地味に見えて、仕事で使う障壁がほぼ消えた、大きな一歩でした。

(b) Cosmos 3 = OpenMDW 1.1 は「open だが OSS ではない」

NVIDIA の Cosmos 3 は OpenMDW 1.1(Linux Foundation 系の model 中心ライセンス)。これは「open model」を名乗りますが、OSI 認定の古典的 OSS とは別物です。商用条件や派生物の扱いは、Apache のように一律「自由」とは限らない。条文を読まずに「open だから商用 OK」と判断するのは危険な型です。先ほどのレンタル品でいう「B:借りられるが商用には別条件」に当たります。

(c) PaddleOCR = Apache 2.0、ただしベースに注意

PaddleOCR-VL は Apache 2.0。素直に見えますが、ERNIE-4.5 をベースにしているため、ベースモデル側のライセンス継承を確認する必要があります。「ラッパーは Apache、でも中身の継承は別」というパターンは、派生モデルでよくある落とし穴。レンタル品でいう「C:本体は自由だが中の部品は別の貸主」です。

なぜこれが FullSense / llmesh の戦略に効くか

ここからが本題の「だから何か」です。私の関わる FullSense は Apache-2.0 + Commercial dual-license で、その中の llmesh は「複数の LLM を on-prem(手元)で統合して配信するハブ」です。llmesh にとって、ローカルで商用利用できるバックエンドモデルが増えることは、そのまま選択肢の拡大=追い風です。

dual-license(デュアルライセンス): 同じソフトを 2 種類のライセンスで同時に配る方式。ここでは無償の OSS 版(Apache-2.0)と有償の商用版を併売するやり方で、1 冊の本を「図書館で無料」と「書店で有料」の両方に置くイメージ。

  • Apache 2.0 のローカル実行可能モデルが増えた(Gemma 4 等)→ llmesh の on-prem バックエンド候補が、商用障壁なしで増える。
  • 一方、商用障壁のあるモデル(独自規約・条件付き open model ライセンス、あるいは Qwen 系のような商用条件)に依存しすぎないのが、dual-license 製品としての安全側。FullSense は「Qwen 依存は商用障壁になりうる」という観点から、バックエンドの可搬性を重視しています。

そしてもう 1 つ、llcore(自作の極小モデル研究)の立ち位置を補強します。「Apache 2.0 の優秀なローカルモデルが増えた」世界では、自作モデルで賢さを競う意味はますます薄い。会話品質が要るなら llmesh 経由で Gemma 等を回せばいい。llcore はモデルで競合せず、メモリ効率の研究ビークルに徹する —— このライセンス地図は、その役割分担の正しさを裏側から支えます(この「メモリ効率」という賭けは、第 3 章でまた戻ってきます)。

第 1 章の持ち帰り — 「open」を 3 つの問いに分解する

公開モデルを採用候補にするとき、「open かどうか」ではなく、次の 3 つを別々に確認してください。

  1. ライセンスの種類: OSI 認定 OSS(Apache/MIT)か、独自規約か、「open model」ライセンス(OpenMDW 等)か。
  2. 商用利用の条件: 商用に追加条件・制限はあるか(売上閾値・用途制限・帰属義務の範囲)。
  3. 派生物とベースの継承: 派生モデルを出せるか。ベースモデルのライセンスを継承していないか。

検出シグナル: 「open weights!」の一言で商用可否を判断しない。ライセンス名を確認し、OSI 認定 OSS でなければ必ず条文を実読する。「Apache」と書いてあってもベースモデルの継承を一段たどる。

黒髪の女性が目を閉じ汗をかいて「犯罪のボーダーが身近過ぎて怖すぎる…!」と嘆き、手前の金髪の女性が「知らなかったでは許されない…!」と返すコマ。頭上に「合法」の細い足場と「違法」の断崖のイラストが描かれている

🗒️ 「知らなかったでは許されない…!」— ライセンスも同じで、「open って書いてあったから」は免罪符にならない。結局、条文を読むしかない(© Forbidden shibukawa / SHUEISHA・『スナックバス江』)

honest な留保(第 1 章)

  • 本章は 法的助言ではありません。ライセンス分類は方向性の地図で、束縛力を持つのは各モデルのライセンス条文そのものです。採用判断の前に原文を読んでください。
  • 記載は 2026 年 6 月時点の理解で、ライセンスは改定されえます(Gemma が 3→4 で変えたように)。
  • 各モデルの細目(OpenMDW 1.1 の商用条件・派生物条項、ERNIE-4.5 ベースの継承範囲)は、本章では条文の逐条確認まではしていません。「要条文実読」と明記した箇所は、まさにそこが採用前の確認ポイントです。

ライセンスは「技術の外の支配項」の第一例でした。どれだけ性能が良くても、商用条件が合わなければ採用できない —— 重みが落とせること(技術)と、商用に使えること(ライセンス)を、別々に検収する。これが honest disclosure をライセンス面に当てた作法です。次の章は、もう 1 つの「技術の外の支配項」 —— エージェントの「成長」を扱います。


第 2 章 — 「成長する」と「責任を持って成長する」は別物

「使うほど育つ」は、必ずしも「良くなる」ではない

ライセンスが「採用できるか」の支配項なら、自己成長エージェントにとっての支配項は「育つ方向」です。いま最もホットな謳い文句「自己成長するエージェント」を解剖します。

結論を先に言います。「使うほど育つ」は魅力的な言葉ですが、"育つ"は"良くなる"を意味しません。 間違った学びを溜め込めば、エージェントは「使うほど劣化」もしうる。この章は、その分岐点を「責任を持って成長する」という設計思想で捉え直します。

Hermes Agent とは(公平に、まず長所から)

Nous Research の Hermes Agent(OSS、MIT ライセンス、2026 年初頭リリース)は、**built-in learning loop(内蔵学習ループ)**を売りにしたエージェントです。公開情報によれば、骨子は次の 5 点:

  1. タスク完了後に skill(再利用可能な手順)を自動生成
  2. 使用中に skill を自己改善
  3. 記憶を永続化
  4. FTS5 による全文横断検索で過去を引く
  5. Honcho による user modeling(ユーザー像の学習)

FTS5 / Honcho: FTS5 は SQLite(軽量データベース)の全文検索機能(Full-Text Search 第 5 版)で、ためた過去ログから該当箇所をすぐ引ける索引——本の巻末索引で語をたどるイメージ。Honcho はユーザーの好み・傾向を学習する外部ライブラリ(部品)。どちらも「過去を覚えて引き出す」ための道具立て。

「使うほど自分用に育っていく」エージェント。これは本物の魅力で、GitHub star も非常に多い(後述、ただし star の質には留保)。そして、これは私の関わる llive(自己進化・4 層メモリ・派生集団進化を掲げる認知 OS)と、真正面から競合します。だからこそ、公平に、でも正直に見ていきます。

★核心 — 「成長」には、暗黙の前提がある

「使うほど育つ」という主張には、語られない前提があります。

学んだことが、常に正しいとは限らない。

エージェントが「タスク後に skill を自動生成し、それを再利用する」とき、もしその skill が間違っていたらどうなるか。間違った手順が記憶に溜まり、次のタスクで再利用され、さらに別の skill の土台になる。誤りが自己増殖する —— これを私は「汚染ループ」と呼びます(二次情報でも同種のリスクが指摘されています)。

具体的にはこうです。AI が一度「この種の作業はこの手順で」と覚えた手順に小さな誤りがあったとします。すると次の似た作業でその誤った手順がそのまま呼び出され、さらにその上に「その手順を使った、より大きな手順」が積み上がっていく。こうなると元の小さな誤りを後から抜き取るのは難しく、土台ごと汚れた状態で AI が"成長"してしまう。

たとえるなら、自己流の変なクセが付いたまま練習を続けるスポーツ選手。練習すればするほど上手くなる——とは限りません。間違ったフォームを反復すれば、練習するほど下手が固まることもある。「成長」を無条件に善とすると、この汚染ループが見えなくなります。成長 = 改善、ではない。 学習ループは、正しく学べば改善し、誤って学べば劣化する。両方向に開いた刃です。

同じ内蔵学習ループ(skill 自動生成/改善/記憶永続化/全文検索/user modeling)が、ゲートの有無で二方向に分岐する図。ゲート無し(成長する)は誤りが自己増殖する「汚染ループ」へ、承認ゲート(Approval Bus / HITL / honest disclosure, fail-closed)を噛ませた「責任を持って成長する」は誤 skill を黙って通さず止める方へ。右列は Hermes も llive も独立ベンチ・査読が無く両者とも未証明である点を示す。分岐点は「学べる量」でなく「誤って学んだとき止められるか」、という一枚図。

同じ学習ループでも、止める機構が architecture にあるかで「育つ」か「劣化する」かが分かれる。

だから問うべきは「成長するか」でなく「責任を持って成長するか」

ここに llive の設計思想の分岐点があります。llive は「成長する」より一歩進んで、**「誤った学びを止める仕組みを持って成長する」**を core に据えています。具体的な機構は:

  • Approval Bus: 状態変化(skill 採用・記憶への昇格)を、無条件に通さず承認を要する関所に通す。
  • HITL(Human-in-the-Loop): 重要な学習の採否に人間(または上位の検証)を挟む。
  • honest disclosure: 「成長した」と主張する前に、その学びが本当に改善かを疑い、内訳を開示する(本稿冒頭で定義した、あの規律です)。

これらは要するに、**「学習ループに fail-closed なゲートを噛ませる」**設計です。fail-closed とは「迷ったら通さず止める」既定動作のこと。要は、コーチが横について「そのフォーム、間違ってるよ」と止めてくれる仕組みを、最初から組み込むという発想です。気合で気をつけるのではなく、architecture として誤学習を止める

成長するエージェント = 学習ループを回す。
責任を持って成長するエージェント = 学習ループに承認ゲートを噛ませ、汚染を止める。

FullSense の設計哲学(責任所在を architecture level に持ち込む)が、ここで具体化します。

★ここで自分に刃を向ける(競合だけ斬らない)

ここまでだと「llive すごい / Hermes 危ない」に読めてしまう。それは本連載が最も嫌う型です。公平に、両方に同じ物差しを当てます。

Hermes 側への公平な評価:

  • Hermes は実在し、MIT で公開され、広く使われている本物の OSS です。「危ない」と決めつけるのは不当。
  • ただし honest に見ると、learning loop の有効性を示す独立ベンチ・査読論文は確認できません(arXiv 検索 0 件、効果は公式の自称が主)。「育つと良くなる」はまだ第三者検証されていない主張です。
  • GitHub star は 数万規模(複数の独立レポートで 2026 年 4 月時点 約 47,000〜57,000、2026 年 2 月リリースから 2 か月での急増)で、確かに人気です。ただし star の数値・質(bot / キャンペーン由来の比率)は出所により食い違い、私が当初参照した「約 196,554」という値は他ソースで裏付けられませんでした(過大の疑い)。「マインドシェア先行」の脅威は実在するが、規模の正確な数値は出所依存で確度に留保が要ります。
  • 直近リリースは公開情報では既存 core の GUI ガワ寄りで、新モデル・新フレームワークの追加ではない点も、誇張を避けるため明記します。

llive 側(自分)への同じ刃:

  • llive も同じく、未証明です。 Approval Bus + HITL が「汚染ループを実際に止める」ことを示す独立ベンチを、私はまだ出していません。「責任ある成長」は現時点で設計思想であって、実証された優位ではない
  • Hermes に「独立ベンチがない」と言うなら、llive にも同じ札が貼られます。違いは「汚染を止める機構を architecture に持っているか」という設計の有無だけで、その機構の有効性は両者とも今後の検証待ちです。
  • 「成長 ≠ 改善」を掲げる以上、llive 自身の「進化」も、勝った気にならず内訳を疑う対象です。

つまり正直な結論は「llive が優れている」ではなく、**「両者とも未証明だが、llive は誤学習を止める機構を最初から architecture に組み込む側に賭けている」**という、設計選択の表明です。

第 2 章の持ち帰り — 「自己成長」を見たら 3 つを問う

「使うほど育つ AI」という売り文句を見たら、次の 3 つを確認してください。

  1. 学びの正しさを誰が保証するか: 自動生成した skill / 記憶を、無条件に採用していないか。承認・検証のゲートはあるか。
  2. 汚染ループ対策はあるか: 誤った学びが溜まり再利用される経路を、止める仕組みがあるか。
  3. 「育つと良くなる」は検証済みか: 独立ベンチ・査読があるか、それとも自称か(これは competitor にも自分にも問う)。

検出シグナル: 「使うほど賢くなる」を無条件の善として語っていたら警戒。成長は両刃で、止める機構の有無が責任の分かれ目。

honest な留保(第 2 章)

自己成長エージェントの競争は「どれだけ学べるか」で語られがちです。でも本当の分岐点は、「誤って学んだとき、それを止められるか」です。学習ループは、承認ゲートが無ければ汚染ループに反転する。ただし —— 本連載の作法どおり最後にもう一度言います —— その機構が実際に汚染を止めることは、llive 自身もまだ証明していません。 Hermes も llive も、同じ「未証明」の段にいる。違うのは賭けている設計だけ。「責任ある成長」は、これから実測で証明すべき約束であって、達成済みの勝利ではありません。

責任を「運用で気をつける」ではなく architecture に置く —— ここで第 2 章に出てきた「記憶を永続化し、後で引く」という共通機構が、実は第 3 章の主役です。Hermes も llive も、その骨格を使っていました。最後の章は、その「記憶」が分野を超えて再演されることを見ます。


第 3 章 — 記憶による一貫性は、ドメイン横断の普遍部品

「過去を記憶に畳んで、後で引く」

第 2 章でエージェントは「記憶を永続化し、後で引く」機構を持っていました。実はこの「過去を記憶に畳んで一貫性を保つ」という発想は、LLM の長文脈やエージェントにとどまらず、マルチモーダル生成(マンガ生成)でも同じ骨格で効いている。この章はその傍証を集めます。

ここで冒頭に定義した 定数状態 を思い出してください。文章 AI が長文を扱うとき、過去をどれだけ読んでも固定サイズの「まとめ(状態)」に畳んで運ぶ。日記をその日のうちに 1 枚のまとめカードに圧縮しておき、翌日はカードだけ見れば済む —— あの発想です。recurrent / SSM 系はこれを使い、文章が長くなっても状態のサイズが増えません。

MangaFlow とは(公平に、まず要点)

MangaFlow(東大 + 香港科技大広州、arXiv:2605.28173)は、マンガを生成する研究です。マンガ生成の難所の 1 つが、コマをまたいだキャラクターの一貫性——同じキャラが次のコマで別人のように描かれては困る。MangaFlow はこれを **story section memory(物語セクション記憶)**で担保します。

arXiv(アーカイブ): 論文を査読(専門家による事前チェック)の前に誰でも公開できるプレプリント(査読前原稿)の置き場。arXiv:番号 は通し番号で、「載っている=正しさが第三者に確認済み」を意味しない点に注意。

仕組みは、各セクションにキャラ・シーン・オブジェクトの参照を紐づけ、コマ間で再利用する外部記憶。「このキャラはこういう見た目」という参照を記憶に持ち、後のコマで引いてくる。ablation(その機構を外す実験)で寄与が出ています(後述・self-report)。

self-report(自己申告): 論文の著者自身が出した数値で、第三者による独立の追試・検証を経ていないもの。テストの点を自己採点で報告した状態に近く、方向性の参考にはなるが鵜呑みは禁物。

★骨格が同じ — 「過去を記憶に畳んで、後で引く」

ここで連載の本筋とつながります。MangaFlow の story section memory は、構造としては llcore / llive で繰り返してきた「記憶で状態を保つ」発想と同じ骨格です。

  • LLM の長文脈: 定数状態 recurrent / SSM は、過去を固定サイズの状態に畳んで運び、後の予測に使う。
  • マンガ生成(MangaFlow): キャラ参照を外部記憶に畳んで持ち、後のコマ生成で引く。
  • 認知 OS(llive の 4 層メモリ): 経験を階層化した記憶に畳み、後のタスクで引く。

ドメインは違う(テキスト予測 / 画像生成 / エージェント)のに、**「一貫性は、過去を記憶に保持して再利用することで得る」**という骨格が共通しています。これは「記憶機構は LLM 固有の小技ではなく、生成・推論の一貫性を支える普遍的な部品だ」という主張の、他ドメインからの傍証になります。

ablation の数字で寄与を見ます(いずれも論文 self-report):

指標 記憶あり 記憶なし(ablation)
CIDS(キャラ一貫性系) 0.619 0.582
CSD(キャラ類似系) 0.668 0.547

記憶を外すと一貫性指標が落ちる。**「記憶が一貫性に効いている」**ことを、別ドメインが自分の実験で示した——これが傍証の中身です。

「過去を記憶に畳んで後で引く」という普遍部品(骨格)が、LLM の長文脈・マンガ生成(MangaFlow)・認知 OS(llive 4 層メモリ)の 3 ドメインで同じ形で再演されることを示す図。下部に MangaFlow ablation の self-report 値(CIDS 0.619→0.582 / CSD 0.668→0.547、記憶を外すと低下)を添え、傍証として使えるのは「記憶が一貫性に効く方向性」までと釘を刺す、一枚図。

同じ「記憶に畳んで後で引く」骨格が、テキスト予測・画像生成・エージェントの 3 ドメインに渡って再演される。

★honest な必須注記(MangaFlow を過大評価しないために)

この傍証を「だからマンガ生成 SOTA だ」と読むと誤ります。論文を honest に扱うため、4 つの注記を明示します。

SOTA(State Of The Art、最先端): その時点で最も性能が高いとされる手法・記録のこと。スポーツでいう「世界記録保持者」に当たる位置づけ。

  1. 「作画」は MangaFlow 自体ではない。 ピクセルを生成するのは外部のクラウド拡散モデル(Gemini 2.5 Flash Image / FLUX.2 9B)で、MangaFlow が担うのはその制御層(レイアウトとキャラ参照の指示)です。「MangaFlow が絵を描く」と読むのは誤り。
  2. Layout IoU 100% / Coverage 99.98% は土俵が違う。 これは幾何座標で明示配置する設計上ほぼ自明な自作メトリクスで、ピクセルから生成するベースラインと同じ土俵で比べた数字ではありません。しかも自分で設計したテストなので、有利な数字が出やすい点にも注意が必要です。
  3. 商用サイト mangaflow.studio は本論文と無関係の別製品。 名前が同じだけで混同しないこと。
  4. 査読前 v1・引用ゼロ・GitHub 公開記載なし。 つまり第三者検証は未了(信頼の梯子で言えば self-report の段)。

拡散モデル(diffusion model)/ IoU(Intersection over Union): 拡散モデルはノイズだらけの画像を少しずつ整えて絵にしていく、画像生成 AI の主流方式。IoU は 2 つの領域の「重なり具合」を 0〜1(百分率なら 0〜100%)で測る指標で、1=完全一致——ここでは Coverage と並んで「指示どおりの位置に描けたか」を測る。これらが自作の有利な土俵で測られている、という点が注記の核。

傍証として使えるのは「記憶が一貫性に効く方向性」までで、絶対的な性能主張ではない——この線引きが honest disclosure です。

もう 1 つの接続 — MangaFlow の「弱点」が、別の取り組みの存在意義を裏づける

MangaFlow は自分の限界も書いています。「stylized(様式化された)顔での話者帰属や吹き出し配置が困難」。マンガ的にデフォルメされた顔だと、「誰が喋っているか」「吹き出しをどこに置くか」が難しい、と。

これは、私の別の取り組み(マンガのコマ理解ベンチ、特に「話者 ≠ 中央の被写体」のような hard case を突くもの)が狙っているまさにその弱点です。つまり MangaFlow の自認の限界は、「様式化された絵での話者・発話の帰属は未解決の難所だ」という、ベンチの存在意義の外部裏づけになります。生成側(MangaFlow)が「ここが難しい」と言う場所は、理解側のベンチが評価すべき場所と一致する。弱点の告白が、別の取り組みの存在意義を裏づけてくれたわけです。

第 3 章の持ち帰り — 「記憶機構」を見たら、骨格とドメインを分けて読む

新しい生成 AI が「一貫性を保つ記憶」を謳っていたら、次を分けて見てください。

  1. 骨格は何か: 過去を記憶に畳んで後で引く、という普遍的な部品か(多くはそう)。
  2. どのドメインの一貫性か: テキストの文脈か、画像のキャラか、エージェントの経験か。骨格が同じでも、効く指標とコストは違う。
  3. 数字の土俵: その一貫性メトリクスは、ベースラインと同じ土俵で測ったものか、設計上自明な自作指標か。

検出シグナル: 「記憶で一貫性を保つ」は強力だが普遍的な骨格。新規性は「骨格」でなく「どのドメインで・どう畳むか」にある。自作メトリクスの 100% は土俵を疑う。

honest な留保(第 3 章)

記憶機構は LLM の小技ではない。生成と推論の一貫性を支える、ドメイン横断の普遍部品です。だからこそ FullSense は「記憶を architecture の中心に置く」(llive の 4 層メモリ)。ただし——本連載の作法どおり——MangaFlow の数字は査読前 self-report であり、傍証として使えるのは方向性まで。骨格の普遍性は支持できても、個別の性能主張は第三者検証を待つ、という線引きを保ちます。


着地 — honest disclosure を、業界とエコシステムの軸に拡張する

3 つの章は、別々の話に見えて 1 本の糸で繋がっています。支配項は、しばしば技術の外にある。

  • ライセンス(第 1 章): 性能がどれだけ良くても、商用条件が合わなければ採用できない。「open」の一語を 3 つの問いに分解する。
  • 成長(第 2 章): 学べる量がどれだけ多くても、誤りを止める機構がなければ「使うほど劣化」する。責任を architecture に置く。
  • 記憶(第 3 章): 記憶という骨格は普遍だが、新規性は「どのドメインで・どう畳むか」にある。自作指標の 100% は土俵を疑う。

そして 3 つすべてに、同じ規律 —— honest disclosure —— を当てました。本連載はもともと「自宅 CPU の極小モデルで、測り方を疑い、負けを見せる」ところから始まりました。本稿はその規律を、自分の実測値だけでなく、業界の数字・他社の主張・他ドメインの傍証にまで拡張したものです。

  • 他社の数字(Hermes の star)を引くときも、自分の引用値を疑い、過大な値は撤回した。
  • 他ドメインの数字(MangaFlow の ablation)を引くときも、土俵の違いと self-report 段であることを明記した。
  • 競合を斬る刃は、最後に必ず自分(llive も未証明)に向けた。

「open だから安心」「使うほど賢くなる」「記憶で一貫性が出る」 —— どれも魅力的なフレーズですが、その一語を信じきらず、前提を 1 つずつ検品する。数字だけでなく、ライセンス・設計思想・分野横断の傍証にまで、同じ honest disclosure を貫く。それが、技術の外の支配項を見落とさないための作法でした。


出典・確認状況(2026-06 時点)。本稿は法的・投資助言ではない。

  • 第 1 章: Gemma 4(Apache 2.0、2026-04-02 リリース、Google 公式 blog「Expanding the Gemmaverse with Apache 2.0」で独自規約→Apache 2.0 の変更=商用制約撤廃を確認。サイズは E2B/E4B/26B MoE/31B Dense)/ Cosmos 3(arXiv:2606.02800、NVIDIA 2026-06-01、OpenMDW-1.1 License=Linux Foundation)/ PaddleOCR-VL(arXiv:2606.03264、Apache 2.0、NaViT+ERNIE-4.5-0.3B、OmniDocBench v1.6 96.33%)。いずれも 2026-06 時点の理解で、条文の逐条確認は採用前に各自で必要。FullSense 側の文脈 = Apache-2.0 + Commercial dual-license / llmesh on-prem バックエンド戦略 / Qwen 商用障壁の回避方針。
  • 第 2 章: Hermes Agent = GitHub NousResearch/hermes-agent(MIT、2026 年 2 月リリース)。learning loop(skill 自動生成/使用中改善/記憶永続化/過去検索/user modeling)は確認。有効性を示す独立ベンチ・査読論文は確認できず(=公式自称が主)。star は複数レポートで 2026/4 時点 約 47k〜57k(数万規模)。当初参照した「約 196,554」は他ソースで裏付けられず過大の疑いとして撤回。汚染ループ risk は二次情報指摘。訂正履歴: 初稿は seed 由来で「作成 2025-07 / star 196,554」と記載したが、web 再照合で「2026-02 リリース / star 数万」に修正。llive 側 = FullSense の Approval Bus + HITL + honest disclosure(本稿時点で独立ベンチ未提示=設計思想であり実証済み優位ではない)。
  • 第 3 章: MangaFlow = arXiv:2605.28173(東大+HKUST広州)。Table1/Table2 + ablation(CIDS 0.619→0.582 / CSD 0.668→0.547、いずれも論文 self-report)。必須注記: (1) 作画は外部クラウド拡散モデル(Gemini 2.5 Flash Image / FLUX.2 9B)で MangaFlow は制御層、(2) Layout IoU 100%/Coverage 99.98% は幾何明示配置の自作メトリクスで生成ベースラインと土俵が違う、(3) 商用 mangaflow.studio は無関係の別製品、(4) 査読前 v1・引用ゼロ・GitHub 公開記載なし(=self-report 段)。接続先 = llcore 定数状態 recurrent / llive 4 層メモリ / マンガコマ理解ベンチ(話者≠中央被写体の hard case)。本稿は性能 SOTA 主張ではなく方向性の傍証。_

全体の着地 — 4 つのアークを貫く 1 本の糸

4 つのアークは、別々のトピックに見えて、1 本の糸で縫われています。

  1. 測れないものは、改善できない(S) — まず「1 個のスコアを信じすぎる罠」を解剖した。物差しが粗ければ、壊れたモデルも合格する。
  2. だから構造で測り、構造で勝つ(A) — bit を下げる小手先ではなく、メモリの「支配項」を測って攻める。定数状態は 60 年前の制御工学が既に解いていた。
  3. そして、負けを開示する(B) — 勝ち報告より、敗北ログのほうが信用される。自分に赤紙を出す審判を、仕組みとして実装した。
  4. 規律は、技術の外へ拡張される(C) — ライセンス・自己成長・記憶という「コードの外の支配項」にも、同じ honest な目を向ける。

つまり本連載は「自分の成果を、自分で疑う仕組みを作る」という 1 つの営みを、評価・構造・開示・エコシステムの 4 層で実演した記録です。派手な新発明の主張はどこにもありません。むしろ「車輪の再発明だった」「自分の TTT は TTT ではなかった」「壁の犯人は自分の思い込みだった」という #44 の自己訂正と、地続きです。

金髪の女性が穏やかな表情で「そんなマジに考える事じゃないからよ」と語りかけ、左手前に黒髪の女性の横顔がのぞくコマ

🗒️ 「そんなマジに考える事じゃないからよ」— 全部を疑う話を 4 アーク書いたあとで言うのも何ですが、肩の力は抜いて。ここまでお付き合いいただき、ありがとうございました(© Forbidden shibukawa / SHUEISHA・『スナックバス江』)

派生版について(本アーカイブには統合しない)

  • 一般向けかみくだき版(16 本) … 同じ内容を非エンジニア読者向けに噛み砕いた版。難度が異なるため、本アーカイブには混ぜません。
  • 多言語版(en / zh / ko の S / A / B / C アーク) … 各言語で別記事として管理します。1 本に複数言語を混在させると可読性が破綻するためです。

これらは公開戦略(どの単位・どの言語から出すか)が決まった段階で、それぞれ独立に publish 準備(タグ付与・画像の公開 URL 化・姉妹リンク解決)を行います。


この #45 を非公開にしている理由
本アーカイブは 48 本の素材を 1 本に束ねた 作業用の集約物 であり、(1) 画像が相対パスのまま(公開には raw 絶対 URL 化が必要)、(2) 公開単位(総集編 1 本か、アーク 4 本か、個別 48 本か)が未決、という 2 点で publish-ready ではありません。まず「内容を 1 か所に集約して読める状態」を作ることを優先し、公開可否はこの集約版をレビューしてから判断します。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?