Slide 1

Slide 1 text

Kubernetes で作る AI プラットフォーム Oracle Cloud Hangout Cafe - Season 10 #1 古⼿川 忠久 2025年6⽉11⽇ ⽇本オラクル株式会社

Slide 2

Slide 2 text

Copyright © 2025, Oracle and/or its affiliates 2 はじめに https://www.oracle.com/customers/cohere-case-study/ AIが要求する膨⼤なワークロードを円滑に処理するGPUの 役割は計り知れませんが、それを全てオーケストレーションする Kubernetesの役割も同様に重要です。 「Kubernetesは私たちのあらゆる業務を⽀えています」

Slide 3

Slide 3 text

Copyright © 2025, Oracle and/or its affiliates 3 学習編 • クラスタ、ネットワーク & ストレージ • ジョブ管理 - Volcano • デモ 推論編 • 概説 • 推論フレームワーク - KServe • デモ まとめ Agenda OCI Kubernetes Engine (OKE)で実現する 超スケーラブルなAIプラットフォーム 古⼿川 忠久 2025年5⽉23⽇ ⽇本オラクル株式会社 Oracle Developer Day 2025 Oracle Developer Day 2025 のセッションがベースになっているので いつもより若⼲ Oracle 依存の話が多めです 😅

Slide 4

Slide 4 text

Copyright © 2025, Oracle and/or its affiliates 4 ⾃⼰紹介 古⼿川 忠久 ⽇本オラクル株式会社 クラウド・ソリューション統括 @tkote_ tkote oracle-japan @tkote クラウド・ネイティブな勉強会 (OCHaCafe) の世話役︖をやっています...

Slide 5

Slide 5 text

学習編 5 Copyright © 2025, Oracle and/or its affiliates

Slide 6

Slide 6 text

クラスタ、ネットワーク & ストレージ 6 Copyright © 2025, Oracle and/or its affiliates

Slide 7

Slide 7 text

OCI GPUラインアップ 7 Copyright © 2025, Oracle and/or its affiliates Bare Metal 192 GB GPU Memory 4 x L40S GPU.L40S.4 VM & Bare Metal 320 GB GPU Memory 8 x A100 40GB GPU.4.8 100 Gb/sec Front-end network VM & Bare Metal 24 GB 48 GB GPU Memory GPU.A10.1 GPU.A10.2 GPU.A10.4 1 x A10 2 x A10 Bare Metal 768 GB GPU Memory 72 x B200 192GB GPU.GB200.4 NVL72 (18 servers/rack) 7,200 Gb/sec Front-end network 36 x Grace CPU Bare Metal 1,128 GB GPU Memory 30.7 TB Local NVMe 200 Gb/sec Front-end network 8 x H200 141GB GPU.H200.8 Bare Metal 1,536 GB GPU Memory 30.7 TB Local NVMe 400 Gb/sec Front-end network 8 x B200 192GB GPU.B200.8 Bare Metal 640 GB GPU Memory 8 X A100 80GB GPU.A100-v2.8 Bare Metal 8 x H100 80GB GPU.H100.8 640 GB GPU Memory 61.4 TB Local NVMe 100 Gb/sec Front-end network 4⽉GA 1.7 TB CPU+GPU Memory 15.3 TB Local NVMe 4⽉GA Bare Metal 8 x MI300X 192GB GPU.MI300X.8 1,536 GB GPU Memory 30.7 TB Local NVMe 100 Gb/sec Front-end network Bare Metal 2,304 GB GPU Memory 8 x 2 B300 288GB GPU.B300 NVL16 予約受付中 Bare Metal 20.7 TB GPU Memory 72 x B300 GPU.GB300.4 NVL72 (18 servers/rack) 7,200 Gb/sec Front-end Network 36 x Grace CPU 38.7 TB CPU+GPU Memory 553 TB Local NVMe 予約受付中 ⼩ → ⼤規模 3,840GPU 800 Gb/sec RDMA 1,600 Gb/sec RDMA 200 Gb/sec Front-end network 100 Gb/sec Front-end network 32,768GPU 16,384GPU 3,200 Gb/sec RDMA 16,384GPU 65,536GPU 131,072GPU 131,072GPU 28,800 Gb/sec RDMA 6,400 Gb/sec RDMA 57,600 Gb/sec RDMA OCI Object & File Storage FSS HPMT—20/40/80 Gb/sec per MT | Managed Lustre—1 Gb/sec per TB AI向けストレージ AI向けネットワーク: OCI Supercluster

Slide 8

Slide 8 text

GPUを最⼤限活⽤するクラウド基盤︓OCI Supercluster™ クラウド最⼤規模単⼀GPUクラスタにより、AIの学習時間を⼤幅に短縮し、コストも削減 8 Copyright © 2025, Oracle and/or its affiliates ⾼性能ベアメタルGPUサーバー: • NVIDIAのリファレンス設計に従ったベアメタルGPUサーバー • 最⼤131,072GPU*で単⼀のクラスタを構成 • ⾼いAI学習性能を実現し、かつ実装コストも削減 ⾼速ストレージ: • GPUへのデータ⼊⼒、また学習時のチェックポイントを⾼速に • 最⼤61.4TBのローカルNVMe SSDストレージを搭載 • さらに、⾼性能な共有ストレージ・サービスも提供 超低遅延/⾼帯域ネットワーク: • GPUサーバー間を数μs、最⼤28.8Tbpsの⾼帯域で接続 • RoCEv2 RDMAネットワークを実装してパフォーマンスをスケール • AI学習時間の短縮が可能 RDMA: Remote Direct Memory Access RoCEv2: RDMA over Converged Ethernet version 2 *OCI Supercluster scales up to - 131,072 NVIDIA B200 GPUs - 65,536 NVIDIA H200 GPUs - 16,384 NVIDIA H100 GPUs - 32,768 NVIDIA A100 GPUs OCI Supercluster: 最⼤131,072GPU*を搭載した 超⼤規模 単⼀GPUクラスタ

Slide 9

Slide 9 text

