Skip to content

Releases: linkerlin/leaves

v2.4.0: BackendAuto opt-in profiling probe

Choose a tag to compare

@linkerlin linkerlin released this 12 Jul 04:56

leaves v2.4.0

主题:BackendAuto 第二轮 — opt-in profiling 探测。

Highlights

  1. tree.ProfileBackend:对实际 workload warm-up + 计时 Native / BornCPU / BornGPU,返回各后端实测 ns/op 与最快推荐。给 BackendAuto 2.0 启发式阈值补上数据驱动选项。
  2. 不破坏 2.0 决策表SelectBackendExplained(batch 64/256、稀疏 0.15)行为零变更;profiling 是 opt-in
  3. 可解释:结果带 Rule 码(profile_native|born_cpu|born_gpu|none_ok|invalid)+ 含各后端 ns/op 的 Reason —— 遵守 docs/backend-auto.md 「任何自动选择必须能被 Rule 码解释」 原则。

Usage

// 用真实批量样本测一遍,拿测量证据替代启发式
res := tree.ProfileBackend(caps, sampleVals, nrows, ncols, 20) // iters 建议 ≥10
fmt.Println(res.Reason)
// "profiling: native fastest at 410 ns/op (native=410 born_cpu=9120 born_gpu=0)"

opts.Backend = res.Pick // 用最快后端
// 也可直接读 res.Native.NsPerOp / res.BornCPU.NsPerOp / res.BornGPU.NsPerOp

Design notes

  • 为何 opt-in 而非接入 Auto:profiling 需要代表性批量样本(调用方才知道真实输入),且首调用有计时延迟。强行接入 BackendAuto 会引入「样本从哪来」+「首调用延迟」两个难题。故保持 2.0 决策表为默认,profiling 作为需要测量证据时的显式工具。
  • 公平性:各后端 nEstimators=0(全量树)、同输入、同 warm-up(2 轮)。
  • 安全:Native 始终参与计时(golden 不变);cat-small 森林或无 WebGPU 的后端 Ok=false 自动排除。

Verification

  • TestProfileBackendPicks:Pick 与实测最快一致(断言一致性,非机器相关具体值)。
  • TestProfileBackendInvalid:非法输入 → profile_invalid 回落 Native。
  • TestProfileBackendNoBornOnUnsupported:cat-small 森林 → Born 排除、Native 选中。
  • tree 全量、docs gate、build、6-linter 门禁全绿。

Compatibility

  • Breaking:无。新增 ProfileBackend 函数 + ProfileResult/BackendTiming 类型;既有 SelectBackend/SelectBackendExplained 不变。

Recommended API

  • 默认推理选型:BackendAuto(2.0 决策表,无需样本)
  • 数据驱动选型:ProfileBackend(传样本,拿测量)
  • 详见 docs/backend-auto.md §第二轮

v2.3.0: complete ONNX graph import via born runtime

Choose a tag to compare

@linkerlin linkerlin released this 12 Jul 04:02

leaves v2.3.0

主题:完整 ONNX Graph 导入(复用 born 运行时,原列「明确不做」)。

Highlights

  1. io.LoadOnnxGraph:加载任意 ONNX 模型(30+ 算子,opset 1–21)——复用 github.com/born-ml/born/onnx 运行时,不在 leaves 重实现算子
  2. 双路径 ONNXLoadONNX(TreeEnsembleRegressor 子集,转 ForestIR,wasm 可用)+ LoadOnnxGraph(完整 Graph,born 运行时,非 wasm)互补。
  3. 化解 born API internal 泄漏:born 公共 onnx.Model 接口引用 internal/tensor.RawTensor,leaves 经 born/tensor.RawTensor 公共别名构造张量调用 Forward。

Usage

// 任意 ONNX 模型(NN / 通用图)
data, _ := os.ReadFile("model.onnx")
m, err := io.LoadOnnxGraph(data)
if err != nil { return err }
out, err := m.Predict([]float32{...}) // 单样本前向
fmt.Println(m.InputNames(), m.OutputNames(), m.OpsetVersion())

OnnxModel 接口:Predict([]float32) ([]float32, error) + InputNames/OutputNames/OpsetVersion。要求模型恰有 1 输入 / 1 输出(多输入输出需直接用 born onnx.ForwardNamed)。

