O modelo TimesFM da Google Research é um modelo base para a previsão de séries de tempo que foi pré-preparado em milhares de milhões de pontos de tempo de muitos conjuntos de dados do mundo real, para que o possa aplicar a novos conjuntos de dados de previsão em vários domínios.
Este guia de tutorial mostra como implementar o TimesFM na área de testes do GDC e tem os seguintes objetivos.
- Crie um contentor do Docker que execute o TimesFM
- Implemente o contentor com GPUs fornecidas pelo SKU otimizado para IA do sandbox da GDC e
- Invocar funções TimesFM através de pedidos HTTP simples.
Antes de começar
As GPUs no sandbox da GDC estão incluídas no cluster org-infra
.
Para executar comandos no cluster de infraestrutura da organização, certifique-se de que tem o kubeconfig do cluster
org-1-infra
, conforme descrito em Trabalhar com clusters:- Configurar e autenticar com a linha de comandos
gdcloud
e - gerar o ficheiro kubeconfig para o cluster de infraestrutura da organização e
atribuir o respetivo caminho à variável de ambiente
KUBECONFIG
.
- Configurar e autenticar com a linha de comandos
Certifique-se de que a função
sandbox-gpu-admin
está atribuída ao utilizador para o projetosandbox-gpu-project
. Por predefinição, a função é atribuída ao utilizadorplatform-admin
. Pode atribuir a função a outros utilizadores iniciando sessão comoplatform-admin
e executando o seguinte comando:kubectl --kubeconfig ${KUBECONFIG} create rolebinding ${NAME} --role=sandbox-gpu-admin \ --user=${USER} --namespace=sandbox-gpu-project
Certifique-se de que configura o repositório do Artifact Registry conforme descrito no artigo Usar o Artifact Registry e inicie sessão para poder enviar e extrair imagens para o Artifact Registry.
Implemente o modelo TimesFM
A implementação é orquestrada através de um conjunto de ficheiros de configuração do Kubernetes (manifestos YAML), cada um a definir um componente ou um serviço específico.
Crie um script Python baseado em Flask
app.py
com funçõespredict
para fazer previsões de séries cronológicas etimeseries
para gerar uma visualização com base nos dados de teste.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)
Crie um Dockerfile com o
timesfm
instalado que invoca a app.# 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
Crie a imagem do Docker e carregue-a para o repositório do Artifact Registry.
docker build -t timesfm . docker tag timesfm "REGISTRY_REPOSITORY_URL"/timesfm:latest docker push "REGISTRY_REPOSITORY_URL"/timesfm:latest
Substitua o seguinte:
REGISTRY_REPOSITORY_URL
: o URL do repositório.
Crie um segredo para guardar as credenciais do 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
Substitua o seguinte:
DOCKER_REGISTRY_SECRET
nome do segredo.
Crie um ficheiro
timesfm-deployment.yaml
para implementartimesfm
.A implementação do servidor
timesfm
pede uma GPU.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
Substitua o seguinte:
REGISTRY_REPOSITORY_URL
: o URL do repositório.DOCKER_REGISTRY_SECRET
: nome do segredo do Docker.
Crie um ficheiro
timesfm-service.yaml
para expor o servidortimesfm
internamente.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
Aplique os manifestos.
kubectl --kubeconfig ${KUBECONFIG} apply -f timesfm-deployment.yaml kubectl --kubeconfig ${KUBECONFIG} apply -f timesfm-service.yaml
Certifique-se de que os pods
TimesFM
estão em execução.kubectl --kubeconfig ${KUBECONFIG} get deployments timesfm-deployment -n sandbox-gpu-project kubectl --kubeconfig ${KUBECONFIG} get service timesfm-service -n sandbox-gpu-project
Crie uma política de rede do projeto para permitir o tráfego de entrada de endereços IP externos.
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
Identifique o IP externo do serviço TimesFM executando o seguinte comando. Anote-o para usar nos passos posteriores, onde vai substituir este valor por TIMESFM_END_POINT.
kubectl --kubeconfig ${KUBECONFIG} get service timesfm-service \ -n sandbox-gpu-project -o jsonpath='{.status.loadBalancer.ingress[*].ip}'
Teste o serviço.
Para obter uma previsão, envie dados para o serviço através de um comando
curl
, substituindo TIMESFM_END_POINT pelo endereço real do serviço e pelos seus valores de entrada para funcionalidades. Isto invoca a funçãopredict
definida emapp.py
, que vai realizar alguma manipulação nos seus dados de entrada e devolvê-los no formato JSON.curl -X POST http://TIMESFM_END_POINT/predict -H "Content-Type: application/json" -d '{"features": [1.2, 3.4, 5.6]}'
Envie um pedido curl para /timeseries para ver um exemplo de visualização de dados com dados gerados aleatoriamente. Isto invoca a função de série temporal definida em app.py, que gera uma série temporal aleatória e realiza uma análise de média móvel na mesma.
curl http://TIMESFM_END_POINT/timeseries