פריסת Gemma באמצעות Ollama ו-Open-WebUI

עם מעבדי ה-GPU של NVIDIA ברמה הארגונית שכלולים ב-SKU של GDC Sandbox עם אופטימיזציה ל-AI, אתם יכולים לפתח ולבדוק אפליקציות תובעניות של אימון AI והסקת מסקנות, כמו AI גנרטיבי.

‫Gemma הוא מודל שפה גדול וקל משקל שמבוסס על טכנולוגיית Gemini. במדריך הזה נסביר איך לפרוס את Gemma באמצעות Ollama ו-Open-WebUI ב-GDC Sandbox. המדריך כולל את המטרות הבאות:

  • פריסת Ollama עם מודל Gemma בארגז חול של GDC שעבר אופטימיזציה ל-AI עם מעבדי GPU.
  • שליחת הנחיות לשירות Ollama בנקודת הקצה הפרטית שלו דרך ממשק Open-WebUI.

לפני שמתחילים

ה-GPU בארגז החול של GDC נכללים באשכול org-infra.

  • כדי להריץ פקודות מול אשכול התשתית של הארגון, צריך לוודא שיש לכם את קובץ ה-kubeconfig של אשכול org-1-infra, כמו שמתואר במאמר עבודה עם אשכולות:

    • להגדיר ולאמת באמצעות שורת הפקודה gdcloud, וגם
    • יוצרים את קובץ ה-kubeconfig עבור אשכול התשתית של הארגון, ומקצים את הנתיב שלו למשתנה הסביבה KUBECONFIG.
  • מוודאים שהוקצה למשתמש התפקיד sandbox-gpu-admin בפרויקט sandbox-gpu-project. כברירת מחדל, התפקיד מוקצה למשתמש platform-admin. כדי להקצות את התפקיד למשתמשים אחרים, צריך להיכנס לחשבון בתור platform-admin ולהריץ את הפקודה הבאה:

    kubectl --kubeconfig ${KUBECONFIG} create rolebinding ${NAME} --role=sandbox-gpu-admin \
    --user=${USER} --namespace=sandbox-gpu-project
    
  • חשוב להגדיר מאגר Artifact Registry כמו שמתואר במאמר שימוש ב-Artifact Registry ולהיכנס לחשבון כדי להעביר בדחיפה ולמשוך קובצי אימג' ל-Artifact Registry.

פריסת מודל Gemma באמצעות Ollama ו-Open-WebUI

