From e0c1b721119a4135a01deec975967cdb115b0129 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Mon, 18 Mar 2024 15:00:59 -0500 Subject: [PATCH 1/8] feat: add liveness and readiness probes --- charts/local-ai/templates/deployment.yaml | 8 ++++++++ charts/local-ai/values.yaml | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/charts/local-ai/templates/deployment.yaml b/charts/local-ai/templates/deployment.yaml index d8dcbe4..bfbfdc7 100644 --- a/charts/local-ai/templates/deployment.yaml +++ b/charts/local-ai/templates/deployment.yaml @@ -235,6 +235,14 @@ spec: imagePullPolicy: {{ .Values.deployment.pullPolicy }} resources: {{- toYaml .Values.resources | nindent 12 }} + ports: + - containerPort: 8080 + name: http + protocol: TCP + livenessProbe: + {{- toYaml .Values.livenessProbe | nindent 12 }} + readinessProbe: + {{- toYaml .Values.readinessProbe | nindent 12 }} env: {{- range $key, $value := .Values.deployment.env }} - name: {{ $key | upper }} diff --git a/charts/local-ai/values.yaml b/charts/local-ai/values.yaml index b1dbbe1..da6a855 100644 --- a/charts/local-ai/values.yaml +++ b/charts/local-ai/values.yaml @@ -34,6 +34,16 @@ resources: # cpu: 100m # memory: 128Mi +livenessProbe: + httpGet: + path: /healthz + port: http +readinessProbe: + httpGet: + path: /readyz + port: http + + # Prompt templates to include # Note: the keys of this map will be the names of the prompt template files promptTemplates: From 91590038c2112b1715e0863b59e254dd738802f5 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Mon, 18 Mar 2024 15:34:30 -0500 Subject: [PATCH 2/8] fix: indentation and use more modern label templates --- charts/local-ai/templates/_helpers.tpl | 26 +++++++++++++++++------ charts/local-ai/templates/deployment.yaml | 19 ++++++++--------- charts/local-ai/templates/service.yaml | 14 ++++++------ charts/local-ai/values.yaml | 23 ++++++++++++++++++++ 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/charts/local-ai/templates/_helpers.tpl b/charts/local-ai/templates/_helpers.tpl index 7f06ef3..eaf56ee 100644 --- a/charts/local-ai/templates/_helpers.tpl +++ b/charts/local-ai/templates/_helpers.tpl @@ -36,16 +36,28 @@ Common labels */}} {{- define "local-ai.labels" -}} helm.sh/chart: {{ include "local-ai.chart" . }} -app.kubernetes.io/name: {{ include "local-ai.name" . }} -app.kubernetes.io/instance: "{{ .Release.Name }}" -app.kubernetes.io/managed-by: {{ .Release.Service }} +{{ include "local-ai.selectorLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end }} -# Add defaults for global.labels and global.annotations -{{- define "local-ai.annotations" -}} - {} -{{- end -}} +{{/* +Selector labels +*/}} +{{- define "local-ai.selectorLabels" -}} +app.kubernetes.io/name: {{ include "local-ai.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{/* +Create the name of the service account to use +*/}} +{{- define "local-ai.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "local-ai.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/local-ai/templates/deployment.yaml b/charts/local-ai/templates/deployment.yaml index bfbfdc7..4fc541c 100644 --- a/charts/local-ai/templates/deployment.yaml +++ b/charts/local-ai/templates/deployment.yaml @@ -15,8 +15,7 @@ metadata: spec: selector: matchLabels: - app.kubernetes.io/name: {{ include "local-ai.name" . }} - app.kubernetes.io/instance: {{ .Release.Name }} + {{- include "local-ai.selectorLabels" . | nindent 6 }} replicas: {{ .Values.replicaCount }} template: metadata: @@ -191,24 +190,24 @@ spec: {{- end }} {{- if .args }} args: - {{- toYaml .args | nindent 6 }} + {{- toYaml .args | nindent 12 }} {{- end }} {{- if .env }} env: - {{- toYaml .env | nindent 6 }} + {{- toYaml .env | nindent 12 }} {{- end }} {{- if .ports }} ports: - {{- toYaml .ports | nindent 6 }} + {{- toYaml .ports | nindent 12 }} {{- end }} {{- if .resources }} resources: - {{- toYaml .resources | nindent 6 }} + {{- toYaml .resources | nindent 12 }} {{- end }} {{- if or .volumeMounts $rootPersistence }} volumeMounts: {{- if .volumeMounts }} - {{- toYaml .volumeMounts | nindent 6 }} + {{- toYaml .volumeMounts | nindent 12 }} {{- end }} {{- range $key, $pvc := $rootPersistence }} {{- if $pvc.enabled }} @@ -219,15 +218,15 @@ spec: {{- end }} {{- if .livenessProbe }} livenessProbe: - {{- toYaml .livenessProbe | nindent 6 }} + {{- toYaml .livenessProbe | nindent 12 }} {{- end }} {{- if .readinessProbe }} readinessProbe: - {{- toYaml .readinessProbe | nindent 6 }} + {{- toYaml .readinessProbe | nindent 12 }} {{- end }} {{- if .securityContext }} securityContext: - {{- toYaml .securityContext | nindent 6 }} + {{- toYaml .securityContext | nindent 12 }} {{- end }} {{- end }} - name: {{ template "local-ai.fullname" . }} diff --git a/charts/local-ai/templates/service.yaml b/charts/local-ai/templates/service.yaml index 203d4fc..cd268dd 100644 --- a/charts/local-ai/templates/service.yaml +++ b/charts/local-ai/templates/service.yaml @@ -10,14 +10,14 @@ metadata: {{ toYaml .Values.service.annotations | nindent 4 }} {{- end }} spec: - selector: - app.kubernetes.io/name: {{ include "local-ai.name" . }} type: "{{ .Values.service.type }}" + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "local-ai.selectorLabels" . | nindent 4 }} {{- if .Values.service.externalTrafficPolicy }} externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} {{- end }} - ports: - - protocol: TCP - port: {{ .Values.service.port }} - targetPort: 8080 - name: http diff --git a/charts/local-ai/values.yaml b/charts/local-ai/values.yaml index da6a855..69ab29c 100644 --- a/charts/local-ai/values.yaml +++ b/charts/local-ai/values.yaml @@ -76,6 +76,18 @@ initContainers: [] # mountPath: /path/to/mount sidecarContainers: [] +# - name: model-loader +# image: quay.io/kiwigrid/k8s-sidecar:1.26.1 +# imagePullPolicy: IfNotPresent +# env: +# - name: LABEL +# value: io.localai/model_source +# - name: LABEL_VALUE +# value: "1" +# - name: METHOD +# value: WATCH +# - name: FOLDER +# value: /models # Example: # - name: my-sidecar-container # image: my-sidecar-image @@ -129,6 +141,17 @@ ingress: # hosts: # - chart-example.local +serviceAccount: + # Specifies whether a service account should be created + create: true + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + nodeSelector: {} tolerations: [] From 9c804120ebdd62d42bc4adca6f58276da133ab07 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Mon, 18 Mar 2024 17:48:08 -0500 Subject: [PATCH 3/8] feat: add sidecar to get model configurations from configMaps --- charts/local-ai/templates/_sidecars.tpl | 74 +++++++++++++++++++ charts/local-ai/templates/configmap.yaml | 18 +++++ charts/local-ai/templates/deployment.yaml | 65 ++++------------ charts/local-ai/templates/role.yaml | 19 +++++ charts/local-ai/templates/roleBinding.yaml | 24 ++++++ charts/local-ai/templates/serviceaccount.yaml | 13 ++++ charts/local-ai/values.yaml | 39 +++++++--- 7 files changed, 188 insertions(+), 64 deletions(-) create mode 100644 charts/local-ai/templates/_sidecars.tpl create mode 100644 charts/local-ai/templates/configmap.yaml create mode 100644 charts/local-ai/templates/role.yaml create mode 100644 charts/local-ai/templates/roleBinding.yaml create mode 100644 charts/local-ai/templates/serviceaccount.yaml diff --git a/charts/local-ai/templates/_sidecars.tpl b/charts/local-ai/templates/_sidecars.tpl new file mode 100644 index 0000000..d2266ad --- /dev/null +++ b/charts/local-ai/templates/_sidecars.tpl @@ -0,0 +1,74 @@ +{{- define "local-ai.sidecars" }} +{{- range .Values.sidecarContainers }} +# Sidecar container from values.yaml +- name: {{ .name }} + image: {{ .image }} + imagePullPolicy: {{ .imagePullPolicy }} + {{- if .command }} + command: + {{- toYaml .command | nindent 12 }} + {{- end }} + {{- if .args }} + args: + {{- toYaml .args | nindent 12 }} + {{- end }} + {{- if .env }} + env: + {{- toYaml .env | nindent 12 }} + {{- end }} + {{- if .ports }} + ports: + {{- toYaml .ports | nindent 12 }} + {{- end }} + {{- if .resources }} + resources: + {{- toYaml .resources | nindent 12 }} + {{- end }} + {{- if or .volumeMounts .Values.persistence }} + volumeMounts: + {{- if .volumeMounts }} + {{- toYaml .volumeMounts | nindent 12 }} + {{- end }} + {{- range $key, $pvc := .Values.persistence }} + {{- if $pvc.enabled }} + - name: {{ $key }} + mountPath: {{ $pvc.globalMount | default (print "/" $key) }} + {{- end }} + {{- end }} + {{- end }} + {{- if .livenessProbe }} + livenessProbe: + {{- toYaml .livenessProbe | nindent 12 }} + {{- end }} + {{- if .readinessProbe }} + readinessProbe: + {{- toYaml .readinessProbe | nindent 12 }} + {{- end }} + {{- if .securityContext }} + securityContext: + {{- toYaml .securityContext | nindent 12 }} + {{- end }} +{{- end }} +{{ if .Values.enableModelSyncronizationSidecar }} +# Built in sidecar for model syncronization +- name: model-loader + image: quay.io/kiwigrid/k8s-sidecar:1.26.1 + imagePullPolicy: IfNotPresent + env: + - name: LABEL + value: io.localai/model_source + - name: LABEL_VALUE + value: "1" + - name: METHOD + value: WATCH + - name: FOLDER + value: {{ .Values.deployment.modelsPath }} + - name: FOLDER_ANNOTATION + value: "io.localai/target-directory" + securityContext: + runAsGroup: 1000 + volumeMounts: + - mountPath: {{ .Values.deployment.modelsPath }} + name: models +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/local-ai/templates/configmap.yaml b/charts/local-ai/templates/configmap.yaml new file mode 100644 index 0000000..a36e830 --- /dev/null +++ b/charts/local-ai/templates/configmap.yaml @@ -0,0 +1,18 @@ +{{- if .Values.models.configs }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "local-ai.fullname" . }}-models + labels: + {{- include "local-ai.labels" . | nindent 4 }} + io.localai/model_source: "1" + {{- with .Values.annotations }} + annotations: + io.localai/target-directory: /models + {{- end }} +data: + {{- range $key, $data := .Values.models.configs}} + {{ if or (hasSuffix $key ".yml") (hasSuffix $key ".yaml") }}{{ $key }}{{ else }}{{ $key }}.yaml{{ end }}: |- + {{- $data | toYaml | nindent 4}} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/local-ai/templates/deployment.yaml b/charts/local-ai/templates/deployment.yaml index 4fc541c..5518c26 100644 --- a/charts/local-ai/templates/deployment.yaml +++ b/charts/local-ai/templates/deployment.yaml @@ -35,6 +35,7 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} + serviceAccountName: {{ include "local-ai.serviceAccountName" . }} initContainers: # Additional initContainers from values.yaml {{- if .Values.initContainers }} @@ -85,6 +86,8 @@ spec: args: - | cp -fL /prompt-templates/* /models + securityContext: + runAsGroup: 1000 volumeMounts: - mountPath: /prompt-templates name: prompt-templates @@ -179,56 +182,6 @@ spec: {{- end }} containers: - # Sidecar containers from values.yaml - {{- range .Values.sidecarContainers }} - - name: {{ .name }} - image: {{ .image }} - imagePullPolicy: {{ .imagePullPolicy }} - {{- if .command }} - command: - {{- toYaml .command | nindent 12 }} - {{- end }} - {{- if .args }} - args: - {{- toYaml .args | nindent 12 }} - {{- end }} - {{- if .env }} - env: - {{- toYaml .env | nindent 12 }} - {{- end }} - {{- if .ports }} - ports: - {{- toYaml .ports | nindent 12 }} - {{- end }} - {{- if .resources }} - resources: - {{- toYaml .resources | nindent 12 }} - {{- end }} - {{- if or .volumeMounts $rootPersistence }} - volumeMounts: - {{- if .volumeMounts }} - {{- toYaml .volumeMounts | nindent 12 }} - {{- end }} - {{- range $key, $pvc := $rootPersistence }} - {{- if $pvc.enabled }} - - name: {{ $key }} - mountPath: {{ $pvc.globalMount | default (print "/" $key) }} - {{- end }} - {{- end }} - {{- end }} - {{- if .livenessProbe }} - livenessProbe: - {{- toYaml .livenessProbe | nindent 12 }} - {{- end }} - {{- if .readinessProbe }} - readinessProbe: - {{- toYaml .readinessProbe | nindent 12 }} - {{- end }} - {{- if .securityContext }} - securityContext: - {{- toYaml .securityContext | nindent 12 }} - {{- end }} - {{- end }} - name: {{ template "local-ai.fullname" . }} image: "{{ .Values.deployment.image.repository }}:{{ .Values.deployment.image.tag }}" imagePullPolicy: {{ .Values.deployment.pullPolicy }} @@ -247,8 +200,12 @@ spec: - name: {{ $key | upper }} value: {{ quote $value }} {{- end }} + - name: GALLERIES + value: {{ .Values.models.galleries | dict }} - name: MODELS_PATH value: {{ .Values.deployment.modelsPath }} + securityContext: + runAsGroup: 1000 volumeMounts: {{- range $key, $pvc := $rootPersistence}} {{- if $pvc.enabled }} @@ -256,14 +213,18 @@ spec: mountPath: {{ $pvc.globalMount | default (print "/" $key) }} {{- end }} {{- end }} + {{ include "local-ai.sidecars" . | nindent 8 }} {{- if $rootPersistence}} volumes: {{- range $key, $pvc := $rootPersistence}} - {{- if $pvc.enabled }} + {{- if $pvc.enabled }} - name: {{ $key }} persistentVolumeClaim: claimName: {{ printf "%s-%s" (include "local-ai.fullname" $) $key }} - {{- end }} + {{- else }} + - name: {{ $key }} + emptyDir: {} + {{- end }} {{- end }} - name: prompt-templates configMap: diff --git a/charts/local-ai/templates/role.yaml b/charts/local-ai/templates/role.yaml new file mode 100644 index 0000000..3e5fa26 --- /dev/null +++ b/charts/local-ai/templates/role.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.rbac.create (not .Values.rbac.useExistingRole) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "local-ai.fullname" . }} + labels: + {{- include "local-ai.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] + {{- with .Values.rbac.extraRoleRules }} + {{- toYaml . | nindent 2 }} + {{- end}} +{{- end }} diff --git a/charts/local-ai/templates/roleBinding.yaml b/charts/local-ai/templates/roleBinding.yaml new file mode 100644 index 0000000..6d45e6f --- /dev/null +++ b/charts/local-ai/templates/roleBinding.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "local-ai.fullname" . }} + labels: + {{- include "local-ai.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + {{- if .Values.rbac.useExistingRole }} + name: {{ .Values.rbac.useExistingRole }} + {{- else }} + name: {{ include "local-ai.fullname" . }} + {{- end }} +subjects: +- kind: ServiceAccount + name: {{ include "local-ai.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/charts/local-ai/templates/serviceaccount.yaml b/charts/local-ai/templates/serviceaccount.yaml new file mode 100644 index 0000000..330fad0 --- /dev/null +++ b/charts/local-ai/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "local-ai.serviceAccountName" . }} + labels: + {{- include "local-ai.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/charts/local-ai/values.yaml b/charts/local-ai/values.yaml index 69ab29c..cc19f02 100644 --- a/charts/local-ai/values.yaml +++ b/charts/local-ai/values.yaml @@ -56,6 +56,18 @@ promptTemplates: # Models to download at runtime models: + configs: {} + # myModel: + # backend: llama + # context_size: 2048 + # name: myModel + # parameters: + # model: some_file.gguf + # temperature: 0.1 + # top_p: 0.95 + # threads: 5 + # f16: true + # gpu_layers: 33 # Whether to force download models even if they already exist forceDownload: false @@ -75,19 +87,8 @@ initContainers: [] # - name: my-volume # mountPath: /path/to/mount +enableModelSyncronizationSidecar: true sidecarContainers: [] -# - name: model-loader -# image: quay.io/kiwigrid/k8s-sidecar:1.26.1 -# imagePullPolicy: IfNotPresent -# env: -# - name: LABEL -# value: io.localai/model_source -# - name: LABEL_VALUE -# value: "1" -# - name: METHOD -# value: WATCH -# - name: FOLDER -# value: /models # Example: # - name: my-sidecar-container # image: my-sidecar-image @@ -141,6 +142,20 @@ ingress: # hosts: # - chart-example.local +rbac: + create: true + ## Use an existing ClusterRole/Role (depending on rbac.namespaced false/true) + # useExistingRole: name-of-some-role + # useExistingClusterRole: name-of-some-clusterRole + namespaced: false + extraRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] + extraClusterRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] serviceAccount: # Specifies whether a service account should be created create: true From ab509d73551f4aea884f0077da60ddef0e484a89 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Mon, 18 Mar 2024 19:36:40 -0500 Subject: [PATCH 4/8] feat: configure model-galleries via Helm --- charts/local-ai/templates/_helpers.tpl | 11 +++++++++++ charts/local-ai/templates/deployment.yaml | 2 +- charts/local-ai/values.yaml | 5 +++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/charts/local-ai/templates/_helpers.tpl b/charts/local-ai/templates/_helpers.tpl index eaf56ee..da65ab7 100644 --- a/charts/local-ai/templates/_helpers.tpl +++ b/charts/local-ai/templates/_helpers.tpl @@ -60,4 +60,15 @@ Create the name of the service account to use {{- else }} {{- default "default" .Values.serviceAccount.name }} {{- end }} +{{- end }} + +{{/* +Preprocess the models.galleries values into what is expected by LocalAI +*/}} +{{- define "local-ai.galleries" -}} +{{- $galleries := list -}} +{{- range $name, $url := .Values.models.galleries -}} +{{- $galleries = append $galleries (dict "name" $name "url" $url) -}} +{{- end -}} +{{- $galleries | toJson | squote -}} {{- end }} \ No newline at end of file diff --git a/charts/local-ai/templates/deployment.yaml b/charts/local-ai/templates/deployment.yaml index 5518c26..ac0e038 100644 --- a/charts/local-ai/templates/deployment.yaml +++ b/charts/local-ai/templates/deployment.yaml @@ -201,7 +201,7 @@ spec: value: {{ quote $value }} {{- end }} - name: GALLERIES - value: {{ .Values.models.galleries | dict }} + value: {{ include "local-ai.galleries" . }} - name: MODELS_PATH value: {{ .Values.deployment.modelsPath }} securityContext: diff --git a/charts/local-ai/values.yaml b/charts/local-ai/values.yaml index cc19f02..1f87c61 100644 --- a/charts/local-ai/values.yaml +++ b/charts/local-ai/values.yaml @@ -68,6 +68,11 @@ models: # threads: 5 # f16: true # gpu_layers: 33 + + galleries: + model-gallery: github:go-skynet/model-gallery/index.yaml + huggingface: go-skynet/model-gallery/huggingface.yaml + # Whether to force download models even if they already exist forceDownload: false From 674e3dcda379eec824464ced29b5a069184b27c4 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Mon, 18 Mar 2024 19:47:12 -0500 Subject: [PATCH 5/8] fix: download-models regex did not allow underscores --- charts/local-ai/templates/deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/local-ai/templates/deployment.yaml b/charts/local-ai/templates/deployment.yaml index ac0e038..47e10af 100644 --- a/charts/local-ai/templates/deployment.yaml +++ b/charts/local-ai/templates/deployment.yaml @@ -117,7 +117,7 @@ spec: validate_url() { local url=$1 - local regex='^(https?|ftp)://[a-zA-Z0-9.-]+(:[a-zA-Z0-9.-]+)?(/[a-zA-Z0-9.-]*)*$' + local regex='^(https?|ftp)://[a-zA-Z0-9.-]+(:[a-zA-Z0-9.-]+)?(/[a-zA-Z0-9._-]*)*$' if [[ $url =~ $regex ]]; then return 0 # URL is valid else From 26ce858f1eb872fc3f46412a749241e776ef87ce Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Mon, 18 Mar 2024 20:00:09 -0500 Subject: [PATCH 6/8] fix: download-models did not join urls correctly --- charts/local-ai/templates/deployment.yaml | 5 +++-- charts/local-ai/values.yaml | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/charts/local-ai/templates/deployment.yaml b/charts/local-ai/templates/deployment.yaml index 47e10af..22d40c6 100644 --- a/charts/local-ai/templates/deployment.yaml +++ b/charts/local-ai/templates/deployment.yaml @@ -1,9 +1,10 @@ # yamllint disable rule:line-length -{{- $urls := "" -}} +{{- $urls := list -}} {{- $rootPersistence := .Values.persistence }} {{- range $idx, $model := .Values.models.list }} -{{- $urls = printf "%s%s %s," $urls $model.url ($model.basicAuth | default "") }} +{{- $urls = append $urls (printf "%s %s" $model.url ($model.basicAuth | default "")) }} {{- end }} +{{- $urls = join "," $urls}} apiVersion: apps/v1 kind: Deployment diff --git a/charts/local-ai/values.yaml b/charts/local-ai/values.yaml index 1f87c61..45c181c 100644 --- a/charts/local-ai/values.yaml +++ b/charts/local-ai/values.yaml @@ -79,8 +79,8 @@ models: # The list of URLs to download models from # Note: the name of the file will be the name of the loaded model list: - # - url: "https://gpt4all.io/models/ggml-gpt4all-j.bin" - # basicAuth: base64EncodedCredentials + # - url: "https://gpt4all.io/models/ggml-gpt4all-j.bin" + # basicAuth: base64EncodedCredentials initContainers: [] # Example: From 2f6157c0935c4a080a9938e6eae2e8570690edc7 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Tue, 19 Mar 2024 11:26:11 -0500 Subject: [PATCH 7/8] feat: allow helm chart to load models from galleries --- charts/local-ai/templates/_helpers.tpl | 2 +- charts/local-ai/templates/_sidecars.tpl | 2 ++ .../templates/configmap-prompt-templates.yaml | 11 ------- charts/local-ai/templates/configmap.yaml | 20 +++++++++++-- charts/local-ai/templates/deployment.yaml | 30 +------------------ charts/local-ai/values.yaml | 10 +++++-- 6 files changed, 30 insertions(+), 45 deletions(-) delete mode 100644 charts/local-ai/templates/configmap-prompt-templates.yaml diff --git a/charts/local-ai/templates/_helpers.tpl b/charts/local-ai/templates/_helpers.tpl index da65ab7..f4299aa 100644 --- a/charts/local-ai/templates/_helpers.tpl +++ b/charts/local-ai/templates/_helpers.tpl @@ -70,5 +70,5 @@ Preprocess the models.galleries values into what is expected by LocalAI {{- range $name, $url := .Values.models.galleries -}} {{- $galleries = append $galleries (dict "name" $name "url" $url) -}} {{- end -}} -{{- $galleries | toJson | squote -}} +{{- $galleries | toJson -}} {{- end }} \ No newline at end of file diff --git a/charts/local-ai/templates/_sidecars.tpl b/charts/local-ai/templates/_sidecars.tpl index d2266ad..84c7a0a 100644 --- a/charts/local-ai/templates/_sidecars.tpl +++ b/charts/local-ai/templates/_sidecars.tpl @@ -65,6 +65,8 @@ value: {{ .Values.deployment.modelsPath }} - name: FOLDER_ANNOTATION value: "io.localai/target-directory" + - name: SCRIPT + value: {{ .Values.deployment.modelsPath }}/gallery-models.sh securityContext: runAsGroup: 1000 volumeMounts: diff --git a/charts/local-ai/templates/configmap-prompt-templates.yaml b/charts/local-ai/templates/configmap-prompt-templates.yaml deleted file mode 100644 index 014eaf8..0000000 --- a/charts/local-ai/templates/configmap-prompt-templates.yaml +++ /dev/null @@ -1,11 +0,0 @@ -{{- if .Values.promptTemplates -}} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "local-ai.fullname" . }}-prompt-templates -data: -{{- range $key, $val := .Values.promptTemplates }} - {{ $key }}: |- -{{ $val | indent 4 }} -{{- end }} -{{- end -}} diff --git a/charts/local-ai/templates/configmap.yaml b/charts/local-ai/templates/configmap.yaml index a36e830..bf737f0 100644 --- a/charts/local-ai/templates/configmap.yaml +++ b/charts/local-ai/templates/configmap.yaml @@ -1,4 +1,8 @@ -{{- if .Values.models.configs }} +{{- $numModelConfigs := .Values.models.configs | keys | len -}} +{{- $numPromptTemplates := .Values.promptTemplates | keys | len -}} +{{- if lt ((concat (.Values.models.configs | keys) (.Values.promptTemplates | keys)) | uniq | len ) (add $numModelConfigs $numPromptTemplates) -}} +{{- fail "All object names within models.configs and promptTemplates must be unique" -}} +{{- end -}} apiVersion: v1 kind: ConfigMap metadata: @@ -15,4 +19,16 @@ data: {{ if or (hasSuffix $key ".yml") (hasSuffix $key ".yaml") }}{{ $key }}{{ else }}{{ $key }}.yaml{{ end }}: |- {{- $data | toYaml | nindent 4}} {{- end }} -{{- end }} \ No newline at end of file + {{- range $key, $data := .Values.promptTemplates}} + {{ $key }}: |- + {{- $data | nindent 4}} + {{- end }} + gallery-models.sh: |- + #!/bin/sh + MODELS="{{ .Values.models.loadFromGalleries | join "," }}" + + if [ -n "$MODELS" ]; then + echo "$MODELS" | awk -F, '{for (i=1; i<=NF; i++) print $i}' | while read -r model; do + wget 127.0.0.1:8080/models/apply -q --header "Content-Type: application/json" --post-data "{\"id\":\"${model}\"}" -O - + done + fi \ No newline at end of file diff --git a/charts/local-ai/templates/deployment.yaml b/charts/local-ai/templates/deployment.yaml index 22d40c6..99c5ee9 100644 --- a/charts/local-ai/templates/deployment.yaml +++ b/charts/local-ai/templates/deployment.yaml @@ -24,10 +24,6 @@ spec: labels: app.kubernetes.io/name: {{ include "local-ai.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} - annotations: - {{- if .Values.promptTemplates }} - checksum/config-prompt-templates: {{ include (print $.Template.BasePath "/configmap-prompt-templates.yaml") . | sha256sum }} - {{- end }} spec: {{- with .Values.deployment.runtimeClassName }} runtimeClassName: {{ . }} @@ -78,27 +74,6 @@ spec: {{- end }} {{- end }} {{- end }} - - {{- if .Values.promptTemplates }} - - name: prompt-templates - image: {{ .Values.deployment.prompt_templates.image }} - imagePullPolicy: {{ .Values.deployment.pullPolicy }} - command: ["/bin/sh", "-c"] - args: - - | - cp -fL /prompt-templates/* /models - securityContext: - runAsGroup: 1000 - volumeMounts: - - mountPath: /prompt-templates - name: prompt-templates - {{- range $key, $pvc := $rootPersistence }} - {{- if $pvc.enabled }} - - name: {{ $key }} - mountPath: {{ $pvc.globalMount | default (print "/" $key) }} - {{- end }} - {{- end }} - {{- end }} - name: download-model image: {{ .Values.deployment.download_model.image }} imagePullPolicy: {{ .Values.deployment.pullPolicy }} @@ -202,7 +177,7 @@ spec: value: {{ quote $value }} {{- end }} - name: GALLERIES - value: {{ include "local-ai.galleries" . }} + value: {{ include "local-ai.galleries" . | squote }} - name: MODELS_PATH value: {{ .Values.deployment.modelsPath }} securityContext: @@ -227,9 +202,6 @@ spec: emptyDir: {} {{- end }} {{- end }} - - name: prompt-templates - configMap: - name: {{ template "local-ai.fullname" . }}-prompt-templates {{- end }} {{- with .Values.nodeSelector }} nodeSelector: diff --git a/charts/local-ai/values.yaml b/charts/local-ai/values.yaml index 45c181c..bfea425 100644 --- a/charts/local-ai/values.yaml +++ b/charts/local-ai/values.yaml @@ -56,7 +56,8 @@ promptTemplates: # Models to download at runtime models: - configs: {} + configs: + {} # myModel: # backend: llama # context_size: 2048 @@ -71,11 +72,16 @@ models: galleries: model-gallery: github:go-skynet/model-gallery/index.yaml - huggingface: go-skynet/model-gallery/huggingface.yaml + huggingface: github:go-skynet/model-gallery/huggingface.yaml # Whether to force download models even if they already exist forceDownload: false + loadFromGalleries: + [] + # - "model-gallery@lunademo" + # - huggingface@thebloke__llama-2-7b-chat-gguf__llama-2-7b-chat.q4_0.gguf + # The list of URLs to download models from # Note: the name of the file will be the name of the loaded model list: From 1bb33e469a8fcafaa4ddb6413469875d9dc11762 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Tue, 19 Mar 2024 15:33:18 -0500 Subject: [PATCH 8/8] fix: model suffix detection within configMap --- charts/local-ai/templates/configmap.yaml | 8 ++++---- charts/local-ai/values.yaml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/charts/local-ai/templates/configmap.yaml b/charts/local-ai/templates/configmap.yaml index bf737f0..eee758a 100644 --- a/charts/local-ai/templates/configmap.yaml +++ b/charts/local-ai/templates/configmap.yaml @@ -16,7 +16,7 @@ metadata: {{- end }} data: {{- range $key, $data := .Values.models.configs}} - {{ if or (hasSuffix $key ".yml") (hasSuffix $key ".yaml") }}{{ $key }}{{ else }}{{ $key }}.yaml{{ end }}: |- + {{ if or (hasSuffix ".yml" $key) (hasSuffix ".yaml" $key) }}{{ $key }}{{ else }}{{ $key }}.yaml{{ end }}: |- {{- $data | toYaml | nindent 4}} {{- end }} {{- range $key, $data := .Values.promptTemplates}} @@ -25,10 +25,10 @@ data: {{- end }} gallery-models.sh: |- #!/bin/sh - MODELS="{{ .Values.models.loadFromGalleries | join "," }}" + GALLERY_MODELS="{{ .Values.models.loadFromGalleries | join "," }}" - if [ -n "$MODELS" ]; then - echo "$MODELS" | awk -F, '{for (i=1; i<=NF; i++) print $i}' | while read -r model; do + if [ -n "$GALLERY_MODELS" ]; then + echo "$GALLERY_MODELS" | awk -F, '{for (i=1; i<=NF; i++) print $i}' | while read -r model; do wget 127.0.0.1:8080/models/apply -q --header "Content-Type: application/json" --post-data "{\"id\":\"${model}\"}" -O - done fi \ No newline at end of file diff --git a/charts/local-ai/values.yaml b/charts/local-ai/values.yaml index bfea425..bc6fe58 100644 --- a/charts/local-ai/values.yaml +++ b/charts/local-ai/values.yaml @@ -74,14 +74,14 @@ models: model-gallery: github:go-skynet/model-gallery/index.yaml huggingface: github:go-skynet/model-gallery/huggingface.yaml - # Whether to force download models even if they already exist - forceDownload: false - loadFromGalleries: [] # - "model-gallery@lunademo" # - huggingface@thebloke__llama-2-7b-chat-gguf__llama-2-7b-chat.q4_0.gguf + # Whether to force download models even if they already exist + forceDownload: false + # The list of URLs to download models from # Note: the name of the file will be the name of the loaded model list: