Repository navigation
neuralnet.cpp v1.12.0
neuralnet.cpp v1.12.0 Release Notes
发布范围:
v1.11.0(tagv1.11.0,2026-10-23)→v1.12.0(tagv1.12.0)。
主题:RL 与可组合训练基础设施——具名多输出模型、schema 化 experience、
GAE/return/group normalization、REINFORCE/PPO/GRPO objectives、多模型角色容器与
可替换 rollout pipeline。
兼容性:无破坏性 API 或 CLI 变更。模型/断点文件格式仍为 v8;新增的
output_schema/output_packing是ModelSpec可选键,旧文件缺键时保持单输出语义。
授权条款变更:项目许可证从 MIT 切换为 LGPL-3.0,升级、链接或分发前请阅读 §4。
1. 主题与定位
v1.12.0 把此前散落在调用方的 policy-gradient 公共语义收进库层,同时保留算法和
环境边界:
- 库提供 schema、experience、objective、session 与 pipeline;
- 环境
reset/step、MCTS、棋规、自对局 worker、replay policy 仍由消费者实现; - 首版分布为 categorical,其他分布经
PolicyDistribution扩展; - 不新增引擎原语或 shader;RL 数值路径全部由现有 Tensor/Engine/DSL 组合。
设计背景与能力下界见 ../todo/31-rl-training-primitives.md,
调用指南见 ../usage/06-reinforcement-learning.md。
2. 新增能力
2.1 有序 schema 与具名多输出
TensorSchema/FieldHandle/NamedTensorSet/GradientBundle提供稳定字段顺序、
shape / precision / placement 校验和 setup 期名称解析。Layer::output_schema()、forward_named()、backward_named()为单输出层提供默认适配;
OutputBundleLayer将同一输入 fan-out 到具名分支并汇总输入梯度。Model::forward_named()/backward_named()让共享 trunk 的中间层继续使用单 Tensor,
最后一层可展开为多端口。RowBandPacking只作为旧单 Tensor ABI 的显式兼容适配器;named API 不依赖行号约定。ModelSpec可持久化可选output_schema/output_packing,缺键保持旧单输出行为。
2.2 Experience、GAE 与归一化
TensorRecord/ExperienceSchema/PolicyBatchView:标准字段可选项可按算法收紧,
自定义字段仍可由 consumer 通过 typed record 读取。GaeAdvantage:支持 done 截断、mask、terminal bootstrap;mask 外时间步不参与状态值
或 advantage 的跨步传递。MonteCarloReturn、MaskedNormalizer、GroupAdvantage:支持总体标准差、零方差与
GRPO 连续 group span。
2.3 Policy 与 objective 组件
PolicyDistribution接口与首版CategoricalDistribution:log-prob、entropy、sample、
analytic gradient。- 低层组件:
ReinforceObjective、ValueRegressionObjective、
EntropyBonusObjective、SampledKlObjective、ClippedPolicyObjective、
ClippedValueObjective。 - 标准 preset:
PpoObjective与GrpoObjective;preset 的组合损失/梯度与手工组件组合
等价。
2.4 多模型与 rollout 编排
TrainingGroupSession:具名 trainable/readonly role,共享同一ComputeEngine,
保持每个TrainingSession的 optimizer-before-model 生命周期。RLTrainingPipeline:固定rollout → buffer → sample → update顺序,batch 索引、
hooks、metrics、RNG/update/rollout 计数和 checkpoint provider 可替换。TrainingSession::train_named_step:与train_step共用 global/micro batch 累积、
归一化、裁剪和 optimizer update 语义,仅把最后反向替换为backward_named。
3. 发布审查修正
独立 Release 审查在合并前修复了以下路径,并加入回归:
- PPO off-policy 梯度:负 advantage 的裁剪两侧及容差带内部曾使用错误分支;现在
统一使用ratio * advantage的未被裁剪侧梯度,并覆盖负 advantage 的有限差分。 - GAE mask 语义:mask 外时间步的 value 不再泄漏到前一步 bootstrap;新增非零 value
的 masked-value 回归。 - Policy batch 形状校验:REINFORCE/entropy/KL/PPO 在进入引擎前置检查
(1,T),
阻止宽度不符时继续读写。 - 具名反向状态:失败的 forward 会立即失效旧的 backward 配对状态。
- 不可信 schema 解码:字段/名称计数在大分配前按上限和负载长度校验;字段名校验
改为线性重复检测,schema 指纹加入字符串长度边界。 - Pipeline 状态提交:模型 update 成功后,即使 post-update hook 失败,也会提交
update 计数与 on-policy buffer 清理,避免重试重复更新。
4. 兼容性与迁移
| 项目 | v1.11.0 → v1.12.0 |
|---|---|
| 已有 Model/Layer/Loss/Optimizer API | 不变;新增具名入口均为默认适配 |
已有单输出 Model::forward/backward |
不变 |
| 多输出旧 ABI | 使用 RowBandPacking;named API 直接用 forward_named/backward_named |
| 模型/断点格式 | v8 不变 |
ModelSpec |
新增可选 output_schema / output_packing;旧文件缺键 = 单输出 |
| CLI / GUI | 无新增或破坏性参数 |
nn.hpp |
聚合新增 RL 头;需要最短依赖时可改 include rl.hpp |
| 项目许可证 | MIT → LGPL-3.0;修改本库并分发时须继续使用 LGPL-3.0,应用链接本库的边界按 LGPL §4 处理 |
迁移旧 policy/value 双头模型时,将原有拼接输出拆为具名分支,并用
TensorSchema::create 固定端口顺序、shape 和 precision;只有仍消费单 Tensor 的调用方
才需要 RowBandPacking。
5. 验收基线
口径:
NN_ENABLE_NATIVE=OFF可移植基线;GPU = NVIDIA CMP 40HX / Vulkan SDK
1.4.350 / 驱动 616.92。全部构建目录均为全新构建。逐项记录见
../todo/25-release-requirements.md§9。
| # | 配置 | 构建 | 完整测试 |
|---|---|---|---|
| 1 | Windows clang 23.1 + MSVC STL / Release / Vulkan | 239/239 步 | 69/69:68 pass + 1 skip + 0 fail(604.58 s;skip=scan_bitwise_test 平台口径) |
| 2 | Windows clang 23.1 + MSVC STL / Debug / Vulkan | 239/239 步 | 69/69:68 pass + 1 skip + 0 fail(883.82 s;skip=scan_bitwise_test;rapt_test_f16 实际执行并 Passed) |
| 3 | Windows cl.exe 19.51 + MSVC STL / Debug / CPU-only | 全目标成功链接 | 67/67:46 pass + 21 skip + 0 fail(194.66 s) |
| 4 | WSL g++ 15.2 + libstdc++ / Release / CPU-only | 132/132 步 | 67/67:48 pass + 19 skip + 0 fail(41.05 s) |
| 5 | WSL clang 24.0 + libc++ / Release / CPU-only | 132/132 步 | 67/67:48 pass + 19 skip + 0 fail(37.09 s);ldd 确认 libc++ |
CPU-only 的 19 个 skip 均为 GPU/offload 依赖用例;MSVC 额外 2 个 skip 为已知的多配置
app 发现路径缺口。rapt_test_f16 在 Debug GPU 与 MSVC Debug 下均为实际执行并通过。
5.1 真实端到端训练
数据集 = datasets/tinystories_20k.nndataset(20,000 docs / 4,244,522 tokens /
66,321 个 seq64 窗口);GPT d_model=64 / heads=4 / layers=2 / d_ff=128 / seq_len=64,--batch-size 8 --accum-steps 2,20 update step,40HX:
| 配方 | loss 轨迹(step 5/10/15/20) | 结果 |
|---|---|---|
| f32 | 8.7752 → 8.3832 → 8.0131 → 7.7011 | 1.8 s,无 NaN/冻结 |
--f16 |
8.7207 → 8.3779 → 7.9881 → 7.6188 | 1.5 s,无 NaN/冻结 |
--t1_58 |
8.8803 → 8.6901 → 8.4593 → 8.1366 | 4.5 s,无 NaN/冻结 |
f32 模型 warm start 1 step:loss 7.6060;保存文件 SHA-256 由
A060F06A…02D2 变为 0211B037…27D06,证明参数确实移动。
5.2 门禁与 AOT
bench/doc_inventory.ps1:52/52 engine virtual,L2-VIOLATIONS: 0,
HANDWRITTEN-RESIDUE: 0,TERMINATING-CALLS: 0。bench/gui_cli_audit.py:七节 PASS,可行动问题 0(使用最终 Release 二进制)。bench/doc_align_audit.ps1/bench/audit_dangling.ps1:可行动问题 0。scan_exprs:库内 158 条融合表达式;RL PPO 梯度选择、value clip、GAE 与 reduction
路径均进入 AOT 闭合世界。
6. 提交索引
主要能力提交从 fb21e21(架构冻结)到 2eb21a2(named PPO → TrainingSession);
独立发布审查修复提交为 1cb1c2b(基于 d822089)。正式发布另含一个
release: v1.12.0 提交,仅同步版本号、文档计数、发布说明和验收记录。审查期间远端
main 已合并许可证变更 PR #22(11987ef / merge 736c2a1),本版本通过合并保留
该 MIT → LGPL-3.0 变更;代码与构建测试结果不受影响。
7. 已知限制
OutputBundleLayer当前是单输入 fan-out;任意多阶段 DAG 不在 v1.12 范围。ModelSpec保存 schema/packing 元数据,但不序列化任意自定义分支拓扑;具名模型仍由
应用代码或领域工厂重建。RLTrainingPipeline自身 checkpoint 只固定 RNG、update/rollout 计数;experience
buffer 与 replay policy 由CheckpointProvider的自定义 section 管理。- policy distribution 首版仅 categorical;连续动作与 multi-discrete 需实现
PolicyDistribution。 - 环境、MCTS、自对局、棋规与规则引擎不内置于库。