简介:Kronos 是专为金融K线数据设计的时序基础模型,首次把大语言模型的“预训练+微调”范式迁移到量化金融领域。核心架构包含两部分:一部分是BSQ双粒度分词器,把开盘、最高、最低、收盘、成交量等连续数值转换为粗粒度和细粒度两种词元,模拟交易者“先看大势、再精算点位”的决策过程;另一部分是仅含解码器的自回归Transformer,在大规模金融语料上预训练,学习跨越不同时间和资产的K线形态与市场规律。整个资源面向具备Python基础的量化研究者、金融数据分析师,可用于辅助投研分析、构建量化因子和生成合成市场数据。资源包共92个文件,大小约9.01MB,以30个Python源代码文件为主,覆盖模型预训练、微调、预测、回测和Web界面;另有JSON配置文件、CSV数据文件、PNG效果图、Markdown中文说明文档、启动脚本与许可证,目录按模型、数据、示例、微调等模块划分,便于快速定位和复现实验。已有434人浏览学习;下载后可以获得完整可运行的模型实现和部署说明,直接体验K线语言建模的完整流程,并将预测结果用于多资产分析报告、量化策略因子或策略回测所需的合成数据。
1. Kronos把LLM的“预训练+微调”搬到K线预测上:先看它能解决什么
做量化的人大概都经历过这种尴尬:用LSTM、GRU甚至普通Transformer去预测下一根K线,训练时loss一路下降,一到实盘就失灵;换一组股票、换一个周期,之前的参数全部作废。问题往往不出在模型结构上,而出在数据规模和训练范式上——你用几个月甚至几小时的行情数据去训一个模型,却指望它学到跨越市场、跨越周期的规律,这本身就是不现实的。Kronos这个专为金融K线设计的时序模型,思路是直接模仿大语言模型(LLM)的成功路径:先用45个以上全球交易所的120亿条K线数据做预训练,让模型先“见过”足够多的价格形态,再让你用自己手上的数据做微调。它解决的不是“多一个预测指标”,而是把“预训练+微调”这套被NLP验证过的建模范式,完整迁移到金融时序领域。适合手里有行情数据、想在K线预测上换一个更扎实底座的Python开发者。
2. 120亿条K线预训练意味着什么:数据形态、token设计与领域假设
2.1 Kronos把K线“翻译”成模型能读的token序列
大语言模型处理文本时,第一步是把文字切成token;Kronos处理K线时,同样存在一个“翻译”过程。传统时序模型直接喂数值,比如把开盘价、最高价、最低价、收盘价、成交量拼成一个向量,这有个老问题:不同股票的价格绝对数值差异巨大,茅台和农业银行的股价差了几十倍,模型必须在训练中自己学会“价格高低不重要,价格变化才重要”。Kronos的设计思路是,在进入模型之前先对K线做归一化和离散化,把连续的OHLCV序列转换成类似token的离散表示或标准化嵌入。常见做法是用对数收益率替换绝对价格,因为对数收益率天然消除了价格绝对水平的影响,而且跨市场、跨标的有可比性。举个例子,一只股价从10元涨到11元,另一只从100元涨到110元,对数收益率都是0.0953,模型看到的模式就是一致的。这一步是整个预训练的数据地基,比后面调任何模型参数都关键。
2.2 预训练数据量大不是关键,数据覆盖维度才是
45个以上全球交易所、120亿条K线,这两个数字放在一起很容易让人兴奋,但做时序模型的人知道:数据量再大,如果都来自同一个市场、同一个品种周期,模型学到的只是单一市场的“方言”,换个市场就失效。Kronos的数据覆盖了我认为最有价值的三个维度:地域维度(45个以上交易所意味着欧美、亚洲、新兴市场都有),资产维度(股票、指数、ETF、加密货币都可能包含),时间周期维度(不同交易所的K线周期不同,模型必须学会跨周期迁移)。这才是120亿条数据的真正含义——不是单纯堆量,而是保证训练分布足够宽,让模型在预训练阶段就见过足够多样的价格形态。你自己做类似项目时,如果手头只有A股日线数据,不要指望训练出通用模型,但你可以用Kronos的预训练权重作为起点,在自己数据上继续训练,这比从随机初始化开始训练要稳定得多。
2.3 时钟、日历与休市:金融时序和LLM处理文本的本质区别
文本是离散事件序列,句子与句子之间没有日期时间属性,但K线序列有严格的时间轴:交易时段与休市时段交替,每周有周末,每年有节假日,不同交易所的休市日历还完全不同。这意味着Kronos在预训练时不能像LLM处理文本那样做简单的序列拼接——把周五收盘和周一开盘连在一起当成连续序列,模型就会学会一个错误假设:每天都是连续交易的。Kronos的设计里需要处理这个时间对齐问题。我看到这个模型在数据组织上的一个关键假设是:把K线按时间排序,同时通过额外的特征或特殊token标记时间间隔。比如周五15:00收盘到周一9:30开盘,间隔了66.5小时,而正常K线间隔可能是1小时,模型需要知道两个相邻K线之间的真实时间距离,否则会把夜间的跳空缺口当成正常的连续价格变化。这一点在你后续微调时也要注意:如果你用日线数据,但你的标的经常跳空开盘,模型预期的时间间隔假设可能和你真实数据不一致。
2.4 为什么“将大语言模型的建模范式迁移到金融时序”不是噱头
LLM成功的核心其实不是“大”,而是三个要素的组合:海量数据上的预训练、预测下一个token的自监督任务、以及微调时代化到具体任务的能力。Kronos把这套范式映射到金融时序上,对应的是:海量K线数据上的预训练、预测下一根K线的自监督任务、以及在你自己的交易标的上的微调。这个迁移之所以成立,是因为K线序列和文本序列在底层结构上有相似性——都是有限状态下的序列模式学习,价格形态像词汇组合一样存在重复出现的“短语”。当然,金融时序比文本更困难的地方在于,文本的语法规则是人类制定的,相对稳定,而市场规律会因为参与者行为改变而漂移。Kronos能做的不是告诉你明天涨还是跌,而是提供一个比随机初始化模型更强的特征提取底座,让你在微调阶段用更少的数据、更短的时间训练出可用的预测器。
3. 拿到Kronos源码后的第一件事:模型结构、权重与推理前的准备工作
3.1 官方源码的目录结构:先分清哪些是模型定义、哪些是训练工具
把Kronos的Python源码克隆下来之后,不要急着跑demo,先花十分钟理清目录结构。我的经验是,这类模型的代码库通常分成几个明确的部分:模型定义文件(包含Transformer主干、输入编码器、输出解码器)、数据处理工具(负责把K线数据转换成训练样本)、训练脚本(预训练和微调分开)、推理脚本(加载权重、输出预测)。你本地微调真正需要动的是训练脚本和推理脚本,模型定义文件一般只在你想改网络结构时才需要碰。还有一个容易忽略的文件是模型配置,通常是JSON或YAML格式,里面写了隐藏层维度、注意力头数、层数、dropout比例等超参数。在开始微调之前,打开这个配置看一眼,确认它和你下载的权重文件一致。很多人在这里翻车:换了权重文件,但配置还是旧的,模型加载时参数名对不上,报出一堆莫名其妙的错误。我一般会先把配置里和模型结构相关的字段(层数、头数、维度)记下来,再去看权重文件,确保两者对应。
3.2 权重文件的加载:状态字典、兼容性与版本差异
Kronos发布时应该会附带预训练权重,文件格式一般是PyTorch的.pt或.pth。加载权重时有几个坑值得提前说。第一个坑是权重文件的键名兼容性——如果Kronos的模型代码后来更新过,比如把某个层的命名从encoder.layer0改成了encoder.layers.0,你拿旧权重加载新模型,会报missing keys。遇到这种情况,先看官方有没有升级脚本,没有的话就要自己手动映射键名。第二个坑是设备迁移——权重在GPU上保存的,你本地如果没有GPU,加载的时候要指定map_location='cpu'。第三个坑是精度问题——如果预训练用的是FP16混合精度,你CPU推理时最好把权重转到FP32,否则低精度下的预测结果会有些偏差。我自己的习惯是写一个单独的小脚本来验证权重加载完整性,加载完打印所有层的shape,和配置文件里比对一遍,确保关键维度对得上。这一步花十分钟,能省掉后面好几个小时的排查时间。
3.3 输入数据的格式约定:Kronos到底要什么样的K线序列
在推理之前,必须搞清楚Kronos的输入格式。从模型设计的角度看,它接收的应该是规范的K线序列数据,包含时间戳、开盘价、最高价、最低价、收盘价、成交量这些字段。但具体的格式细节——比如时间是字符串还是Unix时间戳、价格是原始值还是已经做过对数转换——每个模型都不一样。我的建议是直接看源码里的数据处理函数,尤其是preprocess或encode相关的部分。不要凭感觉猜测。Kronos的处理逻辑大概率在数据入口处做归一化和序列化,你需要确保你喂进去的原始数据和预训练时的数据格式一致。举个例子,如果预训练时用的K线是向前复权的,你推理时用了不复权数据,两者在除权除息日的价格模式上会有明显差异,模型预测会失真。还有一个细节是序列长度——模型有固定的最大输入长度(通常由训练时的窗口大小决定),你输入超过这个长度的序列,要么截断,要么需要分组处理。低于最小长度也不行,模型可能无法有效编码短序列的上下文。检查一下你的数据时间跨度,是否落在模型支持的范围内。
3.4 环境依赖清单:Python版本、PyTorch版本与CUDA
安装部署Kronos之前,先确认本机环境。这类模型的依赖核心是PyTorch,模型代码可能在某个PyTorch版本上开发和测试的,版本跨度太大容易出兼容性问题。我的建议是用conda建一个独立环境,然后按顺序安装依赖:先装PyTorch,再装模型的其他依赖(常见的有pandas、numpy、tqdm这些)。不要直接pip install跑requirements.txt,因为requirements里可能锁了版本号,和你本机已有的包冲突。如果你不用GPU,只需要CPU推理,安装CPU版PyTorch就够了,显存占用为零,但推理速度会慢。如果要用GPU加速微调,注意CUDA版本和PyTorch版本的对应关系,这一步配错的话后续所有GPU相关操作都会失败。如果你的机器是Apple Silicon的Mac,也可以用MPS后端跑PyTorch,但和CUDA相比,某些算子的支持不完整,跑Kronos这类Transformer模型可能会出现不兼容的警告。
3.5 快速跑通官方demo:验证模型能加载、能推理、输出形状正确
环境配好、权重加载成功之后,第一件要做的事是跑通官方提供的demo或示例脚本。这个demo的目的不是看预测效果好不好,而是验证整条链路是通的。我当时做类似模型部署时,会先构造一个极小的输入——比如用最近20根K线作为输入序列,跑一次推理,看模型输出的形状是不是符合预期。预测输出可能是一个向量,代表预测的未来收益率分布或K线数值,也可能是一组参数。确认输出维度正确之后,再逐步增加序列长度,验证模型在较长输入下不会报内存错误。跑demo时如果遇到报错,先看是模型加载阶段的错误还是前向传播阶段的错误。前者通常是权重和模型结构不匹配,后者通常是输入张量的维度或类型不对。把这两类错误分开排查,效率会高很多。记住,第一次跑通demo追求的不是预测准确,而是链路完整——数据能进模型,结果能出来。
4. 用Kronos跑通一次K线预测:最小部署路径与三个必调参数
4.1 初始化模型:加载预训练权重并进入评估模式
当你确认环境无误后,写一个最简单的推理脚本来加载Kronos模型。下面这段代码基于PyTorch的常见写法,实际调用时要以你下载的源码为准。
import torch import kronos from kronos import KronosForPrediction # 以实际源码模块名为准 # 初始化模型结构并加载预训练权重 model = KronosForPrediction.from_pretrained( "./kronos_pretrained/kronos_base", # 权重所在目录 config_file="./kronos_pretrained/config.json" ) # 切换到评估模式,关闭dropout和batch norm的随机行为 model.eval() # 如果只有CPU,强制把模型放在CPU上并转为FP32 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = model.to(device).float() print(f"模型已加载,运行设备: {device}")这段代码的逻辑很直接:先通过from_pretrained加载预训练权重,这一步会同时读取配置文件来构建模型结构;然后调用eval(),这在PyTorch里是必须的——不调用的话,模型里的dropout层在推理时仍会随机丢弃神经元,导致每次预测结果都不一样;最后把模型放到可用的计算设备上,CPU就转成FP32,GPU就保持默认精度。这里最容易被忽略的是model.eval(),我见过不少人在推理时漏了这一步,结果同一个输入每次跑出的预测都略有差异,还以为是模型有问题。
4.2 构造输入:把原始K线数据处理成模型需要的张量
接下来是把你的K线数据转换成模型能接收的张量格式。这里假设你的原始数据是pandas的DataFrame,包含open、high、low、close、volume五列。
import pandas as pd import numpy as np import torch # 读取本地K线数据,Excel或CSV都可以,但必须保证列名规范 df = pd.read_csv("./data/btc_usdt_1h.csv") print(f"原始数据共 {len(df)} 根K线,时间范围: {df['timestamp'].iloc[0]} ~ {df['timestamp'].iloc[-1]}") # 按时间升序排列,防止数据乱序影响序列建模 df = df.sort_values("timestamp").reset_index(drop=True) # 计算对数收益率,替代绝对价格,消除价格水平影响 df["log_return"] = np.log(df["close"] / df["close"].shift(1)) df["log_return"] = df["log_return"].fillna(0.0) # 第一行没有前值,补0 # 用对数收益率加成交量构造特征矩阵 features = df[["log_return", "volume"]].values.astype(np.float32) print(f"特征矩阵形状: {features.shape}") # 取最近64根K线作为输入序列,长度要和模型训练时的窗口匹配 seq_len = 64 seq = features[-seq_len:] # 转换为PyTorch张量,并增加batch维度,形状变为 (1, seq_len, feature_dim) input_tensor = torch.from_numpy(seq).unsqueeze(0).to(device) print(f"输入张量形状: {input_tensor.shape}")这段代码有两个关键参数值得说明。第一个是seq_len,也就是输入序列长度。这个参数不能随便拍脑袋定——它在模型预训练时就已经固定了,你输入更长的序列会被截断或分窗,输入更短则上下文不足。我一般会先查模型配置文件里的max_seq_len字段,然后选用不超过它的、足够描述一个完整交易模式的值,比如64或128。第二个是特征构造——我用的是“对数收益率+成交量”两列特征,你在实践当中可以加入更多特征,但前提是预训练权重里对应位置的维度能对齐。如果模型输入维度是固定的,你加了特征后维度不匹配,模型加载和推理都会报错。
4.3 推理预测:解读模型输出并转成可操作的风险度量
输入张量构造好之后,前向传播只需要一行代码,但输出的解读才是关键。
with torch.no_grad(): output = model(input_tensor) # Kronos的输出通常是下一根K线的预测分布参数,具体含义看模型设计 pred = output["prediction"] if isinstance(output, dict) else output print(f"模型输出形状: {pred.shape}") # 如果输出是均值和方差,可以构造预测区间 if hasattr(pred, "mean"): pred_mean = pred.mean(dim=-1).item() print(f"下一根K线的预测收益率均值: {pred_mean:.4f}") else: # 如果输出是单个值,直接打印 print(f"下一根K线的预测值: {pred.item():.4f}")torch.no_grad()在推理时是必须的——它告诉PyTorch不需要为这个计算图保存梯度,不仅省显存,还会让前向传播提速。从模型输出的解读来看,Kronos所在的那一类模型通常有两种输出模式:一种是直接输出下一根K线的预测值,另一种是输出一个概率分布的参数(比如均值和方法)。如果是后者,你得到的预测结果天生带有不确定性度量,这在金融场景里非常有用——你不仅可以知道模型预测涨还是跌,还能知道模型的置信度有多高。我建议你在使用Kronos时,优先关注输出中能反映不确定性的部分,不要只盯着预测方向这一个数值。
4.4 微调前的三个必调参数:学习率、训练轮数与冻结策略
当你决定在自己的数据上微调Kronos时,有三个参数直接影响最终效果。
第一个是学习率。预训练模型已经学到了通用的价格形态,微调时如果学习率过大,模型会把之前学到的通用特征全部忘掉,只记住你提供的少量数据。我一般从1e-5开始,如果loss下降太慢,再调整到3e-5——这个量级的调整是正常的,不建议直接上1e-3。
第二个是训练轮数(epochs)。微调不是越多越好。预训练模型在你的小数据集上训练1到3轮通常就够了,训练过久会过拟合——模型在你的历史数据上表现很好,但未来数据上预测能力急剧下降。判断方法很简单:每一轮结束后在验证集上测一次预测误差,当验证误差开始上升时立刻停。
第三个是冻结策略。你可以选择冻结模型底层的部分层,只微调靠近输出的上层。原因是底层学到的是通用的价格形态特征,跨市场通用;上层学到的是预训练数据里特定市场的交易风格,需要被你自己的数据校正。冻结策略表现成一个布尔参数,怎么选看你手里的数据量——数据量越少,越应该多冻结底层。
4.5 微调训练脚本的骨架:数据切分、损失函数与保存检查点
from torch.utils.data import DataLoader, TensorDataset # 假设你已经构造好了训练用样本X_train和对应标签y_train X_train = torch.from_numpy(train_features).float() y_train = torch.from_numpy(train_labels).float() # 封装成PyTorch标准数据集 train_dataset = TensorDataset(X_train, y_train) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5) loss_fn = torch.nn.MSELoss() # 回归任务用MSE,如果是概率输出则用NLL model.train() # 切换到训练模式 for epoch in range(3): total_loss = 0.0 for batch_X, batch_y in train_loader: batch_X, batch_y = batch_X.to(device), batch_y.to(device) optimizer.zero_grad() pred = model(batch_X) loss = loss_fn(pred, batch_y) loss.backward() optimizer.step() total_loss += loss.item() print(f"Epoch {epoch+1}/3, loss: {total_loss/len(train_loader):.6f}") # 每个epoch结束后保存一次检查点,方便回退到最优版本 torch.save(model.state_dict(), f"./checkpoints/kronos_finetuned_epoch{epoch+1}.pt")这个脚本是微调的标准骨架。其中batch_size=32是一个还算保守的选择,如果你的显存不够,降到16或8都是可以的。损失函数的选择取决于你的预测目标:如果预测的是具体的收益率数值,MSE(均方误差)够用;如果模型输出的是分布参数,应该用负对数似然损失。每个epoch结束保存检查点是我个人的习惯,因为训练过程中可能出现loss先降后升的情况,有了检查点你可以回退到表现最好的那个epoch。训练结束之后,把微调后的权重和预训练权重都保存好,后续回测和实盘验证时可以对比二者效果。
5. Kronos避坑实录:从数据泄露到归一化处理的五条踩坑记
5.1 训练集和测试集混入了同一条K线:未来函数引发的虚幻收益
现象:模型在回测里表现惊人,年化收益率高得离谱,但一到实盘就完全失灵,甚至亏损。排查了很久,发现是数据切分出了问题。
原因:构造训练样本的时候,直接按时间排序后截取了一段做训练集,另一段做测试集,但样本之间存在重叠。比如训练样本用的是第1根到第64根K线预测第65根,测试样本却包含了第65根K线作为输入的一部分。模型在训练时已经见过第65根K线的价格信息,测试时当然“预测”得异常准确。这是典型的未来函数问题,也就是数据泄露。
解决:按时间严格切分,训练集和测试集之间留出间隔。我现在的做法是把数据集按时间切成三段:训练集用前70%,验证集用中间10%,测试集用最后20%,并且训练集的结束时间和验证集的开始时间之间留出至少一个序列长度的间隔,保证没有样本跨越切分边界。
5.2 价格归一化的统一问题:训练用复权价,推理用原始价
现象:模型在训练集上loss很低,但加载同样的权重去预测新数据时,预测结果明显偏倚,方向经常判断错误。
原因:训练时用的K线是前复权价格,推理时手里的数据是未复权的原始价格。股票除权除息之后,股价会突然跳空,前复权数据会把历史价格整体调整,未复权数据则保留真实的历史价格。两种数据在同一根K线上的数值不同,对数收益率的计算也会有偏差。模型在预训练和微调时学到的价格模式是复权价下的,推理时输入未复权价,数据分布不一致。
解决:确保训练和推理用同一复权方式的数据。我个人的习惯是统一用前复权数据,因为后复权数据的当前价格和历史价格差距很大,模型不好统一处理。另外需要留意交易所停牌复牌造成的长时间价格不变序列,某些停牌期长的股票会出现连续好多根K线收盘价完全一样的现象,这种极端序列在金融时序里会导致梯度异常,处理时可以考虑剔除或标记。
5.3 日志收益率出现无穷值:除零和数据异常没有预处理
现象:模型前向传播时报错,提示输入张量里存在NaN或inf值,监督训练时loss直接变成NaN。
原因:计算对数收益率时,某根K线的收盘价为0(数据源出现了异常值),或者前一根收盘价为0,np.log(0 / prev_close)就会产生-inf。常见的数据源错误还包括成交量缺失或时间为空导致的行错位。模型一旦碰到无穷值,反向传播时梯度就会变成NaN,整个训练过程直接被污染。
解决:在预处理阶段显式检查并处理这些异常。我的做法是数据清洗环节里加一步检查:遍历所有K线,如果发现收盘价小于等于0或出现空值,直接丢弃该行;对数收益率出现无穷值的行也一并删除或填为0。最稳妥的方式是用df.replace([np.inf, -np.inf], np.nan).dropna()把异常行清除干净,再进入后续特征工程。
5.4 不同交易所数据拼接顺序混乱:跨市场时间轴错位
现象:想把多个交易所的数据混合起来训练或微调,模型加载后训练loss下降很慢,预测效果也不好,检查发现输入序列的时间顺序是乱的。
原因:不同交易所的休市时间不同,比如美股有中午休市,A股有午间休市,加密货币则全天交易。如果直接把不同标的的K线按本地时间拼接在一起,时间戳会错位,模型的注意力机制会把这个混乱的时序当成正常的序列模式去学习,结果什么都学不到。
解决:每个标的单独处理,不要混在一个序列里。训练样本应该保证每个样本内部的K线来自同一个标的、同一个周期,并且时间严格递增。多标的混合的正确做法是:在同一个batch里放不同标的的独立样本,通过模型内部的批次维度区分,而不是在序列维度上拼接。如果你的模型支持类似LLM的“文档分隔符”,也可以用特殊标记区分不同标的的边界。
5.5 预训练权重和模型结构版本不匹配:加载报错与输出异常
现象:from_pretrained加载权重时报错,报错信息是unexpected key或missing key,有些时候不报错但预测结果完全不合理——输出恒为某个固定值。
原因:官方仓库更新了模型配置或层命名,你下载的权重文件是旧版本,和当前源码里的模型结构对不上。PyTorch加载权重时按层名严格匹配,名字对不上就会报missing或unexpected;如果恰好名字匹配但层顺序调整过,不会报错但语义就不对了,输出自然荒诞。
解决:检查权重文件附带的版本信息或配置文件,确保和源码版本一致。如果源码版本更新了,看官方release note里有没有权重迁移说明。最稳妥的折中方案是checkout到和权重文件匹配的git commit再运行。如果实在对不上,就自己对权重文件做一个键名映射,把旧名字转换为新名字,这个需要仔细对比模型构造代码里每一层的名称,没有捷径。
6. 验证Kronos预测效果的一个技巧:按“时间戳”切分,而不是按“股票”切分
很多人在评估Kronos这类模型的预测能力时,习惯把所有标的的数据混合在一起,然后随机切分训练集和测试集。这在其他机器学习领域没问题,但在金融时序里是错的。原因很简单:同一时间段内,不同标的价格往往受共同因素影响,比如某个宏观新闻导致整个板块同时大涨。如果你的训练集和测试集在同一个时间窗口内,模型在训练时已经见过其他标的同一时间段的走势,测试时面对这个标的的同类模式,等于“看过答案”。正确的评估方式是按时间戳切分:用2024年之前的所有数据训练,用2024年之后的数据测试,物理上保证训练和测试之间没有时间重叠。
具体操作时,我一般会记录验证集里每一段预测的时间范围,确认训练集最后一条数据的时间戳早于验证集最早一条。这个技巧虽然简单,但很多人会在实际编码时忘记,因为数据加载器shuffle之后,时间信息容易丢失。我的习惯是在构造Dataset时,让每个样本携带它的结束时间戳,切分时严格按时间戳过滤,而不是按索引切分。这样做还有一个额外好处:你可以单独检查验证集的时间跨度是否覆盖了完整的市场周期——如果测试期恰好只有牛市行情,那模型的表现再好看也没有说服力。回测结果需要按年、按季度分别看预测误差,确认模型不是只在某个行情阶段有效。
我在用Kronos这一类预训练模型时,还有一个不成文的习惯:微调完之后,先在原始预训练模型和新微调模型之间做一个对比基准。用完全相同的验证集数据,跑两个模型的预测,计算预测误差和相关指标。如果微调后的模型在验证集上的表现还不如预训练模型,说明你微调数据的分布与预训练数据严重不匹配,或者微调超参数设置不合理,需要回头检查数据预处理,而不是继续调模型。这个对比过程只需要几十行代码,但对判断模型是否真的“变好”非常有价值。
关于Kronos的方向,我的建议是:不要把它当成一个黑匣子,也不要指望它给出确定性预测。它真正的价值在于提供了一个见过足够多市场形态的底座,你要做的是在这个底座上构建自己的预测逻辑——无论是对接一个简单的趋势跟踪策略,还是作为其他信号模型的特征输入。动手之前先把环境、数据、权重这三件事准备好,跑通之后再决定要不要微调。这个顺序每次都能少走很多弯路,希望帮到你。
本文还有配套的精品资源,点击获取