「おまかせで整える」でデスクトップアプリが 11 GB 使ったのはなぜか 2026-11-05 測定 · v0.120
確かめたこと。 約 2,300 ページのナレッジで おまかせで整える を走らせると、デスクトップアプリの本体プロセスが数分で 11〜12 GB に膨らみ(起きた Mac からの報告値)、Mac 全体がスワップに入りました。メモリを抱えていたのは Web ビューでも AI サーバーでもなく、ネイティブの本体です。何が持っていて、どう止めるか。
ひとことで。 端末内の埋め込みエンジンでした。fastembed 7.5 が同梱する ONNX Runtime(1.31)では、32 節のページ 1 枚を埋め込むだけでこの Mac の本体が 39 GB を超え、終わりませんでした。ONNX Runtime 1.23 を同梱する fastembed 5.13 では、同じ呼び出しが 6.5 秒で終わり、大きな確保のピークは 1.4 GB(600 MB のモデルを載せた状態でプロセス全体は約 2.4 GB)。直しは依存の固定と、1 回に渡す文の数を減らすこと。あなたの側の設定は何も変わりません。
測り方
| 機材 | M1 Max(10 コア・64 GB)、macOS 26 |
| ビルド | デスクトップアプリの debug ビルドに、アプリが呼ぶのと同じネイティブ命令を Web ビューからループで呼ぶ計測コードを足したもの。データは隔離したフォルダで、実データには触れていません |
| 負荷 | 埋め込み: 約 3,000 字の文 × 32(各 512 トークンで切られる。長い 32 節のページ 1 枚の改訂が送るものと同じ)、その 1 文だけ、300 字の短文 × 100。モデルは既定の bge-m3 と multilingual-e5-small。ファイル読み: 最初に疑ったネイティブ命令で 10 MB のファイルを 180 回——13 MB の base64 文字列として 120 回、生のまま 60 回 |
| 記録 | プロセスの常駐メモリと footprint の MALLOC_LARGE 行を 3 秒ごと。常駐 5〜8 GB を超えたら自動で止める見張り付き(見張りなしの最初の 1 回でスワップを 25 GB 使ったため) |
| 版 | fastembed 7.5 は ort 2.0.0-rc.15(ONNX Runtime 1.31.0)に、fastembed 5.13.0 は ort 2.0.0-rc.11(1.23.2)に解決される。いずれも Cargo.lock で確認、1.23.2 の文字列はビルドしたバイナリにもある。fastembed 5.8.0(1.22.0)の 3 つ目のビルドは 1.23 と同じ挙動 |
結果
違ったもの。 ネイティブの橋を渡るファイル読みは横ばいでした。180 回で、本体は 170〜260 MB のまま。
原因だったもの。 埋め込みエンジンと、それが同梱するランタイム。
| 負荷 | ONNX Runtime 1.31(fastembed 7.5、前) | ONNX Runtime 1.23(fastembed 5.13、後) |
|---|---|---|
| bge-m3・32 節 × 512 トークン・1 回 | 40 秒たっても終わらない。大きな確保が 39 GB でまだ増えている(442 ブロック) | 6.5 秒。大きな確保のピークは 1 回 32 文で 3.2 GB、1 回 8 文で 1.4 GB |
| bge-m3・1 節だけ | 3 秒で常駐 5 GB、見張りが停止(arena 無効) | 1.23 では測り直していない(1.22 で 0.7〜1.0 秒) |
| e5-small・短文 100・1 回 8 文 | 6 秒で大きな確保が 4.3 GB、停止(arena 無効) | 2.7 秒・395 MB |
39 GB の行はランタイム既定のメモリ arena のまま。1.31 の残り 2 行は下の knob の試験からで、arena を切ったビルドで始めています。
1.31 で絵が変わらなかったこと(arena を切った実行の上にそれぞれ重ねました): 推論スレッドを 1 本にする、KleidiAI カーネルを切る(この Mac には SME がないので、もともと使われていなかった可能性が高い)、重みの事前パックを切る、memory pattern を切る。推論中のスタックを採ると、確保は ONNX Runtime 自身のノードごとの割り当て計画から来ていて、ふつうの中間テンソルです。推論の中で再利用されない理由は外からは見えませんでした。全部の層の中間テンソルの合計がピークになる、と考えると数字が合います。
1.23 でのバッチ: 1 回 32 文と 1 回 8 文は、32 節で同じ 6.5 秒。8 文はピークが 3.2 GB → 1.4 GB。アプリは 8 にしました。
分かったこと
- 2 つのビルドで変わったのは同梱のランタイムです。 モデルファイル・トークナイザの設定・呼び出しは
fastembed5.13 と 7.5 で同じ。もっとも近い上流の報告 microsoft/onnxruntime#29538 は Apple Silicon で 1.24 以降に同じ形の保持が起きると述べていて、matmul 側の直しがないまま stale として閉じられています。この計測自体が比べたのは 1.22・1.23・1.31 だけ。Graphium はfastembedを 5.13.0 に固定し、動かす前に繰り返す計測の手順をリポジトリに残しました。 - ピークは推論のあとも残ります。 各実行のあと 8 秒の計測では常駐メモリは下がりませんでした。ONNX Runtime の arena は自分では縮まず、アプリは最後に使ってから 10 分でモデルを降ろすので、それまで約 2.4 GB が見える見込みです(10 分はアプリの決まりで、ここで測ったものではありません)。
- 小さいバッチはただです。 速さは同じで、ピークは半分以下。
限界
- 機材 1 台・macOS 1 版・条件ごとに 1 回。上流の報告は Apple Silicon についてで、Windows はここでは測っていません。
- 負荷に使った文は 512 トークンの打ち切りに当てるための人工的なもの(語彙の繰り返し)。実際のページはまちまちなので、表は 32 節のページの最悪値で、平均ではありません。
- 整える最中に Web ビュー側が PDF の原文を読み直して使うメモリ(同じナレッジで 2〜4 GB)は別の話で、今回は変えていません。
