Engram の参照テーブルが元モデルとバイト単位で一致していても、Backbone の重みを変更すると候補トークンのスコアが変化し、選択されるトークンが入れ替わる場合があります。保存値の一致で確認できるのは、その参照テーブルに保持された数値の同一性です。
Python と NumPy で参照テーブルを固定し、Backbone に相当する重み行列だけを変更すると、この違いを分離して確認できます。検証する項目は、参照テーブルのバイト一致、候補スコアの一致、選択されたトークンの一致の 3 つです。
Engram の保存値と Backbone の演算を分ける
Engram は、入力トークンの連続した組み合わせである n-gram から参照位置を決め、対応する埋め込みベクトルを取り出す記憶参照機構です。取得した値は文脈に応じた処理と組み合わされ、Backbone の計算経路へ渡されます[1]。
保存された参照テーブルを D、取り出したベクトルを e、Backbone に相当する重み行列を W、候補スコアを z とします。参照後の計算を、次の線形変換に縮約します。
\begin{aligned}
e &= D[0], \\
z &= We, \\
y &= \operatorname*{arg\,max}_{i \in \{A,B\}} z_i
\end{aligned}
D[0] はテーブルの 0 行目を取得する操作で、y は最大スコアの候補です。参照位置を 0 に固定し、参照後の計算を線形変換で表現します。実際の Engram に含まれる n-gram のハッシュ、文脈依存ゲート、畳み込み演算は検証範囲から外し、W の差を独立して調べます。
比較する条件は次の 3 ケースです。
| 条件 | 参照テーブル | Backbone の重み | 確認する性質 |
|---|---|---|---|
| 元モデル | 同一の D
|
W_ORIGINAL |
候補 A が選択される |
| 順位逆転 | 同一の D
|
W_FLIP |
候補 B が選択される |
| 順位維持 | 同一の D
|
W_KEEP |
スコアが変化しても候補 A が選択される |
Python と NumPy の実行環境を固定する
再現用の環境は Python 3.12 と NumPy 2.2.6 です。GPU やモデルのダウンロードは使用しません。Linux または macOS で、次のコマンドを実行します。
python3.12 -m venv .venv
. .venv/bin/activate
python -m pip install numpy==2.2.6
python --version
python -c 'import numpy as np; print(np.__version__)'
バージョン確認では Python 3.12 系と 2.2.6 が表示されることを確認します。比較する浮動小数点数にはリトルエンディアンの 64 ビット形式(<f8)を使用し、バイト列の比較条件を一定にします。
参照テーブルのバイト一致を確認する
NumPy の ndarray.tobytes(order="C") は、配列の要素を C 順序に並べたバイト列を返します[2]。本例では dtype と形状も一致することを確認してから、バイト列を比較します。
D_ORIGINAL と D_COPY は別々に生成した配列ですが、格納値は同じです。D_MODIFIED は 1 要素を変えた比較用の配列で、バイト不一致を検出できることを確認します。
Backbone の変更で候補スコアが逆転する条件を作る
参照テーブルの 0 行目から取得する値を e = [1.0, 0.0] に固定します。元の重みと順位逆転用の重みは次のとおりです。
W_0 =
\begin{pmatrix}
2.001 & 0 \\
2.000 & 0
\end{pmatrix},
\qquad
W_1 =
\begin{pmatrix}
1.999 & 0 \\
2.000 & 0
\end{pmatrix}
元のスコアは候補 A が 2.001、候補 B が 2.000 です。W_1 では候補 A が 1.999 となり、候補 B が最大になります。これらの数値は実験のための設定値であり、公開されたモデルの測定値ではありません。
Backbone の値が変わっても出力が一致する条件を作る
第三のケースでは、候補 A のスコアを 2.0005 に変更します。候補 B の 2.000 より大きいため、選択結果は A のままです。スコアが異なることと、選択結果が異なることを別々に判定します。
以下が、テーブルのバイト比較から 3 ケースのスコア計算までを実行する全コードです。engram_fixed_lookup.py として保存します。
import numpy as np
DTYPE = np.dtype("<f8")
LOOKUP_INDEX = 0
CANDIDATES = ("A", "B")
# 同一の値を持つ独立した参照テーブル
D_ORIGINAL = np.array([[1.0, 0.0], [0.0, 1.0]], dtype=DTYPE)
D_COPY = np.array([[1.0, 0.0], [0.0, 1.0]], dtype=DTYPE)
D_MODIFIED = np.array([[1.0, 0.5], [0.0, 1.0]], dtype=DTYPE)
W_ORIGINAL = np.array([[2.001, 0.0], [2.000, 0.0]], dtype=DTYPE)
W_FLIP = np.array([[1.999, 0.0], [2.000, 0.0]], dtype=DTYPE)
W_KEEP = np.array([[2.0005, 0.0], [2.000, 0.0]], dtype=DTYPE)
def same_bytes(a, b):
return (
a.dtype == b.dtype
and a.shape == b.shape
and a.tobytes(order="C") == b.tobytes(order="C")
)
def infer(table, backbone):
reference = table[LOOKUP_INDEX]
scores = backbone @ reference
token = CANDIDATES[int(np.argmax(scores))]
return scores, token
original_scores, original_token = infer(D_ORIGINAL, W_ORIGINAL)
flip_scores, flip_token = infer(D_COPY, W_FLIP)
keep_scores, keep_token = infer(D_COPY, W_KEEP)
assert same_bytes(D_ORIGINAL, D_COPY)
assert not same_bytes(D_ORIGINAL, D_MODIFIED)
assert np.array_equal(original_scores, infer(D_COPY, W_ORIGINAL)[0])
assert not np.array_equal(original_scores, flip_scores)
assert not np.array_equal(original_scores, keep_scores)
assert (original_token, flip_token, keep_token) == ("A", "B", "A")
print(f"参照テーブル一致: {same_bytes(D_ORIGINAL, D_COPY)}")
print(f"変更した参照テーブルとの一致: {same_bytes(D_ORIGINAL, D_MODIFIED)}")
for name, scores, token in (
("元モデル", original_scores, original_token),
("順位逆転", flip_scores, flip_token),
("順位維持", keep_scores, keep_token),
):
print(f"{name}: A={scores[0]:.4f}, B={scores[1]:.4f}, token={token}")
print(f"スコア一致(順位逆転): {np.array_equal(original_scores, flip_scores)}")
print(f"スコア一致(順位維持): {np.array_equal(original_scores, keep_scores)}")
保存後に実行します。
python engram_fixed_lookup.py
保存値と出力の検証結果を分けて判定する
実行結果は次のとおりです。
参照テーブル一致: True
変更した参照テーブルとの一致: False
元モデル: A=2.0010, B=2.0000, token=A
順位逆転: A=1.9990, B=2.0000, token=B
順位維持: A=2.0005, B=2.0000, token=A
スコア一致(順位逆転): False
スコア一致(順位維持): False
出力例は Python 3.13.5 / NumPy 2.3.5 で照合した結果です。前節で指定した Python 3.12 / NumPy 2.2.6 の組み合わせでは、実行検証を行っていません。コードの比較条件は固定していますが、実行環境を含めた再現確認では実際に使用したバージョンも記録します。
3 ケースの差を整理します。
| 比較項目 | 元モデルと順位逆転 | 元モデルと順位維持 |
|---|---|---|
| 参照テーブルのバイト列 | 一致 | 一致 |
| 候補スコア | 不一致 | 不一致 |
argmax の選択結果 |
A → B | A → A |
assert は、参照値の一致、候補スコアの差、選択されたトークンを独立して検証します。順位逆転と順位維持の両ケースで、参照テーブルのバイト列は同一です。選択結果を分ける条件は、変更後の候補 A と B のスコアの大小関係です。
縮約モデルの結果を実モデルへ適用する条件
今回の重み行列は、順位逆転と順位維持を確認するために直接設定した値です。量子化アルゴリズムから生成した重みではありません。また、float64 の参照テーブルを使用しているため、原典で扱う MXFP8 形式の Engram と同じ保存形式を検証した結果でもありません。
実際の量子化モデルで同様の比較を行う場合、確認対象を次のように分離します。
| 検証対象 | 比較方法 | 直接確認できる範囲 |
|---|---|---|
| Engram の保存値 | 対応する重みの型・形状・バイト列を比較 | 比較対象に含めた保存値の同一性 |
| モデルの推論処理 | 固定した入力・実行環境で生成を実行 | 指定条件で生成処理が成立すること |
| 候補スコア・出力 | 同一入力・選択条件で元モデルと変更後を比較 | 対象入力でのスコア差と出力差 |
| 回答品質 | 課題と採点基準を揃え、両モデルの正答率や成功率を測定 | 評価した課題・入力分布での性能差 |
本例では argmax を使い、乱数によるトークン選択を排除しています。確率的に出力を選択する実装では、乱数条件も比較対象になります。参照位置の決定規則、ゲート機構、後続の演算、モデル固有の量子化形式についても、実モデルでの評価時には確認が必要です。
参照テーブルのバイト一致が成立しても、Backbone の変更によって最終的な候補スコアが変化する可能性があります。一方、スコアが変化しても選択結果が一致する条件もあります。回答品質の維持は、正解のある課題や採点基準を用いて別途評価する性質です。この区別は、Engram の保存値とモデル全体の能力を評価する際の判断基準になります[3]。
参考文献
- Xin Cheng et al., Conditional Memory via Scalable Lookup: A New Axis of Sparsity for Large Language Models(2026-01-12). https://arxiv.org/abs/2601.07372
- NumPy Developers, numpy.ndarray.tobytes. https://numpy.org/doc/2.2/reference/generated/numpy.ndarray.tobytes.html
- id774, Engram のバイト一致だけでは回答品質を証明できない(2026-11-02). https://blog.id774.net/entry/2026/11/02/5828/