1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ryzen AI MAX+ 395でNemotron 3.5 Boltを動かす:ROCm・llama.cppで約30.8 tokens/s

1
Posted at

AMD Ryzen AI MAX+ 395の内蔵GPU、Radeon 8060Sで、NVIDIA Nemotron 3.5 Bolt 74B-A9B 24GBの公式GGUFを動かしました。llama.cppをHIPバックエンドでビルドし、テキスト生成、GPUオフロード、OpenAI互換APIの応答を確認しています。

生成速度は3回平均で約30.8 tokens/sでした。7936トークンを入力済みの状態でも、今回の測定ではほぼ同じ速度になりました。この記事では、2026年10月16日に実施した実験の構成、実行コマンド、速度とメモリの測定結果を記録します。

検証環境と対象モデル

今回使用したのは、NVIDIAが公開する公式GGUFです。画像用のエンコーダーは追加せず、テキストだけを入力しました。

項目 構成
CPU AMD Ryzen AI MAX+ 395
GPU Radeon 8060S、gfx1151
メモリ 共有RAM 96 GB構成、利用可能容量は約90 GiB
OS Ubuntu 26.04.1 LTS
ROCm環境 /opt/rocm/core-10.1 配下のHIPコンパイラーを使用
llama.cpp build 11695、コミット 9a16f1dbe4722a93ab75a2d15e29aa71ef764c7b
モデル NVIDIA-Nemotron-3.5-Bolt-74B-A9B-24GB.gguf
量子化形式 llama-benchの表示では IQ2_XXS - 2.0625 bpw
投機的デコーディング 無効

ROCm 10.1用に用意した環境を使っていますが、ここではコンパイラーの実体をパスで示しています。この構成での動作確認であり、ほかのROCm構成やOSとの互換性まで検証したものではありません。

llama.cppのHIPビルド

既存の ~/llama.cpp を更新し、HIPを有効にした既存のビルド設定で llama-cli、llama-server、llama-bench をビルドしました。使用コミットは上表のとおりです。

cd ~/llama.cpp
cmake -S . -B build
cmake --build build -j 12 --target llama-cli llama-server llama-bench
build/bin/llama-cli --version
build/bin/llama-cli --list-devices

ビルドキャッシュに保存されていた主な設定は次のとおりです。cmake -S . -B build だけでは、初めてビルドする環境でこれらの設定は揃いません。

CMAKE_BUILD_TYPE=Release
GGML_HIP=ON
AMDGPU_TARGETS=gfx1151
GGML_HIP_NO_VMM=ON
CMAKE_PREFIX_PATH=/opt/rocm/core-10.1
CMAKE_HIP_COMPILER=/opt/rocm/core-10.1/lib/llvm/bin/clang++

新しいビルドディレクトリに同じ設定を指定する場合の例は以下です。このコマンドは、実験時のキャッシュ設定を明示したものです。新規環境でのインストール手順全体は検証していません。

cmake -S . -B build-bolt-hip \
  -DCMAKE_BUILD_TYPE=Release \
  -DGGML_HIP=ON \
  -DAMDGPU_TARGETS=gfx1151 \
  -DGGML_HIP_NO_VMM=ON \
  -DCMAKE_PREFIX_PATH=/opt/rocm/core-10.1 \
  -DCMAKE_HIP_COMPILER=/opt/rocm/core-10.1/lib/llvm/bin/clang++

cmake --build build-bolt-hip -j 12 \
  --target llama-cli llama-server llama-bench

ビルド時には、実行環境の制限による書き込み失敗と、サーバーのUI依存ファイル取得時のネットワーク失敗がありました。書き込みとネットワークアクセスが可能な環境で再実行した後、3つのターゲットをビルドできました。llama.cppのソースコードには変更を加えていません。

公式GGUFの取得とテキスト生成

Hugging Face CLIでモデルを取得しました。以下では実験時と同じディレクトリ構成を使います。hf は導入済みであることを前提としています。