Supercluster にはどの OKE ワーカー・ノードを使う? Oracle Kubernetes Engine (OKE) のノード種別 • 管理対象ノード (Managed Nodes) – ノード・プールで利⽤可能なGPUシェイプも若⼲あり • テナンシのコンピュート・インスタンス(ベア・メタルまたは仮想マシン)で実⾏される • 管理対象ノード・プール上に作成される • 管理対象ノードおよび管理対象ノード・プールはユーザーが管理する • 仮想ノード (Virtual Nodes) – GPUのサポートなし • 「サーバーレス」な Kubernetes エクスペリエンスを提供、ノード管理の運⽤オーバーヘッドを軽減 • 仮想ノード・プール上に作成される • 仮想ノードおよび仮想ノード・プールは、Oracleによって完全に管理される • ⾃⼰管理ノード (Self-Managed Nodes, or Bring Your Own Nodes "BYON") • ワーカー・ノードをユーザー⾃⾝で管理する (OCI の API では作成できない) • カスタマイズ性が⾼いため、特定の要件に応じた環境を構築したい場合に適す 9 Copyright © 2025, Oracle and/or its affiliates Supercluster 上の GPU ノードを OKE のワーカー・ノードとして組み込む

Slide 10

Slide 10 text

OKE ワーカー・ノードを Supercluster に配置する⽅法 Supercluster 上のコンピュート・インスタンスを OKE のワーカー・ノードとして組み込む ⾃⼰管理ノードは… • コンピュート・インスタンス(またはインスタンス・プール)でホストされる • ノード・プールにグループ化されない 10 Copyright © 2025, Oracle and/or its affiliates # ⾃⼰管理ノードは (現状) OCI コンソールから確認する⼿段がない... $ kubectl get nodes NAME STATUS ROLES AGE VERSION 10.0.22.162 Ready node 89m v1.31.1 10.0.22.225 Ready 41m v1.31.1 10.0.22.50 Ready node 93m v1.31.1 # ⾃⼰管理ノードの検索 $ kubectl get nodes -l oci.oraclecloud.com/node.info.byon=true NAME STATUS ROLES AGE VERSION 10.0.22.225 Ready 13m v1.31.1 # 管理対象ノードの検索 $ kubectl get nodes -l oci.oraclecloud.com/node.info.managed=true NAME STATUS ROLES AGE VERSION 10.0.22.162 Ready node 61m v1.31.1 10.0.22.50 Ready node 66m v1.31.1 OKE 拡張クラスタ Supercluster (RDMA) NW VCN NW インスタンス・プール ノード・プール OCI Container Engine Instance Pools Managed Node Managed Node Self Managed Node Self Managed Node Self Managed Node ⾃⼰管理ノードを Supercluster ネットワーク上に 作成したインスタンス・プールに配置する例 File Storage ノード・ラベルで 識別可能 RDMAに対応した⾃⼰管理ノードは、 OKE Quick Start (Terraform) (後述)で作成 ポイント︕

Slide 11

Slide 11 text

Supercluster に対応した OKE クラスタの構成 ⾃⼰管理ノード (Compute Instance Pool) 上で RDMA 対応した Pod を動かすためには︖ Kubernetes の標準構成では (OKE も然り) ... • Pod は NIC を1つしか持てない • そのままでは RDMA 通信できない Terraform OCI module for OKE • OKE クラスタをプロビジョニングするための基本的な Terraform スクリプトを提供 • Network • Cluster • Node Pool • Virtual Node pool • Instance (⾃⼰管理ノード) • Instance Pool • Cluster Network 11 Copyright © 2025, Oracle and/or its affiliates シェイプ OCPU GPUメモリー CPUメモリー ローカル・ディスク 最⼤ネットワーク帯域幅 最⼤VNIC合計 BM.GPU.H200.8 (GPU: 8xH200) 112 1128GB 3072GB 8 x 3.84TB NVMe 1 x 200Gbps 8 x 400Gbps RDMA 256 File Storage Bare Metal Compute eth0 rdma0 rdma1 rdma2 rdma3 rdma4 rdma5 rdma6 rdma7 RDMA Network Pod Network https://oracle-terraform-modules.github.io/terraform-oci-oke/guide/deploy.html ワン・クリックで OCI コンソールの”スタック”画⾯にジャンプ RDMA 対応の⾃⼰管理ノード・クラスタを簡単にプロビジョニング 上記をスクラッチで作るには以下のプラグインを ⾃分で導⼊・構成する必要があります... • Multus CNI plugin • SR-IOV network plugin • SR-IOV CNI plugin どうすればいいの︖ … さらに…

Slide 12

Slide 12 text

Quick Start: リソース・マネージャ (Terraform) によるスマートなプロビジョニング GPU & RDMA クラスタ対応の All-In-One OKE Terraform スクリプト RDMA 接続を備えた GPUノードで構成される OKEクラスタ ”⼀式” をデプロイするための Terraformスクリプトを提供 • GitHub 上で公開 - github.com/oracle-quickstart/oci-hpc-oke • リソース・マネージャのコンソールからオプションを選んで要件に合わせた環境を構築 12 Copyright © 2025, Oracle and/or its affiliates OCI Resource Manager = Terraform を使って OCI のリソースを定義・プロビジョニング・管理することができる IaC(Infrastructure as Code) のためのサービス

Slide 13

Slide 13 text

リソース・マネージャ (Terraform) によるスマートなプロビジョニング Quick Start スタック (Terraform 構成ファイル群)の 変数編集UIで構成オプションを簡単設定 13 Copyright © 2025, Oracle and/or its affiliates • GPU Kubernetes環境の作成 - ポリシー - VCN - Bastion / Operator インスタンス - OKE クラスタ - OKE ワーカー・ノード (Operational, CPU, GPU/RDMA) - ストレージ (NVMe, Block Volume, FSS) • RDMA/GPU モニタリング - Prometheus - Grafana - Node Exporter - K8s Metrics Server - DCGM Exporter - Node Problem Detector ⾊々と罠があるので README をよく読んで 作業を⾏なって下さい︕ & 適宜カスタマイズして下さい GPU/RDMA向けにカスタマイズ / カスタム・プラグインを提供 • インポートしたイメージを使う • RDMA なら CNI は Flannel • ...

Slide 14

Slide 14 text

