RTX 5090とM4 MacBook Air:ゲームは可能か?
(scottjg.com)- M4 MacBook AirにRTX 5090 eGPUを接続し、Linux VMでゲームを実行。macOSのドライバ不在とThunderboltの制約を回避する必要があった
- 実装にはapple-dma-pci仮想PCIデバイス、DARTマッピング回避、kprobesベースのNVIDIAドライバパッチ、QEMU/HVF修正が必要だった
- Cyberpunk 2077はM4 Air + eGPUで4K RT Ultra 27fps、DLSSフレーム生成使用時は111fpsまで向上し、プレイ可能になった
- 同じRTX 5090を通常のPCIe PCに挿すと、ゲームによっては2〜4倍高速で、FEX・Proton・VM・Thunderboltのオーバーヘッドが大きく残る
- より大きな成果はAI推論で、M4 AirのQwen prefillは約100分の1に短縮され、単一ストリーム生成は約22 tok/sから155 tok/sへ増加した
Thunderbolt eGPUとApple Silicon Macの制約
-
Thunderbolt eGPUの構造
- RTX 5090のようなデスクトップGPUをThunderbolt dockに挿し、dockがPCIeをThunderboltへ変換してM4 MacBook AirのUSB-Cポートに接続する方式
- ThunderboltはUSB-Cケーブル上でPCIeをトンネリングするため、コンピュータ側からはThunderboltデバイスがUSBデバイスではなくPCIeデバイスとして見える
- Thunderbolt 4は最大40Gbpsの4本のPCIe laneを提供し、トンネリングによるわずかな性能損失がある
- 一般にLinuxやWindowsでは、eGPUは少し遅いPCIeデバイスとして認識され、既存ドライバでほぼそのまま動作する
- 最初の障害は、Apple Silicon macOSがNVIDIAやAMD GPUドライバを標準提供していないこと
-
Linux VMによる回避
- Apple Silicon MacでLinuxを動かすことは可能だが、現状のLinux kernelはApple Silicon上でThunderboltをサポートしておらず、内部デバイスとUSB3しか対応していない
- macOSホスト上で64ビットARM Linux VMを動かせば、macOSがThunderboltデバイスを処理し、LinuxがNVIDIA GPUを処理する構成が可能になる
- ARM64 Windows向けのNVIDIAカードドライバがないため、Linuxを使用した
- tinygradのmacOS eGPUドライバはtinygradスタック内でしか使えず、AI推論やゲーム実行向けの汎用ドライバには適していなかった
macOSでのPCIパススルー実装
-
PCI BARとDMA
- VMがPCI deviceと通信するには、PCI BAR(Base Address Registers) とDMAが動作する必要がある
- PCI BARはPCI deviceがコンピュータと読み書きするために使うメモリ領域で、PCIパススルーを動かすにはこの領域をVM内にmirrorする必要がある
- DMA(Direct Memory Access) は、deviceがCPUコピーなしにコンピュータのメモリを直接読み書きする方式
-
Hypervisor.frameworkとBARマッピング
- QEMUはVM起動時に
Hypervisor.frameworkのhv_vm_map()を呼び出してguest memory layoutを設定する - hostのPCIDriverKit driverに接続し、
IOConnectMapMemory64()でPCI device memoryをprocessにマッピングすると、BAR0 memoryを読み取れる BAR0[0]を読むと、RTX 5090を指すdevice-specific constantである0x1b2000a1が出力される- QEMUがdevice memoryをguestに直接マッピングすればguestがGPUと直接通信できるが、当初はVMがPCI BAR memoryに触れた瞬間にhost kernelがクラッシュした
- 原因は、QEMUがRAM-device/MMIO mappingにも
HV_MEMORY_EXECを付けることにあり、device/MMIO mappingではEXECを外すworkaroundでhost panicを回避した - この方式は、アクセスごとにtrapする方法より約30倍高速だが、
hv_vm_map()がARM device memory subtypeを指定できないため、BAR書き込みは通常時より約10倍遅い
- QEMUはVM起動時に
DMAとDART制約の回避
-
Apple SiliconのDARTの限界
- Apple SiliconにはIOMMUに似たDART hardware unitがあり、deviceが任意のhost memoryへアクセスできないようにするセキュリティ境界としても機能する
- PCIDriverKit経由でThunderbolt deviceを使う場合、3つの制約が大きかった
- 約1.5GBのmapping limitのため、CUDAや最新ゲームで必要な8〜16GB級のメモリマッピングをそのまま維持できない
- 約64k mapping capのため、小さなDMA bufferが多いとmapping tableが埋まる
- アドレスとalignmentを直接選べないため、guestがDMA addressを決めるvirtual IOMMU方式と相性が悪い
restricted-dma-poolでDMAを事前確保領域に強制する方式は単純なdeviceでは動いたが、GPU driverには適していなかった
-
apple-dma-pci仮想PCIデバイス- QEMUに**
apple-dma-pci**というvirtual PCI deviceを追加し、passed-through GPUとともにVMへ挿入した - guest kernel driverがNVIDIA driverのDMA mapping callを横取りし、DMA requestごとにon-demand mappingを作成、buffer解放時にmappingも解除する
- この構造では、guest RAM全体ではなく、その時点のlive DMA buffer working setだけが1.5GB limit内に収まればよい
- guest driverは、NVIDIA driverがGPUを使う前にcustom DMA opsへ差し替えられ、
map_page,unmap_page,map_sg,unmap_sg,alloc,freeを薄いwrapperで処理する - host側QEMUはrequestをPCIDriverKit driverへ渡し、このdriverが実際のDART mappingを行った後、DMA addressをguest memoryへ書き戻す
- QEMUに**
-
NVIDIAのalignment問題とkprobesパッチ
- CUDA workload実行中に
NV_ERR_INVALID_OFFSETとRM_PAGE_SIZE_HUGEのalignment関連kernel logが発生した - 問題のallocationは
UVM_RM_MEM_TYPE_SYS型の16MB allocationで、NVIDIA driverが2MB page sizeを使うことがalignment制約と衝突していた - driverには
NV_ERR_NO_MEMORY失敗時にdefault page sizeで再試行するworkaroundがあったが、NV_ERR_INVALID_OFFSETは処理していなかった - Linux kernelのkprobesを使い、
nvUvmInterfaceMemoryAllocSys()呼び出し時にpageSizeをUVM_PAGE_SIZE_DEFAULTへ強制した - NVIDIA driver自体を修正せず、小さいpage sizeを要求させることでsimple workloadを動作させた
- CUDA workload実行中に
-
Mapping coalescingによる64k cap回避
- ゲーム設定を上げるとtiny mappingが大量に発生し、約64k mapping count limitを超える
- mapping logでは90%以上のmappingが4kBで、連続ではないがcluster状に現れていた
- guest memoryを256kBなどのfixed-size regionに分割し、4kB bufferがmappingされる際にそのcluster全体をmappingして、以後同じclusterのallocationが既存mappingを再利用できるようにした
- この方式は実際のlive bufferよりやや多くのmemoryをmappingするが、テストworkloadでは約1.5GBのmapping ceiling以下に収まった
- live mapping数が約4分の1に減り、高負荷なゲームを最高設定で動かすためのheadroomが生まれた
VM性能の改善
-
vCPU scheduling
- benchmark scoreがランダムに大きく揺れ、ときどき50%遅く出る問題があった
- QEMUがvCPU threadにpriorityを設定しておらず、schedulerがVMへ十分な実行時間を与えていないように見えた
pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0)とpthread_setschedparam(..., SCHED_RR, ...)をQEMUのvCPU start pathにpatchして高priorityを与えた
-
Total Store OrderingとFEX-Emu
- VMはarm64 Linuxだが、流通しているゲームの多くはx86-64 Windows binaryなのでProton)とFEX-Emuを併用する
- x86は、storeがprogram orderどおりに他coreから見えるTotal Store Ordering(TSO) を使う一方、ARMはより弱いmemory ordering modelを使う
- Apple Siliconにはthread単位のhardware TSO modeがあり、macOS 15+の
Hypervisor.frameworkでこれが公開されている - UTMのpatchを取り込み、vCPUで
ACTLR_EL1bit 1を有効にし、FEX-Emuのsoftware TSO emulationを無効化した - hardware bitなしでsoftware TSO emulationを切ると、Geekbench 6は途中でクラッシュする
- FEXとCPU TSOを使ったguest performanceはnative host performanceより約50%低い
ゲーム性能
-
Cyberpunk 2077
- Cyberpunk 2077は、M4 AirネイティブmacOS、M4 Air + eGPU、2020 Intel MacBook Pro + eGPU、M5 MaxネイティブmacOS、M5 Max + eGPU、i5-12600K gaming PC + RTX 5090でテストされた
+ Framegenは、eGPU/ネイティブPCIe構成ではDLSS 4xを、ネイティブmacOS構成ではFSR 2xを使用する- 720p LowではGPU負荷が小さく、CPUとエミュレーション/仮想化オーバーヘッドが支配的で、M4 Airネイティブの61fpsがM4 Air + eGPUの49fpsを上回った
- 1080p HighではM5 MaxネイティブmacOSが131fpsで、M5 Max + eGPUの68fpsより速く、統合GPUで十分な条件ではオーバーヘッドの影響がより大きい
- M4 AirネイティブmacOSは1080p RT Ultraで7fpsにとどまったが、M4 Air + eGPUは30fps、フレーム生成使用時は119fpsを記録した
- 4KではGPUボトルネックが中心となり、M4 Air + eGPUはRT Ultraで27fps、DLSSフレーム生成使用時は111fpsを記録し、プレイ可能な水準に達した
- ネイティブPCIeのgaming PCは4K RT Ultraで100fps、DLSSフレーム生成使用時は282fpsで最速だった
- M5 Max + eGPUは4K RT Ultraで47fps、フレーム生成使用時は145fpsで、M4 Air + eGPUよりおおむね**30〜70%**速かった
-
その他のゲームとベンチマーク
- GravityMarkでは、同じGPUをPCIeスロットではなくThunderboltで接続すると性能が約**20%低下し、M4 Air + eGPUはネイティブPCIe接続より約31%**遅かった
- Shadow of the Tomb Raiderでは、eGPUによってM4 Airは4Kネイティブの8fpsから40fpsへ向上し、1080pもネイティブの26fpsからeGPUの42fpsへ改善した
- Shadow of the Tomb RaiderのeGPU性能は1080pと4Kでほぼ同じで、ボトルネックがGPUではなくFEX下のCPUにあることを示している
- Horizon Zero Dawn Remasteredは、最低の720p設定でも一度に1.5GBを超えるDMA memory mappingを要求し、ベンチマークを開始できなかった
- Doom (2016)はeGPU構成で動作し、性能オーバーレイでは49fpsを示し、常に30fps以上を維持した
- Crysis Remasteredはgaming PCより最大約4倍遅かったが、M4 MacBook Airでもプレイ可能なフレームレートで動作した
AI推論性能
-
Qwen 3.6
- Qwen 35B MoEモデルを4ビット量子化してテストし、有効パラメータは3B
- NVIDIA GPUではvLLMとNVFP4版を使い、Apple Siliconではvllm-mlxと4ビットMLX量子化モデルを使用した
- ベンチマークは
llama-benchyで実行された - Thunderbolt eGPUはPCIe比で約**9%**性能を失ったが、処理の大半がカード上で完結するため、PCIeにかなり近い性能だった
- RTX 5090は単一ストリーム生成で、M4 Airの6.5倍、M4 Max Mac Studioの2.1倍、M5 Max MacBook Proの1.2倍速かった
- 4Kトークンのプロンプトでは、M4 MacBook Airはprefillに17秒かかったが、同じM4 AirにeGPUを接続すると150msに縮まり、120倍高速化した
- 同時リクエストを1件から4件に増やすと、RTX 5090構成の総スループットは約3倍増加し、Apple Silicon Macはこれより低いスケーラビリティを示した
-
Gemma 4
- Gemma 4 31Bは疎なMoEではないdense 31Bモデルで、すべてのトークンが全パラメータを通過する
- M4 Airの統合GPUはテスト中毎秒2〜3トークンを超えられず、実用外と分類された
- vLLMベースのRTX 5090構成はすべて約50 t/s前後に収まり、数パーセント差以内だった一方、M4 Max Mac Studioは約22 t/s、M5 Max MacBook Proは約27 t/sを記録した
- prefillでもRTX 5090は常に400ms未満だったが、M4 Maxは4Kトークンのプロンプト解析に最大21秒、M5 Maxは約7.5秒かかった
- vLLM構成は4同時リクエストで約3.5倍のスループットを示したが、MacのMLX backendは4リクエストでもほとんど伸びなかった
直接実行の可否と安定性
-
配布とビルド条件
- 現状は「ダウンロードしてすぐ実行できる」段階ではなく、Appleの特別なentitlementが必要
- entitlementは申請済みだがまだ返答がなく、待ち時間が数か月に及ぶ可能性がある
- その間はdriverを自分でビルドでき、署名証明書アカウントに対象Macが含まれている必要がある
- SIPを無効化したりreduced security modeを使ったりする必要はない
- コードはqemu-vfio-appleで入手できる
- 同梱のlauncherは、特別な
apple_dmadriverが入った事前ビルド済みUbuntuイメージを自動ダウンロードする
-
安定性
- 安定性はまだ良くない
- FEXには現在Steamがループ状に頻繁にクラッシュするバグがあり、この構成では問題がより深刻に見える
- 特定のゲームは起動までに数分かかることがある
- DMA mapping上限のため、時間経過とともにmappingが断片化し、新しいゲームを実行する空きがなくなる可能性がある
- この場合はLinux VMを停止し、GPUを抜き差ししてDMA mappingをすべて消去したうえで再試行する必要がある
- 最も安定している用途はAIで、この用途では非常によく動作する
- upstream QEMUとの統合やパッチ取り込みを進めており、理想的にはUTMのようなQEMU系メインストリーム配布物に含まれ、そのまま動く形を目指している
1件のコメント
Hacker Newsの意見
何年ものあいだ VM チームに VM GPU パススルーを要望してきた。Apple Silicon Mac Pro の取り組みもしていたが、筐体内に入る GPU を Linux VM にパススルーできていたなら、ずっと筋が通っていたと思う。
残念ながら要望は受け入れられなかったが、他の人たちが動かしたのはすごい
結局のところ、QEMU のような仮想マシンモニタが Linux の VFIO のような仕組みに加えてこのインターフェースを採用すればよい話に見える。Virtualization.framework のことを指しているなら、それ自体が一種の仮想マシンモニタにかなり近いし、macOS に正確に何が欠けていると見ているのか気になる
最近では QEMU メインラインにも、Hypervisor.framework 配下の Linux ゲストで似た機能をサポートするため、virtio-gpu と一緒に "venus server" を使うパッチが入った。2 つ目は、Apple 内部には Virtualization.framework 向けの PCI パススルー対応があるらしいことだ。フレームワークのコード自体は顧客向けに配布されているが、通常の macOS には含まれない kext やカーネルコンポーネントに依存しているようだ。顧客に公開する意図があるのかは分からないが、Apple の中で誰かがこの機能を考えていたのは確かだ
いずれにせよ Mac Pro はもう死んだ製品だ。オーディオ・ビデオ専門家向けの販売だけでは限界がある
素晴らしい記事だ。ゲームベンチマークも面白いが、実用面では LLM 性能の改善が本当に興味深い部分だ。
Apple プラットフォームは RAM が多く、ローカルモデルを動かしやすいアクセスしやすい環境だが、相対的に遅いプロンプト処理速度はしばしば見過ごされる。記事の引用どおり、4K トークンのプロンプトでは M4 MacBook Air は応答生成を始める前のパースに 17 秒かかるが、eGPU を付ければ 150ms で終わり、120 倍速い。小さなチャットで LLM を触っていると prefill の問題は見えにくいが、より大きな作業に使い始めると演算限界がボトルネックになる。最初のトークンまでの時間(TTFT)のグラフも、一見それほど悪く見えないが、Mac プラットフォームが総 GPU 演算であまりに遅すぎて対数スケールで描かざるを得なかったと知ると意味合いが変わる
著者が結果をこういう出し方をするとバイアスがあるような印象を与えかねないが、実際にはそうではないと信じたい
OpenGL が macOS でもはや十分にサポートされていないため、ゲームが CrossOver でも完全にはプレイ不能だという部分は、そのとおりだと思う。
ただし Doom は Vulkan をサポートしているようで、MoltenVK に
VK_NV_glsl_shaderを追加すればいける可能性がある。M4 に RTX 5090 をぶら下げる作業よりは、はるかに少ない労力で済みそうだが、それでも Scott には拍手を送りたい。ローカル AI 推論速度もかなりすごいし、本当に狂気のプロジェクトだかなり印象的だ。私の認識では Apple Silicon では eGPU は単純に使えないはずだった。
Apple も同じ立場だ。「eGPU を使用するには Intel プロセッサ搭載の Mac が必要です。」しかも公式サポートの eGPU もすべて NVIDIA ではなく AMD だった。https://support.apple.com/en-us/102363
ここではその eGPU を Linux VM にトンネリングしている構成だ
最初は、遅い tinygrad ドライバで VM を動かす話かと思ったが、実際にはずっと良いアプローチだった。
Apple がもっと手厚くサポートして、1.5GB ウィンドウ制限を緩和してくれれば、ずっと簡単になるのにと思う。Arm には全般的に PCIe デバイスまわりの癖があるが、少なくとも Linux では最新ドライバの大半が arm64 を第一級市民として扱うようになって、かなり楽になった
推測だが、tinygrad が遅い大きな理由は、tinygrad の推論エンジンがこうした公開 LLM モデル向けにまだ十分最適化されていないからではないか。おそらく作業の大半は George の自動運転ハードウェア企業向けスタックの最適化に向けられているのだろう。既存の CUDA カーネルをそのエンジンでそのまま動かせるわけではないので、エンジニアリング難度はずっと高くなる。自分のプロジェクトが彼らと macOS ホストドライバを共有できるのかも気になる。多少の変更は必要だろうが、重なる部分はかなりありそうだ
「最近のほとんどのプロジェクトの第一歩は、認めたくはないが AI に聞くことだ」というくだりは、もっとありそうなのは AI が 自分でも分かっていないことを教えてくる、という意味になってしまう。
昨日 ChatGPT と 5070TI が実在するグラフィックカードかどうかで言い争ったことを思い出す。ChatGPT は、そんな 5070TI というカードは存在せず、4070ti の言い間違いに違いないと、しつこく訂正しようとしてきた
Claude に PowerShell 7 の HTML ページを作れと頼んだら、7.4 が最新の LTS リリースだと書いた。7.6 が 3 月にリリースされたというリンクを渡し、最新情報で作り直せと言ったのに、ほぼ同じページを作って 7.4 が最新リリースだという同じ主張を繰り返した
それでも元記事に対する ChatGPT の返答は正確そのものだった。「非常に深い」「ほぼ実用不能に近い」「研究観点では」という要約は、この記事そのものを完璧に言い表している
これは本当にすごい。余っている 5090 があって、M4 Mini で claw-like を動かしているのだが、安定性のために 3D プリントしたフレームのようなものに差し込み、TB ポートにつなげば、ローカル推論用としてかなり使える道具になるかもしれない。
電源供給のようなものをきちんと保証する装置は必要になる。問題は
max-num-seqsとmax-model-lenが互いに衝突することで、純粋な単一クライアントモードでないなら、いわば複数スロットが必要になる点だApple の承認さえ通れば、AI 推論にかなり有用そうだ。Mac Mini で NVIDIA GPU を使いたかったのだが、このやり方なら CUDA を直接動かせるようになる。本当にすごい