TimesFM in der GDC Sandbox bereitstellen

Das TimesFM-Modell von Google Research ist ein Fundierungsmodell für Zeitreihenprognosen, das mit Milliarden von Zeitpunkten aus vielen realen Datasets vortrainiert wurde. Sie können es also auf neue Prognosedatasets in vielen Bereichen anwenden.

In dieser Anleitung wird beschrieben, wie Sie TimesFM in der GDC Sandbox bereitstellen. Sie hat die folgenden Ziele:

  • Einen Docker-Container erstellen, der TimesFM ausführt
  • Stellen Sie den Container mit GPUs bereit, die von der KI-optimierten SKU für GDC Sandbox bereitgestellt werden.
  • TimesFM-Funktionen mit einfachen HTTP-Anfragen aufrufen

Hinweise

Die GPUs in GDC Sandbox sind im org-infra-Cluster enthalten.

  • Wenn Sie Befehle für den Infrastrukturcluster der Organisation ausführen möchten, müssen Sie die kubeconfig des org-1-infra-Clusters haben, wie unter Mit Clustern arbeiten beschrieben:

    • Konfigurieren und authentifizieren Sie sich mit der gdcloud-Befehlszeile.
    • Generieren Sie die kubeconfig-Datei für den Infrastrukturcluster der Organisation und weisen Sie ihren Pfad der Umgebungsvariable KUBECONFIG zu.
  • Prüfen Sie, ob dem Nutzer die Rolle sandbox-gpu-admin für das Projekt sandbox-gpu-project zugewiesen ist. Standardmäßig ist die Rolle dem Nutzer platform-admin zugewiesen. Sie können die Rolle anderen Nutzern zuweisen, indem Sie sich als platform-admin anmelden und den folgenden Befehl ausführen:

    kubectl --kubeconfig ${KUBECONFIG} create rolebinding ${NAME} --role=sandbox-gpu-admin \
    --user=${USER} --namespace=sandbox-gpu-project
    
  • Richten Sie das Artifact Registry-Repository wie unter Artifact Registry verwenden beschrieben ein und melden Sie sich an, um Images in die Artifact Registry zu übertragen und daraus abzurufen.

TimesFM-Modell bereitstellen