GPU のモニタリング Prometheus & Grafana の監視環境 • NVIDIA Data Center GPU Manager (DCGM) - GPU を管理および監視するためのツール スイート • DCGM-Exporter – GPU関連のメトリクスを Prometheus にエクスポーズする • https://github.com/NVIDIA/dcgm-exporter/ • Grafana ⽤のダッシュボード • https://grafana.com/grafana/dashboards/12239-nvidia-dcgm-exporter-dashboard/ 14 Copyright © 2025, Oracle and/or its affiliates Quick Start の Terraform でプロビジョンすると Grafana のモニタリング環境までセットアップしてくれる︕ Grafana の画⾯

Slide 15

Slide 15 text

GPU & RDMA クラスタのヘルスチェック Node Problem Detector • ノードで発⽣した問題の概要を即時に把握 by ノードの Condition (条件) の変更、Event (イベント) の通知 • kubectl describe node で状態を確認可能 • Prometheus exporter もあり • Quick Start では GPU & RDMA クラスタ向けのカスタム・プラグインを提供 15 Copyright © 2025, Oracle and/or its affiliates Name Description GpuCount Checks if the node has the expected number of GPUs available GpuEcc Checks for GPU ECC errors GpuRowRemap Checks for GPU Row Remapping Errors GpuBus Checks if any GPU has fallen off the bus GpuPcie Checks if PCIE has the expected bandwidth GpuFabricManager Checks if Fabric Manager is running GpuBadPages Checks if any AMD GPU has bad pages RdmaLink Checks if RDMA links are up RdmaLinkFlapping Checks if there's any RDMA links that are flapping RdmaWpaAuth Checks if all RDMA interfaces are authenticated RdmaRttcc Checks if RTTCC is disabled on the RDMA interfaces OcaVersion Checks if node has the correct Oracle Cloud Agent version CpuProfile Checks if the CPU profile is set to performance Quick Start の Terraform でプロビジョンすると Node Problem Detector もセットアップしてくれる︕ Grafana の画⾯

Slide 16

Slide 16 text

Pod アプリケーションから GPU を利⽤するには? NVIDIA Device Plugin アドオン • NVIDIA Device Plugin for Kubernetes • Kubernetes デバイス・プラグイン・フレームワークのNVIDIA実装 • Daemonsetをデプロイ - 各ワーカー・ノードにNVIDIA GPUの数を公開し、それらのGPUの健全性を追跡 • nvidia.com/gpu リソースタイプを使⽤してコンテナからGPUを要求できるようになる • OKE では、クラスタ・アドオンとして提供 • 拡張クラスタで利⽤可能な Kubernetes クラスタの機能をサポートおよび拡張するソフトウェア 16 Copyright © 2025, Oracle and/or its affiliates * (余談) GPU が搭載されたノードには Taints: nvidia.com/gpu=present:NoSchedule が設定されているので、GPU の有無に関わらず Pod を デプロイしたい場合 (含 deployment/daemonset) は tolerations を spec に記述する必要あり︕ (例) tolerations: - operator: "Exists" # Taints 完全無視 Quick Start の Terraform でプロビジョンすると Device Plugin アドオンもセットアップしてくれる︕ (外すオプションもあり)

Slide 17

Slide 17 text

RDMA ネットワークのトポロジーと Pod 配置の最適化 ネットワーク・ローカリティ情報を使って分散学習のパフォーマンスを最⼤化 ネットワークのトポロジーが分かれば、可能な限り近接するノードに Pod を配置してネットワーク遅延を最⼩化できる • OCI のベアメタルGPUインスタンスでは、ネットワーク・ローカリティに 関するメタデータ情報を取得可能 • OKE では以下のラベルをノード起動時に付与する → nodeAffinity や podAffinity で利⽤可能 17 Copyright © 2025, Oracle and/or its affiliates curl -H 'Authorization: Bearer Oracle' ¥ http://169.254.169.254/opc/v2/host/rdmaTopologyData { "customerHPCIslandId": "ocid1.hpcisland.oc1.iad.anuwcljrg5py...", "customerHostId": "ocid1.computebaremetalhost.oc1.iad.anuwcl...", "customerLocalBlock": "ocid1.computelocalblock.oc1.iad.anuwc...", "customerNetworkBlock": "ocid1.computenetworkblock.oc1.iad.a..." oci.oraclecloud.com/rdma.host_id = ab3zs7y7v7q oci.oraclecloud.com/rdma.hpc_island_id = af7ubvouuyq oci.oraclecloud.com/rdma.local_block_id = 4tjxbt4s6ua oci.oraclecloud.com/rdma.network_block_id = 7xmzl4p4wba Supercluster の詳しい解説 (blog) https://blogs.oracle.com/cloud-infrastructure/post/first-principles-zettascale-oci-superclusters Host ID Local Block ID Network Block ID HPC Island ID max 2 μs max 5 μs max 8 μs

Slide 18

Slide 18 text

OKE ノード・ラベルを使った Pod の最適配置 nodeAffinity podAffinity (スケジューリングの計算処理⼤) 18 Copyright © 2025, Oracle and/or its affiliates rdma.local_block_id, rdma.network_block_id, rdma.hpc_island_id affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: oci.oraclecloud.com/rdma.local_block_id operator: In values: - 5tjxbt5s6ua - weight: 50 preference: matchExpressions: - key: oci.oraclecloud.com/rdma.network_block_id operator: In values: - 7xmzl5p5wba - weight: 25 preference: matchExpressions: - key: oci.oraclecloud.com/rdma.hpc_island_id operator: In values: - af7ubvouuyq affinity: podAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - pod-affinity-app topologyKey: oci.oraclecloud.com/rdma.local_block_id - weight: 50 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - pod-affinity-app topologyKey: oci.oraclecloud.com/rdma.network_block_id - weight: 25 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - pod-affinity-app topologyKey: oci.oraclecloud.com/rdma.hpc_island_id

Slide 19

Slide 19 text

Pod ネットワーキングの考慮点 hostNetwork: true • Pod 内のコンテナはホスト(Kubernetes ノード)と 同じネットワークインターフェースとIPアドレス を使う • オーバーレイ・ネットワークをバイパスするのでオーバーヘッドが⼩さく、レイテンシも低い • 制約される点もあり – e.g. ホスト上で既に使われているポートは使えない 19 Copyright © 2025, Oracle and/or its affiliates spec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet Pod のスペックのパート ✖ ✖ ※ OCI Native Pod Networking で適⽤すると、ワーカー・ノードの Primary vNIC とその IPアドレスがアサインされるので注意

