モデル別実行レシピ

2台のMacでMLX-JACCLを使う:分散設定と検証条件

Macを接続する前に、分散実行の前提条件を確認しましょう。

Macを接続してもメモリが自動的に一つのプールになるわけではありません。MLX1 JACCLは、OS・Thunderbolt/RDMA topology・host設定・モデルの分散経路が対応している場合にデバイス間通信を行います。2台のhostを設定し、2-rank smoke testを確認してから、モデル配置を調べ、同じworkloadで単一Macと比較します。

実行条件と要点
  • JACCLは通信backendであり、すべてのMac・OS・network topologyを自動対応するものではありません。
  • MLX/MLX-LMのversion、macOS、network interface、model sharding対応を合わせます。
  • throughputや遅延を測る前にログでデバイス配置を確認します。
  • 同じpromptとmodel設定で1台と2台を比較します。

最初に確認すること:メモリ合算ではなく分散実行

大きなモデルファイルが1台のMacに収まらない場合、Macを2台つなげばメモリ容量を単純に合算できると思いがちです。しかし分散推論では、モデルのtensorの一部を各デバイスに配置し、計算中にデバイス間でデータをやり取りします。どのtensorをどこに置くか、runtime2がその分割に対応するか、通信コストが計算上の利点を打ち消さないかによって結果が変わります。ストレージやunified memory3の数値を足しても、実行可否は予測できません。

このガイドでは、Apple MLXのJACCL backendとMLX-LM4の分散生成経路を確認します。JACCLは通信層であり、それ自体がモデルの分割方式ではありません。MLX 0.30.6ではJACCLとMLX-LMの分散serverに関する変更が発表されましたが、あらゆるMac構成に共通する高速化率や互換性表が示されたわけではありません。ここで扱うのは設定と検証の手順であり、再現済みbenchmarkではありません。

開始前に、両方のMacがApple silicon搭載で、同じローカルnetworkから互いに接続でき、使用するMLX/MLX-LM versionがJACCL経路を提供することを確認します。MLX 0.30.6のJACCL更新に記載された条件であるmacOS 26.3以降も確認してください。管理対象端末やpublic Wi-Fiでは、許可なくnetwork権限やfirewall policyを変更せず、管理者の指示に従います。

短いケーブルで接続された2台のMacデスクトップ
ケーブル接続だけでは推論が分散されたことになりません。

まず両方のMacのversionとnetworkを確認する

このJACCL経路では、2台のMac miniをThunderbolt cableで接続し、MLXのRDMA setup toolでhostfileを作成してから、`mlx.launch`で小さな分散testとMLX-LMの例を順に実行します。MLX公式guideによると、自動setupはnode間のSSH、RDMAの利用可否、Thunderbolt meshを確認します。接続がfull meshでない場合、Ethernetのみの場合、OSが非対応の場合はJACCLを無理に使わず、MLXが説明するring/Ethernet方式か単一Macへ戻してください。

2台のMacで互いのhostnameを解決でき、passwordless SSHが使え、Pythonとtest scriptが同じpathに存在する必要があります。JACCLの`--auto-setup`は各端末でpasswordless sudoを必要とし、Thunderbolt network設定を変更します。管理対象Macで許可されない場合は`--auto-setup`を省略し、表示されたcommandを確認して管理者の承認を得てください。JACCLの条件を満たすには、インストール済みMLXがmacOS 26.3以降で動作する必要があります。

以下の手順はnetworkやkernel設定を変更する可能性があるため、専用のtest端末で実行してください。最初から大きなmodelを起動せず、まずprocess groupが2 rankとして認識されることを確認します。両方のlogにrank 0/1と`size=2`が表示されるまでは、実際の推論に進まないでください。

2台のMacを確認してJACCL接続を設定する
# Run on both Macs; replace the hostnames with names configured for SSH.
sw_vers
python3 --version
python3 -m pip show mlx mlx-lm
ssh mac-mini-2 'python3 --version && python3 -m pip show mlx mlx-lm'
mlx.distributed_config --verbose --hosts mac-mini-1,mac-mini-2 --over thunderbolt --dot
mlx.distributed_config --verbose --backend jaccl --hosts mac-mini-1,mac-mini-2 --over thunderbolt --auto-setup --output hosts.json
ホスト名は実際のSSH設定に合わせて変更してください。auto-setupはThunderboltネットワーク設定を変更するため、専用のテスト機で実行します。

小さなtestで分散実行を検証する

hostfileができたら、MLX公式docsの形式で小さなrank checkを行い、両端末に同じPythonとtest scriptがあることを確認します。JACCLではhostfileに2 rankを接続するRDMA device情報が必要です。生成されたfileを編集する場合は、実際の配線に対応するRDMA device名とrank順を確認してください。

最初は小さく実行できるmodelと短いpromptを使います。model fileのdownload先、各processのrank、すべてのhostが接続したかをlogで確認します。回答が生成されたことだけでは、分散実行成功の証明になりません。デバイスごとのメモリ使用量と配置を確認してください。errorが起きた場合は両processを停止し、port、address、versionを一つずつ比較します。

rank checkで`rank=0 size=2`と`rank=1 size=2`が表示されれば、2 processの分散groupが作られたことは確認できますが、modelが分割された証明ではありません。次にMLX distributed guideのMLX-LM chat例を実行し、modelが両デバイスに分割されているかlogを確認します。利用するmodel architectureが指定した分散分割に対応することを公式docsで確認してください。launcherが起動しただけではshardingの証明になりません。

