AI・機械学習
Kimi K3をRAM 29 GBで0.50トークン/秒で実行する
Run Kimi K3 using 29 GB of RAM at 0.50 tok/s (github.com)
要約
この記事は、WASTE(Weight-Aware Streaming Tensor Engine)という、大規模言語モデル(LLM)を限られたリソースで実行するための新しい推論エンジンを紹介しています。特に、2.78兆パラメータを持つKimi K3モデルを、64 GB RAMのコンシューマーラップトップで、ディスクからストリーミングしながら実行することに成功しました。この技術は、モデル全体をメモリにロードする必要がなく、必要な部分だけをディスクから読み込むことで、低速なストレージと限られたRAMを効率的に活用します。これにより、ネットワーク接続や高価なハードウェアなしで、大規模モデルをローカルで実行する可能性が開かれます。
全文翻訳
WASTE — Weight-Aware Streaming Tensor Engine
Kimi K3 — 2.78兆パラメータ — コンシューマーラップトップで実行中。
$ waste run ~/models/k3.waste 'What is the capital of Italy?'
waste: no --budget, using 46.24 GB of 64.00 GB (expert cache 17.56 GB)
The capital of Italy is **Rome**.
[16 tokens, 31.09 s, 0.51 tok/s | experts 3357 hit / 20195 miss = 14%]
WASTEは、Cで書かれた埋め込み可能な推論エンジンで、サードパーティのランタイム依存関係はありません。モデルのトランクをメモリに保持し、選択されたエキスパートをディスクから直接ストリーミングし、残りのRAMをバウンドされたエキスパートキャッシュとして使用します。現在の証明点は、完全にオープンウェイトのKimi K3モデルです。2.78兆パラメータを982 GiBのコンテナに変換し、64 GBのMacBook Proで毎秒0.49〜0.54トークンの速度で実行します。これは、蒸留、プルーニング、または削減されたバリアントではありません。
モデルコンテナ | 最小RAM | テスト済み速度
Kimi K3 2.78T | 982 GiB | 29.05 GiB | 0.49–0.54 tok/s
Kimi-Linear 48B | 19 GiB | 1.87 GiB | 10.7 tok/s
WASTEは、その1つのモデルと1つの制約のために書かれました。K3は、現在の主流のコンシューマーシステムのRAMには収まりません。公開されている状態では1.42 TB、変換後は982 GBです。しかし、混合エキスパートはトークンごとに約4%をアクティブにするため、ほとんどすべての重みが瞬時にアイドル状態になります。アイドル状態の重みはメモリにある必要はなく、時間内に到達可能である必要があります。WASTEはそれをディスク上に、1つのエキスパートがちょうど1回の読み取りを必要とするレイアウトで保持し、各トークンが必要とするものをストリーミングし、残りのRAMバイトをすべて繰り返される部分に使用します。
現状
エンジンは正確です。各レイヤーはPyTorchリファレンスに対して検証されており、最終的なロジットは3.6e-06まで一致し、ビジョンタワーは独自のオラクルに2.3e-06まで一致します。また、遅いです。毎秒半トークン、上記の文で30秒かかります。その両方が重要であり、後者は免責事項として読むべきではありません。これほど大きなモデルをコンシューマーマシンでディスクからストリーミングする公開デモンストレーションは他にありません。兆単位のNVMeストリーミングの例は見つかりませんでした。最もよく文書化された671Bクラスのレシピでさえ、1テラバイトのDDR5を備えたサーバーを想定しています。これは、検索で見つかったものの報告であり、調査ではありません。このリポジトリには参考文献も比較表もありませんので、反例を送るための招待として読んでください。結果としてではありません。興味深いのは速度ではなく、すべてが単一のコンシューマーマシンで到達可能な範囲にあることです。そして、ここから問題は実現可能性ではなくエンジニアリングであるということです。レバーがあった場所は、現在ある場所ではありません。エキスパートの読み取りと算術演算のオーバーラップは〜1.6倍の価値があり、出荷されました。より大きく見えた2つのもの—トークンあたりのバイト数を少なく読み取ること、およびそれらのより多くをRAMに保持すること—は両方とも測定され、両方とも拒否されました。1つは、このファミリーのルーターに降格するテールがないため、もう1つは、マシンが常駐させないキャッシュはどんな価格でも購入できないためです。読み取りがオーバーラップしても、デコードステップの55%に対して算術演算の27%を占めるため、残りはより高速なディスクまたはより多くのRAMを備えたマシンであり、カーネルの再実行ではありません。docs/EFFICIENCY.mdは、測定される前に構築された2つを含む、それぞれがどのように価格設定されたかの説明です。具体的に何が開かれるか:ネットワークなし、トークンごとの請求なし、マシンから何も送信しないフロンティアスケールモデル。これは、「そのデータをAPIに送信することはできません」と「ここで実行する」の違いです。フォーマットとエンジンは、K3に深く固有のものではありません。K3は今日存在する最も難しいケースにすぎず、2.78Tでストリーミングするモデルは48Bでも快適にストリーミングします。このドキュメントのすべての数値は、公開されたコミットで測定されており、間違っていたものはdocs/LEARNED.mdに誤りとして記録されており、静かに修正されていません。
なぜこの名前なのか
クラウドサービスで回答される各トークンは2回支払われます。1回は請求書で、もう1回は、デスクにすでに置かれているハードウェアに—かろうじて、ぎこちなく、しかし本質的に—収まるモデルを実行するデータセンターの電力でです。WASTEは、トークンの無駄を終わらせるための最初の具体的なステップとなることを意味します。頭字語は後から来ました。
必要なもの
ディスク、モデル用
982 GBの変換済みコンテナ—1テラバイトのディスクを計画してください。
変換するには、さらに1.42 TBのステージングが必要です(公開されたシャード用、後で解放されます)。
RAM
K3を4Kコンテキストで開くには29.05 GiBの最小値。ここで示されている数値は64 GiBです。
ストレージ速度
コンテナは内部NVMe上にある必要があります—以下を参照してください。
ビルド
C11コンパイラとmake。
実行時にはBLAS、CUDA、Pythonは不要です。
ここでのサイズは2の累乗です。dfとエンジンが報告する方法です。コンテナは982 GiBで、ディスクベンダーは1.05 TBと呼びます。RAMフロアはエンジンが起動を拒否する下限であり、ほぼ完全に27.28 GBの常駐トランクです。有用なスループットはそれ以上で始まります。64 GBのマシンでは、エンジンは46 GBの予算を自身に与えます。そのうち17.56 GBはエキスパートキャッシュであり、それが測定曲線の頂点です。32 GBのマシンは技術的にはモデルを開くことができますが、ひどくページングします。64 GBを実際の要件として扱ってください。
ストレージ速度は詳細ではありません。1つのトークンは17 GBのエキスパートを読み取ります。内部SSDでは12.78 GB/秒でモデルがストリーミングされます。USBエンクロージャー経由では0.94 GB/秒で、同じトークンは13秒かかります。内部NVMeに変換し、ダウンロードのみに外部ディスクを使用してください。
テラバイトが利用できない場合、同じエンジンとフォーマットで、19 GBのコンテナと1.87 GBのフロアからKimi-Linear-48B-A3B-Instructを実行し、10.7 tok/sで動作します。これは、K3にディスクを割り当てる前にWASTEを試すための良いパスです。
これは何ですか
自己完結型です。1つのlibwaste.a、1つのwasteバイナリ、実行時にはlibcとpthreads以外の何もありません。依存関係ゼロ。実行パスにBLAS、ONNX、Pythonはなく、インストールするものもありません。tools/下のPythonはモデルを変換し、エンジンを検証します。それは決して並行して実行されません。
完全に埋め込み可能。src/waste.hに26の公開関数があります。RAM上限下でモデルを開き、生成し、セッションを保存し、閉じます。CLIはそのAPIのクライアントであり、プライベートなものには一切触れません。CLIができることなら、埋め込みホストもできます。
waste_cfg cfg;
waste_cfg_init(&cfg);
cfg.ram_budget_bytes = 46ULL << 30; /* ハードシーリングであり、ヒントではありません。0はマシンに合わせてサイズ設定します */
waste_ctx *ctx;
if (waste_open("/path/to/k3.waste", &cfg, &ctx) != WASTE_OK) return 1;
waste_generate(ctx, ids, n, ¶ms, on_token, user);
waste_close(ctx);
パスはコンバーターが書き込んだコンテナディレクトリです。シェルが担当する〜展開はありません。
仕組み
配置が速度を決定します。
モデルは一度.wasteコンテナに変換されます。JSONマニフェスト、常駐トランク、レイヤーごとに1つのエキスパートバンクです。各エキスパートレコードは4 KiBアラインメントで、ゲート、アップ、ダウンマトリックスが隣接しているため、エキスパートへのルーティングは正確に1回のpreadで済みます。3回ではなく、マトリックスごとにシークするわけではありません。算術演算が決してボトルネックになることはありませんでした。
読み取りはページキャッシュをバイパスします(macOSではF_NOCACHE、LinuxではO_DIRECT、WindowsではFILE_FLAG_NO_BUFFERING)。これは意図的です。コンテナがRAMより小さい場合、カーネルはすべてをキャッシュしますが、その方法で測定されたヒット率はフィクションであり、982 GBモデルとの接触では生き残りません。
各レコードのヘッダーは、入力時にチェックされます—正しいマジック、要求されたエキスパート、適合するオフセット—そのため、切り捨てられたりスプライスされたりしたバンクは、生成を停止し、間違ったバイトから回答するのではなく、レコードの名前を付けます。これは測定可能なコストはかかりません。レコードにはペイロードのCRC32も含まれており、それをチェックするのは--verify(デフォルトでオフ)です。これは、キャッシュミスごとに各レコードを通過します。Kimi-Linearでは約5%、K3では1%です。コピーまたはダウンロードしたコンテナで、まだ読んでいないものには価値がありますが、自分で変換したコンテナの各トークンには価値がありません。docs/FORMAT.mdを参照してください。
エキスパートウェイトあたり3ビット
エキスパートは残差ベクトル量子化として格納されます—8次元ベクトルに対する256エントリのコードブックの3段階、ウェイトあたり3.00ビット—そしてマトリックスは決して