openasocket/Lingo

Pure Rust multilingual NLP: NLLB-200 translation + LaBSE/SONAR similarity scoring with Metal/CUDA GPU acceleration via candle

Rust

0

14 commits

updated Jun 4, 2026

See the code

README

lingo

Pure Rust multilingual NLP toolkit built on candle. Translates text using the NLLB-200 model and performs similarity calculations on translated text against pre-translated text using LaBSE and SONAR. No Python required.

What It Does

CapabilityModelDescription
TranslationNLLB-200Translate between 200+ languages
SimilarityLaBSECross-lingual semantic similarity scoring (768-dim)
SimilaritySONARCross-lingual sentence embeddings (1024-dim)

All models run on Apple Metal GPU, NVIDIA CUDA, or CPU.

Use as a Rust Library

[dependencies]
lingo = { version = "0.1", features = ["metal"] }  # macOS
# lingo = { version = "0.1", features = ["cuda"] } # Linux NVIDIA
tokio = { version = "1", features = ["full"] }

Translation

use lingo::NllbTranslator;

let translator = NllbTranslator::new(None)?;
let result = translator.translate("Hello, how are you?", "en", "fr").await?;
println!("{}", result.text);       // "Bonjour, comment allez-vous ?"
println!("{}ms", result.duration_ms); // ~130ms

Similarity Scoring (LaBSE)

use lingo::LaBSEEncoder;

let encoder = LaBSEEncoder::new(None)?;

// Cross-lingual similarity
let score = encoder.score("Hello world", "Bonjour le monde").await?;
println!("{:.3}", score); // ~0.85

// Get raw embeddings (768-dim)
let embedding = encoder.embed("Hello world").await?;

Similarity Scoring (SONAR)

use lingo::SonarEncoder;

let encoder = SonarEncoder::new(None)?;

// Cross-lingual similarity (1024-dim embeddings)
let score = encoder.score("Hello world", "Bonjour le monde").await?;
println!("{:.3}", score);

// Get raw embeddings (1024-dim)
let embedding = encoder.embed("Hello world").await?;

Language Codes

use lingo::NllbLanguage;

let lang = NllbLanguage::from_iso_code("fr").unwrap();
println!("{}: {}", lang.name(), lang.nllb_code()); // "French: fra_Latn"

for lang in NllbLanguage::all_languages() {
    println!("{}: {}", lang.iso_code(), lang.name());
}

Use as a CLI Tool

# macOS (Apple Silicon)
cargo install lingo --features cli,metal

# Linux (NVIDIA GPU) — requires CUDA toolkit
CUDA_HOME=/usr/local/cuda-13.0 cargo install lingo --features cli,cuda

# CPU only
cargo install lingo --features cli

Translate

lingo translate "Hello world" --to fr
# [fr] Bonjour le monde (135ms)

lingo translate "Good morning" --to fr,es,ja,ar,ko

echo "Hello world" | lingo translate --to fr

lingo translate "Hello" --to fr,es --json

Score Similarity (LaBSE)

lingo score "Hello world" "Bonjour le monde"
# 0.9471

Score Similarity (SONAR)

lingo sonar-score "Hello world" "Bonjour le monde"
# 0.7441

Embed (LaBSE)

lingo embed "Hello world"
# [0.0234, -0.0891, 0.0412, ...]  (768 floats)

Embed (SONAR)

lingo sonar-embed "Hello world"
# [0.0123, -0.0456, 0.0789, ...]  (1024 floats)

Download Models

lingo download all     # Download all models
lingo download sonar   # Download just SONAR

List Languages

lingo languages

Use as an HTTP Server

cargo run --example server --features server,metal

Endpoints

MethodPathDescription
POST/translate{"text", "source", "target"} -> translation
POST/translate_batch{"texts": [...], "source", "target"} -> batch translation, no scoring
POST/score{"text1", "text2"} -> similarity score
POST/embed{"text"} -> 768-dim embedding
POST/embed_batch{"texts": [...]} -> batch embeddings
POST/analyze{"text", "source", "target"} -> translation + LaBSE & SONAR scores
POST/analyze_batch{"texts": [...], "source", "target"} -> batch translate + score
GET/healthServer status
curl -X POST http://localhost:3000/translate \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello world", "source": "en", "target": "fr"}'

