使用GPU计算时序模型

PaddleTS 基于 PaddlePaddle 框架构建深度时序模型。由于PaddlePaddle提供GPU能力,因此仅需一些简单的步骤即可在GPU上训练、预测PaddleTS模型。

1. 前置条件

在Nvidia GPU设备上运行PaddleTS提供的深度时序模型,需要满足以下前置条件:

同时需要注意,由于一些已知原因,目前无法在GPU设备上运行PaddleTS的内置 NHiTS 模型 ,后续会修复此问题。

2. 示例

通常来说,在GPU设备上运行PaddleTS深度时序模型需要完成以下3步:

  • 获取当前系统可用的GPU设备。

  • 选择其中一个GPU设备用于计算。

  • 执行你的程序,以便在GPU上完成模型训练、预测。

详见下方步骤。

2.1 获取当前系统可用的GPU设备

假设当前系统已安装GPU及其驱动。你可以在Linux Shell运行 nvidia-smi 命令来获取一组GPU列表,其包含较详细的GPU设备状态信息。

下方是一个返回的输出示例。简单来说,它包含以下信息:

  • 当前系统共有4台Nvidia A30型号的GPU设备可用。

  • 每台可用设备有24258MiB空闲内存可以使用。

  • 目前没有运行中的进程占用任何GPU设备。

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.82.01    Driver Version: 470.82.01    CUDA Version: 11.4     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA A30          On   | 00000000:17:00.0 Off |                    0 |
| N/A   33C    P0    31W / 165W |      3MiB / 24258MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   1  NVIDIA A30          On   | 00000000:65:00.0 Off |                    0 |
| N/A   35C    P0    29W / 165W |      3MiB / 24258MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   2  NVIDIA A30          On   | 00000000:B1:00.0 Off |                    0 |
| N/A   33C    P0    28W / 165W |      3MiB / 24258MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   3  NVIDIA A30          On   | 00000000:E3:00.0 Off |                    0 |
| N/A   35C    P0    30W / 165W |      3MiB / 24258MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

2.2 显式地设置希望使用的GPU设备

Nvidia 提供了 CUDA_VISIBLE_DEVICES 环境变量,该变量可以使系统中已安装的GPU设备对CUDA应用程序可见。假设当前系统共有 {0, 1, 2, 3} 四台可用GPU设备,并且已知给定场景中仅会用到第0台GPU设备,那么你可以通过运行`export CUDA_VISIBLE_DEVICES=0` 命令来显式地指定设备0对你的CUDA应用程序可见。

此时如果你运行 echo $CUDA_VISIBLE_DEVICES 命令,则你看到的输出 0 表明你将会使用设备0来训练、预测深度时序模型。

更多细节可参考 Nvidia CUDA_VISIBLE_DEVICES

2.3 安装可以运行在GPU上的PaddleTS

有两种方法来准备环境:

  • pip

  • docker

2.3.1 pip 安装

安装PaddleTS之前,需要保证已安装 GPU版本的PaddlePaddle

pip install paddlepaddle-gpu

现在可以运行以下命令安装最新版本PaddleTS:

pip install paddlets

2.3.2 docker

首先需要参考 Nvidia Container Toolkit 安装指南 。来安装 nvidia-docker 客户端。

现在可以拉取支持GPU的docker镜像。

nvidia-docker pull registry.baidubce.com/paddlets/paddlets:latest-gpu-cuda11.2-cudnn8

2.3 使用GPU设备进行模型训练、预测

在完成以上所有步骤,剩余步骤与CPU完全一致,可以参考 开始使用PaddleTS 了解更多细节。

import numpy as np

from paddlets.datasets.repository import get_dataset
from paddlets.transform.sklearn_transforms import StandardScaler
from paddlets.models.forecasting import MLPRegressor

np.random.seed(2022)

# prepare data
tsdataset = get_dataset("WTH")
ts_train, ts_val_test = tsdataset.split("2012-03-31 23:00:00")
ts_val, ts_test = ts_val_test.split("2013-02-28 23:00:00")

# transform
scaler = StandardScaler()
scaler.fit(ts_train)
ts_train_scaled = scaler.transform(ts_train)
ts_val_scaled = scaler.transform(ts_val)
ts_test_scaled = scaler.transform(ts_test)
ts_val_test_scaled = scaler.transform(ts_val_test)

# model
model = MLPRegressor(
     in_chunk_len=7 * 24,
     out_chunk_len=24,
     skip_chunk_len=0,
     sampling_stride=24,
     eval_metrics=["mse", "mae"],
     batch_size=32,
     max_epochs=1000,
     patience=100,
     use_bn=True,
     seed=2022
)

model.fit(ts_train_scaled, ts_val_scaled)

predicted_tsdataset = model.predict(ts_val_test_scaled)

print(predicted_tsdataset)

#                      WetBulbCelsius
# 2014-01-01 00:00:00       -0.124221
# 2014-01-01 01:00:00       -0.184970
# 2014-01-01 02:00:00       -0.398122
# 2014-01-01 03:00:00       -0.500016
# 2014-01-01 04:00:00       -0.350443
# 2014-01-01 05:00:00       -0.580986
# 2014-01-01 06:00:00       -0.482264
# 2014-01-01 07:00:00       -0.413248
# 2014-01-01 08:00:00       -0.451982
# 2014-01-01 09:00:00       -0.471430
# 2014-01-01 10:00:00       -0.427212
# 2014-01-01 11:00:00       -0.264509
# 2014-01-01 12:00:00       -0.308266
# 2014-01-01 13:00:00       -0.386270
# 2014-01-01 14:00:00       -0.261341
# 2014-01-01 15:00:00       -0.492441
# 2014-01-01 16:00:00       -0.497322
# 2014-01-01 17:00:00       -0.628926
# 2014-01-01 18:00:00       -0.528971
# 2014-01-01 19:00:00       -0.588881
# 2014-01-01 20:00:00       -0.860580
# 2014-01-01 21:00:00       -0.742121
# 2014-01-01 22:00:00       -0.819053
# 2014-01-01 23:00:00       -0.875322