ローカルで大規模LLMを動かしたい。RTX 5090も、DGX Sparkも、メモリを積んだMac Studioも気になる。ただ、どれも気軽に買える機材ではない。そんな中、TITAN RTXの2枚目を手に入れた。X299マシンに2枚を載せ、NVLinkもつないだ。2019年ごろのハイエンド機材を組み合わせた環境で、今の大規模LLMはどこまで動くのか。
TITAN RTX 24GBを2枚使い、StrataでQwen3.8-Flash-Nextを動かした。GSQ-RCOのIQ3_S、MTPありの構成で、自由文の生成は56〜59 tok/sだった。約25万トークンの合成入力から目印を取り出す試験も、1回は成功した。
この記事では、測定結果に加えて、ドライバー、ソースからのビルド、Docker内のLiteLLMとの接続、別モデルとの同居でつまずいた点をまとめる。実際のエージェント用途での有用性や長時間の安定性は、これから確かめる段階だ。
検証環境と、この記事が対象にする版
検証日は2026年10月4日。Strataは同日に取得したGitHub mainのソースzipからビルドした。更新後の版でも同じ挙動になるとは限らない。
| 項目 | 検証時の構成 |
|---|---|
| 仮想化・OS | Proxmox上のUbuntu 24.04.5、kernel 6.8.0-146。GPUをパススルー |
| CPU | Core i9-10900X、VMに16 vCPU。AVX2、AVX-512なし |
| RAM | VMへの割り当て96GiB → 112GiB。ゲスト可視は約94GiB → 約110GiB |
| GPU | TITAN RTX 24GB ×2、compute capability 7.5、PCIe Gen3 x16、NVLinkブリッジ |
| GPUの電力上限 | 1枚200W |
| NVIDIAドライバー | 580.178.04 |
| ビルド環境 | CUDA Toolkit 13.4.92、g++ 13.3.0、Python 3.12.3 |
| 比較用llama.cpp | build 11118、commit e6ab7c1a4、Dockerのserver-cudaイメージ |
| Ollama | 0.34.3 |
Strataの取得コミットは、zipで取得したため記録していない。取得物の識別情報は次のとおりだ。
- ソースzip:13,582,889バイト
- SHA-256:
5014a1d6c2dfcabe73ce10fa71ddb1facd3f7292069cc7c016060537456fd2ea - セットアップに記載された最低エンジン版:
MIN_ENGINE = 0.1.38。起動ログにもengine 0.1.38と表示された。 - 内部で利用するllama.cppのコミット:
3cf03257f219afbe7334045ff7c6a06ac68c627d
Strataは独自のC++/CUDAエンジンで、ggmlとmtmdを利用する。大きなMoEモデルのExpertをGPU・RAM・SSDに分けて扱い、よく使うExpertをGPUにキャッシュする。量子化しても48GBのVRAMだけには収まらないため、RAMも必要になる。
導入:ドライバーとビルドの注意点
580未満で停止する判定があった
取得したsetup.pyにはMIN_DRIVER = 580があり、580未満で停止する判定があった。私の環境では先に570.195.03から580.178.04へ更新しており、570のままセットアップを実行したわけではない。
Ubuntu 24.04では、候補と変更内容を確認してから更新した。
apt-cache policy nvidia-driver-580
apt-get -s install nvidia-driver-580
sudo apt-get install nvidia-driver-580
sudo reboot
nvidia-smi
apt-get -sはインストールのシミュレーションだ。私の環境には570系を固定する設定があったが、580の導入は妨げなかった。固定の内容やパッケージ候補は環境ごとに確認する必要がある。
元の570.195.03はUbuntuの配布先に残っておらず、パッケージを入れ直すだけでは同じ版へ戻せなかった。今回のパススルーVMは稼働中のスナップショットも取れなかったため、更新前にVMを停止して復元手段を用意するのがよい。
Linux版の配布先が404で、ソースからビルドした
作業当日はLinux用のstrata-linux-x64.zipの配布先がHTTP 404だった。セットアップはソースからのビルドに切り替わった。
CUDA ToolkitとC++コンパイラは導入済みだった。nvccがPATHになくても、セットアップは/usr/local/cuda-13.4を見つけた。CMakeとNinjaは.venvへ導入された。道具がない場合は、セットアップがsudoで追加導入しようとする経路もある。
画像入力用のstrata-visionもビルドした。こちらは約18分かかった。エンジン本体のビルド時間は記録していない。
非対話でも、質問への指定を省かない
zipから展開したsetup.shには実行権限がなかったため、sh ./setup.shで実行した。今回通った指定は次のとおりだ。これは、約110GiBのRAMで、IQ3_S・GPU2枚・画像入力あり・文脈上限262,144にしたときの設定になる。
cd Strata-main
sh ./setup.sh --family qwen --model IQ3_S --gpus 0,1 --port 8082 \
--context 262144 --kv int8 --vision gpu \
--experimental-speed-projection off --no-start
--yesは使わなかった。ビルド道具の導入にも既定のyesで答えるためだ。質問への指定が足りない場合は、非対話入力が途切れて停止した。そこで、必要なフラグを足して再実行した。
| 指定 | 用途 |
|---|---|
--family qwen |
モデルの系統を指定 |
--kv int8 |
KVキャッシュの精度を指定。取得時のREADMEの推奨 |
--vision gpu |
画像エンコーダを準備し、GPUで画像入力を処理 |
--experimental-speed-projection off |
応答傾向を変える実験機能を無効化 |
--no-start |
導入後にサーバーを起動しない |
先に環境の確認だけ行う場合は、sh ./setup.sh --check --gpus 0,1が使えた。この経路ではモデルのダウンロードやパッケージの導入は行われず、作られたのは.venvと空のデータ用フォルダーだけだった。
IQ3_Sのモデルは約84GB(約78GiB)。別途MTPのドラフト層約5〜6GB、画像エンコーダ約0.91GB、Pythonパッケージなどを取得した。IQ2_XSとIQ3_Sの両方を置いたStrata-dataは約124GBになった。
起動と待ち受け
セットアップが生成した設定を使い、次のように起動した。
.venv/bin/python serve/server.py \
--engine strata --config strata-iq3_s.json --port 8082
起動には約1分かかった。RAMへのExpertの読み込みとGPUキャッシュの準備があるため、モデルを切り替えてすぐ使えるわけではない。
待ち受けは既定でループバックに限定される。変更する場合は設定のhostを使う。ループバック以外で待ち受ける場合、Strataの資料はAPI鍵の設定を求めている。鍵はSTRATA_API_KEYまたは--api-keyで指定できる。
DockerのLiteLLMから接続する
私の環境では、LiteLLMはDocker内、StrataはVM内のプロセスとして動く。コンテナ内のループバックはStrataの待ち受け先ではないため、そのままでは接続できない。
そこでDockerネットワークのホスト側ブリッジに限って待ち受けさせた。以下の<network>や<bridge-gateway>は、利用する環境の値へ置き換える。
docker network inspect <network> \
--format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'
生成済みの設定を複製し、strata-iq3_s-bridge.jsonのhostを<bridge-gateway>にした。設定へ追加する項目は次のとおり。
"host": "<bridge-gateway>"
鍵は環境変数で渡す。次は起動の形を示した例だ。
export STRATA_API_KEY='<API鍵>'
.venv/bin/python serve/server.py \
--engine strata --config strata-iq3_s-bridge.json --port 8082
実運用では鍵を履歴に残さず、保護したファイルなどから環境変数へ読み込ませる。Dockerの.envもGitの管理対象から外す。
ComposeのLiteLLMサービスへ環境変数を渡す。
environment:
STRATA_API_KEY: ${STRATA_API_KEY}
LiteLLMのmodel_listには次の項目を追加した。
model_list:
- model_name: qwen3.8-flash-next-iq3_s
litellm_params:
model: openai/qwen3.8-flash-next-iq3_s
api_base: http://<bridge-gateway>:8082/v1
api_key: os.environ/STRATA_API_KEY
timeout: 1800
stream_timeout: 1800
model_info:
mode: chat
max_input_tokens: 262144
max_output_tokens: 16384
supports_vision: true
supports_reasoning: true
ここは接続先を登録する設定で、各機能の実用性を検証した結果ではない。
ファイルとしてマウントした設定の変更は、私の構成ではdocker compose up -dだけでは読み直されず、LiteLLMの再起動が必要だった。
docker restart <litellm-container>
コンテナ内から疎通を確認する例は次のとおり。標準入力でPythonを渡すため、docker execの-iを付ける。鍵の値は出力しない。
docker exec -i <litellm-container> python3 - <<'PY'
import os
import urllib.request
import urllib.error
def status(key=None):
request = urllib.request.Request('http://<bridge-gateway>:8082/v1/models')
if key:
request.add_header('Authorization', 'Bearer ' + key)
try:
with urllib.request.urlopen(request, timeout=10) as response:
return response.status
except urllib.error.HTTPError as error:
return error.code
print('with key:', status(os.environ['STRATA_API_KEY']))
print('without key:', status())
PY
この構成では鍵あり200、鍵なし401を確認した。LiteLLM側で利用者ごとにモデルを制限している場合は、許可一覧にも追加する。/key/updateのmodelsは一覧を丸ごと置き換えるため、既存の許可モデルを落とさないようにする。
同居の落とし穴:VRAMの予約を二重に引かない
Gemma4 12B QATをGPU1に常駐させたまま、Strata IQ3_Sを起動してみた。
最初に--vram-reserve-mib 10240を指定すると、エンジンは起動前に終了した。常駐モデルのVRAM使用量は、すでに空き容量から引かれている。そこへ常駐モデル相当の予約を加えると、さらに差し引かれるためだ。
今回は、先にGemmaをロードし、Strataの設定ファイルのargs配列に次の2要素を追加した。
"--vram-reserve-mib", "1536"
これは配列へ追加する断片で、予約するのは追加で増える分の余裕だ。1,536MiBは今回通った値であり、別モデルや別設定でも十分とは限らない。StrataのExpertキャッシュは起動時の空きVRAMに合わせて決まるので、常駐させたいモデルを先にロードする順序も重要だった。
同居できても、同時に生成すると遅くなった。
| モデル | 単独生成時 | 同時生成時 |
|---|---|---|
| Gemma4 12B QAT | 約59 tok/s | 約40 tok/s |
| Strata IQ3_S、MTPあり | 約57 tok/s | 約44 tok/s |
「単独生成時」も、もう一方は常駐していて生成していない状態だ。Strata側はRAM約94GiB、文脈上限131,072、画像入力なし。GemmaはOllamaのネイティブな生成APIを既定設定で使った。同時生成でおおむね2〜3割の低下を観測した。
増設後の別試験では、RAM約110GiB、文脈上限262,144、画像入力あり、MTPあり、Gemma常駐のIQ3_Sで、自由文3課題が53.0〜57.6 tok/sだった。温度0.7、各1回、生成上限512トークン。同居できることと、同時利用時の待ち時間は分けて考えたい。
画像入力と256Kの文脈
画像入力は導入時に指定すると手戻りが少ない
最初は--vision noneで導入したため、あとから画像入力を有効にする際に再ビルドと再設定が必要になった。使う予定なら、導入時に--vision gpuを指定しておく。
エンコーダ用に約1.2〜1.4GBのVRAMが必要になり、GPUのExpertキャッシュは9,504個・17.54GiBから、8,873個・16.35GiBへ減った。
動作確認は、OpenAI形式のimage_urlにdata URLを渡した。256×256の合成画像を2色・4色に塗り分け、その色を答えるところまで確認した。1枚あたり2.1〜3.2秒、思考を含む。写真の細部や複数画像の理解は未確認だ。ツール呼び出しも1つのツールで1回動作したが、エージェント全体の検証はしていない。
約25万トークンを入力すると、読み込みは約3.7分
文脈上限を262,144へ変える際は、セットアップを再実行した。モデルの再取得は不要だった。KVキャッシュはRAMも使い、ログでは直近32,768セルをVRAMに置く構成だった。
IQ3_S、MTPあり、RAM約110GiB、画像入力ありの設定で、合成入力の前方5%・中央50%・後方95%に目印を置いた。
| 項目 | 結果 |
|---|---|
| 入力トークン数 | 253,627 |
| 入力の読み込み | 219秒 |
| 入力処理速度 | 約1,157 tok/s |
| 生成速度 | 58.5 tok/s |
| 目印の回収 | 3つとも成功 |
| 試行回数 | 1回 |
同じRAM・文脈上限・画像設定で、36,060トークンの入力処理は22.3秒、約1,614 tok/sだった。この試験では、長い入力のほうが処理速度は低かった。
生成が速くても、長文の最初の読み込みは数分になる。目印を探す合成試験の成功だけでは、実文書の理解やエージェントの待ち時間が改善したとは言えない。512K以上の拡張も試していない。
速度と回答品質の比較
自由文生成はIQ3でも50トークン台
同じ2問を各1回試した。
| Flash-Nextの構成(TITAN RTX ×2) | 量子化 | MTP | 自由文の生成速度 |
|---|---|---|---|
| llama.cpp、層単位で分割 | UD-IQ4_XS、約4ビット | なし | 15.8〜16.1 tok/s |
| Strata | IQ2_XS、2ビット級 | あり | 52〜57 tok/s |
| Strata | IQ3_S、約3.5ビット級 | あり | 56〜59 tok/s |
Strata側の設定はRAM約94GiB、文脈上限131,072、画像入力なし。表の速度は、起動や入力処理を除いた生成部分だ。
約9,060トークンの合成入力では、llama.cppの入力処理が約480〜494 tok/s、Strata IQ2_XSが約1,109、IQ3_Sが約1,073 tok/sだった。長い入力で使うメモリ容量や設定は、前節の試験と異なる。
llama.cppではGPU使用率12〜24%、CPUは6〜10コア分を観察した。VRAMに載らない層のCPU計算が詰まりになっていると推定している。一方、StrataのExpertキャッシュのヒット率は94〜100%だった。GPUで処理する部分を増やせることが、速度差の主因ではないかと考えている。
監視画面の瞬間値。表の測定値や平均値ではない。
簡易的なLLM as a Judgeで比較した
モデル名を伏せてClaudeに採点してもらった。論点、日本語、根拠、洞察、簡潔さの5観点を各5点、1問25点とし、2問の合計50点で比べた。
| 構成 | 合計/50 | 自由文の生成速度 |
|---|---|---|
| Flash-Next、llama.cpp、UD-IQ4_XS、MTPなし | 42 | 約16 tok/s |
| Flash-Next、Strata、IQ3_S、MTPあり | 41 | 56〜59 tok/s |
| Qwen3.8 27B、llama.cpp、tensor分割 | 38 | 約43 tok/s |
| Gemma4 12B QAT、Ollama | 38 | 92〜102 tok/s |
| Flash-Next、Strata、IQ2_XS、MTPあり | 30 | 52〜57 tok/s |
IQ2では日本語の誤記や中国語字形の混入が見られた。IQ3はIQ4に近い点数だったが、2問・各1回で評価者も1つ。長い回答を好む偏りもあり得る。品質の同等性を実証したわけではなく、次に試す候補を選ぶための参考だ。
Gemma QATはQ4_0。92〜102 tok/sは公式27Bが常駐して生成していない状態で、Ollamaの既定設定とOpenAI互換APIから測った値だ。同居節の約59 tok/sはStrata常駐・ネイティブ生成APIであり、条件が違う。別試験では、Strata常駐下でスレッド数2・文脈32,768にしても60〜64 tok/sだった。92〜102との差の原因は切り分けていない。
MTPを切った比較はできなかった
Strataのサーバーモードは--spec T、--mtp DIR、--prefill CHUNKを必須としていた。無効化を試みたが起動せず、ネイティブなIQのpackにも--specが2以上という条件があった。
したがって、今回の速度差は次の要因を分離できていない。
- エンジンとExpertキャッシュ
- 量子化の差(Strataは2〜3.5ビット級、llama.cppは約4ビット)
- MTPによる投機的デコード
llama.cppでExpertのテンソルだけをCPUへ置く--n-cpu-moeなども試していない。最善の設定同士の比較ではない。速度測定も大半が1回〜数回で、ばらつきの統計は取っていない。
余談:27Bはtensor分割で速くなった
Strataとは別に、普段使いのQwen3.8 27Bをllama.cppで比較した。Q4_K_M、文脈上限131,072、画像入力ありの設定だ。
| GPUへの配置 | 定型出力の生成速度 |
|---|---|
| TITAN RTX 1枚 | 約28.3 tok/s |
| 2枚、layer分割 | 約29.3 tok/s |
| 2枚、tensor分割 | 約43〜44 tok/s |
数を並べる指示による256トークン生成の比較で、自由文の速度表とは別の測定だ。tensor分割は、各層の計算を2枚で分担する方式になる。
routerのmodels.iniでは次のように指定した。モデルのパスは利用する環境へ読み替える。
[qwen3.8-27b]
device = CUDA0,CUDA1
split-mode = tensor
model = /models/qwen3.8-27b/qwen3.8-27b.gguf
mmproj = /models/qwen3.8-27b/mmproj.gguf
ctx-size = 131072
flash-attn = true
fit = off
n-gpu-layers = 99
cache-type-k = q8_0
cache-type-v = q8_0
tensor分割では自動配置に対応せず、llama_params_fit is not implemented for SPLIT_MODE_TENSORとなった。fit = offとn-gpu-layers = 99を明示した。コンテナにもGPU2枚を見せる必要がある。共通設定の[*]をdevice = CUDA0にし、2枚を使うモデルだけ上書きした。
NVLinkが伸びに寄与した可能性はあるが、NVLinkなしとの比較はしていない。Strataについては、資料のRAM経由のGPU間転送という説明からNVLinkを使わないと推定しており、こちらも実測では切り分けていない。
運用で気をつけたいことと、次の確認
取得した版のStrataサーバーは1リクエストずつ処理する。思考が既定でオンのため、max_tokensを小さくすると思考だけで使い切り、最終回答が出ない場合がある。取得時の資料にはreasoning_budget_tokensによる調整も記載されていた。
起動時にはhuge pagesが使えない警告も出たが、設定した場合の性能差は未確認だ。モデル切り替えも、起動の約1分以外は体系的に測っていない。
今回確認できたのは、この構成での50トークン台の自由文生成、限定的な品質比較、合成長文からの目印回収、簡単な画像入力とツール呼び出しだ。次はOpenCodeなどの実用途で、入力処理を含む待ち時間、長時間の安定性、回答品質を確かめたい。

