A lightweight multilingual translation service powered by the pure Rust LinguaSpark inference engine and compatible with multiple translation frontend APIs.
This project originated when I discovered the MTranServer repository, which uses Firefox Translations Models for machine translation and is compatible with APIs like Immersive Translate and Kiss Translator, but found that it wasn't open-sourced yet.
While searching for similar projects, I found Mozilla's translation-service, which works but hasn't been updated for a year and isn't compatible with Immersive Translate or Kiss Translator APIs. Since that project is written in C++ and I'm not very familiar with C++, I rewrote this project in Rust.
- 💪 Written in Rust for excellent performance and low memory footprint
- 🔄 Pure Rust inference through LinguaSpark
- 🧠 Compatible with Firefox Translations Models
- 🔍 Built-in language detection with automatic source language identification
- 🔌 Supports multiple translation API formats:
- Native API
- Immersive Translate API
- Kiss Translator API
- HCFY API
- DeepLX API
- 🔑 API key protection support
- 🐳 Docker deployment ready
- Web Framework: Axum
- Translation Engine: LinguaSpark
- Translation Models: Firefox Translations Models
- Language Detection: Whichlang
Docker is the only recommended deployment method for this service.
# Create models directory
mkdir -p models
# Download your models here
# Pull and start container
docker run -d --name translation-service \
-p 3000:3000 \
-v "$(pwd)/models:/app/models" \
ghcr.io/linguaspark/server:maindocker run -d --name translation-service \
-p 3000:3000 \
docker.cnb.cool/aalivexy/translation-service:latestCreate a compose.yaml file:
services:
translation-service:
image: ghcr.io/linguaspark/server:main
ports:
- "3000:3000"
volumes:
- ./models:/app/models
environment:
API_KEY: "your_api_key" # Optional, leave empty to disable API key protection
restart: unless-stopped
healthcheck:
test: ["CMD", "/bin/sh", "-c", "echo -e 'GET /health HTTP/1.1\r\nHost: localhost:3000\r\n\r\n' | timeout 5 bash -c 'cat > /dev/tcp/localhost/3000' && echo 'Health check passed'"]
interval: 30s
timeout: 10s
retries: 3Start the service:
docker compose up -dIf you need to create a custom image with specific language pairs, use this Dockerfile template:
FROM ghcr.io/linguaspark/server:main
COPY ./your-models-directory /app/models
ENV MODELS_DIR=/app/models
ENV IP=0.0.0.0
ENV PORT=3000
ENV RUST_LOG=info
EXPOSE 3000
ENTRYPOINT ["/app/linguaspark-server"]- Download pre-trained models from Firefox Translations Models
- Place them in the models directory with the following structure:
models/
├── en-zh/
│ ├── model.enzh.intgemm.alphas.bin.gz
│ ├── lex.50.50.enzh.s2t.bin.gz
│ ├── srcvocab.enzh.spm.gz
│ └── trgvocab.enzh.spm.gz
└── zh-en/ # Another language pair
└── ...
Assets may be gzip-compressed (.gz) or already decompressed. Models with a single vocab*.spm[.gz] file are also supported as shared-vocabulary models.
The translation service automatically scans all language pair directories under models. Directory names use the source-target form, such as en-zh or zh-en, with ISO 639-1 language codes.
| Variable Name | Description | Default Value |
|---|---|---|
MODELS_DIR |
Path to models directory | /app/models |
IP |
IP address for the service to listen on | 127.0.0.1 |
PORT |
Port for the service to listen on | 3000 |
API_KEY |
API key (leave empty to disable) | "" |
RUST_LOG |
Log level | info |
POST /translate
Request body:
{
"text": "Hello world",
"from": "en", // Optional, omit to auto-detect
"to": "zh"
}Response:
{
"text": "你好世界",
"from": "en",
"to": "zh"
}The native endpoint also accepts a batch in text. All texts in one batch are
translated as the same source language; when from is omitted, the first text
is used for language detection.
{
"text": ["Hello world", "How are you?"],
"from": "en",
"to": "zh"
}The response keeps the same shape:
{
"text": ["你好世界", "你好吗?"],
"from": "en",
"to": "zh"
}POST /detect
Request body:
{
"text": "Hello world"
}Response:
{
"language": "en"
}POST /imme
Request body:
{
"source_lang": "auto", // Optional, omit to auto-detect
"target_lang": "zh",
"text_list": ["Hello world", "How are you?"]
}Response:
{
"translations": [
{
"detected_source_lang": "en",
"text": "你好世界"
},
{
"detected_source_lang": "en",
"text": "你好吗?"
}
]
}POST /kiss
Request body:
{
"text": "Hello world",
"from": "en", // Optional, omit to auto-detect
"to": "zh"
}Response:
{
"text": "你好世界",
"from": "en",
"to": "zh"
}POST /hcfy
Request body:
{
"text": "Hello world",
"source": "英语", // Optional, omit to auto-detect
"destination": ["中文(简体)"]
}Response:
{
"text": "Hello world",
"from": "英语",
"to": "中文(简体)",
"result": ["你好世界"]
}POST /deeplx
Request body:
{
"text": "Hello world",
"source_lang": "EN",
"target_lang": "ZH"
}Response:
{
"code": 200,
"id": 1744646400,
"data": "你好世界",
"alternatives": [],
"source_lang": "EN",
"target_lang": "ZH",
"method": "Free"
}GET /health
Response:
{
"status": "ok"
}If the API_KEY environment variable is set, all API requests except GET /health must provide authentication credentials using one of the following methods:
- Authorization header:
Authorization: Bearer your_api_key - Query parameter:
?token=your_api_key
This project is open-sourced under the AGPL-3.0 license.
- LinguaSpark - Pure Rust translation inference
- Firefox Translations Models - Translation models
- MTranServer - Inspiration
- Mozilla Translation Service - Reference implementation
- Bergamot Translator - Reference implementation