mkdir -p ~/nemotron-3-5-bolt-74b-a9b-24gb

hf download \
  nvidia/NVIDIA-Nemotron-3.5-Bolt-74B-A9B-24GB-GGUF \
  NVIDIA-Nemotron-3.5-Bolt-74B-A9B-24GB.gguf \
  --local-dir ~/nemotron-3-5-bolt-74b-a9b-24gb

MODEL="$HOME/nemotron-3-5-bolt-74b-a9b-24gb/NVIDIA-Nemotron-3.5-Bolt-74B-A9B-24GB.gguf"

最初は8192トークンのコンテキストを指定し、Fibonacci数を求めるPython関数の生成を試しました。

cd ~/llama.cpp
build/bin/llama-cli \
  -m "$MODEL" -ngl 999 -c 8192 \
  -p 'Write a short Python function that computes Fibonacci numbers.' \
  -n 256 --reasoning off --single-turn --simple-io

この実行は終了コード0で完了し、入力処理は96.16 tokens/s、生成は30.53 tokens/sでした。ただし、出力は256トークンの上限に到達しています。ここで確認したのは生成処理の動作と速度であり、コードの正しさや回答全体の品質は評価していません。

GPUへの配置は、ベンチマークのログでも確認しました。-ngl 999 はGPUへのオフロードを要求する指定なので、指定値だけで判断せず、実際の配置ログを確認しています。

Device 0: AMD Radeon 8060S Graphics, gfx1151
load_tensors: offloaded 89/89 layers to GPU
load_tensors:        ROCm0 model buffer size = 20446.77 MiB
load_tensors:    ROCm_Host model buffer size =   544.00 MiB

89/89層がGPUにオフロードされ、CPUだけで実行するフォールバックは使われませんでした。ホスト側にもバッファがあるため、この記録から「すべての処理とメモリがGPU側だけにある」とは判断していません。

短い入力と8K近くの入力で速度を比較

速度の測定には llama-bench を使いました。入力を処理する速度と、入力済みの状態からトークンを生成する速度を分けて測っています。

共通条件は、バッチサイズ2048、マイクロバッチサイズ512、CPUスレッド数16、K/VキャッシュはF16です。各テストを3回ずつ実施し、投機的デコーディングは使用していません。

短い入力での基準値

まず、512トークンの入力処理と128トークンの生成を測りました。

build/bin/llama-bench \
  -m "$MODEL" -ngl 999 \
  -p 512 -n 128 -r 3 -v -o json
テスト 1回目 2回目 3回目 平均
pp512:512トークンの入力処理 520.967 562.020 560.990 547.99 tokens/s
tg128:128トークンの生成 30.745 30.823 30.813 30.79 tokens/s

このコマンドの pp512 と tg128 は別々のテストです。tg128 は、512トークンの入力を処理した後の生成速度を表すものではありません。また、この測定中はアイドル状態のAPIサーバーが常駐していました。サーバーへの同時生成リクエストは送っていません。

7936トークンを入力した状態での生成

次に、8K近くまで入力したときの速度を測りました。入力処理は7936トークンで測定し、生成は -d 7936 で7936トークン分の入力済み状態を用意してから128トークンを生成しています。

# 7936トークンの入力処理
build/bin/llama-bench \
  -m "$MODEL" -ngl 999 \
  -p 7936 -n 0 -r 3 -v -o json

# 7936トークンを入力済みの状態から128トークンを生成
build/bin/llama-bench \
  -m "$MODEL" -ngl 999 \
  -p 0 -n 128 -d 7936 -r 3 -v -o json

生成テストでは8192トークンのコンテキストが確保されていました。入力だけを処理するテストのコンテキストは7936トークンです。

テスト 1回目 2回目 3回目 平均
pp7936:7936トークンの入力処理 544.449 541.922 541.651 542.67 tokens/s
tg128、深さ7936:128トークンの生成 30.496 30.905 30.872 30.76 tokens/s