Slide 20

Slide 20 text

Pod ネットワーキングの考慮点 OCI Native Pod Networking CNI plugin (⾃⼰管理ノードは利⽤不可) • 各 Pod に専⽤の vNIC が割り当てられ、OCI の Virtual Cloud Network(VCN)に直接接続される • Flannel のようなオーバーレイ・ネットワーク(VXLANなど)を使わないため、オーバーヘッドが⼩さく、レイテンシも低い 20 Copyright © 2025, Oracle and/or its affiliates Flannel オーバーレイ・ネットワーク (VXLAN) OCI Na've Pod Networking • L2のフレームをL3(IP)ネットワーク上でカプセル化してトンネリング • ノード間の通信は UDPを使⽤ • Native Pod Networking ⽤の vNIC をノードに追加 • Pod に割り当てるための複数のセカンダリ IPアドレスをこの vNIC に関連付ける (ノード・プール作成時に、Native Pod Networking ⽤のサブネットを指定する) • 各Pod は、作成時に空いているセカンダリ IPアドレスが割り当てられる Primary vNIC Primary vNIC ※ CNI = Container Network Interface

Slide 21

Slide 21 text

Pod ネットワーキングの考慮点 複数NIC・複数GPU・複数ノード環境 最適な NIC 選択や経路設定が必要 • GPU 間通信 (ノード内) – NVLink (⾼速 GPU インターコネクト) 優先、なければ PCIe • ノード間通信 (ノード間) - InfiniBand (RDMA over IB) や⾼速 Ethernet (RoCEv2) を使⽤ • どの NIC 経由で通信するか? NCCL(NVIDIA Collective Communication Library) • NVIDIA が提供する GPU 間の⾼速通信ライブラリ • モデルの重みや勾配をやりとりする通信処理(AllReduceなど)を効率化 • GPU 間のトポロジー(PCIe、NVLink、RDMA ネットワークなど)を検出し、最適な通信経路を⾃動構築 NCCL Test • NCCL通信のパフォーマンスと正常性を確認するツール • Quick Start に Volcano (後述) を使って OKE クラスタ上で NCCL Test を⾏う⼿順あり 21 Copyright © 2025, Oracle and/or its affiliates

Slide 22

Slide 22 text

OCI Region Customer DC Availability Domain VCN Public Subnet GPU Subnet bastion host GPU Instance User … GPU Instance RoCEv2 Interconnect Object Storage Service Gateway Internet Gateway Storage Subnet File Storage ストレージの基本パターン – Object Storage と File Storage • Object Storage: スケーラブルかつ⾼い耐障害性、⼤容量学習データを効率的に格納 • File Storage: フルマネージドの弾⼒的なエンタープライズグレードのNFSストレージ・サービス • ⾼パフォーマンス・マウント・ターゲット(HPMT) - スループットを最⼤80Gbpsまでスケーリング 22 Copyright © 2025, Oracle and/or its affiliates HPMT HPMT HPMT 20/40/80 Gbs/HPMT ※OKE では File Storage 向けの プロビジョナーを提供 (fss.csi.oraclecloud.com) StorageClass リソースで設定すること によって動的にPVを作成する • ノード障害対策 • 分散学習環境での共有・同期 • 中断後の再実⾏・再学習 • モデルバージョン管理・監査

Slide 23

Slide 23 text

⾼性能ファイル・システム チェックポイント/ロールバックのオーバーヘッドを削減して、実⾏学習時間を改善するカギ OCI では Marketplace から様々な⾼性能ファイル・システムを提供 • Lustre, GlusterFS, BeeGFS / BeeOND, Weka OCI File Storage with Lustre – Lustre をベースとしたフルマネージドサービス • ⾼い拡張性とパフォーマンス • 最⼤ 20PB まで拡張可能 • 階層的なパフォーマンスレベルを提供 – 125/250/500/1000 Mbps per provisioned TB • フルマネージド • Lustre のコンポーネント (ストレージサーバー、メタデータサーバー、データボリューム) の設定・管理を⾃動化 • Lustre と Object Storage間のシームレスなコピー(近⽇提供開始) • Object Storage のデータを Lustre にオンデマンドでコピー • OKE ⽤の CSI (Container Storage Interface) ドライバを提供 23 Copyright © 2025, Oracle and/or its affiliates

Slide 24

Slide 24 text

ジョブ管理 24 Copyright © 2025, Oracle and/or its affiliates

Slide 25

Slide 25 text

ディープ・ラーニングにおける学習の並列化⼿法 Data Parallel • 同じモデルを複数のデバイスにコピー • 各デバイスで異なるミニバッチのデータを処理 • すべてのデバイスで独⽴にフォワード&バックプロパ ゲーション • 最後に勾配を集約(同期)して平均 or 合計し、 モデルを更新 • モデルサイズが1デバイスに収まるとき Model Parallel • モデル⾃体を層単位で複数のデバイスに分割 • 1つの⼊⼒データを、複数のデバイスに分かれたモデル で順番に処理 • モデルが⼤きすぎて1デバイスに収まらないとき Tensor Parallel • 1つの層の中の⾏列演算⾃体を分割して複数GPU で並列処理する⼿法 • より細かい粒度で分散するため、スループットが上がる • ⾼効率な並列化が可能 Pipeline Parallel • モデル全体をいくつかのステージ(層のまとまり) に 分割して、それぞれを異なるGPUで担当 • バッチをさらに細かく 「マイクロバッチ」に分割 • 各GPUが異なるマイクロバッチを同時に異なるステー ジで処理することで、GPU全体の使⽤率を⾼く保つ Hybrid Parallel (これらの組み合わせ) • ⼤規模なモデルを学習するときはこれが主流 25 Copyright © 2025, Oracle and/or its affiliates

Slide 26

Slide 26 text

