Arm CPU の INT8 TOPS 値も計測してみる

前回の x64 VNNI 命令の TOPS 計測に続いて ARM CPU の TOPS 値も求めてみました。vfpbench による実測です。

結果

SoCarchCore数命令INT8 tops
Snapdragon 8s Gen 4v8.2A X4 A720 A720 A7201+2+3+2I8MM4.200 TOPS
Tensor G5 (Pixel 10 Pro)v9.2A X4 A725 A5201+5+2I8MM3.173 TOPS
Snapragon 7+ Gen 3v8.2A X4 A720 A5201+4+3I8MM2.400 TOPS
Tensor G4 (Pixel 9a)V9.2A X4 A720 A5201+3+4I8MM2.202 TOPS
Snapdragon 6 Gen 1V8.2A A78 A554+4 DotProd0.789 TOPS

INT8 TOPS で最も演算能力が高かったのは Snapdragon 8s Gen4 で、CPU だけでも 4.2 TOPS 出ています。同じ 8 core でも Snapdragon 8s Gen4 はすべて big Core なので、その分演算能力が高くなっています。

前回の x64 CPU の結果と比べると以下のとおり。SIMD 幅が 128bt の Mobile Arm CPU でも INT8 演算能力は Desktop CPU と比べて遜色ないレベルに見えます。これは Arm CPU が VNNI のような内積命令だけでなく、Matrix の乗算命令 I8MM を持っているためです。

CPUArchCore数命令INT8 TOPS
Ryzen AI Max+ 395Zen516C 32TAVX512-VNNI20.482 TOPS
Ryzen 7 9700XZen58C 16TAVX512-VNNI10.699 TOPS
Core i7-13700RaptorCove16C 24TAVX-VNNI5.456 TOPS
Ryzen 7 7840HSZen48C 16TAVX512-VNNI4.713 TOPS
Snapdragon 8s Gen 4X4 A7208C 8TI8MM4.200 TOPS⭐️
Ryzen 7 5700XZen38C 16TAVX23.547 TOPS
Ryzen 9 3950XZen216C 32TAVX23.178 TOPS
Tensor G5 (Pixel 10 Pro)X4 A725 A5208C 8TI8MM3.173 TOPS⭐️
Snapdragon 7+ Gen 3X4 A720 A5208C 8TI8MM2.400 TOPS⭐️
Tensor G4 (Pixel 9a)X4 A720 A5208C 8TI8MM2.202 TOPS⭐️
Ryzen 7 4750GZen28C 16TAVX21.629 TOPS
Snapragon 6 Gen 1A78 A558C 8TDotProd0.789 TOPS⭐️
Intel N97Gracemont4C 4TAVX-VNNI0.366 TOPS

I8MM 命令

x64 の VNNI に相当する命令は Arm にも搭載されており DotProd (udot/sdot) です。DotProd は 32bit 単位で 4要素同士の内積を行います。128bit で 32 iops になります。

I8MM 命令 (smmla/ummla/usmmla) は 2×8と 8×2 のマトリクス乗算が可能で、それぞれ各 8bit 値が 2回ずつ利用されます。64bit 単位、8要素の内積を 4組実行します。128bit で 32個の積和演算が可能で、命令あたりの演算回数は 64 iops となります。レジスタへの再転送なしに DotProd と比較して 2倍の演算ができるわけです。

また結果を見ると Cortex-X4 の場合 DotProd/I8MM は同時に 4命令実行可能であることがわかります。以下は Google Tensor G5 (Pixel 10 Pro) の Cortex-X4 の結果からの抜粋です。

Cortex-X4                             TIME(s)   MFLOPS      MOPS     IOP   IPC
NEON smmla.4s  (int8 x16) n12     :    0.272   799709.3    12495.5  ( 64.0 3.3)
NEON ummla.4s  (int8 x16) n12     :    0.227   959218.0    14987.8  ( 64.0 4.0) ⭐️
NEON usmmla.4s (int8 x16) n12     :    0.225   966448.1    15100.8  ( 64.0 4.0) ⭐️
NEON sdot.4s   (int8 x16) n12     :    0.225   483251.9    15101.6  ( 32.0 4.0)
NEON udot.4s   (int8 x16) n12     :    0.225   483342.0    15104.4  ( 32.0 4.0)

よって CPU Core あたり最大 256 iops となり、これは AMD Ryzen Zen5 の AVX512-VNNI に匹敵します。

ただしこれだけ強力なのは Prime Core の X4 だけで、Mobile SoC の場合は大抵 1~2 core しか搭載されていません。Cortex-A725/A720 の場合は半分の同時 2命令、LITTEL Core (E-Core) の Cortex-A520 の場合は 2 Pipe が 2 CPU で共有されているため実質 1 命令です。

下の表は CPU Core 毎の INT8 演算能力の比較です。

CPU Core対応命令bit幅clockあたりCORE あたりの演算数
Cortex-X4I8NN128bitx4256 iops
Cortex-A725/A720I8NN128bitx2128 iops
Cortex-A520I8NN128bitx1 (実質)64 iops
Zen5AVX512-VNNI512bitx 2256 iops
Zen4AVX512-VNNI512bitx 1128 iops
RaptorLake (RaptorCove) P-CoreAVX-VNNI256bitx 2128 iops
AlderLake-N (Gracemont) E-CoreAVX-VNNI256bitx 0.532 iops

BF16 命令

