字节发了一个新的reasearch paper在vldb25上:
ChatTS: Aligning Time Series with LLMs via Synthetic Data for Enhanced Understanding and Reasoning
支持时序数据这个模态的大模型,可能也可以叫做time serise foundation model
之所以需要让模型原生支持读取时序数据,是因为现在模型对时序数据的输入支持比较差,需要直接把具体的数值输入进去,个人理解这里有两个问题:
* 模型对数字的感知能力,以及时序数据中包含的大量数字
* 通过自然语言输入,token花费比较多
可能还有一个想法是,既然人一般是通过图表是看时序数据的,是不是可以把时序数据转化成图表给视觉大模型看呢?
* 这里文章中提到是因为视觉模型可能有细节丢失的问题。
* 我个人感觉的话,时序数据本身就是带有序列的,把他转成图表,然后再拍成片给大模型,可能会有一些特征的丢失,或者是利用的效率比较低
这个paper主要做了两个事情:
* 数据生成,包括时序数据和对应的QA
* 支持时序数据的模型
数据生成这块看图比较直观,时序数据的几种特征,包含趋势/周期性/局部波动/噪音。根据一些预定义的规则就可以生成出来。
然后根据上面生成的数据,以及一些seed QA,可以生成新的QA。
* 比如这里从描述趋势可以演变成描述趋势+判断周期性,以及判断多个时序数据的趋势
模型的使用方式在github中有展示,比较简单
from transformers import AutoModelForCausalLM, AutoTokenizer, AutoProcessor
import torch
import numpy as np
# Load the model, tokenizer and processor
model = AutoModelForCausalLM.from_pretrained("./ckpt", trust_remote_code=True, device_map=0, torch_dtype='float16')
tokenizer = AutoTokenizer.from_pretrained("./ckpt", trust_remote_code=True)
processor = AutoProcessor.from_pretrained("./ckpt", trust_remote_code=True, tokenizer=tokenizer)
# Create time series and prompts
timeseries = np.sin(np.arange(256) / 10) * 5.0
timeseries[100:] -= 10.0
prompt = f"I have a time series length of 256: <ts><ts/>. Please analyze the local changes in this time series."
# Apply Chat Template
prompt = f"<|im_start|>system\nYou are a helpful assistant.<|im_end|><|im_start|>user\n{prompt}<|im_end|><|im_start|>assistant\n"
# Convert to tensor
inputs = processor(text=[prompt], timeseries=[timeseries], padding=True, return_tensors="pt")
# Move to GPU
inputs = {k: v.to(0) for k, v in inputs.items()}
# Model Generate
outputs = model.generate(**inputs, max_new_tokens=300)
print(tokenizer.decode(outputs[0][len(inputs['input_ids'][0]):], skip_special_tokens=True))
在prompt中会有特殊的token用来替换时序数据,在推理的时候把时序数据通过timeseries这个key传给模型即可。
然后针对模型的设计,我个人感觉核心和之前的GraphGPT等GFM相关模型差不多,会先用一个神经网络把其他模态的数据转化成embedding,然后和其他的token的embedding一起丢给LLM做推理。
因为模型是开源的,核心代码在github和hf上都可以看到。
这里会先把时序数据过一个MLP:
* 模型中,会把时序数据分成若干个小batch,batch size为16
* 每一个数据都有两个特征:一个是时序数据具体的数值,另一个则是一个0/1的mask,表示数据是否存在,用来处理变长字段。
* 把这个(16, 2)的batch丢到mlp中,最后会输出一个embedding。
这里会处理一些对齐的逻辑,最终出来的数据就是(batch_cnt, embedding_size)的特征,然后和prompt其他的字符的embedding放到一起喂给大模型
有一个值得注意的点是,这里针对输入的数据做了一下normalize。我估计是因为这里看时序数据不太需要绝对值,而是主要看上面说的趋势/周期性/尖刺。
* 但是他们也尽力保留了原始数据,做法是把normalize后的数据的scale factor/offset通过prompt传给了大模型。这样大模型在理解相对值的时候,也可以通过prompt中的scale factor得到原始的值。
* 代码中是sp_encoding
还有一个点,就是这里encoder的消融实验,究竟work的是这个adaptor,还是在时序数据问答上的SFT?
* 这里文章中有对应的消融实验,部分case下还是有比较大的作用的
*
总体来说还是挺不错的一篇文章,这里和GraphGPT的相似之处让我在想,这种直接在外面套一层把其他模态的数据对齐到文本的embedding,是不是真的可以work。还是说在benchmark中很好看,但是并不是一个真正的foundation model(没有通用性)。因为我个人对大模型训练这块了解不多,这块无法给出很好的判断。
仓库中也提到了,收到训练集的限制,输入的time series的长度不能太大。这里其实和长上下文依赖长的训练数据是类似的。
文章中提到了他们的训练方法是finetune,并非全量训练,所以这里可能还有一个问题是, 把时序数据的embedding对齐到文本embedding这种方式是否可以泛化。
* btw,这里的训练方法好像和GraphGPT也是类似的,就是先对齐,然后再和LLM一起在一些QA数据集上做训练
* 如果可以泛化的话,那么其他模态的foundation model,是不是都可以通过一些适配层加进来。
* 感觉像是,LLM通过大量语料的预训练学到了不局限于模态的“逻辑”。然后这里我们只是帮这里的大脑增加传感器而已
* 并且如果可以泛化,那么GFM领域是不是在增加数据量的情况下,就可以提高泛化性?
* 可能不一定完全一样,图数据相比之下还是比时序数据更加复杂一些。毕竟时序数据本身就是序列数据,transformer这个架构专业对口。
* 所以这里可能重点不一样,时序数据的重点在于缺少数据,所以这篇paper搞了个数据合成。图数据应该不算缺少,可能更多的还是去设计模型
文章评论