Repository navigation
feat(SemanticEmojiFilter): embedding filter with a Laya decision verifier - #37
Merged
Merged
Conversation
…fier New example: a Compose Multiplatform app (Android, Desktop, Web) that ranks 208 emoji by the meaning of a typed query with on-device sentence embeddings, and an opt-in second stage on Desktop/Android where the Laya decision model re-checks the top hits through sk.ainet.decisions. System 1: MongoDB LEAF (mdbr-leaf-ir, Apache-2.0) on the SKaiNET-transformers BERT runtime — engine WordPiece tokenizer, mean pooling, 2_Dense projection to 768-d, L2; the query carries LEAF's retrieval prompt. Catalog embeddings are computed once (shipped precomputed for wasm); the sweep is a dot product. Calibrated logistic confidence (balanced fit, F1-optimal threshold), top tier capped at 12. Debounced 120 ms, mapLatest. System 2 (-PlayaVerifier=true, transformers 0.59.0 / 0.59.0-SNAPSHOT from mavenLocal): one BooleanProbability question per candidate, one request per item so every decision is a cancellation point, verdicts stream into the badges, "?" for an abstention. Policy: reject below 0.2, accept from 0.6 (the base checkpoint is conservative). The model source is one interface (DecisionAdapterSource) a decision cartridge can replace later. Catalog from CLDR 47 annotations (en + de) via scripts/generate-catalog.py and a curated selection; LEAF fetched by scripts/fetch-model.sh into the wasm Compose resources only. CLI: bench | embed-catalog | calibrate | golden | query | tokens | verify. Measured numbers in the README. Tests: shared 11 (jvm + Android host), verifier 2. CI workflow mirrors KernelRace. No iOS (bert, laya and decisions publish no Apple targets).
…nore excludes *.jar)
…erifier in CI The decisions and laya coordinates move under the BOM, the mavenLocal gate goes, and the CI workflow builds and tests the verifier module behind -PlayaVerifier=true.
michalharakal
marked this pull request as ready for review
October 13, 2026 21:32
Engine 0.59.0 adds erf and gelu(approximate) as op metadata; transformers 0.60.0 runs the Laya verifier's exact GELU through that op instead of a host-side loop per FFN per layer. Catalog, BuildInfo and README follow. Base targets and the -PlayaVerifier=true set build and test green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New example
SemanticEmojiFilter/: type what you mean, get the emoji. A Compose Multiplatform app (Android, Desktop, Web) that ranks a bilingual catalog of 208 emoji by the meaning of a free-text query with on-device sentence embeddings, plus an opt-in second stage on Desktop/Android where the Laya decision model re-checks the top hits throughsk.ainet.decisions.System 1 — embedding filter, every keystroke. MongoDB LEAF (
mdbr-leaf-ir, 23M params, Apache-2.0) on the SKaiNET-transformers BERT runtime: engine WordPiece tokenizer, mean pooling, the model's2_Denseprojection to 768-d, L2. Catalog embeddings computed once (shipped precomputed for wasm, 639 KB); a sweep is a dot product over 208 rows. Calibrated logistic confidence, top tier capped at 12.System 2 — typed decisions, when the query settles (500 ms). One
BooleanProbabilityquestion per candidate ("is this emoji a good answer to the search?"), one request per item so every ~2.5 s decision is a cancellation point; verdicts stream into the badges next to the vector score,?for an abstention. 🍕/🥓/🍩 drop for "healthy things to eat", "feeling sick" gets four confident yes.Measured (12-core laptop, Panama Vector, DIRECT): LEAF load 345 ms, catalog embed 112 ms/item, query embed p50 81 ms / p95 98 ms (with LEAF's retrieval prompt — without it the ranking is useless), sweep 0.28 ms, RSS 512 MB. Laya: load 9.0 s, 1.8–3.6 s per decision, RSS 4.8 GB. Details and the honest findings (conservative base checkpoint, asymmetric policy 0.2/0.6, LEAF is English-first) in the README.
Build
-PlayaVerifier=trueadds the:verifiermodule and resolvesskainet-transformers-{decisions-api,decisions-runtime,inference-laya}as0.59.0-SNAPSHOTfrom mavenLocal. Draft until transformers 0.59.0 is on Maven Central; then the three coordinates move under the BOM and the flag only toggles the module.scripts/fetch-model.sh+fetchModeltask bundle LEAF (92 MB) into the wasm Compose resources only (gitignored); Desktop/Android download per file at first run.scripts/generate-catalog.pybuildscatalog.jsonfrom CLDR 47 annotations (en + de) and the curated selection. CLI:bench | embed-catalog | calibrate | golden | query | tokens | verify.jvmTest+testAndroidHostTest): calibration fit, index/bin round trip, view model debounce + stable-query trigger, catalog schema + digest, ranking goldens (no model needed), model-gated parity; verifier 2 on a scripted adapter. CI workflowsemanticemojifilter-ci.ymlmirrors KernelRace (no verifier).docs/screenshots/grid.pngreferenced).The verifier's model source is one interface (
DecisionAdapterSource); a SKaiNET decision cartridge replaces it later without touching UI or view model.