curl -X POST http://localhost:3000/score \
  -H "Content-Type: application/json" \
  -d '{"text1": "Hello world", "text2": "Bonjour le monde"}'

curl -X POST http://localhost:3000/translate_batch \
  -H "Content-Type: application/json" \
  -d '{"texts": ["Hello world", "Good morning", "How are you"], "source": "en", "target": "fr"}'
# {"translations":["Bonjour le monde","Bonjour","Comment allez-vous"],"count":3,...}

curl -X POST http://localhost:3000/embed_batch \
  -H "Content-Type: application/json" \
  -d '{"texts": ["Hello world", "Bonjour le monde", "Hola mundo"]}'

curl -X POST http://localhost:3000/analyze \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello world", "source": "en", "target": "fr"}'
# {"source_text":"Hello world","translation":"Bonjour le monde","labse_score":0.947,"sonar_score":0.744,...}

curl -X POST http://localhost:3000/analyze_batch \
  -H "Content-Type: application/json" \
  -d '{"texts": ["Hello world", "Good morning"], "source": "en", "target": "fr"}'

Use from Python

Start the server, then:

import json, urllib.request

def translate(text, source="en", target="fr"):
    data = json.dumps({"text": text, "source": source, "target": target}).encode()
    req = urllib.request.Request("http://localhost:3000/translate", data=data,
        headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(req).read())

def score(text1, text2):
    data = json.dumps({"text1": text1, "text2": text2}).encode()
    req = urllib.request.Request("http://localhost:3000/score", data=data,
        headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(req).read())

def embed_batch(texts):
    data = json.dumps({"texts": texts}).encode()
    req = urllib.request.Request("http://localhost:3000/embed_batch", data=data,
        headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(req).read())

def analyze(text, source="en", target="fr"):
    data = json.dumps({"text": text, "source": source, "target": target}).encode()
    req = urllib.request.Request("http://localhost:3000/analyze", data=data,
        headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(req).read())

def analyze_batch(texts, source="en", target="fr"):
    data = json.dumps({"texts": texts, "source": source, "target": target}).encode()
    req = urllib.request.Request("http://localhost:3000/analyze_batch", data=data,
        headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(req).read())

print(translate("Hello", "en", "fr")["translation"])  # "Bonjour"
print(score("Hello", "Bonjour")["score"])              # 0.85

embeddings = embed_batch(["Hello", "Bonjour", "Hola"])
print(len(embeddings["embeddings"]))  # 3

result = analyze("Hello world", "en", "fr")
print(result["translation"])   # "Bonjour le monde"
print(result["labse_score"])   # 0.947
print(result["sonar_score"])   # 0.744
print(embeddings["dimensions"])       # 768

Model Setup

All models auto-download when first used via the CLI. You can also download them explicitly:

# Download all models at once
lingo download all

# Or individually
lingo download nllb    # NLLB-200 (~1.2 GB from HuggingFace)
lingo download labse   # LaBSE (~1.8 GB from HuggingFace)
lingo download sonar   # SONAR (~3 GB, requires Python for conversion)

NLLB-200 (translation)

Auto-downloads from HuggingFace, or convert manually:

python scripts/convert_nllb_safetensors.py
# Saves to ~/.cache/lingo/nllb-200-distilled-600M/ (~1.2 GB)

LaBSE (similarity/embeddings)

Auto-downloads from sentence-transformers/LaBSE:

~/.cache/lingo/labse/
  model.safetensors         # BERT weights (~1.8 GB)
  config.json               # Model config
  tokenizer.json            # Tokenizer
  2_Dense/model.safetensors # Projection layer

SONAR (similarity/embeddings)

Auto-downloads from Meta's CDN and converts to safetensors (requires Python 3 with torch, safetensors, sentencepiece, tokenizers):

python scripts/convert_sonar_safetensors.py
# Downloads from Meta's CDN and saves to ~/.cache/lingo/sonar/ (~3 GB)

Feature Flags

FeatureDescription
metalMetal GPU (macOS Apple Silicon)
cudaCUDA GPU (Linux NVIDIA)
accelerateApple Accelerate (CPU SIMD)
cliCLI binary
serverHTTP server (axum)

Building with CUDA

