前提
本記事は、Open Source Summit Japan | LF Events の「Dynamic GPU Provisioning in Kubernetes With Composable Disaggregated Infrastructure」にて紹介されていたCDIとそのCDI上のKubernetesでGPUを扱うためのOSS「CoHDI」についての話です。
関係者ではないため間違っていたらすみません。その際はコメント頂けますと幸いです。
CDI(Composable Disaggregated Infrastructure)
CPUやメモリー、ストレージ、GPUなどの各デバイスをPCIe/CXL(PCIeをベースに策定された新規格)といった規格で統一し、リソースプール化し、ソフトウェア定義によって必要な時に必要な分だけ組み合わせて「Composed Baremetal」と呼ばれるベアメタルサーバを動的に構成する技術のことを言います。
これにより、ワークロードによって柔軟に構成を変更し、貴重なGPUの無駄を減らす動かし方もできそうです。
PRIMERGY CDIのカタログはこちら。

https://www.fsastech.com/ja-jp/products/primergy/solution/cdi/ より引用
※PRIMERGY CDIでのメモリのプール化は2026年、CPUのプール化は2027年以降を予定とのこと
このようなメモリモジュールをPCIe Gen 5.0(CXL 2.0)にブスッと挿して使うようです(画像のメモリの製品は発表者のFujitsu sanとは別のプロダクトです)。

https://www.businesswire.com/news/home/20240423215157/ja より引用
CDIでは、CDI Managerという管理ソフトが存在し、PCIe/CXLスイッチを制御して ベアメタルを作成しており、ユーザはCDI APIを通じて任意の構成のベアメタルを作成できます。

https://static.sched.com/hosted_files/ossjapan2025/e6/OSSJ2025_CoHDI.pdf の4ページ目より引用
構成としては、PCIeファブリックスイッチ for CDIでPCIe Box for CDIにあるGPUと計算サーバのCPUを繋いでいるようです。

https://www.fsastech.com/ja-jp/products/primergy/solution/cdi/ より引用
CXL(Compute eXpress Link)には、キャッシュコヒーレンシ(キャッシュ整合性)とCXL.memという筐体の外にあるメモリプールをCPUが直接管理するメモリとして高速・低レイテンシで認識・利用できる機能があるようです。
現状のPCIeでは、基本的にキャッシュコヒーレンシを提供しないため、CPU/GPU間で同じメモリを整合性を保って共有する用途に向かない特徴があります。
例えば、現状のDMA(Direct Memory Access)だとコヒーレンシを保った共有が難しいようです。
CXLでは、キャッシュ整合性を保つプロトコルを備えており、CPUとGPUがお互いのメモリを自分の手元のメモリのように直接参照・更新できる特徴があります。
特に、Transformerを使ったLLMでは、推論時にKVキャッシュが重要となるためCXLのキャッシュ整合性の仕組みが効いて来るようです
Exploring CXL-based KV Cache Storage for LLM Serving(NeurIPS 2024)では、VRAMに入りきらないKVキャッシュをCXLによる増設DRAMに置くことでGPU再計算に比べバッチサイズが30%増えたとのこと
※ こちらの結果は、あくまで研究のため実際は試してみないとわからないところではあります
- CXLの詳細については、2025年のCXLの動向について や PCI expressを進化させた次世代インターコネクト規格CXLの紹介 にて記載されています。
CoHDI(Composable Hardware Disaggregated Infrastructure)
CoHDIは、CDIの技術をKubernetes(以下、k8s)環境に統合し、GPUなどのデバイスを利用可能にするためのOSSプロジェクトです。
k8sのDRAについて
k8sには、DRA(Dynamic Resource Allocation, 動的リソース割り当て)というv1.34でGAになったGPUやFPGAなどのデバイスのリソース量を柔軟に指定できる仕組みがあります。
ResourceClaimをDRAが受け取り、ResourceSliceに登録された利用可能なGPUといったデバイスリストからk8sのPodにデバイスを割り当てます。

画像はGemini Nano Banana Proで作成したイメージ図
CDIを扱う上での現状のDRAの問題点
大きく2つあります。
- k8sのスケジューラは、原則として各ノードに物理的に接続されているデバイスしか認識できない問題
- Resource poolのGPU情報を取得してリスト化する機能が必要
- 仮に認識できたとしても、GPUがノードに接続される前にk8sがGPUを使おうとしてエラーになる問題
- GPUがノードに接続されるまで、k8sのschedulerが待つ仕組みが必要
※補足:Dynamic GPU Provisioning in Kubernetes with
Composable Disaggregated Infrastructureの発表資料の32p目、「Future Challenges」では、将来的に Intel GPU / CXL memory をサポート対象に挙げています。
CXLメモリも「外部リソースを必要な時にノードへ追加する」点ではGPUと似た課題が出る可能性もあり、ResourceSliceでの公開方法や、OS側のhot-add、Kubernetes側の整合設計も論点になりそうです。

