James O'Brien の SOTA LLM をローカルで実行するガイド(12 分読)
James O'Brien は、高価なハードウェア構成と BIOS/カーネル設定の秘密を公開し、個人や小規模チームが SOTA LLM をローカルで実行する具体的なロードマップを示している。
キーポイント
予算別の実装戦略
$2,000 で Qwen と高品質な音声認識、$40,000 でほぼ Opus レベルの性能を出すための明確なコスト対効果の分析。
高性能ハードウェア構成
前世代 EPYC プロセッサと中古 DDR4 メモリを組み合わせたベースシステムに、RTX PRO 6000 を 4 枚搭載し 384GB の VRAM を確保する構成案。
GPU ピアツーピア通信の最適化
PCIe スイッチとカスタムマウントを用いて GPU 間の直接通信を実現し、BIOS の bifurcation やカーネルパラメータ(iommu=off など)の詳細な設定手順。
電力制限と Docker 環境
$46,000 の機器を 110V 回路で安全に動作させるための電力制限設定と、すぐに実行可能なモデル serving 構成の提供。
ACS 無効化の必要性
デフォルトで有効な ACS (Access Control Services) を無効にしないと、P2P 通信が CPU ルートポートを経由して迂回し、スイッチファブリックの恩恵を受けられなくなるため。
パッチ不要の実行時対応
カーネルのパッチ適用を要する `pcie_acs_override` ではなく、`setpci` コマンドを用いて実行時に直接レジスタを書き換えることで ACS を無効化する。
ブート時の自動化
設定が永続化されるよう、作成したスクリプトを systemd oneshot サービスとして登録し、起動時に自動的に実行させる必要がある。
重要な引用
Have $2k burning a hole in your pocket and want some local, state-of-the-art machine intelligence?
If Dario and Altman are giving you heartburn (they should be), read on to figure out how to run this new kind of computing locally.
$40k gets you almost-Opus
With ACS enabled (default), P2P traffic gets bounced through the CPU root port instead of staying inside the switch fabric, negating the switch entirely.
`pcie_acs_override` requires a patched kernel, so we disable via setpci at runtime.
P2P through switch: 27.5 GB/s unidirectional / 50.4 GB/s bidirectional, 0.37–0.45 µs latency, i.e. Gen4 line rate.
影響分析・編集コメントを表示
影響分析
この記事は、大企業やクラウドプロバイダに依存せずとも、特定のハードウェア知識と投資があれば SOTA LLM をローカルで運用できる可能性を具体的に示しており、エッジ AI やプライバシー重視のユースケースにおける実装のハードルを下げる重要な指針となります。特に PCIe スイッチの設定や BIOS パラメータといった「隠れた技術的課題」への言及は、実務レベルでの導入を検討するエンジニアにとって極めて価値が高い情報です。
編集コメント
クラウド依存からの脱却を目指す開発者にとって、具体的なハードウェア選定と設定ノウハウが詰まった実用的なガイドです。ただし、$40k という高額投資が必要な点は、予算計画において慎重な検討を要します。
jamesob's guide to running SOTA LLMs locally
*注:この README の記述のうち、表以外の部分は AI によって作成されたものではありません。*
ポケットの中で燃え盛る 2,000 ドルを持っており、ローカルで最先端の機械知能を手に入れたいですか?
では、40,000 ドルはどうでしょう?
Dario や Altman に胸やけを感じているなら(感じるべきです)、この新しい種類のコンピューティングをローカルで実行する方法について読み進めてください。
このリポジトリには以下が含まれています。
- SOTA をローカルで実行するために私が使用するハードウェア、
何をなぜ購入したか、そして設定に関するあまり知られていない秘密、
- 音声認識(STT)をローカルで実行する方法、
私が良いと思うモデルを Docker コンテナ内で実行するためのすぐに使える構成。
目次
セクション
TL;DR
2,000 ドルで Qwen と良好な STT が手に入ります(かなり遠くまで!);40,000 ドルでほぼ Opus が手に入ります
前世代の EPYC + eBay の DDR4 で 5,600 ドル
RTX PRO 6000 を 4 台、VRAM 384GB(お金がどこへ行ったか)
c-payne.com からのインディー製 PCIe スイッチにより、GPU がピアツーピアで通信します
大工仕事に一日を費やす
BIOS の bifurcation(分岐)、リンク速度、ASPM
iommu=off または NCCL がハングアップする
P2P トラフィックをスイッチファブリック内に維持する
110V の回路に 46,000 ドル相当の半導体を稼働させる
Gen4 リンクルート: 27.5/50.4 GB/s、サブマイクロ秒レイテンシ
すぐに実行可能なサービング設定: GLM-5.2-594B: vLLM docker-compose、DCP4+MTP5、約 80 トークン/秒 @ 460k コンテキスト
whisper-large-v3 を使用したすぐに実行可能な音声認識設定
measure-gpu-speed.sh: P2P バンド幅/レイテンシベンチマーク
rtx6kpro リポジトリ、c-payne
私のセットアップ
私は運よく(あるいは無謀に)、まだ安かった頃に RTX Pro 6000 を 4 枚購入しました。現在は RAM の価格が高騰しているため、これらのカードをホストするために前世代の DDR4 システムを構築し、その部品は eBay で調達しました。これにより、ベースシステムの費用を適正に保ちつつ、多くの VRAM を確保することができました。
私が行ったもう一つのやや珍しい取り組みは、PCIe4 スイッチ(c-payne.com 製)を使用することでした。これにより、テンソル並列処理における allreduce ステップで GPU 同士が PCI ルート複合体を介してすべてのデータを送信する必要はなく、「直接」ワイヤードスピードで通信できるようになります。その結果、カード間のレイテンシが低減され、高価な PCIe5 ハードウェアへの依存度が下がります。
したがって、私は VRAM(特に重要な部分)にお金をかけることにし、PCIe5/DDR5 ベースシステムには投資していません。これは 2026 年 7 月現在、非常に高価な構成です。
私の特定の BOM(部品表)は以下に詳述されています。
いくらまでなら支払う気がありますか?
〜$2k
最適な選択肢の一つは、RTX 3090 を 2 枚使用し、合計で48GB の VRAMを確保することです。これにより、素晴らしいモデルである Qwen3.6-27B を実行できます。
また、whisper-large-v3 を使用して SOTA(State-of-the-Art)の音声認識(STT: Speech-to-Text)を実行することも可能です。私はこのモデルを非常に有用だと感じています。これはモデルそのものであり、その後、私のクロスプラットフォーム stt ハーネス を通じてアクセスします。
ローカルでの STT は予想以上に有用であることがわかりました。ホスト型の同等サービスとは異なり、私は安心して使用できます。Nvidia GPU で約 11GB の VRAM があれば動作する、すぐに実行可能な設定ファイルが ./runners/stt に用意されています。
〜$40k
この価格帯では、モデルの知能において次のステップアップが得られます。Claude Opus に非常に近い性能です。
4 枚の RTX 6000 Pro を購入し、合計で384GB の VRAM(ビデオメモリ)を確保します。
4x RTX6kPRO 向け現在の最良モデル
日付
最良モデル
私の構成
2026-07
GLM-5.2-Int8Mix-NVFP4-REAP-594B
その他のアプローチ
注:これらは私の推奨事項ですが、お金を使う他の完全に有効な方法も存在します。例えば、RTX 6000 Pro を 4 枚入手するのではなく、予算の大部分を リンクされた 4x DGX Spark クラスター の構築に割り当て、合計 512GB の VRAM を確保し、それを「遅いが巨大な脳」として活用して Qwen3.7-27b を駆使し、単純作業を高速で処理させるという運用も考えられます。
ハードウェア
4x RTX 6000 Pro マシン用に私が実際に購入したハードウェアは以下の通りです。
ベースシステム
eBay でほぼ全て部品単位で購入した、控えめな前世代の EPYC システムです。
コンポーネント
仕様
価格
マザーボード
ASRock Rack ROMED8-2T (SP3, 7× PCIe 4.0 x16, デュアル 10GbE)
$715
CPU
AMD EPYC Milan 7313P (16 コア 3.0GHz)
$504
RAM
8× 16GB Crucial CT16G4RFD4213 DDR4 ECC RDIMM (合計 128GB、eBay)
$642
CPU クーラー
Dynatron T17 SP3 タワー、280W TDP
$40
ケース
AAAWave Sluice V2 オープンフレーム
$100
PSU (電源ユニット)
2× Super Flower 1700W
$750
PCIe スイッチ
c-payne Microchip Switchtec PM40100 Gen4(後述のサブ BOM を参照)
~$1,330
Boot NVMe
4TB M.2
$291
ストレージ NVMe
(2x) 8TB M.2 (モデル重み)
$1,200
ファン
3× 120mm PWM
$15
合計
$5,587
GPUs
コンポーネント
仕様
価格
GPUs
4× NVIDIA RTX PRO 6000 Blackwell Workstation (各 96GB、VRAM 総量 384GB)
約 $46,000
c-payne PCIe Gen4 スイッチ サブ BOM (c-payne.com)
部品
数量
単価 (€)
備考
PCIe gen4 Switch 5× x16 — Microchip Switchtec PM40100
1
1.050
2× SlimSAS 8i アップストリーム、5× x16 クワッド幅間隔ダウンストリーム、補助 x4 SlimSAS、3× 8-pin EPS 電源
SlimSAS PCIe gen4 ホストアダプター x16 — REDRIVER AIC (DS160PR810)
1
140
ROMED8-2T の x16 スロットに挿入し、スイッチへアップストリームを供給
SlimSAS SFF-8654 8i ケーブル — PCIe gen4
2
約 30
各々 x8 を伝送; ペアで x16 アップストリーム
合計
€1,220 ($1,330 USD)
GPU マウント
PCI スイッチと GPU のために木製の筐体を自作する必要があり、それには約 1 日かかりました。
PCI スイッチに内蔵されたファンが非常にうるさく、かつ実用的でないように思えたため、私は単にそのファンのケーブルを基板から抜きました。
モデル重みの収集
すべてのモデル重みは、2 つの 8TB ドライブ間でレプリケートされる ZFS ファイルシステム上にローカルで保存しており、これは ~/storage にマウントされています。
実行したいモデルがある場合、まず以下のようにしてモデルをダウンロードします:
hf download <model-name> --local-dir ~/storage/<model-name>
モデルの実行
モデル重みがローカルにキャッシュされたら、各モデルごとに特定のディレクトリを用意し、そこには docker-compose.yml ファイルが含まれています。これにより、各モデルの実行がそれぞれの Docker コンテナに隔離されます。
これらの設定は ./runners/ で確認できます。
各コンテナは、私がローカルにキャッシュした重み(weights)を取得するために、読み取り専用モードで ~/storage/models にマウントされます。
その後、http://clank.j.co:5000 上でモデルがサービス提供されるようになったら、別のマシン上の VM でホストされている opencode を使用してモデルにアクセスします。
私はネットワーク内部の DNS サーバーを使用して clank.j.co を LLM マシンへポイントしていますが、単に http://<llm-machine-ip>:5000 とするだけでも構いません。
ハーネスそのもの
私は VM を作成し、VM の ~/src ツリー内の各ディレクトリに対して tmux セッションを1つずつ作成し、それぞれが推論マシンの HTTP API(http://clank.j.co:5000)にバックアップする opencode インスタンスを実行するようなアプリケーションを clanked しました。
オープンソースモデルを良好な状態にするための鍵は、適切なツールリングを行うことです。私のスキル/の要約は以下の通りです:
- ウェブブラウジングと検索には camofox、kagi.com API キー、および searXNG を使用し、
- 通信とアラートには Telegram ボットを使用し、
- ソースコードでの共同作業にはローカルプライベート Gitea インスタンスを使用します。
この clanker は、セッション内で私と対話的に動作するか、Gitea の課題(issues)の解決や PR の提出のために遠隔で処理させることも可能です。
これらすべてはサンドボックス化された VM 内で行われ、ホストシステムへの通信は共有ファイルシステムマウントを介してのみ行われるため、このマシンは制限なく何でもインストールできます。
PCI スイッチの正常な動作確保
マザーボードが PCI スイッチの速度を降格させないようにするために、BIOS で多くの調整を行いました。
BIOS 設定 (ROMED8-2T)
設定 | 値 | 理由
---|---|---
チップセット構成 → AMD PCIE リンク幅 (スロット用) | x16 (以前は x8/x8) | バイファケーションによりスロットが分割されており、アップストリームリンクが Gen4 x8 でトレーニングされていました。SlimSAS 8i ケーブルを両方接続する必要があります (それぞれ x8 を伝送)。
PCIe リンク速度 (スロット用) | Gen4 (自動ではなく) | Blackwell Gen5 デバイスが Gen4 スイッチを通じて自動ネゴシエーションで降格すると、トレーニングに失敗して Gen1 に落ちる可能性があります。Gen4 に強制することで安定化します。
ASPM | 無効 | ASPM L1 はアイドルリンクを 2.5GT/s に下げます。これが「Gen1 に降格した」という lspci の読み取り結果の説明となりました — リンクは実際には負荷下で Gen4 で動作していました (p2pBandwidthLatencyTest で検証済み) が、ASPM を無効化することで見かけ上の警告と再トレーニングの遅延を排除できます。
Re-Size BAR | 有効 | 96GB VRAM の BAR エクスposure と GPU P2P に必要です。
SR-IOV | 無効 | ベアメタル推論のため、IOMMU オーバーヘッドや P2P 干渉を回避します。
Preferred IO | 自動 | 任意で手動設定し、バス番号 81 (c-payne スイッチ) にすることでわずかなレイテンシの改善が得られますが、自動のままにしました — これは最適化のための微調整であり修正ではなく、BIOS 変更後にバス番号が変動するためです。
Redriver のゲインを低下させる
c-payne のアドバイスに従い、彼のツール を使用してゲインを「lvl 3」に下げました。これはおそらくプロセスの中で最も厄介な部分でした。
ゲインレベルは、SAS コネクタケーブルの長さに依存します。
適切な SAS ケーブルの選択
c-payne から直接ケーブルを少なめに注文してしまい失敗したので、Amazon で同じ SAS ケーブルだと思って購入しました。しかし実際にはわずかな違いがあり問題が発生したため、再注文せざるを得ませんでした。正しい製品かどうか必ずダブルチェックしてください!
カーネル / GRUB パラメータ
/etc/default/grub
GRUB_CMDLINE_LINUX="iommu=off amd_iommu=off nomodeset"
sudo update-grub
nvidia_uvm P2P 修正
echo 'options nvidia_uvm uvm_disable_hmm=1' | sudo tee /etc/modprobe.d/uvm.conf
sudo update-initramfs -u
iommu=off を指定しないと、NCCL (NVIDIA Collective Communications Library) がマルチ GPU P2P (Peer-to-Peer) でハングアップします。
ACS 無効化(スイッチ P2P に必須)
ACS (Access Control Services) が有効なデフォルト設定では、P2P トラフィックが CPU ルートポートを経由して迂回され、スイッチファブリック内で完結しないため、スイッチの効果が完全に無効化されてしまいます。pcie_acs_override はパッチ済みカーネルを必要とするため、ここではランタイムで setpci を使用して無効化します。
/usr/local/bin/disable-acs.sh
#!/bin/bash
if [ "$EUID" -ne 0 ]; then
echo "ERROR: must be run as root"
exit 1
fi
for BDF in $(lspci -d "*:*:*" | awk '{print $1}'); do
setpci -v -s ${BDF} ECAP_ACS+0x6.w > /dev/null 2>&2
if [ $? -ne 0 ]; then
continue
fi
echo "Disabling ACS on $(lspci -s ${BDF})"
setpci -v -s ${BDF} ECAP_ACS+0x6.w=0000
done
systemd oneshot を使用して、起動時に毎回実行してください:
/etc/systemd/system/disable-acs.service
[Unit]
Description=Disable PCIe ACS for GPU P2P
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/disable-acs.sh
[Install]
WantedBy=multi-user.target
検証:lspci -vvv | grep ACSCtl を実行すると、すべての値がマイナス記号(-)で表示されるはずです。また、nvidia-smi topo -m を実行すると、4 つの GPU 間の接続が PIX(PCI Express Switch)として表示され、PHB/NODE ではないことを確認できます。
この測定は ./tools/measure-gpu-speed.sh ツールを使用すると簡単に実施できます。
GPU パワー制限
220V の回路を設置するのを避けるため、私は(おそらく無謀にも)このシステムを単一の 110V 回路で稼働させていますが、GPU カードのパワーは規制しています。
ブート時に systemd を介して永続化モードとパワーキャップを適用します(install-gpu-power-limit.sh スクリプトを使用):
sudo nvidia-smi -pm 1
sudo nvidia-smi -pl 350 # GPU あたり 350W(デフォルトは 600W)
GPU あたり 350W = GPU負荷合計 1,400W で、PSU の予算に合わせて設定されています。中間段階として単一の 1700W PSU を使用していた時期(240V 回路導入前)には、カードは約 260W で動作していました(4×260 = GPU 合計 1,040W + システム約 280W ≒ 総消費電力 1,320W)。
検証:nvidia-smi --query-gpu=index,power.limit,power.draw --format=csv を実行します。
結果
アップストリーム(標準):Gen4 x16(CPU への転送速度約 30 GB/s)。スイッチを介した P2P(Peer-to-Peer、ピアツーピア)通信:双方向 50.4 GB/s、単方向 27.5 GB/s、レイテンシ 0.37–0.45 µs、つまり Gen4 のラインレートです。注意:ASPM(Active State Power Management、アクティブステートパワーマネージメント)がどこかで有効になっている場合、アイドル時に lspci で GPU リンクが「2.5GT/s(ダウングレード済み)」と表示されることがありますが、これは外観上の問題に過ぎません。負荷がかかるとリンクは Gen4 に再トレーニングされます。
リソース
- 4 枚、6 枚、または 8 枚の RTX 6000 Pro カードを最大限活用する方法について頻繁に更新されているリポジトリ:https://github.com/local-inference-lab/rtx6kpro
- 私が使用しているインディペンデントな PCI スイッチ:https://c-payne.com
- RTX6kPRO の Discord サーバーでは、多くの人がベンチマークや新モデルのテストを行っています:https://discord.gg/QMNvFkuDN
原文を表示
jamesob's guide to running SOTA LLMs locally
*Note: nothing in this README aside from the tables was written by AI.*
Have $2k burning a hole in your pocket and want some local, state-of-the-art machine
intelligence?
How about $40k?
If Dario and Altman are giving you heartburn (they should be), read on to figure out
how to run this new kind of computing locally.
In this repo you'll find
- the hardware I use to run SOTA locally,
why I bought what and little-known secrets for configuring it,
- how I run speech-to-text (STT) locally,
- ready-to-run configuration for running models I think are good within Docker containers.
Contents
Section
TL;DR
How much are you willing to spend?
$2k gets you Qwen and good STT (pretty far!); $40k gets you almost-Opus
Last-gen EPYC + eBay DDR4 for $5.6k
4× RTX PRO 6000, 384GB VRAM (where the money went)
Indie PCIe switching from c-payne.com so GPUs talk peer-to-peer
A day of carpentry
BIOS bifurcation, link speed, ASPM
iommu=off or NCCL hangs
Keep P2P traffic inside the switch fabric
Running $46k of silicon on a 110V circuit
Gen4 line rate: 27.5/50.4 GB/s, sub-µs latency
Ready-to-run serving configs: GLM-5.2-594B: vLLM docker-compose, DCP4+MTP5, ~80 t/s @ 460k ctx
Ready-to-run speech-to-text config with whisper-large-v3
measure-gpu-speed.sh: P2P bandwidth/latency benchmark
rtx6kpro repo, c-payne
My setup
I was lucky/dumb enough to buy 4x RTX Pro 6000s back when they were cheaper. Because
RAM is now so expensive, I opted to build a last-gen DDR4 system to host these cards,
the parts for which I got off eBay. This allowed me to keep base system cost reasonable
while still getting a lot of VRAM.
Another somewhat unusual thing I did was to use PCIe4 switches (from
c-payne.com). This allows the GPUs to communicate to one another
"directly" at wire speeds during the allreduce step in tensor parallelism, rather than
having to send all data through the PCI root complex. The upshot of this is reduced
latency between the cards with less of a need for expensive PCIe5 hardware.
Consequently, I'm spending money on VRAM (where it counts) rather than on a PCIe5/DDR5
base system, which is terrifically expensive as of July 2026.
My particular BOM is detailed below.
How much are you willing to spend?
~$2k
A great way to go is 2x RTX 3090s for a total of 48GB VRAM total. You can then run
Qwen3.6-27B, which is an awesome model.
You can also run SOTA speech-to-text (STT) with
whisper-large-v3, which I find very
useful. That's the model - you'd then access it with my cross-platform [stt
harness](https://github.com/jamesob/stt).
I've found local STT surprisingly useful - and I feel comfortable using it, unlike a
hosted equivalent. You can find a ready-to-run config in
./runners/stt that only assumes the presence of ~11GB of VRAM on an
Nvidia GPU.
~$40k
At this price level, you get the next step up in model intelligence. Something pretty
close to Claude Opus.
You'd buy 4x RTX 6000 Pros for a total of 384GB of VRAM.
Current best models for 4x RTX6kPRO
Date
Best model
My config
2026-07
GLM-5.2-Int8Mix-NVFP4-REAP-594B
Other approaches
Note: these are my recommendations, but there are other completely valid ways to spend
your money. For example, there's probably also some regime where rather than getting 4
rtx6kpros, you allocate most of your money to building out a [linked 4x DGX Spark
cluster](https://youtu.be/QJqKqxQR36Y?si=MiKNYtIzut_5pnXy) for a total of 512GB VRAM
and use that as the slow, big brain to drive Qwen3.7-27b to do the rote tasks quickly.
Hardware
Here's the hardware I wound up purchasing for the 4x RTX 6000 pro machine.
Base system
A modest, last-gen EPYC system purchased in parts almost entirely from eBay.
Component
Spec
Price
Motherboard
ASRock Rack ROMED8-2T (SP3, 7× PCIe 4.0 x16, dual 10GbE)
$715
CPU
AMD EPYC Milan 7313P (16-core 3.0GHz)
$504
RAM
8× 16GB Crucial CT16G4RFD4213 DDR4 ECC RDIMM (128GB total, eBay)
$642
CPU Cooler
Dynatron T17 SP3 tower, 280W TDP
$40
Case
AAAWave Sluice V2 open frame
$100
PSUs
2× Super Flower 1700W
$750
PCIe Switch
c-payne Microchip Switchtec PM40100 Gen4 (see sub-BOM below)
~$1,330
Boot NVMe
4TB M.2
$291
Storage NVMe
(2x) 8TB M.2 (model weights)
$1,200
Fans
3× 120mm PWM
$15
Total
$5,587
GPUs
Component
Spec
Price
GPUs
4× NVIDIA RTX PRO 6000 Blackwell Workstation (96GB each, 384GB VRAM total)
~$46,000
c-payne PCIe Gen4 Switch Sub-BOM (c-payne.com)
Part
Qty
Unit (€)
Notes
PCIe gen4 Switch 5× x16 — Microchip Switchtec PM40100
1
1.050
2× SlimSAS 8i upstream, 5× x16 quad-width-spaced downstream, aux x4 SlimSAS, 3× 8-pin EPS power
SlimSAS PCIe gen4 Host Adapter x16 — REDRIVER AIC (DS160PR810)
1
140
Plugs into ROMED8-2T x16 slot, feeds switch upstream
SlimSAS SFF-8654 8i cable — PCIe gen4
2
~30
Each carries x8; pair = x16 upstream
Total
€1,220 ($1,330 USD)
GPU mount
I had to custom fabricate a wood enclosure for the PCI switch and GPUs, which took
about a day.
I found the PCI switch's builtin fan very loud and seemingly useless, so I simply
unplugged that from the board.
Hoarding model weights
I save all model weights locally on a ZFS filesystem that's replicated across the two
8TB drives, which is mounted at ~/storage.
For any model I want to run, I first download the model using
hf download <model-name> --local-dir ~/storage/<model-name>
Running models
Once the model weights are cached locally, I have a specific directory for each model
that contains a docker-compose.yml file that cordones off the running of each model
to its own Docker container.
You can find these configurations in ./runners/.
Each container mounts in ~/storage/models in read-only mode to obtain the weights
that I've cached locally.
I then use opencode hosted on a VM on another machine to access the models once
they're serving on http://clank.j.co:5000.
I use a network-internal DNS server to point clank.j.co to the LLM machine, but you
could simply do http://<llm-machine-ip>:5000 too.
The harness itself
I created a VM and clanked up an application that basically just creates a tmux session
for each directory within the VM's ~/src tree, which then runs an opencode instance
that backs up to the inference machine's HTTP API (http://clank.j.co:5000).
One key to making the opensource models good is tooling them properly; a summary of my
skills/ is:
- camofox, kagi.com API key, and searXNG for web browsing and search,
- Telegram bot for communication and alerting,
- a local private Gitea instance for collaborating on source code.
The clanker will either work with me interactively in a session, or can be farmed off
to work on Gitea issues and file PRs there.
All this happens in a sandboxed VM where the only communication back to the host system
happens via a shared filesystem mount, so the thing can go ham and install whatever it
wants.
Getting the PCI switches to work properly
There was a lot of fiddling with the BIOS in order to make sure the motherboard wasn't
downregulating the PCI switch speeds.
BIOS Configuration (ROMED8-2T)
Setting
Value
Why
Chipset Configuration → AMD PCIE Link Width (switch slot)
x16 (was x8/x8)
Bifurcation was splitting the slot; upstream link trained at Gen4 x8. Requires both SlimSAS 8i cables connected (each carries x8).
PCIe Link Speed (switch slot)
Gen4 (not Auto)
Blackwell Gen5 devices auto-negotiating down through the Gen4 switch could fail training and fall to Gen1. Forcing Gen4 stabilizes it.
ASPM
Disabled
ASPM L1 drops idle links to 2.5GT/s. This turned out to be the explanation for the "Gen1 downgraded" lspci readings — links were actually running Gen4 under load (verified via p2pBandwidthLatencyTest), but disabling ASPM removes the cosmetic scare and any re-train latency.
Re-Size BAR
Enabled
Required for full 96GB VRAM BAR exposure and GPU P2P.
SR-IOV
Disabled
Bare-metal inference; avoids IOMMU overhead and P2P interference.
Preferred IO
Auto
Optionally set Manual → bus 81 (the c-payne switch) for marginal latency gains, but left at Auto — it's a squeeze-more optimization, not a fix, and bus numbers shift after BIOS changes.
Reducing gain on the redriver
Per c-payne's advice, I did reduce the gain to "lvl 3" using [his
tool](https://c-payne.com/c-payne-tool), which was probably the most finicky part of
the process.
The gain level is going to be a function of how long your SAS connector cables are.
Picking the right SAS cables
I screwed up and ordered too few of the cables from c-payne directly, so I bought what
I thought was the same SAS cable off of Amazon. There was actually a slight difference
that was causing issues, and I had to reorder cables - so double-check that you're
getting the right stuff!
Kernel / GRUB Parameters
# /etc/default/grub
GRUB_CMDLINE_LINUX="iommu=off amd_iommu=off nomodeset"
sudo update-grub
# nvidia_uvm P2P fix
echo 'options nvidia_uvm uvm_disable_hmm=1' | sudo tee /etc/modprobe.d/uvm.conf
sudo update-initramfs -uWithout iommu=off, NCCL hangs on multi-GPU P2P.
ACS Disable (critical for switch P2P)
With ACS enabled (default), P2P traffic gets bounced through the CPU root port
instead of staying inside the switch fabric, negating the switch entirely.
pcie_acs_override requires a patched kernel, so we disable via setpci at runtime.
# /usr/local/bin/disable-acs.sh
#!/bin/bash
if [ "$EUID" -ne 0 ]; then
echo "ERROR: must be run as root"
exit 1
fi
for BDF in $(lspci -d "*:*:*" | awk '{print $1}'); do
setpci -v -s ${BDF} ECAP_ACS+0x6.w > /dev/null 2>&1
if [ $? -ne 0 ]; then
continue
fi
echo "Disabling ACS on $(lspci -s ${BDF})"
setpci -v -s ${BDF} ECAP_ACS+0x6.w=0000
doneRun on every boot via systemd oneshot:
# /etc/systemd/system/disable-acs.service
[Unit]
Description=Disable PCIe ACS for GPU P2P
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/disable-acs.sh
[Install]
WantedBy=multi-user.targetVerify: lspci -vvv | grep ACSCtl should show all minus signs, and
nvidia-smi topo -m should show PIX between all four GPUs (not PHB/NODE).
Use ./tools/measure-gpu-speed.sh to measure this easily.
GPU Power Limiting
In order to avoid installing a 220V circuit, I (probably unwisely) run this rig on a
single 110V circuit, but I power regulate the cards.
Persistence mode + power cap applied at boot via systemd
(install-gpu-power-limit.sh):
sudo nvidia-smi -pm 1
sudo nvidia-smi -pl 350 # 350W per GPU (default 600W)350W/GPU = 1,400W GPU load, sized for the PSU budget. During the interim
single-1700W-PSU phase (before the 240V circuit), cards ran at ~260W
(4×260 = 1,040W GPUs + ~280W system ≈ 1,320W total).
Verify: nvidia-smi --query-gpu=index,power.limit,power.draw --format=csv
Result
Upstream: Gen4 x16 (~30 GB/s to CPU). P2P through switch: **27.5 GB/s
unidirectional / 50.4 GB/s bidirectional, 0.37–0.45 µs latency**, i.e. Gen4 line
rate. Note: lspci may still show downstream GPU links as "2.5GT/s (downgraded)"
at idle if ASPM is active anywhere; this is cosmetic. Links retrain to Gen4
under load.
Resources
- A frequently updated repo on getting the most out of 4, 6, or 8 RTX 6000 Pro cards: https://github.com/local-inference-lab/rtx6kpro
- Indie PCI switches that I use: https://c-payne.com
- RTX6kPRO discord server; lotta guys benching and testing new models: https://discord.gg/QMNvFkuDN
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み