Requires CUDA toolkit 13.0+ for Blackwell GPUs (RTX 5090/5080), or CUDA 12.x for older architectures.

# Set CUDA_HOME to the correct toolkit version
export CUDA_HOME=/usr/local/cuda-13.0

# Build release binary with CUDA + CLI
cargo build --release --features cli,cuda

# Run
LINGO_ACCEPT_LICENSE=1 ./target/release/lingo translate "Hello world" --to fr

Performance

All benchmarks are release builds (cargo build --release), measuring warm inference (model already loaded) unless noted otherwise. NLLB uses F16 weights via conversion script; LaBSE and SONAR use F32 weights.

NVIDIA RTX 5090 — CUDA 13.0

System: RTX 5090 (32 GB VRAM, Blackwell), CUDA toolkit 13.0, Linux 6.8

OperationTimeNotes
NLLB translation (short, warm)~57msCached encoder, subsequent targets
NLLB translation (short, cold)~169msFirst target in invocation
NLLB translation (paragraph, 3 targets)~371ms avg40-word input
NLLB multi-target (10 languages)~224ms totalSingle invocation
NLLB model load~1.27s
NLLB cold start (load + first translate)~1.44s
LaBSE similarity (per pair)~9msCustom BERT encoder
LaBSE model load~839ms
LaBSE cold start (load + first score)~926ms
SONAR similarity (per pair)~14ms24-layer transformer encoder
SONAR model load~916msF32 weights
SONAR cold start (load + first score)~953ms

Apple M5 Max — Metal GPU

System: MacBook Pro, M5 Max, 128 GB unified memory, macOS 26.4

OperationTimeNotes
NLLB translation (short, warm)~85msCached encoder, subsequent targets
NLLB translation (short, cold)~136msFirst target in invocation
NLLB translation (paragraph, 3 targets)~810ms avg40-word input
NLLB multi-target (10 languages)~1.14s totalSingle invocation
NLLB model load~440msF16 weights
NLLB cold start (load + first translate)~660ms
LaBSE similarity (per pair)~100msCustom BERT encoder
LaBSE model load~385ms
LaBSE cold start (load + first score)~500ms
SONAR similarity (per pair)~28ms24-layer transformer encoder
SONAR model load~449msF32 weights
SONAR cold start (load + first score)~501ms

Apple M5 Max — Accelerate (CPU SIMD)

System: MacBook Pro, M5 Max, 128 GB unified memory, macOS 26.4

OperationTimeNotes
NLLB translation (short, warm)~225msCached encoder, subsequent targets
NLLB translation (short, cold)~399msFirst target in invocation
NLLB translation (paragraph, 3 targets)~2.7s avg40-word input
NLLB multi-target (10 languages)~2.56s totalSingle invocation
NLLB model load~630msF16 weights
NLLB cold start (load + first translate)~1.31s
LaBSE similarity (per pair)~55msFaster than Metal for BERT inference
LaBSE model load~395ms
LaBSE cold start (load + first score)~450ms
SONAR similarity (per pair)~73ms24-layer transformer encoder
SONAR model load~408msF32 weights
SONAR cold start (load + first score)~522ms

Cross-Lingual Similarity Scores (LaBSE)

Scores are cosine similarity of L2-normalized 768-dim embeddings. Identical on CPU and CUDA.

Text 1Text 2Score
"Hello world""Bonjour le monde" (fr)0.947
"Hello world""Hola mundo" (es)0.957
"Hello world""こんにちは世界" (ja)0.948
"The cat sat on the mat""The dog ran in the park"0.517
"I love programming""I love programming"1.000

Cross-Lingual Similarity Scores (SONAR)

Scores are cosine similarity of L2-normalized 1024-dim embeddings. Identical on CPU and GPU.

Text 1Text 2Score
"Hello world""Bonjour le monde" (fr)0.744
"Hello world""Hola mundo" (es)0.753
"Hello world""こんにちは世界" (ja)0.699
"The cat sat on the mat""The dog ran in the park"0.168
"I love programming""I love programming"1.000

License

FiddyCent Software License. See LICENSE for full terms.

Model weights: CC-BY-NC 4.0 (Meta AI), Apache 2.0 (Google).

Contributors

openasocket

14 commits

openasocket/Lingo

