EasyLLMOps: عمليات MLOps بدون جهد لنماذج اللغة القوية.
EasyLLMOps هو مشروع تم إنشاؤه باستخدام Open WebUI ويمكن نشره على Google Kubernetes Engine (GKE) لإدارة نماذج اللغة وتوسيع نطاقها. وهو يقدم كلاً من أساليب النشر Terraform واليدوية، ويتضمن ممارسات MLOps القوية. يتضمن ذلك خطوط أنابيب CI/CD مع Jenkins وAnsible للأتمتة، والمراقبة باستخدام Prometheus وGrafana للحصول على رؤى الأداء، والتسجيل المركزي باستخدام مكدس ELK لاستكشاف الأخطاء وإصلاحها والتحليل. يمكن للمطورين العثور على وثائق وتعليمات مفصلة على موقع المشروع.
يقوم المطورون ببناء ونشر التطبيقات التي تدعم LLM. علماء البيانات ومهندسو التعلم الآلي الذين يعملون مع LLMs. فرق DevOps المسؤولة عن إدارة البنية التحتية لـ LLM. المنظمات التي تتطلع إلى دمج LLMs في عملياتها.
في حالة عدم رغبتك في قضاء الكثير من الوقت، يرجى تشغيل هذا البرنامج النصي والاستمتاع بقهوتك:
chmod +x ./cluster.sh
./cluster.sh
تذكر إجراء المصادقة مع GCP قبل استخدام Terraform:
gcloud auth application-default login
يوفر هذا القسم دليل بداية سريعًا جدًا لإعداد التطبيق وتشغيله في أسرع وقت ممكن. يرجى الرجوع إلى الأقسام التالية للحصول على تعليمات أكثر تفصيلا.
1. إعداد المجموعة:
إذا كنت تنشر التطبيق على GKE، فيمكنك استخدام Terraform لأتمتة إعداد مجموعة Kubernetes الخاصة بك. انتقل إلى دليل iac/terraform
وقم بتهيئة Terraform:
cd iac/terraform
terraform init
تخطيط وتطبيق التكوين:
أنشئ خطة تنفيذ للتحقق من الموارد التي ستقوم Terraform بإنشائها أو تعديلها، ثم قم بتطبيق التكوين لإعداد المجموعة:
terraform plan
terraform apply
2. استرداد معلومات المجموعة:
للتفاعل مع مجموعة GKE الخاصة بك، ستحتاج إلى استرداد تكوينها. يمكنك عرض تكوين المجموعة الحالي باستخدام الأمر التالي:
cat ~ /.kube/config
تأكد من ضبط سياق kubectl
الخاص بك بشكل صحيح لإدارة المجموعة.
للحصول على عملية نشر عملية أكثر، اتبع الخطوات التالية:
1. نشر وحدة تحكم الدخول Nginx:
يدير Nginx Ingress Controller الوصول الخارجي إلى الخدمات في مجموعة Kubernetes الخاصة بك. قم بإنشاء مساحة اسم وتثبيت وحدة التحكم في الدخول باستخدام Helm:
kubectl create ns nginx-system
kubens nginx-system
helm upgrade --install nginx-ingress ./deployments/nginx-ingress
يرجى كتابة عنوان IP الخاص بوحدة تحكم Nginx Ingress، حيث ستحتاج إليه لاحقًا.
2. تكوين سر مفتاح API:
قم بتخزين متغيرات البيئة الخاصة بك، مثل مفاتيح API، بشكل آمن في أسرار Kubernetes. أنشئ مساحة اسم لعرض النماذج وأنشئ سرًا من ملف .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. منح الأذونات:
غالبًا ما تتطلب موارد Kubernetes أذونات محددة. تطبيق الأدوار والارتباطات اللازمة:
cd deployments/infrastructure
kubectl apply -f role.yaml
kubectl apply -f rolebinding.yaml
4. نشر خدمة التخزين المؤقت باستخدام Redis:
الآن، قم بنشر خدمة التخزين المؤقت الدلالي باستخدام Redis:
cd ./deployments/redis
helm dependency build
helm upgrade --install redis .
5. نشر LiteLLM:
نشر خدمة LiteLLM:
kubens model-serving
helm upgrade --install litellm ./deployments/litellm
6. نشر واجهة WebUI المفتوحة:
بعد ذلك، انشر واجهة مستخدم الويب إلى مجموعة GKE الخاصة بك:
cd open-webui
kubectl apply -f ./kubernetes/manifest/base -n model-serving
7. العب مع التطبيق:
افتح المتصفح وانتقل إلى عنوان URL لمجموعة GKE الخاصة بك (على سبيل المثال http://172.0.0.0
في الخطوة 1) وأضف .nip.io
إلى نهاية عنوان URL (على سبيل المثال http://172.0.0.0.nip.io
) . يجب أن تشاهد واجهة WebUI المفتوحة:
بالنسبة لخطوط أنابيب CI/CD الآلية، استخدم Jenkins وAnsible كما يلي:
1. إعداد خادم جنكينز:
أولاً، قم بإنشاء حساب خدمة وقم بتعيين دور Compute Admin
له. ثم قم بإنشاء ملف مفتاح Json لحساب الخدمة وقم بتخزينه في الدليل iac/ansible/secrets
.
قم بعد ذلك بإنشاء مثيل Google Compute Engine المسمى "jenkins-server" الذي يعمل بنظام Ubuntu 22.04 مع قاعدة جدار الحماية التي تسمح بحركة المرور على المنفذين 8081 و50000.
ansible-playbook iac/ansible/deploy_jenkins/create_compute_instance.yaml
انشر Jenkins على خادم عن طريق تثبيت المتطلبات الأساسية، وسحب صورة Docker، وإنشاء حاوية مميزة مع إمكانية الوصول إلى مقبس Docker والمنافذ المكشوفة 8081 و50000.
ansible-playbook -i iac/ansible/inventory iac/ansible/deploy_jenkins/deploy_jenkins.yaml
2. الوصول إلى جينكينز:
للوصول إلى خادم Jenkins عبر SSH، نحتاج إلى إنشاء زوج مفاتيح عام/خاص. قم بتشغيل الأمر التالي لإنشاء زوج مفاتيح:
ssh-keygen
افتح Metadata
وانسخ قيمة ssh-keys
.
نحتاج إلى العثور على كلمة مرور خادم Jenkins حتى نتمكن من الوصول إلى الخادم. أولاً، قم بالوصول إلى خادم Jenkins:
ssh < USERNAME > : < EXTERNAL_IP >
ثم قم بتشغيل الأمر التالي للحصول على كلمة المرور:
sudo docker exec -it jenkins-server bash
cat /var/jenkins_home/secrets/initialAdminPassword
بمجرد نشر Jenkins، قم بالوصول إليه عبر متصفحك:
http://<EXTERNAL_IP>:8081
3. تثبيت ملحقات جنكينز:
قم بتثبيت المكونات الإضافية التالية لدمج Jenkins مع Docker وKubernetes وGKE:
بعد تثبيت المكونات الإضافية، قم بإعادة تشغيل Jenkins.
sudo docker restart jenkins-server
4. تكوين جنكينز:
4.1. أضف خطافات الويب إلى مستودع GitHub الخاص بك لتشغيل إصدارات Jenkins.
انتقل إلى مستودع GitHub وانقر على Settings
. انقر فوق Webhooks
ثم انقر فوق Add Webhook
. أدخل عنوان URL لخادم Jenkins الخاص بك (على سبيل المثال http://<EXTERNAL_IP>:8081/github-webhook/
). ثم انقر فوق Let me select individual events
وحدد " Let me select individual events
. حدد Pull Request
Push
والسحب وانقر فوق Add Webhook
.
4.2. أضف مستودع Github كمستودع كود مصدر Jenkins.
انتقل إلى لوحة تحكم Jenkins وانقر على New Item
. أدخل اسمًا لمشروعك (على سبيل المثال، easy-llmops
) وحدد Multibranch Pipeline
. انقر على OK
. انقر فوق Configure
ثم انقر فوق Add Source
. حدد GitHub
وانقر فوق Add
. أدخل عنوان URL لمستودع GitHub الخاص بك (على سبيل المثال https://github.com/bmd1905/EasyLLMOps
). في حقل Credentials
، حدد Add
وحدد Username with password
. أدخل اسم المستخدم وكلمة المرور الخاصين بـ GitHub (أو استخدم رمز وصول شخصي). انقر فوق Test Connection
ثم انقر فوق Save
.
4.3. إعداد بيانات اعتماد مركز الإرساء.
أولاً، قم بإنشاء حساب Docker Hub. انتقل إلى موقع Docker Hub وانقر على Sign Up
. أدخل اسم المستخدم وكلمة المرور الخاصة بك. انقر فوق Sign Up
. انقر فوق Create Repository
. أدخل اسمًا للمستودع الخاص بك (على سبيل المثال، easy-llmops
) وانقر فوق Create
.
من لوحة تحكم Jenkins، انتقل إلى Manage Jenkins
> Credentials
. انقر على Add Credentials
. حدد Username with password
وانقر فوق Add
. أدخل اسم مستخدم Docker Hub الخاص بك، ورمز الوصول، وقم بتعيين ID
على dockerhub
.
4.4. إعداد بيانات اعتماد Kubernetes.
أولاً، قم بإنشاء حساب خدمة لخادم Jenkins للوصول إلى مجموعة GKE. انتقل إلى وحدة تحكم Google Cloud Platform وانتقل إلى IAM & Admin > حسابات الخدمة. قم بإنشاء حساب خدمة جديد باستخدام دور Kubernetes Engine Admin
. قم بتسمية حساب الخدمة ووصفه. انقر فوق حساب الخدمة ثم انقر فوق علامة التبويب Keys
". انقر فوق Add Key
وحدد JSON
كنوع المفتاح. انقر فوق Create
وتنزيل ملف JSON.
ثم، من لوحة معلومات Jenkins، انتقل إلى Manage Jenkins
> Cloud
. انقر على New cloud
. حدد Kubernetes
. أدخل اسم مجموعتك (على سبيل المثال gke-easy-llmops-cluster-1), enter the URL and Certificate from your GKE cluster. In the
مساحة اسم Kubernetes , enter the namespace of your cluster (eg
، خدمة النماذج ). In the
field, select
إضافة and select
حساب خدمة Google من القطاع الخاص`. أدخل معرف المشروع الخاص بك والمسار إلى ملف JSON.
5. اختبار الإعداد:
ادفع التزامًا جديدًا إلى مستودع GitHub الخاص بك. يجب أن تشاهد بناءًا جديدًا في جينكينز.
1. إنشاء خطاف ويب Discord:
أولاً، قم بإنشاء خطاف ويب على Discord. انتقل إلى موقع Discord وانقر على Server Settings
. انقر على Integrations
. انقر فوق Create Webhook
. أدخل اسمًا لخطاف الويب الخاص بك (على سبيل المثال، easy-llmops-discord-webhook
) وانقر فوق Create
. انسخ عنوان URL الخاص بالويب هوك.
2. تكوين مستودعات هيلم
أولاً، نحتاج إلى إضافة مستودعات Helm اللازمة لـ Prometheus و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
تضيف هذه الأوامر مستودعات Prometheus وGrafana Helm الرسمية وتقوم بتحديث معلومات مخطط Helm المحلي لديك.
3. تثبيت التبعيات
يتطلب بروميثيوس بعض التبعيات التي يمكن إدارتها باستخدام هيلم. انتقل إلى دليل المراقبة وقم ببناء هذه التبعيات:
helm dependency build ./deployments/monitoring/kube-prometheus-stack
4. نشر بروميثيوس
سنقوم الآن بنشر Prometheus والخدمات المرتبطة به باستخدام 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
يقوم هذا الأمر بما يلي:
helm upgrade --install
: سيؤدي هذا إلى تثبيت Prometheus إذا لم يكن موجودًا، أو ترقيته إذا كان موجودًا.-f deployments/monitoring/kube-prometheus-stack.expanded.yaml
: يحدد هذا ملف قيم مخصصة للتكوين.kube-prometheus-stack
: هذا هو اسم الإصدار لتثبيت Helm.deployments/monitoring/kube-prometheus-stack
: هذا هو المخطط الذي سيتم استخدامه للتثبيت.-n monitoring
: يحدد هذا مساحة الاسم المراد التثبيت فيها.بشكل افتراضي، لا يتم عرض الخدمات خارجيًا. للوصول إليها، يمكنك استخدام إعادة توجيه المنفذ:
بالنسبة لبروميثيوس:
kubectl port-forward -n monitoring svc/kube-prometheus-stack-prometheus 9090:9090
ثم قم بالوصول إلى Prometheus على http://localhost:9090
بالنسبة للجرافانا:
kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 3000:80
ثم قم بالوصول إلى Grafana على http://localhost:3000
عادة ما تكون بيانات الاعتماد الافتراضية لـ Grafana هي:
5. اختبار التنبيه
نحتاج أولاً إلى إنشاء نموذج تنبيه. انتقل إلى دليل monitoring
وقم بتشغيل الأمر التالي:
kubectl port-forward -n monitoring svc/alertmanager-operated 9093:9093
ثم، في محطة جديدة، قم بتشغيل الأمر التالي:
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
يقوم هذا الأمر بإنشاء نموذج تنبيه. يمكنك التحقق من إنشاء التنبيه عن طريق تشغيل الأمر التالي:
curl http://localhost:9093/api/v2/status
أو يمكنك التحقق يدويًا من قناة Discord.
يوفر هذا الإعداد إمكانات مراقبة شاملة لمجموعة Kubernetes الخاصة بك. من خلال قيام Prometheus بجمع المقاييس وتصور Grafana لها، يمكنك تتبع الأداء بشكل فعال، وإعداد تنبيهات للمشكلات المحتملة، والحصول على رؤى قيمة حول البنية التحتية والتطبيقات الخاصة بك.
يعد التسجيل المركزي ضروريًا لمراقبة التطبيقات المنشورة على Kubernetes واستكشاف الأخطاء وإصلاحها. يرشدك هذا القسم خلال إعداد مكدس ELK (Elasticsearch وLogstash وKibana) باستخدام Filebeat لتسجيل مجموعة GKE الخاصة بك.
0. الجري السريع
يمكنك استخدام هذا البرنامج النصي helmfile الفردي لبدء مكدس ELK:
cd deployments/ELK
helmfile sync
1. قم بتثبيت ELK Stack بالخوذة
سوف نستخدم Helm لنشر مكونات مكدس ELK:
أولاً، قم بإنشاء مساحة اسم لمكونات التسجيل:
kubectl create ns logging
kubens logging
بعد ذلك، قم بتثبيت Elasticsearch:
helm install elk-elasticsearch elastic/elasticsearch -f deployments/ELK/elastic.expanded.yaml --namespace logging --create-namespace
انتظر حتى يصبح Elasticsearch جاهزًا:
echo " Waiting for Elasticsearch to be ready... "
kubectl wait --for=condition=ready pod -l app=elasticsearch-master --timeout=300s
قم بإنشاء سر لـ Logstash للوصول إلى 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 )
تثبيت كيبانا:
helm install elk-kibana elastic/kibana -f deployments/ELK/kibana.expanded.yaml
تثبيت لوغستاش:
helm install elk-logstash elastic/logstash -f deployments/ELK/logstash.expanded.yaml
تثبيت Filebeat:
helm install elk-filebeat elastic/filebeat -f deployments/ELK/filebeat.expanded.yaml
2. الوصول إلى كيبانا:
فضح Kibana باستخدام إحدى الخدمات والوصول إليها من خلال متصفحك:
kubectl port-forward -n logging svc/elk-kibana-kibana 5601:5601
الرجاء استخدام هذا البرنامج النصي للحصول على كلمة مرور Kibana:
kubectl get secrets --namespace=logging elasticsearch-master-credentials -ojsonpath= ' {.data.password} ' | base64 -d
افتح المتصفح وانتقل إلى http://localhost:5601
.
3. التحقق من جمع السجل
من المفترض أن تكون الآن قادرًا على رؤية السجلات من كبسولات Kubernetes الخاصة بك في Kibana. يمكنك إنشاء لوحات معلومات ومرئيات لتحليل سجلاتك والحصول على رؤى حول سلوك التطبيق الخاص بك.
يرجى الانتقال إلى Cast AI للتسجيل للحصول على حساب مجاني والحصول على الرمز المميز.
ثم قم بتشغيل هذا الخط للاتصال بـ GKE:
curl -H " Authorization: Token <TOKEN> " " https://api.cast.ai/v1/agent.yaml?provider=gke " | kubectl apply -f -
اضغط على I ran this script
على واجهة مستخدم Cast AI، ثم انسخ رمز التكوين والصقه في الجهاز:
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 ' ) "
اضغط على I ran this script
مرة أخرى وانتظر حتى يكتمل التثبيت.
بعد ذلك، يمكنك رؤية لوحات المعلومات الخاصة بك على واجهة مستخدم Cast AI:
حان الوقت لتحسين مجموعتك باستخدام Cast AI! انتقل إلى قسم Available savings
وانقر على زر Rebalance
.
يُرجى الانتقال إلى Langfuse وSupabase للتسجيل للحصول على حساب مجاني والحصول على مفاتيح API، ثم استبدال العناصر النائبة في ملف .env.example بمفاتيح API الخاصة بك.
نحن نرحب بالمساهمات في EasyLLMOps! يرجى الاطلاع على CONTRIBUTING.md لمزيد من المعلومات حول كيفية البدء.
تم إصدار EasyLLMOps بموجب ترخيص MIT. راجع ملف الترخيص لمزيد من التفاصيل.
إذا كنت تستخدم EasyLLMOps في بحثك، فيرجى الاستشهاد به على النحو التالي:
@software{EasyLLMOps2024,
author = {Minh-Duc Bui},
title = {EasyLLMOps: Effortless MLOps for Powerful Language Models.},
year = {2024},
url = {https://github.com/bmd1905/EasyLLMOps}
}
بالنسبة للأسئلة أو المشكلات أو التعاون، يرجى فتح مشكلة في مستودع GitHub الخاص بنا أو الاتصال بالمشرفين مباشرة.