Design notes

  • 复用而非重造:完整 ONNX 算子集(MatMul/Gemm/Conv/Softmax/…)是 born 的领域;leaves 作为 GBRT 库不重实现,直接桥接 born 运行时。
  • 平台取舍:born ONNX 运行时为 non-wasm。leaves 的 TreeEnsemble 子集路径仍 wasm 可用;通用 Graph 路径在 wasm 返回可操作错误(指向转 leaves.json)。
  • 既有路径不变LoadONNX(树模型子集)行为零变更;LoadOnnxGraph 是新增的并列 API。

Verification

  • TestLoadOnnxGraphRelu:用 leaves 自身 pb helpers 构造 Z=Relu(X) ONNX 图 → LoadOnnxGraphPredict → 断言 Relu([-1,0,2])=[0,0,2](端到端通)。
  • TestLoadOnnxGraphGarbage:非法字节返回错误不 panic。
  • io 全量、docs gate、build、6-linter 门禁全绿。

Compatibility

  • Breaking:无。新增 OnnxModel 接口与 LoadOnnxGraph 函数;既有 LoadONNX 不变。
  • 新增运行时依赖:LoadOnnxGraph 路径经 born(已在 go.mod);TreeEnsemble 子集与树/线性推理路径不触达新代码。

Recommended API

  • 树模型 ONNX(TreeEnsembleRegressor):LoadONNX(wasm 可用)
  • 通用 ONNX 图:LoadOnnxGraph(非 wasm)
  • XGB / LightGBM / leaves.json:LoadFromFile
  • 详见 docs/api-surface.mddocs/interop-matrix.md

v2.2.0: vector-leaf multi_output_tree training

Choose a tag to compare

@linkerlin linkerlin released this 11 Jul 23:42

leaves v2.2.0

主题:向量叶 multi_output_tree 训练(multi-target 一棵树、叶子为向量)。

Highlights

  1. 向量叶训练落地(原列「明确不做」):XGBoost multi_output_treesize_leaf_vector=num_groups)—— 每轮长一棵树,叶子为 numGroups 维向量;分裂增益跨输出组求和,叶权重逐类 -G_c/(H_c+λ)。此前仅推理/加载支持向量叶,训练只有 one_output_per_tree
  2. 统一 k 维 treebuilder:grad/hess [n*k]splitGain 跨类求和、leaf-major LeafValuek=1 退化为标量 —— 现有训练路径零回归(全量 golden 套件验证)。
  3. exact + hist 双路径都支持向量叶;Born/WebGPU 增益扫描对 k>1 回退纯 CPU(标量路径仍享加速)。

Usage

learner, _ := train.NewLearner(train.Config{
    Objective:       "multi:softprob", // 或 reg:squarederror + NumTarget>1
    NumClass:        5,                 // 多输出
    MultiOutputTree: true,              // ← 向量叶(默认 false = one_output_per_tree)
    NumRound:        50,
    TreeMethod:      "hist",
    // ...
})
learner.Fit(dm)

MultiOutputTree=true 时:每轮一棵 OutputDim=numGroups 的树;推理按 OutputDim scatter 到所有输出组(与加载的 XGBoost 向量叶模型一致)。NewLearner 校验:单输出目标开此选项会报错。

Design notes

  • 为何统一而非复制:把 treebuilder 数学参数化为 k,而非为向量叶复制一套并行代码 —— 更少代码、单一代码路径可测,k=1 由现有 golden 套件保证不变。
  • accel 取舍:Born/WebGPU 增益扫描当前为标量 kernel;向量叶(k>1)回退纯 CPU gain scan。正确优先,性能留信号再开(k=1 标量训练仍享 Born/WebGPU 加速)。

Verification

  • 确定性手算测试(4 样本×k=2:分裂点、leaf 向量、OutputDim 逐项断言)
  • 端到端多目标训练:每棵树 OutputDim=2、收敛(rmse<0.35)、leaves.json 往返保留 OutputDim
  • 单输出 + MultiOutputTree → NewLearner 报错
  • 全量回归:13 包 -short 全绿、6-linter 门禁 0 issues、race detector 无竞争

Compatibility

  • Breaking:无。MultiOutputTree 默认 false,现有 one_output_per_tree 行为完全不变。
  • 向量叶推理/加载/保存此前已支持,本版本补齐训练端到端闭环。

