blob: 9be94435992eb7f8fac084f553c20a48658c7df8 [file] [log] [blame] [view]
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
# AINode
AINode 是支持时序相关模型注册、管理、调用的 IoTDB 原生节点,内置业界领先的自研时序大模型,如清华自研时序模型 Timer 系列,可通过标准 SQL 语句进行调用,实现时序数据的毫秒级实时推理,可支持时序趋势预测、缺失值填补、异常值检测等应用场景。
系统架构如下图所示:
![](/img/h4.png)
三种节点的职责如下:
- **ConfigNode**:负责保存和管理模型的元信息;负责分布式节点管理。
- **DataNode**:负责接收并解析用户的 SQL请求;负责存储时间序列数据;负责数据的预处理计算。
- **AINode**:负责模型文件的导入创建以及模型推理。
## 1. 优势特点
与单独构建机器学习服务相比,具有以下优势:
- **简单易用**:无需使用 Python 或 Java 编程,使用 SQL 语句即可完成机器学习模型管理与推理的完整流程。如创建模型可使用CREATE MODEL语句、使用模型进行推理可使用 SELECT * FROM FORECAST (...) 语句等,使用更加简单便捷。
- **避免数据迁移**:使用 IoTDB 原生机器学习可以将存储在 IoTDB 中的数据直接应用于机器学习模型的推理,无需将数据移动到单独的机器学习服务平台,从而加速数据处理、提高安全性并降低成本。
![](/img/h1.png)
- **内置先进算法**:支持业内领先机器学习分析算法,覆盖典型时序分析任务,为时序数据库赋能原生数据分析能力。如:
- **时间序列预测(Time Series Forecasting)**:从过去时间序列中学习变化模式;从而根据给定过去时间的观测值,输出未来序列最可能的预测。
- **时序异常检测(Anomaly Detection for Time Series)**:在给定的时间序列数据中检测和识别异常值,帮助发现时间序列中的异常行为。
- **时间序列标注(Time Series Annotation)**:为每个数据点或特定时间段添加额外的信息或标记,例如事件发生、异常点、趋势变化等,以便更好地理解和分析数据。
## 2. 基本概念
- **模型(Model)**:机器学习模型,以时序数据作为输入,输出分析任务的结果或决策。模型是 AINode 的基本管理单元,支持模型的增(注册)、删、查、用(推理)。
- **创建(Create)**: 将外部设计或训练好的模型文件或算法加载到 AINode 中,由 IoTDB 统一管理与使用。
- **推理(Inference)**:使用创建的模型在指定时序数据上完成该模型适用的时序分析任务。
- **内置能力(Built-in)**:AINode 自带常见时序分析场景(例如预测与异常检测)的机器学习算法或自研模型。
![](/img/h3.png)
## 3. 安装部署
AINode 的部署可参考文档 [部署指导](../Deployment-and-Maintenance/AINode_Deployment_apache.md#ainode-部署) 章节。
## 4. 使用指导
AINode 对时序模型提供了模型创建及删除功能,内置模型无需创建,可直接使用。
### 4.1 注册模型
通过指定模型输入输出的向量维度,可以注册训练好的深度学习模型,从而用于模型推理。
符合以下内容的模型可以注册到AINode中:
1. AINode 目前支持基于 PyTorch 2.4.0 版本训练的模型,需避免使用 2.4.0 版本以上的特性。
2. AINode 支持使用 PyTorch JIT 存储的模型(`model.pt`),模型文件需要包含模型的结构和权重。
3. 模型输入序列可以包含一列或多列,若有多列,需要和模型能力、模型配置文件对应。
4. 模型的配置参数必须在`config.yaml`配置文件中明确定义。使用模型时,必须严格按照`config.yaml`配置文件中定义的输入输出维度。如果输入输出列数不匹配配置文件,将会导致错误。
下方为模型注册的SQL语法定义。
```SQL
create model <model_name> using uri <uri>
```
SQL中参数的具体含义如下:
- model_name:模型的全局唯一标识,不可重复。模型名称具备以下约束:
- 允许出现标识符 [ 0-9 a-z A-Z _ ] (字母,数字,下划线)
- 长度限制为2-64字符
- 大小写敏感
- uri:模型注册文件的资源路径,路径下应包含**模型结构及权重文件 model.pt 文件和模型配置文件 config.yaml**
- 模型结构及权重文件:模型训练完成后得到的权重文件,目前支持 pytorch 训练得到的 .pt 文件
- 模型配置文件:模型注册时需要提供的与模型结构有关的参数,其中必须包含模型的输入输出维度用于模型推理:
- | **参数名** | **参数描述** | **示例** |
| ------------ | ---------------------------- | -------- |
| input_shape | 模型输入的行列,用于模型推理 | [96,2] |
| output_shape | 模型输出的行列,用于模型推理 | [48,2] |
- ​ 除了模型推理外,还可以指定模型输入输出的数据类型:
- | **参数名** | **参数描述** | **示例** |
| ----------- | ------------------ | --------------------- |
| input_type | 模型输入的数据类型 | ['float32','float32'] |
| output_type | 模型输出的数据类型 | ['float32','float32'] |
- ​ 除此之外,可以额外指定备注信息用于在模型管理时进行展示
- | **参数名** | **参数描述** | **示例** |
| ---------- | ---------------------------------------------- | ------------------------------------------- |
| attributes | 可选,用户自行设定的模型备注信息,用于模型展示 | 'model_type': 'dlinear','kernel_size': '25' |
除了本地模型文件的注册,还可以通过URI来指定远程资源路径来进行注册,使用开源的模型仓库(例如HuggingFace)。
#### 示例
在当前的example文件夹下,包含model.pt和config.yaml文件,model.pt为训练得到,config.yaml的内容如下:
```YAML
configs:
# 必选项
input_shape: [96, 2] # 表示模型接收的数据为96行x2列
output_shape: [48, 2] # 表示模型输出的数据为48行x2列
# 可选项 默认为全部float32,列数为shape对应的列数
input_type: ["int64","int64"] #输入对应的数据类型,需要与输入列数匹配
output_type: ["text","int64"] #输出对应的数据类型,需要与输出列数匹配
attributes: # 可选项 为用户自定义的备注信息
'model_type': 'dlinear'
'kernel_size': '25'
```
指定该文件夹作为加载路径就可以注册该模型
```SQL
IoTDB> create model dlinear_example using uri "file://./example"
```
也可以从huggingFace上下载对应的模型文件进行注册
```SQL
IoTDB> create model dlinear_example using uri "https://huggingface.co/google/timesfm-2.0-500m-pytorch"
```
SQL执行后会异步进行注册的流程,可以通过模型展示查看模型的注册状态(见模型展示章节),注册成功的耗时主要受到模型文件大小的影响。
模型注册完成后,就可以通过使用正常查询的方式调用具体函数,进行模型推理。
### 4.2 查看模型
注册成功的模型可以通过show models指令查询模型的具体信息。其SQL定义如下:
```SQL
show models
show models <model_name>
```
除了直接展示所有模型的信息外,可以指定model id来查看某一具体模型的信息。模型展示的结果中包含如下信息:
| **ModelId** | **State** | **Configs** | **Attributes** |
| ------------ | ------------------------------------- | ---------------------------------------------- | -------------- |
| 模型唯一标识 | 模型注册状态(INACTIVE,LOADING,ACTIVE,DROPPING) | InputShape, outputShapeInputTypes, outputTypes | 模型备注信息 |
其中,State用于展示当前模型注册的状态,包含以下三个阶段
- **INACTIVE**:模型处于不可用状态
- **LOADING**:模型加载中状态
- **ACTIVE**:模型处于可用状态
- **DROPPING**:模型删除中状态
#### 示例
```SQL
IoTDB> show models
+---------------------+--------------------+--------+--------+
| ModelId| ModelType|Category| State|
+---------------------+--------------------+--------+--------+
| arima| Arima|BUILT-IN| ACTIVE|
| holtwinters| HoltWinters|BUILT-IN| ACTIVE|
|exponential_smoothing|ExponentialSmoothing|BUILT-IN| ACTIVE|
| naive_forecaster| NaiveForecaster|BUILT-IN| ACTIVE|
| stl_forecaster| StlForecaster|BUILT-IN| ACTIVE|
| gaussian_hmm| GaussianHmm|BUILT-IN| ACTIVE|
| gmm_hmm| GmmHmm|BUILT-IN| ACTIVE|
| stray| Stray|BUILT-IN| ACTIVE|
| timer_xl| Timer-XL|BUILT-IN| ACTIVE|
| sundial| Timer-Sundial|BUILT-IN| ACTIVE|
+---------------------+--------------------+--------+--------+
```
### 4.3 删除模型
对于注册成功的模型,用户可以通过SQL进行删除,该操作会删除所有 AINode 下的相关模型文件,其SQL如下:
```SQL
drop model <model_id>
```
需要指定已经成功注册的模型 model_id 来删除对应的模型。由于模型删除涉及模型数据清理,操作不会立即完成,此时模型的状态为 DROPPING,该状态的模型不能用于模型推理。请注意,该功能不支持删除内置模型。
### 4.4 使用内置模型推理
SQL语法如下:
```SQL
SELECT * FROM forecast(
input,
model_id,
[output_length,
output_start_time,
output_interval,
timecol,
preserve_input,
model_options]?
)
```
内置模型推理无需注册流程,通过 forecast 函数,指定 model_id 就可以使用模型的推理功能
- 请注意,使用内置时序大模型进行推理的前提条件是本地存有对应模型权重,目录为 /IOTDB_AINODE_HOME/data/ainode/models/weights/model_id/。若本地没有模型权重,则会自动从 HuggingFace 拉取,请保证本地能直接访问 HuggingFace。
- 参数介绍如下:
| 参数名 | 参数类型 | 参数属性 | 描述 | 是否必填 | 备注 |
| :---------------- | :------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :------- | :----------------------------------------------------------- |
| input | 表参数 | SET SEMANTIC | 待预测的输入数据 | 是 | |
| model_id | 标量参数 | 字符串类型 | 需要选择的model名 | 是 | 只能为非空,且内置的模型,否则报错:空字符串:MODEL_ID should never be null or empty不存在的模型:model [%s] has not been created模型不可用:model [%s] is not available |
| output_length | 标量参数 | INT32类型默认值:96 | 输出窗口大小 | 否 | 必须大于 0,否则报错:OUTPUT_LENGTH should be greater than 0 |
| output_start_time | 标量参数 | 时间戳类型默认值:输入数据的最后一个时间戳加 output_interval | 输出的预测点的起始时间戳 | 否 | 可以为负数,表示1970年1月1号之前的时间戳 |
| output_interval | 标量参数 | 时间间隔类型默认值:0(输入数据的采样间隔) | 输出的预测点之间的时间间隔支持的单位是 ns、us、ms、s、m、h、d、w | 否 | 大于 0 时,采用用户指定的输出间隔;小于等于 0 时,根据输入数据自动推测 |
| timecol | 标量参数 | 字符串类型默认值:time | 时间列名 | 否 | 存在于 input 中的,数据类型为 TIMESTAMP 的列,否则报错:若数据类型不为 TIMESTAMP: The type of the column [%s] is not as expected.若列不存在:Required column [%s] not found in the source table argument. |
| preserve_input | 标量参数 | 布尔类型默认值:false | 是否在输出结果集中保留输入的所有原始行 | 否 | |
| model_options | 标量参数 | 字符串类型默认值:空字符串 | 模型相关的key-value对,比如是否需要对输入进行归一化等。不同的key-value对以';'间隔 | 否 | 指定某个模型不支持参数,并不会报错,只会被忽略;AINode 中内置的模型支持的常见参数详见文末附录说明。 |
**说明:**
1. forecast 函数默认对输入表中所有列进行预测(不包含time列和partition by 的列)。
2. forecast 函数对于输入数据无顺序性要求,默认对输入数据按照时间戳(由 TIMECOL 参数指定时间戳的列名)做升序排序后,再调用模型进行预测。
3. 不同模型对于输入数据的行数要求不同,输入数据少于最低行数要求时,则报错;输入数据高于最大行数要求时,则自动截取最后的满足要求的行数。
- 在当前的 AINdoe 内置模型中,仅_sundial对输入行数有限制。_sundial 目前支持的最大输入行数为 2880,超过 2880 时,会自动截取输入数据的最后 2880 行。
4. forecast 函数的返回结果列包含 input 表的所有输入列,列的数据类型与原表列的数据类型一致。若 preserve_input= true,则还包含 is_input 列(表征当前行是否为输入行)
- 目前只支持对 INT32、INT64、FLOAT、DOUBLE 进行预测,否则报错:The type of the column [%s] is [%s], only INT32, INT64, FLOAT, DOUBLE is allowed
5. output_start_time 和 output_interval 只会影响输出结果集的时间戳列生成,均为可选参数。
- output_start_time 默认为输入数据的最后一个时间戳加 output_interval
- output_interval = (输入数据的最后一个时间戳 - 输入数据的第一个时间戳) / n - 1, 默认为输入数据的采样间隔
- 第 N 个输出行的时间为 output_start_time + (N - 1) * output_interval
#### 示例
我们所使用的的测试集的数据为[ETTh1-tab](/img/ETTh1-tab.csv)。
**查看当前支持的模型**
```Bash
IoTDB:etth> show models
+---------------------+--------------------+--------+------+
| ModelId| ModelType|Category| State|
+---------------------+--------------------+--------+------+
| arima| Arima|BUILT-IN|ACTIVE|
| holtwinters| HoltWinters|BUILT-IN|ACTIVE|
|exponential_smoothing|ExponentialSmoothing|BUILT-IN|ACTIVE|
| naive_forecaster| NaiveForecaster|BUILT-IN|ACTIVE|
| stl_forecaster| StlForecaster|BUILT-IN|ACTIVE|
| gaussian_hmm| GaussianHmm|BUILT-IN|ACTIVE|
| gmm_hmm| GmmHmm|BUILT-IN|ACTIVE|
| stray| Stray|BUILT-IN|ACTIVE|
| sundial| Timer-Sundial|BUILT-IN|ACTIVE|
| timer_xl| Timer-XL|BUILT-IN|ACTIVE|
+---------------------+--------------------+--------+------+
Total line number = 10
It costs 0.004s
```
**表模型推理(以 sundial 为例)**
```Bash
IoTDB:etth> select Time, HUFL,HULL,MUFL,MULL,LUFL,LULL,OT from eg LIMIT 96
+-----------------------------+------+-----+-----+-----+-----+-----+------+
| Time| HUFL| HULL| MUFL| MULL| LUFL| LULL| OT|
+-----------------------------+------+-----+-----+-----+-----+-----+------+
|2016-07-01T00:00:00.000+08:00| 5.827|2.009|1.599|0.462|4.203| 1.34|30.531|
|2016-07-01T01:00:00.000+08:00| 5.693|2.076|1.492|0.426|4.142|1.371|27.787|
|2016-07-01T02:00:00.000+08:00| 5.157|1.741|1.279|0.355|3.777|1.218|27.787|
|2016-07-01T03:00:00.000+08:00| 5.09|1.942|1.279|0.391|3.807|1.279|25.044|
......
Total line number = 96
It costs 0.119s
IoTDB:etth> select * from forecast(
model_id => 'sundial',
input => (select Time, ot from etth.eg where time >= 2016-08-07T18:00:00.000+08:00 limit 1440) order BY time,
output_length => 96
)
+-----------------------------+---------+
| time| ot|
+-----------------------------+---------+
|2016-10-06T18:00:00.000+08:00|20.781654|
|2016-10-06T19:00:00.000+08:00|20.252121|
|2016-10-06T20:00:00.000+08:00|19.960138|
|2016-10-06T21:00:00.000+08:00|19.662334|
......
Total line number = 96
It costs 1.615s
```
### 4.5 时序大模型导入步骤
AINode 目前支持多种时序大模型,部署使用请参考[时序大模型](https://timecho.com/docs/zh/UserGuide/latest/AI-capability/TimeSeries-Large-Model.html)
## 5 权限管理
使用AINode相关的功能时,可以使用IoTDB本身的鉴权去做一个权限管理,用户只有在具备 USE_MODEL 权限时,才可以使用模型管理的相关功能。当使用推理功能时,用户需要有访问输入模型的SQL对应的源序列的权限。
| **权限名称** | **权限范围** | **管理员用户(默认ROOT)** | **普通用户** | **路径相关** |
| :----------- | :-------------------------------------- | :------------------------- | :----------- | :----------- |
| USE_MODEL | create model / show models / drop model | √ | √ | x |
| READ_DATA | call inference | √ | √ | √ |
## 6 附录
**Arima**
| 支持的参数 | 含义 | 默认值 |
| :---------------------- | :----------------------------------------------------------- | :-------- |
| order | ARIMA模型的阶数 `(p, d, q)`:p是自回归阶数,d是差分阶数,q是滑动平均阶数。 | (1,0,0) |
| seansonal_order | 季节性ARIMA的阶数 `(P, D, Q, s)`:分别为季节性自回归、差分、滑动平均阶数,s是季节周期(如12代表月度数据)。 | (0,0,0,0) |
| method | 优化器选择,可选:'newton'、'nm'、'bfgs'、'lbfgs'、'powell'、'cg'、'ncg'、'basinhopping'。 | 'lbfgs' |
| maxiter | 最大迭代次数或函数评估次数。 | 50 |
| out_of_sample_size | 用于验证的时间序列尾部样本数,模型不在这些样本上拟合。 | 0 |
| scoring | 验证时使用的评分函数,字符串需为 sklearn 中可导入的评分指标,或用户自定义函数。 | 'mse' |
| trend | 趋势项配置,若 with_intercept=True 且此项为 None,则默认使用 'c'(包含常数项)。 | None |
| with_intercept | 是否包含截距项。 | True |
| time_varying_regression | 是否允许回归系数随时间变化。 | False |
| enforce_stationarity | 是否强制AR部分平稳性。 | True |
| enforce_invertibility | 是否强制MA部分可逆性。 | True |
| simple_differnecing | 是否使用差分后的数据估计(牺牲前几行数据换取更简状态空间)。 | False |
| measurement_error | 是否认为观测值中含有误差。 | False |
| mle_regression | 是否使用极大似然估计回归系数,若 `time_varying_regression=True` 则必须为 False。 | True |
| hamilton_representation | 是否使用 Hamilton 表达方式(默认用 Harvey)。 | False |
| concentrate_scale | 是否从似然函数中排除误差方差参数,减少待估参数个数(但无法获得误差项方差的标准误)。 | False |
**NaiveForecaster**
| 支持的参数 | 含义 | 默认值 |
| ---------- | ------------------------------------------------------------ | ------ |
| strategy | 预测策略: • `"last"`:预测训练集最后一个值;若设置了季节周期(`sp`>1),则每个季节分别预测其最后一个周期值。对 NaN 值鲁棒。 • `"mean"`:预测最后窗口中的平均值;若 `sp`>1,按每个季节分别计算均值。对 NaN 值鲁棒。 • `"drift"`:用最后窗口的首尾点拟合一条直线并外推预测。对 NaN 值不鲁棒。 | "last" |
| sp | 季节性周期。若为 `None`,等效于 `1`,表示无季节性;如果设为 12,表示每 12 个单位(如月)为一个周期。 | 1 |
- STLForecaster
| 支持的参数 | 含义 | 默认值 |
| :------------ | :----------------------------------------------------------- | :----- |
| sp | 季节周期长度(周期性单位数)。传入 statsmodels 的 STL 中。 | 2 |
| seasonal | 季节项平滑窗口长度,必须为 ≥3 的奇数,通常建议 ≥7。 | 7 |
| seasonal_deg | 季节项 LOESS 的多项式阶数(0 表示常数,1 表示线性)。 | 1 |
| trend_deg | 趋势项 LOESS 的多项式阶数(0 或 1)。 | 1 |
| low_pass_deg | 低通项 LOESS 的多项式阶数(0 或 1)。 | 1 |
| seasonal_jump | LOESS 拟合的插值步长(季节项),每 n 点拟合一次,中间插值。值越大,估计速度越快。 | 1 |
| trend_jump | 趋势项插值步长,越大速度越快但精度可能下降。 | 1 |
| low_pass_jump | 低通项插值步长,设置同上。 | 1 |
**ExponentialSmoothing (HoltWinters)**
| 支持的参数 | 含义 | 默认值 |
| :-------------------- | :----------------------------------------------------------- | :---------- |
| damped_trend | 是否使用阻尼趋势(趋势会逐渐平缓,而非无限增长)。 | True |
| initialization_method | 初始化方法: • `"estimated"`:通过拟合估计初始状态 • `"heuristic"`:使用启发式方法估计初始水平/趋势/季节 • `"known"`:用户显式提供所有初始值 • `"legacy-heuristic"`:旧版本兼容方式 | "estimated" |
| optmized | 是否通过最大化对数似然来优化参数。 | True |
| remove_bias | 是否移除偏差,使预测值和拟合值的残差平均值为0。 | False |
| use_brute | 是否使用穷举法(网格搜索)来寻找初始参数。否则使用启发式初始值。 | |