Spaces:
Sleeping
Sleeping
Update README.md
Browse files
README.md
CHANGED
|
@@ -1,301 +1,71 @@
|
|
| 1 |
-
# The Translator App
|
| 2 |
-
|
| 3 |
-
A Django web application for text translation, with a **separate backend model
|
| 4 |
-
API** (FastAPI) in `backend/` that serves translation engines and model
|
| 5 |
-
inference.
|
| 6 |
-
|
| 7 |
---
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
| Model-serving API | `backend/` (FastAPI) | Exposes `/api/translate`, `/api/engines`, `/api/languages`, and routes requests to available providers (NLLB/MADLAD/Ollama/Gemini/Groq) |
|
| 17 |
-
|
| 18 |
-
High-level request flow:
|
| 19 |
-
|
| 20 |
-
1. User submits text on Django page (`/`).
|
| 21 |
-
2. Django `translate_api` view validates input and calls `TranslationService`.
|
| 22 |
-
3. `TranslationService` maps app language codes to FLORES-200 codes and calls `MODEL_API_URL`.
|
| 23 |
-
4. FastAPI backend dispatches to the selected provider/engine.
|
| 24 |
-
5. Django stores translation in `TranslationHistory` and returns JSON to the UI.
|
| 25 |
-
|
| 26 |
---
|
| 27 |
|
| 28 |
-
#
|
| 29 |
-
|
| 30 |
-
```text
|
| 31 |
-
.
|
| 32 |
-
├── translator_app/ # Django app (user-facing application)
|
| 33 |
-
│ ├── translator_project/ # Django project config
|
| 34 |
-
│ ├── translator/ # App: models, views, services, templates
|
| 35 |
-
│ └── manage.py
|
| 36 |
-
├── backend/ # FastAPI model-serving API
|
| 37 |
-
│ ├── main.py # API entrypoint
|
| 38 |
-
│ ├── providers/ # Translation engine implementations
|
| 39 |
-
│ ├── languages.py # FLORES-200 language map
|
| 40 |
-
│ ├── convert_model.py # NLLB/MADLAD conversion helper
|
| 41 |
-
│ └── deploy_hf.py # Hugging Face Space deployment helper
|
| 42 |
-
├── Dockerfile # Root Docker build (backend-focused)
|
| 43 |
-
├── docker-compose.yml # Local backend compose setup
|
| 44 |
-
└── entrypoint.sh # Runtime model conversion + uvicorn start
|
| 45 |
-
```
|
| 46 |
-
|
| 47 |
-
---
|
| 48 |
-
|
| 49 |
-
## 3. Django application (`translator_app/`)
|
| 50 |
-
|
| 51 |
-
### 3.1 Core URLs
|
| 52 |
-
|
| 53 |
-
- `/` → translation UI (`translator.views.translator`)
|
| 54 |
-
- `/api/translate/` → AJAX translation endpoint (`translator.views.translate_api`)
|
| 55 |
-
- `/history/` → translation history list (`translator.views.history`)
|
| 56 |
-
- `/history/<id>/delete/` → delete one entry
|
| 57 |
-
- `/history/clear/` → clear all entries
|
| 58 |
-
|
| 59 |
-
### 3.2 Models
|
| 60 |
-
|
| 61 |
-
Defined in `translator/models.py`:
|
| 62 |
-
|
| 63 |
-
- `Language`: curated/active language list used by UI when present.
|
| 64 |
-
- `TranslationHistory`: persisted history with source text, translated text,
|
| 65 |
-
source/target language FK, selected model, and metadata.
|
| 66 |
-
- `TranslationCache`: hash-based cache for repeated translations.
|
| 67 |
-
|
| 68 |
-
Notable behavior:
|
| 69 |
-
|
| 70 |
-
- `TranslationHistory.save()` auto-computes `character_count` and `word_count`.
|
| 71 |
-
- History is ordered newest-first and indexed by `(user, -created_at)`.
|
| 72 |
-
|
| 73 |
-
### 3.3 Views and orchestration
|
| 74 |
-
|
| 75 |
-
`translator/views.py` coordinates UI + backend translation:
|
| 76 |
-
|
| 77 |
-
- `_languages()`:
|
| 78 |
-
- uses DB `Language` rows where `is_active=True`;
|
| 79 |
-
- falls back to `TranslationService().get_supported_languages()`.
|
| 80 |
-
- `translator()` renders model picker and language selectors.
|
| 81 |
-
- `translate_api()`:
|
| 82 |
-
- validates JSON payload and limits text to 5000 chars;
|
| 83 |
-
- validates selected model against `TRANSLATION_MODELS`;
|
| 84 |
-
- calls `TranslationService.translate(...)`;
|
| 85 |
-
- persists `TranslationHistory`;
|
| 86 |
-
- returns translated text + model label.
|
| 87 |
|
| 88 |
-
|
| 89 |
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
- Detects source language with `langdetect` when source is not provided.
|
| 93 |
-
- Converts app language codes (`en`, `sw`, etc.) to FLORES-200 (`eng_Latn`,
|
| 94 |
-
`swh_Latn`) for the backend API.
|
| 95 |
-
- Uses cache (`TranslationCache`) keyed by text + source + target + model.
|
| 96 |
-
- Supports:
|
| 97 |
-
- model API path (via `MODEL_API_URL`), and
|
| 98 |
-
- optional `deepl_fallback` path when `TRANSLATION_API_KEY` is configured.
|
| 99 |
-
|
| 100 |
-
### 3.5 Templates/UI behavior
|
| 101 |
-
|
| 102 |
-
Templates in `translator/templates/translator/`:
|
| 103 |
-
|
| 104 |
-
- `base.html`: shell layout and Tailwind CDN styling.
|
| 105 |
-
- `translator.html`: main translation page with JS submit flow.
|
| 106 |
-
- `history.html`: persisted history view with delete/clear actions.
|
| 107 |
-
|
| 108 |
-
Client-side behavior in `translator.html`:
|
| 109 |
-
|
| 110 |
-
- POSTs JSON to `/api/translate/` with CSRF header.
|
| 111 |
-
- Sends selected `model`, `source_language`, `target_language`, and text.
|
| 112 |
-
- Disables source selector when model is `madlad` (MADLAD auto-detect source).
|
| 113 |
|
| 114 |
---
|
| 115 |
|
| 116 |
-
##
|
| 117 |
-
|
| 118 |
-
### 4.1 API endpoints (`backend/main.py`)
|
| 119 |
-
|
| 120 |
-
- `GET /api/health` → service status + default available engine.
|
| 121 |
-
- `GET /api/engines` → all engines with metadata and availability.
|
| 122 |
-
- `GET /api/languages` → language list (from FLORES-200 map).
|
| 123 |
-
- `POST /api/translate` → translation endpoint.
|
| 124 |
-
- `GET /scalar` → Scalar API documentation UI.
|
| 125 |
-
|
| 126 |
-
`/api/translate` request shape:
|
| 127 |
-
|
| 128 |
-
```json
|
| 129 |
-
{
|
| 130 |
-
"text": "Hello world",
|
| 131 |
-
"source": "eng_Latn",
|
| 132 |
-
"target": "swh_Latn",
|
| 133 |
-
"engine": "nllb"
|
| 134 |
-
}
|
| 135 |
-
```
|
| 136 |
-
|
| 137 |
-
Response shape:
|
| 138 |
-
|
| 139 |
-
```json
|
| 140 |
-
{
|
| 141 |
-
"translation": "Habari dunia",
|
| 142 |
-
"source": "eng_Latn",
|
| 143 |
-
"target": "swh_Latn",
|
| 144 |
-
"engine": "nllb"
|
| 145 |
-
}
|
| 146 |
-
```
|
| 147 |
-
|
| 148 |
-
### 4.2 Provider architecture
|
| 149 |
-
|
| 150 |
-
Providers implement `TranslationProvider` (`backend/providers/base.py`).
|
| 151 |
-
|
| 152 |
-
Registry in `backend/providers/__init__.py` includes:
|
| 153 |
-
|
| 154 |
-
- `nllb` (NLLB-200 600M)
|
| 155 |
-
- `nllb_1_3b` (NLLB-200 1.3B)
|
| 156 |
-
- `madlad` (MADLAD-400 3B)
|
| 157 |
-
- `ollama` (local Ollama model)
|
| 158 |
-
- `gemini` (Google API)
|
| 159 |
-
- `groq_qwen` and `groq` (Groq API models)
|
| 160 |
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
### 4.3 Language system
|
| 168 |
-
|
| 169 |
-
`backend/languages.py` provides a full FLORES-200 code map used by local/API
|
| 170 |
-
providers. Django only exposes a curated subset in app-level UI defaults.
|
| 171 |
-
|
| 172 |
-
### 4.4 Model conversion
|
| 173 |
-
|
| 174 |
-
`backend/convert_model.py` converts Hugging Face checkpoints to CTranslate2
|
| 175 |
-
int8 models (faster/lower-memory inference). Conversion target path defaults to:
|
| 176 |
-
|
| 177 |
-
- `models/nllb-200-distilled-600M-int8`
|
| 178 |
-
|
| 179 |
-
Environment overrides allow converting additional models (e.g. 1.3B, MADLAD).
|
| 180 |
|
| 181 |
---
|
| 182 |
|
| 183 |
-
##
|
| 184 |
-
|
| 185 |
-
### 5.1 Django (`translator_app/.env`)
|
| 186 |
-
|
| 187 |
-
Important settings loaded by `translator_project/settings.py`:
|
| 188 |
-
|
| 189 |
-
- `MODEL_API_URL` (**required** for model API translation path)
|
| 190 |
-
- `TRANSLATION_DEFAULT_MODEL` (default: `nllb`)
|
| 191 |
-
- `TRANSLATION_API_KEY` (optional; enables `deepl_fallback`)
|
| 192 |
-
- `TRANSLATION_API_URL` (optional; DeepL-compatible endpoint override)
|
| 193 |
-
|
| 194 |
-
Model IDs configured in Django:
|
| 195 |
|
| 196 |
-
-
|
| 197 |
-
-
|
| 198 |
-
- `
|
| 199 |
-
- `deepl_fallback` (only when fallback key configured)
|
| 200 |
-
|
| 201 |
-
### 5.2 Backend (`backend/.env`)
|
| 202 |
-
|
| 203 |
-
See `backend/.env.example` for optional engine keys:
|
| 204 |
-
|
| 205 |
-
- `GEMINI_API_KEY`
|
| 206 |
-
- `GROQ_API_KEY`
|
| 207 |
-
- `OLLAMA_HOST`, `OLLAMA_MODEL`
|
| 208 |
-
- `CT2_DEVICE`, `CT2_COMPUTE_TYPE`
|
| 209 |
-
- `MADLAD_MODEL_DIR`, related model paths
|
| 210 |
-
- `CORS_ORIGINS`
|
| 211 |
|
| 212 |
---
|
| 213 |
|
| 214 |
-
##
|
| 215 |
-
|
| 216 |
-
### 6.1 Run Django app
|
| 217 |
|
|
|
|
| 218 |
```bash
|
| 219 |
-
|
| 220 |
-
python -m venv .venv
|
| 221 |
-
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
| 222 |
-
pip install -r ../requirements.txt
|
| 223 |
-
python manage.py migrate
|
| 224 |
-
python manage.py runserver
|
| 225 |
```
|
| 226 |
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
### 6.2 Run backend API (direct)
|
| 230 |
-
|
| 231 |
```bash
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
source .venv/bin/activate
|
| 235 |
-
pip install -r requirements.txt
|
| 236 |
-
uvicorn main:app --host 0.0.0.0 --port 7860
|
| 237 |
-
```
|
| 238 |
-
|
| 239 |
-
API URL: `http://127.0.0.1:7860/api/health`
|
| 240 |
-
|
| 241 |
-
### 6.3 Run backend API via Docker Compose
|
| 242 |
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
|
|
|
|
|
|
| 247 |
```
|
| 248 |
|
| 249 |
-
Compose maps port `7860` and mounts persistent model/cache volumes.
|
| 250 |
-
|
| 251 |
---
|
| 252 |
|
| 253 |
-
##
|
| 254 |
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
Use helper:
|
| 258 |
|
| 259 |
```bash
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
python backend/deploy_hf.py
|
| 263 |
-
```
|
| 264 |
-
|
| 265 |
-
Detailed deployment notes are in `backend/HUGGINGFACE_DEPLOYMENT.md`.
|
| 266 |
-
|
| 267 |
-
After deployment, set Django:
|
| 268 |
-
|
| 269 |
-
```env
|
| 270 |
-
MODEL_API_URL=https://<your-space>.hf.space/api/translate
|
| 271 |
-
```
|
| 272 |
-
|
| 273 |
-
---
|
| 274 |
-
|
| 275 |
-
## 8. Data and persistence
|
| 276 |
-
|
| 277 |
-
- Django DB: `translator_app/db.sqlite3`
|
| 278 |
-
- Translation history and cache live in Django DB.
|
| 279 |
-
- Backend model artifacts are stored under configured model directories
|
| 280 |
-
(often mounted as Docker volumes in local/containerized runs).
|
| 281 |
-
|
| 282 |
-
---
|
| 283 |
-
|
| 284 |
-
## 9. Current test coverage
|
| 285 |
-
|
| 286 |
-
`translator/tests.py` currently covers:
|
| 287 |
-
|
| 288 |
-
- translation page renders model selector
|
| 289 |
-
- translation API saves history record
|
| 290 |
-
- translation API rejects missing text
|
| 291 |
-
|
| 292 |
-
---
|
| 293 |
-
|
| 294 |
-
## 10. Key integration contract (Django ↔ backend)
|
| 295 |
-
|
| 296 |
-
For end-to-end translation to work:
|
| 297 |
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
4. Selected model is persisted in `TranslationHistory.translation_model` and shown in history.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: Translator Model API
|
| 3 |
+
emoji: 🌍
|
| 4 |
+
colorFrom: indigo
|
| 5 |
+
colorTo: green
|
| 6 |
+
sdk: docker
|
| 7 |
+
app_port: 7860
|
| 8 |
+
pinned: false
|
| 9 |
+
short_description: Fast CPU-optimized Translation API powered by CTranslate2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# 🌍 Translator Model API
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
+
A lightweight, high-performance Translation API built with **FastAPI** and powered by **CTranslate2 (INT8)** for fast, memory-efficient CPU inference.
|
| 15 |
|
| 16 |
+
Models are automatically fetched from Hugging Face on container startup and converted to CTranslate2 INT8 format to minimize RAM consumption and maximize CPU execution throughput.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
---
|
| 19 |
|
| 20 |
+
## 🚀 Supported Models
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
+
| Model Name | Original Source | CT2 INT8 Size | Primary Use Case |
|
| 23 |
+
| :--- | :--- | :--- | :--- |
|
| 24 |
+
| **NLLB 600M** | `facebook/nllb-200-distilled-600M` | ~600 MB | Fast general translation (200+ languages) |
|
| 25 |
+
| **NLLB 1.3B** | `facebook/nllb-200-distilled-1.3B` | ~1.4 GB | Higher quality general translation |
|
| 26 |
+
| **MADLAD 3B** | `google/madlad400-3b-mt` | ~3.1 GB | Multilingual translation across 400+ languages |
|
| 27 |
+
| **Sunbird NLLB 3.3B** | `Sunbird/translate-nllb-3.3b-salt` | ~3.8 GB | Ugandan & East African languages (Luganda, Acholi, Runyankole, Swahili, etc.) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
|
| 29 |
---
|
| 30 |
|
| 31 |
+
## ⚡ Performance Highlights
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
+
- **CTranslate2 INT8 Quantization:** Reduces weight footprint by ~75% and speeds up token generation by up to 4–8x on CPU compared to standard PyTorch FP32/FP16 models.
|
| 34 |
+
- **OpenMP Multi-threading:** Configured to parallelize generation across available CPU cores.
|
| 35 |
+
- **Safetensors Support:** Automatically handles Hugging Face `.safetensors` weights during startup conversion.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
---
|
| 38 |
|
| 39 |
+
## 🛠️ API Usage
|
|
|
|
|
|
|
| 40 |
|
| 41 |
+
### Health Check
|
| 42 |
```bash
|
| 43 |
+
GET /
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
```
|
| 45 |
|
| 46 |
+
### Translate Text
|
|
|
|
|
|
|
|
|
|
| 47 |
```bash
|
| 48 |
+
POST /translate
|
| 49 |
+
Content-Type: application/json
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
+
{
|
| 52 |
+
"model": "sunbird-nllb-3.3b",
|
| 53 |
+
"text": "Hello, how are you today?",
|
| 54 |
+
"src_lang": "eng_Latn",
|
| 55 |
+
"tgt_lang": "lug_Latn"
|
| 56 |
+
}
|
| 57 |
```
|
| 58 |
|
|
|
|
|
|
|
| 59 |
---
|
| 60 |
|
| 61 |
+
## 🐳 Local Development (Docker)
|
| 62 |
|
| 63 |
+
To build and test the container locally:
|
|
|
|
|
|
|
| 64 |
|
| 65 |
```bash
|
| 66 |
+
# Build Docker image
|
| 67 |
+
docker build -t translator-api .
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
+
# Run Docker container mapping port 7860
|
| 70 |
+
docker run -p 7860:7860 -v $(pwd)/data:/data translator-api
|
| 71 |
+
```
|
|
|