0
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?

Engram のバイト一致が成立してもトークン選択が変わる条件を Python で検証する

0
Posted at

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 として保存します。

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]。

参考文献

  1. 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
  2. NumPy Developers, numpy.ndarray.tobytes. https://numpy.org/doc/2.2/reference/generated/numpy.ndarray.tobytes.html
  3. id774, Engram のバイト一致だけでは回答品質を証明できない(2026-11-02). https://blog.id774.net/entry/2026/11/02/5828/
0
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
0
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?