Voidly Atlas's semantic search at /v1/atlas/search
used all-MiniLM-L6-v2, an
English-only sentence-transformer. That model was trained on
the same general-purpose web corpora as the rest of the
sentence-transformers family, but it embeds non-English
queries into a near-random region of the 384-d space — so a
journalist in Tehran typing اینترنت ایران or in
Moscow typing блокировка интернета got mostly noise.
We added a parallel multilingual index using
paraphrase-multilingual-MiniLM-L12-v2 —
same dimensionality (384), same sentence-transformers
library, but trained on the LaBSE parallel corpus across
50+ languages. We re-embedded all 2,696
incidents into a separate SQLite table
(incident_embeddings_multilingual)
so the legacy English-only endpoint stays byte-identical.
GET|POST /v1/atlas/search/multilingual?q=... —
same response shape as the English-only endpoint, plus a
detected_language field from a
cheap script-based heuristic (Unicode block prefixes for
Arabic / Persian / Cyrillic / CJK / Hangul / Hiragana /
Hebrew / Devanagari / Thai / Burmese / Ethiopic). The
heuristic distinguishes scripts but won't separate
Spanish vs French vs Italian inside Latin.
/v1/atlas/search/info/v1/atlas/search for
best precision.
fa,
but otherwise we report the dominant script. Pure-ASCII Latin
queries always report as en;
the multilingual model still embeds them correctly, the detection
field is just a hint.
?country=IR&incident_type=censorship)
remain strongly recommended.
5 5 * * 0 runs /opt/voidly-ai/scripts/rebuild-incident-embeddings-multilingual.py via the ML venv (sentence-transformers + torch-cpu)._maybe_reload_multilingual() — no restart needed.This is an accessibility ship, not a precision claim. Journalists and researchers outside the West can now ask Voidly Atlas questions in their own language and get back the same permalink-backed incident IDs we hand to English speakers.