コンテンツにスキップ

対応プラットフォーム

どれも必須ではありません。tensai は Go が動く場所ならどこでも、ポータブル カーネルと GPU なしで動きます。この表は、各プラットフォームがその上に何を 足せるか、そして何がまだ足りないかを示します。

OS 別

CPU カーネルは OS に一切依存しません。決めるのはアーキテクチャと Go の バージョンで、それは次の表です。OS が決めるのは GPU バックエンドと、 重みキャッシュの読み方です。

OS GPU 重みキャッシュ マップの解放
Linux Vulkan、dlopen メモリマップ madvise(MADV_DONTNEED)
macOS Metal、dlopen メモリマップ madvise (生のシステムコール)
Windows D3D12 または Vulkan、LoadLibrary メモリマップ (file mapping 経由) 無し。アンマップまで保持
その他 (BSD, illumos, ...) ビルドされない ReadAt で読み込み 無し

リリースバイナリは linux / macOS / Windows の amd64 と arm64 を配布しています。 それ以外でも go build は通り、tensai は動きます。失うのはマップ (ロードが キャッシュファイルの読み込みになり、時間とメモリを食いますが動作は同じ) と GPU タグです。

CPU カーネル

ベクトルカーネルは Go で書かれており (実験的な simd/archsimd パッケージ)、 ビルド時の GOEXPERIMENT=simd で有効になります。付けない場合、または下の表に 無い組み合わせでは、ポータブル実装が使われます。結果は同一で、速度は一桁落ちます。

AVX2 と NEON (ARM の Advanced SIMD) は命令セット拡張なので、どちらになるかは アーキテクチャと Go のバージョンだけで決まります。OS は関与しません。arm64 なら Linux でも macOS でも Windows でも同じ NEON カーネルが使われます。

アーキテクチャ Go カーネル 備考
amd64 1.26, 1.27 AVX2 実行時に判定。AVX2 と FMA が無い CPU はフォールバック
arm64 1.27 NEON AArch64 では必須のため判定不要。Go 1.26 の simd/archsimd に arm64 が無いため 1.26 はフォールバック
その他 すべて ポータブル

「ビルドがどれを選ぶか」と「実際に動かして確かめたか」は別の話なので、分けて示します。

プラットフォーム 選ばれるカーネル 検証
linux/amd64 AVX2 済。開発と計測はここで行っています
linux/arm64 NEON 済。エミュレータ上でテストと生成を確認
darwin/arm64 NEON CI の Apple Silicon でテスト済。計測は未
windows/amd64 AVX2 済
windows/arm64 NEON 未

エミュレータでの確認と CI の Apple Silicon ジョブは、arm64 の計算結果を信頼する 根拠にはなりますが、速度の根拠にはなりません。全パッケージのテストが通り、量子化 matvec のチェックサムがポータブル実装とも AVX2 とも一致し、0.5B が amd64 と同じ テキストを生成します。しかし実機でどれだけ速いかは、実機で計測しないと分かりません。

AVX2 ビルドがベクトル化しているカーネルには、すべて NEON 版があります (128 ビット、float 4 レーンまたは 16 バイトで、AVX2 の半分の幅)。

カーネル amd64 arm64
int8 matvec (-q8、requant 済みの重み) AVX2 NEON
grouped int8 matvec (gguf ブロックの直接リパック) AVX2 NEON
4bit matvec (-q4) AVX2 NEON
三値 matvec (PTQ1_0) AVX2 NEON
MXFP4 (gpt-oss) AVX2 NEON
プレフィルのバッチ畳み込み AVX2 NEON
活性化の量子化 AVX2 NEON
attention の内積・値累算・softmax の exp AVX2 NEON
要素ごとの演算 (加算、スケール、SwiGLU と GELU のゲート) AVX2 NEON
Hadamard 回転、delta rule の読み出し AVX2 NEON
密行列積 (学習) AVX2 NEON
学習側カーネル (活性化、LayerNorm、Adam、SGD) AVX2 NEON

NEON には符号なし×符号つきのバイト積和 (VPMADDUBSW) が無いので、整数 カーネルは符号つきの拡張乗算とペア加算で 16 ビットに手で広げます。グループの スケールは fused multiply-add で畳み込みます。arm64 のコンパイラはポータブル 実装でも同じ融合をするので、ベクトル列とスカラ列の結果がビット単位で一致します。

tensai bench はどの系統で走ったかを最初の行に出力するので、意図せず フォールバックしているビルドはすぐ分かります。

GPU

GPU バックエンドはビルドタグ 1 つで有効になり、実行時に wgpu-native を読み込みます。cgo も GPU SDK のインストールも不要です。ライブラリのバージョンと参照先の環境変数は GPU (WebGPU) を参照してください。

OS ローダ wgpu-native が選ぶバックエンド
Linux dlopen Vulkan
macOS dlopen Metal
Windows LoadLibrary D3D12 または Vulkan
その他 なし ビルドは通り、GPU は利用不可と報告

3 つの OS すべてで amd64 と arm64 をクロスビルドしています。2 つのタグは バインディング世代の選択で、-tags wgpu24 が v29 C API、-tags wgpu が v22.1.0.5 です。WSL2 内では dozen 経由で実 GPU に届くのは v29 の方で、素の wgpu ビルドはソフトウェアラスタライザに落ちます。

プラットフォームではなくモデル側の制限が 1 つあります。value を key から取る層を 持つ Gemma 4 のチェックポイントは、デバイス側カーネルがその形に未対応のため、 どのプラットフォームでもデコードが CPU で走ります。実行時にその旨を表示して 続行します。

どれも変えないもの

モデルの取得・リパック・キャッシュの手順はどこでも同じで、出てくる数値も同じです。 ベクトルカーネルはポータブル実装と一致するように書かれており、量子化 matvec は AVX2 でも NEON でもどちらでもない場合でもビット一致します。プラットフォームは tensai を遅くすることはありますが、違う答えを出させることはありません。