From 9f9826bba600a86d20b9e200d28c3f7f2bf3d29e Mon Sep 17 00:00:00 2001 From: Michal Harakal <471011+michalharakal@users.noreply.github.com> Date: Sat, 7 Nov 2026 09:59:43 +0100 Subject: [PATCH 1/2] fix(lfm2): import the BOM as api so the published POM carries versions lfm2 declares skainet-lang-core and skainet-backend-cpu as api but imported the transformers BOM only as implementation, so the jvm POM listed both at compile scope without a version and Maven Central rejected the 0.64.0 deployment. With the BOM as api the POM imports it in dependencyManagement; all 229 generated POMs now resolve every dependency version. Co-Authored-By: Claude Opus 5.5 --- llm-inference/lfm2/build.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llm-inference/lfm2/build.gradle.kts b/llm-inference/lfm2/build.gradle.kts index 4df7c04a..3ac45a62 100644 --- a/llm-inference/lfm2/build.gradle.kts +++ b/llm-inference/lfm2/build.gradle.kts @@ -17,7 +17,8 @@ kotlin { jvm() sourceSets { commonMain.dependencies { - implementation(project.dependencies.platform(project(":llm-bom"))) + // api, not implementation: the api dependencies below take their versions from it in the POM. + api(project.dependencies.platform(project(":llm-bom"))) api(libs.skainet.lang.core) api(libs.skainet.backend.cpu) api(libs.kotlinx.serialization.json) From fec239367967958b1a78d1c421cc4bdeb36c9c9c Mon Sep 17 00:00:00 2001 From: Michal Harakal <471011+michalharakal@users.noreply.github.com> Date: Sat, 7 Nov 2026 10:00:01 +0100 Subject: [PATCH 2/2] release: prepare 0.64.1 -- the 0.64.0 content with a publishable lfm2 POM, against engine 0.63.0 Version 0.64.1 in gradle.properties, the README release paragraph and the BOM snippets in README and docs. CHANGELOG 0.64.1: the POM fix, and the note that Maven Central refused 0.64.0, which was never published. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 11 +++++++++++ README.md | 4 ++-- .../pages/how-to/export-moonshine-v2-streaming.adoc | 2 +- .../ROOT/pages/reference/moonshine-encoder.adoc | 2 +- .../modules/ROOT/pages/reference/typed-decisions.adoc | 2 +- .../ROOT/pages/tutorials/android-getting-started.adoc | 2 +- .../ROOT/pages/tutorials/getting-started-java.adoc | 4 ++-- .../ROOT/pages/tutorials/getting-started-leaf.adoc | 2 +- .../ROOT/pages/tutorials/llama3-tool-calling.adoc | 2 +- gradle.properties | 2 +- 10 files changed, 22 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a23e68aa..d77ef1cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,17 @@ requiring an engine release. `0.57.1` against engine `0.57.0` is such a release. The format roughly follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.64.1] — 2026-11-07 + +Against engine **0.63.0**. A packaging fix: Maven Central refused the 0.64.0 deployment, so **0.64.0 was never +published** and its content (below) ships with this release. + +### Fixed + +- `skainet-transformers-inference-lfm2` imports the BOM as `api`: it declares `skainet-lang-core` and + `skainet-backend-cpu` as `api` dependencies, and with the BOM only as `implementation` its POM listed both without a + version, which Central rejects. + ## [0.64.0] — 2026-11-06 Against engine **0.63.0** (block-quantized weights through StableHLO export: SKaiNET#1478 and SKaiNET#1479, plus diff --git a/README.md b/README.md index 2e08e14e..0f78f172 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ Honest status — see the project-status note at the top of this README. ## Current release -The current release is **0.64.0**, against **SKaiNET 0.63.0**: `DecodeStepExport` (`llm-core`) traces one single-token step of any KV-cache decoder with a static past and keeps Q8_0 / Q4_0 weights packed for the engine's block-quant matmul fusion, so FunctionGemma 270M's decode step compiles to one dispatch on the Torq NPU of an SL2610 (162 ms per step, same top-1 as the f32 reference); the with-past types (`RopeCosSin`, `ChunkContext`, `KvStepOutput`) are shared by Gemma and the generic KV decoder in `sk.ainet.lang.nn.dsl.decoder`. LFM2 arrives as `llm-inference:lfm2` (dense hybrid short-conv + GQA model, verified checkpoint loading, fixed-shape StableHLO export) and the `llm-runtime:klfm2` chat frontend. 0.63.3 let the streaming Moonshine runtime hand the decoder to an external native library too (`ext:|` as the prefill path), so with 0.63.2's external encoder the whole model can run on an accelerator outside IREE while the runtime keeps the streaming loop, greedy decoding and its guards. 0.63.2 handed the encoder side to an external library (`ext:` as the encoder path) while the decoder stays on the IREE device. 0.63.1 gave the streaming Moonshine runtime an incremental frontend (an optional `frontend_step.vmfb` takes most of the frontend out of the end-of-utterance flush, transcripts unchanged) and `IreeModuleRunner` runs one compiled IREE module on Android. 0.63.0 brought expert heads and routing for Laya — a decision head fine-tuned on top of the frozen encoder (`expert.safetensors` + `expert.json`) loads on its own with `LayaExpertLoader`, any number of heads share one encoder pass per question (`LayaDecisionModel.logitsFrom`), `LayaRouterSpec` + `LayaMixtureAgent` route a request by asking the base head what kind of text it is, and `LayaMixtureDecisionAdapter` puts the mixture behind the typed decision contract; verified against the published layaMOE evaluation. The ModernBERT-large `laya-typed-decisions` checkpoint loads (`position_embedding_type: absolute`). The whisper StableHLO export ships as `WhisperExportCli`. Engine 0.62.0 brings the JVM ↔ Kotlin/Wasm parity: every kernel on the wasm tier, resident activations, fused attention / norms / softmax, browser IO parity. The Laya Q8_0 lane on the desktop JVM with the native provider needs engine 0.62.1 (SKaiNET #1436). +The current release is **0.64.1**, against **SKaiNET 0.63.0**: a packaging fix: Maven Central refused 0.64.0 (the `skainet-transformers-inference-lfm2` POM lacked dependency versions), so 0.64.0 was never published and its content ships here. `DecodeStepExport` (`llm-core`) traces one single-token step of any KV-cache decoder with a static past and keeps Q8_0 / Q4_0 weights packed for the engine's block-quant matmul fusion, so FunctionGemma 270M's decode step compiles to one dispatch on the Torq NPU of an SL2610 (162 ms per step, same top-1 as the f32 reference); the with-past types (`RopeCosSin`, `ChunkContext`, `KvStepOutput`) are shared by Gemma and the generic KV decoder in `sk.ainet.lang.nn.dsl.decoder`. LFM2 arrives as `llm-inference:lfm2` (dense hybrid short-conv + GQA model, verified checkpoint loading, fixed-shape StableHLO export) and the `llm-runtime:klfm2` chat frontend. 0.63.3 let the streaming Moonshine runtime hand the decoder to an external native library too (`ext:|` as the prefill path), so with 0.63.2's external encoder the whole model can run on an accelerator outside IREE while the runtime keeps the streaming loop, greedy decoding and its guards. 0.63.2 handed the encoder side to an external library (`ext:` as the encoder path) while the decoder stays on the IREE device. 0.63.1 gave the streaming Moonshine runtime an incremental frontend (an optional `frontend_step.vmfb` takes most of the frontend out of the end-of-utterance flush, transcripts unchanged) and `IreeModuleRunner` runs one compiled IREE module on Android. 0.63.0 brought expert heads and routing for Laya — a decision head fine-tuned on top of the frozen encoder (`expert.safetensors` + `expert.json`) loads on its own with `LayaExpertLoader`, any number of heads share one encoder pass per question (`LayaDecisionModel.logitsFrom`), `LayaRouterSpec` + `LayaMixtureAgent` route a request by asking the base head what kind of text it is, and `LayaMixtureDecisionAdapter` puts the mixture behind the typed decision contract; verified against the published layaMOE evaluation. The ModernBERT-large `laya-typed-decisions` checkpoint loads (`position_embedding_type: absolute`). The whisper StableHLO export ships as `WhisperExportCli`. Engine 0.62.0 brings the JVM ↔ Kotlin/Wasm parity: every kernel on the wasm tier, resident activations, fused attention / norms / softmax, browser IO parity. The Laya Q8_0 lane on the desktop JVM with the native provider needs engine 0.62.1 (SKaiNET #1436). It builds on **0.62.2**, against **SKaiNET 0.61.0**: a transformers-only fix, the Android runtime's streaming Moonshine libraries are rebuilt with the utterance-start fix (#500; 0.62.0 and 0.62.1 packed the old build, which garbles transcripts on device). It builds on **0.62.1**, a transformers-only fix on 0.62.0, whose JVM `LayaModelLoader.load(directory, …)` had become an extension function that existing callers did not import; it is a member again (`@JvmOverloads`, so Java callers keep the 0.61 signature). @@ -305,7 +305,7 @@ The recommended way to consume is via the BOM. It pins every published `skainet- ```kotlin dependencies { - implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.0")) + implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.1")) // Versions resolved from the BOM: implementation("sk.ainet.transformers:skainet-transformers-core") diff --git a/docs/modules/ROOT/pages/how-to/export-moonshine-v2-streaming.adoc b/docs/modules/ROOT/pages/how-to/export-moonshine-v2-streaming.adoc index cc045e9a..fca223fb 100644 --- a/docs/modules/ROOT/pages/how-to/export-moonshine-v2-streaming.adoc +++ b/docs/modules/ROOT/pages/how-to/export-moonshine-v2-streaming.adoc @@ -32,7 +32,7 @@ From your own build, resolve the published module and run its main class: ---- val exportTool by configurations.creating dependencies { - exportTool(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.0")) + exportTool(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.1")) exportTool("sk.ainet.transformers:skainet-transformers-inference-moonshine") } tasks.register("exportMoonshine") { diff --git a/docs/modules/ROOT/pages/reference/moonshine-encoder.adoc b/docs/modules/ROOT/pages/reference/moonshine-encoder.adoc index 864a263f..e79ed59a 100644 --- a/docs/modules/ROOT/pages/reference/moonshine-encoder.adoc +++ b/docs/modules/ROOT/pages/reference/moonshine-encoder.adoc @@ -24,7 +24,7 @@ a DSL decoder is future work. [source,kotlin] ---- dependencies { - implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.0")) + implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.1")) implementation("sk.ainet.transformers:skainet-transformers-inference-moonshine") } ---- diff --git a/docs/modules/ROOT/pages/reference/typed-decisions.adoc b/docs/modules/ROOT/pages/reference/typed-decisions.adoc index 0e35bb9a..00f51045 100644 --- a/docs/modules/ROOT/pages/reference/typed-decisions.adoc +++ b/docs/modules/ROOT/pages/reference/typed-decisions.adoc @@ -12,7 +12,7 @@ below put that on the JVM path with the same contract for every model. [source,kotlin] ---- dependencies { - implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.0")) + implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.1")) implementation("sk.ainet.transformers:skainet-transformers-decisions-api") // the contract, no engine dependency implementation("sk.ainet.transformers:skainet-transformers-decisions-runtime") // validation + acceptance policy implementation("sk.ainet.transformers:skainet-transformers-inference-laya") // Laya as a DecisionAdapter diff --git a/docs/modules/ROOT/pages/tutorials/android-getting-started.adoc b/docs/modules/ROOT/pages/tutorials/android-getting-started.adoc index 48cb4918..e8d514a0 100644 --- a/docs/modules/ROOT/pages/tutorials/android-getting-started.adoc +++ b/docs/modules/ROOT/pages/tutorials/android-getting-started.adoc @@ -55,7 +55,7 @@ dependencies { // self-registers it on ART at process start — nothing to call. runtimeOnly("sk.ainet.core:skainet-backend-jni-cpu") - implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.0")) + implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.1")) implementation("sk.ainet.transformers:skainet-transformers-core") implementation("sk.ainet.transformers:skainet-transformers-runtime-kllama") implementation("sk.ainet.transformers:skainet-transformers-inference-llama") diff --git a/docs/modules/ROOT/pages/tutorials/getting-started-java.adoc b/docs/modules/ROOT/pages/tutorials/getting-started-java.adoc index afb71b10..fd7eb364 100644 --- a/docs/modules/ROOT/pages/tutorials/getting-started-java.adoc +++ b/docs/modules/ROOT/pages/tutorials/getting-started-java.adoc @@ -25,7 +25,7 @@ In your `build.gradle.kts`: [source,kotlin] ---- dependencies { - implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.0")) + implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.1")) implementation("sk.ainet.transformers:skainet-transformers-runtime-kllama") implementation("sk.ainet.transformers:skainet-transformers-agent") @@ -41,7 +41,7 @@ Or in Maven (Maven needs the `-jvm` classifier suffix on platform artifacts): sk.ainet.transformers skainet-transformers-bom - 0.64.0 + 0.64.1 pom import diff --git a/docs/modules/ROOT/pages/tutorials/getting-started-leaf.adoc b/docs/modules/ROOT/pages/tutorials/getting-started-leaf.adoc index 90b3b82b..24fc4a73 100644 --- a/docs/modules/ROOT/pages/tutorials/getting-started-leaf.adoc +++ b/docs/modules/ROOT/pages/tutorials/getting-started-leaf.adoc @@ -34,7 +34,7 @@ encoder output to the advertised dimensionality. The runtime applies it automati [source,kotlin] ---- dependencies { - implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.0")) + implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.1")) implementation("sk.ainet.transformers:skainet-transformers-providers") } ---- diff --git a/docs/modules/ROOT/pages/tutorials/llama3-tool-calling.adoc b/docs/modules/ROOT/pages/tutorials/llama3-tool-calling.adoc index 9654d325..f4164a59 100644 --- a/docs/modules/ROOT/pages/tutorials/llama3-tool-calling.adoc +++ b/docs/modules/ROOT/pages/tutorials/llama3-tool-calling.adoc @@ -52,7 +52,7 @@ The pieces you need live in three modules: [source,kotlin] ---- dependencies { - implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.0")) + implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.64.1")) implementation("sk.ainet.transformers:skainet-transformers-runtime-kllama") implementation("sk.ainet.transformers:skainet-transformers-agent") diff --git a/gradle.properties b/gradle.properties index 9cff65d6..119b53aa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ GROUP=sk.ainet.transformers -VERSION_NAME=0.64.0 +VERSION_NAME=0.64.1 POM_DESCRIPTION=SKaiNET-transformers