EasyLLMOps: MLOps sin esfuerzo para modelos de lenguaje potentes.
EasyLLMOps es un proyecto creado con Open WebUI que se puede implementar en Google Kubernetes Engine (GKE) para administrar y escalar modelos de lenguaje. Ofrece métodos de implementación manual y Terraform e incorpora prácticas sólidas de MLOps. Esto incluye canalizaciones de CI/CD con Jenkins y Ansible para automatización, monitoreo con Prometheus y Grafana para obtener información sobre el rendimiento y registro centralizado con la pila ELK para resolución de problemas y análisis. Los desarrolladores pueden encontrar documentación detallada e instrucciones en el sitio web del proyecto.
Desarrolladores que crean e implementan aplicaciones basadas en LLM. Científicos de datos e ingenieros de aprendizaje automático que trabajan con LLM. Equipos de DevOps responsables de gestionar la infraestructura LLM. Organizaciones que buscan integrar LLM en sus operaciones.
En caso de que no quieras perder mucho tiempo, ejecuta este script y disfruta de tu café:
chmod +x ./cluster.sh
./cluster.sh
Recuerde autenticarse con GCP antes de usar Terraform:
gcloud auth application-default login
Esta sección proporciona una guía de inicio muy rápida para que la aplicación esté en funcionamiento lo antes posible. Consulte las siguientes secciones para obtener instrucciones más detalladas.
1. Configure el clúster:
Si estás implementando la aplicación en GKE, puedes usar Terraform para automatizar la configuración de tu clúster de Kubernetes. Navegue hasta el directorio iac/terraform
e inicialice Terraform:
cd iac/terraform
terraform init
Planificar y aplicar configuración:
Genere un plan de ejecución para verificar los recursos que Terraform creará o modificará y luego aplique la configuración para configurar el clúster:
terraform plan
terraform apply
2. Recuperar información del clúster:
Para interactuar con tu clúster de GKE, necesitarás recuperar su configuración. Puede ver la configuración actual del clúster con el siguiente comando:
cat ~ /.kube/config
Asegúrese de que su contexto kubectl
esté configurado correctamente para administrar el clúster.
Para un proceso de implementación más práctico, siga estos pasos:
1. Implementar el controlador de ingreso Nginx:
El controlador de ingreso Nginx administra el acceso externo a los servicios en su clúster de Kubernetes. Cree un espacio de nombres e instale el controlador de ingreso usando Helm:
kubectl create ns nginx-system
kubens nginx-system
helm upgrade --install nginx-ingress ./deployments/nginx-ingress
Indique la dirección IP del controlador de ingreso Nginx, ya que la necesitará más adelante.
2. Configurar la clave secreta de API:
Almacene sus variables de entorno, como claves API, de forma segura en secretos de Kubernetes. Cree un espacio de nombres para la publicación de modelos y cree un secreto a partir de su archivo .env
:
kubectl create ns model-serving
kubens model-serving
kubectl delete secret easyllmops-env
kubectl create secret generic easyllmops-env --from-env-file=.env -n model-serving
kubectl describe secret easyllmops-env -n model-serving
3. Otorgar permisos:
Los recursos de Kubernetes suelen requerir permisos específicos. Aplicar los roles y vinculaciones necesarios:
cd deployments/infrastructure
kubectl apply -f role.yaml
kubectl apply -f rolebinding.yaml
4. Implemente el servicio de almacenamiento en caché usando Redis:
Ahora, implemente el servicio de almacenamiento en caché semántico usando Redis:
cd ./deployments/redis
helm dependency build
helm upgrade --install redis .
5. Implementar LiteLLM:
Implemente el servicio LiteLLM:
kubens model-serving
helm upgrade --install litellm ./deployments/litellm
6. Implemente la interfaz de usuario web abierta:
A continuación, implemente la interfaz de usuario web en su clúster de GKE:
cd open-webui
kubectl apply -f ./kubernetes/manifest/base -n model-serving
7. Experimente con la aplicación:
Abra el navegador y navegue hasta la URL de su clúster de GKE (por ejemplo, http://172.0.0.0
en el paso 1) y agregue .nip.io
al final de la URL (por ejemplo, http://172.0.0.0.nip.io
). . Deberías ver la Open WebUI:
Para canalizaciones de CI/CD automatizadas, utilice Jenkins y Ansible de la siguiente manera:
1. Configure el servidor Jenkins:
Primero, cree una cuenta de servicio y asígnele la función Compute Admin
. Luego cree un archivo de clave Json para la cuenta de servicio y guárdelo en el directorio iac/ansible/secrets
.
A continuación, cree una instancia de Google Compute Engine llamada "jenkins-server" que ejecute Ubuntu 22.04 con una regla de firewall que permita el tráfico en los puertos 8081 y 50000.
ansible-playbook iac/ansible/deploy_jenkins/create_compute_instance.yaml
Implemente Jenkins en un servidor instalando requisitos previos, extrayendo una imagen de Docker y creando un contenedor privilegiado con acceso al socket de Docker y a los puertos expuestos 8081 y 50000.
ansible-playbook -i iac/ansible/inventory iac/ansible/deploy_jenkins/deploy_jenkins.yaml
2. Acceda a Jenkins:
Para acceder al servidor Jenkins a través de SSH, necesitamos crear un par de claves pública/privada. Ejecute el siguiente comando para crear un par de claves:
ssh-keygen
Abra Metadata
y copie el valor ssh-keys
.
Necesitamos encontrar la contraseña del servidor Jenkins para poder acceder al servidor. Primero, acceda al servidor Jenkins:
ssh < USERNAME > : < EXTERNAL_IP >
Luego ejecute el siguiente comando para obtener la contraseña:
sudo docker exec -it jenkins-server bash
cat /var/jenkins_home/secrets/initialAdminPassword
Una vez implementado Jenkins, acceda a través de su navegador:
http://<EXTERNAL_IP>:8081
3. Instale los complementos de Jenkins:
Instale los siguientes complementos para integrar Jenkins con Docker, Kubernetes y GKE:
Después de instalar los complementos, reinicie Jenkins.
sudo docker restart jenkins-server
4. Configure Jenkins:
4.1. Agregue webhooks a su repositorio de GitHub para activar compilaciones de Jenkins.
Vaya al repositorio de GitHub y haga clic en Settings
. Haga clic en Webhooks
y luego haga clic en Add Webhook
. Ingrese la URL de su servidor Jenkins (por ejemplo http://<EXTERNAL_IP>:8081/github-webhook/
). Luego haga clic en Let me select individual events
y selecciona Let me select individual events
. Seleccione Pull Request
Push
y pull y haga clic en Add Webhook
.
4.2. Agregue el repositorio de Github como repositorio de código fuente de Jenkins.
Vaya al panel de Jenkins y haga clic en New Item
. Ingrese un nombre para su proyecto (por ejemplo, easy-llmops
) y seleccione Multibranch Pipeline
. Haga clic en OK
. Haga clic en Configure
y luego haga clic en Add Source
. Seleccione GitHub
y haga clic en Add
. Ingrese la URL de su repositorio de GitHub (por ejemplo, https://github.com/bmd1905/EasyLLMOps
). En el campo Credentials
, seleccione Add
y seleccione Username with password
. Ingrese su nombre de usuario y contraseña de GitHub (o use un token de acceso personal). Haga clic en Test Connection
y luego haga clic en Save
.
4.3. Configure las credenciales de Docker Hub.
Primero, cree una cuenta de Docker Hub. Vaya al sitio web de Docker Hub y haga clic en Sign Up
. Ingrese su nombre de usuario y contraseña. Haga clic en Sign Up
. Haga clic en Create Repository
. Ingrese un nombre para su repositorio (por ejemplo, easy-llmops
) y haga clic en Create
.
Desde el panel de Jenkins, vaya a Manage Jenkins
> Credentials
. Haga clic en Add Credentials
. Seleccione Username with password
y haga clic en Add
. Ingrese su nombre de usuario de Docker Hub, token de acceso y configure ID
en dockerhub
.
4.4. Configure las credenciales de Kubernetes.
Primero, cree una cuenta de servicio para que el servidor Jenkins acceda al clúster de GKE. Vaya a la consola de GCP y navegue hasta IAM y administrador > Cuentas de servicio. Cree una nueva cuenta de servicio con la función Kubernetes Engine Admin
. Asigne un nombre y una descripción a la cuenta de servicio. Haga clic en la cuenta de servicio y luego haga clic en la pestaña Keys
. Haga clic en Add Key
y seleccione JSON
como tipo de clave. Haga clic en Create
y descargue el archivo JSON.
Luego, desde el panel de Jenkins, vaya a Manage Jenkins
> Cloud
. Haga clic en New cloud
. Kubernetes
. Ingrese el nombre de su clúster (por ejemplo, gke-easy-llmops-cluster-1), enter the URL and Certificate from your GKE cluster. In the
espacio de nombres de Kubernetes , enter the namespace of your cluster (eg
model-serving ). In the
field, select
Agregar and select
Cuenta de servicio de Google desde privada. Ingrese su ID de proyecto y la ruta al archivo JSON.
5. Pruebe la configuración:
Envía una nueva confirmación a tu repositorio de GitHub. Deberías ver una nueva compilación en Jenkins.
1. Cree un webhook de Discord:
Primero, cree un webhook de Discord. Vaya al sitio web de Discord y haga clic en Server Settings
. Haga clic en Integrations
. Haga clic en Create Webhook
. Ingrese un nombre para su webhook (por ejemplo, easy-llmops-discord-webhook
) y haga clic en Create
. Copie la URL del webhook.
2. Configurar repositorios de Helm
Primero, necesitamos agregar los repositorios Helm necesarios para Prometheus y Grafana:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
Estos comandos agregan los repositorios oficiales de Prometheus y Grafana Helm y actualizan la información de su gráfico Helm local.
3. Instalar dependencias
Prometheus requiere ciertas dependencias que se pueden gestionar con Helm. Navegue hasta el directorio de monitoreo y cree estas dependencias:
helm dependency build ./deployments/monitoring/kube-prometheus-stack
4. Implementar Prometeo
Ahora implementaremos Prometheus y sus servicios asociados usando Helm:
kubectl create namespace monitoring
helm upgrade --install -f deployments/monitoring/kube-prometheus-stack.expanded.yaml kube-prometheus-stack deployments/monitoring/kube-prometheus-stack -n monitoring
Este comando hace lo siguiente:
helm upgrade --install
: Esto instalará Prometheus si no existe, o lo actualizará si existe.-f deployments/monitoring/kube-prometheus-stack.expanded.yaml
: esto especifica un archivo de valores personalizados para la configuración.kube-prometheus-stack
: este es el nombre de la versión para la instalación de Helm.deployments/monitoring/kube-prometheus-stack
: este es el cuadro que se utilizará para la instalación.-n monitoring
: esto especifica el espacio de nombres en el que se instalará.De forma predeterminada, los servicios no están expuestos externamente. Para acceder a ellos, puede utilizar el reenvío de puertos:
Para Prometeo:
kubectl port-forward -n monitoring svc/kube-prometheus-stack-prometheus 9090:9090
Luego acceda a Prometheus en http://localhost:9090
Para Grafana:
kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 3000:80
Luego acceda a Grafana en http://localhost:3000
Las credenciales predeterminadas para Grafana suelen ser:
5. Alerta de prueba
Primero necesitamos crear una alerta de muestra. Navegue hasta el directorio monitoring
y ejecute el siguiente comando:
kubectl port-forward -n monitoring svc/alertmanager-operated 9093:9093
Luego, en una nueva terminal, ejecute el siguiente comando:
curl -XPOST -H " Content-Type: application/json " -d ' [
{
"labels": {
"alertname": "DiskSpaceLow",
"severity": "critical",
"instance": "server02",
"job": "node_exporter",
"mountpoint": "/data"
},
"annotations": {
"summary": "Disk space critically low",
"description": "Server02 has only 5% free disk space on /data volume"
},
"startsAt": "2023-09-01T12:00:00Z",
"generatorURL": "http://prometheus.example.com/graph?g0.expr=node_filesystem_free_bytes+%2F+node_filesystem_size_bytes+%2A+100+%3C+5"
},
{
"labels": {
"alertname": "HighMemoryUsage",
"severity": "warning",
"instance": "server03",
"job": "node_exporter"
},
"annotations": {
"summary": "High memory usage detected",
"description": "Server03 is using over 90% of its available memory"
},
"startsAt": "2023-09-01T12:05:00Z",
"generatorURL": "http://prometheus.example.com/graph?g0.expr=node_memory_MemAvailable_bytes+%2F+node_memory_MemTotal_bytes+%2A+100+%3C+10"
}
] ' http://localhost:9093/api/v2/alerts
Este comando crea una alerta de ejemplo. Puede verificar que la alerta se creó ejecutando el siguiente comando:
curl http://localhost:9093/api/v2/status
O puede verificar manualmente el canal de Discord.
Esta configuración proporciona capacidades de monitoreo integrales para su clúster de Kubernetes. Con Prometheus recopilando métricas y Grafana visualizándolas, puede realizar un seguimiento eficaz del rendimiento, configurar alertas para posibles problemas y obtener información valiosa sobre su infraestructura y aplicaciones.
El registro centralizado es esencial para monitorear y solucionar problemas de aplicaciones implementadas en Kubernetes. Esta sección lo guía a través de la configuración de una pila ELK (Elasticsearch, Logstash, Kibana) con Filebeat para registrar su clúster de GKE.
0. Ejecución rápida
Puede utilizar este único script de helmfile para iniciar la pila ELK:
cd deployments/ELK
helmfile sync
1. Instale ELK Stack con Helm
Usaremos Helm para implementar los componentes de la pila ELK:
Primero, cree un espacio de nombres para los componentes de registro:
kubectl create ns logging
kubens logging
A continuación, instale Elasticsearch:
helm install elk-elasticsearch elastic/elasticsearch -f deployments/ELK/elastic.expanded.yaml --namespace logging --create-namespace
Espere a que Elasticsearch esté listo:
echo " Waiting for Elasticsearch to be ready... "
kubectl wait --for=condition=ready pod -l app=elasticsearch-master --timeout=300s
Cree un secreto para que Logstash acceda a Elasticsearch:
kubectl create secret generic logstash-elasticsearch-credentials
--from-literal=username=elastic
--from-literal=password= $( kubectl get secrets --namespace=logging elasticsearch-master-credentials -ojsonpath= ' {.data.password} ' | base64 -d )
Instalar Kibana:
helm install elk-kibana elastic/kibana -f deployments/ELK/kibana.expanded.yaml
Instalar Logstash:
helm install elk-logstash elastic/logstash -f deployments/ELK/logstash.expanded.yaml
Instalar Filebeat:
helm install elk-filebeat elastic/filebeat -f deployments/ELK/filebeat.expanded.yaml
2. Acceda a Kibana:
Exponga Kibana utilizando un servicio y acceda a él a través de su navegador:
kubectl port-forward -n logging svc/elk-kibana-kibana 5601:5601
Utilice este script para obtener la contraseña de Kibana:
kubectl get secrets --namespace=logging elasticsearch-master-credentials -ojsonpath= ' {.data.password} ' | base64 -d
Abra su navegador y navegue hasta http://localhost:5601
.
3. Verificar la recopilación de registros
Ahora debería poder ver los registros de sus pods de Kubernetes en Kibana. Puede crear paneles y visualizaciones para analizar sus registros y obtener información sobre el comportamiento de su aplicación.
Vaya a Cast AI para registrarse para obtener una cuenta gratuita y obtener el TOKEN.
Luego ejecuta esta línea para conectarte a GKE:
curl -H " Authorization: Token <TOKEN> " " https://api.cast.ai/v1/agent.yaml?provider=gke " | kubectl apply -f -
Presione I ran this script
en la interfaz de usuario de Cast AI, luego copie el código de configuración y péguelo en la terminal:
CASTAI_API_TOKEN= < API_TOKEN > CASTAI_CLUSTER_ID= < CASTAI_CLUSTER_ID > CLUSTER_NAME=easy-llmops-gke INSTALL_AUTOSCALER=true INSTALL_POD_PINNER=true INSTALL_SECURITY_AGENT=true LOCATION=asia-southeast1-b PROJECT_ID=easy-llmops /bin/bash -c " $( curl -fsSL ' https://api.cast.ai/v1/scripts/gke/onboarding.sh ' ) "
Presiona I ran this script
nuevamente y esperé a que se complete la instalación.
Luego podrá ver sus paneles en la interfaz de usuario de Cast AI:
¡Es hora de optimizar su clúster con Cast AI! Vaya a la sección Available savings
y haga clic en el botón Rebalance
.
Vaya a Langfuse y Supabase para registrarse para obtener una cuenta gratuita y obtener claves API, luego reemplace los marcadores de posición en el archivo .env.example con sus claves API.
¡Agradecemos las contribuciones a EasyLLMOps! Consulte nuestro CONTRIBUTING.md para obtener más información sobre cómo comenzar.
EasyLLMOps se publica bajo la licencia MIT. Consulte el archivo de LICENCIA para obtener más detalles.
Si utiliza EasyLLMOps en su investigación, cítelo de la siguiente manera:
@software{EasyLLMOps2024,
author = {Minh-Duc Bui},
title = {EasyLLMOps: Effortless MLOps for Powerful Language Models.},
year = {2024},
url = {https://github.com/bmd1905/EasyLLMOps}
}
Si tiene preguntas, problemas o colaboraciones, abra un problema en nuestro repositorio de GitHub o comuníquese directamente con los mantenedores.