pplx-embed-coreml / README.md
dokterbob's picture
update model card (native RMSNorm + content-addressed download)
53428a9 verified
|
Raw
History Blame Contribute Delete
2.91 kB
---
language: multilingual
license: apache-2.0
base_model: perplexity-ai/pplx-embed-v1-0.6b
tags:
- coreml
- apple-neural-engine
- qwen3
- sentence-embedding
- on-device
library_name: coreml
---
# pplx-embed for Apple CoreML (ANE-optimized)
CoreML conversion of Perplexity's
[`pplx-embed-v1-0.6b`](https://huggingface.co/perplexity-ai/pplx-embed-v1-0.6b)
(a bidirectional Qwen3-0.6B encoder β†’ masked-mean pool β†’ tanh-int8 head) produced with
the [CoreML-LLM](https://github.com/john-rocky/CoreML-LLM) pipeline. Targets macOS 26.
Each subfolder is a **fixed-shape sequence-length bucket** that stays resident on the
Apple Neural Engine (flexible shapes force CPU fallback). At runtime the Swift package
pads each input to the smallest bucket that fits; inputs longer than the largest fixed
bucket fall through to the `dyn*-int8/` flexible GPU catch-all. The encoder uses native
RMSNorm and a single fixed RoPE table β€” the ANE-fastest path on M4 Max / macOS 26.
## Buckets in this repo
| Subfolder | Variant | Bucket (L) | Kind | Size |
|---|---|---|---|---|
| `L1024-int8/` | plain | 1024 | fixed ANE bucket | 2.44 GB |
| `L2048-int8/` | plain | 2048 | fixed ANE bucket | 2.44 GB |
| `L4096-int8/` | plain | 4096 | fixed ANE bucket | 2.44 GB |
| `L512-int8/` | plain | 512 | fixed ANE bucket | 2.44 GB |
| `dyn8192-int8/` | plain | 1..8192 | dynamic GPU catch-all | 2.44 GB |
| `context/L512-int8/` | context | 512 | fixed ANE bucket | 2.44 GB |
The encoder `weight.bin` is **byte-identical across every bucket** (a single fixed-size
RoPE table makes the weights independent of bucket length). So HF stores the weight blob
**once**, and the HF content-addressed cache fetches it **once by etag** on download β€”
pulling several buckets costs ~1.15 GB total, not ~1.15 GB Γ— N.
## Use it
Via the [CoreML-LLM Swift package](https://github.com/john-rocky/CoreML-LLM). It uses the
HF Swift Hub client, so only the buckets you request are downloaded and the shared weight
is fetched once into the content-addressed cache:
```swift
import CoreMLLLM
let embedder = try await PplxEmbed.load(
repo: "dokterbob/pplx-embed-coreml",
buckets: [512, 1024, 2048]) // shared HF cache; weight fetched once by etag
let vecs = try embedder.embed(["On-device embeddings", "Bonjour le monde"]) // [[Int8]]
```
Each bucket is published in both `.mlpackage` and precompiled `.mlmodelc`; pass
`preferCompiled: false` for the portable package. Or download the bundle directory
yourself and load it with `load(bundleDir:)`.
## I/O contract (per bucket `model_config.json`)
- `input_ids (1, L) int32`, `attention_mask (1, L) fp16` (1.0 valid, 0.0 pad)
- `embedding (1, 1024) int8` β€” `clamp(round(tanh(x)*127), -128, 127)`; derive
`binary`/`ubinary` from the int8 sign (see `PplxEmbed`).
## License
Inherits the base model's [license](https://huggingface.co/perplexity-ai/pplx-embed-v1-0.6b).