torchrun PyTorch の分散トレーニングを簡単に実⾏するためのコマンドラインツール • 各ノードで、⽣成するプロセスに環境変数(RANK や WORLD_SIZE など)を設定して学習プログラムを実⾏ • マルチGPUやマルチノードの起動を簡素化 ノード数が増えてくると、Job管理ツールなしの運⽤は厳しい︕ • ノード毎のRANKの設定、IPアドレスの設定 • スケジューリング(他のジョブとの競合回避、GPUの割り当て) • エラー発⽣時の⾃動再実⾏ • etc. 26 Copyright © 2025, Oracle and/or its affiliates torchrun ¥ --nnodes=2 ¥ # ノード数 --node_rank=0 ¥ # 各ノードに振られる番号(0..n) --nproc_per_node=4 ¥ # ノードあたりのプロセス数(=通常はGPU数に合わせる) --master_addr="192.168.1.1" ¥ # マスターノードのアドレス --master_port=29500 ¥ # マスターノードのポート番号 ... train.py # PyTorch Pythonプログラム本体

Slide 27

Slide 27 text

Kubernetes 向け機械学習ジョブ管理ツール 3選 • Volcano, Kueue とも Topology Aware Scheduling が可能 – Pod を最適配置 • Volcano - マニュアルで定義 (HyperNode) 必要 (改善のプルリクあり) • Kueue - Topology, ResourceFlavor カスタム・リソースを使ってシンプルに定義可能 OKEユーザでは ほぼほぼ Volcano だそうです... 27 Copyright © 2025, Oracle and/or its affiliates ツール名 特徴 主な⽤途・強み Volcano • CNCF Incubating プロジェクト • 多機能 - Gang Scheduling、優先度、DRF、MPI 対応、etc. • HPCジョブ、機械学習、バッチ処理に最適 • Kubeflow、Ray、Sparkなどとの統合も充実 Kueue • Kubernetes SIG Scheduling が開発 • Kubernetes ネイティブで Job Queue 機能を提供 • Kubernetes Job/Kubeflow TrainingJob などを柔軟にキュー管理 • Volcanoより軽量志向 Slurm on Kubernetes • HPC 界隈で有名な Slurm (⾮ Kubernetes) を Kubernetes に統合するアプローチ • 既存のHPCクラスタとKubernetesの ハイブリッド運⽤に便利

Slide 28

Slide 28 text

Volcano – Kubenetes上で実⾏される Job 管理ツール Kubernetes 上での HPC や AI/ML ワークロードのために設計された Job 管理システム バッチジョブに最適化 • 並列ジョブや依存関係を持つタスクの実⾏を効率的に管理 • ジョブ単位でのリソース割り当て・優先順位制御が可能 Kubernetes ネイティブ • Kubernetes の CRD(Custom Resource Definitions)を活⽤し、ネイティブな⽅法でジョブを定義・管理 柔軟なスケジューリング戦略 • 公平性(fair-share)、優先度(priority)、キュー制御、Gang Scheduling、Preemption などに対応 • カスタム・スケジューリング・ポリシーの設定も可能 拡張性 • プラグイン・ベースのアーキテクチャで、独⾃のスケジューリング・ロジックを拡張可能 • svc, ssh, pytorch, etc. 28 Copyright © 2025, Oracle and/or its affiliates 複数のユーザ・チームによる共有クラスタにおいて、公平かつ効率的なリソース利⽤を実現

Slide 29

Slide 29 text

デモ (学習編) 29 Copyright © 2025, Oracle and/or its affiliates

Slide 30

Slide 30 text

デモ: MNIST 画像分類モデルを OKEクラスタ / GPUノードで分散学習する MNIST = 「0」〜「9」の⼿書き数字の画像データセット • 6万枚の訓練データ⽤(画像とラベル) • 1万枚のテストデータ⽤(画像とラベル) • 合計7万枚 PyTorch DistributedDataParallel (DDP) ベースの学習プログラム作成 • LSTM (Long short-term memory) で実装 • Pod で稼働させるので、プログラムはコンテナ・イメージ化 Volcano + torchrun で学習ジョブを起動 30 Copyright © 2025, Oracle and/or its affiliates

Slide 31

Slide 31 text

PyTorch DistributedDataParallel (DDP) 複数のマシン間で (= 複数のGPUを使って) モデルを並列化して学習する⽅法 • (複数マシンに分散配置された) 全プロセスは同じパラメータの初期値から開始 • 各プロセスは異なるミニバッチを処理して損失 (Loss) を算出し、ローカルな勾配 (Gradient) を計算 • 各プロセスの勾配を集めて全プロセスで平均化 (All-Reduce) して各プロセスに戻す • 各プロセスは平均化されたグローバルな勾配を基にパラメータの更新を⾏う • 結果、全プロセスのモデルのパラメータが同じになることが保証される︕ 31 Copyright © 2025, Oracle and/or its affiliates Mini Batch Mini Batch Mini Batch Model Model Model Param Param Param Local Gradient Local Gradient GPU Global Gradient Global Gradient Global Gradient Global Gradient GPU GPU プロセス プロセス プロセス 更新 更新 更新 平均化 (All-Reduce) Data Local Gradient * NCCL は Ring-AllReduce という⽅式で⾼速化 All-Reduce を 効率よく⾏うことが パフォーマンスのカギ

Slide 32

Slide 32 text

Volcano + torchrun で Job (Pytorch DDP) を実⾏ • Volcano PyTorch プラグインが、コンテナの環境変数を設定して、Volcano の Job が起動 (→ Pod が起動) • MASTER_ADDR, MASTER_PORT, WORLD_SIZE, RANK • torchrun は必要な分プロセスを spawn(⽣成)する(環境変数 RANK, LOCAL_RANK を(再)設定) 32 Copyright © 2025, Oracle and/or its affiliates process CPU GPU:0 CPU GPU:1 process RANK=1, LOCAL_RANK=1 RANK=0, LOCAL_RANK=0 GPUs process CPU GPU:0 CPU GPU:1 process RANK=3, LOCAL_RANK=1 RANK=2, LOCAL_RANK=0 GPUs process CPU GPU:0 CPU GPU:1 process RANK=5, LOCAL_RANK=1 RANK=4, LOCAL_RANK=0 GPUs torchrun torchrun torchrun master worker worker torchrun --nnodes=$WORLD_SIZE(=3) --nproc_per_node=$GPU_LIMITS(=2) --node_rank=$RANK(=0..2) NPROC=2, WORLD_SIZE=3, RANK=0 container: pytorch container: pytorch container: pytorch File Storage Data NPROC=2, WORLD_SIZE=3, RANK=1 NPROC=2, WORLD_SIZE=3, RANK=2 GPU を 2枚搭載したノード 3 台で学習を実⾏するケース (Pod はノードに1個づつ配置し、コンテナの中でプロセスを GPU 分だけ spawn する) spawn spawn spawn vcjob (カスタムリソース)