Recommended API

  • Infer:LoadFromFile + DefaultLoadOptions
  • Train:NewLearner(多输出可开 MultiOutputTree)/ LoadDataAuto / CLI leaves train
  • 详见 docs/api-surface.md

v2.1.6: data race + transformation panic fix; golangci-lint v2 gate

Choose a tag to compare

@linkerlin linkerlin released this 11 Jul 14:45

leaves v2.1.6

主题:并发 DATA RACE 与 transformation panic 修复;golangci-lint v2 门禁全量落地。

Highlights

  1. 修复并发 DATA RACEtreebuilder.parallelEvalHistFeats):多 goroutine 共享同一 row buffer 写入 Dense.Row(),race detector 首启即捕获;改为每 goroutine 独立 buffer。影响多线程 hist 训练正确性。
  2. 修复 transformation 数组越界 panicTransformType(Exponential).Name()transformNamesexponential 项而越界崩溃;TransformExponential.Name() 因此被绕成错报 "logistic"。加载 LightGBM exponential objective 模型时触发。
  3. golangci-lint v2 门禁全量 blockinggovet / ineffassign / unused / staticcheck / errcheck + gofmt formatter,6 项 0 issues 基线;附 race detector CI job。
  4. 死代码清除 ~360 行:unused linter 全清零(explain interventional SHAP、treebuilder 被取代的 GPU hist 旧路径、孤立 helper、永跳测试、失效 GoMLX 脚本、误入库产物)。
  5. 3 包从 0 测试覆盖transformation / predict / booster,+17 测试)、6 包补 doc.go、文档治理(维护期→开发期、版本一致性 gate)。

Fixed

  • treebuilder/hist_parallel.go:per-goroutine row buffer,消除 parallelEvalHistFeats 数据竞争。
  • transformation/transformation.go + exponential.go:补 transformNamesexponential 项;TransformExponential.Name() 返回正确名称。

CI / 工程

  • .golangci.yml(v2):6 项门禁全 blocking,基线 0 issues。
  • .github/workflows/ci.yml:新增 lintgolangci/golangci-lint-action@v6, v2.11.4)与 racego test -race -short)job。
  • 全仓 gofmt 归一(CRLF→LF + 对齐 + 1 处 composite literal 类型名简化)。

Compatibility

  • Breaking:无。
  • 推理 / 训练主路径行为不变;修复仅提升并发训练正确性与 exponential 模型加载健壮性。
  • 根包兼容层 LGEnsembleFromFile / XGEnsembleFromFile 仍委托可用。

Recommended API

  • Infer:LoadFromFile + DefaultLoadOptions
  • Train:NewLearner / LoadDataAuto / CLI leaves train
  • 详见 docs/api-surface.md

Docs

  • 维护期 → 开发期;演进计划 v5.4 / 演进方案 v1.5 版本引用全局一致(新增 TestDocVersionRefsConsistent gate)。
  • 6 个公共包补 doc.gotrain / explain / objective / metrics / mat / util

v2.1.5 — MovieLens four-stage prep→recall→rank→deal

Choose a tag to compare

@linkerlin linkerlin released this 11 Jul 09:20

leaves v2.1.5

主题:MovieLens 四段推荐流水线(prep → 召回 → LTR → 发牌)。

Highlights

  1. 真实数据四段recsys/movielens 纯 Go 加载 ml-100k → 四元 User/Item/Score/Tag + catalog 特征 + 片名旁车。
  2. 共用串联pipeline.RunFromDataset(合成 smoke 与 MovieLens 同一路径)。
  3. 入口齐全
    • go run ./recsys/cmd/movielens
    • go run ./demos/movielens/cmd/agent four-stage
    • MCP movielens_four_stage
  4. 召回 / 发牌加固:部分正样本 + 未交互补齐;deal.fillOverflow 可凑满 DeckSize。

Quick start

# Agent JSON
go run ./demos/movielens/cmd/agent four-stage
# 人类 CLI
go run ./recsys/cmd/movielens -workspace demos/movielens/out/fourstage
# 回归
go test ./recsys/pipeline/ -run TestMovieLensFourStage -count=1

