Skip to content

Commit d2f5185

Browse files
author
Ubuntu
committed
Add GPU KubeRay benchmark workflow
1 parent 11c3096 commit d2f5185

33 files changed

Lines changed: 1985 additions & 15 deletions

.dockerignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.git
2+
.github
3+
.pytest_cache
4+
.ruff_cache
5+
.mypy_cache
6+
__pycache__
7+
*.py[cod]
8+
*.log
9+
.coverage
10+
htmlcov
11+
build
12+
dist
13+
*.egg-info
14+
15+
# Datasets and benchmark output are mounted or downloaded at runtime.
16+
data
17+
dataset
18+
benchmark/results
19+
results
20+
21+
# Local walkthrough material is not needed by the runtime image.
22+
docs
23+
kuberay
24+
ray_cluster_configs

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ repos:
66
hooks:
77
- id: check-merge-conflict
88
- id: check-yaml
9+
args: [--allow-multiple-documents]
910
- id: end-of-file-fixer
1011
- id: trailing-whitespace
1112
- repo: https://github.com/PyCQA/isort

Dockerfile.gpu

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
ARG RAY_VERSION=2.56.0
2+
FROM rayproject/ray:${RAY_VERSION}-py312-cu121
3+
4+
USER root
5+
6+
RUN apt-get update \
7+
&& apt-get install -y --no-install-recommends \
8+
build-essential \
9+
cmake \
10+
git \
11+
wget \
12+
&& rm -rf /var/lib/apt/lists/*
13+
14+
WORKDIR /app
15+
16+
ARG TORCH_VERSION=2.5.1
17+
RUN python -m pip install --upgrade pip setuptools wheel \
18+
&& python -m pip install \
19+
"torch==${TORCH_VERSION}" \
20+
--index-url https://download.pytorch.org/whl/cu121 \
21+
&& python -m pip install \
22+
"pyg-lib==0.4.0+pt25cu121" \
23+
"torch-scatter==2.1.2+pt25cu121" \
24+
"torch-sparse==0.6.18+pt25cu121" \
25+
"torch-cluster==1.6.3+pt25cu121" \
26+
"torch-spline-conv==1.2.2+pt25cu121" \
27+
--find-links https://data.pyg.org/whl/torch-2.5.1+cu121.html \
28+
&& python -m pip install \
29+
torch-geometric==2.8.0 \
30+
numpy==2.4.4 \
31+
scipy==1.18.0 \
32+
pandas==3.0.3 \
33+
scikit-learn==1.9.0 \
34+
omegaconf==2.3.0 \
35+
attridict==0.0.9 \
36+
torchmetrics==1.9.0 \
37+
tensorboard==2.21.0 \
38+
dtaidistance==2.4.0 \
39+
gdown==6.1.0 \
40+
tenseal==0.3.16 \
41+
ogb==1.3.6 \
42+
openfhe==1.2.3.0.24.4 \
43+
psutil==7.2.2 \
44+
matplotlib==3.11.0
45+
46+
COPY --chown=1000:100 setup.py README.md ./
47+
COPY --chown=1000:100 fedgraph ./fedgraph
48+
COPY --chown=1000:100 benchmark ./benchmark
49+
50+
# The source remains in /app so FedGraph subpackages omitted by the legacy
51+
# setup.py package list are still importable.
52+
RUN mkdir -p /app/data \
53+
&& chown -R 1000:100 /app \
54+
&& python -m pip install --no-deps --editable . \
55+
&& python -c "import ray, torch, torch_geometric, fedgraph; print(ray.__version__, torch.__version__, torch_geometric.__version__)"
56+
57+
ENV PYTHONPATH=/app \
58+
PYTHONUNBUFFERED=1
59+
60+
USER 1000
61+
CMD ["python", "-c", "import ray, torch; print('Ray', ray.__version__, 'CUDA build', torch.version.cuda)"]

Dockerfile.gpu.draft

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Draft GPU image for FedGraph on KubeRay.
2+
#
3+
# This file is intentionally not used by setup_cluster.sh yet. Review the base
4+
# image tag and CUDA/PyTorch/PyG versions before building or pushing.
5+
#
6+
# The existing Dockerfile installs CPU PyTorch. For GPU Ray worker pods, the
7+
# image must include CUDA-compatible PyTorch and matching PyG extension wheels.
8+
9+
ARG RAY_VERSION=2.56.0
10+
FROM rayproject/ray-ml:${RAY_VERSION}-gpu
11+
12+
WORKDIR /app
13+
14+
USER root
15+
16+
RUN apt-get update && apt-get install -y --no-install-recommends \
17+
build-essential \
18+
cmake \
19+
git \
20+
&& rm -rf /var/lib/apt/lists/*
21+
22+
COPY docker_requirements.txt .
23+
24+
# Align these with the CUDA runtime in the selected rayproject/ray-ml image.
25+
# The local EC2 validation environment used torch 2.5.1+cu121 successfully.
26+
RUN python -m pip install --no-cache-dir --upgrade pip && \
27+
python -m pip install --no-cache-dir \
28+
torch==2.5.1+cu121 \
29+
--index-url https://download.pytorch.org/whl/cu121 && \
30+
python -m pip install --no-cache-dir \
31+
pyg-lib \
32+
torch-scatter \
33+
torch-sparse \
34+
torch-cluster \
35+
torch-spline-conv \
36+
-f https://data.pyg.org/whl/torch-2.5.1+cu121.html && \
37+
python -m pip install --no-cache-dir torch-geometric
38+
39+
RUN grep -v "tenseal" docker_requirements.txt | \
40+
grep -v "torch" | \
41+
grep -v "torch-cluster" | \
42+
grep -v "torch-scatter" | \
43+
grep -v "torch-sparse" | \
44+
grep -v "torch-spline-conv" | \
45+
grep -v "torch-geometric" > requirements_filtered.txt && \
46+
python -m pip install --no-cache-dir -r requirements_filtered.txt
47+
48+
RUN python -m pip install --no-cache-dir openfhe==1.2.3.0.24.4 || \
49+
echo "Warning: OpenFHE installation may need manual verification"
50+
51+
COPY fedgraph /app/fedgraph
52+
COPY benchmark /app/benchmark
53+
COPY setup.py README.md ./
54+
55+
RUN python -m pip install --no-deps -e .
56+
57+
CMD ["python", "-c", "import torch, ray, fedgraph; print('cuda_available=', torch.cuda.is_available()); print('ray=', ray.__version__)"]

benchmark/benchmark_NC_batch_size_convergence.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class ExperimentConfig:
8282
num_layers: int
8383
num_hops: int
8484
gpu: bool
85+
server_device: Optional[str]
8586
num_cpus_per_trainer: int
8687
num_gpus_per_trainer: float
8788
use_ogb_load_patch: bool
@@ -339,6 +340,7 @@ def to_fedgraph_args(
339340
"num_layers": config.num_layers,
340341
"num_hops": config.num_hops,
341342
"gpu": config.gpu,
343+
"server_device": config.server_device,
342344
"num_cpus_per_trainer": config.num_cpus_per_trainer,
343345
"num_gpus_per_trainer": config.num_gpus_per_trainer,
344346
"logdir": str(logdir),
@@ -981,6 +983,7 @@ def build_configs(args) -> List[ExperimentConfig]:
981983
num_layers=args.num_layers,
982984
num_hops=args.num_hops,
983985
gpu=args.gpu,
986+
server_device=args.server_device,
984987
num_cpus_per_trainer=args.num_cpus_per_trainer,
985988
num_gpus_per_trainer=args.num_gpus_per_trainer,
986989
use_ogb_load_patch=use_ogb_load_patch,
@@ -1021,6 +1024,15 @@ def parse_args():
10211024
parser.add_argument("--num-hops", type=int, default=0)
10221025
parser.add_argument("--method", default=None)
10231026
parser.add_argument("--gpu", action="store_true")
1027+
parser.add_argument(
1028+
"--server-device",
1029+
choices=("cpu", "cuda"),
1030+
default=None,
1031+
help=(
1032+
"Temporary NC server-device override. By default, the server uses "
1033+
"the same device selected by --gpu."
1034+
),
1035+
)
10241036
parser.add_argument("--num-cpus-per-trainer", type=int, default=1)
10251037
parser.add_argument("--num-gpus-per-trainer", type=float, default=0.0)
10261038
parser.add_argument(
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
cloudProvider: aws
2+
3+
rbac:
4+
serviceAccount:
5+
create: false
6+
name: cluster-autoscaler
7+
8+
nodeSelector:
9+
workload: system
10+
11+
extraArgs:
12+
expander: least-waste
13+
scale-down-delay-after-add: 5m
14+
scale-down-unneeded-time: 5m
15+
scan-interval: 20s
16+
17+
resources:
18+
requests:
19+
cpu: 100m
20+
memory: 300Mi
21+
limits:
22+
cpu: 300m
23+
memory: 600Mi
24+
25+
serviceMonitor:
26+
enabled: true
27+
interval: 5s
28+
namespace: prometheus-system
29+
selector:
30+
release: prometheus

deploy/kuberay/dcgm-values.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
arguments:
2+
- -f
3+
- /etc/dcgm-exporter/default-counters.csv
4+
- -c
5+
- "5000"
6+
7+
nodeSelector:
8+
ray-node-type: gpu-worker
9+
10+
tolerations:
11+
- key: nvidia.com/gpu
12+
operator: Equal
13+
value: "true"
14+
effect: NoSchedule
15+
16+
serviceMonitor:
17+
enabled: true
18+
interval: 5s
19+
scrapeTimeout: 4s
20+
additionalLabels:
21+
release: prometheus
22+
23+
kubernetes:
24+
enablePodLabels: true
25+
enablePodUID: true
26+
podLabelAllowlistRegex:
27+
- ^ray\.io/(cluster|group|node-type)$
28+
29+
resources:
30+
requests:
31+
cpu: 100m
32+
memory: 128Mi
33+
limits:
34+
cpu: 300m
35+
memory: 512Mi

deploy/kuberay/eks-cluster.yaml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
apiVersion: eksctl.io/v1alpha5
2+
kind: ClusterConfig
3+
4+
metadata:
5+
name: fedgraph-gpu
6+
region: eu-central-1
7+
version: "1.34"
8+
9+
iam:
10+
withOIDC: true
11+
serviceAccounts:
12+
- metadata:
13+
name: cluster-autoscaler
14+
namespace: kube-system
15+
attachPolicy:
16+
Version: "2012-10-17"
17+
Statement:
18+
- Effect: Allow
19+
Action:
20+
- autoscaling:SetDesiredCapacity
21+
- autoscaling:TerminateInstanceInAutoScalingGroup
22+
Resource: "*"
23+
Condition:
24+
StringEquals:
25+
aws:ResourceTag/k8s.io/cluster-autoscaler/enabled: "true"
26+
aws:ResourceTag/k8s.io/cluster-autoscaler/fedgraph-gpu: owned
27+
- Effect: Allow
28+
Action:
29+
- autoscaling:DescribeAutoScalingGroups
30+
- autoscaling:DescribeAutoScalingInstances
31+
- autoscaling:DescribeLaunchConfigurations
32+
- autoscaling:DescribeScalingActivities
33+
- autoscaling:DescribeTags
34+
- ec2:DescribeImages
35+
- ec2:DescribeInstanceTypes
36+
- ec2:DescribeLaunchTemplateVersions
37+
- ec2:GetInstanceTypesFromInstanceRequirements
38+
- eks:DescribeNodegroup
39+
Resource: "*"
40+
41+
addons:
42+
- name: aws-ebs-csi-driver
43+
wellKnownPolicies:
44+
ebsCSIController: true
45+
46+
managedNodeGroups:
47+
# System services, monitoring, and the CPU-only Ray head share this node.
48+
- name: system-head-cpu
49+
instanceType: m7i.xlarge
50+
amiFamily: AmazonLinux2023
51+
minSize: 1
52+
desiredCapacity: 1
53+
maxSize: 1
54+
volumeSize: 100
55+
volumeType: gp3
56+
volumeEncrypted: true
57+
labels:
58+
workload: system
59+
ray-node-type: head
60+
tags:
61+
workload: system-head
62+
k8s.io/cluster-autoscaler/enabled: "true"
63+
k8s.io/cluster-autoscaler/fedgraph-gpu: owned
64+
propagateASGTags: true
65+
66+
# GPU workers begin at zero. Ray creates pending worker pods on demand, then
67+
# Cluster Autoscaler adds up to five EC2 nodes. Each node has one T4 GPU, so
68+
# one one-GPU Ray worker pod and trainer actor can run on each node.
69+
- name: ray-worker-gpu
70+
instanceType: g4dn.xlarge
71+
amiFamily: AmazonLinux2023
72+
minSize: 0
73+
desiredCapacity: 0
74+
maxSize: 5
75+
volumeSize: 100
76+
volumeType: gp3
77+
volumeEncrypted: true
78+
labels:
79+
workload: ray
80+
ray-node-type: gpu-worker
81+
accelerator: nvidia-tesla-t4
82+
k8s.amazonaws.com/accelerator: nvidia-tesla-t4
83+
taints:
84+
- key: nvidia.com/gpu
85+
value: "true"
86+
effect: NoSchedule
87+
tags:
88+
workload: ray-gpu-worker
89+
k8s.io/cluster-autoscaler/enabled: "true"
90+
k8s.io/cluster-autoscaler/fedgraph-gpu: owned
91+
propagateASGTags: true

0 commit comments

Comments
 (0)