TOPS とは直接関係ないのですが、AI 向けの演算命令として bfloat16 命令があります。bfloat16 は 16bit の浮動小数点フォーマットの一種で、一般的な fp16 の s10e5 ではなく s7e8 になります。仮数部の精度は 8bit しかありませんが、その代わり指数部のレンジも 8bit あり fp32 と同等です。

Arm CPU には I8MM 同様 bfloat16 にも 2×4 と 4×2 のマトリクス乗算命令 bfmmla があります。結果は fp32 です。fp16 には同等の命令がないので、16bit のピーク FLOPS 値は fp16 よりも bfloat16 の方が高くなっています。

単純に考えると bit 数が倍なので 8bit I8MM の半分のレートになるように見えますが、結果を見ると 8bit int の 1/4 となっています。以下は Tensor G5 の Cortex-X4 の結果の抜粋です。INT8 が 966 TOPS なのに対して BF16 はおよそ 1/4 の 230~250 FLOPS となっています。

Cortex-X4
Group 2:  Thread=1  Clock=3.782000 GHz  (mask:80)
  SingleThread HP   max:   181.306 GFLOPS     INT8  3/16
  SingleThread SP   max:    90.649 GFLOPS     INT8  3/32
  SingleThread DP   max:    45.310 GFLOPS     INT8  3/64
  SingleThread BF16 max:   253.620 GFLOPS     INT8  1/4
  SingleThread INT8 max:   966.281 GOPS       INT8
  MultiThread  HP   max:   138.243 GFLOPS
  MultiThread  SP   max:    67.191 GFLOPS
  MultiThread  DP   max:    45.303 GFLOPS
  MultiThread  BF16 max:   229.727 GFLOPS
  MultiThread  INT8 max:   966.448 GOPS

Cortex-X4 の bfmmla 命令は I8MM の smmla/ummla/usmmla とは異なり同時に 2命令しか実行できないことが原因です。以下は Cortex-X4 の bfmmla 命令の抜粋です。

Cortex-X4                             TIME(s)   MFLOPS      MOPS     FOP   IPC
NEON bfmmla.4s (bf16 x8) n12      :    0.429   253620.4     7925.6  ( 32.0 2.1) ⭐️
NEON bfdot.2s (bf16 x4) n12       :    0.451    60410.1     7551.3  (  8.0 2.0)
NEON bfdot.4s (bf16 x8) n12       :    0.368   148077.4     9254.8  ( 16.0 2.4)

ちなみに fp16 命令 (HP) は 181 GFLOPS と INT8 の 3/16 になっています。Cortex-X4 の浮動小数点積和命令は 3命令同時に実行できるため、4命令実行可能な I8MM と比べて (3/4) ✕ (16 iop / 64 iop) = 3/16 となります。

Cortex-A725/A720 の場合は INT8 も BF16 も同じ 2命令なので、BF16 はちょうど 1/2 となっています。また浮動小数点積和も 2命令で同じなので、fp16 (HP) もぴったり 1/4 です。

Cortex-A725
Group 1:  Thread=5  Clock=3.052000 GHz  (mask:7c)
  SingleThread HP   max:    97.521 GFLOPS
  SingleThread SP   max:    48.758 GFLOPS
  SingleThread DP   max:    24.377 GFLOPS
  SingleThread BF16 max:   194.937 GFLOPS
  SingleThread INT8 max:   390.017 GOPS
  MultiThread  HP   max:   487.591 GFLOPS     INT8  1/4
  MultiThread  SP   max:   243.788 GFLOPS     INT8  1/8
  MultiThread  DP   max:   121.888 GFLOPS     INT8  1/16
  MultiThread  BF16 max:   917.726 GFLOPS     INT8  1/2
  MultiThread  INT8 max:  1950.065 GOPS       INT8

Cortex-A520 の場合は bfmmla は一つの ALU を複数コアで共有しており、シングルスレッド時に 1命令、マルチスレッドでは 0.5 に半減します。実測値を見ると理論値よりも値が小さくなっていますが、おそらくレイテンシが大きいためだと思われます。

Cortex-A520                           TIME(s)   MFLOPS      MOPS     FOP   IPC
NEON bfmmla.4s (bf16 x8) n12      :    1.264    51177.2     1599.3  ( 32.0 0.7)
NEON bfdot.2s (bf16 x4) n12       :    0.929    17408.1     2176.0  (  8.0 1.0)
NEON bfdot.4s (bf16 x8) n12       :    0.927    34897.8     2181.1  ( 16.0 1.0)

Aarm A520 のマニュアルによると Exec Latency は 14~15 cycle となっており、また bfloat16 の演算は VMAC と VALU を両方占有する特殊な命令であることもわかります。

まとめ

Arm CPU も AI 向けの演算命令が強化されており、高い演算能力を持っていることがわかります。今後 SME/SME2 によってさらにマトリクス演算命令は強化されていくようです。Apple M4 以降や C1 ではすでにこれらの命令が搭載されているため、さらに高いスループットが得られるものと思われます。

計測データのリンク

関連ページ

vfpbench のカテゴリ一覧

VNNI 命令を使って AI Max+ 395 と他の CPU の INT8 TOPS 値を計測してみる

AI 向け演算能力である TOPS 値は GPU や NPU のスペックとして用いられますが CPU ではあまりデータが載っていません。vfpbench に int8 と bf16 命令の計測機能を追加したので、実際の CPU でもこれらの値を調べてみました。(TOPS 値が大きい方が高速)