הפריסה מתבצעת באמצעות קבוצה של קובצי הגדרות של Kubernetes (מניפסטים של YAML), שכל אחד מהם מגדיר רכיב או שירות ספציפיים.

  1. יוצרים קובץ Dockerfile עם Gemma שהורד מראש.

     FROM ubuntu
    
     # Install Ollama
     # This uses Ollamas official installation script, which adds Ollama to /usr/local/bin
     RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates zstd
     RUN curl -fsSL https://ollama.com/install.sh -o install.sh
     RUN chmod +x install.sh
     RUN ./install.sh && \
         rm -rf /var/lib/apt/lists/*
    
     # Set environment variables for Ollama (optional, but good practice)
     ENV OLLAMA_HOST="0.0.0.0"
     # ENV OLLAMA_MODELS="/usr/local/ollama/models" # Default is /root/.ollama
     # If you want to customize the model storage path within the container, set OLLAMA_MODELS
     # and then ensure you create and populate that directory. Default is usually fine for pre-downloaded.
    
     # --- Predownload Gemma Model ---
     # This step starts Ollama server in the background, pulls the model,
     # and then kills the server to allow the Docker build to continue.
     # This approach works around Docker''s RUN command limitations for services.
    
     RUN ollama serve & \
         sleep 5 && \
         # Give the Ollama server a moment to start up
         # Use --retry and --retry-connrefused to handle startup delays
         curl --retry 10 --retry-connrefused -s http://localhost:11434 || true && \
         echo "Attempting to pull gemma:7b..." && \
         ollama pull gemma:7b && \
         echo "Model pull complete. Cleaning up background Ollama process." && \
         pkill ollama || true # Gracefully kill the ollama serve process
    
     # Expose Ollama's default port
     EXPOSE 11434
    
     # Command to run Ollama server when the container starts
     CMD ["ollama", "serve"]
    
    
  1. יוצרים את קובץ האימג' של Docker ומעלים אותו למאגר ב-Artifact Registry.

    docker build -t ollama-gemma .
    docker tag ollama-gemma REGISTRY_REPOSITORY_URL/ollama-gemma:latest
    docker push REGISTRY_REPOSITORY_URL/ollama-gemma:latest
    

    מחליפים את מה שכתוב בשדות הבאים:

    • REGISTRY_REPOSITORY_URL בכתובת ה-URL של המאגר.
  2. יוצרים סוד כדי לשמור את פרטי הכניסה של Docker.

    
    export SECRET=DOCKER_REGISTRY_SECRET
    export DOCKER_TEST_CONFIG=~/.docker/config.json
    kubectl --kubeconfig ${KUBECONFIG} create secret docker-registry ${SECRET} --from-file=.dockerconfigjson=${DOCKER_TEST_CONFIG} -n sandbox-gpu-project
    

    מחליפים את מה שכתוב בשדות הבאים:

    • DOCKER_REGISTRY_SECRET שם הסוד.
  3. יוצרים קובץ ollama-deployment.yaml כדי להגדיר את פריסת מנוע ה-AI של Ollama:

    הפריסה של שרת Ollama דורשת GPU אחד.

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        annotations:
          deployment.kubernetes.io/revision: "9"
        name: ollama
        namespace: sandbox-gpu-project
      spec:
        progressDeadlineSeconds: 600
        replicas: 1
        revisionHistoryLimit: 10
        selector:
          matchLabels:
            app: ollama
        strategy:
          rollingUpdate:
            maxSurge: 25%
            maxUnavailable: 25%
          type: RollingUpdate
        template:
          metadata:
            creationTimestamp: null
            labels:
              app: ollama
              egress.networking.gke.io/enabled: "true"
          spec:
            containers:
              - name: ollama
                image: REGISTRY_REPOSITORY_URL/ollama-gemma:latest
                imagePullPolicy: Always
                ports:
                  - containerPort: 11434
                    protocol: TCP
                resources:
                  limits:
                    nvidia.com/gpu-pod-NVIDIA_H100_80GB_HBM3: "1"
                  requests:
                    nvidia.com/gpu-pod-NVIDIA_H100_80GB_HBM3: "1"
                env:
                  - name: OLLAMA_HOST
                    value: 0.0.0.0
                  - name: OLLAMA_ORIGINS
                    value: http://localhost:8080,http://ollama-webui.ollama-llm.svc.cluster.local:8080,http://ollama-webui:8080
                securityContext:
                  seLinuxOptions:
                    type: unconfined_t
                terminationMessagePath: /dev/termination-log
                terminationMessagePolicy: File
            imagePullSecrets:
            - name: DOCKER_REGISTRY_SECRET
            dnsConfig:
              nameservers:
                - 8.8.8.8
            dnsPolicy: ClusterFirst
            restartPolicy: Always
            schedulerName: default-scheduler
            terminationGracePeriodSeconds: 30
    
    

    מחליפים את מה שכתוב בשדות הבאים:

    • REGISTRY_REPOSITORY_URL: כתובת ה-URL של המאגר.
    • DOCKER_REGISTRY_SECRET: שם הסוד.
  4. יוצרים את הקובץ ollama-service.yaml כדי לחשוף את שרת Ollama באופן פנימי.

    apiVersion: v1
    kind: Service
    metadata:
      name: ollama
      namespace: sandbox-gpu-project
      annotations:
        metallb.universe.tf/ip-allocated-from-pool: lb-address-pool-0-ptleg
    spec:
      type: LoadBalancer
      selector:
        app: ollama
      ports:
        - port: 11434
          nodePort: 30450
      ipFamilyPolicy: SingleStack
      ipFamilies:
        - IPv4
      clusterIPs:
        - 10.1.122.216
      clusterIP: 10.1.122.216
    
  5. החלת המניפסטים

    kubectl --kubeconfig ${KUBECONFIG} apply -f ollama-deployment.yaml
    kubectl --kubeconfig ${KUBECONFIG} apply -f ollama-service.yaml
    
  6. מוודאים שה-pods של ollama פועלים.

    kubectl --kubeconfig ${KUBECONFIG} get deployments -n sandbox-gpu-project
    kubectl --kubeconfig ${KUBECONFIG} get service -n sandbox-gpu-project
    
  7. שימו לב לכתובת ה-IP החיצונית של שירות Ollama OLLAMA_BASE_END_POINT מהפלט

    kubectl --kubeconfig ${KUBECONFIG} get service ollama \
          -n sandbox-gpu-project -o jsonpath='{.status.loadBalancer.ingress[*].ip}'
    
  8. יוצרים את הקובץ openweb-ui-deployment.yaml כדי לפרוס את הממשק של Open-WebUI.

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: ollama-webui
        namespace: sandbox-gpu-project
        labels:
          app: ollama-webui
        annotations:
          deployment.kubernetes.io/revision: "5"
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: ollama-webui
        strategy:
          type: RollingUpdate
          rollingUpdate:
            maxSurge: 25%
            maxUnavailable: 25%
        progressDeadlineSeconds: 600
        revisionHistoryLimit: 10
        template:
          metadata:
            labels:
              app: ollama-webui
            creationTimestamp: null
          spec:
            containers:
              - name: ollama-webui
                image: ghcr.io/open-webui/open-webui:main
                imagePullPolicy: IfNotPresent
                ports:
                  - name: http
                    containerPort: 8080
                    protocol: TCP
                env:
                  - name: OLLAMA_BASE_URL
                    value: OLLAMA_BASE_END_POINT
                  - name: PORT
                    value: "8080"
                terminationMessagePath: /dev/termination-log
                terminationMessagePolicy: File
            restartPolicy: Always
            dnsPolicy: ClusterFirst
            schedulerName: default-scheduler
            terminationGracePeriodSeconds: 30
    

    מחליפים את מה שכתוב בשדות הבאים:

    • OLLAMA_BASE_END_POINT: כתובת ה-IP החיצונית של שירות Ollama.
  9. יוצרים קובץ ollama-webui-service.yaml כדי לחשוף את ממשק ה-webui הפתוח באופן חיצוני.

    apiVersion: v1
    kind: Service
    metadata:
      name: ollama-webui
      namespace: sandbox-gpu-project
      annotations:
        metallb.universe.tf/ip-allocated-from-pool: lb-address-pool-0-ptleg
    spec:
      type: LoadBalancer
      ipFamilyPolicy: SingleStack
      ipFamilies:
      - IPv4
      clusterIPs:
      - 10.1.104.52
      clusterIP: 10.1.104.52
      ports:
      - port: 80
        targetPort: 8080
        nodePort: 32351
      selector:
        app: ollama-webui
    
  10. מחילים את קובצי המניפסט openweb-ui-deployment.yaml ו-ollama-webui-service.yaml על האשכול.

        kubectl --kubeconfig ${KUBECONFIG} apply -f openweb-ui-deployment.yaml
        kubectl --kubeconfig ${KUBECONFIG} apply -f ollama-webui-service.yaml
    
  11. יוצרים מדיניות רשת בפרויקט כדי לאפשר תנועה נכנסת מכתובות IP חיצוניות.

    kubectl --kubeconfig ${KUBECONFIG} apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: ProjectNetworkPolicy
    metadata:
      namespace: sandbox-gpu-project
      name: allow-inbound-traffic-from-external
    spec:
      policyType: Ingress
      subject:
        subjectType: UserWorkload
      ingress:
      - from:
        - ipBlock:
            cidr: 0.0.0.0/0
    EOF
    
  12. מריצים את הפקודה הבאה כדי לזהות את כתובת ה-IP החיצונית של שירות Ollama. חשוב לשמור את הערך הזה כדי להשתמש בו בשלבים הבאים, שבהם תצטרכו להחליף את הערך OPEN_WEB_UI_ENDPOINT.

    kubectl --kubeconfig ${KUBECONFIG} get service -n sandbox-gpu-project
    
  13. פותחים את Google Chrome ומזינים את כתובת ה-URL באמצעות כתובת ה-IP החיצונית שמצאתם בשלב הקודם. עכשיו אפשר להשתמש במודל Gemma דרך ממשק Open Web UI.

    http://OPEN_WEB_UI_ENDPOINT/