Skip to content

Commit

Permalink
feat: Added front end to kaito
Browse files Browse the repository at this point in the history
  • Loading branch information
ishaansehgal99 committed Mar 13, 2024
1 parent 4b3d3ba commit 44634aa
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 5 deletions.
33 changes: 32 additions & 1 deletion pkg/controllers/workspace_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ func (c *WorkspaceReconciler) addOrUpdateWorkspace(ctx context.Context, wObj *ka
return reconcile.Result{}, updateErr
}
return reconcile.Result{}, err
} else {

Check warning on line 119 in pkg/controllers/workspace_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/workspace_controller.go#L119

Added line #L119 was not covered by tests
// Given service and inference were successfully applied
wAnnotation := wObj.GetAnnotations()
if len(wAnnotation) != 0 {
val, found := wAnnotation[kaitov1alpha1.AnnotationEnableSampleFrontEnd]
if found && val == "True" {
if c.createSampleFrontEnd(ctx, wObj); err != nil {
klog.ErrorS(err, "failed to create sample front end", "workspace", klog.KObj(wObj))

Check warning on line 126 in pkg/controllers/workspace_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/workspace_controller.go#L121-L126

Added lines #L121 - L126 were not covered by tests
}
}
}
}

// TODO apply TrainingSpec
Expand Down Expand Up @@ -450,7 +461,6 @@ func (c *WorkspaceReconciler) applyInference(ctx context.Context, wObj *kaitov1a
existingObj = &appsv1.StatefulSet{}
} else {
existingObj = &appsv1.Deployment{}

}