画像はGemini Nano Banana Proで作成したイメージ図
これらのDRAの問題を解決するOSS「CoHDI」
CoHDIの構成コンポーネント
以下の3つで構成されます。
- Composable DRA Driver
- Dynamic Device Scaler(以下、DDS)
- Composable Resource Operator(以下、CRO)
また、KEP-5007:DRA: Device Binding Conditions という外部リソース(ファブリック接続されたGPU、FPGAなど)の準備が整うまでPodのバインディングを延期する仕組みも利用しています。
※ DRADeviceBindingConditionsは、v1.34、v1.35でAlphaのfeature gateです。
CoHDIの流れ
流れはこちらの公式のgifが一番わかりやすいです

https://github.com/CoHDI/.github/blob/main/profile/how_cohdi_works.gif より引用。以下の画像は本gifから切り取ったものです。
1.リソースプール内GPUをResourceSliceとして公開
Composable DRA Driverが、CDIのGPUプールをみて今プールに空いているGPUが何枚あるかをResourceSliceとしてk8sに登録します。
これにより、DRAの問題である原則として各ノードに物理的に接続されているデバイスしか認識できない問題を解決します。
2.ResourceClaim(ユーザのGPUの要求仕様)付きのPodが作られる
3.Podがスケジュール対象になる
Podはk8sのschedulerに渡されて、配置先ノードを決めるフェーズに入ります。
4. schedulerがResourceClaimに対して候補となるGPUを割り当てる
schedulerは、ResourceClaimとResourceSliceを突き合わせて、このResourceClaimにはこのGPUを割り当てるということを決めます。
この時点では、まだデバイスは利用できる状態ではないため、Preparingとなります。
5. Dynamic Device ScalerがResourceClaimがまだPreparingであるかを監視する
6. Dynamic Device ScalerがComposable Resource OperatorにGPUのアタッチを依頼
7. Composable Resource OperatorはCDI APIを叩きに行く
ここからはCDI製品内部の話。
8. CDIがGPUをnode1に物理アタッチする
9.ノード上のGPUとリソースプール内GPUの両方をResourceSliceとして更新・公開する
GPUがノードに刺さったら、k8sに見える情報も更新する必要があります。
- ノード側
- OSが認識したGPUを
DRA driverが拾い、node1のResourceSliceにGPUを載せる
- OSが認識したGPUを
- プール側
- free poolからGPUが1枚減ったので、リソースプール(free pool)の
ResourceSliceも更新
- free poolからGPUが1枚減ったので、リソースプール(free pool)の
10. Dynamic Device ScalerがResourceClaimをReadyに更新してアタッチ完了を宣言
この状態になることで、待っていたPod側がGPUを使えると判断でき、次の処理へ進めます。
11. schedulerがPodを再スケジュールし、ResourceClaimの内容をクリアする
ResourceSlice(at free pool)からResourceSlice(at node1)になったのでPodを再スケジュールして、ResourceClaimの情報を更新します。
12. schedulerがResourceClaimに対して、ノード上GPUを正式に割り当てる
ここでようやく通常のDRAと同じように、物理的にnode1に刺さっているGPUとResourceClaimが一致するようになりました。
13. Podがnode1にデプロイされ、動的にアタッチされたGPUを利用する
ここではschedulerはもう仕事が終わっていて、Podがnode1上で起動(Deployed) しGPUを使えるようになりました。
めでたし。めでたし。
いかがでしたでしょうか。殿山の個人的な感想ですが、DRAを拡張した革新的な仕組みに思いました。
今後の期待
ベアメタルレベルで柔軟に再構成できるという強みをCDI及びCoHDIに感じることができました。とはいえ、従来までのDRAとはHWレベルで仕組みが異なるため、リプレイスするのであればかなり大変そうな道のりにもなりそうです。その他、現状、NVIDIA DriverはCoHDIのようにGPUのホットプラグは想定していないそうなのでその対応も待つ必要がありそうです。
余談:CDI 系のOSS
Sunfish(OpenFabrics / 旧OFMF)というCDI向けにRESTful APIと標準化データモデルを提供するOSSもあるようでした。
CoHDIでは、Sunfish等も使っているため、CoHDI自体はCDI APIとDRAのインテグレーションを実現する立ち位置のOSSのようです。1
このSunfishはRedfish API仕様の拡張として設計されているようです。
Redfishは、IPMIToolやベンダー固有の管理ツールをAPIを通して標準化しようという試みです。
謝辞
-
情報を提供して頂きました。@everpeace san ありがとうございます。 ↩