Pure Rust multilingual NLP: NLLB-200 translation + LaBSE/SONAR similarity scoring with Metal/CUDA GPU acceleration via candle

Rust

0

14 commits

updated Jun 4, 2026

See the code

README

lingo

Pure Rust multilingual NLP toolkit built on candle. Translates text using the NLLB-200 model and performs similarity calculations on translated text against pre-translated text using LaBSE and SONAR. No Python required.

What It Does

CapabilityModelDescription
TranslationNLLB-200Translate between 200+ languages
SimilarityLaBSECross-lingual semantic similarity scoring (768-dim)
SimilaritySONARCross-lingual sentence embeddings (1024-dim)

All models run on Apple Metal GPU, NVIDIA CUDA, or CPU.

Use as a Rust Library

[dependencies]
lingo = { version = "0.1", features = ["metal"] }  # macOS
# lingo = { version = "0.1", features = ["cuda"] } # Linux NVIDIA
tokio = { version = "1", features = ["full"] }

Translation

use lingo::NllbTranslator;

let translator = NllbTranslator::new(None)?;
let result = translator.translate("Hello, how are you?", "en", "fr").await?;
println!("{}", result.text);       // "Bonjour, comment allez-vous ?"
println!("{}ms", result.duration_ms); // ~130ms

Similarity Scoring (LaBSE)

use lingo::LaBSEEncoder;

let encoder = LaBSEEncoder::new(None)?;

// Cross-lingual similarity
let score = encoder.score("Hello world", "Bonjour le monde").await?;
println!("{:.3}", score); // ~0.85

// Get raw embeddings (768-dim)
let embedding = encoder.embed("Hello world").await?;

Similarity Scoring (SONAR)

use lingo::SonarEncoder;

let encoder = SonarEncoder::new(None)?;

// Cross-lingual similarity (1024-dim embeddings)
let score = encoder.score("Hello world", "Bonjour le monde").await?;
println!("{:.3}", score);

// Get raw embeddings (1024-dim)
let embedding = encoder.embed("Hello world").await?;

Language Codes

use lingo::NllbLanguage;

let lang = NllbLanguage::from_iso_code("fr").unwrap();
println!("{}: {}", lang.name(), lang.nllb_code()); // "French: fra_Latn"

for lang in NllbLanguage::all_languages() {
    println!("{}: {}", lang.iso_code(), lang.name());
}

Use as a CLI Tool

# macOS (Apple Silicon)
cargo install lingo --features cli,metal

# Linux (NVIDIA GPU) — requires CUDA toolkit
CUDA_HOME=/usr/local/cuda-13.0 cargo install lingo --features cli,cuda

# CPU only
cargo install lingo --features cli

Translate

lingo translate "Hello world" --to fr
# [fr] Bonjour le monde (135ms)

lingo translate "Good morning" --to fr,es,ja,ar,ko

echo "Hello world" | lingo translate --to fr

lingo translate "Hello" --to fr,es --json

Score Similarity (LaBSE)

lingo score "Hello world" "Bonjour le monde"
# 0.9471

Score Similarity (SONAR)

lingo sonar-score "Hello world" "Bonjour le monde"
# 0.7441

Embed (LaBSE)

lingo embed "Hello world"
# [0.0234, -0.0891, 0.0412, ...]  (768 floats)

Embed (SONAR)

lingo sonar-embed "Hello world"
# [0.0123, -0.0456, 0.0789, ...]  (1024 floats)

Download Models

lingo download all     # Download all models
lingo download sonar   # Download just SONAR

List Languages

lingo languages

Use as an HTTP Server

cargo run --example server --features server,metal

Endpoints

MethodPathDescription
POST/translate{"text", "source", "target"} -> translation
POST/translate_batch{"texts": [...], "source", "target"} -> batch translation, no scoring
POST/score{"text1", "text2"} -> similarity score
POST/embed{"text"} -> 768-dim embedding
POST/embed_batch{"texts": [...]} -> batch embeddings
POST/analyze{"text", "source", "target"} -> translation + LaBSE & SONAR scores
POST/analyze_batch{"texts": [...], "source", "target"} -> batch translate + score
GET/healthServer status
curl -X POST http://localhost:3000/translate \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello world", "source": "en", "target": "fr"}'

curl -X POST http://localhost:3000/score \
  -H "Content-Type: application/json" \
  -d '{"text1": "Hello world", "text2": "Bonjour le monde"}'

curl -X POST http://localhost:3000/translate_batch \
  -H "Content-Type: application/json" \
  -d '{"texts": ["Hello world", "Good morning", "How are you"], "source": "en", "target": "fr"}'
# {"translations":["Bonjour le monde","Bonjour","Comment allez-vous"],"count":3,...}

curl -X POST http://localhost:3000/embed_batch \
  -H "Content-Type: application/json" \
  -d '{"texts": ["Hello world", "Bonjour le monde", "Hola mundo"]}'

curl -X POST http://localhost:3000/analyze \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello world", "source": "en", "target": "fr"}'
# {"source_text":"Hello world","translation":"Bonjour le monde","labse_score":0.947,"sonar_score":0.744,...}

curl -X POST http://localhost:3000/analyze_batch \
  -H "Content-Type: application/json" \
  -d '{"texts": ["Hello world", "Good morning"], "source": "en", "target": "fr"}'

Use from Python

Start the server, then:

import json, urllib.request

def translate(text, source="en", target="fr"):
    data = json.dumps({"text": text, "source": source, "target": target}).encode()
    req = urllib.request.Request("http://localhost:3000/translate", data=data,
        headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(req).read())

def score(text1, text2):
    data = json.dumps({"text1": text1, "text2": text2}).encode()
    req = urllib.request.Request("http://localhost:3000/score", data=data,
        headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(req).read())

def embed_batch(texts):
    data = json.dumps({"texts": texts}).encode()
    req = urllib.request.Request("http://localhost:3000/embed_batch", data=data,
        headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(req).read())

def analyze(text, source="en", target="fr"):
    data = json.dumps({"text": text, "source": source, "target": target}).encode()
    req = urllib.request.Request("http://localhost:3000/analyze", data=data,
        headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(req).read())

def analyze_batch(texts, source="en", target="fr"):
    data = json.dumps({"texts": texts, "source": source, "target": target}).encode()
    req = urllib.request.Request("http://localhost:3000/analyze_batch", data=data,
        headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(req).read())

print(translate("Hello", "en", "fr")["translation"])  # "Bonjour"
print(score("Hello", "Bonjour")["score"])              # 0.85

embeddings = embed_batch(["Hello", "Bonjour", "Hola"])
print(len(embeddings["embeddings"]))  # 3

result = analyze("Hello world", "en", "fr")
print(result["translation"])   # "Bonjour le monde"
print(result["labse_score"])   # 0.947
print(result["sonar_score"])   # 0.744
print(embeddings["dimensions"])       # 768

Model Setup

All models auto-download when first used via the CLI. You can also download them explicitly:

# Download all models at once
lingo download all

# Or individually
lingo download nllb    # NLLB-200 (~1.2 GB from HuggingFace)
lingo download labse   # LaBSE (~1.8 GB from HuggingFace)
lingo download sonar   # SONAR (~3 GB, requires Python for conversion)

NLLB-200 (translation)

Auto-downloads from HuggingFace, or convert manually:

python scripts/convert_nllb_safetensors.py
# Saves to ~/.cache/lingo/nllb-200-distilled-600M/ (~1.2 GB)

LaBSE (similarity/embeddings)

Auto-downloads from sentence-transformers/LaBSE:

~/.cache/lingo/labse/
  model.safetensors         # BERT weights (~1.8 GB)
  config.json               # Model config
  tokenizer.json            # Tokenizer
  2_Dense/model.safetensors # Projection layer

SONAR (similarity/embeddings)

Auto-downloads from Meta's CDN and converts to safetensors (requires Python 3 with torch, safetensors, sentencepiece, tokenizers):

python scripts/convert_sonar_safetensors.py
# Downloads from Meta's CDN and saves to ~/.cache/lingo/sonar/ (~3 GB)

Feature Flags

FeatureDescription
metalMetal GPU (macOS Apple Silicon)
cudaCUDA GPU (Linux NVIDIA)
accelerateApple Accelerate (CPU SIMD)
cliCLI binary
serverHTTP server (axum)

Building with CUDA

