Skip to content

Commit a49fe30

Browse files
Merge pull request #186 from SKaiNET-developers/release/0.31.1
Release 0.31.1 — transformer-core + publish guardrail
2 parents 6c548d7 + e6da5dc commit a49fe30

8 files changed

Lines changed: 75 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,33 @@ version line is kept in lock-step with the underlying SKaiNET engine
77
The format roughly follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
88
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
99

10+
## [0.31.1] — 2026-06-17
11+
12+
Adds **`transformer-core`** — the framework NN primitives (attention, the KV-cache family, embedding,
13+
norms, RoPE, SwiGLU/GeGLU FFN, residual, linear projection) extracted from `llm-core` so they build on the
14+
**full Kotlin target matrix including `androidNative`** (32-bit + 64-bit ARM). `llm-core` re-exports it, so
15+
existing consumers are unaffected; ARM-native downstreams (e.g. on-device whisper) can now reuse the
16+
primitives instead of reimplementing them.
17+
18+
### Added
19+
20+
- **`transformer-core` module** (`sk.ainet.transformers:skainet-transformers-transformer-core`) — the
21+
lang-core-only NN primitives, reusable on every target incl. `androidNativeArm32`/`androidNativeArm64`.
22+
Depends only on `skainet-lang-core`. Added to the BOM. (#183)
23+
24+
### Changed
25+
26+
- **`llm-core` now `api`-depends on `transformer-core` and re-exports it** (no behaviour change). The NN
27+
primitive sources moved out of `llm-core` into `transformer-core`; `dsl/decoder/*` stayed (it needs the
28+
compile-opt-coupled `HybridTransformerBlock`). `MultiHeadAttention`'s diagnostic `dumpStats` is decoupled
29+
via a settable `mhaStatSink` that `HybridTransformerBlock` wires to llm-core's platform `dumpStats`.
30+
31+
### Notes
32+
33+
- **Engine pin unchanged (`skainet = 0.31.0`).** `transformer-core` needs nothing new from the engine (only
34+
`skainet-lang-core`, already in 0.31.0), so this patch ships against engine **0.31.0** — the one case the
35+
transformers-`X.Y.Z` ↔ engine-`X.Y.Z` alignment is intentionally relaxed (additive + engine-independent).
36+
1037
## [0.31.0] — 2026-06-15
1138

1239
Version-aligned with **SKaiNET 0.31.0**. Completes the eager board-decode path

README.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,13 @@ Honest status — see the project-status note at the top of this README.
103103

104104
## Current release
105105

106-
The current release is **0.31.0** — version-aligned with **SKaiNET 0.31.0**.
107-
The headline is that the eager `NATIVE_OPTIMIZED` Gemma path now keeps the
106+
The current release is **0.31.1** (against **SKaiNET 0.31.0**). It adds
107+
**`transformer-core`** — the framework NN primitives (attention, KV-cache family,
108+
embedding, norms, RoPE, FFNs, linear projection) extracted out of `llm-core` so they
109+
build on the **full target matrix including `androidNative`** (32-bit + 64-bit ARM);
110+
`llm-core` re-exports it, so nothing changes for existing consumers, and ARM-native
111+
downstreams (e.g. on-device whisper) can reuse the primitives instead of reimplementing
112+
them. The 0.31.0 highlights still apply: the eager `NATIVE_OPTIMIZED` Gemma path keeps the
108113
**tied Q8_0 lm_head packed** (paired with SKaiNET 0.31.0's `ops.transpose` fix
109114
for all packed dtypes), and `GemmaNetworkLoader.load()` takes an optional
110115
`maxInferenceLen` to cap the KV cache for constrained devices — together
@@ -116,7 +121,7 @@ The recommended way to consume is via the BOM. It pins every published `skainet-
116121

117122
```kotlin
118123
dependencies {
119-
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.31.0"))
124+
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.31.1"))
120125

121126
// Versions resolved from the BOM:
122127
implementation("sk.ainet.transformers:skainet-transformers-core")
@@ -141,6 +146,7 @@ dependencies {
141146
| Module | Purpose |
142147
| -------------------- | ----------------------------------------------------------------------- |
143148
| `llm-api` | Framework-neutral interfaces (`ChatModel`, `EmbeddingModel`, `ToolDefinition`) — Spring AI-shaped. |
149+
| `transformer-core` | Framework NN primitives (attention, KV-cache family, embedding, norms, RoPE, FFNs, linear projection). `lang-core`-only → **all targets incl. `androidNative`**; re-exported by `llm-core`. |
144150
| `llm-core` | `OptimizedLLMRuntime`, `ModelRegistry`, `UnifiedModelLoader`, shared abstractions. |
145151
| `llm-inference/<arch>` | Per-architecture network DSLs and weight loaders (`llama`, `gemma`, `qwen`, `apertus`, `bert`). |
146152
| `llm-runtime/<arch>` | Per-architecture runtime facades (`kllama`, `kgemma`, `kqwen`, `kapertus`). |
@@ -193,6 +199,15 @@ try (KLlamaSession session = KLlamaJava.loadGGUF(modelPath, /* systemPrompt */ n
193199

194200
See `llm-test/llm-test-java/src/test/java/.../KLlamaJavaToolCallingTest.java` for a runnable reference.
195201

202+
## What's new in 0.31.1
203+
204+
- **`transformer-core` module — NN primitives reusable on all targets incl. `androidNative`.** The
205+
attention / KV-cache / embedding / norm / RoPE / FFN / linear-projection primitives were trapped in
206+
`llm-core` (whose io/compile/backend deps lack `androidNative`); they only need `skainet-lang-core`
207+
(which has it), so they're extracted into `transformer-core` and `llm-core` re-exports them. Existing
208+
consumers are unaffected; ARM-native downstreams (on-device whisper, future models) reuse them instead of
209+
reimplementing. Ships against engine **0.31.0** (additive, no engine change). (#183)
210+
196211
## What's new in 0.31.0
197212

198213
- **Tied Q8_0 lm_head stays packed (eager `NATIVE_OPTIMIZED`).** FunctionGemma's

buildSrc/src/main/kotlin/sk/ainet/transformers/gradle/BomCoveragePlugin.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,28 @@ class BomCoveragePlugin : Plugin<Project> {
3737
)
3838
}
3939

40+
// Fail fast (at configuration time, not at Maven Central deploy time) when a NEW published
41+
// module forgot its gradle.properties. Without POM_ARTIFACT_ID the artifact silently defaults
42+
// to the bare project name (wrong coordinates / not the skainet-transformers-* convention);
43+
// without POM_NAME, Maven Central rejects the deploy. This recurs on every new module — catch it.
44+
val pomProblems = publishedPaths.mapNotNull { path ->
45+
val p = project.project(path)
46+
val missing = buildList {
47+
if (p.findProperty("POM_ARTIFACT_ID")?.toString().isNullOrBlank()) add("POM_ARTIFACT_ID")
48+
if (p.findProperty("POM_NAME")?.toString().isNullOrBlank()) add("POM_NAME")
49+
}
50+
if (missing.isEmpty()) null else "$path — missing ${missing.joinToString(" + ")}"
51+
}
52+
if (pomProblems.isNotEmpty()) {
53+
throw GradleException(
54+
"[bom-coverage] Published module(s) are missing required POM properties — the Maven " +
55+
"Central deploy would fail:\n" +
56+
pomProblems.joinToString("\n") { " - $it" } +
57+
"\nAdd a `gradle.properties` to each module with POM_ARTIFACT_ID + POM_NAME " +
58+
"(see `llm-core/gradle.properties`)."
59+
)
60+
}
61+
4062
project.dependencies.constraints {
4163
publishedPaths.forEach { add("api", project.project(it)) }
4264
}

docs/modules/ROOT/pages/reference/architecture.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
== Module Structure
55

66
----
7-
llm-core Core abstractions (Tokenizer, InferenceRuntime, ModelRegistry)
7+
transformer-core NN primitives (attention, KV-cache, embedding, norms, RoPE, FFNs) — all targets incl. androidNative
8+
llm-core Core abstractions (Tokenizer, InferenceRuntime, ModelRegistry); re-exports transformer-core
89
llm-agent Chat templates, tool calling, AgentLoop, ChatSession
910
llm-inference/
1011
llama/ LLaMA/Qwen network definition and weight loading

docs/modules/ROOT/pages/tutorials/getting-started-java.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ In your `build.gradle.kts`:
2525
[source,kotlin]
2626
----
2727
dependencies {
28-
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.31.0"))
28+
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.31.1"))
2929
3030
implementation("sk.ainet.transformers:skainet-transformers-runtime-kllama")
3131
implementation("sk.ainet.transformers:skainet-transformers-agent")
@@ -41,7 +41,7 @@ Or in Maven (Maven needs the `-jvm` classifier suffix on platform artifacts):
4141
<dependency>
4242
<groupId>sk.ainet.transformers</groupId>
4343
<artifactId>skainet-transformers-bom</artifactId>
44-
<version>0.31.0</version>
44+
<version>0.31.1</version>
4545
<type>pom</type>
4646
<scope>import</scope>
4747
</dependency>

docs/modules/ROOT/pages/tutorials/llama3-tool-calling.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ The pieces you need live in three modules:
5252
[source,kotlin]
5353
----
5454
dependencies {
55-
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.31.0"))
55+
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.31.1"))
5656
5757
implementation("sk.ainet.transformers:skainet-transformers-runtime-kllama")
5858
implementation("sk.ainet.transformers:skainet-transformers-agent")

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
GROUP=sk.ainet.transformers
2-
VERSION_NAME=0.31.0
2+
VERSION_NAME=0.31.1
33

44
POM_DESCRIPTION=SKaiNET-transformers
55

transformer-core/gradle.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
POM_ARTIFACT_ID=skainet-transformers-transformer-core
2+
POM_NAME=skainet transformers transformer-core

0 commit comments

Comments
 (0)