7936トークンの入力処理にかかった時間は平均14.62秒、128トークンの生成は平均4.16秒でした。生成時間には、事前の入力処理や状態の復元は含まれません。そのため、4.16秒をリクエスト全体の応答時間として扱うことはできません。

短い入力の基準値30.79 tokens/sと、深さ7936での30.76 tokens/sの差は約0.12%でした。今回の3回測定では、8K近くの入力による生成速度の明確な低下は観測していません。これらは合成トークンによるベンチマークであり、長文の読解精度や、8Kを超えるコンテキストでの性能は別途検証が必要です。

共有メモリの使用量

8K近くの測定では、ベンチマークの起動前から終了まで、0.2秒間隔で /proc/meminfo とDRMのメモリ・GPU使用率カウンターを記録しました。システム全体の使用量は次の式で算出しています。

システム全体の使用量 = MemTotal - MemAvailable
テスト 起動前の使用量 観測したピーク 起動前からの増加量
7936トークンの入力処理 27.92 GiB 49.65 GiB 21.73 GiB
深さ7936から128トークン生成 27.78 GiB 49.98 GiB 22.20 GiB

約50 GiBという値は、他プロセスを含むシステム全体の観測ピークです。 起動前から約28 GiBを使用しており、モデル単体の必要メモリが50 GiBだったという測定ではありません。起動前との差分も、同時に動くほかの処理の影響を含むため、モデル単体の厳密な消費量とは区別しています。

GPU使用率は両テストで最大100%に達し、観測中のスワップ使用量は0でした。DRMのGTT使用量は最大約41.88 GiBでしたが、これはほかのGPU割り当ても含む値です。APUではGPU用の割り当てとシステムRAMが重なるため、GTTやVRAMの値を上表の使用量に加算していません。

なお、CLIを /usr/bin/time -v で測ったときの最大RSSは約1.49 GiBでした。RSSにはGPU・共有メモリの割り当て全体が反映されないため、これだけでモデルの必要メモリを見積もることはできません。今回の0.2秒間隔の記録にも、それより短いピークを取りこぼす可能性があります。

OpenAI互換APIの動作確認

llama-server をlocalhostで起動し、チャットAPIから短い応答を取得しました。

cd ~/llama.cpp
build/bin/llama-server \
  -m "$MODEL" -ngl 999 -c 8192 \
  --host 127.0.0.1 --port 18080 \
  --jinja --reasoning off

別のターミナルから、次のリクエストを送ります。

curl -sS http://127.0.0.1:18080/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "local",
    "messages": [{"role": "user", "content": "Reply with exactly: OK"}],
    "max_tokens": 32,
    "temperature": 0
  }'

実際の応答から必要な項目を抜粋すると、次のようになりました。

{
  "choices": [
    {
      "finish_reason": "stop",
      "message": {"role": "assistant", "content": "OK"}
    }
  ],
  "usage": {
    "prompt_tokens": 21,
    "completion_tokens": 2,
    "total_tokens": 23
  }
}

指定どおり OK が返り、finish_reason は stop でした。今回のAPI確認は単一の短いリクエストに限っています。並列リクエスト時のスループットやtool callingは測っていません。

今回確認できた範囲と追加検証

今回の構成では、公式GGUFの読み込み、89/89層のGPUオフロード、テキスト生成、localhostでのチャットAPI応答を確認できました。共有RAMを使うRadeon 8060Sでも、HIPバックエンドで通常の推論を実行できています。

画像入力、LiLiCorr/DFlashによる投機的デコーディング、tool calling、8Kを超える入力、生成品質の比較は未検証です。モデル初期化にはキャッシュがある状態で約2.9秒という記録がありますが、ディスクからのコールドロード時間は測っていません。

まず通常推論の基準値として、生成約30.8 tokens/s、7936トークンの入力処理約14.6秒という結果を得ました。投機的デコーディングを試す際は、この条件と揃えて速度とメモリを比較できます。

参考資料

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?