Slide 33

Slide 33 text

PyTorch DDP Pythonプログラム(.py) をコンテナ・イメージにする Dockerfile の例 33 Copyright © 2025, Oracle and/or its affiliates # ベースイメージ(CUDA)の指定 FROM nvidia/cuda:12.6.3-runtime-ubuntu24.04 # 必要なパッケージをインストール RUN apt-get update && apt-get install -y python3-pip python3-venv git nano # 作業ディレクトリを設定 WORKDIR /app # Python仮想環境の作成 RUN python3 -m venv /app/.venv # 仮想環境をアクティベートするコマンドを.bashrcに追加 RUN echo "source /app/.venv/bin/activate" >> /root/.bashrc # PyTorchのインストール RUN /app/.venv/bin/pip install numpy torch torchvision # モデル学習プログラムの配置 ADD main.py /app/ # 起動時に実⾏するコマンドを指定 ENTRYPOINT ["/app/.venv/bin/python", "/app/main.py"] ポイント • NVIDIA GPU の場合であれば CUDA ドライバの⼊ったベースイメージを使う • Python仮想環境を作って、PyTorch をインストール

Slide 34

Slide 34 text

Volcano + torchrun で 学習ジョブを起動 Volcano ジョブ yaml をレビュー - ⾻格部分 34 Copyright © 2025, Oracle and/or its affiliates apiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: name: torchrun-job spec: minAvailable: 3 # Gang Scheduling schedulerName: volcano plugins: pytorch: [] # ["--master=master","--worker=worker","--port=23456"] volumes: - mountPath: "/data" volumeClaimName: "fss-data-volume" tasks: - replicas: 1 name: master template: spec: - replicas: 2 name: worker template: spec: マスターノードのPodのスペック ワーカーノードのPodのスペック Volcano の CRD (Custom Resource Definitions) PyTorch プラグインを設定 • スケジュール可能な Pod がこの値に達しないと ジョブがスケジュールされない (= Pending) • タスクの完了数がこの値に達しないと、ジョブの ステータスが Complete にならない (= Failed) タスク = master x1 + worker x2 = 合計 3 各 Pod に共通的にマウントするボリューム

Slide 35

Slide 35 text

Volcano + torchrun で 学習ジョブを起動 Volcano ジョブ yaml をレビュー - マスター/ワーカー Pod スペック部分 35 Copyright © 2025, Oracle and/or its affiliates #hostNetwork: true #dnsPolicy: ClusterFirstWithHostNet restartPolicy: OnFailure nodeSelector: my_ready: "true" containers: - name: pytorch image: iad.ocir.io/orasejapan/ml/pytorch-dist-mnist:1.0.0 imagePullPolicy: IfNotPresent command: ["/bin/bash", "-c"] args: - | export NCCL_DEBUG=INFO export NCCL_TOPO_DUMP_FILE=/data/nccl/topo_dump.xml echo "Master at $MASTER_ADDR:$MASTER_PORT" /app/.venv/bin/torchrun --nnodes=$WORLD_SIZE --nproc_per_node=2 --node_rank=$RANK ¥ --rdzv_id=1234 --rdzv_backend=c10d --rdzv_endpoint=$MASTER_ADDR:$MASTER_PORT ¥ /app/main.py --root /data --backend nccl --epochs 20 resources: limits: nvidia.com/gpu: 2 pytorch プラグインが必要な環境変数を提供 • $WORLD_SIZE • $RANK (master: 0, worker: 1~) • $MASTER_ADDR • $MASTER_PORT GPUの割り当て (必須) ノード・セレクタを使って、稼働させるノードを指定できる (障害ノードはこれで除外する) NCCLデバッグ情報出⼒ & トポロジー情報をダンプ PyTorch 学習プログラムのコンテナ・イメージ (CUDAドライバ要)

Slide 36

Slide 36 text

デモ 実演 36 Copyright © 2025, Oracle and/or its affiliates

Slide 37

Slide 37 text

NCCL トポロジー情報ダンプファイル (topo_dump.xml) の内容 VM.GPU3.2 の場合 (GPU: V100 x2) 37 Copyright © 2025, Oracle and/or its affiliates Chat GPTに解読してもらいました… •システムのCPU情報を表しています。 •host_hash: ホストを⼀意に識別するハッシュ値。 •numaid="-1": NUMAノードID(-1は指定されていない、または⾮対応)。 •arch="x86_64": 64ビットアーキテクチャ。 •vendor="GenuineIntel": インテル製CPU。 •familyid="6" modelid="85": CPUのファミリー・モデルID(Skylakeなどを識別可能)。 •PCIデバイス情報。ここではGPUが2枚搭載されています。 (バスID 0000:00:04.0 と 0000:00:05.0) •class="0x030200": デバイスクラス(GPU = 3Dコントローラ)。 •vendor="0x10de": NVIDIA製(NVIDIAのベンダーID)。 •device="0x1db1": 特定GPUのデバイスID(例: Tesla V100など)。 •link_speed="8.0 GT/s PCIe": PCI Expressのリンク速度。 •link_width="0": リンク幅が0(正確な幅が未設定または未取得)。 •GPUデバイスに関する情報。 •dev="0" / dev="1": GPUの識別番号。 •sm="70": SMアーキテクチャ(Volta世代など)。 •rank="0" / rank="1": GPUのランク/順番。 •gdr="1": GDR(GPU Direct RDMA)が有効。 •GPU間の⾼速相互接続(NVLink)の情報。 •target="0000:00:05.0" / target="0000:00:04.0": 接続先GPU。 •count="1": 接続数(1本のNVLinkで接続)。 •tclass="0x030200": 相⼿もGPUであることを⽰す。 → つまり、GPU0 と GPU1 は相互に NVLink 接続されていることがわかります。 •ネットワークインターフェースカード(NIC)の情報。 •name="eth0": デバイス名。 •speed="10000": 10Gbpsの速度。 •port="0": ポート番号。 •latency="0.000000": レイテンシ(この値は未取得か無視されている)。 •guid="0x0": グローバル⼀意ID(未設定)。 •maxconn="65536": 最⼤接続数。 •gdr="0": GPU Direct RDMAはNICに対して無効。

