RillML
面向 Rust 应用、边缘设备和持续变化数据流的轻量在线机器学习库。
RillML 提供可直接嵌入 Rust 原生应用的增量学习组件:在线统计、预处理器、线性/逻辑回归、评估指标、Pipeline、渐进式评估,以及基于 serde 的可选状态持久化。
除嵌入式 crate 外,workspace 还提供可独立分发的 rill-runtime、稳定 IPC 约定和签名 .rillpack 模型包。宿主可以只依赖协议 crate,让 Runtime 与模型脱离主程序单独更新。完整边界与发布流程见 RUNTIME.md。
RillML 受 River 推广的在线学习工作流启发。它是一个独立的 Rust 项目,与 River 无关联,也未获得 River 的认可。目前不追求 API 或模型兼容性。
为什么需要在线学习?
传统机器学习采用批量工作流:收集数据、离线训练、部署固定模型、定期重训练。这在数据充足、稳定且可集中获取时表现良好。
在线学习采用不同方式:逐条处理样本,先预测后学习,持续适应。适用于:
- 流式数据:无法存储全部历史。
- 边缘设备:内存有限,无 Python 运行时。
- 持续变化的环境:固定模型会逐渐失效。
- 隐私敏感场景:数据不应离开设备。
- 实时系统:需要在下一条样本到达前给出预测。
RillML 用纯安全 Rust 实现这一工作流,内存有界。
适用场景
- IoT 遥测、资源用量、传感器读数等在线回归任务。
- 基于滚动统计的传感器异常检测。
- 实时点击或事件分类。
- 存在概念漂移的网络延迟预测。
- 任何需要轻量、持续学习组件的 Rust 应用。
非适用场景
- 大规模离线模型训练(请使用 Linfa、SmartCore 或 Python)。
- 深度学习(请使用 Burn、candle 或 tch-rs)。
- 跨多机的分布式训练。
- 需要 GPU 加速的场景。
- 研究和快速算法实验(Python 更合适)。
Python 更适合研究、数据分析和快速算法实验。RillML 重点解决 Rust 原生嵌入和持续运行。Rust 不会让同一算法天然更准确,价值主要来自工程部署、状态管理和本地运行。
安装
在 Cargo.toml 中添加:
[]
= "0.5"
需要序列化支持时启用 serde feature:
[]
= { = "0.5", = ["serde"] }
环境要求: Rust 1.85+(Edition 2024),无需 nightly。
快速开始
use ;
let feature_count = 2;
let scaler = new.unwrap;
let optimizer = sgd.unwrap;
let regression = new.unwrap;
let mut model = new.unwrap;
let mut mae = default;
let samples = ;
for in samples
渐进式评估
在线学习的核心契约是:先预测,后学习。RillML 的 evaluate 模块强制执行以下顺序:
predict → metric.update → learn
这确保指标反映模型对未见过数据的泛化能力,而非对已记忆样本的拟合。
use ;
use Mae;
use ;
use OnlineRegressor;
let mut model = new.unwrap;
let mut mae = default;
let samples = vec!;
let final_mae = evaluate_regression.unwrap;
回归示例
参见 examples/online_regression.rs,完整的在线回归演示:
- 对比
MeanRegressor、EWMeanRegressor和LinearRegression。 - 使用
StandardScaler进行特征标准化。 - 演示
Snapshot序列化往返。
分类示例
参见 examples/online_classification.rs,使用 LogisticRegression 进行在线二分类:
诊断示例
参见 examples/diagnostics_demo.rs,演示 v0.2 诊断模块:
- 使用
TrainingSummary跟踪训练统计。 - 使用
PredictionReporter生成带置信度和预测区间的报告。 - 使用
OnlineModelSelector比较MeanRegressor与LinearRegression并自动选择最佳模型。 - 使用
ModelHealthReport检测参数中的 NaN/Infinity。
稀疏特征示例
参见 examples/sparse_classification.rs,演示高维稀疏分类:
- 使用
SparseFeatures表示稀疏特征向量。 - 使用
FeatureHasher将字符串特征名哈希为FeatureId。 - 对比
FtrlClassifier(稀疏输入)与LogisticRegression(哈希后稠密输入)与GaussianNaiveBayes。 - 演示 FTRL 的 L1 正则化产生的稀疏权重。
SparseFeatures 使用排序的 Vec<(u64, f64)> 而非 HashMap,支持二分查找和确定性序列化。FtrlRegressor / FtrlClassifier 通过 BTreeMap<FeatureId, FtrlParam> 实现动态特征增长,无需预先知道所有特征 ID。
漂移检测示例
参见 examples/drift_demo.rs,演示 v0.4 漂移检测模块:
- 使用
PageHinkley检测均值偏移。 - 使用
Adwin检测自适应窗口分布变化。 - 使用
Kswin检测分布形状变化。 - 演示
DriftAwareModel在检测到漂移时自动重置LinearRegression。
在线决策示例
参见 examples/bandit_demo.rs,演示 v0.5 在线决策模块:
- 对比
EpsilonGreedy、Ucb1、ThompsonSampling在固定奖励分布下的表现。 - 演示
LinUCB上下文老虎机根据上下文特征选择最优 arm。 - 演示安全回退策略:在数据不足时使用默认 arm。
Ucb1与ThompsonSampling的奖励必须归一化到[0, 1];反序列化时会校验模型状态。
序列化
启用 serde feature 后可以序列化和恢复模型状态:
use Snapshot;
use Mean;
use OnlineStatistic;
let mut mean = new;
mean.update.unwrap;
mean.update.unwrap;
let snap = new;
let json = to_string.unwrap;
let restored: = from_str.unwrap;
let m = restored.into_model.unwrap;
assert!;
Snapshot<T> 使用格式版本号包裹模型状态,并拒绝不兼容的版本。快照来源不可信或模型还有业务约束时,请使用 into_model_with_validation() 在启用恢复状态前执行应用级校验。完整的生产接入与故障回退建议见 RELIABILITY.md。
生产可靠性
RillML 是进程内算法库,不负责服务副本、流量切换或外部存储高可用;这些由宿主应用承担。核心更新路径会拒绝非有限算术结果,统计量和优化器的失败更新不会提交半成品状态;Pipeline 在可靠性边界可使用 learn_transactional() 获得同样的全有或全无语义。生产环境仍应保留最后一个已验证快照与简单基线,在加载失败、模型健康异常或漂移时回退,并监控拒绝样本、加载失败、漂移事件和相对基线误差。详见 RELIABILITY.md。
基线模型
RillML 提供三个简单的基线回归器:
MeanRegressor— 预测所有已见目标的运行均值。ExponentiallyWeightedMeanRegressor— 对近期目标赋予更高权重。LastValueRegressor— 预测上一个见到的目标。
始终使用渐进式评估将模型与基线比较。只有当复杂模型持续优于基线时,才应信任复杂模型。
当前范围(v0.5)
| 类别 | 模块 |
|---|---|
| 统计 | Mean, Variance, Std, Count, Sum, Min, Max, EWMean, RollingMean, RollingVariance |
| 预处理 | StandardScaler, MinMaxScaler, Clipper, OneHotEncoder, OrdinalEncoder, FrequencyEncoder, MissingIndicator, ConstantImputer, MeanImputer, ForwardFill |
| 稀疏特征 | SparseFeatures, FeatureHasher |
| 模型 | LinearRegression, LogisticRegression, MeanRegressor, EWMeanRegressor, LastValueRegressor, FtrlRegressor, FtrlClassifier, GaussianNaiveBayes, BernoulliNaiveBayes, MultinomialNaiveBayes |
| 优化器 | SGD(含 L2), AdaGrad |
| 损失函数 | SquaredError, HuberLoss, BinaryLogLoss |
| 回归指标 | MAE, MSE, RMSE, R², RollingMAE, RollingMSE |
| 分类指标 | Accuracy, Precision, Recall, F1, LogLoss, RollingAccuracy |
| Pipeline | RegressionPipeline, ClassificationPipeline |
| 评估 | 渐进式评估(predict → metric → learn) |
| 持久化 | Snapshot<T> 版本化封装(serde feature) |
| 诊断 | TrainingSummary, WarmupTracker, BaselineComparator, OnlineModelSelector, ResidualInterval, ModelHealthReport, PredictionReporter |
| 漂移检测 | PageHinkley, Adwin, Kswin, DriftAwareModel, DriftAction, DriftStrategy, TimeDecayedMean, LearningRateScheduler, FixedWindowBuffer |
| 在线决策 | EpsilonGreedy, Ucb1, ThompsonSampling, LinUcb, ArmStats |
内存界限:
- 非滚动统计量:O(1)
- 线性模型:O(d),d 为特征数
- 滚动统计量:O(window_size)
- 诊断组件:O(1) 或 O(window_size),不存储原始样本
- 稀疏模型(FTRL):O(k),k 为已见特征数(非特征空间总量)
- 分类编码器:O(c),c 为已见类别数
- 漂移检测器:O(1)(PageHinkley)或 O(window_size)(Adwin/Kswin)
- DriftAwareModel:O(max_events) 事件日志 + 模型 + 检测器
- 非上下文老虎机:O(arm_count)
- LinUCB 上下文老虎机:O(arm_count * d²),d 为特征数
路线图
RillML 遵循真实需求驱动的路线图。完整规划参见 RillML_Roadmap.md。
- v0.1 — 基础闭环:预测、评估、学习、保存、恢复。
- v0.2 — 可靠性与诊断:预测报告、冷启动、基线比较。
- v0.3 — 稀疏特征与高维数据:FeatureHasher、FTRL、朴素贝叶斯。
- v0.4 — 漂移检测:Page-Hinkley、ADWIN、KSWIN、自适应学习。
- v0.5 — 在线决策:多臂老虎机、上下文老虎机。(当前)
- v0.6 — 平台与生态:WASM、Python 绑定、Tokio Stream 适配。
- v1.0 — 稳定的 API 和状态格式。
正确性与验证
RillML 通过多层验证保证正确性:
- 单元测试:每个模块的单元测试,共 562 个。
- 集成测试:130 个集成测试,将在线算法与批量参考公式对照。
- Doctest:所有公共 API 均有文档测试,共 40 个。
- 序列化往返测试:所有有状态类型的序列化/反序列化验证。
- 性质测试:使用
proptest。 - 确定性测试:使用固定随机种子(
rand_chacha)。 - Clippy:CI 中以
-D warnings强制。 - rustfmt:强制执行。
- 示例运行验证:所有示例均实际运行通过。
数值稳定性:
- Welford 算法计算方差。
- 数值稳定的 sigmoid。
- 带 epsilon 保护的缩放,避免除零。
- 公共 API 不 panic,所有错误以
Result<_, RillError>返回。
与 River 的关系
RillML 受 River 推广的在线学习工作流启发。它是一个独立的 Rust 项目,与 River 无关联,也未获得 River 的认可。目前不追求 API 或模型兼容性。
River 在 Python 在线学习研究和实验方面仍然是优秀的选择。
与 Linfa、SmartCore、Burn 的关系
- Linfa — 受 scikit-learn 启发的 Rust 机器学习工具集,侧重批量学习。RillML 侧重内存有界的在线/增量学习。
- SmartCore — 快速的 Rust 机器学习库,算法覆盖广泛,主要面向批量学习。RillML 面向流式数据和边缘部署。
- Burn — Rust 深度学习框架,面向神经网络和 GPU 计算。RillML 面向可在任何地方运行的轻量在线模型。
这些项目是互补的,而非竞争关系。RillML 不旨在替代它们。
命名说明
本项目名为 RillML。与 Rill Data 或任何名为 "Rill" 的产品无关,也未获得其认可。RillML 不提供名为 rill 的 CLI 工具。
许可证
MIT 许可证(LICENSE-MIT)。
贡献
欢迎贡献。提交 Pull Request 前请阅读 CONTRIBUTING.md。
RillML 遵循"真实需求驱动"的开发原则:每个新功能都应解决真实 Rust 应用中的实际问题,而非仅仅复制其他框架中已有的模块。优先方向参见路线图。