Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kubernetes HPA doesn't work with elastic PytorchJob #1645

Closed
zclyne opened this issue Aug 4, 2022 · 4 comments · Fixed by #1701
Closed

Kubernetes HPA doesn't work with elastic PytorchJob #1645

zclyne opened this issue Aug 4, 2022 · 4 comments · Fixed by #1701
Labels

Comments

@zclyne
Copy link

zclyne commented Aug 4, 2022

Background

Hi! I'm trying to launch elastic PytorchJob on training-operator with horizontal pod autoscaling (HPA), but I cannot get it work.

Here is the manifest of the job that I try to launch:

apiVersion: "kubeflow.org/v1"
kind: PyTorchJob
metadata:
  name: elastic-example-imagenet-c10d-tcp
  namespace: default
spec:
  elasticPolicy:
    rdzvBackend: c10d
    minReplicas: 1
    maxReplicas: 5
    maxRestarts: 100
    metrics:
      - type: Resource
        resource:
          name: cpu
          target:
            type: Utilization
            averageUtilization: 50
  pytorchReplicaSpecs:
    Worker:
      replicas: 5
      restartPolicy: OnFailure
      template:
        spec:
          containers:
            - name: pytorch
              image: artprod.dev.bloomberg.com/ds/yzhang2343/elastic-imagenet:latest
              imagePullPolicy: Always
              resources:
                limits:
                  cpu: 1
                  memory: 8Gi
                requests:
                  cpu: 1
                  memory: 8Gi
              env:
              - name: LOGLEVEL
                value: DEBUG
              command:
                - python
                - -m
                - torch.distributed.run
                - --module
                - imagenet
                - "--arch=resnet18"
                - "--epochs=20"
                - "--batch-size=32"
                - "--workers=0"
                - "/workspace/data/tiny-imagenet-200"

The image contains the imagenet example training code from the examples given under this repo.

Cannot Find PyTorchJob Kind

The first problem I got is that HPA cannot find PyTorchJob Kind.

yzhang2343@C02WC268HTDD ds-repos % kubectl get horizontalpodautoscaler/elastic-example-imagenet-c10d-tcp -o yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  annotations:
    autoscaling.alpha.kubernetes.io/conditions: '[{"type":"AbleToScale","status":"False","lastTransitionTime":"2022-08-01T16:16:44Z","reason":"FailedGetScale","message":"the
      HPA controller was unable to get the target''s current scale: no matches for kind \"PyTorchJob\" in group \"\""}]'

According to this link, the HPA must specify .spec.scaleTargetRef.apiVersion so that it can successfully find the resource, but training-operator does not set this field while creating the HPA:

func desiredHPA(pytorchJob *kubeflowv1.PyTorchJob, scheme *runtime.Scheme) (
    *autoscalingv2beta2.HorizontalPodAutoscaler, error) {
    hpa := &autoscalingv2beta2.HorizontalPodAutoscaler{
        ObjectMeta: metav1.ObjectMeta{
            Name:      pytorchJob.Name,
            Namespace: pytorchJob.Namespace,
        },
        Spec: autoscalingv2beta2.HorizontalPodAutoscalerSpec{
            ScaleTargetRef: autoscalingv2beta2.CrossVersionObjectReference{
                // apiVersion: kubeflow.org/v1 should be set here
                Kind: pytorchJob.Kind,
                Name: pytorchJob.Name,
            },
            MinReplicas: pytorchJob.Spec.ElasticPolicy.MinReplicas,
            MaxReplicas: *pytorchJob.Spec.ElasticPolicy.MaxReplicas,
            Metrics:     pytorchJob.Spec.ElasticPolicy.Metrics,
        },
    }
    if err := controllerruntime.SetControllerReference(pytorchJob, hpa, scheme); err != nil {
        return nil, err
    }
    return hpa, nil
}

Missing a Selector

After I manually added the apiVersion to HPA, it could successfully find PyTorchJob kind but it still could not perform auto scaling because of this new error:

yzhang2343@C02WC268HTDD test % kubectl get horizontalpodautoscaler/elastic-example-imagenet-c10d-tcp -o yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  annotations:
    autoscaling.alpha.kubernetes.io/conditions: '[{"type":"AbleToScale","status":"True","lastTransitionTime":"2022-08-01T16:51:48Z","reason":"SucceededGetScale","message":"the
      HPA controller was able to get the target''s current scale"},{"type":"ScalingActive","status":"False","lastTransitionTime":"2022-08-01T16:51:48Z","reason":"InvalidSelector","message":"the
      HPA target''s scale is missing a selector"}]'

According to the Kubernetes HPA doc, the target resource should have a .spec.selector field so that HPA can find pods using the selectors. However, PyTorchJob struct does not have .spec.selector field at all:

type PyTorchJobSpec struct {
    // RunPolicy encapsulates various runtime policies of the distributed training
    // job, for example how to clean up resources and how long the job can stay
    // active.
    //+kubebuilder:validation:Optional
    RunPolicy commonv1.RunPolicy `json:"runPolicy"`

    ElasticPolicy *ElasticPolicy `json:"elasticPolicy,omitempty"`

    // A map of PyTorchReplicaType (type) to ReplicaSpec (value). Specifies the PyTorch cluster configuration.
    // For example,
    //   {
    //     "Master": PyTorchReplicaSpec,
    //     "Worker": PyTorchReplicaSpec,
    //   }
    PyTorchReplicaSpecs map[commonv1.ReplicaType]*commonv1.ReplicaSpec `json:"pytorchReplicaSpecs"`
}

The expected behavior is that a HorizontalPodAutoscaler should be launched successfully and the number of pods of the training job should be dynamically and automatically updated by HPA according to the resource utilization.

It seems to me that the training-operator's support for HPA is incomplete. Does anybody know how to launch elastic pytorch jobs with HPA? Thanks!

@johnugeorge
Copy link
Member

johnugeorge commented Aug 4, 2022

/cc @gaocegege
/cc @Jeffwan

@gaocegege
Copy link
Member

We defined the scale resource at https://github.com/kubeflow/training-operator/blob/master/manifests/base/crds/kubeflow.org_pytorchjobs.yaml#L8455

I will have a deep dive to see what happened here.

@zclyne
Copy link
Author

zclyne commented Aug 12, 2022

Thank you so much!

@johnugeorge
Copy link
Member

@zclyne Feel free to try this patch for the fix - #1701

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants