Skip to content

Commit 4983dbe

Browse files
committed
[Feat]: Add support for chatTemplates
Signed-off-by: Mahmoud Farouk <[email protected]>
1 parent ab2c023 commit 4983dbe

File tree

3 files changed

+131
-7
lines changed

3 files changed

+131
-7
lines changed

operator/api/v1alpha1/vllmruntime_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ type ModelSpec struct {
122122

123123
// Maximum number of sequences
124124
MaxNumSeqs int32 `json:"maxNumSeqs,omitempty"`
125+
126+
// Chat template
127+
ChatTemplate string `json:"chatTemplate,omitempty"`
125128
}
126129

127130
// LMCacheConfig defines the LM Cache configuration

operator/config/crd/bases/production-stack.vllm.ai_vllmruntimes.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ spec:
181181
model:
182182
description: Model configuration
183183
properties:
184+
chatTemplate:
185+
description: Chat template
186+
type: string
184187
dtype:
185188
description: Data type
186189
type: string

operator/internal/controller/vllmruntime_controller.go

Lines changed: 125 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,70 @@ func (r *VLLMRuntimeReconciler) Reconcile(ctx context.Context, req ctrl.Request)
143143
}
144144
}
145145

146+
if vllmRuntime.Spec.Model.ChatTemplate != "" {
147+
foundCM := &corev1.ConfigMap{}
148+
err := r.Get(ctx, types.NamespacedName{
149+
Name: vllmRuntime.Name + "-chat-template",
150+
Namespace: vllmRuntime.Namespace,
151+
}, foundCM)
152+
153+
if err != nil {
154+
if errors.IsNotFound(err) {
155+
ct := r.configMapForVLLMRuntime(vllmRuntime)
156+
log.Info(
157+
"Creating a new ConfigMap",
158+
"ConfigMap.Namespace",
159+
ct.Namespace,
160+
"ConfigMap.Name",
161+
ct.Name,
162+
)
163+
164+
if err := r.Create(ctx, ct); err != nil {
165+
log.Error(
166+
err,
167+
"failed to create new ConfigMap",
168+
"ConfigMap.Namespace",
169+
ct.Namespace,
170+
"ConfigMap.Name",
171+
ct.Name,
172+
)
173+
174+
return ctrl.Result{}, err
175+
} else {
176+
return ctrl.Result{Requeue: true}, nil
177+
}
178+
}
179+
180+
return ctrl.Result{}, err
181+
}
182+
183+
if r.configMapNeedsUpdate(foundCM, vllmRuntime) {
184+
log.Info(
185+
"Updating ConfigMap",
186+
"ConfigMap.Namespace",
187+
foundCM.Namespace,
188+
"ConfigMap.Name",
189+
foundCM.Name,
190+
)
191+
192+
newCT := r.configMapForVLLMRuntime(vllmRuntime)
193+
if err := r.Update(ctx, newCT); err != nil {
194+
log.Error(
195+
err,
196+
"failed to update ConfigMap",
197+
"cm.Namespace",
198+
foundCM.Namespace,
199+
"cm.Name",
200+
foundCM.Name,
201+
)
202+
203+
return ctrl.Result{}, err
204+
}
205+
206+
return ctrl.Result{Requeue: true}, nil
207+
}
208+
}
209+
146210
// Check if the deployment already exists, if not create a new one
147211
found := &appsv1.Deployment{}
148212
err = r.Get(ctx, types.NamespacedName{Name: vllmRuntime.Name, Namespace: vllmRuntime.Namespace}, found)
@@ -299,6 +363,10 @@ func (r *VLLMRuntimeReconciler) deploymentForVLLMRuntime(vllmRuntime *production
299363
args = append(args, vllmRuntime.Spec.VLLMConfig.ExtraArgs...)
300364
}
301365

366+
if vllmRuntime.Spec.Model.ChatTemplate != "" {
367+
args = append(args, "--chat-template", "/etc/chat-template.json")
368+
}
369+
302370
// Build environment variables
303371
env := []corev1.EnvVar{}
304372
if vllmRuntime.Spec.VLLMConfig.V1 {
@@ -480,6 +548,34 @@ func (r *VLLMRuntimeReconciler) deploymentForVLLMRuntime(vllmRuntime *production
480548
})
481549
}
482550

551+
if vllmRuntime.Spec.Model.ChatTemplate != "" {
552+
volumeName := "chat-template"
553+
mountPath := "/etc/chat-template.json"
554+
555+
volumes = append(volumes, corev1.Volume{
556+
Name: volumeName,
557+
VolumeSource: corev1.VolumeSource{
558+
ConfigMap: &corev1.ConfigMapVolumeSource{
559+
LocalObjectReference: corev1.LocalObjectReference{
560+
Name: vllmRuntime.Name + "-" + volumeName,
561+
},
562+
Items: []corev1.KeyToPath{
563+
{
564+
Key: "chatTemplate",
565+
Path: "chat_template.json",
566+
},
567+
},
568+
},
569+
},
570+
})
571+
572+
volumeMounts = append(volumeMounts, corev1.VolumeMount{
573+
Name: volumeName,
574+
MountPath: mountPath,
575+
SubPath: "chat_template.json",
576+
})
577+
}
578+
483579
containers := []corev1.Container{
484580
{
485581
Name: "vllm",
@@ -784,11 +880,8 @@ func (r *VLLMRuntimeReconciler) serviceNeedsUpdate(svc *corev1.Service, vr *prod
784880
// Compare target port
785881
expectedTargetPort := int(vr.Spec.VLLMConfig.Port)
786882
actualTargetPort := svc.Spec.Ports[0].TargetPort.IntValue()
787-
if expectedTargetPort != actualTargetPort {
788-
return true
789-
}
790883

791-
return false
884+
return expectedTargetPort != actualTargetPort
792885
}
793886

794887
// pvcForVLLMRuntime returns a VLLMRuntime PVC object
@@ -850,11 +943,35 @@ func (r *VLLMRuntimeReconciler) pvcNeedsUpdate(pvc *corev1.PersistentVolumeClaim
850943
expectedSize = vr.Spec.StorageConfig.Size
851944
}
852945
actualSize := pvc.Spec.Resources.Requests[corev1.ResourceStorage]
853-
if expectedSize != actualSize.String() {
854-
return true
946+
947+
return expectedSize != actualSize.String()
948+
}
949+
950+
func (r *VLLMRuntimeReconciler) configMapForVLLMRuntime(
951+
vr *productionstackv1alpha1.VLLMRuntime,
952+
) *corev1.ConfigMap {
953+
cm := &corev1.ConfigMap{
954+
ObjectMeta: metav1.ObjectMeta{
955+
Name: vr.Name + "-chat-template",
956+
Namespace: vr.Namespace,
957+
},
958+
Data: map[string]string{
959+
"chatTemplate": vr.Spec.Model.ChatTemplate,
960+
},
855961
}
856962

857-
return false
963+
ctrl.SetControllerReference(vr, cm, r.Scheme)
964+
return cm
965+
}
966+
967+
func (r *VLLMRuntimeReconciler) configMapNeedsUpdate(
968+
cm *corev1.ConfigMap,
969+
vr *productionstackv1alpha1.VLLMRuntime,
970+
) bool {
971+
actualData := cm.Data["chatTemplate"]
972+
currentData := vr.Spec.Model.ChatTemplate
973+
974+
return actualData != currentData
858975
}
859976

860977
// SetupWithManager sets up the controller with the Manager.
@@ -864,5 +981,6 @@ func (r *VLLMRuntimeReconciler) SetupWithManager(mgr ctrl.Manager) error {
864981
Owns(&appsv1.Deployment{}).
865982
Owns(&corev1.Service{}).
866983
Owns(&corev1.PersistentVolumeClaim{}).
984+
Owns(&corev1.ConfigMap{}).
867985
Complete(r)
868986
}

0 commit comments

Comments
 (0)