CPUArchCore数命令INT8 TOPS
Ryzen AI Max+ 395Zen516C 32TAVX512-VNNI20.482 TOPS
Ryzen 7 9700XZen58C 16TAVX512-VNNI10.699 TOPS
Core i7-13700RaptorCove16C 24TAVX-VNNI5.456 TOPS
Ryzen 7 7840HSZen48C 16TAVX512-VNNI4.713 TOPS
Ryzen 7 5700XZen38C 16TAVX23.547 TOPS
Ryzen 9 3950XZen216C 32TAVX23.178 TOPS
Ryzen 7 4750GZen28C 16TAVX21.629 TOPS
Intel N97Gracemont4C 4TAVX-VNNI0.366 TOPS

Ryzen AI Max+ 395 (EVO-X2) は CPU だけで 20 TOPS となりました。かなり速く、同じ 16コアの 3950X と比べても 6.4 倍です。もちろんこれはメモリ速度やデータ転送を一切考慮しないピーク値となります。実際のアプリケーションでこの速度が出るわけではありませんので予めご了承ください。また計測は短時間で完了するのでブースト時の結果となります。

Zen5 で特に高い値が出ているのは AVX512-VNNI の vpdpb 命令を同時に 2命令実行できるためです。同じく VNNI 対応の Zen4 や Raptor Lake と比べてもクロックあたり 2倍です。

CPU Core対応命令bit幅clockあたりCORE あたりの演算数
Zen5AVX512-VNNI512bitx 2256 iop
Zen4AVX512-VNNI512bitx 1128 iop
RaptorLake (RaptorCove)AVX-VNNI256bitx 2128 iop
AlderLake-N (Gracemont)AVX-VNNI256bitx 0.532 iop

AlderLake-N (Gracemont) はいわゆる AlderLake / RapterLake (Inel Core 12000/13000) の E-Core です。N97 を使っていますが CPU の仕様はほぼ N100 と同じです。通常の AVX 命令は 128bit x2 もしくは 256bit x1 なのですが、VNNI 命令はさらに半分のレートとなっているようです。おそらく int8 VNNI 命令を実行できる Pipe が 128bit 1本しかないためと思われます。

VNNI 非対応の Zen2/Zen3 は代わりに AVX2 の vpmaddsbsw を使用しています。3950X は Core 数が 2倍なのに Zen3 の 5700X より速度が出ていません。どうやら Zen2 では vpmaddsbsw は同時に 1命令しか実行できないようです。Zen3 では 2命令走るので、ちょうど Core 数の差を補っている形になります。なお fp32 の fma は Zen2 でも 2命令実行できるため、fp32 の FLOPS 値では Core 数が多い 3950X が逆転します。

Ryzen AI Max+ 395 の公称値との比較

Ryzen AI Max+ 395 の公称値は CPU, GPU, NPU を全部合わせて 126 TOPS となっています。

NPU 単体は 50 TOPS ですが、GPU や CPU の値は上記 AMD の仕様ページでも特に記載されていませんでした。ですがスペック表をよく見ると、各グレードの Core 数の差から CPU の TOPS 値がわかります。

メーカーのページから AI Max+ のスペックを抜き出してまとめると以下の通りです。

CPUCPU コア数GPU CU数GPU ClockNPUOverall
AMD Ryzen AI Max+ 3951640 CU2.9 GHz50 TOPS126 TOPS
AMD Ryzen AI Max+ 3921240 CU2.9 GHz50 TOPS122 TOPS
AMD Ryzen AI Max+ 388840 CU2.9 GHz50 TOPS118 TOPS

AI Max+ 395 と AI Max+ 388 のコア数差が 8 で、OVERALL の TOPS 値の差もちょうど 8 です。AI Max+ 392 を含めても、それぞれ Core 数の差と TOPS 値の差が同一です。公式スペックでは CPU 1 core あたり 1 TOPS の見積もりになっていることがわかります。Ryzen AI Max+ 395 は 16 core あるため、126 TOPS 中 CPU が 16 TOPS です。

これは CPU が 4.0 GHz で動作している計算になります。今回の計測結果では 20.48 TOPS なので、公式のスペックよりもだいぶ高い値となっています。20.48 TOPS から逆算すると 5.0 GHz なので、公式よりも 1 GHz 高いクロックで vfpbench が走っていたことになります。

おそらく短時間のブーストだったことと、CPU 単体での計測が原因と思われます。公称値は NPU, GPU, CPU の全ユニットの合計なので、すべてのユニットが同時にフル稼働する場合は冷却&電力制限から公式の値の通り 4.0GHz に下がるのではないかと考えられます。

CPU が判明したので GPU の分もわかります。Ryzen AI Max+ の GPU (Radeon 8060S) 単体では以下のように 60 TOPS です。

CPUCPU最大TOPSGPU最大TOPSNPU最大TOPS合計
AMD Ryzen AI Max+ 39516 TOPS60 TOPS50 TOPS126 TOPS
AMD Ryzen AI Max+ 39212 TOPS60 TOPS50 TOPS122 TOPS
AMD Ryzen AI Max+ 3888 TOPS60 TOPS50 TOPS118 TOPS

計算からも求めてみます。AI Max+ 395 の GPU は RDNA 3.5 の Ryzen 8060S ですが、CU の基本仕様は RDNA 3 と同じです。CU あたり 64 sp x Dual Issue なので、単純に計算すると 40CU、 2.9GHz の Ryzen 8060S は fp32 で 29.7 TFLOPS になります