首次需网络下载 ml-100k,或预置 .cache/ml-100k.zip

Compatibility

  • 库 API / CLI schema:无破坏
  • 精排-only(full-pipeline / ranking TSV)路径不变
  • Breaking:

Docs

v2.1.4 — MovieLens recommend titles + walkthrough

Choose a tag to compare

@linkerlin linkerlin released this 11 Jul 08:36

leaves v2.1.4

主题:MovieLens 推荐结果带片名(meta 旁车)+ 一键 walkthrough。

Highlights

  1. meta 旁车testdata/rank_movielens_*_meta.jsonlmovie_id / title / user_id),由 testdata/gen_rank_movielens.py 写出。
  2. 可读推荐agent recommend / cmd/recommend / MCP movielens_recommend 输出片名与 movie_id。
  3. 一键脚本demos/movielens/scripts/walkthrough.ps1 · .sh
  4. 教程同步TUTORIAL.md 示例 JSON 与故障表。

Quick start

.\demos\movielens\scripts\walkthrough.ps1
# 或仅推荐
go run ./demos/movielens/cmd/recommend -group 0 -topk 10
go run ./demos/movielens/cmd/agent recommend -group 0 -topk 5

Compatibility

  • 库 API / CLI schema:无破坏
  • meta 文件缺失时仍可推荐(仅 row/score/label;stderr 提示生成旁车)
  • Breaking:

Docs

v2.1.3 — MovieLens Ranker Agent/MCP demo

Choose a tag to compare

@linkerlin linkerlin released this 11 Jul 08:25

leaves v2.1.3

主题:MovieLens 推荐 Ranker 全流程 — Agent JSON CLI + MCP + 详尽教程。

Highlights

  1. Agent 契约 CLIgo run ./demos/movielens/cmd/agent(prepare → train → eval → recommend,stdout JSON)。
  2. MCP servergo run ./demos/movielens/cmd/mcp(stdio;movielens_status|prepare|train|eval|recommend|full_pipeline)。
  3. 教程demos/movielens/TUTORIAL.md(架构、数据、Shell/MCP、调参剧本、验收)。
  4. 案例数据:MovieLens 100K ranking TSV + XGB NDCG baseline。

Quick start

go run ./demos/movielens/cmd/agent full-pipeline
go test ./demos/movielens/agentops -count=1

MCP 配置示例见教程 §6。

Compatibility

  • 库 API / CLI schema:无破坏
  • MCP 为 demo 可选适配层(库核心仍不强制 MCP 运行时)
  • Breaking:

Docs

v2.1.2 — explain perf + serving template

Choose a tag to compare

@linkerlin linkerlin released this 11 Jul 08:06

leaves v2.1.2

主题:Explain 性能(LIB-22)、可拆 serving 模板(LIB-30)、文档/回归门禁加固。

Highlights

  1. Tree SHAP 更快、更少分配TreeExplainer 预计算节点覆盖权重与背景 margin,多样本复用 path 缓冲。
  2. Serving 脚手架examples/serving-template 可整目录复制为独立服务(非官方 serving 框架)。
  3. 质量门禁:sklearn 实验边界写实 + testdata-matrix.md 工件存在性测试。

Recommended API

  • Infer: LoadFromFile + DefaultLoadOptions
  • Explain: explain.NewTreeExplainer(forest).ShapleyValues(rows)
  • Embed HTTP: examples/http(最小)或 examples/serving-template(可拆仓)

Compatibility

  • SHAP 数值语义不变(既有 golden / 可加性测试仍绿)
  • metrics/CLI schema:无破坏schema_version 仍为 1
  • Breaking:

CI / 本地

go test ./explain -count=1
go test ./explain -bench=TreeSHAP -benchmem -count=1
go test ./examples/serving-template/... -count=1
go test ./docs -run 'TestdataMatrix|SkillsMirror' -count=1

Docs

v2.1.1 — Agent hardening + ONNX subset + multi-target

Choose a tag to compare

@linkerlin linkerlin released this 11 Jul 06:17

leaves v2.1.1

主题:v2.1.0 之后的 Agent 契约加固、ONNX TreeEnsemble 实验子集、多目标回归闭环。