Requires CUDA toolkit 13.0+ for Blackwell GPUs (RTX 5090/5080), or CUDA 12.x for older architectures.

# Set CUDA_HOME to the correct toolkit version
export CUDA_HOME=/usr/local/cuda-13.0

# Build release binary with CUDA + CLI
cargo build --release --features cli,cuda

# Run
LINGO_ACCEPT_LICENSE=1 ./target/release/lingo translate "Hello world" --to fr

Performance

All benchmarks are release builds (cargo build --release), measuring warm inference (model already loaded) unless noted otherwise. NLLB uses F16 weights via conversion script; LaBSE and SONAR use F32 weights.

NVIDIA RTX 5090 — CUDA 13.0

System: RTX 5090 (32 GB VRAM, Blackwell), CUDA toolkit 13.0, Linux 6.8

OperationTimeNotes
NLLB translation (short, warm)~57msCached encoder, subsequent targets
NLLB translation (short, cold)~169msFirst target in invocation
NLLB translation (paragraph, 3 targets)~371ms avg40-word input
NLLB multi-target (10 languages)~224ms totalSingle invocation
NLLB model load~1.27s
NLLB cold start (load + first translate)~1.44s
LaBSE similarity (per pair)~9msCustom BERT encoder
LaBSE model load~839ms
LaBSE cold start (load + first score)~926ms
SONAR similarity (per pair)~14ms24-layer transformer encoder
SONAR model load~916msF32 weights
SONAR cold start (load + first score)~953ms

Apple M5 Max — Metal GPU

System: MacBook Pro, M5 Max, 128 GB unified memory, macOS 26.4

OperationTimeNotes
NLLB translation (short, warm)~85msCached encoder, subsequent targets
NLLB translation (short, cold)~136msFirst target in invocation
NLLB translation (paragraph, 3 targets)~810ms avg40-word input
NLLB multi-target (10 languages)~1.14s totalSingle invocation
NLLB model load~440msF16 weights
NLLB cold start (load + first translate)~660ms
LaBSE similarity (per pair)~100msCustom BERT encoder
LaBSE model load~385ms
LaBSE cold start (load + first score)~500ms
SONAR similarity (per pair)~28ms24-layer transformer encoder
SONAR model load~449msF32 weights
SONAR cold start (load + first score)~501ms

Apple M5 Max — Accelerate (CPU SIMD)

System: MacBook Pro, M5 Max, 128 GB unified memory, macOS 26.4

OperationTimeNotes
NLLB translation (short, warm)~225msCached encoder, subsequent targets
NLLB translation (short, cold)~399msFirst target in invocation
NLLB translation (paragraph, 3 targets)~2.7s avg40-word input
NLLB multi-target (10 languages)~2.56s totalSingle invocation
NLLB model load~630msF16 weights
NLLB cold start (load + first translate)~1.31s
LaBSE similarity (per pair)~55msFaster than Metal for BERT inference
LaBSE model load~395ms
LaBSE cold start (load + first score)~450ms
SONAR similarity (per pair)~73ms24-layer transformer encoder
SONAR model load~408msF32 weights
SONAR cold start (load + first score)~522ms

Cross-Lingual Similarity Scores (LaBSE)

Scores are cosine similarity of L2-normalized 768-dim embeddings. Identical on CPU and CUDA.

Text 1Text 2Score
"Hello world""Bonjour le monde" (fr)0.947
"Hello world""Hola mundo" (es)0.957
"Hello world""こんにちは世界" (ja)0.948
"The cat sat on the mat""The dog ran in the park"0.517
"I love programming""I love programming"1.000

Cross-Lingual Similarity Scores (SONAR)

Scores are cosine similarity of L2-normalized 1024-dim embeddings. Identical on CPU and GPU.

Text 1Text 2Score
"Hello world""Bonjour le monde" (fr)0.744
"Hello world""Hola mundo" (es)0.753
"Hello world""こんにちは世界" (ja)0.699
"The cat sat on the mat""The dog ran in the park"0.168
"I love programming""I love programming"1.000

License

FiddyCent Software License. See LICENSE for full terms.

Model weights: CC-BY-NC 4.0 (Meta AI), Apache 2.0 (Google).

Contributors

openasocket

14 commits

Languages

Rust

94.1%

Python

5.9%