fp32 64(sp) x 2(dual) x 2(fma) x 40(cu) x 2.9GHz = 29696 GFLOPS

fp16 では少々制限がありますが内積の Dual Issue もしくは WMMA 利用時にこの 2倍です。int8 演算は fp32 FMA のような Dual Issue に対応しておらず、また Matrix 専用命令の WMMA でも以下のページによると演算レートは fp16 と変わらないようです。

データ形式CLockあたりのピーク演算能力 (RDNA3)
fp32256 fop / CU
fp16512 fop / CU
bf16512 fop / CU
int8512 iop / CU
int41024 iop / CU

よって int8 では 2.9GHz 時に

512(iop) x 40(cu) x 2.9GHz = 59.392 TOPS

となり、公称値から求めた 60 TOPS とほぼ同じ結果になりました。また int4 ではなく int8 の値が用いられていることもわかります。

fp32 と int8 演算

AI 用途向けに、CPU にも専用の演算命令が追加されるようになってきました。そのため従来の fp32, fp64 等の基本演算と比べて、AI 向け演算の方が急激に能力が上がってきていることが分かります。

世代fp32 (fma)fp32の性能比int8int8の性能比iop/fop
Zen564 fopx 2.0256 iopx 5.34.0
Zen432 fopx 1.0128 iopx 2.74.0
Zen332 fopx 1.096 iopx 2.03.0
Zen232 fopx 1.048 iopx 1.01.5

この傾向は他の CPU でも同じで、ARM では VNNI のような内積だけでなく i8mm といった Matrix の乗算命令も搭載されています。今後も Matrix 命令や fp8 演算対応など、この傾向はさらに強くなっていくものと思われます。

vfpbench では ARM の i8mm にも対応したので、ARM CPU の TOPS 値についても計測しています。こちらは次回以降にまとめてみたいと思います。

実際の計測データ

実際の計測データは以下のリンクから参照できます。

関連ページ

OpenClaw を複数台の PC を使って 122b の Local LLM だけで運用する

複数台の PC を使って OpenClaw を使用しています。OpenClaw は多くのトークンを消費しますので、クラウドの API を使わずに自分の PC だけで運用できないかいろいろ試しています。

現在は以下の図のように 120b クラスのモデルを使用しています。AI 用の特別なマシンではなく、(メモリ増設した) 汎用の PC です。

本来なら LLM 用の PC は 1台だけでも動作できるのですが、複数台に分けているのは理由があります。PC-3 は空いてる PC の VRAM を間借りすることが目的です。PC-2 を用意したのは Sub Agent をバックグラウンドで並列動作させられることと、Main セッションの KV キャッシュとの分離のためです。

もし使える PC 台数に余裕があるなら、だいぶ贅沢ですが Heartbeat 用 PC も分けることができます。

一般向け PC での生成速度

前回説明したように、普通の PC でもメモリさえあれば 100b 以上のモデルも動くようになってきました。生成速度は 10~20 token/s ほどなので、AI 専用のマシンやクラウドの API と比べると非常に低速です。

それでも Slack のようにストリーミング表示してくれるクライアントで使っていると、思ったよりもずっと早くレスポンスが返ってくることがわかります。生成速度が遅くても使えているのは KV キャッシュが再利用できているおかげです。

逆にキャッシュが効かないケースでは一度のやりとりでも 5~10分ほど待たされるので、これが非常に重要であることがわかります。

Sub Agent を別の PC に割り当てる

OpenClaw は大きなコンテキストサイズを必要としますが、コンテキストウィンドウ長を増やすとその分生成速度は落ちていきます。VRAM 16GB でバランスを取るとだいたい 64K くらいがちょうどよいかと思います。

OpenClaw はコンパクション後でもトークン数は 20K 以上あり、使っていると簡単に 50K を超えます。そのため Main セッションの場合は、コンテキストウィンドウはほぼ単一のスロットです。この状態で Sub Agent などの別のセッションが走ると KV キャッシュが上書きされてしまい、再び長い再生成 (Prefill) 待ちになってしまうことがあります。

そこで Sub Agent に使う LLM 用の PC を別に用意すれば、長いコンテキストでのキャッシュ領域の衝突を避けることができます。.openclaw/openclaw.json の設定だと以下のようになります。

{
  "agents": {
    "defaults": {
      "model": {
        "primary": "llamacpp-pc1/Qwen3.5-122B-A10B"                 Main モデル
      },
      "subagents": {
        "model": "llamacpp-pc2/NVIDIA-Nemotron-3-Super-120B-A12B",  Sub Agent 
        "maxConcurrent": 1
      },
      "maxConcurrent": 2,
      "timeoutSeconds": 1800,
      "llm": {
        "idleTimeoutSeconds": 1800
      },
      
    }
  },
  "models": {
    "providers": {
      "llamacpp-pc1": {
        "api": "openai-completions",
        "apiKey": "llama.cpp",
        "baseUrl": "http://192.168.0.101:8080/v1",     Main  LLM PC  URL
        "models": [
          {
            "contextWindow": 65536,
            "cost": { "cacheRead": 0, "cacheWrite": 0, "input": 0, "output": 0 },
            "id": "Qwen3.5-122B-A10B",
            "input": [ "text", "image" ],
            "maxTokens": 32768,
            "name": "Qwen3.5-122B-A10B",
            "reasoning": true
          }
        ]
      },
      "llamacpp-pc2": {
        "api": "openai-completions",
        "apiKey": "llama.cpp",
        "baseUrl": "http://192.168.0.102:8080/v1",     Sub Agent  LLM PC  URL
        "models": [
          {
            "contextWindow": 65536,
            "cost": { "cacheRead": 0, "cacheWrite": 0, "input": 0, "output": 0 },
            "id": "NVIDIA-Nemotron-3-Super-120B-A12B",
            "input": [ "text" ],
            "maxTokens": 32768,
            "name": "NVIDIA-Nemotron-3-Super-120B-A12B",
            "reasoning": true
          }
        ]
      }
    }
  },
  
}

