diff --git a/api/v1alpha1/workspace_types.go b/api/v1alpha1/workspace_types.go index fea3a6f6e..2f966f647 100644 --- a/api/v1alpha1/workspace_types.go +++ b/api/v1alpha1/workspace_types.go @@ -60,7 +60,7 @@ type PresetOptions struct { // Image is the name of the containerized model image. // +optional Image string `json:"image,omitempty"` - // ImagePullSecrets is a list of secret names in the same namespace used for pulling the image. + // ImagePullSecrets is a list of secret names in the same namespace used for pulling the model image. // +optional ImagePullSecrets []string `json:"imagePullSecrets,omitempty"` } @@ -73,7 +73,7 @@ type PresetSpec struct { } type InferenceSpec struct { - // Preset describles the model that will be deployed with preset configurations. + // Preset describes the base model that will be deployed with preset configurations. // +optional Preset *PresetSpec `json:"preset,omitempty"` // Template specifies the Pod template used to run the inference service. Users can specify custom Pod settings @@ -83,6 +83,76 @@ type InferenceSpec struct { // +kubebuilder:validation:Schemaless // +optional Template *v1.PodTemplateSpec `json:"template,omitempty"` + // Adapters are integrated into the base model for inference. + // Users can specify multiple adapters for the model and the respective weight of using each of them. + // +optional + Adapters []AdapterSpec `json:"adapters,omitempty"` +} + +type AdapterSpec struct { + // Source describes where to obtain the adapter data. + // +optional + Source *DataSource `json:"source,omitempty"` + // Strength specifies the default multiplier for applying the adapter weights to the raw model weights. + // It is usually a float number between 0 and 1. It is defined as a string type to be language agnostic. + // +optional + Strength *string `json:"strength,omitempty"` +} + +type DataSource struct { + // The name of the dataset. The same name will be used as a container name. + // It must be a valid DNS subdomain value, + Name string `json:"name,omitempty"` + // URLs specifies the links to the public data sources. E.g., files in a public github repository. + // +optional + URLs []string `json:"urls,omitempty"` + // The directory in the hsot that contains the data. + // +optional + HostPath string `json:"hostPath,omitempty"` + // The name of the image that contains the source data. The assumption is that the source data locates in the + // `data` directory in the image. + // +optional + Image string `json:"image,omitempty"` + // ImagePullSecrets is a list of secret names in the same namespace used for pulling the data image. + // +optional + ImagePullSecrets []string `json:"imagePullSecrets,omitempty"` +} + +type DataDestination struct { + // The directory in the host that contains the output data. + // +optional + HostPath string `json:"hostPath,omitempty"` + // Name of the image where the output data is pushed to. + // +optional + Image string `json:"image,omitempty"` + // ImagePushSecret is the name of the secret in the same namespace that contains the authentication + // information that is needed for running `docker push`. + // +optional + ImagePushSecret string `json:"imagePushSecret,omitempty"` +} + +type TuningMethod string + +const ( + TuningMethodLora TuningMethod = "lora" + TuningMethodQLora TuningMethod = "qlora" +) + +type TuningSpec struct { + // Preset describes which model to load for tuning. + // +optional + Preset *PresetSpec `json:"preset,omitempty"` + // Method specifies the Parameter-Efficient Fine-Tuning(PEFT) method, such as lora, qlora, used for the tuning. + // +optional + Method TuningMethod `json:"method,omitempty"` + // Config specifies the name of the configmap in the same namespace that contains the arguments used by the tuning method. + // If not specified, a default configmap is used based on the specified method. + // +optional + Config string `json:"config,omitempty"` + // Input describes the input used by the tuning method. + Input *DataSource `json:"input,omitempty"` + // Output specified where to store the tuning output. + Output *DataDestination `json:"output,omitempty"` } // WorkspaceStatus defines the observed state of Workspace @@ -112,6 +182,7 @@ type Workspace struct { Resource ResourceSpec `json:"resource,omitempty"` Inference InferenceSpec `json:"inference,omitempty"` + Tuning TuningSpec `json:"tuning,omitempty"` Status WorkspaceStatus `json:"status,omitempty"` } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 6bab34c9f..a9d662c0f 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -14,6 +14,71 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdapterSpec) DeepCopyInto(out *AdapterSpec) { + *out = *in + if in.Source != nil { + in, out := &in.Source, &out.Source + *out = new(DataSource) + (*in).DeepCopyInto(*out) + } + if in.Strength != nil { + in, out := &in.Strength, &out.Strength + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdapterSpec. +func (in *AdapterSpec) DeepCopy() *AdapterSpec { + if in == nil { + return nil + } + out := new(AdapterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DataDestination) DeepCopyInto(out *DataDestination) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataDestination. +func (in *DataDestination) DeepCopy() *DataDestination { + if in == nil { + return nil + } + out := new(DataDestination) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DataSource) DeepCopyInto(out *DataSource) { + *out = *in + if in.URLs != nil { + in, out := &in.URLs, &out.URLs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ImagePullSecrets != nil { + in, out := &in.ImagePullSecrets, &out.ImagePullSecrets + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataSource. +func (in *DataSource) DeepCopy() *DataSource { + if in == nil { + return nil + } + out := new(DataSource) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GPUConfig) DeepCopyInto(out *GPUConfig) { *out = *in @@ -47,6 +112,13 @@ func (in *InferenceSpec) DeepCopyInto(out *InferenceSpec) { *out = new(corev1.PodTemplateSpec) (*in).DeepCopyInto(*out) } + if in.Adapters != nil { + in, out := &in.Adapters, &out.Adapters + *out = make([]AdapterSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InferenceSpec. @@ -141,6 +213,36 @@ func (in *ResourceSpec) DeepCopy() *ResourceSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TuningSpec) DeepCopyInto(out *TuningSpec) { + *out = *in + if in.Preset != nil { + in, out := &in.Preset, &out.Preset + *out = new(PresetSpec) + (*in).DeepCopyInto(*out) + } + if in.Input != nil { + in, out := &in.Input, &out.Input + *out = new(DataSource) + (*in).DeepCopyInto(*out) + } + if in.Output != nil { + in, out := &in.Output, &out.Output + *out = new(DataDestination) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TuningSpec. +func (in *TuningSpec) DeepCopy() *TuningSpec { + if in == nil { + return nil + } + out := new(TuningSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Workspace) DeepCopyInto(out *Workspace) { *out = *in @@ -148,6 +250,7 @@ func (in *Workspace) DeepCopyInto(out *Workspace) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Resource.DeepCopyInto(&out.Resource) in.Inference.DeepCopyInto(&out.Inference) + in.Tuning.DeepCopyInto(&out.Tuning) in.Status.DeepCopyInto(&out.Status) } diff --git a/config/crd/bases/kaito.sh_workspaces.yaml b/config/crd/bases/kaito.sh_workspaces.yaml index 40908f609..b3af23a76 100644 --- a/config/crd/bases/kaito.sh_workspaces.yaml +++ b/config/crd/bases/kaito.sh_workspaces.yaml @@ -47,9 +47,53 @@ spec: type: string inference: properties: + adapters: + description: Adapters are integrated into the base model for inference. + Users can specify multiple adapters for the model and the respective + weight of using each of them. + items: + properties: + source: + description: Source describes where to obtain the adapter data. + properties: + hostPath: + description: The directory in the hsot that contains the + data. + type: string + image: + description: The name of the image that contains the source + data. The assumption is that the source data locates in + the `data` directory in the image. + type: string + imagePullSecrets: + description: ImagePullSecrets is a list of secret names + in the same namespace used for pulling the data image. + items: + type: string + type: array + name: + description: The name of the dataset. The same name will + be used as a container name. It must be a valid DNS subdomain + value, + type: string + urls: + description: URLs specifies the links to the public data + sources. E.g., files in a public github repository. + items: + type: string + type: array + type: object + strength: + description: Strength specifies the default multiplier for applying + the adapter weights to the raw model weights. It is usually + a float number between 0 and 1. It is defined as a string + type to be language agnostic. + type: string + type: object + type: array preset: - description: Preset describles the model that will be deployed with - preset configurations. + description: Preset describes the base model that will be deployed + with preset configurations. properties: accessMode: description: AccessMode specifies whether the containerized model @@ -72,7 +116,7 @@ spec: type: string imagePullSecrets: description: ImagePullSecrets is a list of secret names in - the same namespace used for pulling the image. + the same namespace used for pulling the model image. items: type: string type: array @@ -245,6 +289,96 @@ spec: type: string type: array type: object + tuning: + properties: + config: + description: Config specifies the name of the configmap in the same + namespace that contains the arguments used by the tuning method. + If not specified, a default configmap is used based on the specified + method. + type: string + input: + description: Input describes the input used by the tuning method. + properties: + hostPath: + description: The directory in the hsot that contains the data. + type: string + image: + description: The name of the image that contains the source data. + The assumption is that the source data locates in the `data` + directory in the image. + type: string + imagePullSecrets: + description: ImagePullSecrets is a list of secret names in the + same namespace used for pulling the data image. + items: + type: string + type: array + name: + description: The name of the dataset. The same name will be used + as a container name. It must be a valid DNS subdomain value, + type: string + urls: + description: URLs specifies the links to the public data sources. + E.g., files in a public github repository. + items: + type: string + type: array + type: object + method: + description: Method specifies the Parameter-Efficient Fine-Tuning(PEFT) + method, such as lora, qlora, used for the tuning. + type: string + output: + description: Output specified where to store the tuning output. + properties: + hostPath: + description: The directory in the host that contains the output + data. + type: string + image: + description: Name of the image where the output data is pushed + to. + type: string + imagePushSecret: + description: ImagePushSecret is the name of the secret in the + same namespace that contains the authentication information + that is needed for running `docker push`. + type: string + type: object + preset: + description: Preset describes which model to load for tuning. + properties: + accessMode: + description: AccessMode specifies whether the containerized model + image is accessible via public registry or private registry. + This field defaults to "public" if not specified. If this field + is "private", user needs to provide the private image information + in PresetOptions. + enum: + - public + - private + type: string + name: + description: Name of the supported models with preset configurations. + type: string + presetOptions: + properties: + image: + description: Image is the name of the containerized model + image. + type: string + imagePullSecrets: + description: ImagePullSecrets is a list of secret names in + the same namespace used for pulling the model image. + items: + type: string + type: array + type: object + required: + - name + type: object + type: object type: object served: true storage: true