Google Research 的 TimesFM 模型是一种时序预测基础模型,已通过许多真实世界数据集中的数十亿个时间点进行预训练,因此您可以将其应用于许多领域的新预测数据集。
本教程指南介绍了如何在 GDC 沙盒上部署 TimesFM,并具有以下目标。
- 创建运行 TimesFM 的 Docker 容器,
- 使用 GDC Sandbox AI 优化 SKU 提供的 GPU 部署容器,并
- 使用简单的 HTTP 请求调用 TimesFM 函数。
准备工作
GDC Sandbox 中的 GPU 包含在 org-infra
集群中。
如需针对组织基础架构集群运行命令,请确保您拥有
org-1-infra
集群的 kubeconfig,如处理集群中所述:- 使用
gdcloud
命令行工具进行配置和身份验证,并 - 为组织基础架构集群生成 kubeconfig 文件,并将其路径分配给环境变量
KUBECONFIG
。
- 使用
确保用户已获分配项目
sandbox-gpu-project
的sandbox-gpu-admin
角色。 默认情况下,该角色会分配给platform-admin
用户。您可以登录platform-admin
并运行以下命令,将该角色分配给其他用户:kubectl --kubeconfig ${KUBECONFIG} create rolebinding ${NAME} --role=sandbox-gpu-admin \ --user=${USER} --namespace=sandbox-gpu-project
请务必按照使用 Artifact Registry 中的说明设置 Artifact Registry 代码库,并登录以便能够将映像推送到制品注册表和从制品注册表中拉取映像。
部署 TimesFM 模型
部署通过一组 Kubernetes 配置文件(YAML 清单)进行编排,每个文件定义一个特定的组件或服务。
创建一个基于 Flask 的 Python 脚本
app.py
,其中包含用于进行时间序列预测的函数predict
和用于根据测试数据生成可视化的函数timeseries
。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)
创建一个安装了
timesfm
的 Dockerfile,用于调用应用。# 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
构建 Docker 映像并将其上传到 Artifact Registry 代码库。
docker build -t timesfm . docker tag timesfm "REGISTRY_REPOSITORY_URL"/timesfm:latest docker push "REGISTRY_REPOSITORY_URL"/timesfm:latest
替换以下内容:
REGISTRY_REPOSITORY_URL
:代码库网址。
创建一个 Secret 来保存 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
Secret 的名称。
创建文件
timesfm-deployment.yaml
以部署timesfm
。timesfm
服务器的部署请求一个 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
替换以下内容:
REGISTRY_REPOSITORY_URL
:代码库网址。DOCKER_REGISTRY_SECRET
:Docker Secret 的名称。
创建文件
timesfm-service.yaml
以在内部公开timesfm
服务器。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
应用清单。
kubectl --kubeconfig ${KUBECONFIG} apply -f timesfm-deployment.yaml kubectl --kubeconfig ${KUBECONFIG} apply -f timesfm-service.yaml
确保
TimesFM
pod 正在运行。kubectl --kubeconfig ${KUBECONFIG} get deployments timesfm-deployment -n sandbox-gpu-project kubectl --kubeconfig ${KUBECONFIG} get service timesfm-service -n sandbox-gpu-project
创建项目网络政策,以允许来自外部 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
运行以下命令,确定 TimesFM 服务的外部 IP。请记下该值,以便在后续步骤中使用,届时您将使用该值替换 TIMESFM_END_POINT。
kubectl --kubeconfig ${KUBECONFIG} get service timesfm-service \ -n sandbox-gpu-project -o jsonpath='{.status.loadBalancer.ingress[*].ip}'
测试服务。
如需获取预测结果,请使用
curl
命令将数据发送到服务,并将 TIMESFM_END_POINT 替换为服务的实际地址以及您的特征输入值。这会调用app.py
中定义的predict
函数,该函数会对您的输入数据执行一些操作,并以 JSON 格式返回数据。curl -X POST http://TIMESFM_END_POINT/predict -H "Content-Type: application/json" -d '{"features": [1.2, 3.4, 5.6]}'
向 /timeseries 发送 curl 请求,查看使用随机生成的数据进行数据可视化的示例。这会调用 app.py 中定义的时序函数,该函数会生成随机时序并对其执行移动平均分析。
curl http://TIMESFM_END_POINT/timeseries