From f847e05e50505bd54659eff3e70e66698285b016 Mon Sep 17 00:00:00 2001 From: dolpher Date: Mon, 4 Nov 2024 10:44:51 +0800 Subject: [PATCH] Add FaqGen helm chart (#513) Signed-off-by: Dolpher Du --- helm-charts/faqgen/.helmignore | 23 +++++ helm-charts/faqgen/Chart.yaml | 20 ++++ helm-charts/faqgen/README.md | 42 +++++++++ helm-charts/faqgen/ci-gaudi-values.yaml | 1 + helm-charts/faqgen/ci-values.yaml | 1 + helm-charts/faqgen/gaudi-values.yaml | 27 ++++++ helm-charts/faqgen/templates/_helpers.tpl | 62 +++++++++++++ helm-charts/faqgen/templates/deployment.yaml | 77 +++++++++++++++ .../faqgen/templates/nginx-deployment.yaml | 93 +++++++++++++++++++ helm-charts/faqgen/templates/service.yaml | 19 ++++ .../faqgen/templates/tests/test-pod.yaml | 29 ++++++ helm-charts/faqgen/values.yaml | 66 +++++++++++++ 12 files changed, 460 insertions(+) create mode 100644 helm-charts/faqgen/.helmignore create mode 100644 helm-charts/faqgen/Chart.yaml create mode 100644 helm-charts/faqgen/README.md create mode 120000 helm-charts/faqgen/ci-gaudi-values.yaml create mode 120000 helm-charts/faqgen/ci-values.yaml create mode 100644 helm-charts/faqgen/gaudi-values.yaml create mode 100644 helm-charts/faqgen/templates/_helpers.tpl create mode 100644 helm-charts/faqgen/templates/deployment.yaml create mode 100644 helm-charts/faqgen/templates/nginx-deployment.yaml create mode 100644 helm-charts/faqgen/templates/service.yaml create mode 100644 helm-charts/faqgen/templates/tests/test-pod.yaml create mode 100644 helm-charts/faqgen/values.yaml diff --git a/helm-charts/faqgen/.helmignore b/helm-charts/faqgen/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/helm-charts/faqgen/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm-charts/faqgen/Chart.yaml b/helm-charts/faqgen/Chart.yaml new file mode 100644 index 00000000..bea68427 --- /dev/null +++ b/helm-charts/faqgen/Chart.yaml @@ -0,0 +1,20 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v2 +name: faqgen +description: The Helm chart to deploy FaqGen +type: application +dependencies: + - name: tgi + version: 1.0.0 + repository: "file://../common/tgi" + - name: llm-uservice + version: 1.0.0 + repository: "file://../common/llm-uservice" + - name: ui + version: 1.0.0 + repository: "file://../common/ui" + alias: faqgen-ui +version: 1.0.0 +appVersion: "v1.0" diff --git a/helm-charts/faqgen/README.md b/helm-charts/faqgen/README.md new file mode 100644 index 00000000..481cebdd --- /dev/null +++ b/helm-charts/faqgen/README.md @@ -0,0 +1,42 @@ +# FaqGen + +Helm chart for deploying FaqGen service. + +FaqGen depends on LLM and tgi microservice, refer to [llm-uservice](../common/llm-uservice/README.md) and [tgi](../common/tgi/README.md) for more config details. + +## Verify + +To verify the installation, run the command `kubectl get pod` to make sure all pods are running. + +Curl command and UI are the two options that can be leveraged to verify the result. + +### Verify the workload through curl command + +Then run the command `kubectl port-forward svc/faqgen 8888:8888` to expose the service for access. + +Open another terminal and run the following command to verify the service if working: + +```console +curl http://localhost:8888/v1/faqgen \ + -H "Content-Type: application/json" \ + -d '{"messages": "Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."}' +``` + +### Verify the workload through UI + +The UI has already been installed via the Helm chart. To access it, use the external IP of one your Kubernetes node along with the NGINX port. You can find the NGINX port using the following command: + +```bash +export port=$(kubectl get service faqgen-nginx --output='jsonpath={.spec.ports[0].nodePort}') +echo $port +``` + +Open a browser to access `http://:${port}` to play with the ChatQnA workload. + +## Values + +| Key | Type | Default | Description | +| ---------------- | ------ | --------------------------------------- | ------------------------------------------------------------------------ | +| image.repository | string | `"opea/faqgen"` | | +| service.port | string | `"8888"` | | +| tgi.LLM_MODEL_ID | string | `"meta-llama/Meta-Llama-3-8B-Instruct"` | Models id from https://huggingface.co/, or predownloaded model directory | diff --git a/helm-charts/faqgen/ci-gaudi-values.yaml b/helm-charts/faqgen/ci-gaudi-values.yaml new file mode 120000 index 00000000..7243d31b --- /dev/null +++ b/helm-charts/faqgen/ci-gaudi-values.yaml @@ -0,0 +1 @@ +gaudi-values.yaml \ No newline at end of file diff --git a/helm-charts/faqgen/ci-values.yaml b/helm-charts/faqgen/ci-values.yaml new file mode 120000 index 00000000..7d101009 --- /dev/null +++ b/helm-charts/faqgen/ci-values.yaml @@ -0,0 +1 @@ +values.yaml \ No newline at end of file diff --git a/helm-charts/faqgen/gaudi-values.yaml b/helm-charts/faqgen/gaudi-values.yaml new file mode 100644 index 00000000..dcfb159e --- /dev/null +++ b/helm-charts/faqgen/gaudi-values.yaml @@ -0,0 +1,27 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +tgi: + accelDevice: "gaudi" + image: + repository: ghcr.io/huggingface/tgi-gaudi + tag: "2.0.5" + resources: + limits: + habana.ai/gaudi: 1 + MAX_INPUT_LENGTH: "4096" + MAX_TOTAL_TOKENS: "8192" + CUDA_GRAPHS: "0" + livenessProbe: + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + startupProbe: + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + failureThreshold: 120 diff --git a/helm-charts/faqgen/templates/_helpers.tpl b/helm-charts/faqgen/templates/_helpers.tpl new file mode 100644 index 00000000..f5913492 --- /dev/null +++ b/helm-charts/faqgen/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "faqgen.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "faqgen.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "faqgen.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "faqgen.labels" -}} +helm.sh/chart: {{ include "faqgen.chart" . }} +{{ include "faqgen.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "faqgen.selectorLabels" -}} +app.kubernetes.io/name: {{ include "faqgen.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "faqgen.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "faqgen.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm-charts/faqgen/templates/deployment.yaml b/helm-charts/faqgen/templates/deployment.yaml new file mode 100644 index 00000000..bf174e0a --- /dev/null +++ b/helm-charts/faqgen/templates/deployment.yaml @@ -0,0 +1,77 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "faqgen.fullname" . }} + labels: + {{- include "faqgen.labels" . | nindent 4 }} + app: {{ include "faqgen.fullname" . }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "faqgen.selectorLabels" . | nindent 6 }} + app: {{ include "faqgen.fullname" . }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "faqgen.selectorLabels" . | nindent 8 }} + app: {{ include "faqgen.fullname" . }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Release.Name }} + env: + - name: LLM_SERVICE_HOST_IP + value: {{ .Release.Name }}-llm-uservice + #- name: MEGA_SERVICE_PORT + # value: {{ .Values.port }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumeMounts: + - mountPath: /tmp + name: tmp + ports: + - name: faqgen + containerPort: {{ .Values.port }} + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumes: + - name: tmp + emptyDir: {} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.evenly_distributed }} + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + {{- include "faqgen.selectorLabels" . | nindent 14 }} + app: {{ include "faqgen.fullname" . }} + {{- end }} diff --git a/helm-charts/faqgen/templates/nginx-deployment.yaml b/helm-charts/faqgen/templates/nginx-deployment.yaml new file mode 100644 index 00000000..969b63c2 --- /dev/null +++ b/helm-charts/faqgen/templates/nginx-deployment.yaml @@ -0,0 +1,93 @@ +apiVersion: v1 +data: + default.conf: |+ + # Copyright (C) 2024 Intel Corporation + # SPDX-License-Identifier: Apache-2.0 + + + server { + listen 80; + listen [::]:80; + + location /home { + alias /usr/share/nginx/html/index.html; + } + + location / { + proxy_pass http://{{ include "ui.fullname" (index .Subcharts "faqgen-ui") }}:{{ index .Values "faqgen-ui" "service" "port" }}; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /v1/faqgen { + proxy_pass http://{{ include "faqgen.fullname" . }}:{{ .Values.service.port }}; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } + +kind: ConfigMap +metadata: + name: {{ include "faqgen.fullname" . }}-nginx-config +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "faqgen.fullname" . }}-nginx + labels: + {{- include "faqgen.labels" . | nindent 4 }} + app: {{ include "faqgen.fullname" . }}-nginx +spec: + selector: + matchLabels: + {{- include "faqgen.selectorLabels" . | nindent 6 }} + app: {{ include "faqgen.fullname" . }}-nginx + template: + metadata: + labels: + {{- include "faqgen.selectorLabels" . | nindent 8 }} + app: {{ include "faqgen.fullname" . }}-nginx + spec: + containers: + - image: nginx:1.27.1 + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: nginx + volumeMounts: + - mountPath: /etc/nginx/conf.d + name: nginx-config-volume + securityContext: {} + volumes: + - configMap: + defaultMode: 420 + name: {{ include "faqgen.fullname" . }}-nginx-config + name: nginx-config-volume + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "faqgen.fullname" . }}-nginx +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + {{- include "faqgen.selectorLabels" . | nindent 4 }} + app: {{ include "faqgen.fullname" . }}-nginx + type: {{ .Values.nginx.service.type }} diff --git a/helm-charts/faqgen/templates/service.yaml b/helm-charts/faqgen/templates/service.yaml new file mode 100644 index 00000000..a2b29de8 --- /dev/null +++ b/helm-charts/faqgen/templates/service.yaml @@ -0,0 +1,19 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "faqgen.fullname" . }} + labels: + {{- include "faqgen.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.port }} + protocol: TCP + name: faqgen + selector: + {{- include "faqgen.selectorLabels" . | nindent 4 }} + app: {{ include "faqgen.fullname" . }} diff --git a/helm-charts/faqgen/templates/tests/test-pod.yaml b/helm-charts/faqgen/templates/tests/test-pod.yaml new file mode 100644 index 00000000..844a9ae2 --- /dev/null +++ b/helm-charts/faqgen/templates/tests/test-pod.yaml @@ -0,0 +1,29 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "faqgen.fullname" . }}-testpod" + labels: + {{- include "faqgen.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + #"helm.sh/hook-delete-policy": "hook-succeeded, hook-failure" +spec: + containers: + - name: curl + image: python:3.10.14 + command: ['bash', '-c'] + args: + - | + max_retry=20; + for ((i=1; i<=max_retry; i++)); do + curl http://{{ include "faqgen.fullname" . }}:{{ .Values.service.port }}/v1/faqgen -sS --fail-with-body \ + -H "Content-Type: application/json" \ + -d '{"messages": "Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."}' && break; + curlcode=$? + if [[ $curlcode -eq 7 ]]; then sleep 10; else echo "curl failed with code $curlcode"; exit 1; fi; + done; + if [ $i -gt $max_retry ]; then echo "test failed with maximum retry"; exit 1; fi + restartPolicy: Never diff --git a/helm-charts/faqgen/values.yaml b/helm-charts/faqgen/values.yaml new file mode 100644 index 00000000..77d70bdd --- /dev/null +++ b/helm-charts/faqgen/values.yaml @@ -0,0 +1,66 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Default values for faqgen. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: opea/faqgen + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +port: 8888 +service: + type: ClusterIP + port: 8888 + +nginx: + service: + type: NodePort + +securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + runAsNonRoot: true + runAsUser: 1000 + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# To override values in subchart llm-uservice +llm-uservice: + image: + repository: opea/llm-faqgen-tgi + +# To override values in subchart tgi +tgi: + LLM_MODEL_ID: meta-llama/Meta-Llama-3-8B-Instruct + +faqgen-ui: + image: + repository: opea/faqgen-ui + tag: "latest" + BACKEND_SERVICE_ENDPOINT: "/v1/faqgen" + containerPort: 5173 + +global: + http_proxy: "" + https_proxy: "" + no_proxy: "" + HUGGINGFACEHUB_API_TOKEN: "insert-your-huggingface-token-here" + # set modelUseHostPath or modelUsePVC to use model cache. + modelUseHostPath: "" + # modelUseHostPath: /mnt/opea-models + # modelUsePVC: model-volume