Skip to content

Commit 72a326d

Browse files
Cleanup Multi Node API to avoid redundant GPU input
Signed-off-by: Vishesh Tanksale <vtanksale@nvidia.com>
1 parent f51a805 commit 72a326d

File tree

13 files changed

+78
-88
lines changed

13 files changed

+78
-88
lines changed

api/apps/v1alpha1/nimservice_types.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,6 @@ type NimServiceMultiNodeConfig struct {
145145
// +kubebuilder:validation:Minimum=1
146146
Size int `json:"size,omitempty"`
147147

148-
// +kubebuilder:default:=1
149-
// GPUSPerPod specifies the number of GPUs for each instance. In most cases, this should match `resources.limits.nvidia.com/gpu`.
150-
GPUSPerPod int `json:"gpusPerPod,omitempty"`
151-
152148
// MPI config for NIMService using LeaderWorkerSet
153149
MPI *MultiNodeMPIConfig `json:"mpi,omitempty"`
154150
}
@@ -227,6 +223,16 @@ func (n *NIMService) GetLWSName() string {
227223
return fmt.Sprintf("%s-lws", n.GetName())
228224
}
229225

226+
// GetMultiNodeGPUsPerPod returns the number of GPUs per pod for the multi-node NIMService.
227+
func (n *NIMService) GetMultiNodeGPUsPerPod() int {
228+
gpuQuantity, ok := n.Spec.Resources.Requests["nvidia.com/gpu"]
229+
if !ok {
230+
// return 0 if no GPU limit is specified because auto determine base on tp*pp/(.spec.multiNode.size) is a TODO
231+
return 0
232+
}
233+
return int(gpuQuantity.Value())
234+
}
235+
230236
// GetPVCName returns the name to be used for the PVC based on the custom spec
231237
// Prefers pvc.Name if explicitly set by the user in the NIMService instance.
232238
func (n *NIMService) GetPVCName(pvc PersistentVolumeClaim) string {
@@ -336,7 +342,7 @@ func (n *NIMService) getLWSCommonEnv() []corev1.EnvVar {
336342
},
337343
{
338344
Name: "NIM_TENSOR_PARALLEL_SIZE",
339-
Value: fmt.Sprintf("%d", n.Spec.MultiNode.GPUSPerPod),
345+
Value: fmt.Sprintf("%d", n.GetMultiNodeGPUsPerPod()),
340346
},
341347
{
342348
Name: "NIM_PIPELINE_PARALLEL_SIZE",
@@ -377,7 +383,7 @@ func (n *NIMService) GetLWSLeaderEnv() []corev1.EnvVar {
377383
},
378384
{
379385
Name: "GPUS_PER_NODE",
380-
Value: fmt.Sprintf("%d", n.Spec.MultiNode.GPUSPerPod),
386+
Value: fmt.Sprintf("%d", n.GetMultiNodeGPUsPerPod()),
381387
},
382388
{
383389
Name: "CLUSTER_START_TIMEOUT",
@@ -1198,10 +1204,10 @@ func (n *NIMService) generateMPIConfigData() map[string]string {
11981204
// Construct ConfigMap data
11991205
data := make(map[string]string)
12001206
for i := 0; i < n.Spec.Replicas; i++ {
1201-
hostfile := fmt.Sprintf("localhost slots=%d\n", n.Spec.MultiNode.GPUSPerPod)
1207+
hostfile := fmt.Sprintf("localhost slots=%d\n", n.GetMultiNodeGPUsPerPod())
12021208
for j := 1; j < n.Spec.MultiNode.Size; j++ {
12031209
workerHostname := fmt.Sprintf("%s-%d-%d.%s.%s.svc slots=%d",
1204-
n.GetLWSName(), i, j, n.GetLWSName(), n.GetNamespace(), n.Spec.MultiNode.GPUSPerPod)
1210+
n.GetLWSName(), i, j, n.GetLWSName(), n.GetNamespace(), n.GetMultiNodeGPUsPerPod())
12051211
hostfile += workerHostname + "\n"
12061212
}
12071213
dataKey := fmt.Sprintf("hostfile-%d", i)

bundle/manifests/apps.nvidia.com_nimpipelines.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,12 +1293,6 @@ spec:
12931293
enum:
12941294
- lws
12951295
type: string
1296-
gpusPerPod:
1297-
default: 1
1298-
description: GPUSPerPod specifies the number of GPUs
1299-
for each instance. In most cases, this should match
1300-
`resources.limits.nvidia.com/gpu`.
1301-
type: integer
13021296
mpi:
13031297
description: MPI config for NIMService using LeaderWorkerSet
13041298
properties:

bundle/manifests/apps.nvidia.com_nimservices.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,11 +1226,6 @@ spec:
12261226
enum:
12271227
- lws
12281228
type: string
1229-
gpusPerPod:
1230-
default: 1
1231-
description: GPUSPerPod specifies the number of GPUs for each
1232-
instance. In most cases, this should match `resources.limits.nvidia.com/gpu`.
1233-
type: integer
12341229
mpi:
12351230
description: MPI config for NIMService using LeaderWorkerSet
12361231
properties:

config/crd/bases/apps.nvidia.com_nimpipelines.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,12 +1293,6 @@ spec:
12931293
enum:
12941294
- lws
12951295
type: string
1296-
gpusPerPod:
1297-
default: 1
1298-
description: GPUSPerPod specifies the number of GPUs
1299-
for each instance. In most cases, this should match
1300-
`resources.limits.nvidia.com/gpu`.
1301-
type: integer
13021296
mpi:
13031297
description: MPI config for NIMService using LeaderWorkerSet
13041298
properties:

config/crd/bases/apps.nvidia.com_nimservices.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,11 +1226,6 @@ spec:
12261226
enum:
12271227
- lws
12281228
type: string
1229-
gpusPerPod:
1230-
default: 1
1231-
description: GPUSPerPod specifies the number of GPUs for each
1232-
instance. In most cases, this should match `resources.limits.nvidia.com/gpu`.
1233-
type: integer
12341229
mpi:
12351230
description: MPI config for NIMService using LeaderWorkerSet
12361231
properties:

deployments/helm/k8s-nim-operator/crds/apps.nvidia.com_nimpipelines.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,12 +1293,6 @@ spec:
12931293
enum:
12941294
- lws
12951295
type: string
1296-
gpusPerPod:
1297-
default: 1
1298-
description: GPUSPerPod specifies the number of GPUs
1299-
for each instance. In most cases, this should match
1300-
`resources.limits.nvidia.com/gpu`.
1301-
type: integer
13021296
mpi:
13031297
description: MPI config for NIMService using LeaderWorkerSet
13041298
properties:

deployments/helm/k8s-nim-operator/crds/apps.nvidia.com_nimservices.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,11 +1226,6 @@ spec:
12261226
enum:
12271227
- lws
12281228
type: string
1229-
gpusPerPod:
1230-
default: 1
1231-
description: GPUSPerPod specifies the number of GPUs for each
1232-
instance. In most cases, this should match `resources.limits.nvidia.com/gpu`.
1233-
type: integer
12341229
mpi:
12351230
description: MPI config for NIMService using LeaderWorkerSet
12361231
properties:

internal/controller/platform/kserve/nimservice.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ func (r *NIMServiceReconciler) addGPUResources(ctx context.Context, nimService *
577577
// if deployed as multi-node, use the GPU per worker value to assign GPU resources to each worker
578578
// TODO auto determine base on tp*pp/(.spec.multiNode.size)
579579
if nimService.Spec.MultiNode != nil {
580-
gpuQuantity, err = apiResource.ParseQuantity(fmt.Sprintf("%d", nimService.Spec.MultiNode.GPUSPerPod))
580+
gpuQuantity, err = apiResource.ParseQuantity(fmt.Sprintf("%d", nimService.GetMultiNodeGPUsPerPod()))
581581
if err != nil {
582582
logger.Error(err, "Failed to parse GPU per worker value")
583583
return nil, err

internal/controller/platform/kserve/nimservice_test.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,23 +1744,6 @@ var _ = Describe("NIMServiceReconciler for a KServe platform", func() {
17441744
Expect(resources.Limits).To(HaveKeyWithValue(corev1.ResourceName("nvidia.com/gpu"), resource.MustParse("1")))
17451745
})
17461746

1747-
It("should assign GPU resource equal to multiNode.GPUSPerPod in multi-node deployment", func() {
1748-
nimService.Spec.MultiNode = &appsv1alpha1.NimServiceMultiNodeConfig{
1749-
GPUSPerPod: 2,
1750-
}
1751-
profile := &appsv1alpha1.NIMProfile{
1752-
Name: "test-profile",
1753-
Config: map[string]string{"tp": "4"},
1754-
}
1755-
1756-
resources, err := reconciler.addGPUResources(context.TODO(), nimService, profile)
1757-
Expect(err).ToNot(HaveOccurred())
1758-
Expect(resources).ToNot(BeNil())
1759-
1760-
Expect(resources.Requests).To(HaveKeyWithValue(corev1.ResourceName("nvidia.com/gpu"), resource.MustParse("2")))
1761-
Expect(resources.Limits).To(HaveKeyWithValue(corev1.ResourceName("nvidia.com/gpu"), resource.MustParse("2")))
1762-
})
1763-
17641747
It("should return an error if tensor parallelism cannot be parsed", func() {
17651748
profile := &appsv1alpha1.NIMProfile{
17661749
Name: "test-profile",

internal/controller/platform/standalone/nimservice.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ func (r *NIMServiceReconciler) addGPUResources(ctx context.Context, nimService *
10041004
// if deployed as multi-node, use the GPU per worker value to assign GPU resources to each worker
10051005
// TODO auto determine base on tp*pp/(.spec.multiNode.size)
10061006
if nimService.Spec.MultiNode != nil {
1007-
gpuQuantity, err = apiResource.ParseQuantity(fmt.Sprintf("%d", nimService.Spec.MultiNode.GPUSPerPod))
1007+
gpuQuantity, err = apiResource.ParseQuantity(fmt.Sprintf("%d", nimService.GetMultiNodeGPUsPerPod()))
10081008
if err != nil {
10091009
logger.Error(err, "Failed to parse GPU per worker value")
10101010
return nil, err

0 commit comments

Comments
 (0)