Highlights

  1. Agent 契约门禁:skills 镜像 CI 哈希、--strict-flags/cv_conflict、错误码表、--print-repro--out-finaltrain_accel
  2. ONNX(实验):仅 TreeEnsembleRegressorBRANCH_LEQ / SUM / NONE);完整 Graph 仍不做。
  3. 多目标回归one_output_per_tree(API + CLI --num-target + predict/eval)。
  4. 示例examples/extensionexamples/multitargetdocs/bench 样例工件。

Recommended API

  • Infer: LoadFromFile + DefaultLoadOptions
  • Train: NewLearner / LoadDataAuto / CLI leaves train
  • Multi-target: data.NewMultiTargetDense + Config.NumTarget,或 leaves train --num-target N
  • ONNX 子集: io.LoadONNX / .onnx(实验)

Compatibility

  • metrics/CLI:只增字段train_accelfinal_modelnum_target 等);schema_version 仍为 1
  • ONNX:由占位升为实验子集(失败时仍给转换 hint)
  • Breaking:

CI

  • test (3 OS) / wasm ≤16MiB / bench-gate
  • skills mirror: go test ./docs -run TestSkillsMirrorSync

Docs

leaves v2.1.0

Choose a tag to compare

@linkerlin linkerlin released this 10 Jul 15:28

leaves v2.1.0

主题:Agent 可驱动的训练闭环契约收口,以及库稳定/平台化第一轮(扩展点、BackendAuto、互操作、发版治理)。

Highlights

  1. Agentic CLI(无 MCP):sniff → train → eval → inspect → explain → publish,JSON 契约 + SKILL 决策表。
  2. 定稿安全--early-stop 默认 --save-best,磁盘模型树数 = best_round
  3. 可复现:完备 params 账本、train --from-runpublish --emit-repro-scriptmanifest.reproduce
  4. BackendAuto 2.0:小批 Native、中大批 BornCPU、GPU 大批 BornGPU;规则可测可文档解释。
  5. 互操作写实:格式支持等级(稳定/实验/占位)+ 加载失败带 hint:
  6. 发版可勾选docs/release-checklist.md / api-surface / versioning

Recommended API

场景 入口
推理 LoadFromFile + DefaultLoadOptions()
训练 NewLearner / LoadDataAuto / NewLearnerFromModelAndData
Agent go run ./cmd/leaves … + skills/leaves-autotrain
后端 LoadOptions{Backend: BackendAuto, Workload: …} — 见 docs/backend-auto.md

兼容旧 API(LGEnsembleFromFile 等)仍可用,不作为新代码首发入口 — 见 docs/api-surface.md

Compatibility

  • AutoTransform 默认 true:logistic 等返回变换后值;raw margin 请设 AutoTransform: falseNOTES.md)。
  • BackendAuto:batch≥64 数值树倾向 BornCPU;batch=1 仍为 Native。
  • 破坏性:无删除稳定 API;metrics 字段只增不改义。
  • 实验:scikit-learn pickle;占位:ONNX(请先转 JSON/leaves)。

CLI(Agent)

go run ./cmd/leaves sniff --data train.csv --metrics sniff.json
go run ./cmd/leaves train --data train.csv --objective reg:squarederror --cv 5 `
  --runs runs.jsonl --tag baseline --out-model m.leaves.json --metrics metrics.json
go run ./cmd/leaves train --data train.csv --from-run runs.jsonl --tag baseline `
  --out-model final.leaves.json --metrics final.json
go run ./cmd/leaves publish --model final.leaves.json --out-dir release/ `
  --metrics final.json --quantize --export-xgb --emit-repro-script both

Docs

  • docs/api-surface.md — API 分层
  • docs/backend-auto.md — 后端决策表
  • docs/interop-matrix.md — 格式支持等级
  • docs/extension-points.md — 自定义 objective/metric
  • docs/release-checklist.md — 发版检查表
  • docs/versioning.md — v2.x 变更边界
  • 演进方案.md — Agentic DoD(已达成)
  • CHANGELOG.md — 变更列表

CI

  • go test ./...(3 OS)
  • WASM 体积 ≤16 MiB
  • Windows:batch=1 BornCPU ≥20× Native

Install

go get github.com/linkerlin/leaves@v2.1.0
#
go install github.com/linkerlin/leaves/cmd/leaves@v2.1.0

(需 tag 推送后模块代理可见。)