Qlib Meta Controller 深度解析:用 Meta-Task、Meta-Dataset 与 Meta-Model 引导预测模型工作流
【免费下载链接】qlibQlib is an AI-oriented Quant investment platform that aims to use AI tech to empower Quant Research, from exploring ideas to implementing productions. Qlib supports diverse ML modeling paradigms, including supervised learning, market dynamics modeling, and RL, and is now equipped with https://github.com/microsoft/RD-Agent to automate R&D process.项目地址: https://gitcode.com/GitHub_Trending/qli/qlib
本文围绕 Qlib 的Meta Controller组件(文档见 meta.rst)展开:先讲清 Meta-Task、Meta-Dataset、Meta-Model 三类抽象的职责边界与 API 契约,再结合仓库中自带的 DDG-DA 完整实现,剖析"元信息生产 → 元模型训练 → 推理引导 → 改写基座任务"的端到端调用链,并给出运行基准样例所需的配置与命令,帮助你理解如何基于 Meta Controller 自定义自己的元学习模型来适应市场动态变化。
1. Meta Controller 的定位:给预测模型"导学"
Meta Controller的核心目标是:学习一系列预测任务(forecasting tasks)之间的规律性模式,并利用学到的模式去引导后续的预测任务。文档原文将其描述为"provides guidance to Forecast Model"。
在 Qlib 的常规工作流中,一个任务(task)由数据集(dataset)与模型(model)配置组成,由 Trainer 串行训练。而Meta Controller在任务之上加了一层"元层"(meta-level):元模型不直接预测股票收益,而是观察"多个基座任务各自学得怎么样",从中提炼出可迁移的知识,再反过来影响基座预测模型的工作流。
从源码结构看,这一组件的抽象骨架位于qlib/model/meta/包,包含三个文件:
| 抽象 | 源码位置 | 职责 |
|---|---|---|
MetaTask | qlib/model/meta/task.py | 元学习框架的基本元素,保存可喂给元模型的数据 |
MetaTaskDataset | qlib/model/meta/dataset.py | 控制元信息(meta-information)的生成过程,负责为元模型提供训练数据 |
MetaModel及子类 | qlib/model/meta/model.py | 控制工作流:用fit训练、用inference给出引导信息 |
三者构成一条清晰的数据流:MetaTaskDataset.prepare_tasks()产出若干MetaTask→ 元模型fit()消费这些元任务完成训练 → 元模型inference()输出"引导信息"(如改写后的任务定义、样本权重等)→ 引导信息被应用回基座预测模型。
2. MetaTask:元学习的基本数据单元
文档指出:一个Meta Task实例保存了可供Meta Model使用的数据;多个Meta Task实例可以共享同一个Data Handler,这一共享关系由Meta Dataset控制。
从 qlib/model/meta/task.py 的源码看,MetaTask的构造签名是:
MetaTask(task: dict, meta_info: object, mode: str = PROC_MODE_FULL)task:被元模型增强的 Qlib 任务定义(dict 配置);meta_info:喂给元模型的原始输入信息,初始化时会保存原始值,后续再做处理;mode:数据处理模式,源码定义了三种:
| 模式常量 | 取值 | 含义(源码注释) |
|---|---|---|
PROC_MODE_FULL | "full" | 训练用:训练任务需要 X、y、X_test、y_test 齐全 |
PROC_MODE_TEST | "test" | 测试用:测试任务不需要完整的训练/测试对 |
PROC_MODE_TRANSFER | "transfer" | 元模型可迁移到其他数据集时:只需要 meta_info |
源码中还提供了两个关键方法:get_dataset()通过init_instance_by_config(self.task["dataset"])从任务配置中初始化出Dataset实例(这就是"多个 MetaTask 共享 Data Handler"的实现入口——数据集配置相同即可复用);get_meta_input()返回处理后的meta_info,供元模型直接消费(文档中提到的prepare_task_data()在现行源码中对应的就是这条"取出可直接喂入元模型的数据"的语义)。
3. MetaDataset:元信息的生成器
Meta Dataset负责元信息的生成流程,"为训练 Meta Model 提供数据"。用户应通过prepare_tasks获取一组MetaTask实例。
看 qlib/model/meta/dataset.py 中MetaTaskDataset的契约:
- 构造参数
segments(Dict[Text, Tuple]或float)指示数据如何切分;初始化时元数据集就已维护好 meta-tasks 列表; prepare_tasks(segments):传入单个 segment 名或 segment 列表,返回对应的一批 meta-task(多 segment 时返回嵌套列表[[tasks in seg1], ...]);源码中内置了如下调用示例:
# get the train segment and the test segment, both of them are lists train_meta_tasks, test_meta_tasks = meta_dataset.prepare_tasks(["train", "test"])- 抽象方法
_prepare_seg(segment)留给具体实现:负责为单个 segment 准备好训练数据。
值得注意的是源码类注释中明确写出的迁移性设计意图:"A meta-model trained on meta-dataset A and then applied to meta-dataset B"——即在元数据集 A 上训练的元模型,其输入特征应当能在元数据集 B 上复用,因此实现_prepare_seg时必须保证 meta 输入的结构在数据集之间是可对齐的。
仓库自带的完整实现是 qlib/contrib/meta/data_selection/dataset.py 中的MetaDatasetDS,它把"任务模板如何展开成滚动任务序列、每个任务的元输入如何计算"全部落地:
task_tpl:可以是单个任务模板 dict(此时用RollingGen按step/trunc_days滚动生成任务序列),也可以是已排好时间顺序的任务 list(直接使用);step:滚动步长;trunc_days:基于测试起点截断的天数,源码注释特别强调 "trunc_days is very important",用于屏蔽与未来信息重叠的数据;exp_name:元信息来源,可以是实验名(str,自动用InternalData.setup()训练一批代理模型并统计其表现)或已准备好的InternalData实例;segments:float 表示用于训练的 meta-task 比例;str 则保证该日期落在测试集中;hist_step_n:元信息的历史步数(数据相似性信息的回溯长度);task_mode/fill_method:分别控制元任务的数据处理模式(对应MetaTask的三种模式)与元信息缺失值的填充策略("max"、"maxseg"、"zero")。
其中元输入的核心数据结构是MetaTaskDS.processed_meta_input,包含:
time_perf:形状<hist_step_n * step, data pieces>的时间表现矩阵,刻画"各数据段上历史代理模型的表现";time_belong:<sample, data pieces>的 0/1 归属矩阵,标记每个训练样本属于哪个时间数据段(见 MetaTaskDS 的 docstring);FULL模式下还会附带X / y / X_test / y_test / test_idx,即该基座任务的训练/测试特征标签数据。
4. MetaModel:三种引导基座工作流的方式
文档将Meta Model的使用归纳为两步:用fit训练元模型;元模型实例通过inference给出有用信息来引导工作流。抽象基类 qlib/model/meta/model.py 只有两个抽象方法:
@abc.abstractmethod def fit(self, *args, **kwargs): ... @abc.abstractmethod def inference(self, *args, **kwargs) -> object: ...基类注释进一步按"干预基座学习流程的阶段"把引导分成两类,对应两个子类:
4.1 MetaTaskModel:直接改写任务定义
"This type of meta-model may interact with task definitions directly... They guide the base tasks by modifying the base task definitions."
MetaTaskModel约定了签名:fit(meta_dataset)从 meta-dataset 取出准备好的 meta-task 并学习知识;inference(meta_dataset) -> List[dict]在推理时输出一批修改后的任务定义,这些任务可以直接被 Qlib trainer 执行。也就是说,这一类元模型的作用方式是"任务级"的——它把学到的知识物化成对基座任务的修改(例如给样本加权、调整数据范围),而不是在训练循环内部插入逻辑。DDG-DA 正是这一类。
4.2 MetaGuideModel:参与基座模型的训练过程
"This type of meta-model participates in the training process of the base forecasting model... guide the base forecasting models during their training to improve their performances."
MetaGuideModel与MetaTaskModel同样继承MetaModel的fit/inference抽象,但从源码结构看,它的定位是让元模型在基座预测模型的训练期间持续互动(例如在训练循环中提供正则项、损失调制等),属于"训练过程级"的引导。用户实现自定义元模型时,可按需选择继承哪一个子类。
4.3 自定义元模型的实现要点
综合以上契约,实现一个自己的元模型大致是三步:
- 继承
MetaTaskDataset,实现_prepare_seg(segment),返回一批构造好的MetaTask(task, meta_info, mode); - 继承
MetaModel(或MetaTaskModel/MetaGuideModel),实现fit与inference; - 在滚动/在线工作流中,把元模型的
inference输出接回基座任务或基座训练循环。
5. 完整示例:DDG-DA 自适应市场动态
文档给出 Qlib 内置的元模型实现DDG-DA(Data Distribution Generation for Predictable Concept Drift Adaptation),它"adapts to the market dynamics"。文档描述的四个步骤与源码 qlib/contrib/rolling/ddgda.py 中DDGDA.run()的调用一一对应:
| 文档步骤 | 源码方法 | 产出 |
|---|---|---|
1. 计算 meta-information 并封装为MetaTask实例,所有 meta-task 组成MetaDatasetDS | _dump_data_for_proxy_model()、_dump_meta_ipt()、MetaDatasetDS.__init__ | 文件handler_proxy.pkl、internal_data_s{step}.pkl;mlflow 实验data_sim_s{step} |
| 2. 基于元数据集的训练数据训练 DDG-DA | _train_meta_model() | mlflow 实验DDG-DA中保存的MetaModelDS |
| 3. 对 DDG-DA 做推理得到 guide information | get_task_list()中meta_model.inference(mds) | 文件tasks_s{step}.pkl(每个任务被加上了reweighter) |
| 4. 将 guide information 应用到预测模型 | 继承自Rolling的super().run() | 训练滚动预测模型并汇总预测 |
几个值得注意的实现细节:
- 代理模型(proxy model)机制:DDG-DA 先用一个简化代理模型(默认 LightGBM 计算特征重要性、按
sim_task_model选择 linear/gbdt 统计相似性)在历史数据上滚动训练,再用InternalData.setup()把"每个代理模型在不同日期上的日频 Spearman 相关性(IC)表现"整理成data_ic_df,这就是 meta-information 的原始形态(见 qlib/contrib/meta/data_selection/dataset.py)。_prepare_meta_ipt()随后用mask_overlap()掩掉与自身训练期重叠(含 horizon 泄漏窗口)的列,防止信息穿越。 - 元模型本体:
MetaModelDS(qlib/contrib/meta/data_selection/model.py)内部是PredNet(net.py)——一个"时间权重网络 + 加权岭回归闭式解"的组合:TimeWeightMeta从time_perf序列预测每个数据段的时间权重,preds_to_weight_with_clamp用tanh/clamp/sigmoid方式裁剪权重;损失函数ICLoss(utils.py)对每个交易日计算预测与标签的相关性并取负 IC 均值,loss_skip_thresh参数用于跳过样本数过少的交易日。 - 引导的落地形式:
MetaModelDS._prepare_task()对每个基座任务浅拷贝后挂上一个TimeReweighter,即"改写任务定义"具体体现为按时间分布对训练样本加权。这与MetaTaskModel.inference返回List[dict]的契约完全吻合。 - 知识迁移:
get_task_list()中训练侧与推理侧的MetaDatasetDS参数(step、trunc_days、hist_step_n、fill_method)刻意保持一致,推理侧则设置segments=0.0与task_mode=MetaTask.PROC_MODE_TRANSFER,正好呼应了第 2 节中"元模型可迁移到其他数据集,只需要 meta_info"的设计。
运行 DDG-DA 基准
入口脚本是 examples/benchmarks_dynamic/DDG-DA/workflow.py,它定义DDGDABench(DDGDA),默认使用 baseline/workflow_config_linear_Alpha158.yaml(Linear 基座,效率优先),也支持 LightGBM 配置。按 examples/benchmarks_dynamic/DDG-DA/README.md 的说明,运行命令为:
python workflow.py run # 换用 LightGBM 基座模型: python workflow.py --conf_path=../baseline/workflow_config_lightgbm_Alpha158.yaml run运行前提与限制:
- 需要先准备 Qlib 数据(脚本中在未设置
PROVIDER_URI时会通过GetData().qlib_data(exists_skip=True)自动下载;设置PROVIDER_URI环境变量可指向已有数据); - 硬件最低要求:约 45G 内存、4G 磁盘,CPU 版 PyTorch 即可;
- 基类的
Rolling初始化参数(conf_path、horizon=20、step=20、train_start、test_end等,见 qlib/contrib/rolling/base.py)与 DDG-DA 特有参数(sim_task_model、alpha、loss_skip_thresh、fea_imp_n=30、segments=0.62、hist_step_n=30、meta_data_proc="V01"等,见 DDGDA 构造器)均可通过fire命令行覆盖; - 注意源码中的提示:由于 mlflow 实验难以彻底删除(同名实验会移入 .trash 导致创建失败),运行示例前建议清理旧结果(删除
mlruns目录)。
6. 小结与延伸阅读
回到文档的主线:Meta Controller用三个最小抽象把"元层"与"基座层"解耦——MetaTask定义"一个元任务长什么样"(FULL/TEST/TRANSFER 三态),MetaTaskDataset定义"如何批量生产元任务"(prepare_tasks+_prepare_seg),MetaModel定义"元模型如何被训练与如何使用"(fit/inference),并在MetaTaskModel(改任务定义)与MetaGuideModel(介入训练过程)之间给出两条落地路径。仓库中 DDG-DA 的 qlib/contrib/meta/ 与 qlib/contrib/rolling/ddgda.py 提供了从元信息构造、元模型训练到任务级加权的完整参考实现,是自定义元模型时最值得对照阅读的代码路径;配套的滚动基类 qlib/contrib/rolling/base.py 则说明了RollingGen/task_generator这一层在 Meta 模块与滚动重训之间共享的基础设施。
【免费下载链接】qlibQlib is an AI-oriented Quant investment platform that aims to use AI tech to empower Quant Research, from exploring ideas to implementing productions. Qlib supports diverse ML modeling paradigms, including supervised learning, market dynamics modeling, and RL, and is now equipped with https://github.com/microsoft/RD-Agent to automate R&D process.项目地址: https://gitcode.com/GitHub_Trending/qli/qlib
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考