QuantMind模型推理服务架构深解:共享模型内核+私有数据上下文四层设计
QuantMind模型推理服务架构深解:共享模型内核+私有数据上下文四层设计
QuantMind(量化大脑)开源版是一款面向个人开发者与投研团队的 AI 原生多市场量化交易平台,其模型推理服务负责把训练好的模型变成实时行情下的 Alpha 预测信号。本文将带你完整拆解它的核心设计——"共享模型内核 + 私有数据上下文"四层架构:一套模型内核被所有用户共享,而每个用户看到的股票池、信号上下文却严格隔离。即使是量化新手,读完后也能看懂一次推理请求从进入到出分的完整旅程。
为什么需要"共享模型 + 私有数据"的推理架构?
想象这样一个场景:你在 QuantMind 里训练了一个 LightGBM 模型,而你的同事也训练了一个。如果每个用户都要各自拉起一套模型加载器,服务器内存会瞬间爆炸;但如果简单粗暴地"共用一切",A 用户的私有股票池、模拟盘数据就可能泄漏给 B 用户。
QuantMind 的推理服务给出的答案是:计算共享,数据隔离 🧠
- 模型内核共享:同一个
model_id的权重在进程内只加载一次,用 LRU 缓存复用,多个请求、多个租户共用同一份内存; - 数据上下文私有:推理时喂给模型的特征来自当前用户请求的股票池与私有数据目录,
tenant_id + user_id决定你能看到什么。
这套设计在 官方链路设计文档 中有完整的流程图与说明。
四层架构总览:一次推理请求的完整旅程
推理服务位于计算引擎 quantmind-engine 内部,由 backend/services/engine/inference/ 目录承载,核心由四个组件分层协作:
| 层级 | 组件 | 职责 | 一句话理解 |
|---|---|---|---|
| 第 1 层 | InferenceService | 服务入口与编排 | "总指挥":接单、调度、交付 |
| 第 2 层 | ModelLoader | 模型生命周期管理 | "仓库管理员":加载、校验、缓存模型 |
| 第 3 层 | DataAdapter | 特征工程适配 | "翻译官":把行情翻译成模型能懂的输入 |
| 第 4 层 | HistoryBuffer | 状态数据缓冲 | "短期记忆":记住每只股票最近 30 天 K 线 |
第 1 层:InferenceService —— 统一入口与流程编排
一切推理请求都从 InferenceService 进入。它本身不做重活,而是把四个步骤串成流水线:
- 让 ModelLoader 取出(或加载)目标模型;
- 让 DataAdapter 把原始行情转换成特征矩阵;
- 调用模型执行预测;
- 输出 Alpha 分数(通常为 -1 到 1 之间),直接对接下游仓位管理。
在 predict 方法 中还能看到两个贴心细节:*自动剔除 ST / ST / 退市股,以及针对序列模型(如 TFT)自动切换序列预测分支——你不需要关心模型是单点还是时序结构,入口统一。
第 2 层:ModelLoader —— 多框架模型加载与内存缓存
ModelLoader 是整个架构里"共享内核"的承载者。它的能力清单相当可观:
- 7 大框架自动识别:根据
metadata.json中的framework字段,自动分发到 LightGBM、XGBoost、CatBoost、Scikit-learn、PyTorch/TFT、ONNX 等加载器(见框架分发逻辑); - LRU 内存缓存:默认最多常驻 5 个模型,最久未用的模型自动淘汰(LRU 淘汰实现),让"共享"不变成"内存黑洞";
- 集成模型支持:内置
EnsembleBooster(多 Booster 平均融合)与StackingEnsemble(基模型预测 → 元学习器融合),多模型投票开箱即用; - 版本化解析:请求
model_id时可自动匹配model_id_v*的最新版本目录; - 安全防线:官方设计文档中还描述了加载前对模型文件做 SHA256 签名校验(与
metadata.json比对摘要),防止恶意序列化文件带来的代码注入风险。
第 3 层:DataAdapter —— 让线上推理和训练"说同一种语言"
模型训练时吃的是 Qlib 标准特征,实盘推理时来的是实时行情——字段名、口径都可能对不上。DataAdapter 就是解决这个问题的"翻译官":
- 通过字段映射表把
close_price → close、volume → volume等统一成 Qlib 口径; - 标准化股票代码格式(
symbol → instrument); - 关键一步:结合下一层的 HistoryBuffer,基于历史窗口计算真实的 MA、波动率、收益率等技术指标,而不是用单点数据硬编码常数。
这一步直接决定了"离在线一致性"——如果线上特征分布和训练时不一致,预测结果就是无意义的。
第 4 层:HistoryBuffer —— 给推理服务装上"短期记忆"
HistoryBuffer 为每只股票维护一个固定长度(默认 30 天)的环形缓冲区(见 SymbolBuffer 实现):
- 新 K 线进来自动追加,最旧的数据自动淘汰,内存占用恒定;
- 线程安全,支持多股票并发写入;
- 30 天的窗口恰好够计算 MA20 与 10 日波动率等常用指标。
它的价值可以这样理解:没有它,实时推理时"最近 20 日平均价"根本无从谈起;有了它,模型在线上"看到"的数据形态才和训练时一致。
多用户共用一套引擎,隐私如何保障?🔒
"共享内核"听起来很美,但多租户隔离才是生产级系统的底线。QuantMind 在三个层面做了防护:
1. 缓存命名空间隔离
模型虽然共享,但缓存 key 会带上租户命名空间。在 InferenceRouterService 中,cache_namespace 被设置为 {tenant_id}:{user_id}——卸载或替换模型时不可能误伤其他用户已加载的实例。
2. 数据目录私有化 训练与推理产物按用户隔离存放:
- 生产模型:
models/production/{model_id}/ - 用户模型:
models/users/{tenant_id}/{user_id}/{model_id}/
模型解析优先级为 显式 model_id > 策略绑定 > 用户默认(详见 inference/README.md)。请求头中的 X-User-Id 决定推理时可访问的私有股票池与模拟盘上下文。
3. 资源与超时限制 单次推理时长由代理层超时参数约束,避免大批量任务阻塞;引擎容器本身也有内存上限,防止某个用户的复杂模型把系统拖垮(OOM)。
从一次点击到全市场信号:每日信号生成链路 💡
架构的价值最终体现在日常体验上。QuantMind 的"明日信号生成"支持三种触发方式:
- 管理员手动触发:
POST /api/v1/admin/models/run-inference; - 策略激活自动触发:激活策略后按
tenant_id + user_id立即跑一次推理; - Celery 定时兜底:Beat 任务按因子可用日自动补缺口,缺什么补什么。
三条链路最终都汇入同一个执行器(InferenceRouterService + InferenceScriptRunner),并支持批量多日推理:BatchInferenceOrchestrator 解析交易日窗口、逐日幂等执行、默认 5 并发——60 个交易日的回补从串行约 10 分钟压缩到约 2 分钟,且已跑过的日期自动复用,不重复计算。
推理结果统一落库到 engine_feature_runs / engine_signal_scores,并写入 Redis 版本键 qm:signal:latest:{tenant_id}:{user_id},交易侧只消费最新版本信号,自动丢弃过期结果——信号永远新鲜。
更上游:因子演化与模型工场如何喂给推理服务
推理服务不是孤立的。在 QuantMind 的完整闭环中,模型来自两个上游:
- RD-Agent 因子演化:AI 智能体自动提出、编码、回测候选因子,持续扩充 300+ 维因子库,其整体框架如下图所示:
- 13 种模型工场:LightGBM 到 TFT 深度时序模型,训练产物自动注册到
models/users/目录,推理服务无需改一行代码即可加载新模型——这就是"共享内核"的红利:上游换模型,下游无感。
核心文件速查清单 📂
想深入源码?按下面路径直达四层架构核心:
| 模块 | 路径 | 看点 |
|---|---|---|
| 服务编排 | service.py | 推理主流程、ST 股过滤 |
| 模型加载 | model_loader.py | 多框架分发、LRU 缓存 |
| 特征适配 | data_adapter.py | 字段映射、指标计算 |
| 历史缓冲 | history_buffer.py | 30 日滑窗、线程安全 |
| 租户路由 | router_service.py | 模型解析优先级、缓存命名空间 |
| 批量编排 | batch_orchestrator.py | 幂等补跑、并发控制 |
| 设计文档 | 模型推理服务设计与链路文档.md | 完整链路流程图 |
| 模块说明 | inference/README.md | 每日信号口径、数据门禁 |
写在最后
回看 QuantMind 模型推理服务的四层设计,其实只回答了一个问题:如何在"省"与"稳"之间取得平衡——
- InferenceService 保证流程统一,ModelLoader 用缓存省钱,DataAdapter + HistoryBuffer 保证预测有意义;
- 而
tenant_id + user_id的私有数据上下文,则让"共享"永远不等于"暴露"。
这套"共享模型内核 + 私有数据上下文"的思路,不仅适用于量化平台,对任何需要多租户共算的 AI 服务(推荐、风控、内容理解)都是可复用的架构范本。部署 QuantMind 后,你可以从模型中心训练一个自己的模型,再观察每日信号如何自动流入回测与模拟盘——亲手走完这条链路,比读十篇文档都深刻 🚀