また PC を分けたことで、Sub Agent を完全にバックグラウンドで並列に走らせられるようになります。

なお Heartbeat は Main と同じコンテキストを共有しますが、同じスロットが割り当てられるので実行するタスクによっては競合する可能性があります。もし Heartbeat に使う LLM 用 PC も別に用意する場合は以下のように設定します。

{
  "agents": {
    "defaults": {
      "model": {
        "primary": "llamacpp-pc1/Qwen3.5-122B-A10B"                 Main モデル
      },
      "subagents": {
        "model": "llamacpp-pc2/NVIDIA-Nemotron-3-Super-120B-A12B",  Sub Agent 
        "maxConcurrent": 1
      },
      "heartbeat": {
        "model": "llamacpp-pc4/Qwen3.5-122B-A10B"                   Heartbeat 
      },
      "maxConcurrent": 2,
      "timeoutSeconds": 1800,
      "llm": {
        "idleTimeoutSeconds": 1800
      },
      
    }
  },
  
}

注意点

OpenClaw 用に Mac 上で LMStudio を使う場合は GGUF の方をお勧めします。単純な生成速度なら MLX の方が速いのですが、MLX ではキャッシュが再利用されずに毎回 Prefill が走ってしまうようです。

LLM 用 PC 側での実行例

LLM 用 PC では llama.cpp を使っています。以下はその実行例です。

llama-server.exe --model Qwen3.5-122B-A10B-Q4_K_M-00001-of-00002.gguf --mmproj mmproj-Qwen3.5-122B-A10B-BF16.gguf --alias Qwen3.5-122B-A10B -t 8 --ctx-size 65536 --host 0.0.0.0 --port 8080 --temp 0.6 --min-p 0.0 --top-p 0.95 --top-k 20 -fa on
llama-server --model NVIDIA-Nemotron-3-Super-120B-A12B-Q4_K_M-00001-of-00003.gguf --alias NVIDIA-Nemotron-3-Super-120B-A12B -t 8 --ctx-size 65536 --temp 0.6 --min-p 0.0 --top-p 0.95 --host 0.0.0.0 --port 8080 -fa on

複数の Sub Agent を同時実行するには

subagents.maxConcurrent = 1 を指定していますが、複数の Sub Agent を実行することは可能です。ただし並列度は 1になるので、Agent の数だけ時間がかかることになります。

もし実行時間短縮のために並列に走らせたい場合は、Sub Agent 用に更に追加の PC を割り当てる必要があります。直接コマンドから spawn 起動する場合は個別にモデル指定ができますが、設定ファイルの openclaw.json には Agent 毎に一つの Sub Agent モデルしか記述しておくことができないようです。

複数台の PC を使った並列化を行いたい場合は、個別にコマンドから model 指定で spawn するか、もしくは別の Coding Agent を利用する方法があります。例えば OpenClaw から Codex CLI の呼び出しができるので、Codex 側の設定で別の PC の Local LLM を割り当てておけば以下の 3つで並列実行になります。

  • Main Session / Heartbeat
  • Sub Agent
  • Codex CLI

画像認識モデルの指定

クラウドの商用モデルと違い、Local LLM が使うオープンモデルは画像認識に対応していないことがあります。Qwen3.5 の場合は画像入力に対応しているので不要ですが、他のモデルを使うときは以下のように VLM モデルを指定することができます。ここでは更に別の PC を割り当てています。

{
  "agents": {
    "defaults": {
      "model": {
        "primary": "llamacpp-pc1/NVIDIA-Nemotron-3-Super-120B-A12B"  Main モデル
      },
      "imageModel": {
        "primary": "lmstudio-pc3/qwen/qwen3-vl-4b"                  画像認識 
      },
      "subagents": {
        "model": "llamacpp-pc2/NVIDIA-Nemotron-3-Super-120B-A12B",  Sub Agent 
        "maxConcurrent": 1
      },
      "maxConcurrent": 2,
      "timeoutSeconds": 1800,
      "llm": {
        "idleTimeoutSeconds": 1800
      },
      
    }
  },
  "models": {
    "providers": {

       pc1/pc2 省略

      "lmstudio-pc3": {
        "api": "openai-completions",
        "apiKey": "lmstudio",
        "baseUrl": "http://192.168.0.103:1234/v1",     画像認識  VLM PC  URL
        "models": [
          {
            "contextWindow": 16384,
            "cost": { "cacheRead": 0, "cacheWrite": 0, "input": 0, "output": 0 },
            "id": "qwen/qwen3-vl-4b",
            "input": [ "text", "image" ],
            "maxTokens": 16384,
            "name": "qwen/qwen3-vl-4b",
            "reasoning": true
          }
        ]
      },
    }
  },
  
}

