Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

Against engine **0.61.0** (SKEEP-007, the browser lane). The BOM re-exports `skainet-bom:0.61.0`.
Engine 0.61.0 removed its SKEEP-006 compatibility aliases as scheduled; nothing here referenced them.
## [0.62.0] — 2026-10-17

**Laya on the packed Q8_0 lane.** Against engine **0.61.0** (SKEEP-007, the browser lane:
quantize-at-load for the SafeTensors and GGUF loaders, the `skainet-backend-wasm-simd` SIMD128
sidecar, packed-weight dispatch order). The Laya loader is common code over a `RandomAccessSource`,
and `LayaWeightForms.q8_0For` quantizes the encoder and head projections and the token table to
Q8_0 at load — about a quarter of the FP32 bytes, served by the packed kernels on every tier. A
decision-quality gate (every fixture choice agrees with FP32, no value shifts by more than 0.05,
measured 0.035) is the contract of that lane. The BOM re-exports `skainet-bom:0.61.0`. Engine
0.61.0 removed its SKEEP-006 compatibility aliases as scheduled; nothing here referenced them. The
transformers SKEEP-006 schedule moves by one more minor (see *Deprecated*).

### Added

- **Laya on the packed Q8_0 lane** (SKEEP-007 Tier 2 consumer). `LayaModelLoader.load` is common code: the four side files as text plus a `RandomAccessSource` for `model.safetensors`, so the JVM, Android and browser builds share one loader; the JVM `load(directory: Path, …)` is now an extension over it (source-compatible). `weightForm` / `weightFormFor` pass through to the engine's SafeTensors loader, and `LayaWeightForms.q8_0For` quantizes the encoder and head projections and the 256k × 768 token table to Q8_0 at load — about a quarter of the FP32 bytes, served by the packed kernels on every tier. `LayaWeightPreparation` splits the fused `Wqkv` / `Wi` / `in_proj` matrices in their packed form (row blocks are contiguous byte ranges) and wraps the token table as a `PackedRowDequantTensorData`, so the embedding reads rows on demand.
- **Decision-quality gate for the quantized lane**: `LayaQuantizedParityTest` (model-gated) requires every `predict.json` choice of the Q8_0 agent to agree with the FP32 agent's and no probability, score, noul value or confidence to shift by more than 0.05 (`LAYA_Q8_TOL`; measured 2026-10-16 on the multilingual checkpoint: 5/5 choices agree, 45 values, max shift 0.035). FP32 parity (1.5e-4) remains the contract of the reference lane. On the eager JVM path the Q8_0 lane is a memory measure, not a speed one — the row-major packed kernels run one activation row at a time, so the six fixture cases take 173 s against 69 s in FP32 on a 12-core laptop; the speed comes with the browser sidecar and the compiled lane.

### Changed

- **Engine 0.61.0.** The version catalog moves `sk.ainet.core:*` to 0.61.0; the new
`skainet-backend-wasm-simd` module is available to browser builds through the engine BOM.

### Deprecated

- **Schedule moved by one more minor.** The SKEEP-006 legacy surface (`GGUFTokenizer` and its
strategies, `TokenizerType`, `SentencePieceSpecialTokens`, `TekkenTokenizerAdapter`, `ModelRegistry`,
the `sk.ainet.apps.kllama.GGUFTokenizer` alias) stays at WARNING in 0.62, goes to ERROR in 0.63
and leaves in 0.64; `TokenizerFactory` and the `sk.ainet.apps.llm.Tokenizer` sub-interface are
deprecated in 0.63 and removed in 0.64. This release carries the engine bump and the quantized
Laya lane; the runtimes, CLIs and benchmarks still reach the engine through the factory, and that
migration stays a release of its own.

## [0.61.0] — 2026-10-16

**Padded batches for the encoders.** Against engine **0.60.0**, which gives
`scaledDotProductAttention` key lengths, a window and a right context carried as op metadata
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,11 @@ Honest status — see the project-status note at the top of this README.

## Current release

The current release is **0.61.0**, against **SKaiNET 0.60.0**.
The current release is **0.62.0**, against **SKaiNET 0.61.0**.

**Laya on the packed Q8_0 lane.** SKaiNET 0.61.0 (SKEEP-007, the browser lane) brings quantize-at-load for the SafeTensors and GGUF loaders, a SIMD128 kernel sidecar for browser builds and the packed-weight dispatch order. The Laya loader is common code over a `RandomAccessSource`, so the JVM, Android and browser builds share one loader, and `LayaWeightForms.q8_0For` quantizes the encoder and head projections and the 256k × 768 token table to Q8_0 at load — about a quarter of the FP32 bytes, served by the packed kernels on every tier. The lane is gated on decision quality: every `predict.json` choice agrees with FP32 and no value shifts by more than 0.05 (measured 0.035, 5/5 choices). FP32 parity stays the contract of the reference lane.