Slide 38

Slide 38 text

NCCL Test GPU間通信の性能評価を⾏うベンチマーク・プログラム 38 Copyright © 2025, Oracle and/or its affiliates # nThread 1 nGpus 1 minBytes 33554432 maxBytes 1073741824 step: 2(factor) warmup iters: 5 iters: 20 agg iters: 1 validation: 1 graph: 0 # # Using devices # Rank 0 Group 0 Pid 57 on nccl-allreduce-job-mpiworker-0 device 0 [0x00] Tesla V100-SXM2-16GB # Rank 1 Group 0 Pid 58 on nccl-allreduce-job-mpiworker-0 device 1 [0x00] Tesla V100-SXM2-16GB # Rank 2 Group 0 Pid 57 on nccl-allreduce-job-mpiworker-1 device 0 [0x00] Tesla V100-SXM2-16GB # Rank 3 Group 0 Pid 58 on nccl-allreduce-job-mpiworker-1 device 1 [0x00] Tesla V100-SXM2-16GB # Rank 4 Group 0 Pid 57 on nccl-allreduce-job-mpiworker-2 device 0 [0x00] Tesla V100-SXM2-16GB # Rank 5 Group 0 Pid 58 on nccl-allreduce-job-mpiworker-2 device 1 [0x00] Tesla V100-SXM2-16GB NCCL version 2.23.4+cuda12.6 # # out-of-place in-place # size count type redop root time algbw busbw #wrong time algbw busbw #wrong # (B) (elements) (us) (GB/s) (GB/s) (us) (GB/s) (GB/s) 33554432 8388608 float sum -1 49376 0.68 1.13 0 58670 0.57 0.95 0 67108864 16777216 float sum -1 111516 0.60 1.00 0 106893 0.63 1.05 0 134217728 33554432 float sum -1 223938 0.60 1.00 0 226246 0.59 0.99 0 268435456 67108864 float sum -1 443118 0.61 1.01 0 452077 0.59 0.99 0 536870912 134217728 float sum -1 885917 0.61 1.01 0 888869 0.60 1.01 0 1073741824 268435456 float sum -1 1772154 0.61 1.01 0 1771221 0.61 1.01 0 # Out of bounds values : 0 OK # Avg bus bandwidth : 1.01324 # all_reduce_perf -e 1G -f 2 -g 1 -c 1 (VM.GBU3.2 x 3 ノードで実施した例)

Slide 39

Slide 39 text

推論編 39 Copyright © 2025, Oracle and/or its affiliates

Slide 40

Slide 40 text

推論編 推論のためのプラットフォーム • フルサイズの LLM を複数ノードで推論するなら RDMA クラスタは実質必須 • 軽量モデルや量⼦化モデルなら、単⼀マシンで充分に動作する 推論環境構築ツール • これといった定番はない、らしい... • K8s の標準コンポーネントで実現可能 – Pod, ReplicaSet, Deployment, Autoscaler • KServe – 推論のためのサーバレス環境 40 Copyright © 2025, Oracle and/or its affiliates

Slide 41

Slide 41 text

KServe Kubernetes 上で機械学習モデルをデプロイ・管理するためのオープンソースのフレームワーク Kubernetes ネイティブ • Kubernetes の標準リソースのみで構築可能 (Deployment, Service, Ingress/Gateway API, HPA) • Istio (サービス・メッシュ) や Knative (サーバーレス環境) などと連携 複数のフレームワークに対応 • TensorFlow, PyTorch, XGBoost, ONNX など、 主要なMLフレームワークをサポート • Hugging Face LLM Serving Runtime インファレンス⽤ API を⾃動で提供 • REST や gRPC 経由でアクセス バージョン管理やカナリアリリースに対応 • 旧モデルと新モデルを同時に動かして、トラフィックを徐々に 切り替えるなどの運⽤が可能。 41 Copyright © 2025, Oracle and/or its affiliates kserve.github.io/website

Slide 42

Slide 42 text

デモ (推論編) 42 Copyright © 2025, Oracle and/or its affiliates

Slide 43

Slide 43 text

デモ Hugging Face LLM Serving Runtime を使って推論環境を構築 • RawDeployment モードで KServe をインストール – ⼀番シンプルな構成 • Horizontal Pod Autoscaler (HPA) も設定可能 • Ingress Controller に Contour を使⽤(KServe インストール時に Ingress を指定) • OCI フレキシブル・ロード・バランサと連携 43 Copyright © 2025, Oracle and/or its affiliates Load Balancer model File Storage (途中経路省略) model-predictor kserve-controller-manager model-predictor host: model.default.some-domain.com → service: model-predictor model cache

Slide 44

Slide 44 text

デモ InferenceService リソース 44 Copyright © 2025, Oracle and/or its affiliates apiVersion: serving.kserve.io/v1beta1 kind: InferenceService metadata: name: ochacafe-inference annotations: serving.kserve.io/deploymentMode: RawDeployment serving.kserve.io/autoscalerClass: hpa spec: predictor: model: modelFormat: name: huggingface args: - --model_name=tinyswallow - --model_id=SakanaAI/TinySwallow-1.5B-Instruct - --dtype=half env: - name: HF_HOME value: /mnt/kserve volumeMounts: - name: model-pvc mountPath: /mnt resources: limits: cpu: "6" memory: 64Gi nvidia.com/gpu: "1" requests: cpu: "6" memory: 64Gi nvidia.com/gpu: "1" #nodeSelector: # beta.kubernetes.io/instance-type: VM.GPU3.1 volumes: - name: model-pvc persistentVolumeClaim: claimName: "fss-data-volume" minReplicas: 1 maxReplicas: 5 scaleTarget: 80 scaleMetric: cpu CPU/Memory/GPUの割り当て Hugging Face のモデルと パラメータを指定 モデル・キャッシュ ディレクトリ ノード・セレクターも使える autoscaling の設定 HPA を使う (none, external も可)

Slide 45

Slide 45 text

デモ 実演 UI は Streamlit で簡単に作ってみました… 45 Copyright © 2025, Oracle and/or its affiliates

Slide 46

Slide 46 text

まとめ 46 Copyright © 2025, Oracle and/or its affiliates

Slide 47