テキスト埋め込みモデルの指定

OpenClaw で Local LLM を使う場合は、メモリ検索用の埋め込みモデルを指定する必要があります。

OpenClaw が走っている PC のスペックが高く、RAM もストレージも余裕がある場合は CPU が使えます。とはいえ 300m (0.3b) でも 1GB ほどメモリを消費しますので、スペックに余裕がない場合はこれまでと同じ様に他の PC を割り当てて使うことが可能です。

Ollama で Local CPU を使う場合の例

  1. Ollama をインストール
  2. モデルをダウンロード
    • ollama pull embeddinggemma:300m
  3. 以下の設定を追加
{
  "agents": {
      "memorySearch": {
        "provider": "openai",
        "model": "embeddinggemma:300m",             埋め込みモデル
        "fallback": "none",
        "remote": {
          "baseUrl": "http://127.0.0.1:11434/v1",   埋め込みモデル用 PC  URL
          "apiKey": "ollama"
        }
      },
      
    }
  },

}

他の PC で処理する場合の例

LMStudio を使って他の PC 上で走らせる場合の設定例。

{
  "agents": {
      "memorySearch": {
        "provider": "openai",
        "model": "text-embedding-qwen3_embedding_4b",    埋め込みモデル
        "fallback": "none",
        "remote": {
          "baseUrl": "http://192.168.2.103:11434/v1",    埋め込みモデル用 PC  URL
          "apiKey": "lmstudio"
        }
      },
      
    }
  },

}

上記以外に provider = “local” を使う方法もあります。以下のページにまとめています。

しばらく使用してみて

llama.cpp のキャッシュ再利用のおかげで思ったよりもレスポンスは早いです。Slack で簡単な応答なら、リアクションマークが付いたあと 10秒くらいでストリーミングが始まります。ストリーミング表示されないクライアントだと全部生成してからメッセージが届くため、体感速度はだいぶ下がると思います。

たまに Heartbeat ジョブが走って Prefill 待ちが入ることがありますが、それでも長くて 2分くらいです。Heartbeat 用 PC があればこの待ち時間がなくなります。

内容も普通にチャットしている分には全く違和感なく、簡単なプログラムの作成なども問題なくこなします。memory も増えて徐々に育てていくことができます。普通に使う分には十分です。700b などの、よりパラメータ数の多いモデルと比べると細かいところでは正確性(追従性)に差が出るようです。メモリ更新などは指示して明示的にやらせた方が良いです。バックアップはこまめに取りましょう。

応答の仕方はモデルによって結構変わります。用途に合わせてモデルや量子化、temperature 等のパラメータ調整をしていくと良いのかもしれません。Sub Agent も当初はタイトル通り Qwen3.5 122B-A10B を使っていたのですが、今は Nemotron 3 Super に置き換えてテストしています。

注意点

OpenClaw で Local LLM を使用する場合はリスクを伴います。必ず完全に隔離した仮想マシンで Sandbox を有効にしてください。また重要な情報は絶対に与えず、テストする場合でもネットワークアクセスを制限しておくことをお勧めします。

{
  "agents": {
    "defaults": {
      "sandbox": {
        "mode": "all"
      },
      
    }
  },
  
}

openclaw status コマンドを実行すると、制限無しに 300b 未満のモデルを使っている場合にセキュリティの警告が表示されます。今回の説明でも 120b のモデルを使っているためセキュリティ警告が出ています。考えられるリスクとして、AI が騙されて危険な指示に従ってしまう可能性があります。OpenClaw ではできるだけ性能が高いモデルの利用が推奨されていますので、Local LLM を使う場合はご注意ください。

関連ページ

(メモリ増設した) 普通の PC で 100b 以上の LLM を使用する

普通の自分の PC 上でも (メモリさえ増設できれば) 100b (1000億) 以上のパラメータを持った巨大な言語モデルを走らせることができます。

最近立て続けに 120b 前後のモデルが 3つほどリリースされたので、昨年の gpt-oss-120 を含めて実際に走らせてみました。以下その結果です。token/s の数値が大きい方が高速です。(ctx 4096, Q4)

Modelパラメータ数
(active数)
R7 9700X 128GB
RTX5060Ti 16GB
i7-13700 96GB
RTX4060Ti 16GB
R7 5700X 96GB
RX9060XT 16GB
EVO-X2 128GB
AI Max+ 395
gpt-oss-120b120b (5b)23.8 token/s24.5 token/s15.5 token/s47.5 token/s
Qwen3.5 122B-A12B122b (10b)16.7 token/s18.4 token/s11.7 token/s27.6 token/s
Nemotron 3 Super120b (12b)11.4 token/s12.4 token/s7.0 token/s15.7 token/s
Mistral Small 4 2603119b (6b)13.8 token/s15.4 token/s11.3 token/s33.8 token/s

AI 用の EVO-X2 は別格として、普通の PC (700 番台の CPU + 60 番台の GPU) でも RAM 96GB 以上 + VRAM 16GB あれば 10~20 token/s くらいで動いているのがわかるかと思います。

ちょうど 1年前は普通の PC で 70b のモデルを動かすためにビデオカードを 5枚繋いだりしていたのですが、それでもわずか 4 token/s でした。今ではもっとパラメータ数が多い 120b で 3~6 倍速くなっています。MoE が当たり前になって最適化が進んだおかげです。ありがとうございます。

