- Python 36.7%
- JavaScript 26.9%
- CSS 20.5%
- HTML 11%
- Dockerfile 4.9%
| backend | ||
| frontend | ||
| docker-compose.yml | ||
| README.md | ||
Traducteur Local — Suite de traduction auto-hébergée
Traduction automatique privée, basée sur MarianMT (Helsinki-NLP).
Zéro donnée envoyée à l'extérieur. Zéro dépendance cloud. Tourne sur votre machine.
Démarrage en 3 commandes
git clone https://github.com/vous/translation-suite.git
cd translation-suite
mkdir -p models && sudo chown 1001:1001 models # évite une PermissionError au premier téléchargement
docker compose up -d
L'interface est disponible sur http://localhost:3000
Premier lancement : le premier appel de traduction télécharge le modèle MarianMT correspondant (~300 Mo par paire de langues). Les suivants utilisent le cache local. Vous verrez un indicateur de chargement pendant ce téléchargement initial.
Prérequis
| Outil | Version minimale |
|---|---|
| Docker | 24.x |
| Docker Compose | v2.x (docker compose, pas docker-compose) |
| RAM disponible | 1 Go (standard) · 512 Mo (minimal, MAX_LOADED_MODELS=1) |
| Espace disque | 300 Mo par paire de langues téléchargée |
Architecture
translation-suite/
├── backend/ # Moteur de traduction (FastAPI + MarianMT)
│ ├── main.py # Point d'entrée, logging, middleware
│ ├── translator.py # Logique MarianMT, pivot EN, cache LRU
│ ├── routes.py # Endpoints /translate /languages /health
│ ├── requirements.txt # Dépendances Python (versions figées)
│ └── Dockerfile # Multi-stage, CPU only, non-root
├── frontend/ # Interface web statique
│ ├── index.html # Structure HTML, zéro CDN
│ ├── style.css # Thème clair/sombre, responsive
│ ├── app.js # Logique UI, appels API, historique
│ ├── config.js # URL backend configurable
│ ├── nginx.conf # Proxy /api/, headers sécurité, logs privacy
│ └── Dockerfile # nginx:alpine, ~8 Mo
├── models/ # Modèles téléchargés (volume persistant, gitignore)
├── docker-compose.yml
└── .env.example
Flux d'une traduction :
Navigateur → Nginx :3000 → /api/translate → Backend :8000 → MarianMT (CPU) → Réponse
Le backend n'est jamais exposé directement à l'extérieur en production.
Configuration
Copiez .env.example en .env et ajustez :
cp .env.example .env
| Variable | Défaut | Description |
|---|---|---|
MAX_LOADED_MODELS |
3 |
Modèles simultanés en RAM (~300 Mo chacun) |
WARMUP_PAIR |
(vide) | Pré-charger un modèle au démarrage (ex: fr-en) |
LOG_LEVEL |
INFO |
DEBUG · INFO · WARNING · ERROR |
TRANSFORMERS_OFFLINE |
0 |
1 = bloque tout téléchargement (mode air-gap) |
CORS_ORIGINS |
* |
Restreindre en production : http://localhost:3000 |
FRONTEND_PORT |
3000 |
Port exposé pour l'interface |
Ajuster la consommation mémoire
| Profil | MAX_LOADED_MODELS |
RAM utilisée | Cas d'usage |
|---|---|---|---|
| Minimal | 1 |
~400 Mo | Raspberry Pi, NAS |
| Standard | 3 |
~1 Go | VPS 2 Go |
| Large | 6 |
~2 Go | VPS 4 Go ou machine locale |
Modifiez dans docker-compose.yml ou .env, puis :
docker compose up -d --force-recreate backend
Gestion des modèles de traduction
Comment les modèles sont chargés
Les modèles Helsinki-NLP/opus-mt sont téléchargés
automatiquement au premier appel pour chaque paire de langues demandée,
puis conservés dans ./models/ pour tous les appels suivants.
./models/
├── opus-mt-fr-en/ # Français → Anglais
├── opus-mt-en-de/ # Anglais → Allemand
└── opus-mt-fr-de/ # Français → Allemand (si disponible)
Logique de pivot automatique
Si aucun modèle direct fr → de n'existe, le backend traduit automatiquement
via l'anglais : fr → en → de. La réponse inclut "pivot_used": true pour
vous en informer. Ce mécanisme est transparent pour l'utilisateur.
Pré-télécharger des modèles manuellement
Pour éviter la latence du premier appel (utile avant une démo ou en mode offline) :
# Exemple : pré-télécharger français ↔ anglais
docker compose run --rm backend python -c "
from translator import translate
translate('test', 'fr', 'en')
translate('test', 'en', 'fr')
print('Modèles téléchargés.')
"
Supprimer un modèle
rm -rf ./models/opus-mt-fr-en/
Il sera retéléchargé au prochain appel si TRANSFORMERS_OFFLINE=0.
Mode air-gap (zéro réseau)
Pré-téléchargez tous les modèles nécessaires, puis :
# Dans .env
TRANSFORMERS_OFFLINE=1
Le backend refusera tout téléchargement réseau. Toute paire de langues absente retournera une erreur 404 claire.
Compatibilité DeepLX
Ce backend est compatible avec le format de requête/réponse DeepLX, ce qui permet de l'utiliser avec des extensions navigateur comme DeepL for Chrome ou tout outil attendant une API DeepL auto-hébergée.
Configuration d'une extension compatible DeepLX
Dans les paramètres de votre extension, renseignez :
URL de l'API : http://localhost:3000/api/translate
(ou http://votre-serveur:3000/api/translate)
Clé API : (laisser vide ou mettre n'importe quelle valeur)
Exemple d'appel direct
curl -s -X POST http://localhost:3000/api/translate \
-H "Content-Type: application/json" \
-d '{
"text": "Bonjour le monde",
"source_lang": "fr",
"target_lang": "en"
}' | jq .
Réponse :
{
"code": 200,
"data": "Hello world",
"source_lang": "fr",
"target_lang": "en",
"alternatives": [],
"pivot_used": false,
"elapsed_ms": 412
}
Endpoints disponibles
| Méthode | Endpoint | Description |
|---|---|---|
POST |
/api/translate |
Traduit un texte (compatible DeepLX) |
GET |
/api/languages |
Liste les langues disponibles |
GET |
/api/health |
Statut du service (healthcheck) |
GET |
/api/docs |
Documentation Swagger interactive |
Déploiement sur VPS
Exposer via un reverse proxy (recommandé)
Exemple avec Nginx sur l'hôte (sans SSL géré par ce projet) :
server {
listen 443 ssl;
server_name translate.mondomaine.fr;
ssl_certificate /etc/letsencrypt/live/translate.mondomaine.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/translate.mondomaine.fr/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_read_timeout 180s;
}
}
En production, commentez le ports du backend dans docker-compose.yml
pour qu'il ne soit accessible que via le réseau interne Docker.
Commandes utiles
# Voir les logs en temps réel
docker compose logs -f
# Logs backend uniquement (sans le contenu traduit)
docker compose logs -f backend
# Statut des conteneurs
docker compose ps
# Redémarrer uniquement le backend (ex: après changement de config)
docker compose restart backend
# Mettre à jour (rebuild des images)
docker compose up -d --build
# Arrêter sans supprimer les volumes
docker compose stop
# Arrêter et supprimer les conteneurs (les modèles dans ./models/ sont conservés)
docker compose down
Engagement Zéro Donnée Externe
Ce projet est conçu par construction pour ne jamais transmettre vos textes à l'extérieur :
- Traduction locale — Les modèles MarianMT tournent entièrement sur votre machine. Aucune requête de traduction ne quitte votre serveur.
- Logs sans contenu — Les logs du backend enregistrent uniquement les codes de langue, les temps de réponse et les erreurs techniques. Le texte traduit n'y figure jamais.
- Historique navigateur — L'historique des traductions est stocké dans le
localStoragede votre navigateur. Il n'est jamais envoyé au serveur, même local. - Zéro CDN — Le frontend ne charge aucune ressource externe (pas de Google Fonts, pas de bibliothèque JS depuis un CDN). Tout est servi localement.
- Télémétrie désactivée —
HF_HUB_DISABLE_TELEMETRY=1est positionné par défaut : HuggingFace ne reçoit aucune statistique d'utilisation. - Téléchargement unique — Les modèles sont téléchargés une seule fois depuis HuggingFace lors du premier appel, puis conservés localement. Les appels suivants sont 100% offline.
Licence
Ce projet est distribué sous licence GNU Affero General Public License v3.0 (AGPLv3).
Cela signifie que toute modification de ce code, y compris si vous l'utilisez
pour fournir un service en ligne, doit être publiée sous la même licence.
Voir le fichier LICENSE pour le texte complet.