EasyLLMOps: 강력한 언어 모델을 위한 간편한 MLOps.
EasyLLMOps는 언어 모델을 관리하고 확장하기 위해 Google Kubernetes Engine(GKE)에 배포할 수 있는 Open WebUI로 구축된 프로젝트입니다. Terraform과 수동 배포 방법을 모두 제공하고 강력한 MLOps 방식을 통합합니다. 여기에는 자동화를 위한 Jenkins 및 Ansible을 사용한 CI/CD 파이프라인, 성능 통찰력을 위한 Prometheus 및 Grafana를 사용한 모니터링, 문제 해결 및 분석을 위한 ELK 스택을 사용한 중앙 집중식 로깅이 포함됩니다. 개발자는 프로젝트 웹사이트에서 자세한 문서와 지침을 찾을 수 있습니다.
LLM 기반 애플리케이션을 구축하고 배포하는 개발자입니다. LLM으로 작업하는 데이터 과학자 및 기계 학습 엔지니어. LLM 인프라 관리를 담당하는 DevOps 팀입니다. LLM을 운영에 통합하려는 조직.
많은 시간을 보내고 싶지 않은 경우 다음 스크립트를 실행하고 커피를 즐기십시오.
chmod +x ./cluster.sh
./cluster.sh
Terraform을 사용하기 전에 GCP에 인증해야 합니다.
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 수신 컨트롤러는 Kubernetes 클러스터의 서비스에 대한 외부 액세스를 관리합니다. Helm을 사용하여 네임스페이스를 만들고 수신 컨트롤러를 설치합니다.
kubectl create ns nginx-system
kubens nginx-system
helm upgrade --install nginx-ingress ./deployments/nginx-ingress
나중에 필요하므로 Nginx Ingress Controller의 IP 주소를 알려주세요.
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 클러스터에 웹 UI를 배포합니다.
cd open-webui
kubectl apply -f ./kubernetes/manifest/base -n model-serving
7. 애플리케이션을 가지고 놀아보세요:
브라우저를 열고 GKE 클러스터의 URL(예: 1단계의 http://172.0.0.0
)로 이동한 후 URL 끝에 .nip.io
추가합니다(예: http://172.0.0.0.nip.io
). . Open WebUI가 표시되어야 합니다.
자동화된 CI/CD 파이프라인의 경우 다음과 같이 Jenkins 및 Ansible을 사용합니다.
1. Jenkins 서버 설정:
먼저 서비스 계정을 생성하고 여기에 Compute Admin
역할을 할당합니다. 그런 다음 서비스 계정에 대한 Json 키 파일을 생성하고 iac/ansible/secrets
디렉터리에 저장합니다.
다음으로 포트 8081 및 50000에서 트래픽을 허용하는 방화벽 규칙을 사용하여 Ubuntu 22.04를 실행하는 'jenkins-server'라는 Google Compute Engine 인스턴스를 만듭니다.
ansible-playbook iac/ansible/deploy_jenkins/create_compute_instance.yaml
필수 구성 요소를 설치하고, Docker 이미지를 가져오고, Docker 소켓 및 노출된 포트 8081 및 50000에 대한 액세스 권한이 있는 권한 있는 컨테이너를 생성하여 서버에 Jenkins를 배포합니다.
ansible-playbook -i iac/ansible/inventory iac/ansible/deploy_jenkins/deploy_jenkins.yaml
2. Jenkins에 액세스합니다.
SSH를 통해 Jenkins 서버에 액세스하려면 공개/개인 키 쌍을 생성해야 합니다. 다음 명령을 실행하여 키 쌍을 생성합니다.
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 플러그인을 설치합니다:
Jenkins를 Docker, Kubernetes, GKE와 통합하려면 다음 플러그인을 설치하세요.
플러그인을 설치한 후 Jenkins를 다시 시작합니다.
sudo docker restart jenkins-server
4. Jenkins를 구성합니다.
4.1. Jenkins 빌드를 트리거하려면 GitHub 저장소에 웹후크를 추가하세요.
GitHub 저장소로 이동하여 Settings
클릭합니다. Webhooks
를 클릭한 다음 Add Webhook
클릭합니다. Jenkins 서버의 URL을 입력하세요(예 http://<EXTERNAL_IP>:8081/github-webhook/
). 그런 다음 Let me select individual events
을 클릭하고 Let me select individual events
선택합니다. Push
및 Pull Request
선택하고 Add Webhook
클릭합니다.
4.2. Github 저장소를 Jenkins 소스 코드 저장소로 추가합니다.
Jenkins 대시보드로 이동하여 New Item
클릭합니다. 프로젝트 이름(예: easy-llmops
)을 입력하고 Multibranch Pipeline
선택합니다. OK
을 클릭하세요. Configure
클릭한 다음 Add Source
클릭합니다. GitHub
선택하고 Add
클릭합니다. GitHub 저장소의 URL을 입력하세요(예: https://github.com/bmd1905/EasyLLMOps
). Credentials
필드에서 Add
선택하고 Username with password
선택합니다. GitHub 사용자 이름과 비밀번호를 입력하세요(또는 개인 액세스 토큰을 사용하세요). Test Connection
클릭한 다음 Save
을 클릭합니다.
4.3. Docker 허브 자격 증명을 설정합니다.
먼저 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 자격 증명을 설정합니다.
먼저 GKE 클러스터에 액세스하기 위해 Jenkins 서버용 서비스 계정을 만듭니다. GCP 콘솔로 이동하여 IAM 및 관리자 > 서비스 계정으로 이동합니다. 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 Namespace gke-easy-llmops-cluster-1), enter the URL and Certificate from your GKE cluster. In the
, enter the namespace of your cluster (eg
model-serving ). In the
자격 증명 필드 ). In the
추가를 field, select
and select
. 프로젝트 ID와 JSON 파일 경로를 입력하세요.
5. 설정을 테스트합니다.
GitHub 저장소에 새 커밋을 푸시합니다. Jenkins에 새 빌드가 표시됩니다.
1. Discord 웹훅 생성:
먼저 Discord 웹훅을 만듭니다. Discord 웹사이트로 이동하여 Server Settings
클릭하세요. Integrations
클릭합니다. Create Webhook
을 클릭하세요. 웹훅 이름(예: easy-llmops-discord-webhook
)을 입력하고 Create
를 클릭하세요. 웹훅 URL을 복사합니다.
2. Helm 저장소 구성
먼저 Prometheus 및 Grafana에 필요한 Helm 저장소를 추가해야 합니다.
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. 종속성 설치
Prometheus에는 Helm으로 관리할 수 있는 특정 종속성이 필요합니다. 모니터링 디렉터리로 이동하여 다음 종속성을 빌드합니다.
helm dependency build ./deployments/monitoring/kube-prometheus-stack
4. 프로메테우스 배포
이제 Helm을 사용하여 Prometheus 및 관련 서비스를 배포하겠습니다.
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
그런 다음 http://localhost:9090
에서 Prometheus에 액세스합니다.
그라파나의 경우:
kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 3000:80
그런 다음 http://localhost:3000
에서 Grafana에 액세스합니다.
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에 배포된 애플리케이션을 모니터링하고 문제를 해결하려면 중앙 집중식 로깅이 필수적입니다. 이 섹션에서는 GKE 클러스터 로깅을 위해 Filebeat를 사용하여 ELK 스택(Elasticsearch, Logstash, Kibana)을 설정하는 과정을 안내합니다.
0. 빠른 실행
이 단일 helmfile 스크립트를 사용하여 ELK 스택을 시작할 수 있습니다.
cd deployments/ELK
helmfile sync
1. Helm과 함께 ELK 스택 설치
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
Elasticsearch에 액세스하기 위해 Logstash에 대한 비밀을 생성합니다.
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 )
Kibana를 설치합니다:
helm install elk-kibana elastic/kibana -f deployments/ELK/kibana.expanded.yaml
Logstash를 설치합니다:
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에 액세스:
서비스를 사용하여 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. 로그 수집 확인
이제 Kibana에서 Kubernetes Pod의 로그를 볼 수 있습니다. 대시보드와 시각화를 생성하여 로그를 분석하고 애플리케이션 동작에 대한 통찰력을 얻을 수 있습니다.
Cast AI로 이동하여 무료 계정을 등록하고 TOKEN을 받으세요.
그런 다음 다음 줄을 실행하여 GKE에 연결합니다.
curl -H " Authorization: Token <TOKEN> " " https://api.cast.ai/v1/agent.yaml?provider=gke " | kubectl apply -f -
Cast AI의 UI에서 I ran this script
다음 구성 코드를 복사하여 터미널에 붙여넣습니다.
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 UI에서 대시보드를 볼 수 있습니다.
이제 Cast AI로 클러스터를 최적화할 때입니다! Available savings
섹션으로 이동하여 Rebalance
버튼을 클릭하세요.
Langfuse 및 Supabase로 이동하여 무료 계정에 가입하고 API 키를 얻은 다음 .env.example 파일의 자리 표시자를 API 키로 바꾸세요.
EasyLLMOps에 대한 기여를 환영합니다! 시작하는 방법에 대한 자세한 내용은 CONTRIBUTING.md를 참조하세요.
EasyLLMOps는 MIT 라이센스에 따라 출시됩니다. 자세한 내용은 LICENSE 파일을 참조하세요.
연구에 EasyLLMOps를 사용하는 경우 다음과 같이 인용해 주세요.
@software{EasyLLMOps2024,
author = {Minh-Duc Bui},
title = {EasyLLMOps: Effortless MLOps for Powerful Language Models.},
year = {2024},
url = {https://github.com/bmd1905/EasyLLMOps}
}
질문, 문제 또는 협업이 있는 경우 GitHub 저장소에서 문제를 열거나 관리자에게 직접 문의하세요.