Ternlight – 7 MB embedding model that runs in browser (WASM)

(ternlight-demo.vercel.app)

88 points | by soycaporal 3 hours ago

11 comments

  • soycaporal 3 hours ago
    Hobby project, I wanted to "ship a useful model in a web browser". so I distilled a small sentence encoder from MiniLM with ternary quantization-aware training. Also wrote the inference engine from scratch and shipped in Rust → WASM SIMD.

    It's an embeddings model, not an LLM: text goes in, a 384-dim vector comes out, and cosine similarity between two vectors tells you how related the texts are — regardless of shared words ("reset my password" ↔ "I forgot my password" → 0.88). Used for semantic search, FAQ/intent matching, and clustering. Running it on-device means search-as-you-type semantic search is performant with no API dependencies.

    Demo (2k React docs, fully on-device): https://ternlight-demo.vercel.app

    Two tiers on npm: - @ternlight/base (7 MB, ~5 ms/embed, more capable embedings) - @ternlight/mini (5 MB wire, ~2.5 ms/embed).

    Bundled for Node and browsers.

    Repo - see technical details (MIT, training pipeline included): https://github.com/soycaporal/ternlight

    Curious if this is something useful, what are the use cases for on-device embeddings.

    • dwheeler 16 minutes ago
      Thanks! I strongly suggest copy-pasting that explanation to your web page, that's a nice summary.
    • fellowniusmonk 2 hours ago
      Awesome! Besides size, how does this compare to gte-small?
      • soycaporal 2 hours ago
        gte-small outscores all-MiniLM-L6 on MTEB (~61 vs ~56 avg per the GTE paper). MiniLM is ternlight's teacher (ternlight holds 0.84 Spearman fidelity to teacher). I haven't run a head-to-head yet; STS-B/MTEB numbers are on the roadmap. Also on the roadmap is to distill gte-small as teacher.
  • dirteater_ 2 hours ago
    This is cool!

    but also maybe you could put a button on the landing page to trigger the demo because it's a bit startling to hear my fans go crazy when opening a webpage.

    • Waterluvian 2 hours ago
      Agree. But this also reminds me fondly of the days where the sounds of my computer so intimately indicated what’s going on.
      • mwcz 1 hour ago
        Amiga floppy disk sounds are the deepest of sense memories.
    • soycaporal 14 minutes ago
      CPU cycle maxxing, who said GPUs were special?
  • wazzup_im 2 hours ago
    I added an offline search engine to app.wazzup.im/search (no login or payment required).

    First search downloads the model from the internet and subsequent runs are from the cache.

    The model is very small so it's not the best for everything but it's good for basic math and coding.

    Give it a try.

    • wazzup_im 28 minutes ago
    • Barbing 46 minutes ago
      In Safari, stuck on:

      Loading model... + Loading search results...

      Or sometimes "Service Worker API is available and in use." + "Loading search results...".

      • wazzup_im 32 minutes ago
        This is a known issue and I am actively trying to find why this is happening. So far it's pretty good on Brave/Chrome.

        Tested on Macbook Pro M1 8gb RAM and Macbook Air M1 8gb RAM. Mostly likely because of M series of chips. All tests were done on Brave/Chrome.

        Does not work on iPhone 11 Pro Max and iPhone 16 Pro. Mostly likely because of A series of chips. Tests were done on Safari and Chrome and it crashes on both.

      • soycaporal 29 minutes ago
        ohh thanks for the report.. probably has to do with wasm runtime.. Will note this as a known issue
        • wazzup_im 26 minutes ago
          Np!

          The workaround is to unregister/stop the service worker from the DevTools > Application tab > Service workers.

  • aetherspawn 2 hours ago
    Can the 30 second embedding time be done beforehand and sent to the browser?

    Inference is nice and quick after that.

    • soycaporal 2 hours ago
      yes, you could run a 1 time indexing run on the server side, and just ship the embeddings to frontend
  • CobrastanJorji 2 hours ago
    Great, now my websites are gonna push entire LLMs onto my browser in order to use my CPU to make inferences about my shopping habits or whatever.
    • antonvs 2 hours ago
      Disabling WASM is the new disable JavaScript
    • paytonjjones 1 hour ago
      Ha, I was literally thinking this but from the other side.

      "Hmm, 7MB would barely make a dent in the size of the app and allow us to do some of our basic ML without calling the backend"

      Probably a lot more practical to use this though: https://developer.apple.com/apple-intelligence/

  • gaigalas 59 minutes ago
    That's really impressive, congratulations. It's nice to see novel applications of browser models.
    • soycaporal 28 minutes ago
      thank you! hopefully it can unlock some novel applications, that would be cool
  • rvz 2 hours ago
    Why do these things download into the browser automatically? This could be used to distribute malware and also or hog excessive browser memory.
    • akoboldfrying 44 minutes ago
      This doesn't add any malware risks beyond what a JavaScript-enabled browser already allows.

      Re excessive browser memory use: Yes, it adds non-negligible weight, but again, you could already achieve excessive browser memory usage before this. For comparison, a true color 1080p image, uncompressed (which is needed for actual display on screen) is only slightly smaller at 6.22Mb.

    • gaigalas 1 hour ago
      That's... how the web works? You download things on demand.

      There are JS files larger than 7MB in the wild. They run on JIT engines that displayed severe CVEs over the years. PDFs, video running directly on special hardware encoders. That's the web now.

      A WASM model is not that offensive.

  • newspaper1 2 hours ago
    Very cool! I'd love to point it at my own corpus to index/embed. Would be cool if you could give it a link to a markdown file or even a website to crawl.
    • soycaporal 30 minutes ago
      love the idea! Will think of a way to host it probably on huggingface
  • esafak 2 hours ago
    What we need is a W3C LLM API like the one Chrome already offers: https://developer.chrome.com/docs/ai/built-in
    • yesidoagree 2 hours ago
      If it was like Math (Math.round, Math.PI, etc.) it could be Language, as in:

          Language.complete('the quick brown fox jumped over the lazy') 
      
      and maybe even static methods on Image

          Image.generate('a spaceship flying toward a planet')
    • soycaporal 2 hours ago
      I think standardizing the runtime is pretty effective, it then open up portability
  • tangsoupgallery 1 hour ago
    [flagged]
  • Technical_Plant 2 hours ago
    [dead]