なお速度は使用するソフトウエアのバージョンや設定によって変わります。非常に更新が激しいので、2026/03/20 現在での参考値としてみてください。

エージェントとして使う場合はコンテキストウィンドウサイズを増やす必要がありますが、その分 VRAM 割当も減って遅くなります。それでも KV キャッシュの再利用ができれば、生成速度が 10~15 token/s くらいでも割と直ぐにレスポンスが来ます。逆に再利用できないケースでは入力プロンプトの Prefill でだいぶ待たされます。

Ollama の場合は MoE でもパラメータが VRAM に乗らないと速度が出ません。LMStudio の方が速いのですが、モデル毎に CPU/GPU のバランス調整が必要です。llama.cpp が最も簡単で、ほぼデフォルトで大丈夫です。

Windows 11 の Ryzen 7 9700X 128GB + RTX 5060Ti で Qwen3.5 122B-A10B を動かす場合の例

  1. gguf の Q4_K_M モデルをダウンロード
    • もし LMStudio ですでにダウンロードしたファイル ( C:\Users\ユーザー名\.lmstudio\models\ 以下 ) があればそのまま利用可能です
  2. llama.cpp の 「Windows x64 (CUDA 12)」と「CUDA 12.4 DLSs」 をダウンロード
  3. llama-server.exe を以下のようにして起動したら、ブラウザで「 http://127.0.0.1:8080 」を開きます
    • 必要に応じてモデル名やパスの部分は変更してください
llama-server.exe --model Qweun3.5-122B-A10B-Q4_K_M-00001-of-00003.gguf -t 16 --ctx-size 4096 --host 127.0.0.1 --port 8080 --temp 1.0 --top-p 0.95 --top-k 20

EVO-X2 の場合は VRAM 割当を 96GB にしたあと、上記のコマンドラインに「 –no-mmap 」を加えます。

実際にどのような設定を使ったかなど、より詳しいデータは以下のページ以下にまとめています。適宜更新しています。

使用したモデル

リリース開発モデルパラメータ数active
2025/08/05OpenAIgpt-oss-120b120b5b
2026/02/24AlibabaQwen 3.5 122B-A10B122b10b
2026/03/11NVIDIANemotron 3 Super120b12b
2026/03/17MistralMistral Small 4 119B-2603119b6b

使用した PC スペック

OSCPUArchcore/threadRAMGPU
Win11Ryzen 7 9700XZen58/16DDR5-5600 128GBGeForce RTX 5060Ti 16GB
LinuxCore i7-13700RaptorLake16/24DDR5-5600 96GBGeForce RTX 4060Ti 16GB
Win11Ryzen 7 5700XZen38/16DDR4-3200 96GBRadeon RX 9060 XT 16GB
Win11Ryzen AI Max+ 395Zen516/32LPDDR5-8000 128GBRadeon 8060S

関連ページ

OpenClaw を Pixel スマートフォンで動かしてみる

Google の Pixel スマートフォンには標準で Linux のターミナル機能が入っています。これを使って AI エージェントの OpenClaw を走らせてみました。もし機種変更などで使わなくなった Pixel スマートフォンがあるなら、持ち運べる OpenClaw マシンを作ることができるかもしれません。

この画面は Pixel 9a 実機上のものです。

以下はその手順です。

(1) Linux ターミナル (Linux 開発環境) を有効化する

有効化手順は過去にも何度か解説してますので興味ある方はそちらもご覧ください。

先に Display のスリープ時間を 30分に設定しておくことをお勧めします。インストール途中でスリープして止まってしまうのを防ぐためなので、完了したら元の値に戻しておいてください。

コマンド入力は USB or Bluetooth のキーボードがあると便利です。もしくは少々設定の手間が必要ですが、ssh を使って PC からログインして作業することもできます。(tailscale や termux の設定、/etc/ssh/sshd_config の PasswordAuthentication を yes に変更等)

  1. 画面自動消灯の時間を 30分に変更
    • 設定 → ディスプレイとタップ → 画面自動消灯 → 30分を選択
    • ※ インストールが完了したら元の時間に戻しておいてください
  2. 開発者向けオプションを有効化
    • 設定 → デバイス情報 → ビルド番号 の欄を 7回タップ
  3. 開発者向けオプションから Linux ターミナルを有効化
    • 設定 → システム → 開発者向けオプション → Linux開発者環境 (試験運用版) を有効化
    • これで Pixel に「ターミナル」アプリが追加されます
  4. Linux のインストール
    • 「ターミナル」アプリを起動して「インストール」をタッチ
    • ホーム画面には自動的に追加されないので、アプリケーションドロワーから「ターミナル」のアイコンを探してください
    • インストールにはしばらく時間がかかるのでターミナルが起動するまで待ちます
  5. ターミナルが起動したら以下のコマンドを実行します
sudo apt update
sudo apt upgrade -y
sudo apt install systemd-container

(2) OpenClaw 用のユーザーを作る

ターミナルアプリのデフォルトユーザーは droid ですが、Android の内部ストレージから隔離するためにユーザーを分けてみます。新たに openclaw というユーザーを作ってそちらでインストールします。以下のコマンドを実行し、パスワードを登録したらあとは全部 Enter。

sudo adduser openclaw

以下のコマンドを実行してユーザーの権限を設定します。users group から削除しているのは内部ストレージ ( /mnt/shared ) にアクセスできないようにするためです。