if err = resources.GetResource(ctx, wObj.Name, wObj.Namespace, c.Client, existingObj); err == nil {
Expand Down Expand Up @@ -491,6 +501,27 @@ func (c *WorkspaceReconciler) applyInference(ctx context.Context, wObj *kaitov1a
return nil
}

func (c *WorkspaceReconciler) createSampleFrontEnd(ctx context.Context, wObj *kaitov1alpha1.Workspace) error {
deploymentName := wObj.Name + "-chainlit-sample-frontend"
if err := resources.GetResource(ctx, deploymentName, wObj.Namespace, c.Client, &appsv1.Deployment{}); err == nil {
klog.InfoS("A sample front end already exists for workspace", "workspace", klog.KObj(wObj))
if err = resources.CheckResourceStatus(&appsv1.Deployment{}, c.Client, time.Duration(10)*time.Minute); err != nil {
return err

Check warning on line 509 in pkg/controllers/workspace_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/workspace_controller.go#L504-L509

Added lines #L504 - L509 were not covered by tests
}
} else if apierrors.IsNotFound(err) {
var frontEndObj client.Object

Check warning on line 512 in pkg/controllers/workspace_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/workspace_controller.go#L511-L512

Added lines #L511 - L512 were not covered by tests
// Need to create a new workload
frontEndObj, err = inference.CreatePresetFrontEnd(ctx, wObj, c.Client)
if err != nil {
return err

Check warning on line 516 in pkg/controllers/workspace_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/workspace_controller.go#L514-L516

Added lines #L514 - L516 were not covered by tests
}
if err = resources.CheckResourceStatus(frontEndObj, c.Client, time.Duration(10)*time.Minute); err != nil {
return err

Check warning on line 519 in pkg/controllers/workspace_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/workspace_controller.go#L518-L519

Added lines #L518 - L519 were not covered by tests
}
}
return nil

Check warning on line 522 in pkg/controllers/workspace_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/workspace_controller.go#L522

Added line #L522 was not covered by tests
}

// SetupWithManager sets up the controller with the Manager.
func (c *WorkspaceReconciler) SetupWithManager(mgr ctrl.Manager) error {
c.Recorder = mgr.GetEventRecorderFor("Workspace")
Expand Down
9 changes: 9 additions & 0 deletions pkg/inference/preset-inferences.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ func CreatePresetInference(ctx context.Context, workspaceObj *kaitov1alpha1.Work
return depObj, nil
}

func CreatePresetFrontEnd(ctx context.Context, workspaceObj *kaitov1alpha1.Workspace, kubeClient client.Client) (client.Object, error) {
depObj := resources.GenerateFrontEndManifest(ctx, workspaceObj)
err := resources.CreateResource(ctx, depObj, kubeClient)
if client.IgnoreAlreadyExists(err) != nil {
return nil, err

Check warning on line 144 in pkg/inference/preset-inferences.go

View check run for this annotation

Codecov / codecov/patch

pkg/inference/preset-inferences.go#L140-L144

Added lines #L140 - L144 were not covered by tests
}
return depObj, nil

Check warning on line 146 in pkg/inference/preset-inferences.go

View check run for this annotation

Codecov / codecov/patch

pkg/inference/preset-inferences.go#L146

Added line #L146 was not covered by tests
}

// prepareInferenceParameters builds a PyTorch command:
// torchrun <TORCH_PARAMS> <OPTIONAL_RDZV_PARAMS> baseCommand <MODEL_PARAMS>
// and sets the GPU resources required for inference.
Expand Down
61 changes: 61 additions & 0 deletions pkg/resources/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package resources
import (
"context"
"fmt"
"k8s.io/utils/pointer"

"k8s.io/apimachinery/pkg/util/intstr"

Expand Down Expand Up @@ -53,6 +54,66 @@ func GenerateHeadlessServiceManifest(ctx context.Context, workspaceObj *kaitov1a
}
}

func GenerateFrontEndManifest(ctx context.Context, workspaceObj *kaitov1alpha1.Workspace) *appsv1.Deployment {
deploymentName := workspaceObj.Name + "-chainlit-sample-frontend"
serviceDNSName := workspaceObj.Name + "." + workspaceObj.Namespace + ".svc.cluster.local"

Check warning on line 59 in pkg/resources/manifests.go

View check run for this annotation

Codecov / codecov/patch

pkg/resources/manifests.go#L57-L59

Added lines #L57 - L59 were not covered by tests

return &appsv1.Deployment{
ObjectMeta: v1.ObjectMeta{
Name: deploymentName,
Namespace: workspaceObj.Namespace,
OwnerReferences: []v1.OwnerReference{

Check warning on line 65 in pkg/resources/manifests.go

View check run for this annotation

Codecov / codecov/patch

pkg/resources/manifests.go#L61-L65

Added lines #L61 - L65 were not covered by tests
{
APIVersion: kaitov1alpha1.GroupVersion.String(),
Kind: "Workspace",
Name: workspaceObj.Name,
UID: workspaceObj.UID,
Controller: pointer.BoolPtr(true),
},
},
},
Spec: appsv1.DeploymentSpec{
Replicas: pointer.Int32Ptr(1),
Selector: &v1.LabelSelector{
MatchLabels: map[string]string{
"app": deploymentName,
},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: v1.ObjectMeta{
Labels: map[string]string{
"app": deploymentName,
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{

Check warning on line 89 in pkg/resources/manifests.go

View check run for this annotation

Codecov / codecov/patch

pkg/resources/manifests.go#L67-L89

Added lines #L67 - L89 were not covered by tests
{
Name: "chainlit-frontend",
Image: "python:3.10-slim",
Command: []string{
"/bin/sh", "-c",
},
Args: []string{
"apt-get update && apt-get install -y wget && " +
"pip install chainlit requests && " +
"wget -O /app/frontend/chainlit.py https://raw.githubusercontent.com/Azure/kaito/main/presets/inference/text-generation/frontend/chainlit.py && " +
"chainlit run frontend/chainlit.py -w",
},
Env: []corev1.EnvVar{

Check warning on line 102 in pkg/resources/manifests.go

View check run for this annotation

Codecov / codecov/patch

pkg/resources/manifests.go#L91-L102

Added lines #L91 - L102 were not covered by tests
{
Name: "WORKSPACE_SERVICE_URL",
Value: "http://" + serviceDNSName + ":80",
},
},
WorkingDir: "/app",
},
},
},
},
},

Check warning on line 113 in pkg/resources/manifests.go

View check run for this annotation

Codecov / codecov/patch

pkg/resources/manifests.go#L104-L113

Added lines #L104 - L113 were not covered by tests
}
}

func GenerateServiceManifest(ctx context.Context, workspaceObj *kaitov1alpha1.Workspace, serviceType corev1.ServiceType, isStatefulSet bool) *corev1.Service {
selector := map[string]string{
kaitov1alpha1.LabelWorkspaceName: workspaceObj.Name,
Expand Down
8 changes: 4 additions & 4 deletions presets/inference/text-generation/frontend/chainlit.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import chainlit as cl
import requests
import os


URL = os.environ.get('WORKSPACE_SERVICE_URL')
@cl.step
def inference(prompt):
# Endpoint URL
url = "http://localhost:5000/chat"
data = {
"prompt": prompt,
"return_full_text": False,
Expand All @@ -15,15 +15,15 @@ def inference(prompt):
}
}

response = requests.post(url, json=data)
response = requests.post(URL, json=data)

if response.status_code == 200:
response_data = response.json()
return response_data.get("Result", "No result found")
else:
return f"Error: Received response code {response.status_code}"

@cl.on_message # this function will be called every time a user inputs a message in the UI
@cl.on_message
async def main(message: cl.Message):
"""
This function is called every time a user inputs a message in the UI.
Expand Down
28 changes: 28 additions & 0 deletions presets/test/manifests/frontend/frontend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-workspace-chainlit-frontend-deployment
spec:
replicas: 1
selector:
matchLabels:
app: my-workspace-chainlit-frontend
template:
metadata:
labels:
app: my-workspace-chainlit-frontend
spec:
containers:
- name: chainlit-frontend
image: python:3.10-slim
command: ["/bin/sh"]
args:
- -c
- |
pip install chainlit requests && \
wget -O /app/frontend/chainlit.py https://raw.githubusercontent.com/Azure/kaito/main/presets/inference/text-generation/frontend/chainlit.py && \
chainlit run frontend/chainlit.py -w
env:
- name: WORKSPACE_SERVICE_URL
value: http://my-workspace.my-namespace.svc.cluster.local:80
workingDir: /app

0 comments on commit 44634aa

Please sign in to comment.