CAMeLBERT-da-sentiment — Apple Core AI, Arabic dialect sentiment
A Core AI (.aimodel) build of
CAMeL-Lab/bert-base-arabic-camelbert-da-sentiment
for on-device dialectal Arabic sentiment on Apple Silicon.
Upstream ships pytorch_model.bin, flax_model.msgpack and tf_model.h5 — and no MLX, no ONNX,
no Core AI. 81,297 downloads, and this is the Core AI build.
This is the dialect sibling of CAMeLBERT-mix-sentiment-CoreAI.
Same three labels, trained on dialectal Arabic — and on the sentence below it disagrees with the MSA
model, correctly.
Outputs
One graph, two outputs. Keeping both costs nothing at this size and means neither the trained classifier nor the reusable vectors are thrown away.
| Output | Shape | What it is |
|---|---|---|
| logits | float32[1, 3] |
the trained head, in id2label order: 0 = positive, 1 = negative, 2 = neutral |
| embeddings | float32[1, 768] |
mean-pooled over the mask, L2-normalised — our addition, not an upstream objective |
Read this before reading the outputs
Select outputs by shape, not by name. The runtime names tensors after the op that produced them.
On this graph that is div_1 for the vectors and addmm_73 for the logits — the names in the
wrapper's dict do not survive into the .aimodel. A one-line size == 3 / size == 768 pick is the
robust way, and it is what the measurement script does.
Verified equivalence
Compared against the original PyTorch model on six fixed inputs at the exported shape:
| Input | Predicted | logits max abs diff | embeddings max abs diff | cosine |
|---|---|---|---|---|
| الخدمة كانت زي الفل، أنصح بيهم جدا. | positive | 7.15e-07 | 1.15e-07 | 1.00000000 |
| تجربة زي الزفت، مش هكرر تاني. | negative | 1.25e-06 | 2.31e-07 | 1.00000000 |
| المنتج ووصل أمس. | neutral | 4.77e-07 | 1.42e-07 | 1.00000000 |
| الدعم رد عليا بسرعة وحلوا المشكلة. | positive | 4.53e-06 | 3.65e-07 | 1.00000000 |
| الطلب اتأخر أسبوعين وما حد رد عليا. | negative | 3.46e-06 | 1.42e-07 | 1.00000000 |
| كيف أستعيد كلمة المرور؟ | neutral | 2.32e-06 | 3.43e-07 | 1.00000000 |
Worst across all six: 4.53e-06, and 6/6 labels agree with PyTorch. That residual is relative ~1e-6 on logits of magnitude ~3 — float32 rounding accumulated through the classifier layer, not a difference in the model.
One dialect example, and what it does not show
الطلب اتأخر أسبوعين وما حد رد عليا. — an Egyptian-Arabic complaint — is classified negative
here. The MSA model calls the same sentence neutral, which is the wrong answer for a complaint.
This is one sentence. It is the reason both bundles exist, but it is not a benchmark: no dialect sentiment corpus was run, and no accuracy figure for either model is claimed here.
Verified behaviour on six inputs, all matching PyTorch:
| Input | Predicted |
|---|---|
| الخدمة كانت زي الفل، أنصح بيهم جدا. | positive |
| تجربة زي الزفت، مش هكرر تاني. | negative |
| المنتج ووصل أمس. | neutral |
| الدعم رد عليا بسرعة وحلوا المشكلة. | positive |
| الطلب اتأخر أسبوعين وما حد رد عليا. | negative (the MSA model says neutral) |
| كيف أستعيد كلمة المرور؟ | neutral |
Use
import asyncio, numpy as np
from coreai.runtime import AIModel, NDArray, SpecializationOptions
from transformers import AutoTokenizer
LABELS = ["positive", "negative", "neutral"]
SEQUENCE_LENGTH = 512 # fixed shape: pad to it
async def analyse(text: str):
tok = AutoTokenizer.from_pretrained(".")
model = await AIModel.load("camelbert-arabic-sentiment.aimodel", SpecializationOptions.default())
fn = model.load_function("main")
enc = tok([text], padding="max_length", truncation=True, max_length=SEQUENCE_LENGTH,
return_tensors="np")
out = await fn({"input_ids": NDArray(enc["input_ids"].astype("int32")),
"attention_mask": NDArray(enc["attention_mask"].astype("int32"))})
flat = {k: np.asarray(v.numpy()).reshape(-1) for k, v in out.items()}
logits = next(v for v in flat.values() if v.size == 3)
vectors = next(v for v in flat.values() if v.size == 768)
return LABELS[int(np.argmax(logits))], logits, vectors
print(asyncio.run(analyse("الخدمة كانت ممتازة وأنصح به بشدة."))[0]) # positive
What is in here
| File | |
|---|---|
camelbert-arabic-sentiment.aimodel/ |
the graph |
manifest.json |
source, revision, label order, output shapes, precision |
validation.json |
PyTorch-to-Core AI equivalence for each case above (not the download count) |
camelbert_sent_coreai.py |
the exporter and measurer — --check, --export, --measure |
vocab.txt, config.json, tokenizer files |
so the tokenizer loads from this repository |
Limits
- Fixed at 512 tokens; pad rather than passing a shorter sequence.
- Six inputs measured. Dialect variation, long documents and the 512-token boundary were not.
- No speed or memory benchmark. Equivalence only.
- The classification is 3-way and single-label; no confidence calibration was measured.
Licence and attribution
Apache-2.0, as declared by upstream. A derivative work of
CAMeL-Lab/bert-base-arabic-camelbert-da-sentiment; credit for the model is theirs.
- Downloads last month
- 20