rankを確認して公式MLX-LM例を実行する
mlx.launch --verbose --backend jaccl --hostfile hosts.json -- python3 -c 'import mlx.core as mx; g=mx.distributed.init(backend="jaccl"); print(f"rank={g.rank()} size={g.size()}")'
mlx.launch --verbose --backend jaccl --hostfile hosts.json -- python3 -m mlx_lm chat --model mlx-community/DeepSeek-R1-0528-4bit
最初のcommandで両rankの起動を確認します。2つ目はMLX guideの分散chat例です。このmodel/runtimeの組み合わせがshardingに対応するか、実際の配置を各nodeのlogで確認してください。
2台のコンピューター間の接続と分割された重みブロック
両hostのログでデバイス参加と通信を確認します。

同じpromptで1台と2台のMacを比較する

baselineを作る際は、model versionとweights、quantization5、prompt、最大出力長、sampling設定を固定します。1回は単一Mac、もう1回は2台の分散経路で実行します。初回のmodel loadにはdownloadと初期化が含まれるためcold startとして別に記録し、準備後のrequestをwarm状態で繰り返します。

完了時間だけでなく、最初のtoken6までの時間、出力token数と生成速度、各Macのmemory・GPU/CPU使用量、network traffic、errorやretryも記録します。回答内容が異なる場合は、速度を比較する前にrandom seed、sampling、tokenizer、templateが一致するか確認します。分散実行では計算配置と通信の両方が変わるため、入力長と出力長によって効果が異なる場合があります。

たとえば、短い回答はnetwork経由で遅くなり、長い回答でのみ差が現れると仮定します。その場合は平均値一つで判断せず、短いinteractive queryと長いbatch jobを別々に記録してください。これはworkloadの比較方法を示す仮定であり、MLXの測定結果ではありません。

実行可能かどうかと運用上の利点を分けて確認します。
段階記録項目通過基準
接続OS・package・address・rankのlog両processが互いを検出する
配置デバイス別memoryと処理log意図したmodel分割とデバイス参加を確認
正確性同じpromptの出力とtoken数回答品質と完了状態が許容範囲内
性能TTFT・完了時間・memory・転送量実際のworkloadで運用の複雑さを上回る利点がある

実行可能かどうかと運用上の利点を分けて確認します。

接続

記録項目
OS・package・address・rankのlog
通過基準
両processが互いを検出する

配置

記録項目
デバイス別memoryと処理log
通過基準
意図したmodel分割とデバイス参加を確認

正確性

記録項目
同じpromptの出力とtoken数
通過基準
回答品質と完了状態が許容範囲内

性能

記録項目
TTFT・完了時間・memory・転送量
通過基準
実際のworkloadで運用の複雑さを上回る利点がある
1台に載せたモデルと2台に分けたモデルの比較
同じworkloadで分散実行と単一Mac基準を比較します。

失敗時はnetworkと分割条件を順に切り分ける

相手の端末が見つからない場合は、両Macが現在同じnetworkにあるか、routerが端末間通信を許可しているか、firewall・VPN・security softwareが接続を遮断していないか確認します。firewallを無効化するのではなく、OSのblock logや管理者policyを確認してください。port番号は現在のMLX commandと公式docsで調べ、推測でportを開かないでください。

接続できても初期化に失敗する場合は、package version、macOS条件、rank数、address設定を比較します。メモリ不足なら、実際の重みサイズとデバイスごとの配置を、context/KV cacheや他アプリの使用量から分けて確認します。networkを高速にしても重みが各デバイスへ均等に分配されるわけではありません。

実行できても遅い場合は、どの段階で遅延しているかを特定します。modelが小さく通信costが計算上の節約を上回る場合や、promptが短く分散setupの負担が大きい場合は、単一Macのほうが速い可能性があります。分散serverが安定しない、または速度差が一貫しない場合は、単一Mac経路を運用上のdefaultにしてください。

公式実装ドキュメントとrelease note

このガイドにはデバイス別の性能測定はありません。JACCLの対応範囲と実行optionは、インストール済みMLX/MLX-LM versionの公式docs、release note、help出力で確認してください。macOSやnetwork環境を変更した場合は、小さな例で再検証します。

用語の注釈

  1. MLX — Appleが開発する機械学習フレームワークです。Apple siliconでは統合メモリとMetalを活用し、別途Linux向けの実行経路も提供します。対応モデルや機能はMLXを使うツールごとに異なります。

    本文に戻る
  2. ランタイム — プログラムの実行時に必要な機能を提供するソフトウェア環境です。ローカルAIではモデル実行エンジンを指すこともあり、GPUランタイムライブラリと完成したサービングアプリは別の構成要素です。

    本文に戻る
  3. ユニファイドメモリ — CPUとGPUが同じ物理メモリ領域を共有する構造です。メモリ総量が増えるわけではなく、利用可能量はシステムによります。

    本文に戻る
  4. MLX-LM — MLXを使い、言語モデルの読み込み・推論・微調整を行うパッケージです。MLXフレームワーク本体や、MLXを使うすべてのアプリを指す言葉ではありません。

    本文に戻る
  5. 量子化 — モデルの数値を少ないビット数で表す方法です。メモリ使用量のほか、精度や実行速度も変わることがあり、影響は形式と実装によります。

    本文に戻る
  6. トークン — モデルが入力や出力を分けて処理する単位です。1トークンが1文字や一定の時間に相当するわけではありません。

    本文に戻る