Slide 47 text

まとめ AIモデルの学習・推論プラットフォームに Kubernetes を選択する理由 • Kubernetes の持つ本質的な強み • 再現性と移植性、⾃動化管理・障害回復機能、拡張性、リソース制御・アクセス制御、スケーラビリティ • Kubernetes のエコシステムの恩恵 • 各種プラグイン – Device Plugin, CNI Plugin, etc. • モニタリング – Grafana, Prometheus, DCGM Exporter, Node Problem Detector • ツール – Volcano, KServe, KubeFlow, etc. RDMA クラスタ + Kubernetes の考慮点 • 各種 Plugin • Topology / Affinity • Pod ネットワーキング / NCCL • ストレージ • モニタリング • ... 47 Copyright © 2025, Oracle and/or its affiliates

Slide 48

Slide 48 text

参考 Volcano - https://volcano.sh/ / https://github.com/volcano-sh/volcano KServe - https://kserve.github.io/website/ / https://github.com/kserve/kserve DCGM-Exporter - https://github.com/NVIDIA/dcgm-exporter Node Problem Detector - https://github.com/kubernetes/node-problem-detector NVIDIA device plugin for Kubernetes - https://github.com/NVIDIA/k8s-device-plugin NCCL - https://developer.nvidia.com/nccl / https://github.com/NVIDIA/nccl torchrun - https://docs.pytorch.org/docs/stable/elastic/run.html Contour - https://projectcontour.io/ / https://github.com/projectcontour/contour Terraform OKE for Oracle Cloud Infrastructure - https://github.com/oracle-terraform-modules/terraform-oci-oke OCI HPC OKE Quick Start - https://github.com/oracle-quickstart/oci-hpc-oke OCI File Storage with Lustre に OKE の Pod からアクセスする - https://qiita.com/tkote/items/51a44ed7ac6736e4ca11 MLOpsを始めよう!(OCHaCafe Season5#6)- https://speakerdeck.com/oracle4engineer/mlops-getting-started サーバレス on Kubernetes (OCHaCafe Season6#5) - https://speakerdeck.com/oracle4engineer/serverless-on-kubernetes First Principles: Inside Zettascale OCI Superclusters for Next-gen AI - https://blogs.oracle.com/cloud-infrastructure/post/first-principles-zettascale-oci-superclusters 48 Copyright © 2025, Oracle and/or its affiliates

Slide 49

Slide 49 text

Thank you 49 Copyright © 2024, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted

Slide 50

Slide 50 text

⾃⼰管理ノードの作り⽅ 基本パターン (RDMAドライバが⼊っていない普通の⾃⼰管理ノードを作る) OKE Oracle Linux 7 (OL7) または Oracle Linux 8 (OL8) OKE 専⽤イメージを提供 * コンピュート・インスタンスが OKE クラスタに参加できるようにポリシーを設定しておく • Allow dynamic-group to {CLUSTER_JOIN} in compartment コンピュート・インスタンス作成時の cloud-init スクリプトで /etc/oke/oke-install.sh を実⾏するように設定 • パラメータ • 当該クラスタの Kubernetes API プライベート・エンドポイント • Base64 でエンコードされた CA証明書 50 Copyright © 2025, Oracle and/or its affiliates #!/usr/bin/env bash bash /etc/oke/oke-install.sh ¥ --apiserver-endpoint ¥ --kubelet-ca-cert $ oci ce cluster get --cluster-id ¥ | jq -r .data.endpoints.¥"private-endpoint¥" ¥ | sed -E 's^([0-9¥.]+):.*^¥1^' 10.0.0.13 $ oci ce cluster create-kubeconfig --cluster-id ¥ --file - | grep -oE "LS0t.*" LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURpVENDQW5HZ0F3SUJBZ0lSQ UtMMk02blh1eUJTOEhINUZVWWE0em93RFFZSktvWklodmNXcKWGpFUE1BMEdBMVVF QXd3R1N6aURWUVFHRXdKVlV6RVBNQTBHQTFVRUJ3d0dRWFZ6ZEdsdQpNUTh3RFFZR FZRUUc01BMDlqYVRFT01Bd0d(...)BMVVFQ0F3RlZHVjRZWE13CkhoY053TkRFd01 EQTFNekF5V2hjTk1qa3dOREV3TURBMU16QXlXakJlTEWpQUVZ6QmJ1NXdjcmpjRHA 5SDN1ZkFVYUHQ2c283ZzhRCmxWbjArTVpvSHdNZvbXZFU3Ntc2o4TVR4ZlpaR3lYR zlnRnluYlBlYWkrSms4R2IyMQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== cloud-init スクリプト RDMAに対応した ubuntu イメージを使った ⾃⼰管理ノードの作成は、この基本パターンではなくて OKE Quick Start (Terraform) (後述)で作成 ポイント︕

Slide 51

Slide 51 text

OCI File Storage with Lustre • PV/PVCを利⽤する → → → • Lustre クライアントがインストールされたワーカー・ノード でないと、CSI ドライバは機能しない (PV/PVC はペンディング状態に) • But 現時点で、Lustre クライアントがインストールされ た OKE イメージは提供されていない… 対応⽅法 = カスタム・イメージを⾃前で作る 1.OKE イメージを使って、⼀旦通常のコンピュート・ インスタンスとして起動する 2.Lustre クライアントをインストール (公式 Doc 参照) 3.カスタム・イメージとして保存 4.保存したカスタム・イメージを使って - ノード・プール (=管理対象ノード) を作成 ※ CLI/API のみ、コンソールからは不可 - or ⾃⼰管理ノードを作成 (前述の⽅法) 51 Copyright © 2025, Oracle and/or its affiliates Pod から Lustre をマウントするには apiVersion: v1 kind: PersistentVolume metadata: name: lustre-pv-example spec: capacity: storage: 31Ti volumeMode: Filesystem accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain csi: driver: lustre.csi.oraclecloud.com volumeHandle: "10.0.2.6@tcp:/testlustrefs" fsType: lustre volumeAttributes: setupLnet: "true” --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: lustre-pvc-example spec: accessModes: - ReadWriteMany storageClassName: "" volumeName: lustre-pv-example resources: requests: storage: 31Ti qiita.com/tkote 参照

Slide 52

Slide 52 text

No content