sudo gpasswd -a openclaw sudo
sudo gpasswd -d openclaw users

デフォルトの droid ユーザーのパスワードは “droid” が入っているので、パスワードを変更しておきます。以下のコマンドで droid ユーザー用の新しいパスワードを設定します。

sudo passwd droid

OpenClaw 用のユーザーに切り替えるには以下のコマンドを使います。パスワード入力が必要です。最初は su を使っていましたが systemctl –user でエラーになります。

sudo machinectl shell openclaw@.host

ユーザー切り替え後に、プロンプトが ‘$’ 1文字だけの場合は sh が動いているので手動で bash を実行します。

bash

(3) OpenClaw をインストールする

最初にユーザーを “openclaw” に切り替えておいてください。( sudo machinectl shell openclaw@.host )

あとは通常の Linux 版の OpenClaw のインストール手順そのままです。公式サイトにあるように以下のコマンドを実行します。ここでは 2026/03/07 版で手順を解説していきます。

なお連携用の各種 API Key や token は予め PC 上で用意しておくことをお勧めします。

curl -fsSL https://openclaw.ai/install.sh | bash
  1. 「I understand this is personal-by-default and shared/multi-user use requires lock-down. Continue?」
    • Yes を選択
  2. 「Onboarding mode」
    • QuickStart を選択
  3. 「Model/auth provider」
    • もし API Key を持っている物があるなら選択して指示に従ってください。
    • ここで設定せずにあとから登録する場合は「Skip for now」→「openai」→「Keep current」の順で選択します。
  4. 「Select channel (QuickStart)」
    • もしここで Discord や Slack 等の設定を行う場合は選択して指示に従ってください。Bot アプリの設定が必要なので、先に PC 上で作業して token を用意しておくことをお勧めします。
    • ここで設定せずにあとから登録することもできるので、その場合は「Skip for now」を選んでください。
  5. 「Search provider」
    • Web 検索サービスを選択できます。
    • こちらも特に API Key を持っていない場合は「Skip for now」で構いません。
  6. 「Configure skills now? (recommended)」
    • Yes を選択
  7. 「Install missing skill dependencies」
    • スペースキーで選択してから Enter で進みます。
    • 特になければ「Skip for now」を Space キーで選択してから Enter
  8. 「Set GOOGLE_PLACES_API_KEY for goplaces?」
    • 以下、特にキーがなければ全部 No で構いません。
  9. 「Enable hooks?」
    • “Skip for now” を Space キーで選択してから Enter
  10. 「How do you want to hatch your bot?」
    • Do this later を選択

これでインストールは完了です。最初は openclaw コマンドにパスが通っていないので、以下のコマンドを実行しておいてください。

.  ~/.bashrc

(4) インストール手順でスキップした設定を行う

インストーラーの手順でスキップした場合でも、任意のタイミングで設定を行うことができます。最初の選択肢は「Local (this machine)」を選んでください。

使用する LLM Model の選択

openclaw configure --section model

Web 検索用の API 設定

openclaw configure --section web

Discord, Slack などのメッセージングアプリとの接続

openclaw configure --section channel

↓これは Pixel9a 上で動いている OpenClaw に Pixel9a 上の Discord から接続したものです。(LLM は外部サービス)

(5) その他の設定

一通りインストールが終わったら画面の自動消灯設定をもとに戻します。

  • 設定 → ディスプレイとタップ → 画面自動消灯 → 元の値に戻す (30秒などに)

念の為以下の設定もしておきました。

  • 設定 → システム → 開発者向けオプション → 子プロセスの制限を無効化を ON

その他 OpenClaw 側の設定などは以下のページでも解説していますのでもしよろしければ参考にしてください。

動作したあとの問題解決など

一度動作してしまえばあとは OpenClaw 自身に問題解決してもらうことができます。openclaw status 実行時に何らかの Warning や Error が出ていた場合は、直接チャットに送って修正を依頼します。

注意点&使ってみて

メモリを消費する重いアプリケーションを立ち上げるとバックグラウンドのタスクが停止させられてしまう可能性があります。もしできるだけ安定して起動状態を維持したい場合は、Linux のターミナルをフォアグラウンドにして Pixel の直接操作を控えた方が良いかもしれません。

バックグラウンドプロセスの停止を防ぐ設定として Phantom Process Killer の無効化 があります。長時間安定して稼働させたい場合はこちらの設定もしておくことをお勧めします。設定には PC からの adb 接続が必要です。またバッテリー消費量が増えますのでご注意ください。

一日ほど持ち歩いてみましたが Sleep 状態でも OpenClaw 自体はきちんと動作しています。ただし安定動作するとは限らないので、利用時はこまめにバックアップを取って置くことをお勧めします。基本的には ~/.openclaw 以下 (/home/openclaw/.openclaw 以下) をまるごと保存しているだけです。

しばらくして一度コマンド実行ができず不安定になったことがありましたが、この場合スマートフォン本体の再起動で復帰しました。調子が悪くなった場合でもターミナルアプリの強制終了は避けてください。

バックアップ手順の例

user openclaw 側で

cd
tar -zcvf /tmp/backup.tgz .openclaw

user droid 側で

cp /tmp/backup.tgz /mnt/shared/Download/

本体ストレージの Download フォルダに入ります。

復元時は OpenClaw を新規インストール後に .openclaw フォルダをバックアップ時のものに置き換えてから openclaw –fix を実行します。