It builds on **0.61.0**, against **SKaiNET 0.60.0**:

**Padded batches for the encoders.** SKaiNET 0.60.0 gives `scaledDotProductAttention` key lengths, a window and a right context carried as op metadata (`maskKind`), with a `skainet.sdpa` composite for targets that have a fused attention kernel. BERT-class encoders and the Laya decision models run the sequences of one request as right-padded batches (#490): `BertEncoderRuntime.encodeBatch` / `encodePadded`, `LayaDecisionModel.logitsBatch`, the Laya adapter with `batchSupport = true`. One attention node per layer takes the batch's lengths instead of a dense mask, so the compiled path gets the lengths as a graph input. The multilingual predict fixtures reproduce through the batched path (55 values, max |diff| 4.99e-5) and batched and single logits agree within 1.9e-6. On the eager FP32 CPU path a batch saves about 10 % per question at best; the gain is for the compiled lane and accelerators. The SKEEP-006 legacy tokenizer surface stays at WARNING in 0.61; the schedule moves by one more minor (ERROR in 0.62, gone in 0.63).

Expand Down Expand Up @@ -295,7 +299,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.61.0"))
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.62.0"))

// Versions resolved from the BOM:
implementation("sk.ainet.transformers:skainet-transformers-core")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.61.0"))
exportTool(platform("sk.ainet.transformers:skainet-transformers-bom:0.62.0"))
exportTool("sk.ainet.transformers:skainet-transformers-inference-moonshine")
}
tasks.register<JavaExec>("exportMoonshine") {
Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/reference/moonshine-encoder.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ a DSL decoder is future work.
[source,kotlin]
----
dependencies {
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.61.0"))
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.62.0"))
implementation("sk.ainet.transformers:skainet-transformers-inference-moonshine")
}
----
Expand Down
4 changes: 2 additions & 2 deletions docs/modules/ROOT/pages/reference/tokenizer-api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ descriptor with `+`. `GGUFModelInfo.identity` is the string identity
|===

`HuggingFaceBPETokenizer` (no callers since 0.58) was removed in 0.59.0. The schedule for the
rest moved by one minor in 0.59.0, in 0.60.0 and again in 0.61.0: the legacy classes stay at
WARNING through 0.61, go to ERROR in 0.62 and leave in 0.63, because the runtimes, CLIs and
rest moved by one minor in 0.59.0, 0.60.0, 0.61.0 and again in 0.62.0: the legacy classes stay at
WARNING through 0.62, go to ERROR in 0.63 and leave in 0.64, because the runtimes, CLIs and
benchmarks still reach the engine through `TokenizerFactory` and the sub-interface, and moving
them is a release of its own. The engine's io-core aliases they wrapped are errors since
SKaiNET 0.60.0; new code imports the `sk.ainet.frontend.tokenizer` home directly.
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/reference/typed-decisions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.61.0"))
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.62.0"))
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.61.0"))
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.62.0"))
implementation("sk.ainet.transformers:skainet-transformers-core")
implementation("sk.ainet.transformers:skainet-transformers-runtime-kllama")
implementation("sk.ainet.transformers:skainet-transformers-inference-llama")
Expand Down
4 changes: 2 additions & 2 deletions docs/modules/ROOT/pages/tutorials/getting-started-java.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ In your `build.gradle.kts`:
[source,kotlin]
----
dependencies {
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.61.0"))
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.62.0"))

implementation("sk.ainet.transformers:skainet-transformers-runtime-kllama")
implementation("sk.ainet.transformers:skainet-transformers-agent")
Expand All @@ -41,7 +41,7 @@ Or in Maven (Maven needs the `-jvm` classifier suffix on platform artifacts):
<dependency>
<groupId>sk.ainet.transformers</groupId>
<artifactId>skainet-transformers-bom</artifactId>
<version>0.61.0</version>
<version>0.62.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.61.0"))
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.62.0"))
implementation("sk.ainet.transformers:skainet-transformers-providers")
}
----
Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/tutorials/llama3-tool-calling.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ The pieces you need live in three modules:
[source,kotlin]
----
dependencies {
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.61.0"))
implementation(platform("sk.ainet.transformers:skainet-transformers-bom:0.62.0"))

implementation("sk.ainet.transformers:skainet-transformers-runtime-kllama")
implementation("sk.ainet.transformers:skainet-transformers-agent")
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GROUP=sk.ainet.transformers
VERSION_NAME=0.61.0
VERSION_NAME=0.62.0

POM_DESCRIPTION=SKaiNET-transformers

Expand Down
Loading