Das Deployment wird über eine Reihe von Kubernetes-Konfigurationsdateien (YAML-Manifeste) orchestriert, die jeweils eine bestimmte Komponente oder einen bestimmten Dienst definieren.

  1. Erstelle ein auf Flask basierendes Python-Skript app.py mit den Funktionen predict für die Zeitreihenvorhersage und timeseries zum Generieren einer Visualisierung auf Grundlage der Testdaten.

      from flask import Flask, jsonify, request
      import numpy as np
      import pandas as pd
      from sklearn.preprocessing import StandardScaler
    
      # Initialize Flask application
      app = Flask(__name__)
    
      # Sample route to display a welcome message
      @app.route('/')
      def home():
          return "Welcome to TimesFM! Use the API to interact with the app."
    
      # Example route for predictions (TimesFM might do time-series forecasting or music recommendations)
      @app.route('/predict', methods=['POST'])
      def predict():
          data = request.get_json()
    
          # Ensure the data is in the right format
          if 'features' not in data:
              return jsonify({'error': 'No features provided'}), 400
    
          # For this example, assume 'features' is a list of numbers that need to be scaled
          features = data['features']
          features = np.array(features).reshape(1, -1)
    
          # Dummy model: Apply standard scaling (you would use an actual model here)
          scaler = StandardScaler()
          scaled_features = scaler.fit_transform(features)
    
          # You would normally load your model here (e.g., using pickle or joblib)
          # For simplicity, let's just return the scaled features as a placeholder for prediction
          result = scaled_features.tolist()
    
          return jsonify({'scaled_features': result})
    
      # Example of a route for data visualization or analysis
      @app.route('/timeseries', methods=['GET'])
      def timeseries_analysis():
          # Generate a dummy time series data (replace with actual data)
          time_series_data = pd.Series(np.random.randn(100), name="Random Data")
    
          # Example analysis: compute simple moving average
          moving_avg = time_series_data.rolling(window=10).mean()
    
          return jsonify({
              'time_series': time_series_data.tolist(),
              'moving_average': moving_avg.tolist()
          })
    
      # Run the app
      if __name__ == '__main__':
          app.run(debug=True, host='0.0.0.0', port=5000)
    
  2. Erstellen Sie ein Dockerfile mit timesfm, das die App aufruft.

     # Use a base image with Python installed
     FROM python:3.11-slim
     # Set the working directory inside the container
     WORKDIR /app
     # Copy the requirements.txt (if any) and install dependencies
     COPY requirements.txt .
     RUN pip install --no-cache-dir numpy pandas timesfm huggingface_hub jax pytest flask scikit-learn
    
     # Copy the rest of the code into the container
     COPY . .
    
     # Expose the necessary port (default 5000 or whatever your app uses)
     EXPOSE 5000
    
     # Define the entrypoint for the container
     CMD ["python", "app.py"] # Replace with the correct entry script for TimesFM
    
  3. Erstellen Sie das Docker-Image und laden Sie es in das Artifact Registry-Repository hoch.

    docker build -t timesfm .
    docker tag timesfm "REGISTRY_REPOSITORY_URL"/timesfm:latest
    docker push "REGISTRY_REPOSITORY_URL"/timesfm:latest
    

    Ersetzen Sie Folgendes:

    • REGISTRY_REPOSITORY_URL: die Repository-URL.
  4. Erstellen Sie ein Secret zum Speichern der Docker-Anmeldedaten.

    
    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
    

    Ersetzen Sie Folgendes:

    • DOCKER_REGISTRY_SECRET: Name des Secrets.
  5. Erstellen Sie eine Datei timesfm-deployment.yaml, um timesfm bereitzustellen.

    Für die Bereitstellung des timesfm-Servers ist eine GPU erforderlich.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: timesfm-deployment
      namespace: sandbox-gpu-project
      labels:
        app: timesfm
    spec:
      replicas: 1 # You can scale up depending on your needs
      selector:
        matchLabels:
          app: timesfm
      template:
        metadata:
          labels:
            app: timesfm
        spec:
          containers:
          - name: timesfm
            image: REGISTRY_REPOSITORY_URL/timesfm:latest
            ports:
            - containerPort: 5000
            resources:
              requests:
                nvidia.com/gpu-pod-NVIDIA_H100_80GB_HBM3: 1  # Request 1 GPU
              limits:
                nvidia.com/gpu-pod-NVIDIA_H100_80GB_HBM3: 1  # Limit to 1 GPU
            env:
            - name: ENV
              value: "production"
          imagePullSecrets:
          - name: docker-registry-secret
    

    Ersetzen Sie Folgendes:

    • REGISTRY_REPOSITORY_URL: die Repository-URL.
    • DOCKER_REGISTRY_SECRET: Name des Docker-Secrets.
  6. Erstellen Sie eine Datei timesfm-service.yaml, um den timesfm-Server intern verfügbar zu machen.

    apiVersion: v1
    kind: Service
    metadata:
      name: timesfm-service
    spec:
      selector:
        app: timesfm
      ports:
        - protocol: TCP
          port: 80 # External port exposed
          targetPort: 5000 # Internal container port for Flask
      type: LoadBalancer # Use NodePort for internal access
    
  7. Wenden Sie die Manifeste an.

    kubectl --kubeconfig ${KUBECONFIG} apply -f timesfm-deployment.yaml
    kubectl --kubeconfig ${KUBECONFIG} apply -f timesfm-service.yaml
    
  8. Prüfen Sie, ob die TimesFM-Pods ausgeführt werden.

    kubectl --kubeconfig ${KUBECONFIG} get deployments timesfm-deployment -n sandbox-gpu-project
    kubectl --kubeconfig ${KUBECONFIG} get service timesfm-service -n sandbox-gpu-project
    
  9. Erstellen Sie eine Projektnetzwerkrichtlinie, um eingehenden Traffic von externen IP-Adressen zuzulassen.

    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
    
  10. Ermitteln Sie mit dem folgenden Befehl die externe IP-Adresse des TimesFM-Dienstes. Notieren Sie sich den Wert für die späteren Schritte, in denen Sie ihn für TIMESFM_END_POINT einsetzen.

      kubectl --kubeconfig ${KUBECONFIG} get service timesfm-service \
            -n sandbox-gpu-project -o jsonpath='{.status.loadBalancer.ingress[*].ip}'
    

Den Dienst testen

  1. Wenn Sie eine Vorhersage erhalten möchten, senden Sie Daten mit dem Befehl curl an den Dienst. Ersetzen Sie dabei TIMESFM_END_POINT durch die tatsächliche Adresse des Dienstes und Ihre Eingabewerte für die Funktionen. Dadurch wird die in app.py definierte Funktion predict aufgerufen, die Ihre Eingabedaten manipuliert und im JSON-Format zurückgibt.

    curl -X POST http://TIMESFM_END_POINT/predict -H "Content-Type: application/json" -d '{"features": [1.2, 3.4, 5.6]}'
    
  2. Senden Sie eine curl-Anfrage an /timeseries, um ein Beispiel für die Datenvisualisierung mit zufällig generierten Daten zu sehen. Dadurch wird die in „app.py“ definierte Zeitreihenfunktion aufgerufen, die eine zufällige Zeitreihe generiert und eine gleitende Durchschnittsanalyse dafür durchführt.

    curl http://TIMESFM_END_POINT/timeseries